usb hubs, hotplug support, unplug support, saving log files to disk, smt
This commit is contained in:
1 parent
b838f8d83d
commit
27b31f62b6
39 files changed
+6294
-735
No files matched your search
+124
-7
@@ -13,12 +13,53 @@
|
||||
#include <kernel/ke_thread.h>
|
||||
#include <kernel/ke_sched.h>
|
||||
#include <kernel/mm_virt.h>
|
||||
#include <kernel/io_file.h>
|
||||
#include <common/printf.h>
|
||||
int _fltused; // MSVC floating-point helper anchor
|
||||
|
||||
int gDebugEnabled = 0;
|
||||
static uint32_t gDebugFlags = 0;
|
||||
void (*PrintChar)(char, uint32_t, uint32_t);
|
||||
|
||||
#define KE_DEBUG_LOG_BUFFER_SIZE (50u * 1024u)
|
||||
#define KE_DEBUG_LOG_LINE_SIZE 1024u
|
||||
|
||||
static SPINLOCK gDebugPrintLock = SPINLOCK_INIT;
|
||||
static char* gDebugLogBuffer;
|
||||
static size_t gDebugLogSize;
|
||||
static size_t gDebugLogWrite;
|
||||
static size_t gDebugLogUsed;
|
||||
static volatile long gDebugLogFlushing;
|
||||
|
||||
static void KiDebugLogAppendLocked(const char* text, size_t len) {
|
||||
if (!gDebugLogBuffer || gDebugLogSize == 0 || !text || len == 0)
|
||||
return;
|
||||
|
||||
if (len >= gDebugLogSize) {
|
||||
text += len - (gDebugLogSize - 1u);
|
||||
len = gDebugLogSize - 1u;
|
||||
}
|
||||
|
||||
size_t first = gDebugLogSize - gDebugLogWrite;
|
||||
if (first > len) first = len;
|
||||
memcpy(gDebugLogBuffer + gDebugLogWrite, text, first);
|
||||
if (len > first)
|
||||
memcpy(gDebugLogBuffer, text + first, len - first);
|
||||
|
||||
gDebugLogWrite = (gDebugLogWrite + len) % gDebugLogSize;
|
||||
if (gDebugLogUsed + len >= gDebugLogSize)
|
||||
gDebugLogUsed = gDebugLogSize;
|
||||
else
|
||||
gDebugLogUsed += len;
|
||||
}
|
||||
|
||||
static void KiDebugConsoleWrite(const char* text, size_t len) {
|
||||
if (!PrintChar || !text)
|
||||
return;
|
||||
for (size_t i = 0; i < len; i++)
|
||||
PrintChar(text[i], 0x00FF00, 0x000000);
|
||||
}
|
||||
|
||||
static volatile long gPanicInProgress = 0;
|
||||
static volatile long gPanicStoppedCpuCount = 0;
|
||||
|
||||
@@ -50,22 +91,98 @@ void KiKernelPutChar(char c) {
|
||||
PrintChar(c, 0x00FF00, 0x000000);
|
||||
}
|
||||
|
||||
void KeInitDebug(void (*PrintPtr)(char, uint32_t, uint32_t), int v) {
|
||||
gDebugEnabled = v;
|
||||
void KeInitDebug(void (*PrintPtr)(char, uint32_t, uint32_t), uint32_t flags) {
|
||||
gDebugFlags = flags;
|
||||
gDebugEnabled = (flags & (KE_DEBUG_CONSOLE | KE_DEBUG_FILE_LOG)) != 0;
|
||||
PrintChar = PrintPtr;
|
||||
printf_set_putchar(KiKernelPutChar);
|
||||
|
||||
if ((flags & (KE_DEBUG_CONSOLE | KE_DEBUG_FILE_LOG)) && !gDebugLogBuffer) {
|
||||
gDebugLogBuffer = (char*)MmAllocatePool(KE_DEBUG_LOG_BUFFER_SIZE);
|
||||
if (gDebugLogBuffer) {
|
||||
gDebugLogSize = KE_DEBUG_LOG_BUFFER_SIZE;
|
||||
gDebugLogWrite = 0;
|
||||
gDebugLogUsed = 0;
|
||||
memset(gDebugLogBuffer, 0, gDebugLogSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t KeGetDebugFlags(void) {
|
||||
return gDebugFlags;
|
||||
}
|
||||
|
||||
__declspec(dllexport) void DbgPrint(const char* fmt, ...) {
|
||||
if (!gDebugEnabled) return;
|
||||
if (!gDebugEnabled || !fmt) return;
|
||||
|
||||
static SPINLOCK sl = {0};
|
||||
uintptr_t flags = KeAcquireSpinlock(&sl);
|
||||
char line[KE_DEBUG_LOG_LINE_SIZE];
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
vprintf(fmt, va);
|
||||
int n = vsnprintf_(line, sizeof(line), fmt, va);
|
||||
va_end(va);
|
||||
KeReleaseSpinlock(&sl, flags);
|
||||
|
||||
size_t len = 0;
|
||||
if (n > 0) {
|
||||
len = (size_t)n;
|
||||
if (len >= sizeof(line))
|
||||
len = sizeof(line) - 1u;
|
||||
}
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gDebugPrintLock);
|
||||
if (!_InterlockedCompareExchange((volatile long*)&gDebugLogFlushing, 0, 0))
|
||||
KiDebugLogAppendLocked(line, len);
|
||||
if (gDebugFlags & KE_DEBUG_CONSOLE)
|
||||
KiDebugConsoleWrite(line, len);
|
||||
KeReleaseSpinlock(&gDebugPrintLock, flags);
|
||||
}
|
||||
|
||||
__declspec(dllexport) KSTATUS KeFlushDebugLogToFile(SYS_STRING_VIEW path) {
|
||||
if (!gDebugLogBuffer || gDebugLogSize == 0 || !SysSvIsValid(path) || path.Length == 0)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
if (!KeCanWait())
|
||||
return STATUS_INVALID_IRQL;
|
||||
|
||||
if (_InterlockedCompareExchange((volatile long*)&gDebugLogFlushing, 1, 0) != 0)
|
||||
return STATUS_PENDING;
|
||||
|
||||
size_t used;
|
||||
size_t start;
|
||||
uintptr_t flags = KeAcquireSpinlock(&gDebugPrintLock);
|
||||
used = gDebugLogUsed;
|
||||
start = (gDebugLogUsed == gDebugLogSize) ? gDebugLogWrite : 0;
|
||||
KeReleaseSpinlock(&gDebugPrintLock, flags);
|
||||
|
||||
if (used == 0) {
|
||||
_InterlockedExchange((volatile long*)&gDebugLogFlushing, 0);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
(void)IoDeleteFile(path);
|
||||
|
||||
FILE_OBJECT* file = (FILE_OBJECT*)0;
|
||||
KSTATUS st = IoCreateFile(path, &file);
|
||||
if (!KSUCCESS(st)) {
|
||||
_InterlockedExchange((volatile long*)&gDebugLogFlushing, 0);
|
||||
return st;
|
||||
}
|
||||
|
||||
size_t written = 0;
|
||||
size_t totalWritten = 0;
|
||||
size_t first = gDebugLogSize - start;
|
||||
if (first > used) first = used;
|
||||
st = IoWriteFile(file, gDebugLogBuffer + start, first, &written);
|
||||
totalWritten += written;
|
||||
|
||||
if (KSUCCESS(st) && used > first) {
|
||||
written = 0;
|
||||
st = IoWriteFile(file, gDebugLogBuffer, used - first, &written);
|
||||
totalWritten += written;
|
||||
}
|
||||
|
||||
IoCloseFile(file);
|
||||
|
||||
_InterlockedExchange((volatile long*)&gDebugLogFlushing, 0);
|
||||
return (KSUCCESS(st) && totalWritten == used) ? STATUS_SUCCESS : st;
|
||||
}
|
||||
|
||||
// KePanic
|
||||
|
||||
Reference in new issue
Block a user