usb hubs, hotplug support, unplug support, saving log files to disk, smt

This commit is contained in:
maksw committed 2026-06-09 09:14:24 +02:00
1 parent b838f8d83d
commit 27b31f62b6
39 files changed
+6294 -735

No files matched your search

+124 -7
View File
@@ -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