15 Tbuf_shortcut_failed = 8,
16 Tbuf_shortcut_succeeded = 9,
17 Tbuf_context_switch = 10,
34 typedef unsigned Tb_entry_formatter(Tb_entry *e, int max, char *buf);
36 struct Tb_log_table_entry
40 Tb_entry_formatter *fmt;
43 extern Tb_log_table_entry _log_table[];
44 extern Tb_log_table_entry _log_table_end;
55 Mword _number; ///< event number
56 Address _ip; ///< instruction pointer
57 Context const *_ctx; ///< Context
58 Unsigned64 _tsc; ///< time stamp counter
59 Unsigned32 _pmc1; ///< performance counter value 1
60 Unsigned32 _pmc2; ///< performance counter value 2
61 Unsigned32 _kclock; ///< lower 32 bits of kernel clock
62 Unsigned8 _type; ///< type of entry
63 Unsigned8 _cpu; ///< CPU
65 static Mword (*rdcnt1)();
66 static Mword (*rdcnt2)();
67 } __attribute__((packed));
69 class Tb_entry : public Tb_entry_base
78 Align = __alignof__(T), //(sizeof(T) > sizeof(Mword)) ? sizeof(Mword) : sizeof(T),
79 Offset = sizeof(Tb_entry_base),
80 Payload_offset = ((Offset + Align -1) & ~(Align-1)) - Offset,
81 Total = Offset + Payload_offset + sizeof(T),
88 static void tb_entry_size_mismatch(TTI<false> const &) {}
89 static void payload_too_big(TTI<false> const &) {}
90 static void payload_too_big()
92 tb_entry_size_mismatch(TTI<(sizeof(Tb_entry) != Tb_entry_size)>());
93 payload_too_big(TTI<((int)Total > (int)Tb_entry_size)>());
99 template< typename T >
100 T *addr_of_payload() const
102 Payload_traits<T>::payload_too_big();
104 Address p = reinterpret_cast<Address>(_payload);
105 return reinterpret_cast<T*>(p + Payload_traits<T>::Payload_offset);
109 char _payload[Tb_entry_size-sizeof(Tb_entry_base)];
112 T *payload() { return addr_of_payload<T>(); }
115 T const *payload() const { return addr_of_payload<T>(); }
121 class Tb_entry_ipc : public Tb_entry
126 L4_msg_tag _tag; ///< message tag
127 Mword _dword[2]; ///< first two message words
128 L4_obj_ref _dst; ///< destination id
131 L4_timeout_pair _timeout; ///< timeout
135 /** logged ipc result. */
136 class Tb_entry_ipc_res : public Tb_entry
141 L4_msg_tag _tag; ///< message tag
142 Mword _dword[2]; ///< first two dwords
143 L4_error _result; ///< result
144 Mword _from; ///< receive descriptor
145 Mword _pair_event; ///< referred event
146 Unsigned8 _have_snd; ///< ipc had send part
147 Unsigned8 _is_np; ///< next period bit set
151 /** logged ipc for user level tracing with Vampir. */
152 class Tb_entry_ipc_trace : public Tb_entry
157 Unsigned64 _snd_tsc; ///< entry tsc
158 L4_msg_tag _result; ///< result
159 L4_obj_ref _snd_dst; ///< send destination
160 Mword _rcv_dst; ///< rcv partner
167 /** logged short-cut ipc failed. */
168 class Tb_entry_ipc_sfl : public Tb_entry_base
171 Global_id _from; ///< short ipc rcv descriptor
172 L4_timeout_pair _timeout; ///< ipc timeout
173 Global_id _dst; ///< partner
174 Unsigned8 _is_irq, _snd_lst, _dst_ok, _dst_lck, _preempt;
178 /** logged pagefault. */
179 class Tb_entry_pf : public Tb_entry
184 Address _pfa; ///< pagefault address
185 Mword _error; ///< pagefault error code
190 /** pagefault result. */
191 class Tb_entry_pf_res : public Tb_entry
203 /** logged kernel event. */
204 class Tb_entry_ke : public Tb_entry
206 enum { MSG_POINTER_PAYLOAD_OFFSET
207 = 5 - ((sizeof(Tb_entry_base) + 2 + 3) % sizeof(Mword)) };
210 /** logged breakpoint. */
211 class Tb_entry_bp : public Tb_entry
216 Address _address; ///< breakpoint address
217 int _len; ///< breakpoint length
218 Mword _value; ///< value at address
219 int _mode; ///< breakpoint mode
220 } __attribute__((packed));
223 /** logged context switch. */
224 class Tb_entry_ctx_sw : public Tb_entry
229 Context const *_dst; ///< switcher target
230 Context const *_dst_orig;
234 Sched_context *_from_sched;
236 } __attribute__((packed));
239 /** logged scheduling event. */
240 class Tb_entry_sched : public Tb_entry
245 unsigned short _mode;
246 Context const *_owner;
248 unsigned short _prio;
250 unsigned long _quantum;
251 } __attribute__((packed));
255 /** logged preemption */
256 class Tb_entry_preemption : public Tb_entry
266 /** logged binary kernel event. */
267 class Tb_entry_ke_bin : public Tb_entry
280 #include "entry_frame.h"
283 #include "static_init.h"
284 #include "trap_state.h"
287 PROTECTED static Mword Tb_entry_base::dummy_read_pmc() { return 0; }
289 Mword (*Tb_entry_base::rdcnt1)() = dummy_read_pmc;
290 Mword (*Tb_entry_base::rdcnt2)() = dummy_read_pmc;
295 Tb_entry::set_rdcnt(int num, Mword (*f)())
302 case 0: rdcnt1 = f; break;
303 case 1: rdcnt2 = f; break;
309 Tb_entry_base::clear()
310 { _type = Tbuf_unused; }
312 PUBLIC inline NEEDS["kip.h", "globals.h"]
314 Tb_entry_base::set_global(char type, Context const *ctx, Address ip)
319 _kclock = (Unsigned32)Kip::k()->clock;
320 _cpu = current_cpu();
325 Tb_entry_base::hide()
326 { _type |= Tbuf_hidden; }
330 Tb_entry_base::unhide()
331 { _type &= ~Tbuf_hidden; }
335 Tb_entry_base::ip() const
340 Tb_entry_base::ctx() const
345 Tb_entry_base::type() const
346 { return _type & (Tbuf_max-1); }
350 Tb_entry_base::hidden() const
351 { return _type & Tbuf_hidden; }
355 Tb_entry_base::number() const
360 Tb_entry_base::number(Mword number)
361 { _number = number; }
365 Tb_entry_base::rdpmc1()
366 { _pmc1 = rdcnt1(); }
370 Tb_entry_base::rdpmc2()
371 { _pmc2 = rdcnt2(); }
375 Tb_entry_base::kclock() const
380 Tb_entry_base::cpu() const
385 Tb_entry_base::tsc() const
390 Tb_entry_base::pmc1() const
395 Tb_entry_base::pmc2() const
399 PUBLIC inline NEEDS ["entry_frame.h"]
401 Tb_entry_ipc::set(Context const *ctx, Mword ip, Syscall_frame *ipc_regs, Utcb *utcb,
402 Mword dbg_id, Unsigned64 left)
404 set_global(Tbuf_ipc, ctx, ip);
405 Payload *p = payload<Payload>();
406 p->_dst = ipc_regs->ref();
407 p->_label = ipc_regs->from_spec();
412 p->_timeout = ipc_regs->timeout();
413 p->_tag = ipc_regs->tag();
414 if (ipc_regs->next_period())
416 p->_dword[0] = (Unsigned32)(left & 0xffffffff);
417 p->_dword[1] = (Unsigned32)(left >> 32);
422 register Mword tmp0 = utcb->values[0];
423 register Mword tmp1 = utcb->values[1];
431 Tb_entry_ipc::set_sc(Context const *ctx, Mword ip, Syscall_frame *ipc_regs,
432 Utcb *utcb, Unsigned64 left)
434 set_global(Tbuf_shortcut_succeeded, ctx, ip);
435 Payload *p = payload<Payload>();
436 p->_dst = ipc_regs->ref();
437 p->_timeout = ipc_regs->timeout();
438 if (ipc_regs->next_period())
440 p->_dword[0] = (Unsigned32)(left & 0xffffffff);
441 p->_dword[1] = (Unsigned32)(left >> 32);
446 register Mword tmp0 = utcb->values[0];
447 register Mword tmp1 = utcb->values[1];
456 Tb_entry_ipc::ipc_type() const
457 { return payload<Payload>()->_dst.op(); }
461 Tb_entry_ipc::dbg_id() const
462 { return payload<Payload>()->_dbg_id; }
466 Tb_entry_ipc::dst() const
467 { return payload<Payload>()->_dst; }
471 Tb_entry_ipc::timeout() const
472 { return payload<Payload>()->_timeout; }
476 Tb_entry_ipc::tag() const
477 { return payload<Payload>()->_tag; }
481 Tb_entry_ipc::label() const
482 { return payload<Payload>()->_label; }
486 Tb_entry_ipc::dword(unsigned index) const
487 { return payload<Payload>()->_dword[index]; }
490 PUBLIC inline NEEDS ["entry_frame.h"]
492 Tb_entry_ipc_res::set(Context const *ctx, Mword ip, Syscall_frame *ipc_regs,
494 Mword result, Mword pair_event, Unsigned8 have_snd,
497 set_global(Tbuf_ipc_res, ctx, ip);
498 Payload *p = payload<Payload>();
500 register Mword tmp0 = utcb->values[0];
501 register Mword tmp1 = utcb->values[1];
504 p->_tag = ipc_regs->tag();
505 p->_pair_event = pair_event;
506 p->_result = L4_error::from_raw(result);
507 p->_from = ipc_regs->from_spec();
508 p->_have_snd = have_snd;
514 Tb_entry_ipc_res::have_snd() const
515 { return payload<Payload>()->_have_snd; }
519 Tb_entry_ipc_res::is_np() const
520 { return payload<Payload>()->_is_np; }
524 Tb_entry_ipc_res::from() const
525 { return payload<Payload>()->_from; }
529 Tb_entry_ipc_res::result() const
530 { return payload<Payload>()->_result; }
534 Tb_entry_ipc_res::tag() const
535 { return payload<Payload>()->_tag; }
539 Tb_entry_ipc_res::dword(unsigned index) const
540 { return payload<Payload>()->_dword[index]; }
544 Tb_entry_ipc_res::pair_event() const
545 { return payload<Payload>()->_pair_event; }
550 Tb_entry_ipc_trace::set(Context const *ctx, Mword ip, Unsigned64 snd_tsc,
551 L4_obj_ref const &snd_dst, Mword rcv_dst,
552 L4_msg_tag result, Unsigned8 snd_desc,
555 set_global(Tbuf_ipc_trace, ctx, ip);
556 payload<Payload>()->_snd_tsc = snd_tsc;
557 payload<Payload>()->_snd_dst = snd_dst;
558 payload<Payload>()->_rcv_dst = rcv_dst;
559 payload<Payload>()->_result = result;
560 payload<Payload>()->_snd_desc = snd_desc;
561 payload<Payload>()->_rcv_desc = rcv_desc;
567 Tb_entry_ipc_sfl::set(Context *ctx, Mword ip,
569 L4_timeout_pair timeout, Global_id dst,
570 Unsigned8 is_irq, Unsigned8 snd_lst,
571 Unsigned8 dst_ok, Unsigned8 dst_lck,
574 set_global(Tbuf_shortcut_failed, ctx, ip);
575 Payload *p = payload<Payload>();
577 p->_timeout = timeout;
580 p->_snd_lst = snd_lst;
582 p->_dst_lck = dst_lck;
583 p->_preempt = preempt;
588 Tb_entry_ipc_sfl::timeout() const
593 Tb_entry_ipc_sfl::from() const
598 Tb_entry_ipc_sfl::dst() const
603 Tb_entry_ipc_sfl::is_irq() const
608 Tb_entry_ipc_sfl::snd_lst() const
613 Tb_entry_ipc_sfl::dst_ok() const
618 Tb_entry_ipc_sfl::dst_lck() const
623 Tb_entry_ipc_sfl::preempt() const
629 Tb_entry_pf::set(Context const *ctx, Address ip, Address pfa,
630 Mword error, Space *spc)
632 set_global(Tbuf_pf, ctx, ip);
633 Payload *p = payload<Payload>();
641 Tb_entry_pf::error() const
642 { return payload<Payload>()->_error; }
646 Tb_entry_pf::pfa() const
647 { return payload<Payload>()->_pfa; }
651 Tb_entry_pf::space() const
652 { return payload<Payload>()->_space; }
657 Tb_entry_pf_res::set(Context const *ctx, Address ip, Address pfa,
658 L4_error err, L4_error ret)
660 set_global(Tbuf_pf_res, ctx, ip);
661 Payload *p = payload<Payload>();
669 Tb_entry_pf_res::pfa() const
670 { return payload<Payload>()->_pfa; }
674 Tb_entry_pf_res::err() const
675 { return payload<Payload>()->_err; }
679 Tb_entry_pf_res::ret() const
680 { return payload<Payload>()->_ret; }
685 Tb_entry_bp::set(Context const *ctx, Address ip,
686 int mode, int len, Mword value, Address address)
688 set_global(Tbuf_breakpoint, ctx, ip);
689 payload<Payload>()->_mode = mode;
690 payload<Payload>()->_len = len;
691 payload<Payload>()->_value = value;
692 payload<Payload>()->_address = address;
699 Tb_entry_bp::mode() const
700 { return payload<Payload>()->_mode; }
704 Tb_entry_bp::len() const
705 { return payload<Payload>()->_len; }
709 Tb_entry_bp::value() const
710 { return payload<Payload>()->_value; }
714 Tb_entry_bp::addr() const
715 { return payload<Payload>()->_address; }
721 Tb_entry_ke::set(Context const *ctx, Address ip)
722 { set_global(Tbuf_ke, ctx, ip); }
726 Tb_entry_ke::set_const(Context const *ctx, Address ip, const char * const msg)
728 set_global(Tbuf_ke, ctx, ip);
729 char *_msg = payload<char>();
730 _msg[0] = 0; _msg[1] = 1;
731 *(char const ** const)(_msg + MSG_POINTER_PAYLOAD_OFFSET) = msg;
736 Tb_entry_ke::set_buf(unsigned i, char c)
738 char *_msg = payload<char>();
739 if (i < sizeof(_payload)-1)
740 _msg[i] = c >= ' ' ? c : '.';
745 Tb_entry_ke::term_buf(unsigned i)
747 char *_msg = payload<char>();
748 _msg[i < sizeof(_payload)-1 ? i : sizeof(_payload)-1] = '\0';
753 Tb_entry_ke::msg() const
755 char const *_msg = payload<char>();
756 return _msg[0] == 0 && _msg[1] == 1
757 ? *(char const ** const)(_msg + MSG_POINTER_PAYLOAD_OFFSET) : _msg;
763 Tb_entry_ctx_sw::set(Context const *ctx, Space *from_space, Address ip,
764 Context const *dst, Context const *dst_orig,
766 Sched_context *from_sched, Mword from_prio,
769 set_global(Tbuf_context_switch, ctx, ip);
770 payload<Payload>()->_kernel_ip = kernel_ip;
771 payload<Payload>()->_dst = dst;
772 payload<Payload>()->_dst_orig = dst_orig;
773 payload<Payload>()->_lock_cnt = lock_cnt;
774 payload<Payload>()->_from_space = from_space;
775 payload<Payload>()->_from_sched = from_sched;
776 payload<Payload>()->_from_prio = from_prio;
781 Tb_entry_ctx_sw::from_space() const
782 { return payload<Payload>()->_from_space; }
786 Tb_entry_ctx_sw::kernel_ip() const
787 { return payload<Payload>()->_kernel_ip; }
791 Tb_entry_ctx_sw::lock_cnt() const
792 { return payload<Payload>()->_lock_cnt; }
796 Tb_entry_ctx_sw::dst() const
797 { return payload<Payload>()->_dst; }
801 Tb_entry_ctx_sw::dst_orig() const
802 { return payload<Payload>()->_dst_orig; }
806 Tb_entry_ctx_sw::from_prio() const
807 { return payload<Payload>()->_from_prio; }
811 Tb_entry_ctx_sw::from_sched() const
812 { return payload<Payload>()->_from_sched; }
816 Tb_entry_sched::set (Context const *ctx, Address ip, unsigned short mode,
817 Context const *owner, unsigned short id, unsigned short prio,
818 signed long left, unsigned long quantum)
820 set_global (Tbuf_sched, ctx, ip);
821 payload<Payload>()->_mode = mode;
822 payload<Payload>()->_owner = owner;
823 payload<Payload>()->_id = id;
824 payload<Payload>()->_prio = prio;
825 payload<Payload>()->_left = left;
826 payload<Payload>()->_quantum = quantum;
831 Tb_entry_sched::mode() const
832 { return payload<Payload>()->_mode; }
836 Tb_entry_sched::owner() const
837 { return payload<Payload>()->_owner; }
841 Tb_entry_sched::id() const
842 { return payload<Payload>()->_id; }
846 Tb_entry_sched::prio() const
847 { return payload<Payload>()->_prio; }
851 Tb_entry_sched::quantum() const
852 { return payload<Payload>()->_quantum; }
856 Tb_entry_sched::left() const
857 { return payload<Payload>()->_left; }
861 Tb_entry_preemption::set (Context const *ctx, Mword preempter,
864 set_global (Tbuf_preemption, ctx, ip);
865 payload<Payload>()->_preempter = preempter;
870 Tb_entry_preemption::preempter() const
871 { return payload<Payload>()->_preempter; }
877 Tb_entry_ke_bin::set(Context const *ctx, Address ip)
878 { set_global(Tbuf_ke_bin, ctx, ip); }
882 Tb_entry_ke_bin::set_buf(unsigned i, char c)
884 char *_bin = payload<char>();
885 if (i < sizeof(_payload)-1)