implement user mode catchable exceptions, refactor system status codes to use NTLSTATUS_ prefix, update build scripts to use shared literal macros for linker arguments, update named queue lifetime cleanup to include KeNamedQueueUnpublishHandle.
This commit is contained in:
1 parent
1f5477cf66
commit
b7fcfce6f7
140 files changed
+7649
-3943
No files matched your search
+50
-50
@@ -44,18 +44,18 @@ static uint64_t PciDefaultMmioFlags(void) {
|
||||
// Creates mmio Va.
|
||||
static KSTATUS PciAllocateMmioVa(uint64_t length, uintptr_t* outVa) {
|
||||
if (!outVa || !length)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uint64_t alignedLength = PciAlignUp64(length, PAGE_SIZE);
|
||||
uintptr_t va = (uintptr_t)PciAlignUp64((uint64_t)gPciMmioNext, PAGE_SIZE);
|
||||
if (va < PCI_MMIO_VA_BASE || va >= PCI_MMIO_VA_LIMIT)
|
||||
return STATUS_NO_MEMORY;
|
||||
return NTLSTATUS_NO_MEMORY;
|
||||
if (alignedLength > (uint64_t)(PCI_MMIO_VA_LIMIT - va))
|
||||
return STATUS_NO_MEMORY;
|
||||
return NTLSTATUS_NO_MEMORY;
|
||||
|
||||
gPciMmioNext = va + (uintptr_t)alignedLength;
|
||||
*outVa = va;
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Checks whether pdo.
|
||||
@@ -332,7 +332,7 @@ static KSTATUS PciCreatePdo(uint8_t bus, uint8_t dev, uint8_t fn) {
|
||||
uint32_t id = PciRawRead32(bus, dev, fn, PCI_REG_VENDOR_DEVICE);
|
||||
uint16_t vendor = (uint16_t)(id & 0xFFFFu);
|
||||
if (vendor == PCI_VENDOR_INVALID)
|
||||
return STATUS_NOT_FOUND;
|
||||
return NTLSTATUS_NOT_FOUND;
|
||||
|
||||
uint32_t classReg = PciRawRead32(bus, dev, fn, PCI_REG_REVISION_CLASS);
|
||||
uint32_t hdrReg = PciRawRead32(bus, dev, fn, PCI_REG_HEADER_TYPE);
|
||||
@@ -399,7 +399,7 @@ static KSTATUS PciCreatePdo(uint8_t bus, uint8_t dev, uint8_t fn) {
|
||||
info.Subclass,
|
||||
info.ProgIf,
|
||||
info.InterruptLine);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Implements the enumerate Bus operation.
|
||||
@@ -415,7 +415,7 @@ static void PciEnumerateBus(void) {
|
||||
|
||||
for (uint8_t fn = 0; fn < fnLimit; fn++) {
|
||||
KSTATUS st = PciCreatePdo((uint8_t)bus, (uint8_t)dev, fn);
|
||||
if (!KSUCCESS(st) && st != STATUS_NOT_FOUND) {
|
||||
if (!KSUCCESS(st) && st != NTLSTATUS_NOT_FOUND) {
|
||||
DbgPrint("pci: failed to create PDO for %02x:%02x.%u st=0x%x\n",
|
||||
bus, dev, fn, st);
|
||||
}
|
||||
@@ -426,21 +426,21 @@ static void PciEnumerateBus(void) {
|
||||
|
||||
// Dispatches pnp.
|
||||
static KSTATUS PciDispatchPnp(DEVICE_OBJECT* device, IRP* irp) {
|
||||
if (!device || !irp) return STATUS_INVALID_PARAMETER;
|
||||
if (!device || !irp) return NTLSTATUS_INVALID_PARAMETER;
|
||||
IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp);
|
||||
if (!ios || ios->MajorFunction != IRP_MJ_PNP) return STATUS_INVALID_PARAMETER;
|
||||
if (!ios || ios->MajorFunction != IRP_MJ_PNP) return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) {
|
||||
case IRP_MN_START_DEVICE:
|
||||
device->PnpState = DevicePnpStarted;
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
case IRP_MN_QUERY_REMOVE_DEVICE:
|
||||
case IRP_MN_CANCEL_REMOVE_DEVICE:
|
||||
case IRP_MN_SURPRISE_REMOVAL:
|
||||
case IRP_MN_REMOVE_DEVICE:
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
return NTLSTATUS_NOT_SUPPORTED;
|
||||
default:
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
return NTLSTATUS_NOT_SUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -452,81 +452,81 @@ __declspec(dllexport) uint32_t PciDriverAbiVersion(void) {
|
||||
// Returns device Info.
|
||||
__declspec(dllexport) KSTATUS PciGetDeviceInfo(DEVICE_OBJECT* pdo, PCI_DEVICE_INFO* outInfo) {
|
||||
PCI_PDO_EXTENSION* ext;
|
||||
if (!outInfo || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER;
|
||||
if (!outInfo || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER;
|
||||
*outInfo = ext->Info;
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Returns config8.
|
||||
__declspec(dllexport) KSTATUS PciReadConfig8(DEVICE_OBJECT* pdo, uint16_t offset, uint8_t* outValue) {
|
||||
PCI_PDO_EXTENSION* ext;
|
||||
if (!outValue || offset > 0xFFu || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER;
|
||||
if (!outValue || offset > 0xFFu || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER;
|
||||
*outValue = PciRawRead8(ext->Info.Address.Bus, ext->Info.Address.Device, ext->Info.Address.Function, offset);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Returns config16.
|
||||
__declspec(dllexport) KSTATUS PciReadConfig16(DEVICE_OBJECT* pdo, uint16_t offset, uint16_t* outValue) {
|
||||
PCI_PDO_EXTENSION* ext;
|
||||
if (!outValue || offset > 0xFEu || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER;
|
||||
if (!outValue || offset > 0xFEu || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER;
|
||||
*outValue = PciRawRead16(ext->Info.Address.Bus, ext->Info.Address.Device, ext->Info.Address.Function, offset);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Returns config32.
|
||||
__declspec(dllexport) KSTATUS PciReadConfig32(DEVICE_OBJECT* pdo, uint16_t offset, uint32_t* outValue) {
|
||||
PCI_PDO_EXTENSION* ext;
|
||||
if (!outValue || offset > 0xFCu || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER;
|
||||
if (!outValue || offset > 0xFCu || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER;
|
||||
*outValue = PciRawRead32(ext->Info.Address.Bus, ext->Info.Address.Device, ext->Info.Address.Function, offset);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Updates config8.
|
||||
__declspec(dllexport) KSTATUS PciWriteConfig8(DEVICE_OBJECT* pdo, uint16_t offset, uint8_t value) {
|
||||
PCI_PDO_EXTENSION* ext;
|
||||
if (offset > 0xFFu || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER;
|
||||
if (offset > 0xFFu || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER;
|
||||
PciRawWrite8(ext->Info.Address.Bus, ext->Info.Address.Device, ext->Info.Address.Function, offset, value);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Updates config16.
|
||||
__declspec(dllexport) KSTATUS PciWriteConfig16(DEVICE_OBJECT* pdo, uint16_t offset, uint16_t value) {
|
||||
PCI_PDO_EXTENSION* ext;
|
||||
if (offset > 0xFEu || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER;
|
||||
if (offset > 0xFEu || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER;
|
||||
PciRawWrite16(ext->Info.Address.Bus, ext->Info.Address.Device, ext->Info.Address.Function, offset, value);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Updates config32.
|
||||
__declspec(dllexport) KSTATUS PciWriteConfig32(DEVICE_OBJECT* pdo, uint16_t offset, uint32_t value) {
|
||||
PCI_PDO_EXTENSION* ext;
|
||||
if (offset > 0xFCu || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER;
|
||||
if (offset > 0xFCu || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER;
|
||||
PciRawWrite32(ext->Info.Address.Bus, ext->Info.Address.Device, ext->Info.Address.Function, offset, value);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Returns bar.
|
||||
__declspec(dllexport) KSTATUS PciGetBar(DEVICE_OBJECT* pdo, uint8_t index, PCI_BAR* outBar) {
|
||||
PCI_PDO_EXTENSION* ext;
|
||||
if (!outBar || index >= PCI_MAX_BARS || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER;
|
||||
if (ext->Bars[index].Type == PciBarUnused) return STATUS_NOT_FOUND;
|
||||
if (!outBar || index >= PCI_MAX_BARS || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER;
|
||||
if (ext->Bars[index].Type == PciBarUnused) return NTLSTATUS_NOT_FOUND;
|
||||
*outBar = ext->Bars[index];
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Maps a PCI BAR through the private MMIO aperture with explicit cache attributes.
|
||||
__declspec(dllexport) KSTATUS PciMapBar(DEVICE_OBJECT* pdo, uint8_t index, uint64_t pageFlags, void** outVirtual, uint64_t* outLength) {
|
||||
PCI_BAR bar;
|
||||
if (!outVirtual) return STATUS_INVALID_PARAMETER;
|
||||
if (!outVirtual) return NTLSTATUS_INVALID_PARAMETER;
|
||||
*outVirtual = NULL;
|
||||
KSTATUS st = PciGetBar(pdo, index, &bar);
|
||||
if (!KSUCCESS(st)) return st;
|
||||
if (bar.Type != PciBarMemory32 && bar.Type != PciBarMemory64)
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
return NTLSTATUS_NOT_SUPPORTED;
|
||||
if (!bar.Length)
|
||||
return STATUS_DEVICE_ERROR;
|
||||
return NTLSTATUS_DEVICE_ERROR;
|
||||
if (bar.Base + bar.Length < bar.Base)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uint64_t flags = pageFlags ? pageFlags : PciDefaultMmioFlags();
|
||||
flags |= PAGE_PRESENT;
|
||||
@@ -548,13 +548,13 @@ __declspec(dllexport) KSTATUS PciMapBar(DEVICE_OBJECT* pdo, uint8_t index, uint6
|
||||
|
||||
*outVirtual = (void*)(virtBase + (uintptr_t)physOffset);
|
||||
if (outLength) *outLength = bar.Length;
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Enables device.
|
||||
__declspec(dllexport) KSTATUS PciEnableDevice(DEVICE_OBJECT* pdo, uint32_t flags) {
|
||||
PCI_PDO_EXTENSION* ext;
|
||||
if (!PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER;
|
||||
if (!PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uint16_t cmd = PciRawRead16(ext->Info.Address.Bus,
|
||||
ext->Info.Address.Device,
|
||||
@@ -571,16 +571,16 @@ __declspec(dllexport) KSTATUS PciEnableDevice(DEVICE_OBJECT* pdo, uint32_t flags
|
||||
ext->Info.Address.Function,
|
||||
PCI_REG_COMMAND_STATUS,
|
||||
cmd);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Returns interrupt.
|
||||
__declspec(dllexport) KSTATUS PciGetInterrupt(DEVICE_OBJECT* pdo, uint8_t* outIrq) {
|
||||
PCI_PDO_EXTENSION* ext;
|
||||
if (!outIrq || !PciIsPdo(pdo, &ext)) return STATUS_INVALID_PARAMETER;
|
||||
if (ext->Info.InterruptLine == 0xFFu) return STATUS_NOT_FOUND;
|
||||
if (!outIrq || !PciIsPdo(pdo, &ext)) return NTLSTATUS_INVALID_PARAMETER;
|
||||
if (ext->Info.InterruptLine == 0xFFu) return NTLSTATUS_NOT_FOUND;
|
||||
*outIrq = ext->Info.InterruptLine;
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Returns capability.
|
||||
@@ -608,20 +608,20 @@ static uint8_t PciFindCapability(PCI_PDO_EXTENSION* ext, uint8_t capId) {
|
||||
__declspec(dllexport) KSTATUS PciEnableMsi(DEVICE_OBJECT* pdo, uint8_t irqSlot) {
|
||||
PCI_PDO_EXTENSION* ext;
|
||||
if (!PciIsPdo(pdo, &ext))
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
if (irqSlot >= 24u)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
uint8_t cap = PciFindCapability(ext, PCI_CAP_ID_MSI);
|
||||
if (!cap)
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
return NTLSTATUS_NOT_SUPPORTED;
|
||||
|
||||
uint32_t bspLapic = HalGetBspLapicId();
|
||||
if (!HalApicUsingX2Apic() && bspLapic >= 256u)
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
return NTLSTATUS_NOT_SUPPORTED;
|
||||
if (HalApicUsingX2Apic() && bspLapic >= 256u) {
|
||||
// Extended x2APIC MSI destinations need interrupt-remapping awareness.
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
return NTLSTATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
uint8_t bus = ext->Info.Address.Bus;
|
||||
@@ -657,17 +657,17 @@ __declspec(dllexport) KSTATUS PciEnableMsi(DEVICE_OBJECT* pdo, uint8_t irqSlot)
|
||||
|
||||
DbgPrint("pci: MSI enabled %02x:%02x.%u cap=0x%02x vector=0x%02x irqslot=%u dest=%u %s\n",
|
||||
bus, dev, fn, cap, vector, irqSlot, bspLapic, is64 ? "64-bit" : "32-bit");
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Enables a single MSI vector, allocating the nt-lite IRQ slot internally.
|
||||
__declspec(dllexport) KSTATUS PciEnableMsiAuto(DEVICE_OBJECT* pdo, uint8_t* outIrqSlot) {
|
||||
PCI_PDO_EXTENSION* ext;
|
||||
if (!outIrqSlot || !PciIsPdo(pdo, &ext))
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
|
||||
if (!PciFindCapability(ext, PCI_CAP_ID_MSI))
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
return NTLSTATUS_NOT_SUPPORTED;
|
||||
|
||||
uint8_t irq = 0xFFu;
|
||||
KSTATUS st = KeIrqAllocateMsiVector(&irq);
|
||||
@@ -679,12 +679,12 @@ __declspec(dllexport) KSTATUS PciEnableMsiAuto(DEVICE_OBJECT* pdo, uint8_t* outI
|
||||
return st;
|
||||
|
||||
*outIrqSlot = irq;
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Implements the driver Entry operation.
|
||||
KSTATUS DriverEntry(const HAL_API* hal) {
|
||||
if (!hal) return STATUS_INVALID_PARAMETER;
|
||||
if (!hal) return NTLSTATUS_INVALID_PARAMETER;
|
||||
gHal = hal;
|
||||
gPciDeviceCount = 0;
|
||||
|
||||
@@ -697,5 +697,5 @@ KSTATUS DriverEntry(const HAL_API* hal) {
|
||||
DbgPrint("pci: DriverEntry ABI=%u\n", PciDriverAbiVersion());
|
||||
PciEnumerateBus();
|
||||
DbgPrint("pci: enumeration complete, devices=%u\n", gPciDeviceCount);
|
||||
return STATUS_SUCCESS;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
Reference in new issue
Block a user