30 class Tb_entry_formatter;
33 struct Tb_log_table_entry
37 Tb_entry_formatter *fmt;
40 extern Tb_log_table_entry _log_table[];
41 extern Tb_log_table_entry _log_table_end;
48 Mword _number; ///< event number
49 Address _ip; ///< instruction pointer
50 Unsigned64 _tsc; ///< time stamp counter
51 Context const *_ctx; ///< Context
52 Unsigned32 _pmc1; ///< performance counter value 1
53 Unsigned32 _pmc2; ///< performance counter value 2
54 Unsigned32 _kclock; ///< lower 32 bits of kernel clock
55 Unsigned8 _type; ///< type of entry
56 Unsigned8 _cpu; ///< CPU
58 static Mword (*rdcnt1)();
59 static Mword (*rdcnt2)();
65 Group_order() : _o(0) {} // not grouped
66 Group_order(unsigned v) : _o(2 + v) {}
67 static Group_order none() { return Group_order(); }
68 static Group_order last() { return Group_order(255, true); }
69 static Group_order first() { return Group_order(0); }
70 static Group_order direct() { return Group_order(1, true); }
72 bool not_grouped() const { return _o == 0; }
73 bool is_direct() const { return _o == 1; }
74 bool is_first() const { return _o == 2; }
75 bool is_last() const { return _o == 255; }
76 bool grouped() const { return _o >= 2; }
77 unsigned char depth() const { return _o - 2; }
80 Group_order(unsigned char v, bool) : _o(v) {}
84 Group_order has_partner() const { return Group_order::none(); }
85 Group_order is_partner(Tb_entry const *) const { return Group_order::none(); }
86 Mword partner() const { return 0; }
88 } __attribute__((__packed__, __aligned__(8)));
91 class Tb_entry_union : public Tb_entry
94 char _padding[Tb_entry_size - sizeof(Tb_entry)];
97 static_assert(sizeof(Tb_entry_union) == Tb_entry::Tb_entry_size,
98 "Tb_entry_union has the wrong size");
100 struct Tb_entry_empty : public Tb_entry
102 void print(String_buffer *) const {}
105 class Tb_entry_formatter
108 typedef Tb_entry::Group_order Group_order;
110 virtual void print(String_buffer *, Tb_entry const *e) const = 0;
111 virtual Group_order has_partner(Tb_entry const *e) const = 0;
112 virtual Group_order is_pair(Tb_entry const *e, Tb_entry const *n) const = 0;
113 virtual Mword partner(Tb_entry const *e) const = 0;
115 static Tb_entry_formatter const *get_fmt(Tb_entry const *e)
117 if (e->type() >= Tbuf_dynentries)
118 return _log_table[e->type() - Tbuf_dynentries].fmt;
120 return _fixed[e->type()];
124 static Tb_entry_formatter const *_fixed[];
128 template< typename T >
129 class Tb_entry_formatter_t : public Tb_entry_formatter
132 Tb_entry_formatter_t() {}
134 typedef T const *Const_ptr;
137 void print(String_buffer *buf, Tb_entry const *e) const
138 { static_cast<Const_ptr>(e)->print(buf); }
140 Group_order has_partner(Tb_entry const *e) const
141 { return static_cast<Const_ptr>(e)->has_partner(); }
143 Group_order is_pair(Tb_entry const *e, Tb_entry const *n) const
145 //assert (get_fmt(e) == &singleton);
147 if (&singleton == get_fmt(n))
148 return static_cast<Const_ptr>(e)->is_partner(static_cast<Const_ptr>(n));
149 return Tb_entry::Group_order::none();
152 Mword partner(Tb_entry const *e) const
153 { return static_cast<Const_ptr>(e)->partner(); }
155 static Tb_entry_formatter_t const singleton;
159 Tb_entry_formatter_t<T> const Tb_entry_formatter_t<T>::singleton;
163 class Tb_entry_ipc : public Tb_entry
166 L4_msg_tag _tag; ///< message tag
167 Mword _dword[2]; ///< first two message words
168 L4_obj_ref _dst; ///< destination id
171 L4_timeout_pair _timeout; ///< timeout
173 Tb_entry_ipc() : _timeout(0) {}
174 void print(String_buffer *buf) const;
177 /** logged ipc result. */
178 class Tb_entry_ipc_res : public Tb_entry
181 L4_msg_tag _tag; ///< message tag
182 Mword _dword[2]; ///< first two dwords
183 L4_error _result; ///< result
184 Mword _from; ///< receive descriptor
185 Mword _pair_event; ///< referred event
186 Unsigned8 _have_snd; ///< ipc had send part
187 Unsigned8 _is_np; ///< next period bit set
189 void print(String_buffer *buf) const;
192 /** logged ipc for user level tracing with Vampir. */
193 class Tb_entry_ipc_trace : public Tb_entry
196 Unsigned64 _snd_tsc; ///< entry tsc
197 L4_msg_tag _result; ///< result
198 L4_obj_ref _snd_dst; ///< send destination
199 Mword _rcv_dst; ///< rcv partner
203 void print(String_buffer *buf) const;
207 /** logged pagefault. */
208 class Tb_entry_pf : public Tb_entry
211 Address _pfa; ///< pagefault address
212 Mword _error; ///< pagefault error code
215 void print(String_buffer *buf) const;
218 /** logged kernel event. */
219 template<unsigned BASE_SIZE>
222 char msg[Tb_entry::Tb_entry_size - BASE_SIZE];
229 void set_const(char const *msg)
236 void set_buf(unsigned i, char c)
238 if (i < sizeof(msg) - 1)
239 msg[i] = c >= ' ' ? c : '.';
242 void term_buf(unsigned i)
244 msg[i < sizeof(msg) - 1 ? i : sizeof(msg) - 1] = '\0';
247 char const *str() const
249 return mptr.tag[0] == 0 && mptr.tag[1] == 1 ? mptr.ptr : msg;
253 class Tb_entry_ke : public Tb_entry
256 Tb_entry_msg<sizeof(Tb_entry)> msg;
257 void set(Context const *ctx, Address ip)
258 { set_global(Tbuf_ke, ctx, ip); }
261 class Tb_entry_ke_reg : public Tb_entry
265 Tb_entry_msg<sizeof(Tb_entry) + sizeof(v)> msg;
266 void set(Context const *ctx, Address ip)
267 { set_global(Tbuf_ke_reg, ctx, ip); }
270 /** logged breakpoint. */
271 class Tb_entry_bp : public Tb_entry
274 Address _address; ///< breakpoint address
275 int _len; ///< breakpoint length
276 Mword _value; ///< value at address
277 int _mode; ///< breakpoint mode
279 void print(String_buffer *buf) const;
282 /** logged binary kernel event. */
283 class Tb_entry_ke_bin : public Tb_entry
286 char _msg[Tb_entry_size - sizeof(Tb_entry)];
297 #include "entry_frame.h"
300 #include "trap_state.h"
303 PROTECTED static Mword Tb_entry::dummy_read_pmc() { return 0; }
305 Mword (*Tb_entry::rdcnt1)() = dummy_read_pmc;
306 Mword (*Tb_entry::rdcnt2)() = dummy_read_pmc;
307 Tb_entry_formatter const *Tb_entry_formatter::_fixed[Tbuf_dynentries];
312 Tb_entry_formatter::set_fixed(unsigned type, Tb_entry_formatter const *f)
314 if (type >= Tbuf_dynentries)
323 Tb_entry::set_rdcnt(int num, Mword (*f)())
330 case 0: rdcnt1 = f; break;
331 case 1: rdcnt2 = f; break;
338 { _type = Tbuf_unused; }
340 PUBLIC inline NEEDS["kip.h", "globals.h"]
342 Tb_entry::set_global(char type, Context const *ctx, Address ip)
347 _kclock = (Unsigned32)Kip::k()->clock;
348 _cpu = cxx::int_value<Cpu_number>(current_cpu());
354 { _type |= Tbuf_hidden; }
359 { _type &= ~Tbuf_hidden; }
368 Tb_entry::ctx() const
373 Tb_entry::type() const
374 { return _type & (Tbuf_max-1); }
378 Tb_entry::hidden() const
379 { return _type & Tbuf_hidden; }
383 Tb_entry::number() const
388 Tb_entry::number(Mword number)
389 { _number = number; }
394 { _pmc1 = rdcnt1(); }
399 { _pmc2 = rdcnt2(); }
403 Tb_entry::kclock() const
408 Tb_entry::cpu() const
413 Tb_entry::tsc() const
418 Tb_entry::pmc1() const
423 Tb_entry::pmc2() const
427 PUBLIC inline NEEDS ["entry_frame.h"]
429 Tb_entry_ipc::set(Context const *ctx, Mword ip, Syscall_frame *ipc_regs, Utcb *utcb,
430 Mword dbg_id, Unsigned64 left)
433 set_global(Tbuf_ipc, ctx, ip);
434 _dst = ipc_regs->ref();
435 _label = ipc_regs->from_spec();
440 _timeout = ipc_regs->timeout();
441 _tag = ipc_regs->tag();
443 Mword tmp0 = utcb->values[0];
444 Mword tmp1 = utcb->values[1];
451 Tb_entry_ipc::ipc_type() const
452 { return _dst.op(); }
456 Tb_entry_ipc::dbg_id() const
461 Tb_entry_ipc::dst() const
466 Tb_entry_ipc::timeout() const
471 Tb_entry_ipc::tag() const
476 Tb_entry_ipc::label() const
481 Tb_entry_ipc::dword(unsigned index) const
482 { return _dword[index]; }
485 PUBLIC inline NEEDS ["entry_frame.h"]
487 Tb_entry_ipc_res::set(Context const *ctx, Mword ip, Syscall_frame *ipc_regs,
489 Mword result, Mword pair_event, Unsigned8 have_snd,
492 set_global(Tbuf_ipc_res, ctx, ip);
494 Mword tmp0 = utcb->values[0];
495 Mword tmp1 = utcb->values[1];
498 _tag = ipc_regs->tag();
499 _pair_event = pair_event;
500 _result = L4_error::from_raw(result);
501 _from = ipc_regs->from_spec();
502 _have_snd = have_snd;
508 Tb_entry_ipc_res::have_snd() const
509 { return _have_snd; }
513 Tb_entry_ipc_res::is_np() const
518 Tb_entry_ipc_res::from() const
523 Tb_entry_ipc_res::result() const
528 Tb_entry_ipc_res::tag() const
533 Tb_entry_ipc_res::dword(unsigned index) const
534 { return _dword[index]; }
538 Tb_entry_ipc_res::pair_event() const
539 { return _pair_event; }
544 Tb_entry_ipc_trace::set(Context const *ctx, Mword ip, Unsigned64 snd_tsc,
545 L4_obj_ref const &snd_dst, Mword rcv_dst,
546 L4_msg_tag result, Unsigned8 snd_desc,
549 set_global(Tbuf_ipc_trace, ctx, ip);
554 _snd_desc = snd_desc;
555 _rcv_desc = rcv_desc;
560 Tb_entry_pf::set(Context const *ctx, Address ip, Address pfa,
561 Mword error, Space *spc)
563 set_global(Tbuf_pf, ctx, ip);
571 Tb_entry_pf::error() const
576 Tb_entry_pf::pfa() const
581 Tb_entry_pf::space() const
587 Tb_entry_bp::set(Context const *ctx, Address ip,
588 int mode, int len, Mword value, Address address)
590 set_global(Tbuf_breakpoint, ctx, ip);
601 Tb_entry_bp::mode() const
606 Tb_entry_bp::len() const
611 Tb_entry_bp::value() const
616 Tb_entry_bp::addr() const
622 Tb_entry_ke_bin::set(Context const *ctx, Address ip)
623 { set_global(Tbuf_ke_bin, ctx, ip); }
627 Tb_entry_ke_bin::set_buf(unsigned i, char c)
629 if (i < sizeof(_msg)-1)