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:
1 parent
8b254f84f4
commit
4add6789ba
177 files changed
+22565
-3070
No files matched your search
@@ -92,7 +92,7 @@ static KSTATUS AtaIdentify(ATA_DEVICE* dev) {
|
||||
uint16_t ident[256];
|
||||
memset(ident, 0, sizeof(ident));
|
||||
|
||||
KSTATUS st = KeWaitSemaphore(ch->Lock);
|
||||
KSTATUS st = KeWaitSemaphore(ch->Lock, KE_WAIT_INFINITE);
|
||||
if (!KSUCCESS(st))
|
||||
return st;
|
||||
|
||||
@@ -193,7 +193,7 @@ static KSTATUS AtaReadPio(ATA_DEVICE* dev, uint64_t lba, uint32_t count, void* b
|
||||
ATA_CHANNEL* ch = dev->Channel;
|
||||
uint16_t* out = (uint16_t*)buffer;
|
||||
|
||||
KSTATUS st = KeWaitSemaphore(ch->Lock);
|
||||
KSTATUS st = KeWaitSemaphore(ch->Lock, KE_WAIT_INFINITE);
|
||||
if (!KSUCCESS(st))
|
||||
return st;
|
||||
|
||||
@@ -234,6 +234,22 @@ static KSTATUS AtaFlush(ATA_DEVICE* dev) {
|
||||
return AtaWaitNotBusy(ch);
|
||||
}
|
||||
|
||||
// Flushes one device while holding the shared channel lock.
|
||||
static KSTATUS AtaFlushSerialized(ATA_DEVICE* dev) {
|
||||
if (!dev || !dev->Channel)
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
ATA_CHANNEL* ch = dev->Channel;
|
||||
KSTATUS st = KeWaitSemaphore(ch->Lock, KE_WAIT_INFINITE);
|
||||
if (!KSUCCESS(st))
|
||||
return st;
|
||||
|
||||
AtaSelectDrive(dev);
|
||||
st = AtaFlush(dev);
|
||||
KeSignalSemaphore(ch->Lock);
|
||||
return st;
|
||||
}
|
||||
|
||||
// Updates pio.
|
||||
static KSTATUS AtaWritePio(ATA_DEVICE* dev, uint64_t lba, uint32_t count, const void* buffer) {
|
||||
if (!dev || !buffer)
|
||||
@@ -246,7 +262,7 @@ static KSTATUS AtaWritePio(ATA_DEVICE* dev, uint64_t lba, uint32_t count, const
|
||||
ATA_CHANNEL* ch = dev->Channel;
|
||||
const uint16_t* in = (const uint16_t*)buffer;
|
||||
|
||||
KSTATUS st = KeWaitSemaphore(ch->Lock);
|
||||
KSTATUS st = KeWaitSemaphore(ch->Lock, KE_WAIT_INFINITE);
|
||||
if (!KSUCCESS(st))
|
||||
return st;
|
||||
|
||||
@@ -308,27 +324,38 @@ static void AtaWorker(uintptr_t arg) {
|
||||
return;
|
||||
|
||||
while (true) {
|
||||
KeWaitSemaphore(dev->IrpQueue.Semaphore);
|
||||
KeWaitSemaphore(dev->IrpQueue.Semaphore, KE_WAIT_INFINITE);
|
||||
|
||||
IRP* irp = IrpQueueDequeue(&dev->IrpQueue);
|
||||
if (!irp)
|
||||
continue;
|
||||
|
||||
bool write = false;
|
||||
uint64_t lba = 0;
|
||||
uint32_t sectors = 0;
|
||||
void* buffer = (void*)0;
|
||||
KSTATUS st = AtaGetIrpReadWrite(irp, &write, &lba, §ors, &buffer);
|
||||
if (KSUCCESS(st)) {
|
||||
if (lba + sectors > dev->SectorCount)
|
||||
st = NTLSTATUS_INVALID_PARAMETER;
|
||||
else
|
||||
st = write ? AtaWritePio(dev, lba, sectors, buffer)
|
||||
: AtaReadPio(dev, lba, sectors, buffer);
|
||||
IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp);
|
||||
KSTATUS st = NTLSTATUS_INVALID_PARAMETER;
|
||||
size_t information = 0;
|
||||
|
||||
if (ios && ios->MajorFunction == IRP_MJ_FLUSH_BUFFERS) {
|
||||
st = AtaFlushSerialized(dev);
|
||||
} else {
|
||||
bool write = false;
|
||||
uint64_t lba = 0;
|
||||
uint32_t sectors = 0;
|
||||
void* buffer = (void*)0;
|
||||
st = AtaGetIrpReadWrite(irp, &write, &lba, §ors, &buffer);
|
||||
if (KSUCCESS(st)) {
|
||||
if (lba + sectors > dev->SectorCount) {
|
||||
st = NTLSTATUS_INVALID_PARAMETER;
|
||||
} else {
|
||||
st = write ? AtaWritePio(dev, lba, sectors, buffer)
|
||||
: AtaReadPio(dev, lba, sectors, buffer);
|
||||
if (KSUCCESS(st))
|
||||
information = (size_t)sectors * ATA_SECTOR_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IoReleaseRemoveLock(&dev->RemoveLock, irp);
|
||||
IoCompleteRequest(irp, st, KSUCCESS(st) ? ((size_t)sectors * ATA_SECTOR_SIZE) : 0);
|
||||
IoCompleteRequest(irp, st, information);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -363,6 +390,31 @@ KSTATUS AtaDispatchReadWrite(DEVICE_OBJECT* device, IRP* irp) {
|
||||
return NTLSTATUS_PENDING;
|
||||
}
|
||||
|
||||
// Queues one cache flush on the device worker.
|
||||
static KSTATUS AtaDispatchFlush(DEVICE_OBJECT* device, IRP* irp) {
|
||||
if (!device || !irp || !device->DeviceExtension)
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
ATA_DEVICE* dev = (ATA_DEVICE*)device->DeviceExtension;
|
||||
if (dev->Magic != ATA_DEVICE_MAGIC || !dev->Present)
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
KSTATUS st = IoAcquireRemoveLock(&dev->RemoveLock, irp);
|
||||
if (!KSUCCESS(st))
|
||||
return st;
|
||||
|
||||
IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp);
|
||||
if (!ios || ios->MajorFunction != IRP_MJ_FLUSH_BUFFERS) {
|
||||
IoReleaseRemoveLock(&dev->RemoveLock, irp);
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
irp->Status = NTLSTATUS_FAILURE;
|
||||
irp->Information = 0;
|
||||
IrpQueueEnqueue(&dev->IrpQueue, irp);
|
||||
return NTLSTATUS_PENDING;
|
||||
}
|
||||
|
||||
// Returns free Disk Index.
|
||||
static uint8_t AtaFindFreeDiskIndex(void) {
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
@@ -486,8 +538,9 @@ static KSTATUS AtaProbeDrive(ATA_CONTROLLER* ctl, ATA_CHANNEL* ch, uint8_t drive
|
||||
return st;
|
||||
}
|
||||
|
||||
const KE_THREAD_CREATE_PARAMETERS workerParameters = KE_THREAD_CREATE_NORMAL(PriorityHigh);
|
||||
st = KeCreateKernelThread((uintptr_t)AtaWorker, (uintptr_t)dev,
|
||||
PriorityHigh, &dev->WorkerThread);
|
||||
&workerParameters, &dev->WorkerThread);
|
||||
if (!KSUCCESS(st))
|
||||
DbgPrint("ATA: drive %u worker thread create failed (0x%x)\n", dev->DiskIndex, st);
|
||||
return NTLSTATUS_SUCCESS;
|
||||
@@ -580,7 +633,7 @@ static void AtaRemoveControllerDevices(ATA_CONTROLLER* ctl, IO_DEVICE_CHANGE cha
|
||||
if (!dev->Present)
|
||||
continue;
|
||||
|
||||
IrpQueueCancelAllEx(&dev->IrpQueue, NTLSTATUS_OBJECT_DEAD, AtaCancelReleaseRemoveLock, dev);
|
||||
IrpQueueCancelAllWithCallback(&dev->IrpQueue, NTLSTATUS_OBJECT_DEAD, AtaCancelReleaseRemoveLock, dev);
|
||||
if (dev->DiskIndex != 0xFFu) {
|
||||
if (change == IoDeviceSurpriseRemoved)
|
||||
IoNotifyDiskSurpriseRemoved(dev->DiskIndex);
|
||||
@@ -647,12 +700,12 @@ KSTATUS AtaDispatchPnp(DEVICE_OBJECT* device, IRP* irp) {
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
device->PnpState = DevicePnpSurpriseRemoved;
|
||||
dev->Present = false;
|
||||
IrpQueueCancelAllEx(&dev->IrpQueue, NTLSTATUS_OBJECT_DEAD, AtaCancelReleaseRemoveLock, dev);
|
||||
IrpQueueCancelAllWithCallback(&dev->IrpQueue, NTLSTATUS_OBJECT_DEAD, AtaCancelReleaseRemoveLock, dev);
|
||||
return NTLSTATUS_SUCCESS;
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
device->PnpState = DevicePnpDeleted;
|
||||
dev->Present = false;
|
||||
IrpQueueCancelAllEx(&dev->IrpQueue, NTLSTATUS_OBJECT_DEAD, AtaCancelReleaseRemoveLock, dev);
|
||||
IrpQueueCancelAllWithCallback(&dev->IrpQueue, NTLSTATUS_OBJECT_DEAD, AtaCancelReleaseRemoveLock, dev);
|
||||
IoReleaseRemoveLockAndWait(&dev->RemoveLock, irp);
|
||||
IoDeleteDevice(device);
|
||||
dev->DeviceObject = (DEVICE_OBJECT*)0;
|
||||
@@ -708,6 +761,7 @@ KSTATUS DriverEntry(const NTL_DDK* ddk, NTL_DRIVER_INIT* init) {
|
||||
gAtaDriver.DriverAddDevice = AtaAddDevice;
|
||||
gAtaDriver.MajorFunction[IRP_MJ_READ] = AtaDispatchReadWrite;
|
||||
gAtaDriver.MajorFunction[IRP_MJ_WRITE] = AtaDispatchReadWrite;
|
||||
gAtaDriver.MajorFunction[IRP_MJ_FLUSH_BUFFERS] = AtaDispatchFlush;
|
||||
gAtaDriver.MajorFunction[IRP_MJ_PNP] = AtaDispatchPnp;
|
||||
|
||||
KSTATUS st = IoRegisterDriverObject(&gAtaDriver);
|
||||
|
||||
Reference in new issue
Block a user