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 "timer_tick.h"
135 #include "trap_state.h"
137 #include "watchdog.h"
139 char Jdb::_connected; // Jdb::init() was done
140 // explicit single_step command
141 DEFINE_PER_CPU Per_cpu<char> Jdb::permanent_single_step;
142 volatile char Jdb::msr_test; // = 1: trying to access an msr
143 volatile char Jdb::msr_fail; // = 1: MSR access failed
144 DEFINE_PER_CPU Per_cpu<char> Jdb::code_ret; // current instruction is ret/iret
145 DEFINE_PER_CPU Per_cpu<char> Jdb::code_call;// current instruction is call
146 DEFINE_PER_CPU Per_cpu<char> Jdb::code_bra; // current instruction is jmp/jxx
147 DEFINE_PER_CPU Per_cpu<char> Jdb::code_int; // current instruction is int x
149 // special single step state
150 DEFINE_PER_CPU Per_cpu<Jdb::Step_state> Jdb::ss_state;
151 DEFINE_PER_CPU Per_cpu<int> Jdb::ss_level; // current call level
153 const Unsigned8*Jdb::debug_ctrl_str; // string+length for remote control of
154 int Jdb::debug_ctrl_len; // Jdb via enter_kdebugger("*#");
156 Pic::Status Jdb::pic_status;
157 DEFINE_PER_CPU Per_cpu<unsigned> Jdb::apic_tpr;
158 DEFINE_PER_CPU Per_cpu<int> Jdb::jdb_irqs_disabled;
160 int (*Jdb::bp_test_log_only)();
161 int (*Jdb::bp_test_sstep)();
162 int (*Jdb::bp_test_break)(char *errbuf, size_t bufsize);
163 int (*Jdb::bp_test_other)(char *errbuf, size_t bufsize);
165 // available from the jdb_dump module
166 int jdb_dump_addr_task (Address addr, Space *task, int level)
167 __attribute__((weak));
170 STATIC_INITIALIZE_P(Jdb,JDB_INIT_PRIO);
173 IMPLEMENT FIASCO_INIT FIASCO_NOINLINE
176 if (Koptions::o()->opt(Koptions::F_nojdb))
179 if (Koptions::o()->opt(Koptions::F_jdb_never_stop))
182 init_serial_console();
184 Trap_state::base_handler = (Trap_state::Handler)enter_jdb;
186 // if esc_hack, serial_esc or watchdog enabled, set slow timer handler
187 Idt::set_vectors_run();
189 // disable lbr feature per default since it eats cycles on AMD Athlon boxes
190 Cpu::boot_cpu()->lbr_enable(false);
192 Kconsole::console()->register_console(push_cons());
194 Thread::set_int3_handler(handle_int3_threadctx);
197 Thread::may_enter_jdb = true;
200 PUBLIC static inline bool
206 PROTECTED static inline
207 template< typename T >
209 Jdb::set_monitored_address(T *dest, T val)
214 PROTECTED static inline
215 template< typename T >
217 Jdb::monitor_address(unsigned current_cpu, T *addr)
219 if (!*addr && Cpu::cpus.cpu(current_cpu).has_monitor_mwait())
221 asm volatile ("monitor \n" : : "a"(addr), "c"(0), "d"(0) );
222 Mword irq_sup = Cpu::cpus.cpu(current_cpu).has_monitor_mwait_irq() ? 1 : 0;
223 asm volatile ("mwait \n" : : "a"(0x00), "c"(irq_sup) );
232 template <typename T> T
233 Jdb::peek(T const *addr)
239 template <typename T> T
240 Jdb::peek(T const *addr, Address_type)
242 // on IA32 we can touch directly into the user-space
255 DEFINE_PER_CPU static Per_cpu<Proc::Status> jdb_saved_flags;
257 // disable interrupts before entering the kernel debugger
260 Jdb::save_disable_irqs(unsigned cpu)
262 if (!jdb_irqs_disabled.cpu(cpu)++)
264 // save interrupt flags
265 jdb_saved_flags.cpu(cpu) = Proc::cli_save();
270 pic_status = Pic::disable_all_save();
271 if (Config::getchar_does_hlt_works_ok)
272 Timer_tick::disable(0);
274 if (Io_apic::active() && Apic::is_present())
276 apic_tpr.cpu(cpu) = Apic::tpr();
277 Apic::tpr(APIC_IRQ_BASE - 0x10);
280 if (cpu == 0 && Config::getchar_does_hlt_works_ok)
282 // set timer interrupt does nothing than wakeup from hlt
283 Timer_tick::set_vectors_stop();
284 Timer_tick::enable(0);
289 if (cpu == 0 && Config::getchar_does_hlt_works_ok)
290 // explicit enable interrupts because the timer interrupt is
291 // needed to wakeup from "hlt" state in getchar(). All other
292 // interrupts are disabled at the pic.
296 // restore interrupts after leaving the kernel debugger
299 Jdb::restore_irqs(unsigned cpu)
301 if (!--jdb_irqs_disabled.cpu(cpu))
305 if (Io_apic::active() && Apic::is_present())
306 Apic::tpr(apic_tpr.cpu(cpu));
310 Pic::restore_all(Jdb::pic_status);
314 // reset timer interrupt vector
315 if (cpu == 0 && Config::getchar_does_hlt_works_ok)
316 Idt::set_vectors_run();
318 // reset interrupt flags
319 Proc::sti_restore(jdb_saved_flags.cpu(cpu));
327 On_dbg_stack(Mword sp) : sp(sp) {}
328 bool operator () (unsigned cpu) const
330 Thread::Dbg_stack const &st = Thread::dbg_stack.cpu(cpu);
331 return sp <= Mword(st.stack_top)
332 && sp >= Mword(st.stack_top) - Thread::Dbg_stack::Stack_size;
336 // Do thread lookup using Trap_state. In contrast to Thread::current_thread()
337 // this function can also handle cases where we entered from kernel stack
338 // context. We _never_ return 0!
341 Jdb::get_thread(unsigned cpu)
343 Jdb_entry_frame *entry_frame = Jdb::entry_frame.cpu(cpu);
344 Address sp = (Address) entry_frame;
346 // special case since we come from the double fault handler stack
347 if (entry_frame->_trapno == 8 && !(entry_frame->cs() & 3))
348 sp = entry_frame->sp(); // we can trust esp since it comes from main_tss
350 if (foreach_cpu(On_dbg_stack(sp), false))
353 if (!Helping_lock::threading_system_active)
356 return static_cast<Thread*>(context_of((const void*)sp));
361 Jdb::translate_task(Address addr, Space *task)
363 return (Kmem::is_kmem_page_fault(addr, 0)) ? 0 : task;
368 Jdb::peek_phys(Address phys, void *value, int width)
370 assert(!(phys & (width-1)));
372 Address virt = Kmem::map_phys_page_tmp(phys, 0);
374 memcpy(value, (void*)virt, width);
379 Jdb::poke_phys(Address phys, void const *value, int width)
381 assert(!(phys & (width-1)));
383 Address virt = Kmem::map_phys_page_tmp(phys, 0);
385 memcpy((void*)virt, value, width);
391 Jdb::peek_task(Address addr, Space *task, void *value, int width)
395 if (!task && Kmem::is_kmem_page_fault(addr, 0))
397 // address of kernel directory
399 asm volatile ("mov %%cr3, %0" : "=r" (pdbr));
400 Pdir *kdir = (Pdir*)Mem_layout::phys_to_pmem(pdbr);
401 Pdir::Iter i = kdir->walk(Virt_addr(addr));
404 memcpy(value, (void*)addr, width);
408 // specific address space, use temporary mapping
413 // user address, use temporary mapping
414 phys = Address(task->virt_to_phys (addr));
417 phys = task->virt_to_phys_s0((void*)addr);
423 peek_phys(phys, value, width);
429 Jdb::poke_task(Address addr, Space *task, void const *value, int width)
433 if (task && Kmem::is_kmem_page_fault(addr, 0))
436 asm volatile ("mov %%cr3, %0" : "=r" (pdbr));
437 Pdir *kdir = (Pdir*)Mem_layout::phys_to_pmem(pdbr);
438 Pdir::Iter i = kdir->walk(Virt_addr(addr));
441 memcpy((void*)addr, value, width);
450 // user address, use temporary mapping
451 phys = Address(task->virt_to_phys(addr));
454 phys = task->virt_to_phys_s0((void*)addr);
460 poke_phys(phys, value, width);
464 // The content of apdapter memory is not shown by default because reading
465 // memory-mapped I/O registers may confuse the hardware. We assume that all
466 // memory above the end of the RAM is adapter memory.
469 Jdb::is_adapter_memory(Address virt, Space *task)
476 else if ( !Kmem::is_io_bitmap_page_fault(virt)
477 && Kmem::is_kmem_page_fault(virt, 0))
479 phys = Kmem::virt_to_phys((const void*)virt);
482 phys = task->virt_to_phys_s0((void*)virt);
487 Mem_desc *m = Kip::k()->mem_descs();
488 Mem_desc *e = m + Kip::k()->num_mem_descs();
490 if (m->type() == Mem_desc::Conventional && !m->is_virtual()
491 && m->start() <= phys && m->end() >= phys)
497 #define WEAK __attribute__((weak))
498 extern "C" char in_slowtrap, in_page_fault, in_handle_fputrap;
499 extern "C" char in_interrupt, in_timer_interrupt, in_timer_interrupt_slow;
500 extern "C" char i30_ret_switch WEAK, se_ret_switch WEAK, in_slow_ipc1 WEAK;
501 extern "C" char in_slow_ipc2 WEAK, in_slow_ipc4;
502 extern "C" char in_slow_ipc5, in_sc_ipc1 WEAK;
503 extern "C" char in_sc_ipc2 WEAK, in_syscall WEAK;
506 // Try to guess the thread state of t by walking down the kernel stack and
507 // locking at the first return address we find.
509 Jdb::Guessed_thread_state
510 Jdb::guess_thread_state(Thread *t)
512 Guessed_thread_state state = s_unknown;
513 Mword *ktop = (Mword*)((Mword)context_of(t->get_kernel_sp()) +
516 for (int i=-1; i>-26; i--)
520 if (ktop[i] == (Mword)&in_page_fault)
522 if ((ktop[i] == (Mword)&i30_ret_switch) ||// shortcut.S, int 0x30
523 (ktop[i] == (Mword)&in_slow_ipc1) || // shortcut.S, int 0x30
524 (ktop[i] == (Mword)&se_ret_switch) || // shortcut.S, sysenter
525 (ktop[i] == (Mword)&in_slow_ipc2) || // shortcut.S, sysenter
526 (ktop[i] == (Mword)&in_slow_ipc4) || // entry.S, int 0x30 log
527 (ktop[i] == (Mword)&in_slow_ipc5) || // entry.S, sysenter log
528 #if defined (CONFIG_JDB_LOGGING) || !defined(CONFIG_ASSEMBLER_IPC_SHORTCUT)
529 (ktop[i] == (Mword)&in_sc_ipc1) || // entry.S, int 0x30
530 (ktop[i] == (Mword)&in_sc_ipc2) || // entry.S, sysenter
534 else if (ktop[i] == (Mword)&in_syscall)
536 else if (ktop[i] == (Mword)&Thread::user_invoke)
537 state = s_user_invoke;
538 else if (ktop[i] == (Mword)&in_handle_fputrap)
540 else if (ktop[i] == (Mword)&in_interrupt)
542 else if ((ktop[i] == (Mword)&in_timer_interrupt) ||
543 (ktop[i] == (Mword)&in_timer_interrupt_slow))
544 state = s_timer_interrupt;
545 else if (ktop[i] == (Mword)&in_slowtrap)
547 if (state != s_unknown)
552 if (state == s_unknown && (t->state(false) & Thread_ipc_mask))
560 Jdb::set_single_step(unsigned cpu, int on)
563 entry_frame.cpu(cpu)->flags(entry_frame.cpu(cpu)->flags() | EFLAGS_TF);
565 entry_frame.cpu(cpu)->flags(entry_frame.cpu(cpu)->flags() & ~EFLAGS_TF);
567 permanent_single_step.cpu(cpu) = on;
572 Jdb::handle_special_cmds(int c)
574 foreach_cpu(&analyze_code);
578 case 'j': // do restricted "go"
579 switch (putchar(c=getchar()))
581 case 'b': // go until next branch
582 case 'r': // go until current function returns
583 ss_level.cpu(current_cpu) = 0;
584 if (code_call.cpu(current_cpu))
586 // increase call level because currently we
587 // stay on a call instruction
588 ss_level.cpu(current_cpu)++;
590 ss_state.cpu(current_cpu) = (c == 'b') ? SS_BRANCH : SS_RETURN;
591 // if we have lbr feature, the processor treats the single
592 // step flag as step on branches instead of step on instruction
593 Cpu::boot_cpu()->btf_enable(true);
595 case 's': // do one single step
596 entry_frame.cpu(current_cpu)->flags(entry_frame.cpu(current_cpu)->flags() | EFLAGS_TF);
597 hide_statline = false;
606 // ignore character and get next input
615 IMPLEMENTATION[ia32]:
617 // take a look at the code of the current thread eip
618 // set global indicators code_call, code_ret, code_bra, code_int
619 // This can fail if the current page is still not mapped
621 Jdb::analyze_code(unsigned cpu)
623 Jdb_entry_frame *entry_frame = Jdb::entry_frame.cpu(cpu);
624 Space *task = get_task(cpu);
625 // do nothing if page not mapped into this address space
626 if (entry_frame->ip()+1 > Kmem::user_max())
631 if ( !peek((Unsigned8*)entry_frame->ip(), task, op1)
632 || !peek((Unsigned8*)(entry_frame->ip()+1), task, op2))
635 if (op1 != 0x0f && op1 != 0xff)
639 ( ((op1 & 0xf6) == 0xc2) // ret/lret /xxxx
640 || (op1 == 0xcf)); // iret
643 ( (op1 == 0xe8) // call near
645 && ((op2 & 0x30) == 0x10)) // call/lcall *(...)
646 || (op1 == 0x9a)); // lcall xxxx:xxxx
649 ( ((op1 & 0xfc) == 0xe0) // loop/jecxz
650 || ((op1 & 0xf0) == 0x70) // jxx rel 8 bit
651 || (op1 == 0xeb) // jmp rel 8 bit
652 || (op1 == 0xe9) // jmp rel 16/32 bit
654 && ((op2 & 0xf0) == 0x80)) // jxx rel 16/32 bit
656 && ((op2 & 0x30) == 0x20)) // jmp/ljmp *(...)
657 || (op1 == 0xea)); // ljmp xxxx:xxxx
660 ( (op1 == 0xcc) // int3
661 || (op1 == 0xcd) // int xx
662 || (op1 == 0xce)); // into
665 IMPLEMENTATION[amd64]:
668 Jdb::analyze_code(unsigned)
671 IMPLEMENTATION[ia32,amd64]:
673 // entered debugger because of single step trap
674 static inline NOEXPORT int
675 Jdb::handle_single_step(unsigned cpu)
677 int really_break = 1;
681 Cpu const &ccpu = Cpu::cpus.cpu(cpu);
683 // special single_step ('j' command): go until branch/return
684 if (ss_state.cpu(cpu) != SS_NONE)
686 if (ccpu.lbr_type() != Cpu::Lbr_unsupported)
688 // don't worry, the CPU always knows what she is doing :-)
692 // we have to emulate lbr looking at the code ...
693 switch (ss_state.cpu(cpu))
696 // go until function return
698 if (code_call.cpu(cpu))
700 // increase call level
703 else if (code_ret.cpu(cpu))
705 // decrease call level
706 really_break = (ss_level.cpu(cpu)-- == 0);
711 // go until next branch
712 really_break = (code_ret.cpu(cpu) || code_call.cpu(cpu) || code_bra.cpu(cpu) || code_int.cpu(cpu));
720 ss_state.cpu(cpu) = SS_NONE;
721 snprintf(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0)), "%s", "Branch/Call");
724 else // (ss_state == SS_NONE)
725 // regular single_step
726 snprintf(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0)), "%s", "Singlestep");
731 // entered debugger due to debug exception
732 static inline NOEXPORT int
733 Jdb::handle_trap1(unsigned cpu)
735 // FIXME: currently only on bot cpu
739 if (bp_test_sstep && bp_test_sstep())
740 return handle_single_step(cpu);
743 && bp_test_break(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0))))
747 && bp_test_other(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0))))
753 // entered debugger due to software breakpoint
754 static inline NOEXPORT int
755 Jdb::handle_trap3(unsigned cpu)
757 Jdb_entry_frame *entry_frame = Jdb::entry_frame.cpu(cpu);
758 Space *task = get_task(cpu);
762 snprintf(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0)), "%s", "INT 3");
763 if ( !peek((Unsigned8*)entry_frame->ip(), task, op)
764 || !peek((Unsigned8*)(entry_frame->ip()+1), task, len)
768 char const *msg = (char const*)(entry_frame->ip()+2);
770 if (!peek(msg, task, buffer[0]))
773 if (len > 1 && !peek(msg+1, task, buffer[1]))
776 // we are entering here because enter_kdebugger("*#..."); failed
777 if (len > 1 && buffer[0] == '*' && buffer[1] == '#')
784 if (len && peek(msg, task, buffer[2]))
787 if (buffer[2] == '#')
789 // the ``-jdb_cmd='' sequence
790 msg = (char const*)entry_frame->value();
791 for (i=0; i<sizeof(ctrl)-1 && peek(msg, task, tmp) && tmp; i++, msg++)
796 // a ``enter_kdebug("*#")'' sequence
797 for (i=0; i<sizeof(ctrl)-1 && i<len && peek(msg, task, tmp); i++, msg++)
801 snprintf(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0)),
802 "invalid ctrl sequence \"%s\"", ctrl);
805 // enter_kdebugger("...");
809 len = len < 47 ? len : 47;
810 len = len < sizeof(error_buffer.cpu(0))-1
812 : sizeof(error_buffer.cpu(0))-1;
814 for(i=0; i<len && peek(msg+i, task, buffer[0]); i++)
815 error_buffer.cpu(cpu)[i] = buffer[0];
816 error_buffer.cpu(cpu)[i]='\0';
822 // entered debugger due to other exception
823 static inline NOEXPORT int
824 Jdb::handle_trapX(unsigned cpu)
826 unsigned pos = snprintf(error_buffer.cpu(cpu), sizeof(error_buffer.cpu(0)), "%s",
827 Cpu::exception_string(entry_frame.cpu(cpu)->_trapno)) + 1;
828 if ( pos < sizeof(error_buffer.cpu(0))
829 && entry_frame.cpu(cpu)->_trapno >= 10
830 && entry_frame.cpu(cpu)->_trapno <= 14)
831 snprintf(error_buffer.cpu(cpu)+pos, sizeof(error_buffer.cpu(0))-pos,
832 "(ERR=" L4_PTR_FMT ")", entry_frame.cpu(cpu)->_err);
837 /** Int3 debugger interface. This function is called immediately
838 * after entering the kernel debugger.
839 * @return 1 if command was successfully interpreted
843 Jdb::handle_user_request(unsigned cpu)
845 Jdb_entry_frame *entry_frame = Jdb::entry_frame.cpu(cpu);
847 if (entry_frame->_trapno == 3)
849 Space *task = get_task(cpu);
851 if (!peek((Unsigned8*)entry_frame->ip(), task, todo))
854 // jmp == enter_kdebug()
858 if (!peek((Unsigned8*)(entry_frame->ip()+1), task, len))
861 char const *str = (char const *)(entry_frame->ip()+2);
867 if (!peek(str, task, tmp) || tmp !='*')
870 if (!peek(str+1, task, tmp) || tmp != '#')
875 if (peek(str+2, task, tmp) && tmp == '#')
876 ret = execute_command_ni(task, (char const *)entry_frame->value());
878 ret = execute_command_ni(task, str+2, len-2);
884 else if (todo == 0x3c)
886 if (!peek((Unsigned8*)(entry_frame->ip()+1), task, todo))
892 if (entry_frame->value() == 3)
895 execute_command("Tgzip");
908 Jdb::enter_trap_handler(unsigned cpu)
909 { Cpu::cpus.cpu(cpu).debugctl_disable(); }
913 Jdb::leave_trap_handler(unsigned cpu)
914 { Cpu::cpus.cpu(cpu).debugctl_enable(); }
918 Jdb::handle_conditional_breakpoint(unsigned cpu)
919 { return entry_frame.cpu(cpu)->_trapno == 1 && bp_test_log_only && bp_test_log_only(); }
923 Jdb::handle_nested_trap(Jdb_entry_frame *e)
925 // re-enable interrupts if we need them because they are disabled
926 if (Config::getchar_does_hlt_works_ok)
932 cursor(Jdb_screen::height(), 1);
933 printf("\nNMI occured\n");
936 cursor(Jdb_screen::height(), 1);
937 printf("\nSoftware breakpoint inside jdb at " L4_PTR_FMT "\n",
943 case Msr_test_fail_warn:
944 printf(" MSR does not exist or invalid value\n");
945 msr_test = Msr_test_default;
948 case Msr_test_fail_ignore:
949 msr_test = Msr_test_default;
953 cursor(Jdb_screen::height(), 1);
954 printf("\nGeneral Protection (eip=" L4_PTR_FMT ","
955 " err=" L4_PTR_FMT ") -- jdb bug?\n",
961 cursor(Jdb_screen::height(), 1);
962 printf("\nInvalid access (trap=%02lx err=" L4_PTR_FMT
963 " pfa=" L4_PTR_FMT " eip=" L4_PTR_FMT ") "
965 e->_trapno, e->_err, e->_cr2, e->ip());
972 Jdb::handle_debug_traps(unsigned cpu)
974 bool really_break = true;
976 if (entry_frame.cpu(cpu)->_trapno == 1)
977 really_break = handle_trap1(cpu);
978 else if (entry_frame.cpu(cpu)->_trapno == 3)
979 really_break = handle_trap3(cpu);
981 really_break = handle_trapX(cpu);
985 for (unsigned i = 0; i < Config::Max_num_cpus; ++i)
987 if (!Cpu::online(i) || !running.cpu(i))
990 if (!permanent_single_step.cpu(i))
991 entry_frame.cpu(i)->flags(entry_frame.cpu(i)->flags() & ~EFLAGS_TF);
1000 Jdb::test_checksums()
1001 { return Boot_info::get_checksum_ro() == Checksum::get_checksum_ro(); }
1003 PUBLIC static inline
1005 Jdb::enter_getchar()
1008 PUBLIC static inline
1010 Jdb::leave_getchar()
1013 //----------------------------------------------------------------------------
1014 IMPLEMENTATION [(ia32 || amd64) && mp]:
1018 Jdb::send_nmi(unsigned cpu)
1020 Apic::mp_send_ipi(Apic::apic.cpu(cpu)->apic_id(), 0, Apic::APIC_IPI_NMI);