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(), 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(); \
70 BEGIN_LOG_EVENT("Exceptions", "exc", 0) \
72 static_cast<Tb_entry_trap*>(Jdb_tbuf::new_entry()); \
73 tb->set(current_thread(), ts); \
74 Jdb_tbuf::commit_entry(); \
77 #define LOG_TRAP_N(n) \
78 BEGIN_LOG_EVENT("Exception n", "exc", 0) \
80 static_cast<Tb_entry_trap*>(Jdb_tbuf::new_entry()); \
81 Mword ip = (Mword)(__builtin_return_address(0)); \
82 tb->set(current(), ip, n); \
83 Jdb_tbuf::commit_entry(); \
86 #define LOG_PF_RES_USER \
87 BEGIN_LOG_EVENT("Page-fault results", "pfr", 0) \
88 Tb_entry_pf_res *tb = \
89 static_cast<Tb_entry_pf_res*>(Jdb_tbuf::new_entry()); \
90 tb->set(this, regs()->ip(), pfa, err, ret); \
91 Jdb_tbuf::commit_entry(); \
94 #define LOG_SCHED_SAVE(cs) \
95 BEGIN_LOG_EVENT("Scheduling context save", "sch", 0) \
96 Tb_entry_sched *tb = \
97 static_cast<Tb_entry_sched*>(Jdb_tbuf::new_entry()); \
98 tb->set (current(), 0, 0, \
104 Jdb_tbuf::commit_entry(); \
107 #define LOG_SCHED_LOAD(cs) \
108 BEGIN_LOG_EVENT("Scheduling context load", "sch", 0) \
109 Tb_entry_sched *tb = \
110 static_cast<Tb_entry_sched*>(Jdb_tbuf::new_entry()); \
111 tb->set (current(), 0, 1, \
117 Jdb_tbuf::commit_entry(); \
120 #define LOG_SCHED_INVALIDATE \
121 BEGIN_LOG_EVENT("Schduling context invalidate", "sch", 0) \
122 Tb_entry_sched *tb = \
123 static_cast<Tb_entry_sched*>(Jdb_tbuf::new_entry()); \
124 tb->set (current(), current()->regs()->ip(), 2, \
125 current_sched()->context(), \
126 current_sched()->id(), \
127 current_sched()->prio(), \
128 timeslice_timeout.cpu(cpu())->get_timeout(Kip::k()->clock), \
129 current_sched()->quantum()); \
130 Jdb_tbuf::commit_entry(); \
133 #define LOG_SEND_PREEMPTION \
134 BEGIN_LOG_EVENT("Preemption events", "pre", 0) \
135 Lock_guard <Cpu_lock> guard (&cpu_lock); \
136 Tb_entry_preemption *tb = \
137 static_cast<Tb_entry_preemption*>(Jdb_tbuf::new_entry()); \
138 tb->set (context_of(this), _receiver.raw(), current()->regs()->ip()); \
139 Jdb_tbuf::commit_entry(); \
143 * Kernel instrumentation macro used by fm3. Do not remove!
145 #define LOG_MSG(context, text) \
147 /* The cpu_lock is needed since virq::hit() depends on it */ \
148 Lock_guard <Cpu_lock> guard (&cpu_lock); \
149 Tb_entry_ke *tb = static_cast<Tb_entry_ke*>(Jdb_tbuf::new_entry()); \
150 tb->set_const(context, Proc::program_counter(), text); \
151 Jdb_tbuf::commit_entry(); \
155 * Kernel instrumentation macro used by fm3. Do not remove!
157 #define LOG_MSG_3VAL(context, text, v1, v2, v3) \
159 /* The cpu_lock is needed since virq::hit() depends on it */ \
160 Lock_guard <Cpu_lock> guard (&cpu_lock); \
161 Tb_entry_ke_reg *tb = \
162 static_cast<Tb_entry_ke_reg*>(Jdb_tbuf::new_entry()); \
163 tb->set_const(context, Proc::program_counter(), text, v1, v2, v3); \
164 Jdb_tbuf::commit_entry(); \
168 #define LOG_TRACE(name, sc, ctx, fmt, code...) \
169 BEGIN_LOG_EVENT(name, sc, fmt) \
170 Tb_entry *tbe = Jdb_tbuf::new_entry(); \
171 tbe->set_global(__do_log__, ctx, Proc::program_counter()); \
173 Jdb_tbuf::commit_entry(); \
179 #define LOG_TRACE(name, sc, ctx, fmt, code...) do { } while (0)
180 #define LOG_CONTEXT_SWITCH do { } while (0)
181 #define LOG_TRAP do { } while (0)
182 #define LOG_TRAP_N(n) do { } while (0)
183 #define LOG_PF_RES_USER do { } while (0)
184 #define LOG_SCHED do { } while (0)
185 #define LOG_SCHED_SAVE(n) do { } while (0)
186 #define LOG_SCHED_LOAD(n) do { } while (0)
187 #define LOG_SCHED_INVALIDATE do { } while (0)
188 #define LOG_SEND_PREEMPTION do { } while (0)
192 #if defined(CONFIG_JDB) && defined(CONFIG_JDB_ACCOUNTING)
194 #error ARM does not have CONFIG_JDB_ACCOUNTING
196 #define CNT_CONTEXT_SWITCH \
197 Jdb_tbuf::status()->kerncnts[Kern_cnt_context_switch]++;
198 #define CNT_ADDR_SPACE_SWITCH \
199 Jdb_tbuf::status()->kerncnts[Kern_cnt_addr_space_switch]++;
200 #define CNT_SHORTCUT_FAILED \
201 Jdb_tbuf::status()->kerncnts[Kern_cnt_shortcut_failed]++;
202 #define CNT_SHORTCUT_SUCCESS \
203 Jdb_tbuf::status()->kerncnts[Kern_cnt_shortcut_success]++;
205 Jdb_tbuf::status()->kerncnts[Kern_cnt_irq]++;
206 #define CNT_IPC_LONG \
207 Jdb_tbuf::status()->kerncnts[Kern_cnt_ipc_long]++;
208 #define CNT_PAGE_FAULT \
209 Jdb_tbuf::status()->kerncnts[Kern_cnt_page_fault]++;
210 #define CNT_IO_FAULT \
211 Jdb_tbuf::status()->kerncnts[Kern_cnt_io_fault]++;
212 #define CNT_TASK_CREATE \
213 Jdb_tbuf::status()->kerncnts[Kern_cnt_task_create]++;
214 #define CNT_SCHEDULE \
215 Jdb_tbuf::status()->kerncnts[Kern_cnt_schedule]++;
216 #define CNT_IOBMAP_TLB_FLUSH \
217 Jdb_tbuf::status()->kerncnts[Kern_cnt_iobmap_tlb_flush]++;
218 #define CNT_EXC_IPC \
219 Jdb_tbuf::status()->kerncnts[Kern_cnt_exc_ipc]++;
223 #define CNT_CONTEXT_SWITCH do { } while (0)
224 #define CNT_ADDR_SPACE_SWITCH do { } while (0)
225 #define CNT_SHORTCUT_FAILED do { } while (0)
226 #define CNT_SHORTCUT_SUCCESS do { } while (0)
227 #define CNT_IRQ do { } while (0)
228 #define CNT_IPC_LONG do { } while (0)
229 #define CNT_PAGE_FAULT do { } while (0)
230 #define CNT_IO_FAULT do { } while (0)
231 #define CNT_TASK_CREATE do { } while (0)
232 #define CNT_SCHEDULE do { } while (0)
233 #define CNT_IOBMAP_TLB_FLUSH do { } while (0)
234 #define CNT_EXC_IPC do { } while (0)
236 #endif // CONFIG_JDB && CONFIG_JDB_ACCOUNTING