From 44a1cfb8d8d52346d0f616f99f938f3b69852ccf Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Tue, 1 Jan 2019 23:26:58 +0100 Subject: [PATCH] kernel/x86: Reimplement locking for early boot message output. The normal locking uses spinlocks that require getting at the current CPU, which in turn needs a current thread set. This has not been set up at this point and would simply cause tripple faults. Use manual locking using atomic ops instead. Change-Id: Ica894389330ef481eec84b667234139746ac4a46 Reviewed-on: https://review.haiku-os.org/808 Reviewed-by: waddlesplash --- .../kernel/arch/x86/arch_debug_console.cpp | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/system/kernel/arch/x86/arch_debug_console.cpp b/src/system/kernel/arch/x86/arch_debug_console.cpp index 30a1762737..8fdede9223 100644 --- a/src/system/kernel/arch/x86/arch_debug_console.cpp +++ b/src/system/kernel/arch/x86/arch_debug_console.cpp @@ -67,6 +67,8 @@ static bool sKeyboardHandlerInstalled = false; static spinlock sSerialOutputSpinlock = B_SPINLOCK_INITIALIZER; +static int32 sEarlyBootMessageLock = 0; + static void init_serial_port(uint16 basePort, uint32 baudRate) @@ -388,6 +390,16 @@ arch_debug_serial_putchar(const char c) } +static void +arch_debug_serial_puts_locked(const char *string) +{ + while (*string != '\0') { + _arch_debug_serial_putchar(*string); + string++; + } +} + + void arch_debug_serial_puts(const char *s) { @@ -397,10 +409,7 @@ arch_debug_serial_puts(const char *s) acquire_spinlock(&sSerialOutputSpinlock); } - while (*s != '\0') { - _arch_debug_serial_putchar(*s); - s++; - } + arch_debug_serial_puts_locked(s); if (!debug_debugger_running()) { release_spinlock(&sSerialOutputSpinlock); @@ -414,8 +423,14 @@ arch_debug_serial_early_boot_message(const char *string) { // this function will only be called in fatal situations // ToDo: also enable output via text console?! + + // Normal locking doesn't work this early as it needs a current thread. + while (atomic_test_and_set(&sEarlyBootMessageLock, 1, 0) != 0) + arch_cpu_pause(); + arch_debug_console_init(NULL); - arch_debug_serial_puts(string); + arch_debug_serial_puts_locked(string); + atomic_set(&sEarlyBootMessageLock, 0); }