replace ad hoc driver loading with a proper driver manager, new DDK, new PnP manager with device matching, asynchronous startup, resource ownership and removal, add shared PCI capability helpers, replace typed, rigid services with a proper service manager, implement proper system shutdown and restart, shutting down unloads drivers and shuts down services, add simple power button, remove heavyweight boot self-tests and SMP stress runs, add monotonic timestamps to kernel debug output, fruitless USB and PS/2 fixes, make test builds opt in.
This commit is contained in:
1 parent
c0ad63c27f
commit
d36f19509c
160 files changed
+6563
-7366
No files matched your search
+36
-36
@@ -1,3 +1,4 @@
|
||||
#include <ntlite/ddk/module.h>
|
||||
// PCI bus driver. This file owns PCI enumeration, PDO creation, BAR decoding, and explicit MMIO mappings for function drivers.
|
||||
|
||||
#include "pci.h"
|
||||
@@ -9,11 +10,11 @@
|
||||
#include <common/printf.h>
|
||||
|
||||
#include <ntlite/ddk/ddk.h>
|
||||
#include <ntlite/ddk/pci_caps.h>
|
||||
#include <ntlite/ddi/io_driver.h>
|
||||
|
||||
int _fltused; // MSVC floating-point helper anchor required by printf.obj
|
||||
|
||||
static const NTL_DDK* gDdk;
|
||||
static DRIVER_OBJECT gPciDriver;
|
||||
static uint32_t gPciDeviceCount;
|
||||
|
||||
@@ -65,14 +66,14 @@ static bool PciIsPdo(DEVICE_OBJECT* pdo, PCI_PDO_EXTENSION** outExt) {
|
||||
|
||||
// Implements the raw Read32 operation.
|
||||
static uint32_t PciRawRead32(uint8_t bus, uint8_t dev, uint8_t fn, uint16_t offset) {
|
||||
if (!gDdk || !gDdk->Platform || !gDdk->Platform->PciRead32 || offset > 0xFCu) return 0xFFFFFFFFu;
|
||||
return gDdk->Platform->PciRead32(0, bus, dev, fn, offset & 0xFCu);
|
||||
if (offset > 0xFCu) return 0xFFFFFFFFu;
|
||||
return KePciReadConfig32(0, bus, dev, fn, offset & 0xFCu);
|
||||
}
|
||||
|
||||
// Implements the raw Write32 operation.
|
||||
static void PciRawWrite32(uint8_t bus, uint8_t dev, uint8_t fn, uint16_t offset, uint32_t value) {
|
||||
if (!gDdk || !gDdk->Platform || !gDdk->Platform->PciWrite32 || offset > 0xFCu) return;
|
||||
gDdk->Platform->PciWrite32(0, bus, dev, fn, offset & 0xFCu, value);
|
||||
if (offset > 0xFCu) return;
|
||||
KePciWriteConfig32(0, bus, dev, fn, offset & 0xFCu, value);
|
||||
}
|
||||
|
||||
// Implements the raw Read8 operation.
|
||||
@@ -386,7 +387,7 @@ static KSTATUS PciCreatePdo(uint8_t bus, uint8_t dev, uint8_t fn) {
|
||||
}
|
||||
|
||||
gPciDeviceCount++;
|
||||
gDdk->Debug->Print("pci: %v ven=%04x dev=%04x class=%02x%02x%02x irq=%u\n",
|
||||
DbgPrint("pci: %v ven=%04x dev=%04x class=%02x%02x%02x irq=%u\n",
|
||||
pdo->Name,
|
||||
info.VendorId,
|
||||
info.DeviceId,
|
||||
@@ -411,7 +412,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 != NTLSTATUS_NOT_FOUND) {
|
||||
gDdk->Debug->Print("pci: failed to create PDO for %02x:%02x.%u st=0x%x\n",
|
||||
DbgPrint("pci: failed to create PDO for %02x:%02x.%u st=0x%x\n",
|
||||
bus, dev, fn, st);
|
||||
}
|
||||
}
|
||||
@@ -536,7 +537,7 @@ __declspec(dllexport) KSTATUS PciMapBar(DEVICE_OBJECT* pdo, uint8_t index, uint6
|
||||
return st;
|
||||
|
||||
for (uint64_t off = 0; off < mapLength; off += NTL_DDK_PAGE_SIZE) {
|
||||
st = gDdk->Memory->MapPage(virtBase + (uintptr_t)off, physBase + off, flags, NtlDdkMapFailIfPresent);
|
||||
st = MmDdkMapPage(virtBase + (uintptr_t)off, physBase + off, flags, NtlDdkMapFailIfPresent);
|
||||
if (!KSUCCESS(st))
|
||||
return st;
|
||||
}
|
||||
@@ -578,25 +579,26 @@ __declspec(dllexport) KSTATUS PciGetInterrupt(DEVICE_OBJECT* pdo, uint8_t* outIr
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Returns capability.
|
||||
// Reads configuration through the PCI provider bound to this PDO.
|
||||
static uint32_t PciCapabilityRead32(void* context, uint16_t offset) {
|
||||
const PCI_PDO_EXTENSION* ext = (const PCI_PDO_EXTENSION*)context;
|
||||
return PciRawRead32(ext->Info.Address.Bus,
|
||||
ext->Info.Address.Device,
|
||||
ext->Info.Address.Function,
|
||||
offset);
|
||||
}
|
||||
|
||||
// Finds one PCI capability using the shared DDK parser.
|
||||
static uint8_t PciFindCapability(PCI_PDO_EXTENSION* ext, uint8_t capId) {
|
||||
if (!ext || !ext->CapabilityOffset)
|
||||
return 0;
|
||||
|
||||
uint8_t cap = ext->CapabilityOffset & 0xFCu;
|
||||
for (uint32_t guard = 0; cap && guard < 48u; guard++) {
|
||||
uint32_t hdr = PciRawRead32(ext->Info.Address.Bus,
|
||||
ext->Info.Address.Device,
|
||||
ext->Info.Address.Function,
|
||||
cap);
|
||||
uint8_t id = (uint8_t)(hdr & 0xFFu);
|
||||
uint8_t next = (uint8_t)((hdr >> 8) & 0xFCu);
|
||||
if (id == capId)
|
||||
return cap;
|
||||
cap = next;
|
||||
}
|
||||
|
||||
return 0;
|
||||
const NTL_PCI_CONFIG_READER reader = { ext, PciCapabilityRead32 };
|
||||
uint8_t offset = 0;
|
||||
if (!KSUCCESS(NtlPciFindCapability(&reader, ext->CapabilityOffset & 0xFCu,
|
||||
capId, &offset)))
|
||||
return 0;
|
||||
return offset;
|
||||
}
|
||||
|
||||
// Enables msi.
|
||||
@@ -619,7 +621,7 @@ __declspec(dllexport) KSTATUS PciEnableMsi(DEVICE_OBJECT* pdo, uint8_t irqSlot)
|
||||
bool is64 = (control & PCI_MSI_CTRL_64BIT) != 0;
|
||||
bool pvm = (control & PCI_MSI_CTRL_PVM) != 0;
|
||||
NTL_DDK_MSI_MESSAGE message;
|
||||
KSTATUS messageStatus = gDdk->Interrupt->ComposeMsiMessage(irqSlot, &message);
|
||||
KSTATUS messageStatus = KeIrqComposeMsiMessage(irqSlot, &message);
|
||||
if (!KSUCCESS(messageStatus))
|
||||
return messageStatus;
|
||||
|
||||
@@ -643,7 +645,7 @@ __declspec(dllexport) KSTATUS PciEnableMsi(DEVICE_OBJECT* pdo, uint8_t irqSlot)
|
||||
cmd |= PCI_COMMAND_INTX_DISABLE;
|
||||
PciRawWrite16(bus, dev, fn, PCI_REG_COMMAND_STATUS, cmd);
|
||||
|
||||
gDdk->Debug->Print("pci: MSI enabled %02x:%02x.%u cap=0x%02x vector=0x%02x irqslot=%u %s\n",
|
||||
DbgPrint("pci: MSI enabled %02x:%02x.%u cap=0x%02x vector=0x%02x irqslot=%u %s\n",
|
||||
bus, dev, fn, cap, (unsigned)(message.Data & 0xFFu), irqSlot, is64 ? "64-bit" : "32-bit");
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
@@ -658,7 +660,7 @@ __declspec(dllexport) KSTATUS PciEnableMsiAuto(DEVICE_OBJECT* pdo, uint8_t* outI
|
||||
return NTLSTATUS_NOT_SUPPORTED;
|
||||
|
||||
uint8_t irq = 0xFFu;
|
||||
KSTATUS st = gDdk->Interrupt->AllocateMsiVector(&irq);
|
||||
KSTATUS st = KeIrqAllocateMsiVector(&irq);
|
||||
if (!KSUCCESS(st))
|
||||
return st;
|
||||
|
||||
@@ -670,21 +672,19 @@ __declspec(dllexport) KSTATUS PciEnableMsiAuto(DEVICE_OBJECT* pdo, uint8_t* outI
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Implements the driver Entry operation.
|
||||
KSTATUS DriverEntry(const NTL_DDK* ddk, NTL_DRIVER_INIT* init) {
|
||||
(void)init;
|
||||
if (!ddk || !ddk->Debug || !ddk->Interrupt || !ddk->Memory || !ddk->Platform) return NTLSTATUS_INVALID_PARAMETER;
|
||||
gDdk = ddk;
|
||||
static KSTATUS DriverInitialize(NTL_MODULE* module) {
|
||||
(void)module;
|
||||
|
||||
gPciDeviceCount = 0;
|
||||
|
||||
IoInitializeDriverObject(&gPciDriver, SYS_SV_LITERAL("pci"));
|
||||
gPciDriver.MajorFunction[IRP_MJ_PNP] = PciDispatchPnp;
|
||||
|
||||
KSTATUS st = IoRegisterDriverObject(&gPciDriver);
|
||||
if (!KSUCCESS(st)) return st;
|
||||
|
||||
gDdk->Debug->Print("pci: DriverEntry ABI=%u\n", PciDriverAbiVersion());
|
||||
DbgPrint("pci: module ABI=%u\n", PciDriverAbiVersion());
|
||||
PciEnumerateBus();
|
||||
gDdk->Debug->Print("pci: enumeration complete, devices=%u\n", gPciDeviceCount);
|
||||
DbgPrint("pci: enumeration complete, devices=%u\n", gPciDeviceCount);
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static DRIVER_OBJECT* const gModuleIoDrivers[] = { &gPciDriver };
|
||||
NTL_DECLARE_IO_MODULE(DriverInitialize, gModuleIoDrivers);
|
||||
Reference in new issue
Block a user