add a realtime scheduler class and priority-inheritance mutexes with timeouts and abandonment, add an HDA audio driver and a SYS_AUDIO_* syscall family, flesh out kernel32 with Win32 threads, events, mutexes, critical sections, and condition variables, add SYS_RESUME_THREAD for suspended thread creation, add KeInitializeMemoryTypes to reprogram MTRRs and install a canonical PAT for WB/WC/UC control, rework the display pipeline with a pitched present path and console output flush, bring back disk.vhd with mtools since vvfat fucking sucks, harden AHCI with serialized cache flush, USB mass storage with SCSI sense-data decoding, and xHCI with cleaner DMA teardown, fix the last stray for(;;) in HalStopProcessor to while(true), pile on smoke tests for audio, win32 sync primitives, and thread suspend, implement AHCI timeout, kill readahead since it was desperetaly trying to murder me, fix doom sound x2.

This commit is contained in:
maksw committed 2026-08-11 18:38:36 +02:00
1 parent 8b254f84f4
commit 4add6789ba
177 files changed
+22565 -3070

No files matched your search

+81 -30
View File
@@ -82,29 +82,79 @@ static void Rtl8139ReadMac(RTL8139_DEVICE* r) {
r->NetDevice.HardwareAddressLength = 6;
}
// Creates dma.
static KSTATUS Rtl8139AllocateDma(RTL8139_DEVICE* r) {
r->RxPhys = MmPfnAllocateContiguous(RTL8139_RX_PAGES, MmPfnUseDma);
r->TxPhys = MmPfnAllocateContiguous(RTL8139_TX_PAGES, MmPfnUseDma);
if (!r->RxPhys || !r->TxPhys)
return NTLSTATUS_NO_MEMORY;
// Stops bus mastering before DMA memory can be released.
static void Rtl8139StopDma(RTL8139_DEVICE* r) {
if (!r || !r->Started)
return;
r->Started = false;
if (r->SurpriseRemoved)
return;
Rtl8139Write16(r, RTL8139_REG_IMR, 0);
Rtl8139Write8(r, RTL8139_REG_CMD, 0);
KSTATUS status = Rtl8139Reset(r);
if (!KSUCCESS(status))
KePanic(KE_PANIC_CODE_DRIVER,
"RTL8139: failed to stop DMA before release status=0x%x\n",
status);
}
// RTL8139 has 32-bit DMA address registers. This is fine for typical QEMU
// and low-memory hobby OS configs, but make failure explicit.
if ((r->RxPhys + RTL8139_RX_ALLOC_SIZE - 1) > 0xFFFFFFFFULL ||
(r->TxPhys + RTL8139_TX_SLOTS * RTL8139_TX_BUF_SIZE - 1) > 0xFFFFFFFFULL) {
DbgPrint("RTL8139: DMA allocation above 4GiB is not supported by this NIC\n");
return NTLSTATUS_NOT_SUPPORTED;
// Releases the common buffers and adapter owned by one RTL8139 device.
static void Rtl8139ReleaseDma(RTL8139_DEVICE* r) {
if (!r || !gRtl8139Ddk || !gRtl8139Ddk->Dma)
return;
gRtl8139Ddk->Dma->FreeCommonBuffer(r->TxDma);
gRtl8139Ddk->Dma->FreeCommonBuffer(r->RxDma);
r->TxDma = (IO_DMA_BUFFER*)0;
r->RxDma = (IO_DMA_BUFFER*)0;
r->TxBuffers = (uint8_t*)0;
r->RxBuffer = (uint8_t*)0;
r->TxDeviceAddress = 0;
r->RxDeviceAddress = 0;
gRtl8139Ddk->Dma->PutAdapter(r->DmaAdapter);
r->DmaAdapter = (IO_DMA_ADAPTER*)0;
}
// Allocates the receive ring and transmit slots through the device DMA adapter.
static KSTATUS Rtl8139AllocateDma(RTL8139_DEVICE* r) {
IO_DMA_REQUIREMENTS requirements;
memset(&requirements, 0, sizeof(requirements));
requirements.MaximumDeviceAddress = 0xFFFFFFFFULL;
requirements.Alignment = 4;
requirements.MaximumSegmentLength = RTL8139_TX_BUF_SIZE;
requirements.MaximumSegments = 1;
KSTATUS status = gRtl8139Ddk->Dma->GetAdapter(r->Fdo,
&requirements,
&r->DmaAdapter);
if (!KSUCCESS(status))
return status;
status = gRtl8139Ddk->Dma->AllocateCommonBuffer(r->DmaAdapter,
RTL8139_RX_ALLOC_SIZE,
PAGE_SIZE,
&r->RxDma);
if (!KSUCCESS(status)) {
Rtl8139ReleaseDma(r);
return status;
}
r->RxBuffer = (uint8_t*)gRtl8139Ddk->Memory->PhysToVirt(r->RxPhys);
r->TxBuffers = (uint8_t*)gRtl8139Ddk->Memory->PhysToVirt(r->TxPhys);
memset(r->RxBuffer, 0, PAGE_SIZE * RTL8139_RX_PAGES);
memset(r->TxBuffers, 0, PAGE_SIZE * RTL8139_TX_PAGES);
status = gRtl8139Ddk->Dma->AllocateCommonBuffer(r->DmaAdapter,
RTL8139_TX_SLOTS * RTL8139_TX_BUF_SIZE,
PAGE_SIZE,
&r->TxDma);
if (!KSUCCESS(status)) {
Rtl8139ReleaseDma(r);
return status;
}
r->RxBuffer = (uint8_t*)gRtl8139Ddk->Dma->GetCommonBufferAddress(r->RxDma);
r->TxBuffers = (uint8_t*)gRtl8139Ddk->Dma->GetCommonBufferAddress(r->TxDma);
r->RxDeviceAddress = gRtl8139Ddk->Dma->GetCommonBufferDeviceAddress(r->RxDma);
r->TxDeviceAddress = gRtl8139Ddk->Dma->GetCommonBufferDeviceAddress(r->TxDma);
DbgPrint("RTL8139: rx=0x%016llX tx=0x%016llX\n",
(unsigned long long)r->RxPhys,
(unsigned long long)r->TxPhys);
(unsigned long long)r->RxDeviceAddress,
(unsigned long long)r->TxDeviceAddress);
return NTLSTATUS_SUCCESS;
}
@@ -136,13 +186,13 @@ static void Rtl8139ProgramHardware(RTL8139_DEVICE* r) {
Rtl8139Write16(r, RTL8139_REG_IMR, 0);
Rtl8139Write16(r, RTL8139_REG_ISR, 0xFFFFu);
Rtl8139Write32(r, RTL8139_REG_RBSTART, (uint32_t)r->RxPhys);
Rtl8139Write32(r, RTL8139_REG_RBSTART, (uint32_t)r->RxDeviceAddress);
r->RxOffset = 0;
Rtl8139Write16(r, RTL8139_REG_CAPR, 0xFFF0u); // CAPR is rxOffset - 16.
for (uint32_t i = 0; i < RTL8139_TX_SLOTS; i++) {
PHYSICAL_ADDRESS p = r->TxPhys + (PHYSICAL_ADDRESS)i * RTL8139_TX_BUF_SIZE;
Rtl8139Write32(r, RTL8139_REG_TSAD(i), (uint32_t)p);
uint64_t address = r->TxDeviceAddress + (uint64_t)i * RTL8139_TX_BUF_SIZE;
Rtl8139Write32(r, RTL8139_REG_TSAD(i), (uint32_t)address);
}
Rtl8139Write32(r, RTL8139_REG_TCR,
@@ -360,7 +410,7 @@ static KSTATUS Rtl8139SelectRegisterBar(RTL8139_DEVICE* r) {
if (best.Type == PciBarMemory32 || best.Type == PciBarMemory64) {
KSTATUS st = PciMapBar(r->Pdo,
best.Index,
PAGE_PRESENT | PAGE_WRITE | PAGE_NOCACHE,
PAGE_PRESENT | PAGE_WRITE | PAGE_CACHE_UC,
(void**)&r->Mmio,
&r->RegisterBytes);
if (!KSUCCESS(st))
@@ -460,8 +510,10 @@ static KSTATUS Rtl8139StartDevice(RTL8139_DEVICE* r) {
r->NetDevice.SendFrame = Rtl8139SendFrame;
st = Rtl8139RegisterDevice(r);
if (!KSUCCESS(st))
if (!KSUCCESS(st)) {
Rtl8139ReleaseDma(r);
return st;
}
KeIrqRegister(r->Irq, Rtl8139Isr);
r->Started = true;
@@ -470,9 +522,9 @@ static KSTATUS Rtl8139StartDevice(RTL8139_DEVICE* r) {
st = NetRegisterDevice(&r->NetDevice);
if (!KSUCCESS(st)) {
Rtl8139Write16(r, RTL8139_REG_IMR, 0);
r->Started = false;
Rtl8139StopDma(r);
Rtl8139UnregisterDevice(r);
Rtl8139ReleaseDma(r);
return st;
}
@@ -503,17 +555,16 @@ KSTATUS Rtl8139DispatchPnp(DEVICE_OBJECT* device, IRP* irp) {
case IRP_MN_SURPRISE_REMOVAL:
r->SurpriseRemoved = true;
r->Started = false;
device->PnpState = DevicePnpSurpriseRemoved;
if (r->Started)
Rtl8139Write16(r, RTL8139_REG_IMR, 0);
return NTLSTATUS_SUCCESS;
case IRP_MN_REMOVE_DEVICE:
r->Removed = true;
device->PnpState = DevicePnpDeleted;
if (r->Started)
Rtl8139Write16(r, RTL8139_REG_IMR, 0);
Rtl8139StopDma(r);
Rtl8139UnregisterDevice(r);
Rtl8139ReleaseDma(r);
IoDetachDevice(device);
IoDeleteDevice(device);
return NTLSTATUS_SUCCESS;
@@ -555,7 +606,7 @@ KSTATUS Rtl8139AddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObj
// Implements the driver Entry operation.
KSTATUS DriverEntry(const NTL_DDK* ddk, NTL_DRIVER_INIT* init) {
(void)init;
if (!ddk || !ddk->Memory || !ddk->Memory->PhysToVirt || !ddk->Timer)
if (!ddk || !ddk->Dma || !ddk->Timer)
return NTLSTATUS_INVALID_PARAMETER;
DbgPrint("RTL8139: driver loading...\n");