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:
maksw committed 2026-06-27 20:38:43 +02:00
1 parent 1f5477cf66
commit b7fcfce6f7
140 files changed
+7649 -3943

No files matched your search

+50 -50
View File
@@ -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;
}