diff --git a/headers/private/kernel/arch/dbg_console.h b/headers/private/kernel/arch/dbg_console.h index 9af312c637..d8d9e9845d 100644 --- a/headers/private/kernel/arch/dbg_console.h +++ b/headers/private/kernel/arch/dbg_console.h @@ -18,13 +18,13 @@ struct kernel_args; extern "C" { #endif -char arch_dbg_con_read(void); -char arch_dbg_con_putch(char c); -void arch_dbg_con_puts(const char *s); +char arch_debug_serial_getchar(void); +char arch_debug_serial_putchar(char c); +void arch_debug_serial_puts(const char *s); +void arch_debug_serial_early_boot_message(const char *string); -void arch_dbg_con_early_boot_message(const char *string); -status_t arch_dbg_con_init(struct kernel_args *args); -status_t arch_dbg_con_init_settings(struct kernel_args *args); +status_t arch_debug_console_init(struct kernel_args *args, char (**blueScreenGetChar)(void)); +status_t arch_debug_console_init_settings(struct kernel_args *args); #ifdef __cplusplus } diff --git a/headers/private/kernel/arch/debug.h b/headers/private/kernel/arch/debug.h index 06398d5092..72af6e03ef 100644 --- a/headers/private/kernel/arch/debug.h +++ b/headers/private/kernel/arch/debug.h @@ -18,9 +18,9 @@ struct kernel_args; extern "C" { #endif -status_t arch_dbg_init(kernel_args *args); -void *arch_get_caller(void); -void arch_dbg_save_registers(int *); +status_t arch_debug_init(kernel_args *args); +void *arch_debug_get_caller(void); +void arch_debug_save_registers(int *); #ifdef __cplusplus } diff --git a/headers/private/kernel/debug.h b/headers/private/kernel/debug.h index 55df9814ac..ad33ffb78f 100644 --- a/headers/private/kernel/debug.h +++ b/headers/private/kernel/debug.h @@ -1,10 +1,10 @@ /* -** Copyright 2002-2004, The Haiku Team. All rights reserved. -** Distributed under the terms of the Haiku License. -** -** Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ + * Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de + * Distributed under the terms of the Haiku License. + * + * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ #ifndef _KERNEL_DEBUG_H #define _KERNEL_DEBUG_H @@ -14,7 +14,7 @@ struct kernel_args; -#if DEBUG +#if DEBUG # define ASSERT(x) \ if (x) {} else { panic("ASSERT FAILED (%s:%d): %s\n", __FILE__, __LINE__, #x); } #else @@ -22,7 +22,7 @@ struct kernel_args; #endif extern int dbg_register_file[B_MAX_CPU_COUNT][14]; - /* XXXmpetit -- must be made generic */ + #ifdef __cplusplus extern "C" { @@ -30,8 +30,9 @@ extern "C" { extern status_t debug_init(struct kernel_args *args); extern status_t debug_init_post_vm(struct kernel_args *args); -extern char dbg_putch(char c); -extern void dbg_puts(const char *s); +extern void debug_early_boot_message(const char *string); +extern char debug_putchar(char c); +extern void debug_puts(const char *s); extern void _user_debug_output(const char *userString); diff --git a/src/add-ons/kernel/drivers/common/dprintf.cpp b/src/add-ons/kernel/drivers/common/dprintf.cpp index b8756383f4..393bef856d 100644 --- a/src/add-ons/kernel/drivers/common/dprintf.cpp +++ b/src/add-ons/kernel/drivers/common/dprintf.cpp @@ -88,14 +88,14 @@ dprintf_write(void *cookie, off_t pos, const void *buffer, size_t *_length) memcpy(localBuffer, str, chunkSize); localBuffer[chunkSize] = '\0'; - dbg_puts(localBuffer); + debug_puts(localBuffer); str += chunkSize; bytesLeft -= chunkSize; } } else { // null-terminated chunk -- just write it - dbg_puts(str); + debug_puts(str); str += chunkSize + 1; bytesLeft -= chunkSize + 1; diff --git a/src/system/kernel/arch/x86/arch_dbg_console.c b/src/system/kernel/arch/x86/arch_dbg_console.c index b02ed1363d..e8dcf49701 100644 --- a/src/system/kernel/arch/x86/arch_dbg_console.c +++ b/src/system/kernel/arch/x86/arch_dbg_console.c @@ -53,59 +53,52 @@ static bool sBochsOutput = false; #endif -char -arch_dbg_con_read(void) +static char +keyboard_getchar(void) { -#if BOCHS_DEBUG_HACK - if (sBochsOutput) { - /* polling the keyboard, similar to code in keyboard - * driver, but without using an interrupt - */ - static const char unshifted_keymap[128] = { - 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 8, '\t', - 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a', 's', - 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - '\\', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - const char shifted_keymap[128] = { - 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 8, '\t', - 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 0, 'A', 'S', - 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', '<', '>', '?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - static bool shift = false; - static uint8 last = 0; - uint8 key, ascii = 0; - do { - while ((key = in8(0x60)) == last) - ; - last = key; - if (key & 0x80) { - if (key == (0x80 + 42) || key == (54 + 0x80)) - shift = false; - } else { - if (key == 42 || key == 54) - shift = true; - else - ascii = shift ? shifted_keymap[key] : unshifted_keymap[key]; - } - } while (!ascii); - return ascii; - } -#endif + /* polling the keyboard, similar to code in keyboard + * driver, but without using an interrupt + */ + static const char unshifted_keymap[128] = { + 0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 8, '\t', + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a', 's', + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', + 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + '\\', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + static const char shifted_keymap[128] = { + 0, 27, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 8, '\t', + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 0, 'A', 'S', + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|', 'Z', 'X', 'C', 'V', + 'B', 'N', 'M', '<', '>', '?', 0, '*', 0, ' ', 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + static bool shift = false; + static uint8 last = 0; + uint8 key, ascii = 0; - while ((in8(sSerialBasePort + SERIAL_LINE_STATUS) & 0x1) == 0) - ; + do { + while ((key = in8(0x60)) == last) + ; + last = key; + if (key & 0x80) { + if (key == (0x80 + 42) || key == (54 + 0x80)) + shift = false; + } else { + if (key == 42 || key == 54) + shift = true; + else + ascii = shift ? shifted_keymap[key] : unshifted_keymap[key]; + } + } while (!ascii); - return in8(sSerialBasePort + SERIAL_RECEIVE_BUFFER); + return ascii; } @@ -127,8 +120,26 @@ put_char(const char c) } +// #pragma mark - + + char -arch_dbg_con_putch(const char c) +arch_debug_serial_getchar(void) +{ +#if BOCHS_DEBUG_HACK + if (sBochsOutput) + return keyboard_getchar(); +#endif + + while ((in8(sSerialBasePort + SERIAL_LINE_STATUS) & 0x1) == 0) + ; + + return in8(sSerialBasePort + SERIAL_RECEIVE_BUFFER); +} + + +char +arch_debug_serial_putchar(const char c) { if (c == '\n') { put_char('\r'); @@ -141,30 +152,33 @@ arch_dbg_con_putch(const char c) void -arch_dbg_con_puts(const char *s) +arch_debug_serial_puts(const char *s) { while (*s != '\0') { - arch_dbg_con_putch(*s); + arch_debug_serial_putchar(*s); s++; } } void -arch_dbg_con_early_boot_message(const char *string) +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?! - arch_dbg_con_init(NULL); - arch_dbg_con_puts(string); + arch_debug_console_init(NULL, NULL); + arch_debug_serial_puts(string); } status_t -arch_dbg_con_init(kernel_args *args) +arch_debug_console_init(kernel_args *args, char (**_blueScreenGetChar)(void)) { uint16 divisor = (uint16)(115200 / kSerialBaudRate); + if (_blueScreenGetChar) + *_blueScreenGetChar = keyboard_getchar; + // only use the port if we could find one, else use the standard port if (args->platform_args.serial_base_ports[0] != 0) sSerialBasePort = args->platform_args.serial_base_ports[0]; @@ -179,7 +193,7 @@ arch_dbg_con_init(kernel_args *args) status_t -arch_dbg_con_init_settings(kernel_args *args) +arch_debug_console_init_settings(kernel_args *args) { uint32 baudRate = kSerialBaudRate; uint16 basePort = sSerialBasePort; @@ -197,13 +211,15 @@ arch_dbg_con_init_settings(kernel_args *args) value = get_driver_parameter(handle, "serial_debug_port", NULL, NULL); if (value != NULL) { int32 number = strtol(value, NULL, 0); - if (number < MAX_SERIAL_PORTS) { + if (number >= MAX_SERIAL_PORTS) { + // use as port number directly + basePort = number; + } else if (number >= 0) { // use as index into port array if (args->platform_args.serial_base_ports[number] != 0) basePort = args->platform_args.serial_base_ports[number]; } else { - // use as port number directly - basePort = number; + // ignore value and use default } } diff --git a/src/system/kernel/arch/x86/arch_debug.c b/src/system/kernel/arch/x86/arch_debug.c index 3b73922349..3bbda9033f 100644 --- a/src/system/kernel/arch/x86/arch_debug.c +++ b/src/system/kernel/arch/x86/arch_debug.c @@ -49,7 +49,7 @@ already_visited(uint32 *visited, int32 *_last, int32 *_num, uint32 ebp) static int -dbg_stack_trace(int argc, char **argv) +stack_trace(int argc, char **argv) { uint32 previousLocations[NUM_PREVIOUS_LOCATIONS]; struct iframe_stack *frameStack; @@ -156,7 +156,7 @@ dbg_stack_trace(int argc, char **argv) void * -arch_get_caller(void) +arch_debug_get_caller(void) { // It looks like you would get the wrong stack frame here, but // since read_ebp() is an assembler inline macro, GCC seems to @@ -169,12 +169,12 @@ arch_get_caller(void) status_t -arch_dbg_init(kernel_args *args) +arch_debug_init(kernel_args *args) { // at this stage, the debugger command system is alive - add_debugger_command("where", &dbg_stack_trace, "Stack crawl for current thread"); - add_debugger_command("sc", &dbg_stack_trace, NULL); + add_debugger_command("where", &stack_trace, "Same as \"sc\""); + add_debugger_command("sc", &stack_trace, "Stack crawl for current thread"); return B_NO_ERROR; } diff --git a/src/system/kernel/arch/x86/arch_x86.S b/src/system/kernel/arch/x86/arch_x86.S index fbd7a5de44..addf45f843 100644 --- a/src/system/kernel/arch/x86/arch_x86.S +++ b/src/system/kernel/arch/x86/arch_x86.S @@ -153,7 +153,7 @@ done: jmp done -FUNCTION(arch_dbg_save_registers): +FUNCTION(arch_debug_save_registers): pushl %esi pushl %eax movl 12(%esp), %esi @@ -163,7 +163,7 @@ FUNCTION(arch_dbg_save_registers): movl %ecx, 8(%esi) movl %edx, 12(%esi) - lea 16(%esp), %eax + lea 16(%esp), %eax movl %eax, 16(%esi) // caller's %esp movl %ebp, 20(%esi) @@ -174,7 +174,6 @@ FUNCTION(arch_dbg_save_registers): movl 8(%esp), %eax movl %eax, 32(%esi) // caller's %ebp - pushfl popl %eax movl %eax, 36(%esi) diff --git a/src/system/kernel/debug/debug.c b/src/system/kernel/debug/debug.c index 9ddcd0a4d6..f5e9d4850a 100644 --- a/src/system/kernel/debug/debug.c +++ b/src/system/kernel/debug/debug.c @@ -1,12 +1,12 @@ -/* This file contains the debugger */ - /* -** Copyright 2002-2004, The Haiku Team. All rights reserved. -** Distributed under the terms of the Haiku License. -** -** Copyright 2001, Travis Geiselbrecht. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ + * Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de + * Distributed under the terms of the Haiku License. + * + * Copyright 2001, Travis Geiselbrecht. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + +/* This file contains the debugger */ #include #include @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -37,9 +38,14 @@ typedef struct debugger_command { int dbg_register_file[B_MAX_CPU_COUNT][14]; /* XXXmpetit -- must be made generic */ +char (*sBlueScreenGetChar)(void) = NULL; + // this will be set by arch_debug_console_init() + static bool sSerialDebugEnabled = false; -static spinlock dbg_spinlock = 0; -static int debugger_on_cpu = -1; +static bool sSyslogOutputEnabled = false; +static bool sBlueScreenEnabled = false; +static spinlock sSpinlock = 0; +static int sDebuggerOnCPU = -1; static struct debugger_command *sCommands; @@ -51,7 +57,7 @@ static char sOutputBuffer[OUTPUT_BUFFER_SIZE]; #define HISTORY_SIZE 16 static char line_buf[HISTORY_SIZE][LINE_BUF_SIZE] = { "", }; -static char parse_line[LINE_BUF_SIZE] = ""; +static char sParseLine[LINE_BUF_SIZE] = ""; static int cur_line = 0; static char *args[MAX_ARGS] = { NULL, }; @@ -85,43 +91,50 @@ find_command(char *name) static int -debug_read_line(char *buf, int max_len) +read_line(char *buf, int max_len) { char c; int ptr = 0; bool done = false; int cur_history_spot = cur_line; + char (*readChar)(void); + if (sBlueScreenEnabled && sBlueScreenGetChar != NULL) + readChar = sBlueScreenGetChar; + else + readChar = arch_debug_serial_getchar; + while (!done) { - c = arch_dbg_con_read(); + c = readChar(); + switch (c) { case '\n': case '\r': buf[ptr++] = '\0'; - dbg_puts("\n"); + debug_putchar('\n'); done = true; break; case 8: // backspace if (ptr > 0) { - dbg_puts("\x1b[1D"); // move to the left one - dbg_putch(' '); - dbg_puts("\x1b[1D"); // move to the left one + debug_puts("\x1b[1D"); // move to the left one + debug_putchar(' '); + debug_puts("\x1b[1D"); // move to the left one ptr--; } break; case 27: // escape sequence - c = arch_dbg_con_read(); // should be '[' - c = arch_dbg_con_read(); + c = readChar(); // should be '[' + c = readChar(); switch (c) { case 67: // right arrow acts like space buf[ptr++] = ' '; - dbg_putch(' '); + debug_putchar(' '); break; case 68: // left arrow acts like backspace if (ptr > 0) { - dbg_puts("\x1b[1D"); // move to the left one - dbg_putch(' '); - dbg_puts("\x1b[1D"); // move to the left one + debug_puts("\x1b[1D"); // move to the left one + debug_putchar(' '); + debug_puts("\x1b[1D"); // move to the left one ptr--; } break; @@ -150,7 +163,7 @@ debug_read_line(char *buf, int max_len) // dprintf("2c %d h %d ch %d\n", cur_line, history_line, cur_history_spot); // swap the current line with something from the history - if(ptr > 0) + if (ptr > 0) dprintf("\x1b[%dD", ptr); // move to beginning of line strcpy(buf, line_buf[history_line]); @@ -165,26 +178,27 @@ debug_read_line(char *buf, int max_len) break; case '$': case '+': - /* HACK ALERT!!! - * - * If we get a $ at the beginning of the line - * we assume we are talking with GDB - */ - if (ptr == 0) { - strcpy(buf, "gdb"); - ptr= 4; - done= true; - break; - } else { - /* fall thru */ + if (readChar != sBlueScreenGetChar) { + /* HACK ALERT!!! + * + * If we get a $ at the beginning of the line + * we assume we are talking with GDB + */ + if (ptr == 0) { + strcpy(buf, "gdb"); + ptr = 4; + done = true; + break; + } } + /* supposed to fall through */ default: buf[ptr++] = c; - dbg_putch(c); + debug_putchar(c); } if (ptr >= max_len - 2) { buf[ptr++] = '\0'; - dbg_puts("\n"); + debug_puts("\n"); done = true; break; } @@ -194,27 +208,27 @@ debug_read_line(char *buf, int max_len) static int -debug_parse_line(char *buf, char **argv, int *argc, int max_args) +parse_line(char *buf, char **argv, int *argc, int max_args) { int pos = 0; - strcpy(parse_line, buf); + strcpy(sParseLine, buf); - if (!isspace(parse_line[0])) { - argv[0] = parse_line; + if (!isspace(sParseLine[0])) { + argv[0] = sParseLine; *argc = 1; } else *argc = 0; - while (parse_line[pos] != '\0') { - if (isspace(parse_line[pos])) { - parse_line[pos] = '\0'; + while (sParseLine[pos] != '\0') { + if (isspace(sParseLine[pos])) { + sParseLine[pos] = '\0'; // scan all of the whitespace out of this - while (isspace(parse_line[++pos])) + while (isspace(sParseLine[++pos])) ; - if (parse_line[pos] == '\0') + if (sParseLine[pos] == '\0') break; - argv[*argc] = &parse_line[pos]; + argv[*argc] = &sParseLine[pos]; (*argc)++; if (*argc >= max_args - 1) @@ -230,28 +244,28 @@ debug_parse_line(char *buf, char **argv, int *argc, int max_args) static void kernel_debugger_loop(void) { - int argc; struct debugger_command *cmd; - cpu_status state; + int argc; - state = disable_interrupts(); + dprintf("Running on CPU %d\n", smp_get_current_cpu()); + if (sBlueScreenEnabled && sBlueScreenGetChar == NULL) + dprintf("Only serial keyboard input available.\n"); - dprintf("kernel debugger on cpu %d\n", smp_get_current_cpu()); - debugger_on_cpu = smp_get_current_cpu(); + sDebuggerOnCPU = smp_get_current_cpu(); cmd = NULL; for (;;) { dprintf("kdebug> "); - debug_read_line(line_buf[cur_line], LINE_BUF_SIZE); - debug_parse_line(line_buf[cur_line], args, &argc, MAX_ARGS); + read_line(line_buf[cur_line], LINE_BUF_SIZE); + parse_line(line_buf[cur_line], args, &argc, MAX_ARGS); // We support calling last executed command again if // B_KDEDUG_CONT was returned last time, so cmd != NULL if (argc <= 0 && cmd == NULL) continue; - debugger_on_cpu = smp_get_current_cpu(); + sDebuggerOnCPU = smp_get_current_cpu(); if (argc > 0) cmd = find_command(args[0]); @@ -272,41 +286,6 @@ kernel_debugger_loop(void) if (cur_line >= HISTORY_SIZE) cur_line = 0; } - - restore_interrupts(state); -} - - -char -dbg_putch(char c) -{ - char ret; - cpu_status state = disable_interrupts(); - acquire_spinlock(&dbg_spinlock); - - if (sSerialDebugEnabled) - ret = arch_dbg_con_putch(c); - else - ret = c; - - release_spinlock(&dbg_spinlock); - restore_interrupts(state); - - return ret; -} - - -void -dbg_puts(const char *s) -{ - cpu_status state = disable_interrupts(); - acquire_spinlock(&dbg_spinlock); - - if (sSerialDebugEnabled) - arch_dbg_con_puts(s); - - release_spinlock(&dbg_spinlock); - restore_interrupts(state); } @@ -351,16 +330,58 @@ cmd_continue(int argc, char **argv) } +// #pragma mark - + + +char +debug_putchar(char c) +{ + cpu_status state = disable_interrupts(); + acquire_spinlock(&sSpinlock); + + if (sSerialDebugEnabled) + c = arch_debug_serial_putchar(c); + + release_spinlock(&sSpinlock); + restore_interrupts(state); + + return c; +} + + +void +debug_puts(const char *s) +{ + cpu_status state = disable_interrupts(); + acquire_spinlock(&sSpinlock); + + if (sSerialDebugEnabled) + arch_debug_serial_puts(s); + + release_spinlock(&sSpinlock); + restore_interrupts(state); +} + + +void +debug_early_boot_message(const char *string) +{ + arch_debug_serial_early_boot_message(string); +} + + status_t debug_init(kernel_args *args) { - return arch_dbg_con_init(args); + return arch_debug_console_init(args, &sBlueScreenGetChar); } status_t debug_init_post_vm(kernel_args *args) { + void *handle; + add_debugger_command("help", &cmd_help, "List all debugger commands"); add_debugger_command("reboot", &cmd_reboot, "Reboot the system"); add_debugger_command("gdb", &cmd_gdb, "Connect to remote gdb"); @@ -368,18 +389,23 @@ debug_init_post_vm(kernel_args *args) add_debugger_command("exit", &cmd_continue, NULL); add_debugger_command("es", &cmd_continue, NULL); - arch_dbg_con_init_settings(args); - return arch_dbg_init(args); + // get debug settings + handle = load_driver_settings("kernel"); + if (handle != NULL) { + if (get_driver_boolean_parameter(handle, "serial_debug_output", true, true)) + sSerialDebugEnabled = true; + if (get_driver_boolean_parameter(handle, "syslog_debug_output", false, false)) + sSyslogOutputEnabled = true; + if (get_driver_boolean_parameter(handle, "bluescreen", false, false)) + sBlueScreenEnabled = true; + + unload_driver_settings(handle); + } + + arch_debug_console_init_settings(args); + return arch_debug_init(args); } -// ToDo: this one is probably not needed -#if 0 -bool -dbg_get_serial_debug() -{ - return sSerialDebugEnabled; -} -#endif // #pragma mark - // public API @@ -400,12 +426,12 @@ add_debugger_command(char *name, int (*func)(int, char **), char *desc) cmd->description = desc; state = disable_interrupts(); - acquire_spinlock(&dbg_spinlock); + acquire_spinlock(&sSpinlock); cmd->next = sCommands; sCommands = cmd; - release_spinlock(&dbg_spinlock); + release_spinlock(&sSpinlock); restore_interrupts(state); return B_NO_ERROR; @@ -420,7 +446,7 @@ remove_debugger_command(char * name, int (*func)(int, char **)) cpu_status state; state = disable_interrupts(); - acquire_spinlock(&dbg_spinlock); + acquire_spinlock(&sSpinlock); while (cmd) { if (!strcmp(cmd->name, name) && cmd->func == func) @@ -437,7 +463,7 @@ remove_debugger_command(char * name, int (*func)(int, char **)) prev->next = cmd->next; } - release_spinlock(&dbg_spinlock); + release_spinlock(&sSpinlock); restore_interrupts(state); if (cmd) { @@ -457,29 +483,38 @@ parse_expression(const char *expression) void -panic(const char *fmt, ...) +panic(const char *format, ...) { - int ret = 0; va_list args; char temp[128]; - cpu_status state; + set_dprintf_enabled(true); + + va_start(args, format); + vsnprintf(temp, sizeof(temp), format, args); + va_end(args); + + dprintf("PANIC: %s", temp); + kernel_debugger(NULL); +} + + +void +kernel_debugger(const char *message) +{ + cpu_status state; + + arch_debug_save_registers(&dbg_register_file[smp_get_current_cpu()][0]); + set_dprintf_enabled(true); + + state = disable_interrupts(); + // XXX by setting kernel_startup = true, we disable // XXX the interrupt check in semaphore code etc. // XXX should be renamed? kernel_startup = true; - set_dprintf_enabled(true); - - state = disable_interrupts(); - - va_start(args, fmt); - ret = vsprintf(temp, fmt, args); - va_end(args); - - dprintf("PANIC%d: %s", smp_get_current_cpu(), temp); - - if (debugger_on_cpu != smp_get_current_cpu()) { + if (sDebuggerOnCPU != smp_get_current_cpu()) { // halt all of the other cpus // XXX need to flush current smp mailbox to make sure this goes @@ -487,24 +522,18 @@ panic(const char *fmt, ...) smp_send_broadcast_ici(SMP_MSG_CPU_HALT, 0, 0, 0, NULL, SMP_MSG_FLAG_SYNC); } - kernel_debugger(NULL); - - restore_interrupts(state); -} - - -void -kernel_debugger(const char * message) -{ - arch_dbg_save_registers(&(dbg_register_file[smp_get_current_cpu()][0])); - if (message) { dprintf(message); dprintf("\n"); - }; + } dprintf("Welcome to Kernel Debugging Land...\n"); kernel_debugger_loop(); + + kernel_startup = false; + restore_interrupts(state); + + // ToDo: in case we change dbg_register_file - don't we want to restore it? } @@ -532,15 +561,15 @@ dprintf(const char *fmt, ...) // interrupts? state = disable_interrupts(); - acquire_spinlock(&dbg_spinlock); + acquire_spinlock(&sSpinlock); va_start(args, fmt); vsnprintf(sOutputBuffer, OUTPUT_BUFFER_SIZE, fmt, args); va_end(args); - arch_dbg_con_puts(sOutputBuffer); + arch_debug_serial_puts(sOutputBuffer); - release_spinlock(&dbg_spinlock); + release_spinlock(&sSpinlock); restore_interrupts(state); } @@ -563,7 +592,7 @@ _user_debug_output(const char *userString) do { length = user_strlcpy(string, userString, sizeof(string)); - dbg_puts(string); + debug_puts(string); userString += sizeof(string) - 1; } while (length >= (ssize_t)sizeof(string)); } diff --git a/src/system/kernel/debug/gdb.c b/src/system/kernel/debug/gdb.c index 8de294e377..902ce7ff3d 100644 --- a/src/system/kernel/debug/gdb.c +++ b/src/system/kernel/debug/gdb.c @@ -1,9 +1,13 @@ +/* + * Copyright 2005, Axel Dörfler, axeld@pinc-software.de. + * Distributed under the terms of the MIT License. + * + * Copyright 2002, Manuel J. Petit. All rights reserved. + * Distributed under the terms of the NewOS License. + */ + /* Contains the code to interface with a remote GDB */ -/* -** Copyright 2002, Manuel J. Petit. All rights reserved. -** Distributed under the terms of the NewOS License. -*/ #include #include #include @@ -14,21 +18,20 @@ #include -enum { INIT= 0, CMDREAD, CKSUM1, CKSUM2, WAITACK, QUIT, GDBSTATES }; +enum { INIT = 0, CMDREAD, CKSUM1, CKSUM2, WAITACK, QUIT, GDBSTATES }; static char cmd[512]; -static int cmd_ptr; -static int checksum; +static int cmd_ptr; +static int checksum; static char reply[512]; static char safe_mem[512]; -/* - * utility functions - */ +// utility functions + static int parse_nibble(int input) @@ -48,30 +51,27 @@ parse_nibble(int input) } +// #pragma mark - GDB protocol -/* - * GDB protocol ACK & NAK & Reply - * - */ static void gdb_ack(void) { - dbg_putch('+'); + debug_putchar('+'); } static void gdb_nak(void) { - dbg_putch('-'); + debug_putchar('-'); } static void gdb_resend_reply(void) { - dbg_puts(reply); + debug_puts(reply); } @@ -151,10 +151,8 @@ gdb_memreply(char const *bytes, int numbytes) } +// #pragma mark - checksum verification -/* - * checksum verification - */ static int gdb_verify_checksum(void) @@ -174,9 +172,8 @@ gdb_verify_checksum(void) } -/* - * command parsing an dispatching - */ +// #pragma mark - command parsing + static int gdb_parse_command(void) @@ -331,10 +328,8 @@ gdb_parse_command(void) } +// #pragma mark - protocol state machine -/* - * GDB protocol state machine - */ static int gdb_init_handler(int input) @@ -486,7 +481,7 @@ gdb_state_machine(void) int c; while (state != QUIT) { - c = arch_dbg_con_read(); + c = arch_debug_serial_getchar(); state = gdb_state_dispatch(state, c); } diff --git a/src/system/kernel/main.c b/src/system/kernel/main.c index b51ea4c0db..5cf1263d4f 100644 --- a/src/system/kernel/main.c +++ b/src/system/kernel/main.c @@ -67,7 +67,7 @@ _start(kernel_args *oldka, int cpu_num) // This is something we cannot handle right now - release kernels // should always be able to handle the kernel_args of earlier // released kernels. - arch_dbg_con_early_boot_message("Version mismatch between boot loader and kernel!\n"); + debug_early_boot_message("Version mismatch between boot loader and kernel!\n"); return -1; } diff --git a/src/system/kernel/smp.c b/src/system/kernel/smp.c index f864ff3d0a..d1282786ab 100644 --- a/src/system/kernel/smp.c +++ b/src/system/kernel/smp.c @@ -99,8 +99,9 @@ find_lock_caller(spinlock *lock) int32 i; for (i = 0; i < NUM_LAST_CALLERS; i++) { - if (sLastCaller[i].lock == lock) - return sLastCaller[i].caller; + int32 index = (NUM_LAST_CALLERS + sLastIndex - 1 - i) % NUM_LAST_CALLERS; + if (sLastCaller[index].lock == lock) + return sLastCaller[index].caller; } return NULL; @@ -134,7 +135,7 @@ acquire_spinlock(spinlock *lock) lock, find_lock_caller(lock), oldValue); } - push_lock_caller(arch_get_caller(), lock); + push_lock_caller(arch_debug_get_caller(), lock); #endif } }