add page cache with read-ahead and dirty writeback, file-backed and anonymous mmap with CoW, VAD-based virtual memory replacing the old user region model, PFN database with eviction and reclaim, file identity for cross-open section sharing, FAT32 path cache and per-file cluster chain cache, serial.sys for COM1 keyboard input, xHCI MSI with INTx and polled fallback, PciEnableMsiAuto, waitable input queue, KeWaitForAnyEvent, per-process thread info syscall, expanded kernel stats (PFN/PTE/VAD/file-cache/disk), pool allocation tags, async I/O user buffer locking, file flush on close, add docs.md.
This commit is contained in:
1 parent
61ec2442eb
commit
2c4a68a75f
114 files changed
+18069
-2620
No files matched your search
@@ -58,20 +58,20 @@ static inline uint64_t cmd_tbl_phys(AHCI_DRIVE *drv, int slot) {
|
||||
static KSTATUS port_init_memory(AHCI_DRIVE *drv) {
|
||||
uint64_t flags = PAGE_PRESENT | PAGE_WRITE | PAGE_NOCACHE;
|
||||
|
||||
drv->structPhys = MmAllocateContiguous(PORT_PAGES_STRUCT);
|
||||
drv->structPhys = MmPfnAllocateContiguous(PORT_PAGES_STRUCT, MmPfnUseDma);
|
||||
if (!drv->structPhys) return STATUS_NO_MEMORY;
|
||||
drv->structVirt = g_hal->PhysToVirt(drv->structPhys);
|
||||
// Force NOCACHE on DMA descriptor memory.
|
||||
MmSetPageProtect((uintptr_t)drv->structVirt,
|
||||
MmPteProtectRange((uintptr_t)drv->structVirt,
|
||||
PORT_PAGES_STRUCT * 4096, flags);
|
||||
memset(drv->structVirt, 0, PORT_PAGES_STRUCT * 4096);
|
||||
|
||||
drv->bouncePhys = MmAllocateContiguous(BOUNCE_PAGES);
|
||||
drv->bouncePhys = MmPfnAllocateContiguous(BOUNCE_PAGES, MmPfnUseDma);
|
||||
if (!drv->bouncePhys) return STATUS_NO_MEMORY;
|
||||
drv->bounceVirt = g_hal->PhysToVirt(drv->bouncePhys);
|
||||
// Bounce buffer: NOCACHE to ensure CPU writes reach physical memory
|
||||
// before the HBA's DMA engine reads them.
|
||||
MmSetPageProtect((uintptr_t)drv->bounceVirt,
|
||||
MmPteProtectRange((uintptr_t)drv->bounceVirt,
|
||||
BOUNCE_PAGES * 4096, flags);
|
||||
memset(drv->bounceVirt, 0, BOUNCE_BYTES);
|
||||
|
||||
@@ -203,6 +203,9 @@ static void AhciIsr(void) {
|
||||
// Blocks the current thread until the ISR signals completionEvent.
|
||||
|
||||
static KSTATUS port_issue_cmd(AHCI_DRIVE *drv) {
|
||||
if (drv->controller && drv->controller->pollingMode)
|
||||
return port_issue_cmd_poll(drv);
|
||||
|
||||
HBA_PORT *port = drv->port;
|
||||
|
||||
// Clear stale IS and snapshot before issuing so we don't mis-read a
|
||||
@@ -647,12 +650,25 @@ static KSTATUS AhciStartController(AHCI_CONTROLLER* ctl) {
|
||||
ctl->pciInfo.VendorId,
|
||||
ctl->pciInfo.DeviceId);
|
||||
|
||||
st = PciGetInterrupt(ctl->pdo, &ctl->irq);
|
||||
if (!KSUCCESS(st) || ctl->irq == 0xFF) {
|
||||
DbgPrint("AHCI: no PCI IRQ wired - cannot use interrupt-driven mode\n");
|
||||
return KSUCCESS(st) ? STATUS_NOT_SUPPORTED : st;
|
||||
ctl->irq = 0xFFu;
|
||||
ctl->usingMsi = false;
|
||||
ctl->pollingMode = false;
|
||||
|
||||
st = PciEnableMsiAuto(ctl->pdo, &ctl->irq);
|
||||
if (KSUCCESS(st)) {
|
||||
ctl->usingMsi = true;
|
||||
DbgPrint("AHCI: using MSI IRQ slot %u\n", (unsigned)ctl->irq);
|
||||
} else {
|
||||
KSTATUS intxStatus = PciGetInterrupt(ctl->pdo, &ctl->irq);
|
||||
if (KSUCCESS(intxStatus) && ctl->irq != 0xFFu) {
|
||||
DbgPrint("AHCI: using legacy INTx IRQ %u\n", (unsigned)ctl->irq);
|
||||
} else {
|
||||
ctl->irq = 0xFFu;
|
||||
ctl->pollingMode = true;
|
||||
DbgPrint("AHCI: no MSI/INTx interrupt available; using polled command completion (msi=0x%x intx=0x%x)\n",
|
||||
st, intxStatus);
|
||||
}
|
||||
}
|
||||
DbgPrint("AHCI: PCI IRQ line = %u\n", (unsigned)ctl->irq);
|
||||
|
||||
st = PciGetBar(ctl->pdo, AHCI_PCI_BAR_ABAR, &ctl->abar);
|
||||
if (!KSUCCESS(st)) {
|
||||
@@ -674,10 +690,13 @@ static KSTATUS AhciStartController(AHCI_CONTROLLER* ctl) {
|
||||
return st;
|
||||
}
|
||||
|
||||
st = PciEnableDevice(ctl->pdo,
|
||||
PCI_ENABLE_MEMORY |
|
||||
PCI_ENABLE_BUSMASTER |
|
||||
PCI_ENABLE_INTX);
|
||||
uint32_t enableFlags = PCI_ENABLE_MEMORY | PCI_ENABLE_BUSMASTER;
|
||||
if (ctl->usingMsi || ctl->pollingMode)
|
||||
enableFlags |= PCI_DISABLE_INTX;
|
||||
else
|
||||
enableFlags |= PCI_ENABLE_INTX;
|
||||
|
||||
st = PciEnableDevice(ctl->pdo, enableFlags);
|
||||
if (!KSUCCESS(st)) {
|
||||
DbgPrint("AHCI: PciEnableDevice failed: 0x%x\n", st);
|
||||
return st;
|
||||
@@ -831,11 +850,16 @@ static KSTATUS AhciStartController(AHCI_CONTROLLER* ctl) {
|
||||
ctl->pciInfo.Address.Device,
|
||||
ctl->pciInfo.Address.Function);
|
||||
|
||||
KeIrqRegister(ctl->irq, AhciIsr);
|
||||
if (!ctl->pollingMode) {
|
||||
KeIrqRegister(ctl->irq, AhciIsr);
|
||||
DbgPrint("AHCI: ISR registered on IRQ %u (%s); controller drives=%d\n",
|
||||
(unsigned)ctl->irq, ctl->usingMsi ? "MSI" : "INTx", ctl->driveCount);
|
||||
} else {
|
||||
DbgPrint("AHCI: controller started in polling mode; controller drives=%d\n",
|
||||
ctl->driveCount);
|
||||
}
|
||||
ctl->started = true;
|
||||
ctl->fdo->PnpState = DevicePnpStarted;
|
||||
DbgPrint("AHCI: ISR registered on IRQ %u; controller drives=%d\n",
|
||||
(unsigned)ctl->irq, ctl->driveCount);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user