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:
1 parent
e41bf6e2c0
commit
6260de0085
38 files changed
+4011
-467
No files matched your search
+52
-12
@@ -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);
|
||||
|
||||
|
||||
Reference in new issue
Block a user