diff --git a/code/drivers/net/lwip/include/arch/cc.h b/code/drivers/net/lwip/include/arch/cc.h index 4a22cac..d247a64 100644 --- a/code/drivers/net/lwip/include/arch/cc.h +++ b/code/drivers/net/lwip/include/arch/cc.h @@ -35,7 +35,7 @@ typedef uintptr_t sys_prot_t; #define LWIP_PLATFORM_DIAG(x) do { DbgPrint x; } while (0) -#define LWIP_PLATFORM_ASSERT(x) do { KePanic("lwIP assert: %s\n", (x)); } while (0) +#define LWIP_PLATFORM_ASSERT(x) do { KePanic(KE_PANIC_CODE_DRIVER, "lwIP assert: %s\n", (x)); } while (0) unsigned int lwip_port_rand(void); #define LWIP_RAND() ((uint32_t)lwip_port_rand()) diff --git a/code/drivers/net/lwip/lwip_sys_arch.c b/code/drivers/net/lwip/lwip_sys_arch.c index f854747..a77d8cf 100644 --- a/code/drivers/net/lwip/lwip_sys_arch.c +++ b/code/drivers/net/lwip/lwip_sys_arch.c @@ -318,7 +318,7 @@ sys_thread_t sys_thread_new(const char* name, lwip_thread_fn thread, void* arg, (void)stacksize; if (!thread) - KePanic("lwIP: sys_thread_new called with null entry\n"); + KePanic(KE_PANIC_CODE_DRIVER, "lwIP: sys_thread_new called with null entry\n"); THREAD_PRIORITY kp = PriorityNormal; if (prio >= 2) @@ -344,7 +344,7 @@ sys_thread_t sys_thread_new(const char* name, lwip_thread_fn thread, void* arg, kp, &t); if (!KSUCCESS(st)) - KePanic("lwIP: failed to create kernel thread: 0x%x\n", st); + KePanic(KE_PANIC_CODE_DRIVER, "lwIP: failed to create kernel thread: 0x%x\n", st); return (sys_thread_t)t; } diff --git a/code/drivers/storage/ahci/ahci.c b/code/drivers/storage/ahci/ahci.c index 6d1ff34..98d28ad 100644 --- a/code/drivers/storage/ahci/ahci.c +++ b/code/drivers/storage/ahci/ahci.c @@ -860,7 +860,7 @@ static void AhciWorker(uintptr_t arg) { KeWaitSemaphore(drv->irpQueue.Semaphore); IRP *irp = IrpQueueDequeue(&drv->irpQueue); - if (!irp) KePanic("AhciWorker: semaphore fired but queue is empty - IRP accounting bug\n"); + if (!irp) KePanic(KE_PANIC_CODE_DRIVER, "AhciWorker: semaphore fired but queue is empty - IRP accounting bug\n"); bool write = !!(irp->Flags & IRP_FLAG_WRITE); KSTATUS st; diff --git a/code/drivers/storage/ide/ide.c b/code/drivers/storage/ide/ide.c index 7084fad..ffdd6e7 100644 --- a/code/drivers/storage/ide/ide.c +++ b/code/drivers/storage/ide/ide.c @@ -424,7 +424,7 @@ static void IdeWorker(uintptr_t arg) { IRP *irp = IrpQueueDequeue(&gIrpQueue); if (!irp) - KePanic("IdeWorker: semaphore fired but IRP queue is empty — accounting bug\n"); + KePanic(KE_PANIC_CODE_DRIVER, "IdeWorker: semaphore fired but IRP queue is empty — accounting bug\n"); KSTATUS st; if (irp->Lba + irp->SectorCount > gSectorCount) { diff --git a/code/kernel/include/kernel/ke_debug.h b/code/kernel/include/kernel/ke_debug.h index 0498aad..99f84d0 100644 --- a/code/kernel/include/kernel/ke_debug.h +++ b/code/kernel/include/kernel/ke_debug.h @@ -7,7 +7,18 @@ void KeInitDebug(void (*PrintPtr)(char, uint32_t, uint32_t), int v); __declspec(dllexport) void DbgPrint(const char* fmt, ...); __declspec(dllexport) void KePrintConsole(const char* buf, size_t len); -__declspec(dllexport) _Noreturn void KePanic(const char* fmt, ...); + +typedef enum KE_PANIC_CODE { + KE_PANIC_CODE_GENERIC = 0, + KE_PANIC_CODE_FAULT = 1, + KE_PANIC_CODE_IRQL = 2, + KE_PANIC_CODE_SELFTEST = 3, + KE_PANIC_CODE_TRAP = 4, + KE_PANIC_CODE_DRIVER = 5, + KE_PANIC_CODE_INIT = 6, +} KE_PANIC_CODE; + +__declspec(dllexport) _Noreturn void KePanic(int code, const char* fmt, ...); // --------------------------------------------------------------------------- // Fault dispatch - called from the IDT fault stubs (ke_syscall.asm). diff --git a/code/kernel/ke_debug.c b/code/kernel/ke_debug.c index 9e14946..1b2996a 100644 --- a/code/kernel/ke_debug.c +++ b/code/kernel/ke_debug.c @@ -38,7 +38,7 @@ __declspec(dllexport) void DbgPrint(const char* fmt, ...) { } // KePanic -__declspec(dllexport) _Noreturn void KePanic(const char* fmt, ...) { +__declspec(dllexport) _Noreturn void KePanic(int code, const char* fmt, ...) { // Silence! Stop the world! _disable(); @@ -49,7 +49,9 @@ __declspec(dllexport) _Noreturn void KePanic(const char* fmt, ...) { for (const char* p = banner; *p; p++) PrintChar(*p, 0xFF2222, 0x000000); - // Now print the caller's message through the normal vprintf path. + // Print the panic code first, then the caller's message through the normal vprintf path. + printf("Panic code: %d\n", code); + va_list va; va_start(va, fmt); vprintf(fmt, va); @@ -436,7 +438,7 @@ __declspec(dllexport) _Noreturn void KeFaultDispatchFrame(const KFAULT_FRAME* fr PROCESS* proc = thread ? thread->Owner : (PROCESS*)0; if (!frame || frame->Magic != 0x3146544C5541464BULL) { - KePanic("PANIC: bad KFAULT_FRAME %016llx\n", + KePanic(KE_PANIC_CODE_FAULT, "PANIC: bad KFAULT_FRAME %016llx\n", (unsigned long long)(uintptr_t)frame); } @@ -445,18 +447,18 @@ __declspec(dllexport) _Noreturn void KeFaultDispatchFrame(const KFAULT_FRAME* fr const char* name = KiFaultVectorName(vector); if (vector == 14) { - KePanic("PANIC: %s | RIP: %016llx | Code: %04llx | CR2: %016llx\n", + KePanic(KE_PANIC_CODE_FAULT, "PANIC: %s | RIP: %016llx | Code: %04llx | CR2: %016llx\n", name, (unsigned long long)frame->Rip, (unsigned long long)frame->ErrorCode, (unsigned long long)frame->Cr2); } else if (KiFaultHasErrorCode(vector)) { - KePanic("PANIC: %s | RIP: %016llx | Code: %04llx\n", + KePanic(KE_PANIC_CODE_FAULT, "PANIC: %s | RIP: %016llx | Code: %04llx\n", name, (unsigned long long)frame->Rip, (unsigned long long)frame->ErrorCode); } else { - KePanic("PANIC: %s | RIP: %016llx\n", + KePanic(KE_PANIC_CODE_FAULT, "PANIC: %s | RIP: %016llx\n", name, (unsigned long long)frame->Rip); } @@ -476,7 +478,7 @@ __declspec(dllexport) _Noreturn void KeFaultDispatchFrame(const KFAULT_FRAME* fr // KeFaultDispatch - single C entry point for all three IDT fault stubs. // // The asm stubs (ke_syscall.asm) collect the CPU exception frame values and -// call here. We check the CS RPL to decide: kernel fault → KePanic (halt), +// call here. We check the CS RPL to decide: kernel fault → panic and halt, // user fault → KeBugCheckProcess (kill process, resume scheduler). // --------------------------------------------------------------------------- __declspec(dllexport) _Noreturn void KeFaultDispatch(int vector, uintptr_t rip, diff --git a/code/kernel/ke_irql.c b/code/kernel/ke_irql.c index 2d72ce7..fa4149c 100644 --- a/code/kernel/ke_irql.c +++ b/code/kernel/ke_irql.c @@ -26,11 +26,11 @@ __declspec(dllexport) KIRQL KeRaiseIrql(KIRQL newIrql) { KIRQL oldIrql = cpu->CurrentIrql; if (newIrql > HIGH_LEVEL) { - KePanic("KeRaiseIrql: invalid target IRQL %u\n", (unsigned)newIrql); + KePanic(KE_PANIC_CODE_IRQL, "KeRaiseIrql: invalid target IRQL %u\n", (unsigned)newIrql); } if (newIrql < oldIrql) { - KePanic("KeRaiseIrql: attempted raise from %s(%u) down to %s(%u)\n", + KePanic(KE_PANIC_CODE_IRQL, "KeRaiseIrql: attempted raise from %s(%u) down to %s(%u)\n", KeIrqlName(oldIrql), (unsigned)oldIrql, KeIrqlName(newIrql), (unsigned)newIrql); } @@ -44,11 +44,11 @@ __declspec(dllexport) void KeLowerIrql(KIRQL oldIrql) { KIRQL currentIrql = cpu->CurrentIrql; if (oldIrql > HIGH_LEVEL) { - KePanic("KeLowerIrql: invalid target IRQL %u\n", (unsigned)oldIrql); + KePanic(KE_PANIC_CODE_IRQL, "KeLowerIrql: invalid target IRQL %u\n", (unsigned)oldIrql); } if (oldIrql > currentIrql) { - KePanic("KeLowerIrql: attempted lower from %s(%u) up to %s(%u)\n", + KePanic(KE_PANIC_CODE_IRQL, "KeLowerIrql: attempted lower from %s(%u) up to %s(%u)\n", KeIrqlName(currentIrql), (unsigned)currentIrql, KeIrqlName(oldIrql), (unsigned)oldIrql); } @@ -62,7 +62,7 @@ __declspec(dllexport) void KeLowerIrql(KIRQL oldIrql) { __declspec(dllexport) void KeAssertIrql(KIRQL expected) { KIRQL currentIrql = KeGetCurrentIrql(); if (currentIrql != expected) { - KePanic("IRQL assertion failed: expected %s(%u), current %s(%u)\n", + KePanic(KE_PANIC_CODE_IRQL, "IRQL assertion failed: expected %s(%u), current %s(%u)\n", KeIrqlName(expected), (unsigned)expected, KeIrqlName(currentIrql), (unsigned)currentIrql); } @@ -71,7 +71,7 @@ __declspec(dllexport) void KeAssertIrql(KIRQL expected) { __declspec(dllexport) void KeAssertIrqlAtOrBelow(KIRQL maxIrql) { KIRQL currentIrql = KeGetCurrentIrql(); if (currentIrql > maxIrql) { - KePanic("IRQL assertion failed: expected <= %s(%u), current %s(%u)\n", + KePanic(KE_PANIC_CODE_IRQL, "IRQL assertion failed: expected <= %s(%u), current %s(%u)\n", KeIrqlName(maxIrql), (unsigned)maxIrql, KeIrqlName(currentIrql), (unsigned)currentIrql); } diff --git a/code/kernel/ke_selftest.c b/code/kernel/ke_selftest.c index 951700b..9cb9766 100644 --- a/code/kernel/ke_selftest.c +++ b/code/kernel/ke_selftest.c @@ -61,7 +61,7 @@ static void KiApcSelfTestNormalRoutine(void* normalContext, KeGetCurrentIrql()); if (KeGetCurrentIrql() != PASSIVE_LEVEL) - KePanic("APC selftest: normal routine ran above PASSIVE_LEVEL\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: normal routine ran above PASSIVE_LEVEL\n"); (*counter)++; } @@ -77,7 +77,7 @@ static void KiApcSelfTestCrossThreadRoutine(void* normalContext, KeGetCurrentIrql()); if (KeGetCurrentIrql() != PASSIVE_LEVEL) - KePanic("APC selftest: cross-thread APC ran above PASSIVE_LEVEL\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: cross-thread APC ran above PASSIVE_LEVEL\n"); st->CrossDelivered++; KeSignalEvent(st->DoneEvent); @@ -92,7 +92,7 @@ static void KiApcSelfTestWorker(void* arg) { DbgPrint("APC selftest: worker waiting for go event\n"); KSTATUS s = KeWaitForEvent(st->GoEvent, 0); if (!KSUCCESS(s)) - KePanic("APC selftest: worker wait failed status=%d\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: worker wait failed status=%d\n", s); // KeCommitBlockThread(..., alertable) should deliver pending kernel APCs before this // wait returns. If that hook is broken, DoneEvent will never be signaled. @@ -100,7 +100,7 @@ static void KiApcSelfTestWorker(void* arg) { st->CrossDelivered); if (st->CrossDelivered != 1) - KePanic("APC selftest: worker resumed but APC was not delivered\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: worker resumed but APC was not delivered\n"); KeSignalEvent(st->FinishedEvent); KeExitThread(KeGetCurrentThread(), 0); @@ -128,7 +128,7 @@ static void KiApcAlertableSelfTestNormalRoutine(void* normalContext, KeGetCurrentIrql()); if (KeGetCurrentIrql() != PASSIVE_LEVEL) - KePanic("APC selftest: alertable APC ran above PASSIVE_LEVEL\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alertable APC ran above PASSIVE_LEVEL\n"); st->ApcDelivered++; } @@ -147,10 +147,10 @@ static void KiApcAlertableSelfTestWorker(void* arg) { s, st->ApcDelivered); if (s != STATUS_KERNEL_APC) - KePanic("APC selftest: alertable wait returned wrong status=%u\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alertable wait returned wrong status=%u\n", s); if (st->ApcDelivered != 1) - KePanic("APC selftest: alertable APC delivery count wrong=%d\n", + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alertable APC delivery count wrong=%d\n", st->ApcDelivered); KeSignalEvent(st->FinishedEvent); @@ -161,11 +161,11 @@ static void KiRunKernelApcSelfTest(void) { DbgPrint("APC selftest: begin\n"); if (KeGetCurrentIrql() != PASSIVE_LEVEL) - KePanic("APC selftest: called above PASSIVE_LEVEL\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: called above PASSIVE_LEVEL\n"); THREAD* self = KeGetCurrentThread(); if (!self) - KePanic("APC selftest: no current thread\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: no current thread\n"); // Test 1: queue APC to current thread at PASSIVE_LEVEL. { @@ -179,10 +179,10 @@ static void KiRunKernelApcSelfTest(void) { (void*)&count); if (!KeInsertQueueApc(&apc, (void*)0x11111111, (void*)0x22222222)) - KePanic("APC selftest: self queue failed\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: self queue failed\n"); if (count != 1) - KePanic("APC selftest: self APC was not delivered immediately, count=%d\n", count); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: self APC was not delivered immediately, count=%d\n", count); DbgPrint("APC selftest: self APC passed\n"); } @@ -201,15 +201,15 @@ static void KiRunKernelApcSelfTest(void) { KeEnterCriticalRegion(); if (!KeInsertQueueApc(&apc, (void*)0x33333333, (void*)0x44444444)) - KePanic("APC selftest: deferred queue failed\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: deferred queue failed\n"); if (count != 0) - KePanic("APC selftest: APC delivered while critical region held, count=%d\n", count); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: APC delivered while critical region held, count=%d\n", count); KeLeaveCriticalRegion(); if (count != 1) - KePanic("APC selftest: deferred APC was not delivered after leave, count=%d\n", count); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: deferred APC was not delivered after leave, count=%d\n", count); DbgPrint("APC selftest: critical-region deferral passed\n"); } @@ -222,27 +222,27 @@ static void KiRunKernelApcSelfTest(void) { KSTATUS s; s = KeEventCreate(EventAutoReset, 0, &st.ReadyEvent); - if (!KSUCCESS(s)) KePanic("APC selftest: ReadyEvent create failed %d\n", s); + if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: ReadyEvent create failed %d\n", s); s = KeEventCreate(EventAutoReset, 0, &st.GoEvent); - if (!KSUCCESS(s)) KePanic("APC selftest: GoEvent create failed %d\n", s); + if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: GoEvent create failed %d\n", s); s = KeEventCreate(EventAutoReset, 0, &st.DoneEvent); - if (!KSUCCESS(s)) KePanic("APC selftest: DoneEvent create failed %d\n", s); + if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: DoneEvent create failed %d\n", s); s = KeEventCreate(EventAutoReset, 0, &st.FinishedEvent); - if (!KSUCCESS(s)) KePanic("APC selftest: FinishedEvent create failed %d\n", s); + if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: FinishedEvent create failed %d\n", s); s = KeCreateKernelThread((uintptr_t)KiApcSelfTestWorker, (uintptr_t)&st, PriorityNormal, &st.WorkerThread); if (!KSUCCESS(s)) - KePanic("APC selftest: worker create failed %d\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: worker create failed %d\n", s); s = KeWaitForEvent(st.ReadyEvent, 0); if (!KSUCCESS(s)) - KePanic("APC selftest: ready wait failed %d\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: ready wait failed %d\n", s); DbgPrint("APC selftest: worker ready, queueing cross-thread APC\n"); @@ -253,19 +253,19 @@ static void KiRunKernelApcSelfTest(void) { (void*)&st); if (!KeInsertQueueApc(&apc, (void*)0x55555555, (void*)0x66666666)) - KePanic("APC selftest: cross-thread queue failed\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: cross-thread queue failed\n"); if (st.CrossDelivered != 0) - KePanic("APC selftest: cross-thread APC delivered before target resumed\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: cross-thread APC delivered before target resumed\n"); KeSignalEvent(st.GoEvent); s = KeWaitForEvent(st.DoneEvent, 0); if (!KSUCCESS(s)) - KePanic("APC selftest: done wait failed %d\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: done wait failed %d\n", s); if (st.CrossDelivered != 1) - KePanic("APC selftest: cross-thread delivery count wrong, count=%d\n", + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: cross-thread delivery count wrong, count=%d\n", st.CrossDelivered); // The APC signals DoneEvent before the worker returns from the wait. @@ -274,7 +274,7 @@ static void KiRunKernelApcSelfTest(void) { // kernel-thread contract on all builds. s = KeWaitForEvent(st.FinishedEvent, 0); if (!KSUCCESS(s)) - KePanic("APC selftest: worker finished wait failed %d\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: worker finished wait failed %d\n", s); DbgPrint("APC selftest: cross-thread APC passed\n"); @@ -295,24 +295,24 @@ static void KiRunKernelApcSelfTest(void) { KSTATUS s; s = KeEventCreate(EventAutoReset, 0, &st.ReadyEvent); - if (!KSUCCESS(s)) KePanic("APC selftest: alert ReadyEvent create failed %d\n", s); + if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alert ReadyEvent create failed %d\n", s); s = KeEventCreate(EventAutoReset, 0, &st.WaitEvent); - if (!KSUCCESS(s)) KePanic("APC selftest: alert WaitEvent create failed %d\n", s); + if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alert WaitEvent create failed %d\n", s); s = KeEventCreate(EventAutoReset, 0, &st.FinishedEvent); - if (!KSUCCESS(s)) KePanic("APC selftest: alert FinishedEvent create failed %d\n", s); + if (!KSUCCESS(s)) KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alert FinishedEvent create failed %d\n", s); s = KeCreateKernelThread((uintptr_t)KiApcAlertableSelfTestWorker, (uintptr_t)&st, PriorityNormal, &st.WorkerThread); if (!KSUCCESS(s)) - KePanic("APC selftest: alertable worker create failed %d\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alertable worker create failed %d\n", s); s = KeWaitForEvent(st.ReadyEvent, 0); if (!KSUCCESS(s)) - KePanic("APC selftest: alert ready wait failed %d\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alert ready wait failed %d\n", s); DbgPrint("APC selftest: queueing APC to alertable waiter\n"); @@ -323,14 +323,14 @@ static void KiRunKernelApcSelfTest(void) { (void*)&st); if (!KeInsertQueueApc(&apc, (void*)(unsigned long long)0x77777777, (void*)(unsigned long long)0x88888888)) - KePanic("APC selftest: alertable APC queue failed\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alertable APC queue failed\n"); s = KeWaitForEvent(st.FinishedEvent, 0); if (!KSUCCESS(s)) - KePanic("APC selftest: alert finished wait failed %d\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alert finished wait failed %d\n", s); if (st.WaitStatus != STATUS_KERNEL_APC || st.ApcDelivered != 1) - KePanic("APC selftest: alertable result bad status=%u delivered=%d\n", + KePanic(KE_PANIC_CODE_SELFTEST, "APC selftest: alertable result bad status=%u delivered=%d\n", st.WaitStatus, st.ApcDelivered); DbgPrint("APC selftest: alertable wait passed\n"); @@ -388,10 +388,10 @@ static void KiIrpApcSelfTestNormalRoutine(void* normalContext, KeGetCurrentIrql()); if (KeGetCurrentIrql() != PASSIVE_LEVEL) - KePanic("IRP/APC selftest: normal routine ran above PASSIVE_LEVEL\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: normal routine ran above PASSIVE_LEVEL\n"); if (irp != &st->Irp) - KePanic("IRP/APC selftest: APC arg1 was not the submitted IRP\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: APC arg1 was not the submitted IRP\n"); st->ApcDelivered++; st->ApcStatus = status; @@ -408,18 +408,18 @@ static void KiRunIrpKernelApcSelfTest(const HAL_API* hal) { } if (KeGetCurrentIrql() != PASSIVE_LEVEL) - KePanic("IRP/APC selftest: called above PASSIVE_LEVEL\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: called above PASSIVE_LEVEL\n"); KI_IRP_APC_SELFTEST_STATE st; memset(&st, 0, sizeof(st)); KSTATUS s = KeEventCreate(EventAutoReset, 0, &st.CompletionEvent); if (!KSUCCESS(s)) - KePanic("IRP/APC selftest: completion event create failed %u\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: completion event create failed %u\n", s); st.Buffer = (uint8_t*)MmAllocatePool(512); if (!st.Buffer) - KePanic("IRP/APC selftest: no buffer\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: no buffer\n"); memset(st.Buffer, 0xCC, 512); KeInitializeApc(&st.Apc, @@ -446,23 +446,23 @@ static void KiRunIrpKernelApcSelfTest(const HAL_API* hal) { DbgPrint("IRP/APC selftest: submitting drive=0 lba=0 sectors=1\n"); s = IoSubmitIrp(&st.Irp); if (s != STATUS_PENDING) - KePanic("IRP/APC selftest: IoSubmitIrp returned %u\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: IoSubmitIrp returned %u\n", s); s = KeWaitForEvent(st.CompletionEvent, 0); if (!KSUCCESS(s)) - KePanic("IRP/APC selftest: completion wait failed %u\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: completion wait failed %u\n", s); // The wait return path should have delivered the pending kernel APC. if (st.ApcDelivered != 1) - KePanic("IRP/APC selftest: APC was not delivered after I/O wait, count=%d\n", + KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: APC was not delivered after I/O wait, count=%d\n", st.ApcDelivered); if (!KSUCCESS(st.Irp.Status) || !KSUCCESS(st.ApcStatus)) - KePanic("IRP/APC selftest: I/O failed irp=%u apc=%u info=%llu\n", + KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: I/O failed irp=%u apc=%u info=%llu\n", st.Irp.Status, st.ApcStatus, (uint64_t)st.Irp.Information); if (st.Irp.Information != 512 || st.ApcInformation != 512) - KePanic("IRP/APC selftest: wrong byte count irp=%llu apc=%llu\n", + KePanic(KE_PANIC_CODE_SELFTEST, "IRP/APC selftest: wrong byte count irp=%llu apc=%llu\n", (uint64_t)st.Irp.Information, (uint64_t)st.ApcInformation); DbgPrint("IRP/APC selftest: first bytes %02X %02X %02X %02X, tail %02X %02X\n", @@ -486,7 +486,7 @@ static void KiRunMemoryMappingSelfTest(void) { uint64_t flags = 0; KSTATUS s = MmQueryPage(0, &phys, &flags); if (s != STATUS_NOT_FOUND) { - KePanic("MM selftest: virtual page zero is mapped phys=%016llx flags=%016llx status=%u\n", + KePanic(KE_PANIC_CODE_SELFTEST, "MM selftest: virtual page zero is mapped phys=%016llx flags=%016llx status=%u\n", (unsigned long long)phys, (unsigned long long)flags, (unsigned)s); @@ -503,28 +503,28 @@ static void KiRunStringViewSelfTest(void) { SYS_STRING_VIEW hello = SYS_SV_LITERAL("Hello"); if (hello.Length != 5 || !SysSvEqualLit(hello, "Hello")) - KePanic("STRINGVIEW selftest: literal/equality failed\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "STRINGVIEW selftest: literal/equality failed\n"); static const char embedded[] = { 'a', 'b', '\0', 'c', 'd' }; SYS_STRING_VIEW emb = SysSvFromParts(embedded, sizeof(embedded)); if (emb.Length != 5 || !SysSvContainsByte(emb, '\0')) - KePanic("STRINGVIEW selftest: embedded-NUL detection failed\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "STRINGVIEW selftest: embedded-NUL detection failed\n"); char copy[6]; if (!SysSvCopyZ(copy, sizeof(copy), emb)) - KePanic("STRINGVIEW selftest: bounded copy failed\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "STRINGVIEW selftest: bounded copy failed\n"); if (memcmp(copy, embedded, sizeof(embedded)) != 0 || copy[5] != '\0') - KePanic("STRINGVIEW selftest: bounded copy contents wrong\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "STRINGVIEW selftest: bounded copy contents wrong\n"); if (SysSvCopyZ(copy, 4, emb)) - KePanic("STRINGVIEW selftest: undersized copy unexpectedly succeeded\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "STRINGVIEW selftest: undersized copy unexpectedly succeeded\n"); // Paths are string views at the ABI boundary, but FAT/VFS path names do not // accept embedded NUL bytes. This must fail before reaching any filesystem. FILE_OBJECT* f = (FILE_OBJECT*)0; KSTATUS s = IoOpenFile(SysSvFromParts("system/init.exe\0junk", 20), &f); if (s != STATUS_INVALID_PARAMETER) - KePanic("STRINGVIEW selftest: embedded-NUL path status=%u\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "STRINGVIEW selftest: embedded-NUL path status=%u\n", s); DbgPrint("STRINGVIEW selftest: sample view='%v' len=%llu\n", hello, (uint64_t)hello.Length); @@ -576,7 +576,7 @@ static void KiFileAsyncSelfTestNormalRoutine(void* normalContext, KeGetCurrentIrql()); if (KeGetCurrentIrql() != PASSIVE_LEVEL) - KePanic("FILE/ASYNC selftest: APC ran above PASSIVE_LEVEL\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: APC ran above PASSIVE_LEVEL\n"); st->ApcDelivered++; st->ApcStatus = status; @@ -597,11 +597,11 @@ static void KiRunAsyncFileIoSelfTest(void) { s = KeEventCreate(EventAutoReset, 0, &st.CompletionEvent); if (!KSUCCESS(s)) - KePanic("FILE/ASYNC selftest: event create failed %u\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: event create failed %u\n", s); st.Buffer = (uint8_t*)MmAllocatePool(512); if (!st.Buffer) - KePanic("FILE/ASYNC selftest: no buffer\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: no buffer\n"); memset(st.Buffer, 0xCC, 512); KeInitializeApc(&st.Apc, @@ -621,27 +621,27 @@ static void KiRunAsyncFileIoSelfTest(void) { &st.Apc, &readReq); if (s != STATUS_PENDING) - KePanic("FILE/ASYNC selftest: submit returned %u\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: submit returned %u\n", s); s = KeWaitForEvent(st.CompletionEvent, 1); if (s != STATUS_SUCCESS && s != STATUS_KERNEL_APC) - KePanic("FILE/ASYNC selftest: wait returned %u\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: wait returned %u\n", s); if (st.Iosb.Status == STATUS_PENDING) { s = KeWaitForEvent(st.CompletionEvent, 0); if (!KSUCCESS(s)) - KePanic("FILE/ASYNC selftest: final event wait returned %u\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: final event wait returned %u\n", s); } if (st.ApcDelivered != 1) - KePanic("FILE/ASYNC selftest: APC not delivered count=%d\n", st.ApcDelivered); + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: APC not delivered count=%d\n", st.ApcDelivered); if (!KSUCCESS(st.Iosb.Status) || !KSUCCESS(st.ApcStatus)) - KePanic("FILE/ASYNC selftest: I/O failed iosb=%u apc=%u info=%llu\n", + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: I/O failed iosb=%u apc=%u info=%llu\n", st.Iosb.Status, st.ApcStatus, (uint64_t)st.Iosb.Information); if (st.Iosb.Information < 2 || st.Buffer[0] != 'M' || st.Buffer[1] != 'Z') - KePanic("FILE/ASYNC selftest: bad file header info=%llu bytes=%02X %02X\n", + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: bad file header info=%llu bytes=%02X %02X\n", (uint64_t)st.Iosb.Information, st.Buffer[0], st.Buffer[1]); DbgPrint("FILE/ASYNC selftest: first bytes %02X %02X %02X %02X info=%llu wait=%u\n", @@ -671,11 +671,11 @@ static void KiRunAsyncFileIoSelfTest(void) { s = IoCreateFile(SYS_SV_LITERAL("asyncio.tmp"), &wf); if (!KSUCCESS(s)) - KePanic("FILE/ASYNC selftest: create write temp failed %u\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: create write temp failed %u\n", s); s = KeEventCreate(EventAutoReset, 0, &wev); if (!KSUCCESS(s)) - KePanic("FILE/ASYNC selftest: write event create failed %u\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: write event create failed %u\n", s); DbgPrint("FILE/ASYNC selftest: submit write asyncio.tmp size=%llu\n", (uint64_t)(sizeof(payload) - 1)); @@ -690,14 +690,14 @@ static void KiRunAsyncFileIoSelfTest(void) { (KAPC*)0, &writeReq); if (s != STATUS_PENDING) - KePanic("FILE/ASYNC selftest: write submit returned %u\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: write submit returned %u\n", s); s = KeWaitForEvent(wev, 1); if (!KSUCCESS(s)) - KePanic("FILE/ASYNC selftest: write wait returned %u\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: write wait returned %u\n", s); if (!KSUCCESS(wiosb.Status) || wiosb.Information != sizeof(payload) - 1) - KePanic("FILE/ASYNC selftest: write failed status=%u info=%llu\n", + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: write failed status=%u info=%llu\n", wiosb.Status, (uint64_t)wiosb.Information); if (writeReq) @@ -708,12 +708,12 @@ static void KiRunAsyncFileIoSelfTest(void) { s = IoOpenFile(SYS_SV_LITERAL("asyncio.tmp"), &rf); if (!KSUCCESS(s)) - KePanic("FILE/ASYNC selftest: reopen write temp failed %u\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: reopen write temp failed %u\n", s); s = IoReadFileAt(rf, 0, verify, sizeof(payload) - 1, &got); if (!KSUCCESS(s) || got != sizeof(payload) - 1 || memcmp(verify, payload, sizeof(payload) - 1) != 0) { - KePanic("FILE/ASYNC selftest: verify failed status=%u got=%llu\n", + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: verify failed status=%u got=%llu\n", s, (uint64_t)got); } @@ -721,7 +721,7 @@ static void KiRunAsyncFileIoSelfTest(void) { ObDereferenceObject(&wev->Header); s = IoDeleteFile(SYS_SV_LITERAL("asyncio.tmp")); if (!KSUCCESS(s)) - KePanic("FILE/ASYNC selftest: delete temp failed %u\n", s); + KePanic(KE_PANIC_CODE_SELFTEST, "FILE/ASYNC selftest: delete temp failed %u\n", s); DbgPrint("FILE/ASYNC selftest: async write verified\n"); } @@ -734,14 +734,14 @@ static void KiRunTrapFrameSelfTest(void) { DbgPrint("TRAP selftest: begin\n"); if (KeGetCurrentTrapFrame()) - KePanic("TRAP selftest: kernel selftest unexpectedly has active trap frame\n"); + KePanic(KE_PANIC_CODE_SELFTEST, "TRAP selftest: kernel selftest unexpectedly has active trap frame\n"); DbgPrint("TRAP selftest: frame size=%llu query size=%llu\n", (uint64_t)sizeof(KTRAP_FRAME), (uint64_t)sizeof(SYS_TRAP_FRAME_INFO_K)); if (sizeof(KTRAP_FRAME) != 240) - KePanic("TRAP selftest: KTRAP_FRAME size mismatch %llu\n", + KePanic(KE_PANIC_CODE_SELFTEST, "TRAP selftest: KTRAP_FRAME size mismatch %llu\n", (uint64_t)sizeof(KTRAP_FRAME)); DbgPrint("TRAP selftest: PASS\n"); diff --git a/code/kernel/ke_trap.c b/code/kernel/ke_trap.c index d148aa7..ed8612b 100644 --- a/code/kernel/ke_trap.c +++ b/code/kernel/ke_trap.c @@ -57,7 +57,7 @@ KTRAP_FRAME* KeGetCurrentTrapFrame(void) { void KiEnterTrapFrame(KTRAP_FRAME* frame) { if (!frame || frame->Magic != KTRAP_FRAME_MAGIC) - KePanic("KiEnterTrapFrame: invalid trap frame 0x%llX\n", (uint64_t)frame); + KePanic(KE_PANIC_CODE_TRAP, "KiEnterTrapFrame: invalid trap frame 0x%llX\n", (uint64_t)frame); THREAD* t = KeGetCurrentThread(); if (!t) return; @@ -69,7 +69,7 @@ void KiEnterTrapFrame(KTRAP_FRAME* frame) { void KiExitTrapFrame(KTRAP_FRAME* frame) { if (!frame || frame->Magic != KTRAP_FRAME_MAGIC) - KePanic("KiExitTrapFrame: invalid trap frame 0x%llX\n", (uint64_t)frame); + KePanic(KE_PANIC_CODE_TRAP, "KiExitTrapFrame: invalid trap frame 0x%llX\n", (uint64_t)frame); // Give alertable user-mode returns a chance to redirect through the // registered user APC dispatcher before committing IRET slots. @@ -86,7 +86,7 @@ void KiExitTrapFrame(KTRAP_FRAME* frame) { THREAD* t = KeGetCurrentThread(); if (t) { if (t->TrapFrame != frame) - KePanic("KiExitTrapFrame: trap-frame stack mismatch top=0x%llX frame=0x%llX\n", + KePanic(KE_PANIC_CODE_TRAP, "KiExitTrapFrame: trap-frame stack mismatch top=0x%llX frame=0x%llX\n", (uint64_t)t->TrapFrame, (uint64_t)frame); t->TrapFrame = frame->PreviousFrame; } @@ -97,17 +97,17 @@ void KiValidateSyscallTrapFrame(uint64_t nr, uint64_t a0, uint64_t a1, uint64_t a5) { KTRAP_FRAME* f = KeGetCurrentTrapFrame(); if (!f) - KePanic("syscall trap validation: no current trap frame for nr=%llu\n", nr); + KePanic(KE_PANIC_CODE_TRAP, "syscall trap validation: no current trap frame for nr=%llu\n", nr); if (f->Magic != KTRAP_FRAME_MAGIC) - KePanic("syscall trap validation: bad magic 0x%llX\n", f->Magic); + KePanic(KE_PANIC_CODE_TRAP, "syscall trap validation: bad magic 0x%llX\n", f->Magic); if (f->Kind != KTRAP_KIND_SYSCALL) - KePanic("syscall trap validation: kind=%u, expected syscall\n", f->Kind); + KePanic(KE_PANIC_CODE_TRAP, "syscall trap validation: kind=%u, expected syscall\n", f->Kind); if (!KeTrapFrameFromUser(f) || f->PreviousMode != KTRAP_MODE_USER) - KePanic("syscall trap validation: syscall did not come from user cs=0x%llX mode=%u\n", + KePanic(KE_PANIC_CODE_TRAP, "syscall trap validation: syscall did not come from user cs=0x%llX mode=%u\n", f->Cs, f->PreviousMode); if (f->Rax != nr || f->Rcx != a0 || f->Rdx != a1 || f->R8 != a2 || f->R9 != a3 || f->R10 != a4 || f->R11 != a5) { - KePanic("syscall trap validation: arg mismatch nr=%llu tf=%llu/%llX/%llX/%llX/%llX/%llX/%llX call=%llu/%llX/%llX/%llX/%llX/%llX/%llX\n", + KePanic(KE_PANIC_CODE_TRAP, "syscall trap validation: arg mismatch nr=%llu tf=%llu/%llX/%llX/%llX/%llX/%llX/%llX call=%llu/%llX/%llX/%llX/%llX/%llX/%llX\n", nr, f->Rax, f->Rcx, f->Rdx, f->R8, f->R9, f->R10, f->R11, nr, a0, a1, a2, a3, a4, a5); diff --git a/code/kernel/kmain.c b/code/kernel/kmain.c index 9601ec8..1965375 100644 --- a/code/kernel/kmain.c +++ b/code/kernel/kmain.c @@ -191,7 +191,7 @@ static void KiInitializeDrivers(BOOT_INFO* bootInfo, const HAL_API* hal) { s = IoOpenFile(SYS_SV_LITERAL("drivers\\drivers.ini"), &f); if (s != STATUS_SUCCESS) { - KePanic("KiInitializeDrivers: Failed to open drivers.ini (status %d)\n", s); + KePanic(KE_PANIC_CODE_INIT, "KiInitializeDrivers: Failed to open drivers.ini (status %d)\n", s); } uint64_t size = IoGetFileSize(f) + 1; @@ -199,7 +199,7 @@ static void KiInitializeDrivers(BOOT_INFO* bootInfo, const HAL_API* hal) { size_t got; if (!KSUCCESS(IoReadFile(f, mem, size, &got))) { IoCloseFile(f); - KePanic("KiInitializeDrivers: Failed to read drivers.ini\n"); + KePanic(KE_PANIC_CODE_INIT, "KiInitializeDrivers: Failed to read drivers.ini\n"); } mem[got] = '\0'; @@ -513,7 +513,7 @@ extern void KernelMain(BOOT_INFO* bootInfo) { PriorityNormal, &initThread); if (!KSUCCESS(st)) { - KePanic("KernelMain: Failed to create SystemInitThread (status 0x%x)\n", st); + KePanic(KE_PANIC_CODE_INIT, "KernelMain: Failed to create SystemInitThread (status 0x%x)\n", st); } DbgPrint("KernelMain: Handing over to scheduler...\n");