move keyboard and mouse out of HAL into a standalone ps2.sys driver, implement usb stack with xhci controller discovery, hid keyboard/mouse, and bulk-only mass storage, add pci msi support with capability chain walking and software irq vector allocation (slots 16-23), rewrite user virtual memory as a USER_VA_REGION descriptor arena with per-process ownership tracking and guard page support, replacing the old bump allocator and top-down image region, add MmCreateUserRegion/MmDestroyAllUserRegions so process teardown reclaims all user va in one pass, allocate a pool-backed shadow framebuffer in hal_screen to fix cursor tearing and scroll corruption, reserve ap trampoline page below 1mb in uefi bootloader before boot services exit, rewrite memset/memcpy/memmove/memcmp with __stosq/__movsq intrinsics, promote driver flag literals to macros and add multi-tu STANDALONE_DRIVERS table to build.c, split rtl8139/rtl816x into header+source, rename KbReadScancode to KbReadKey, improve page fault output with MmDebugDescribeAddress and user region dump, fix %p to %016llX throughout.

This commit is contained in:
maksw committed 2026-06-02 00:01:20 +02:00
1 parent b970d7f59c
commit b838f8d83d
130 files changed
+8137 -2932

No files matched your search

+87
View File
@@ -0,0 +1,87 @@
// ide_bus.c - Bus-master IDE PCI/DMA initialisation.
#include "ide.h"
bool IdeDmaInit(void) {
// ---- Find PCI IDE controller (class 0x01, subclass 0x01) --------------
uint8_t bus, dev, fn;
if (!gHal->Pci.FindClass(0x01, 0x01, &bus, &dev, &fn)) {
DbgPrint("IDE DMA: No PCI IDE controller found — using PIO\n");
return false;
}
// ---- Read BAR4 (Bus Master base, I/O space) ---------------------------
// PCI config offset 0x20. Bit 0 must be 1 for I/O BAR.
uint32_t bar4 = gHal->Pci.Read32(bus, dev, fn, 0x20);
if (!(bar4 & 0x1)) {
DbgPrint("IDE DMA: BAR4 is a memory BAR (0x%08x) — unexpected, using PIO\n", bar4);
return false;
}
uint16_t bmBase = (uint16_t)(bar4 & 0xFFFC);
if (bmBase == 0) {
DbgPrint("IDE DMA: BAR4 is zero (firmware didn't assign it) — using PIO\n");
return false;
}
DbgPrint("IDE DMA: Bus Master base = 0x%04X (bus %u, dev %u, fn %u)\n",
bmBase, bus, dev, fn);
// ---- Enable Bus Mastering in PCI Command register (bit 2) ------------
uint32_t pciCmd = gHal->Pci.Read32(bus, dev, fn, 0x04);
gHal->Pci.Write32(bus, dev, fn, 0x04, pciCmd | (1u << 2));
// ---- Allocate PRDT page (must be 32-bit physical, 4-byte aligned) ----
PHYSICAL_ADDRESS prdtPhys = MmAllocateContiguous(1);
if (!prdtPhys) {
DbgPrint("IDE DMA: Failed to allocate PRDT page\n");
return false;
}
if (prdtPhys >> 32) {
// MmAllocateContiguous returned memory above 4 GB — BM IDE can't
// address it. This shouldn't happen on normal x86 systems with early
// boot allocations but we check defensively.
DbgPrint("IDE DMA: PRDT page is above 4 GB (0x%016llX) — using PIO\n",
(uint64_t)prdtPhys);
return false;
}
void *prdtVirt = gHal->PhysToVirt(prdtPhys);
DbgPrint("IDE DMA: PRDT at phys 0x%08x, virt 0x%016llX\n", (uint32_t)prdtPhys, prdtVirt);
// ---- Create synchronisation objects ------------------------------------
SEMAPHORE *sem = NULL;
if (!KSUCCESS(KeSemaphoreCreate(0, 0x7FFFFFFF, &sem))) {
DbgPrint("IDE DMA: Failed to create IRP semaphore\n");
return false;
}
EVENT *dmaEv = NULL;
if (!KSUCCESS(KeEventCreate(EventAutoReset, 0, &dmaEv))) {
DbgPrint("IDE DMA: Failed to create DMA completion event\n");
return false;
}
// ---- Commit module state -----------------------------------------------
gBmBase = bmBase;
gPrdtPhys = (uint32_t)prdtPhys;
gPrdtVirt = (PRD *)prdtVirt;
gIrpSemaphore = sem;
gDmaEvent = dmaEv;
KeInitializeDpc(&gDmaDpc, IdeDmaCompletionDpc, (void *)0);
IrpQueueInit(&gIrpQueue, sem);
// ---- Register IRQ 14 --------------------------------------------------
KeIrqRegister(IDE_IRQ_PRIMARY, IdeIsr);
DbgPrint("IDE DMA: IRQ %u registered\n", IDE_IRQ_PRIMARY);
// ---- Spawn worker thread -----------------------------------------------
KSTATUS st = KeCreateKernelThread((uintptr_t)IdeWorker, 0,
PriorityHigh, (THREAD **)NULL);
if (!KSUCCESS(st)) {
DbgPrint("IDE DMA: Worker thread creation failed (0x%x)\n", st);
// Not fatal for init — the PRDT/IRQ are live but async callers will
// never get completions. Better to surface the failure clearly.
return false;
}
DbgPrint("IDE DMA: Init complete\n");
return true;
}