add display subsystem and vmwaresvga driver, support absolute mouse and qemu tablet, map pci mmio to private virtual aperture, better smp panic handling, remove legacy io publish/match, add sys query display info and display command to native shell

This commit is contained in:
maksw committed 2026-06-15 09:58:12 +02:00
1 parent e41bf6e2c0
commit 6260de0085
38 files changed
+4011 -467

No files matched your search

+52 -12
View File
@@ -61,6 +61,7 @@ static void KiDebugConsoleWrite(const char* text, size_t len) {
}
static volatile long gPanicInProgress = 0;
static volatile uintptr_t gPanicOwnerToken = 0;
static volatile long gPanicStoppedCpuCount = 0;
static _Noreturn void KiPanicSecondaryHalt(void) {
@@ -69,10 +70,36 @@ static _Noreturn void KiPanicSecondaryHalt(void) {
for (;;) __halt();
}
static uintptr_t KiPanicCurrentToken(void) {
THREAD* thread = KeGetCurrentThread();
if (thread)
return (uintptr_t)thread;
KCPU* cpu = KeGetCurrentCpu();
if (cpu)
return (uintptr_t)cpu;
return 1u;
}
static int KiPanicIsActive(void) {
return _InterlockedCompareExchange((volatile long*)&gPanicInProgress, 0, 0) != 0;
}
static int KiPanicCurrentCpuOwnsReport(void) {
uintptr_t token = KiPanicCurrentToken();
return token != 0 && gPanicOwnerToken == token;
}
static void KiBeginFatalReport(void) {
_disable();
uintptr_t token = KiPanicCurrentToken();
if (_InterlockedCompareExchange((volatile long*)&gPanicInProgress, 1, 0) == 0) {
gPanicOwnerToken = token;
return;
}
if (gPanicOwnerToken != token)
KiPanicSecondaryHalt();
}
// Returning NMI handler used for SMP control IPIs. Panic NMIs stop the
// target CPU permanently; TLB shootdown NMIs flush and return. A genuinely
// unexpected NMI is not handled here and will fall through to the normal fault
@@ -88,7 +115,8 @@ __declspec(dllexport) int KeHandleNmiIpi(void) {
}
void KiKernelPutChar(char c) {
PrintChar(c, 0xCCCCCC, 0x012456);
if (PrintChar)
PrintChar(c, 0xCCCCCC, 0x012456);
}
void KeInitDebug(void (*PrintPtr)(char, uint32_t, uint32_t), uint32_t flags) {
@@ -112,6 +140,13 @@ uint32_t KeGetDebugFlags(void) {
return gDebugFlags;
}
void KeSetDebugConsoleWriter(void (*PrintPtr)(char, uint32_t, uint32_t)) {
if (!PrintPtr)
return;
PrintChar = PrintPtr;
printf_set_putchar(KiKernelPutChar);
}
__declspec(dllexport) void DbgPrint(const char* fmt, ...) {
if (!gDebugEnabled || !fmt) return;
@@ -128,6 +163,14 @@ __declspec(dllexport) void DbgPrint(const char* fmt, ...) {
len = sizeof(line) - 1u;
}
if (KiPanicIsActive()) {
if (!KiPanicCurrentCpuOwnsReport())
KiPanicSecondaryHalt();
if (gDebugFlags & KE_DEBUG_CONSOLE)
KiDebugConsoleWrite(line, len);
return;
}
uintptr_t flags = KeAcquireSpinlock(&gDebugPrintLock);
if (!_InterlockedCompareExchange((volatile long*)&gDebugLogFlushing, 0, 0))
KiDebugLogAppendLocked(line, len);
@@ -187,17 +230,11 @@ __declspec(dllexport) KSTATUS KeFlushDebugLogToFile(SYS_STRING_VIEW path) {
// KePanic
__declspec(dllexport) _Noreturn void KePanic(int code, const char* fmt, ...) {
// Silence this CPU first.
_disable();
KiBeginFatalReport();
// Only one CPU owns the visible panic report. CPUs that fault while the
// system is already panicking immediately join the stopped set.
if (_InterlockedCompareExchange((volatile long*)&gPanicInProgress, 1, 0) != 0) {
KiPanicSecondaryHalt();
}
// Stop every other CPU as early as possible. This uses an NMI IPI so it
// still reaches CPUs with IF cleared inside spinlock/high-IRQL regions.
// Stop every other CPU for the final panic banner. Kernel fault dispatch
// claims panic ownership before its detailed dump, so this does not steal
// ownership from the CPU that found the fatal error.
HalApicSendPanicIpi();
if (PrintChar) {
@@ -550,7 +587,8 @@ static void KiDumpFaultFrame(PROCESS* proc, const KFAULT_FRAME* f) {
}
static void KiPrintCrashChar(char c) {
PrintChar(c, 0xFFAA00, 0x000000); // amber - distinct from green debug / red panic
if (PrintChar)
PrintChar(c, 0xFFAA00, 0x000000); // amber - distinct from green debug / red panic
}
static void KiPrintCrashHeader(PROCESS* proc, int vector, uintptr_t rip,
@@ -617,6 +655,8 @@ __declspec(dllexport) _Noreturn void KeFaultDispatchFrame(const KFAULT_FRAME* fr
}
if ((frame->Cs & 3) == 0) {
KiBeginFatalReport();
int vector = (int)frame->Vector;
const char* name = KiFaultVectorName(vector);