diff --git a/src/system/kernel/debug/debug.c b/src/system/kernel/debug/debug.c index aa1acc59a1..c26d5fd977 100644 --- a/src/system/kernel/debug/debug.c +++ b/src/system/kernel/debug/debug.c @@ -867,20 +867,23 @@ panic(const char *format, ...) void kernel_debugger(const char *message) { + static vint32 inDebugger; cpu_status state; bool dprintfState; + state = disable_interrupts(); + atomic_add(&inDebugger, 1); + arch_debug_save_registers(&dbg_register_file[smp_get_current_cpu()][0]); dprintfState = set_dprintf_enabled(true); - state = disable_interrupts(); - if (sDebuggerOnCPU != smp_get_current_cpu()) { - // halt all of the other cpus + // First entry, halt all of the other cpus // XXX need to flush current smp mailbox to make sure this goes // through. Otherwise it'll hang - smp_send_broadcast_ici(SMP_MSG_CPU_HALT, 0, 0, 0, NULL, SMP_MSG_FLAG_SYNC); + smp_send_broadcast_ici(SMP_MSG_CPU_HALT, 0, 0, 0, (void *)&inDebugger, + SMP_MSG_FLAG_SYNC); } if (sBlueScreenOutput) { @@ -896,6 +899,7 @@ kernel_debugger(const char *message) set_dprintf_enabled(dprintfState); sBlueScreenEnabled = false; + atomic_add(&inDebugger, -1); restore_interrupts(state); // ToDo: in case we change dbg_register_file - don't we want to restore it? diff --git a/src/system/kernel/smp.c b/src/system/kernel/smp.c index c0e6dc085c..604675b685 100644 --- a/src/system/kernel/smp.c +++ b/src/system/kernel/smp.c @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de. * Distributed under the terms of the MIT License. * * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. @@ -347,11 +347,11 @@ static int32 process_pending_ici(int32 currentCPU) { struct smp_msg *msg; - bool halt = false; - int source_mailbox = 0; + vint32 *haltValue = NULL; + int sourceMailbox = 0; int retval = B_HANDLED_INTERRUPT; - msg = check_for_message(currentCPU, &source_mailbox); + msg = check_for_message(currentCPU, &sourceMailbox); if (msg == NULL) return retval; @@ -374,8 +374,8 @@ process_pending_ici(int32 currentCPU) retval = B_INVOKE_SCHEDULER; break; case SMP_MSG_CPU_HALT: - halt = true; - dprintf("cpu %ld halted!\n", currentCPU); + haltValue = (vint32 *)msg->data_ptr; + dprintf("CPU %ld halted!\n", currentCPU); break; case SMP_MSG_CALL_FUNCTION: { @@ -389,13 +389,16 @@ process_pending_ici(int32 currentCPU) } // finish dealing with this message, possibly removing it from the list - finish_message_processing(currentCPU, msg, source_mailbox); + finish_message_processing(currentCPU, msg, sourceMailbox); // special case for the halt message - // we otherwise wouldn't have gotten the opportunity to clean up - if (halt) { - disable_interrupts(); - for(;;); + if (haltValue) { + cpu_status state = disable_interrupts(); + + while (*haltValue != 0) + ; + + restore_interrupts(state); } return retval;