ptos/amd64+ke: Add bugcheck support
Signed-off-by: Chloe M <chloe@mensia.org>
This commit is contained in:
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2026, Chloe M.
|
||||||
|
* Provided under the BSD-3 clause.
|
||||||
|
*
|
||||||
|
* Description: AMD64 bugcheck wrapper
|
||||||
|
* Author: Chloe M.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text
|
||||||
|
.globl KeBugCheck
|
||||||
|
KeBugCheck:
|
||||||
|
cli /* Disable interrupts */
|
||||||
|
cld /* Just in case */
|
||||||
|
mov $1, %rax /* Prep the lock */
|
||||||
|
xchg %rax, MpLock /* Acquire the lock */
|
||||||
|
or %rax, %rax /* Are we another core? */
|
||||||
|
jnz .LockOut /* Yes, lock out */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* During most cases in which an interrupt occurs, the processor
|
||||||
|
* is to automatically switch to its own interrupt stack and during
|
||||||
|
* such cases it is guaranteed that the stack is safe. However, we still
|
||||||
|
* cannot trust the stack as we do not know if we are coming from an interrupt
|
||||||
|
* or not and thus need to update it to avoid dodgy states from worsening our
|
||||||
|
* problem... Whatever it is...
|
||||||
|
*/
|
||||||
|
lea StackTop(%rip), %rsp
|
||||||
|
|
||||||
|
/* From here we can call the actual bugcheck handler */
|
||||||
|
call KiBugCheck
|
||||||
|
.LockOut:
|
||||||
|
hlt
|
||||||
|
jmp .LockOut
|
||||||
|
|
||||||
|
.section .data
|
||||||
|
MpLock: .quad 0
|
||||||
|
|
||||||
|
/* Our bugcheck stack */
|
||||||
|
Stack: .fill 4096, 1, 0
|
||||||
|
StackTop:
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2026, Chloe M.
|
||||||
|
* Provided under the BSD-3 clause.
|
||||||
|
*
|
||||||
|
* Description: Bugcheck interface
|
||||||
|
* Author: Chloe M.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _KE_BUGCHECK_H_
|
||||||
|
#define _KE_BUGCHECK_H_ 1
|
||||||
|
|
||||||
|
#include <ptdef.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A list of reasons to why a bug check can happen
|
||||||
|
*
|
||||||
|
* @BUGCHECK_MISC: Misc reason
|
||||||
|
* @BUGCHECK_OOM: Out of memory during critical operation
|
||||||
|
* @BUGCHECK_IO_ERROR: Fatal I/O error
|
||||||
|
* @BUGCHECK_UNBOUND_RESRC: Fatal unbound resource
|
||||||
|
* @BUGCHECK_EXCEPTION: Fatal exception
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
BUGCHECK_MISC,
|
||||||
|
BUGCHECK_OOM,
|
||||||
|
BUGCHECK_IO_ERROR,
|
||||||
|
BUGCHECK_UNBOUND_RESRC,
|
||||||
|
BUGCHECK_EXCEPTION
|
||||||
|
} BUGCHECK_REASON;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Signal to the user that something has gone terribly wrong
|
||||||
|
* during system operation and that the machine needs to come to
|
||||||
|
* a screetching halt.
|
||||||
|
*
|
||||||
|
* @Reason: Broad reason of bugcheck
|
||||||
|
* @Fmt: Format specifier
|
||||||
|
* @<...>: Variadic arguments
|
||||||
|
*/
|
||||||
|
NO_RETURN VOID KeBugCheck(BUGCHECK_REASON Reason, const CHAR *Fmt, ...);
|
||||||
|
|
||||||
|
#endif /* !_KE_BUGCHECK_H_ */
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2026, Chloe M.
|
||||||
|
* Provided under the BSD-3 clause.
|
||||||
|
*
|
||||||
|
* Description: Bugcheck handler
|
||||||
|
* Author: Chloe M.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ex/trace.h>
|
||||||
|
#include <ke/bugcheck.h>
|
||||||
|
#include <drivers/bootvid/fbio.h>
|
||||||
|
#include <ptdef.h>
|
||||||
|
|
||||||
|
/* Used to safely obtain bugcheck reason */
|
||||||
|
#define BUGCHECK_REASON(REASON) \
|
||||||
|
((REASON) >= NELEM(ReasonTable)) \
|
||||||
|
? "bad" \
|
||||||
|
: ReasonTable[(REASON)]
|
||||||
|
|
||||||
|
/* Prints the bugcheck banner */
|
||||||
|
#define BUGCHECK_BANNER() \
|
||||||
|
TRACE( \
|
||||||
|
"\033[31;40m! ***** \033[37;40mBUGCHECK \033[31;40m***** !\033[0m\n" \
|
||||||
|
);
|
||||||
|
|
||||||
|
/* Globals to reduce stack usage */
|
||||||
|
static va_list Ap;
|
||||||
|
static CHAR BugCheckBuf[256];
|
||||||
|
static CHAR BugCheckMsg[] =
|
||||||
|
"Something went wrong during system operation and the machine has\n"
|
||||||
|
"been halted to prevent data loss.\n\n";
|
||||||
|
|
||||||
|
/* Table of reason strings */
|
||||||
|
static CHAR *ReasonTable[] = {
|
||||||
|
[BUGCHECK_MISC] = "misc reason",
|
||||||
|
[BUGCHECK_OOM] = "out of memory",
|
||||||
|
[BUGCHECK_IO_ERROR] = "i/o error",
|
||||||
|
[BUGCHECK_UNBOUND_RESRC] = "unbounded resource",
|
||||||
|
[BUGCHECK_EXCEPTION] = "fatal exception"
|
||||||
|
};
|
||||||
|
|
||||||
|
VOID
|
||||||
|
KiBugCheck(BUGCHECK_REASON Reason, const CHAR *Fmt, ...)
|
||||||
|
{
|
||||||
|
/* Enable the console if we don't have one */
|
||||||
|
if (!BootVidConsEn()) {
|
||||||
|
BootVidInitCons(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_start(Ap, Fmt);
|
||||||
|
VFmtPrintf(BugCheckBuf, sizeof(BugCheckBuf), Fmt, Ap);
|
||||||
|
|
||||||
|
BUGCHECK_BANNER();
|
||||||
|
TRACE("\033[37;40m");
|
||||||
|
TRACE(BugCheckMsg);
|
||||||
|
TRACE("\033[31;40mbugcheck: \033[37;40m%s", BugCheckBuf);
|
||||||
|
TRACE("\033[31;40mreason: \033[37;40m%s\n", BUGCHECK_REASON(Reason));
|
||||||
|
TRACE("\033[37;40m");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user