1 // Inside Jdb the method Jdb::get_thread() should be used instead of
2 // Thread::current_thread(). The latter function cannot not handle the
3 // case when we came from the kernel stack context!
13 class Jdb_entry_frame;
22 Msr_test_fail_warn = 1,
23 Msr_test_fail_ignore = 2,
28 static Per_cpu<unsigned> apic_tpr;
29 static Pic::Status pic_status;
30 static volatile char msr_test;
31 static volatile char msr_fail;
35 s_unknown, s_ipc, s_syscall, s_pagefault, s_fputrap,
36 s_interrupt, s_timer_interrupt, s_slowtrap, s_user_invoke,
37 } Guessed_thread_state;
40 static int (*bp_test_log_only)();
41 static int (*bp_test_sstep)();
42 static int (*bp_test_break)(char *errbuf, size_t bufsize);
43 static int (*bp_test_other)(char *errbuf, size_t bufsize);
47 static char _connected;
48 static Per_cpu<char> permanent_single_step;
49 static Per_cpu<char> code_ret, code_call, code_bra, code_int;
53 SS_NONE=0, SS_BRANCH, SS_RETURN
56 static Per_cpu<Step_state> ss_state;
57 static Per_cpu<int> ss_level;
59 static const Unsigned8 *debug_ctrl_str;
60 static int debug_ctrl_len;
62 static Per_cpu<int> jdb_irqs_disabled;
65 IMPLEMENTATION [{amd64,ia32}-!serial]:
68 void Jdb::init_serial_console()
71 IMPLEMENTATION [{amd64,ia32}-serial]:
74 #include "kernel_uart.h"
77 void Jdb::init_serial_console()
79 if (Config::serial_esc == Config::SERIAL_ESC_IRQ &&
80 !Kernel_uart::uart()->failed())
84 if ((irq = Kernel_uart::uart()->irq()) == -1)
86 Config::serial_esc = Config::SERIAL_ESC_NOIRQ;
87 puts("SERIAL ESC: Using serial hack in slow timer handler.");
91 Kernel_uart::enable_rcv_irq();
92 printf("SERIAL ESC: allocated IRQ %d for serial uart\n", irq);
97 IMPLEMENTATION[ia32,amd64]:
105 #include "simpleio.h"
108 #include "boot_info.h"
109 #include "checksum.h"
112 #include "initcalls.h"
115 #include "jdb_core.h"
116 #include "jdb_screen.h"
117 #include "kernel_console.h"
118 #include "keycodes.h"
119 #include "kernel_uart.h"
120 #include "kernel_task.h"
122 #include "koptions.h"
124 #include "mem_layout.h"
126 #include "push_console.h"
127 #include "processor.h"
129 #include "static_init.h"
130 #include "terminate.h"
132 #include "thread_state.h"
134 #include "trap_state.h"
136 #include "watchdog.h"
138 char Jdb::_connected; // Jdb::init() was done
139 // explicit single_step command
140 Per_cpu<char> DEFINE_PER_CPU Jdb::permanent_single_step;
141 volatile char Jdb::msr_test; // = 1: trying to access an msr
142 volatile char Jdb::msr_fail; // = 1: MSR access failed
143 Per_cpu<char> DEFINE_PER_CPU Jdb::code_ret; // current instruction is ret/iret
144 Per_cpu<char> DEFINE_PER_CPU Jdb::code_call;// current instruction is call
145 Per_cpu<char> DEFINE_PER_CPU Jdb::code_bra; // current instruction is jmp/jxx
146 Per_cpu<char> DEFINE_PER_CPU Jdb::code_int; // current instruction is int x
148 // special single step state
149 Per_cpu<Jdb::Step_state> DEFINE_PER_CPU Jdb::ss_state;
150 Per_cpu<int> DEFINE_PER_CPU Jdb::ss_level; // current call level
152 const Unsigned8*Jdb::debug_ctrl_str; // string+length for remote control of
153 int Jdb::debug_ctrl_len; // Jdb via enter_kdebugger("*#");
155 Pic::Status Jdb::pic_status;
156 Per_cpu<unsigned> DEFINE_PER_CPU Jdb::apic_tpr;
157 Per_cpu<int> DEFINE_PER_CPU Jdb::jdb_irqs_disabled;
159 int (*Jdb::bp_test_log_only)();
160 int (*Jdb::bp_test_sstep)();
161 int (*Jdb::bp_test_break)(char *errbuf, size_t bufsize);
162 int (*Jdb::bp_test_other)(char *errbuf, size_t bufsize);
164 // available from the jdb_dump module
165 int jdb_dump_addr_task (Address addr, Space *task, int level)
166 __attribute__((weak));
169 STATIC_INITIALIZE_P(Jdb,JDB_INIT_PRIO);
172 IMPLEMENT FIASCO_INIT FIASCO_NOINLINE
175 if (Koptions::o()->opt(Koptions::F_nojdb))
178 if (Koptions::o()->opt(Koptions::F_jdb_never_stop))
181 init_serial_console();
183 Trap_state::base_handler = (Trap_state::Handler)enter_jdb;
185 // if esc_hack, serial_esc or watchdog enabled, set slow timer handler
186 Idt::set_vectors_run();
188 // disable lbr feature per default since it eats cycles on AMD Athlon boxes
189 Cpu::boot_cpu()->lbr_enable(false);
191 Kconsole::console()->register_console(push_cons());
193 Thread::set_int3_handler(handle_int3_threadctx);
196 Thread::may_enter_jdb = true;
199 PUBLIC static inline bool
205 PROTECTED static inline
206 template< typename T >
208 Jdb::set_monitored_address(T *dest, T val)
213 PROTECTED static inline
214 template< typename T >
216 Jdb::monitor_address(unsigned current_cpu, T *addr)
218 if (!*addr && Cpu::cpus.cpu(current_cpu).has_monitor_mwait())
220 asm volatile ("monitor \n" : : "a"(addr), "c"(0), "d"(0) );
221 Mword irq_sup = Cpu::cpus.cpu(current_cpu).has_monitor_mwait_irq() ? 1 : 0;
222 asm volatile ("mwait \n" : : "a"(0x00), "c"(irq_sup) );
231 template <typename T> T
232 Jdb::peek(T const *addr)
238 template <typename T> T
239 Jdb::peek(T const *addr, Address_type)
241 // on IA32 we can touch directly into the user-space
254 static Per_cpu<Proc::Status> DEFINE_PER_CPU jdb_saved_flags;
256 // disable interrupts before entering the kernel debugger
259 Jdb::save_disable_irqs(unsigned cpu)
261 if (!jdb_irqs_disabled.cpu(cpu)++)
263 // save interrupt flags
264 jdb_saved_flags.cpu(cpu) = Proc::cli_save();
269 pic_status = Pic::disable_all_save();
270 if (Config::getchar_does_hlt && Config::getchar_does_hlt_works_ok)
273 if (Io_apic::active() && Apic::is_present())
275 apic_tpr.cpu(cpu) = Apic::tpr();
276 Apic::tpr(APIC_IRQ_BASE - 0x10);
279 if (cpu == 0 && Config::getchar_does_hlt && Config::getchar_does_hlt_works_ok)
281 // set timer interrupt does nothing than wakeup from hlt
282 Idt::set_vectors_stop();
288 if (cpu == 0 && Config::getchar_does_hlt && Config::getchar_does_hlt_works_ok)
289 // explicit enable interrupts because the timer interrupt is
290 // needed to wakeup from "hlt" state in getchar(). All other
291 // interrupts are disabled at the pic.
295 // restore interrupts after leaving the kernel debugger
298 Jdb::restore_irqs(unsigned cpu)
300 if (!--jdb_irqs_disabled.cpu(cpu))
304 if (Io_apic::active() && Apic::is_present())
305 Apic::tpr(apic_tpr.cpu(cpu));
309 Pic::restore_all(Jdb::pic_status);
313 // reset timer interrupt vector
314 if (cpu == 0 && Config::getchar_does_hlt && Config::getchar_does_hlt_works_ok)
315 Idt::set_vectors_run();
317 // reset interrupt flags
318 Proc::sti_restore(jdb_saved_flags.cpu(cpu));
325 Jdb::get_register(char *reg)
335 putchar(reg_name.c[0] = Jdb_screen::Reg_prefix);
342 putchar(reg_name.c[i] = c & 0xdf);
345 reg_name.c[3] = '\0';
348 if (reg_name.v == *((unsigned*)(Jdb_screen::Reg_names[i])))
361 On_dbg_stack(Mword sp) : sp(sp) {}
362 bool operator () (unsigned cpu) const
364 Thread::Dbg_stack const &st = Thread::dbg_stack.cpu(cpu);
365 return sp <= Mword(st.stack_top)
366 && sp >= Mword(st.stack_top) - Thread::Dbg_stack::Stack_size;
370 // Do thread lookup using Trap_state. In contrast to Thread::current_thread()
371 // this function can also handle cases where we entered from kernel stack
372 // context. We _never_ return 0!
375 Jdb::get_thread(unsigned cpu)
377 Jdb_entry_frame *entry_frame = Jdb::entry_frame.cpu(cpu);
378 Address sp = (Address) entry_frame;
380 // special case since we come from the double fault handler stack
381 if (entry_frame->_trapno == 8 && !(entry_frame->cs() & 3))
382 sp = entry_frame->sp(); // we can trust esp since it comes from main_tss
384 if (foreach_cpu(On_dbg_stack(sp), false))
387 if (sp >= boot_stack - 8192 && sp <= boot_stack + 8192)
390 return static_cast<Thread*>(context_of((const void*)sp));
395 Jdb::translate_task(Address addr, Space *task)
397 return (Kmem::is_kmem_page_fault(addr, 0)) ? 0 : task;
402 Jdb::peek_phys(Address phys, void *value, int width)
404 assert(!(phys & (width-1)));
406 Address virt = Kmem::map_phys_page_tmp(phys, 0);
408 memcpy(value, (void*)virt, width);
413 Jdb::poke_phys(Address phys, void const *value, int width)
415 assert(!(phys & (width-1)));
417 Address virt = Kmem::map_phys_page_tmp(phys, 0);
419 memcpy((void*)virt, value, width);
425 Jdb::peek_task(Address addr, Space *task, void *value, int width)
429 if (!task && Kmem::is_kmem_page_fault(addr, 0))
431 // address of kernel directory
433 asm volatile ("mov %%cr3, %0" : "=r" (pdbr));
434 Pdir *kdir = (Pdir*)Mem_layout::phys_to_pmem(pdbr);
435 Pdir::Iter i = kdir->walk(Virt_addr(addr));
438 memcpy(value, (void*)addr, width);
442 // specific address space, use temporary mapping
447 // user address, use temporary mapping
448 phys = Address(task->mem_space()->virt_to_phys (addr));
451 phys = task->mem_space()->virt_to_phys_s0 ((void*)addr);
457 peek_phys(phys, value, width);
463 Jdb::poke_task(Address addr, Space *task, void const *value, int width)
467 if (task && Kmem::is_kmem_page_fault(addr, 0))
470 asm volatile ("mov %%cr3, %0" : "=r" (pdbr));
471 Pdir *kdir = (Pdir*)Mem_layout::phys_to_pmem(pdbr);
472 Pdir::Iter i = kdir->walk(Virt_addr(addr));
475 memcpy((void*)addr, value, width);
484 // user address, use temporary mapping
485 phys = Address(task->mem_space()->virt_to_phys (addr));
488 phys = task->mem_space()->virt_to_phys_s0 ((void*)addr);
494 poke_phys(phys, value, width);
498 // The content of apdapter memory is not shown by default because reading
499 // memory-mapped I/O registers may confuse the hardware. We assume that all
500 // memory above the end of the RAM is adapter memory.
503 Jdb::is_adapter_memory(Address virt, Space *task)
510 else if ( !Kmem::is_io_bitmap_page_fault(virt)
511 && Kmem::is_kmem_page_fault(virt, 0))
513 phys = Kmem::virt_to_phys((const void*)virt);
516 phys = task->mem_space()->virt_to_phys_s0((void*)virt);
521 Mem_desc *m = Kip::k()->mem_descs();
522 Mem_desc *e = m + Kip::k()->num_mem_descs();
524 if (m->type() == Mem_desc::Conventional && !m->is_virtual()
525 && m->start() <= phys && m->end() >= phys)
531 #define WEAK __attribute__((weak))
532 extern "C" char in_slowtrap, in_page_fault, in_handle_fputrap;
533 extern "C" char in_interrupt, in_timer_interrupt, in_timer_interrupt_slow;
534 extern "C" char i30_ret_switch WEAK, se_ret_switch WEAK, in_slow_ipc1 WEAK;
535 extern "C" char in_slow_ipc2 WEAK, in_slow_ipc4;
536 extern "C" char in_slow_ipc5, in_sc_ipc1 WEAK;
537 extern "C" char in_sc_ipc2 WEAK, in_syscall WEAK;
540 // Try to guess the thread state of t by walking down the kernel stack and
541 // locking at the first return address we find.
543 Jdb::Guessed_thread_state
544 Jdb::guess_thread_state(Thread *t)
546 Guessed_thread_state state = s_unknown;
547 Mword *ktop = (Mword*)((Mword)context_of(t->get_kernel_sp()) +
548 Config::thread_block_size);
550 for (int i=-1; i>-26; i--)
554 if (ktop[i] == (Mword)&in_page_fault)
556 if ((ktop[i] == (Mword)&i30_ret_switch) ||// shortcut.S, int 0x30
557 (ktop[i] == (Mword)&in_slow_ipc1) || // shortcut.S, int 0x30
558 (ktop[i] == (Mword)&se_ret_switch) || // shortcut.S, sysenter
559 (ktop[i] == (Mword)&in_slow_ipc2) || // shortcut.S, sysenter
560 (ktop[i] == (Mword)&in_slow_ipc4) || // entry.S, int 0x30 log
561 (ktop[i] == (Mword)&in_slow_ipc5) || // entry.S, sysenter log
562 #if defined (CONFIG_JDB_LOGGING) || !defined(CONFIG_ASSEMBLER_IPC_SHORTCUT)
563 (ktop[i] == (Mword)&in_sc_ipc1) || // entry.S, int 0x30
564 (ktop[i] == (Mword)&in_sc_ipc2) || // entry.S, sysenter
568 else if (ktop[i] == (Mword)&in_syscall)
570 else if (ktop[i] == (Mword)&Thread::user_invoke)
571 state = s_user_invoke;
572 else if (ktop[i] == (Mword)&in_handle_fputrap)
574 else if (ktop[i] == (Mword)&in_interrupt)
576 else if ((ktop[i] == (Mword)&in_timer_interrupt) ||
577 (ktop[i] == (Mword)&in_timer_interrupt_slow))
578 state = s_timer_interrupt;
579 else if (ktop[i] == (Mword)&in_slowtrap)
581 if (state != s_unknown)
586 if (state == s_unknown && (t->state(false) & Thread_ipc_mask))
594 Jdb::set_single_step(unsigned cpu, int on)
597 entry_frame.cpu(cpu)->flags(entry_frame.cpu(cpu)->flags() | EFLAGS_TF);
599 entry_frame.cpu(cpu)->flags(entry_frame.cpu(cpu)->flags() & ~EFLAGS_TF);
601 permanent_single_step.cpu(cpu) = on;
606 Jdb::handle_special_cmds(int c)
608 foreach_cpu(&analyze_code);
612 case 'j': // do restricted "go"
613 switch (putchar(c=getchar()))
615 case 'b': // go until next branch
616 case 'r': // go until current function returns
617 ss_level.cpu(current_cpu) = 0;
618 if (code_call.cpu(current_cpu))
620 // increase call level because currently we
621 // stay on a call instruction
622 ss_level.cpu(current_cpu)++;
624 ss_state.cpu(current_cpu) = (c == 'b') ? SS_BRANCH : SS_RETURN;
625 // if we have lbr feature, the processor treats the single
626 // step flag as step on branches instead of step on instruction
627 Cpu::boot_cpu()->btf_enable(true);
629 case 's': // do one single step
630 entry_frame.cpu(current_cpu)->flags(entry_frame.cpu(current_cpu)->flags() | EFLAGS_TF);
631 hide_statline = false;
640 // ignore character and get next input
649 IMPLEMENTATION[ia32]:
651 // take a look at the code of the current thread eip
652 // set global indicators code_call, code_ret, code_bra, code_int
653 // This can fail if the current page is still not mapped
655 Jdb::analyze_code(unsigned cpu)
657 Jdb_entry_frame *entry_frame = Jdb::entry_frame.cpu(cpu);
658 Space *task = get_task(cpu);
659 // do nothing if page not mapped into this address space
660 if (entry_frame->ip()+1 > Kmem::user_max())
665 if ( !peek((Unsigned8*)entry_frame->ip(), task, op1)
666 || !peek((Unsigned8*)(entry_frame->ip()+1), task, op2))
669 if (op1 != 0x0f && op1 != 0xff)
673 ( ((op1 & 0xf6) == 0xc2) // ret/lret /xxxx
674 || (op1 == 0xcf)); // iret
677 ( (op1 == 0xe8) // call near
679 && ((op2 & 0x30) == 0x10)) // call/lcall *(...)
680 || (op1 == 0x9a)); // lcall xxxx:xxxx
683 ( ((op1 & 0xfc) == 0xe0) // loop/jecxz
684 || ((op1 & 0xf0) == 0x70) // jxx rel 8 bit
685 || (op1 == 0xeb) // jmp rel 8 bit
686 || (op1 == 0xe9) // jmp rel 16/32 bit
688 && ((op2 & 0xf0) == 0x80)) // jxx rel 16/32 bit
690 && ((op2 & 0x30) == 0x20)) // jmp/ljmp *(...)
691 || (op1 == 0xea)); // ljmp xxxx:xxxx
694 ( (op1 == 0xcc) // int3
695 || (op1 == 0xcd) // int xx
696 || (op1 == 0xce)); // into
699 IMPLEMENTATION[amd64]:
702 Jdb::analyze_code(unsigned)
705 IMPLEMENTATION[ia32,amd64]:
707 // entered debugger because of single step trap
708 static inline NOEXPORT int
709 Jdb::handle_single_step(unsigned cpu)
711 int really_break = 1;
715 Cpu const &ccpu = Cpu::cpus.cpu(cpu);
717 // special single_step ('j' command): go until branch/return
718 if (ss_state.cpu(cpu) != SS_NONE)
720 if (ccpu.lbr_type() != Cpu::Lbr_unsupported)
722 // don't worry, the CPU always knows what she is doing :-)
726 // we have to emulate lbr looking at the code ...
727 switch (ss_state.cpu(cpu))
730 // go until function return
732 if (code_call.cpu(cpu))
734 // increase call level
737 else if (code_ret.cpu(cpu))
739 // decrease call level
740 really_break = (ss_level.cpu(cpu)-- == 0);
745 // go until next branch
746 really_break = (code_ret.cpu(cpu) || code_call.cpu(cpu) || code_bra.cpu(cpu) || code_int.cpu(cpu));
754 ss_state.cpu(cpu) = SS_NONE;
755 snprintf(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0)), "%s", "Branch/Call");
758 else // (ss_state == SS_NONE)
759 // regular single_step
760 snprintf(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0)), "%s", "Singlestep");
765 // entered debugger due to debug exception
766 static inline NOEXPORT int
767 Jdb::handle_trap1(unsigned cpu)
769 // FIXME: currently only on bot cpu
773 if (bp_test_sstep && bp_test_sstep())
774 return handle_single_step(cpu);
777 && bp_test_break(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0))))
781 && bp_test_other(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0))))
787 // entered debugger due to software breakpoint
788 static inline NOEXPORT int
789 Jdb::handle_trap3(unsigned cpu)
791 Jdb_entry_frame *entry_frame = Jdb::entry_frame.cpu(cpu);
792 Space *task = get_task(cpu);
796 snprintf(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0)), "%s", "INT 3");
797 if ( !peek((Unsigned8*)entry_frame->ip(), task, op)
798 || !peek((Unsigned8*)(entry_frame->ip()+1), task, len)
802 char const *msg = (char const*)(entry_frame->ip()+2);
804 if (!peek(msg, task, buffer[0]))
807 if (len > 1 && !peek(msg+1, task, buffer[1]))
810 // we are entering here because enter_kdebugger("*#..."); failed
811 if (len > 1 && buffer[0] == '*' && buffer[1] == '#')
818 if (len && peek(msg, task, buffer[2]))
821 if (buffer[2] == '#')
823 // the ``-jdb_cmd='' sequence
824 msg = (char const*)entry_frame->value();
825 for (i=0; i<sizeof(ctrl)-1 && peek(msg, task, tmp) && tmp; i++, msg++)
830 // a ``enter_kdebug("*#")'' sequence
831 for (i=0; i<sizeof(ctrl)-1 && i<len && peek(msg, task, tmp); i++, msg++)
835 snprintf(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0)),
836 "invalid ctrl sequence \"%s\"", ctrl);
839 // enter_kdebugger("...");
843 len = len < 47 ? len : 47;
844 len = len < sizeof(error_buffer.cpu(0))-1
846 : sizeof(error_buffer.cpu(0))-1;
848 for(i=0; i<len && peek(msg+i, task, buffer[0]); i++)
849 error_buffer.cpu(cpu)[i] = buffer[0];
850 error_buffer.cpu(cpu)[i]='\0';
856 // entered debugger due to other exception
857 static inline NOEXPORT int
858 Jdb::handle_trapX(unsigned cpu)
860 unsigned pos = snprintf(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0)), "%s",
861 Cpu::exception_string(entry_frame.cpu(cpu)->_trapno)) + 1;
862 if ( pos < sizeof(error_buffer.cpu(0))
863 && entry_frame.cpu(cpu)->_trapno >= 10
864 && entry_frame.cpu(cpu)->_trapno <= 14)
865 snprintf(error_buffer.cpu(cpu)+pos, sizeof(error_buffer.cpu(0))-pos,
866 "(ERR="L4_PTR_FMT")", entry_frame.cpu(cpu)->_err);
871 /** Int3 debugger interface. This function is called immediately
872 * after entering the kernel debugger.
873 * @return 1 if command was successfully interpreted
877 Jdb::handle_user_request(unsigned cpu)
879 Jdb_entry_frame *entry_frame = Jdb::entry_frame.cpu(cpu);
881 if (entry_frame->_trapno == 3)
883 Space *task = get_task(cpu);
885 if (!peek((Unsigned8*)entry_frame->ip(), task, todo))
888 // jmp == enter_kdebug()
892 if (!peek((Unsigned8*)(entry_frame->ip()+1), task, len))
895 char const *str = (char const *)(entry_frame->ip()+2);
901 if (!peek(str, task, tmp) || tmp !='*')
904 if (!peek(str+1, task, tmp) || tmp != '#')
909 if (peek(str+2, task, tmp) && tmp == '#')
910 ret = execute_command_ni(task, (char const *)entry_frame->value());
912 ret = execute_command_ni(task, str+2, len-2);
918 else if (todo == 0x3c)
920 if (!peek((Unsigned8*)(entry_frame->ip()+1), task, todo))
926 if (entry_frame->value() == 3)
929 execute_command("Tgzip");
942 Jdb::enter_trap_handler(unsigned cpu)
943 { Cpu::cpus.cpu(cpu).debugctl_disable(); }
947 Jdb::leave_trap_handler(unsigned cpu)
948 { Cpu::cpus.cpu(cpu).debugctl_enable(); }
952 Jdb::handle_conditional_breakpoint(unsigned cpu)
953 { return entry_frame.cpu(cpu)->_trapno == 1 && bp_test_log_only && bp_test_log_only(); }
957 Jdb::handle_nested_trap(Jdb_entry_frame *e)
959 // re-enable interrupts if we need them because they are disabled
960 if (Config::getchar_does_hlt && Config::getchar_does_hlt_works_ok)
966 cursor(Jdb_screen::height(), 1);
967 printf("\nNMI occured\n");
970 cursor(Jdb_screen::height(), 1);
971 printf("\nSoftware breakpoint inside jdb at "L4_PTR_FMT"\n",
977 case Msr_test_fail_warn:
978 printf(" MSR does not exist or invalid value\n");
979 msr_test = Msr_test_default;
982 case Msr_test_fail_ignore:
983 msr_test = Msr_test_default;
987 cursor(Jdb_screen::height(), 1);
988 printf("\nGeneral Protection (eip="L4_PTR_FMT","
989 " err="L4_PTR_FMT") -- jdb bug?\n",
995 cursor(Jdb_screen::height(), 1);
996 printf("\nInvalid access (trap=%02lx err="L4_PTR_FMT
997 " pfa="L4_PTR_FMT" eip="L4_PTR_FMT") "
999 e->_trapno, e->_err, e->_cr2, e->ip());
1006 Jdb::handle_debug_traps(unsigned cpu)
1008 bool really_break = true;
1010 if (entry_frame.cpu(cpu)->_trapno == 1)
1011 really_break = handle_trap1(cpu);
1012 else if (entry_frame.cpu(cpu)->_trapno == 3)
1013 really_break = handle_trap3(cpu);
1015 really_break = handle_trapX(cpu);
1019 for (unsigned i = 0; i < Config::Max_num_cpus; ++i)
1021 if (!Cpu::online(i) || !running.cpu(i))
1024 if (!permanent_single_step.cpu(i))
1025 entry_frame.cpu(i)->flags(entry_frame.cpu(i)->flags() & ~EFLAGS_TF);
1029 return really_break;
1034 Jdb::test_checksums()
1035 { return Boot_info::get_checksum_ro() == Checksum::get_checksum_ro(); }
1037 PUBLIC static inline
1039 Jdb::enter_getchar()
1042 PUBLIC static inline
1044 Jdb::leave_getchar()
1048 //----------------------------------------------------------------------------
1049 IMPLEMENTATION [(ia32 || amd64) && mp]:
1053 Jdb::send_nmi(unsigned cpu)
1055 Apic::mp_send_ipi(Cpu::cpus.cpu(cpu).phys_id(), 0, Apic::APIC_IPI_NMI);