diff --git a/sys/amd64/debug.c b/sys/amd64/debug.c index 52b8ec5..645fc74 100644 --- a/sys/amd64/debug.c +++ b/sys/amd64/debug.c @@ -56,6 +56,8 @@ Debug_Registers(int argc, const char *argv[]) tf->r13, tf->r14, tf->r15); } +REGISTER_DBGCMD(registers, "Show CPU registers", Debug_Registers); + void Debug_Reboot(int argc, const char *argv[]) { @@ -66,3 +68,5 @@ Debug_Reboot(int argc, const char *argv[]) write_cr3(0x8000000000000000ULL); } +REGISTER_DBGCMD(reboot, "Reboot computer", Debug_Reboot); + diff --git a/sys/amd64/kernel.lds b/sys/amd64/kernel.lds index 2c28d7e..905ae50 100644 --- a/sys/amd64/kernel.lds +++ b/sys/amd64/kernel.lds @@ -143,6 +143,13 @@ SECTIONS SORT(CONSTRUCTORS) } .data1 : { *(.data1) } + /* Kernel Debugger */ + __kdbgcmd_start = .; + .kdbgcmd : + { + *(.kdbgcmd) + } + __kdbgcmd_end = .; _edata = .; PROVIDE (edata = .); . = .; __bss_start = .; diff --git a/sys/amd64/lapic.c b/sys/amd64/lapic.c index 0ede6df..9bcee7b 100644 --- a/sys/amd64/lapic.c +++ b/sys/amd64/lapic.c @@ -4,7 +4,9 @@ #include #include + #include +#include #include "amd64.h" #include "amd64op.h" @@ -189,6 +191,9 @@ LAPIC_Init() void Debug_LAPIC(int argc, const char *argv[]) { + uint32_t version = LAPIC_Read(LAPIC_VERSION); + uint32_t lvts = (version & LAPIC_VERSION_LVTMASK) >> LAPIC_VERSION_LVTSHIFT; + kprintf("LAPIC %d\n", LAPIC_CPU()); kprintf("VERSION: %08x\n", LAPIC_Read(LAPIC_VERSION)); kprintf("ESR: %08x\n", LAPIC_Read(LAPIC_ESR)); @@ -196,10 +201,18 @@ Debug_LAPIC(int argc, const char *argv[]) kprintf("ICRHI: %08x\n", LAPIC_Read(LAPIC_ICR_HI)); kprintf("SIV: %08x\n", LAPIC_Read(LAPIC_SIV)); kprintf("ERROR: %08x\n", LAPIC_Read(LAPIC_LVT_ERROR)); - kprintf("THERMAL: %08x\n", LAPIC_Read(LAPIC_LVT_THERMAL)); + if (lvts >= 5) { + kprintf("THERMAL: %08x\n", LAPIC_Read(LAPIC_LVT_THERMAL)); + } kprintf("LINT0: %08x\n", LAPIC_Read(LAPIC_LVT_LINT0)); kprintf("LINT1: %08x\n", LAPIC_Read(LAPIC_LVT_LINT1)); - kprintf("PMCR: %08x\n", LAPIC_Read(LAPIC_LVT_PMCR)); - kprintf("CMCI: %08x\n", LAPIC_Read(LAPIC_LVT_CMCI)); + if (lvts >= 4) { + kprintf("PMCR: %08x\n", LAPIC_Read(LAPIC_LVT_PMCR)); + } + if (lvts >= 6) { + kprintf("CMCI: %08x\n", LAPIC_Read(LAPIC_LVT_CMCI)); + } } +REGISTER_DBGCMD(lapic, "LAPIC Status", Debug_LAPIC); + diff --git a/sys/amd64/pmap.c b/sys/amd64/pmap.c index 2830c0e..4d8cd13 100644 --- a/sys/amd64/pmap.c +++ b/sys/amd64/pmap.c @@ -274,3 +274,5 @@ Debug_PMapDump(int argc, const char *argv[]) PMapDump(&systemAS); } +REGISTER_DBGCMD(pmapdump, "Dump memory mappings", Debug_PMapDump); + diff --git a/sys/amd64/trap.c b/sys/amd64/trap.c index cdf808c..22d96b8 100644 --- a/sys/amd64/trap.c +++ b/sys/amd64/trap.c @@ -1,8 +1,10 @@ +#include #include #include #include +#include #include #include @@ -188,3 +190,5 @@ Debug_Traps(int argc, const char *argv[]) } } +REGISTER_DBGCMD(traps, "Print trap statistics", Debug_Traps); + diff --git a/sys/dev/pci.c b/sys/dev/pci.c index 1bcd8b8..ee5a314 100644 --- a/sys/dev/pci.c +++ b/sys/dev/pci.c @@ -307,3 +307,5 @@ Debug_PCIDump(int argc, const char *argv[]) } } +REGISTER_DBGCMD(pcidump, "PCI Device Dump", Debug_PCIDump); + diff --git a/sys/dev/x86/vgacons.c b/sys/dev/x86/vgacons.c index c6d24b3..f9e37dd 100644 --- a/sys/dev/x86/vgacons.c +++ b/sys/dev/x86/vgacons.c @@ -164,6 +164,7 @@ void VGA_Puts(const char *str) void Panic(const char *str) { VGA_Puts(str); + __asm__("int3"); while (1) { __asm__("hlt"); diff --git a/sys/include/cdefs.h b/sys/include/cdefs.h index 00b57d8..7eddf85 100644 --- a/sys/include/cdefs.h +++ b/sys/include/cdefs.h @@ -4,10 +4,13 @@ #include -#define PACKED __attribute__((__packed__)) +#define PACKED __attribute__((__packed__)) +#define PERCORE __attribute__((section(".data.percore"))) -#define INLINE inline -#define NO_RETURN __attribute__((noreturn)) +#define INLINE inline +#define NO_RETURN __attribute__((noreturn)) + +#define UNREACHABLE __builtin_unreachable() #endif /* __CDEFS_H__ */ diff --git a/sys/include/kdebug.h b/sys/include/kdebug.h index 4789c49..034bf73 100644 --- a/sys/include/kdebug.h +++ b/sys/include/kdebug.h @@ -2,16 +2,20 @@ #ifndef __KDEBUG_H__ #define __KDEBUG_H__ +typedef struct DebugCommand { + const char name[40]; + const char description[80]; + void (*func)(int, const char **); +} DebugCommand; + +#define REGISTER_DBGCMD(_NAME, _DESC, _FUNC) \ + __attribute__((section(".kdbgcmd"))) \ + DebugCommand cmd_##_NAME = { #_NAME, _DESC, _FUNC } + // Platform Functions -void Debug_Registers(int argc, const char *argv[]); -void Debug_Traps(int argc, const char *argv[]); -void Debug_PMapDump(int argc, const char *argv[]); -void Debug_Reboot(int argc, const char *argv[]); uintptr_t db_disasm(uintptr_t loc, bool altfmt); // Generic Functions -void Debug_PAllocStats(int argc, const char *argv[]); -void Debug_Dump(int argc, const char *argv[]); void Debug_Prompt(); // Helper Functions @@ -20,13 +24,5 @@ void Debug_PrintSymbol(uintptr_t off, int strategy); uint64_t Debug_StrToInt(const char *s); uint64_t Debug_SymbolToInt(const char *s); -// Device Functions -void Debug_PCIDump(int argc, const char *argv[]); - -// x86 Functions -#if defined(__amd64__) -void Debug_LAPIC(int argc, const char *argv[]); -#endif - #endif /* __KDEBUG_H__ */ diff --git a/sys/kern/debug.c b/sys/kern/debug.c index 710cdfa..cddb4ae 100644 --- a/sys/kern/debug.c +++ b/sys/kern/debug.c @@ -165,27 +165,28 @@ Debug_SymbolToInt(const char *s) #define PHELP(_cmd, _msg) kprintf("%-16s %s\n", _cmd, _msg) +extern DebugCommand *__kdbgcmd_start; +extern DebugCommand *__kdbgcmd_end; + void Debug_Help(int argc, const char *argv[]) { - kprintf("Commands:\n"); - PHELP("continue", "Continue execution"); - PHELP("disasm", "Disassemble"); - PHELP("dump", "Dump a region of memory"); - PHELP("pallocstats", "Page allocator statistics"); - PHELP("pcidump", "PCI Device Dump"); - PHELP("pmapdump", "Dump memory mappings"); - PHELP("reboot", "Reboot computer"); - PHELP("registers", "Show CPU registers"); - PHELP("traps", "Trap statistics"); - PHELP("help", "Display the list of commands"); + int i; + uintptr_t commands = (uintptr_t)&__kdbgcmd_end - (uintptr_t)&__kdbgcmd_start; + commands /= sizeof(DebugCommand); + DebugCommand *cmds = (DebugCommand *)&__kdbgcmd_start; - kprintf("Platform Commands:\n"); -#if defined(__amd64__) - PHELP("lapic", "LAPIC Status"); -#endif + kprintf("Commands:\n"); + for (i = 0; i < commands; i++) + { + kprintf("%-16s %s\n", cmds[i].name, cmds[i].description); + } + + PHELP("continue", "Continue execution"); } +REGISTER_DBGCMD(help, "Display the list of commands", Debug_Help); + void Debug_Echo(int argc, const char *argv[]) { @@ -198,6 +199,8 @@ Debug_Echo(int argc, const char *argv[]) kprintf("\n"); } +REGISTER_DBGCMD(echo, "Echo arguments", Debug_Echo); + void Debug_Dump(int argc, const char *argv[]) { @@ -215,6 +218,8 @@ Debug_Dump(int argc, const char *argv[]) Debug_PrintHex((const char *)off, len, 0, len); } +REGISTER_DBGCMD(dump, "Dump a region of memory", Debug_Dump); + void Debug_Disasm(int argc, const char *argv[]) { @@ -237,6 +242,8 @@ Debug_Disasm(int argc, const char *argv[]) } } +REGISTER_DBGCMD(disasm, "Disassemble", Debug_Disasm); + void Debug_Prompt() { @@ -246,6 +253,11 @@ Debug_Prompt() char buf[DEBUG_MAX_LINE]; kprintf("Entered Debugger!\n"); + /* + * DebugCommand must be 128 bytes for the Section array to align properly + */ + ASSERT(sizeof(DebugCommand) == 128); + while (1) { kprintf("> "); @@ -265,35 +277,26 @@ Debug_Prompt() argv[argc] = nextArg + 1; } - // execute command - if (strcmp(argv[0], "help") == 0) { - Debug_Help(argc, (const char **)argv); - } else if (strcmp(argv[0], "dump") == 0) { - Debug_Dump(argc, (const char **)argv); - } else if (strcmp(argv[0], "registers") == 0) { - Debug_Registers(argc, (const char **)argv); - } else if (strcmp(argv[0], "disasm") == 0) { - Debug_Disasm(argc, (const char **)argv); - } else if (strcmp(argv[0], "reboot") == 0) { - Debug_Reboot(argc, (const char **)argv); - } else if (strcmp(argv[0], "continue") == 0) { + if (strcmp(argv[0], "continue") == 0) { return; // Continue - } else if (strcmp(argv[0], "traps") == 0) { - Debug_Traps(argc, (const char **)argv); - } else if (strcmp(argv[0], "pallocstats") == 0) { - Debug_PAllocStats(argc, (const char **)argv); - } else if (strcmp(argv[0], "pcidump") == 0) { - Debug_PCIDump(argc, (const char **)argv); - } else if (strcmp(argv[0], "pmapdump") == 0) { - Debug_PMapDump(argc, (const char **)argv); - } else if (strcmp(argv[0], "echo") == 0) { - Debug_Echo(argc, (const char **)argv); -#if defined(__amd64__) - } else if (strcmp(argv[0], "lapic") == 0) { - Debug_LAPIC(argc, (const char **)argv); -#endif - } else if (strcmp(argv[0], "") != 0) { - kprintf("Unknown command '%s'\n", argv[0]); + } else { + // execute command + int i; + uintptr_t commands = (uintptr_t)&__kdbgcmd_end - (uintptr_t)&__kdbgcmd_start; + commands /= sizeof(DebugCommand); + DebugCommand *cmds = (DebugCommand *)&__kdbgcmd_start; + bool found = false; + + for (i = 0; i < commands; i++) + { + if (strcmp(argv[0], cmds[i].name) == 0) + { + cmds[i].func(argc, (const char **)argv); + found = true; + } + } + if (!found) + kprintf("Unknown command '%s'\n", argv[0]); } } } diff --git a/sys/kern/palloc.c b/sys/kern/palloc.c index 6fd4442..e03540a 100644 --- a/sys/kern/palloc.c +++ b/sys/kern/palloc.c @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -113,3 +114,5 @@ Debug_PAllocStats(int argc, const char *argv[]) kprintf("Free Pages: %llu\n", freePages); } +REGISTER_DBGCMD(pallocstats, "Page allocator statistics", Debug_PAllocStats); +