4 // ### How to create a tracebuffer entry ###
6 // If you only need a temporary debugging aid then you can use one of
7 // the standard kernel logging events:
9 // LOG_MSG(Context *context, const char *msg)
10 // - context is something like context_of(this) or current_context()
11 // or 0 if there is no context available
12 // - msg should be displayed in the tracebuffer view
14 // LOG_MSG_3VAL(Context *context, const char *msg,
15 // Mword val1, Mword val2, Mword val3)
16 // - context and msg can be used the same way LOG_MSG does
17 // - val1, val2, and val3 are values that will be displayed in
18 // the tracebuffer view as hexadecimal values
20 // If you want to create a permanent log event xyz, you have to follow
21 // these instructions:
22 // - create enum Log_event_xyz (see jdb_ktrace.cpp)
23 // - create class Tb_entry_xyz derived from Tb_entry (see tb_entry.cpp)
24 // with an appropriate ::set method and with accessor methods
25 // - create function formatter_xyz (see tb_entry_output.cpp) and don't
26 // forget to register it (add an appropriate line to init_formatters)
27 // - create macro LOG_XYZ (see the following example)
29 // BEGIN_LOG_EVENT(log_xyz)
30 // Lock_guard <Cpu_lock> guard (&cpu_lock);
32 // static_cast<Tb_entry_ctx_sw*>(Jdb_tbuf::new_entry());
33 // tb->set (this, <some log specific variables>)
34 // Jdb_tbuf::commit_entry();
36 // (grabbing the cpu_lock isn't necessary if it is still grabbed)
37 // - create an empty macro declaration for CONFIG_JDB_LOGGING=n
38 // - insert the macro call into the code
39 // - WARNING: permanent log events should _not_ be placed into an inline
42 // DECLARE_PATCH (lp<nn>, log_xyz);
43 // static Log_event le<mm>(<description for the 'O' command>,
44 // Log_event_xyz, 1, &lp<nn>);
45 // and create an entry le<mm> for Jdb_tbuf_events::log_events[]
46 // (see jdb_tbuf_events.cpp)
48 #include "globalconfig.h"
50 #if defined(CONFIG_JDB)
55 #include "lock_guard.h"
56 #include "processor.h"
58 #define LOG_CONTEXT_SWITCH \
59 BEGIN_LOG_EVENT("Context switch", "csw", 0) \
60 Tb_entry_ctx_sw *tb = \
61 static_cast<Tb_entry_ctx_sw*>(Jdb_tbuf::new_entry()); \
62 tb->set(this, space(), regs()->ip_syscall_page_user(), t, t_orig, \
63 t_orig->lock_cnt(), current_sched(), \
64 current_sched() ? current_sched()->prio() : 0, \
65 (Mword)__builtin_return_address(0)); \
66 Jdb_tbuf::commit_entry(); \
71 BEGIN_LOG_EVENT("Exceptions", "exc", 0) \
72 if (ts->_trapno != 1 && ts->_trapno != 3) \
75 static_cast<Tb_entry_trap*>(Jdb_tbuf::new_entry()); \
76 tb->set(this, ts->ip(), ts); \
77 Jdb_tbuf::commit_entry(); \
81 #define LOG_TRAP_N(n) \
82 BEGIN_LOG_EVENT("Exception n", "exc", 0) \
84 static_cast<Tb_entry_trap*>(Jdb_tbuf::new_entry()); \
85 Mword ip = (Mword)(__builtin_return_address(0)); \
86 tb->set(current(), ip, n); \
87 Jdb_tbuf::commit_entry(); \
90 #define LOG_PF_RES_USER \
91 BEGIN_LOG_EVENT("Page-fault results", "pfr", 0) \
92 Tb_entry_pf_res *tb = \
93 static_cast<Tb_entry_pf_res*>(Jdb_tbuf::new_entry()); \
94 tb->set(this, regs()->ip_syscall_page_user(), pfa, err, ret); \
95 Jdb_tbuf::commit_entry(); \
98 #define LOG_SCHED_SAVE(cs) \
99 BEGIN_LOG_EVENT("Scheduling context save", "sch", 0) \
100 Tb_entry_sched *tb = \
101 static_cast<Tb_entry_sched*>(Jdb_tbuf::new_entry()); \
102 tb->set (current(), 0, 0, \
108 Jdb_tbuf::commit_entry(); \
111 #define LOG_SCHED_LOAD(cs) \
112 BEGIN_LOG_EVENT("Scheduling context load", "sch", 0) \
113 Tb_entry_sched *tb = \
114 static_cast<Tb_entry_sched*>(Jdb_tbuf::new_entry()); \
115 tb->set (current(), 0, 1, \
121 Jdb_tbuf::commit_entry(); \
124 #define LOG_SCHED_INVALIDATE \
125 BEGIN_LOG_EVENT("Schduling context invalidate", "sch", 0) \
126 Tb_entry_sched *tb = \
127 static_cast<Tb_entry_sched*>(Jdb_tbuf::new_entry()); \
128 tb->set (current(), current()->regs()->ip_syscall_page_user(), 2, \
129 current_sched()->owner(), \
130 current_sched()->id(), \
131 current_sched()->prio(), \
132 timeslice_timeout.cpu(cpu())->get_timeout(Kip::k()->clock), \
133 current_sched()->quantum()); \
134 Jdb_tbuf::commit_entry(); \
137 #define LOG_SEND_PREEMPTION \
138 BEGIN_LOG_EVENT("Preemption events", "pre", 0) \
139 Lock_guard <Cpu_lock> guard (&cpu_lock); \
140 Tb_entry_preemption *tb = \
141 static_cast<Tb_entry_preemption*>(Jdb_tbuf::new_entry()); \
142 tb->set (context_of(this), _receiver.raw(), current()->regs()->ip_syscall_page_user());\
143 Jdb_tbuf::commit_entry(); \
147 * Kernel instrumentation macro used by fm3. Do not remove!
149 #define LOG_MSG(context, text) \
151 /* The cpu_lock is needed since virq::hit() depends on it */ \
152 Lock_guard <Cpu_lock> guard (&cpu_lock); \
153 Tb_entry_ke *tb = static_cast<Tb_entry_ke*>(Jdb_tbuf::new_entry()); \
154 tb->set_const(context, Proc::program_counter(), text); \
155 Jdb_tbuf::commit_entry(); \
159 * Kernel instrumentation macro used by fm3. Do not remove!
161 #define LOG_MSG_3VAL(context, text, v1, v2, v3) \
163 /* The cpu_lock is needed since virq::hit() depends on it */ \
164 Lock_guard <Cpu_lock> guard (&cpu_lock); \
165 Tb_entry_ke_reg *tb = \
166 static_cast<Tb_entry_ke_reg*>(Jdb_tbuf::new_entry()); \
167 tb->set_const(context, Proc::program_counter(), text, v1, v2, v3); \
168 Jdb_tbuf::commit_entry(); \
172 #define LOG_TRACE(name, sc, ctx, fmt, code...) \
173 BEGIN_LOG_EVENT(name, sc, fmt) \
174 Tb_entry *tbe = Jdb_tbuf::new_entry(); \
175 tbe->set_global(__do_log__, ctx, Proc::program_counter()); \
177 Jdb_tbuf::commit_entry(); \
183 #define LOG_TRACE(name, sc, ctx, fmt, code...) do { } while (0)
184 #define LOG_CONTEXT_SWITCH do { } while (0)
185 #define LOG_TRAP do { } while (0)
186 #define LOG_TRAP_N(n) do { } while (0)
187 #define LOG_PF_RES_USER do { } while (0)
188 #define LOG_SCHED do { } while (0)
189 #define LOG_SCHED_SAVE(n) do { } while (0)
190 #define LOG_SCHED_LOAD(n) do { } while (0)
191 #define LOG_SCHED_INVALIDATE do { } while (0)
192 #define LOG_SEND_PREEMPTION do { } while (0)
196 #if defined(CONFIG_JDB) && defined(CONFIG_JDB_ACCOUNTING)
198 #define CNT_CONTEXT_SWITCH \
199 Jdb_tbuf::status()->kerncnts[Kern_cnt_context_switch]++;
200 #define CNT_ADDR_SPACE_SWITCH \
201 Jdb_tbuf::status()->kerncnts[Kern_cnt_addr_space_switch]++;
202 #define CNT_SHORTCUT_FAILED \
203 Jdb_tbuf::status()->kerncnts[Kern_cnt_shortcut_failed]++;
204 #define CNT_SHORTCUT_SUCCESS \
205 Jdb_tbuf::status()->kerncnts[Kern_cnt_shortcut_success]++;
207 Jdb_tbuf::status()->kerncnts[Kern_cnt_irq]++;
208 #define CNT_IPC_LONG \
209 Jdb_tbuf::status()->kerncnts[Kern_cnt_ipc_long]++;
210 #define CNT_PAGE_FAULT \
211 Jdb_tbuf::status()->kerncnts[Kern_cnt_page_fault]++;
212 #define CNT_IO_FAULT \
213 Jdb_tbuf::status()->kerncnts[Kern_cnt_io_fault]++;
214 #define CNT_TASK_CREATE \
215 Jdb_tbuf::status()->kerncnts[Kern_cnt_task_create]++;
216 #define CNT_SCHEDULE \
217 Jdb_tbuf::status()->kerncnts[Kern_cnt_schedule]++;
218 #define CNT_IOBMAP_TLB_FLUSH \
219 Jdb_tbuf::status()->kerncnts[Kern_cnt_iobmap_tlb_flush]++;
220 #define CNT_EXC_IPC \
221 Jdb_tbuf::status()->kerncnts[Kern_cnt_exc_ipc]++;
225 #define CNT_CONTEXT_SWITCH do { } while (0)
226 #define CNT_ADDR_SPACE_SWITCH do { } while (0)
227 #define CNT_SHORTCUT_FAILED do { } while (0)
228 #define CNT_SHORTCUT_SUCCESS do { } while (0)
229 #define CNT_IRQ do { } while (0)
230 #define CNT_IPC_LONG do { } while (0)
231 #define CNT_PAGE_FAULT do { } while (0)
232 #define CNT_IO_FAULT do { } while (0)
233 #define CNT_TASK_CREATE do { } while (0)
234 #define CNT_SCHEDULE do { } while (0)
235 #define CNT_IOBMAP_TLB_FLUSH do { } while (0)
236 #define CNT_EXC_IPC do { } while (0)
238 #endif // CONFIG_JDB && CONFIG_JDB_ACCOUNTING