add system time, clean up pci into pci.sys, clean up syscall names, fix USERAPC1 typo

This commit is contained in:
maksw committed 2026-06-11 18:11:59 +02:00
1 parent c1a291c4c9
commit e41bf6e2c0
64 files changed
+4514 -2220

No files matched your search

+276 -50
View File
@@ -2,8 +2,19 @@
#include "rtl8139.h"
const HAL_API* gHal;
RTL8139_DEVICE gDevice;
bool gDevicePresent = false;
static DRIVER_OBJECT gRtl8139Driver;
static RTL8139_DEVICE* gRtl8139Devices[RTL8139_MAX_DEVICES];
static uint32_t gRtl8139DeviceCount;
static SPINLOCK gRtl8139RegistryLock = SPINLOCK_INIT;
static const IO_DEVICE_ID gRtl8139Ids[] = {
{ IoBusPci, { "PCI\\VEN_10EC&DEV_8139", sizeof("PCI\\VEN_10EC&DEV_8139") - 1 } },
};
static const IO_DRIVER_ID_TABLE gRtl8139IdTable = {
gRtl8139Ids,
sizeof(gRtl8139Ids) / sizeof(gRtl8139Ids[0]),
};
static __forceinline void Rtl8139MemoryBarrier(void) {
_ReadWriteBarrier();
@@ -201,19 +212,68 @@ static void Rtl8139DpcRoutine(KDPC* dpc, void* context, void* systemArgument1, v
DbgPrint("RTL8139: interrupt error bits=0x%04x\n", status);
}
static KSTATUS Rtl8139RegisterDevice(RTL8139_DEVICE* r) {
if (!r) return STATUS_INVALID_PARAMETER;
uintptr_t flags = KeAcquireSpinlock(&gRtl8139RegistryLock);
for (uint32_t i = 0; i < gRtl8139DeviceCount; i++) {
if (gRtl8139Devices[i] == r) {
KeReleaseSpinlock(&gRtl8139RegistryLock, flags);
return STATUS_SUCCESS;
}
}
if (gRtl8139DeviceCount >= RTL8139_MAX_DEVICES) {
KeReleaseSpinlock(&gRtl8139RegistryLock, flags);
return STATUS_NO_MEMORY;
}
gRtl8139Devices[gRtl8139DeviceCount++] = r;
KeReleaseSpinlock(&gRtl8139RegistryLock, flags);
return STATUS_SUCCESS;
}
static void Rtl8139UnregisterDevice(RTL8139_DEVICE* r) {
if (!r) return;
uintptr_t flags = KeAcquireSpinlock(&gRtl8139RegistryLock);
for (uint32_t i = 0; i < gRtl8139DeviceCount; i++) {
if (gRtl8139Devices[i] == r) {
gRtl8139Devices[i] = gRtl8139Devices[gRtl8139DeviceCount - 1u];
gRtl8139Devices[gRtl8139DeviceCount - 1u] = (RTL8139_DEVICE*)0;
gRtl8139DeviceCount--;
break;
}
}
KeReleaseSpinlock(&gRtl8139RegistryLock, flags);
}
static void Rtl8139Isr(void) {
if (!gDevicePresent)
return;
RTL8139_DEVICE* snapshot[RTL8139_MAX_DEVICES];
uint32_t count = 0;
RTL8139_DEVICE* r = &gDevice;
uint16_t status = Rtl8139Read16(r, RTL8139_REG_ISR);
status &= RTL8139_INTR_ENABLES;
if (!status || status == 0xFFFFu)
return;
uintptr_t flags = KeAcquireSpinlock(&gRtl8139RegistryLock);
count = gRtl8139DeviceCount;
if (count > RTL8139_MAX_DEVICES)
count = RTL8139_MAX_DEVICES;
for (uint32_t i = 0; i < count; i++)
snapshot[i] = gRtl8139Devices[i];
KeReleaseSpinlock(&gRtl8139RegistryLock, flags);
Rtl8139Write16(r, RTL8139_REG_ISR, status);
r->PendingIsr |= status;
KeInsertQueueDpc(&r->Dpc, (void*)0, (void*)0);
for (uint32_t i = 0; i < count; i++) {
RTL8139_DEVICE* r = snapshot[i];
if (!r || !r->Started || r->Removed || r->SurpriseRemoved)
continue;
uint16_t status = Rtl8139Read16(r, RTL8139_REG_ISR);
status &= RTL8139_INTR_ENABLES;
if (!status || status == 0xFFFFu)
continue;
Rtl8139Write16(r, RTL8139_REG_ISR, status);
r->PendingIsr |= status;
KeInsertQueueDpc(&r->Dpc, (void*)0, (void*)0);
}
}
static KSTATUS Rtl8139SendFrame(NET_DEVICE* device, const void* frame, size_t length) {
@@ -252,76 +312,242 @@ static KSTATUS Rtl8139SendFrame(NET_DEVICE* device, const void* frame, size_t le
return STATUS_SUCCESS;
}
static KSTATUS Rtl8139Initialize(const HAL_API* hal) {
gHal = hal;
memset(&gDevice, 0, sizeof(gDevice));
gDevice.TxLock = (SPINLOCK)SPINLOCK_INIT;
static KSTATUS Rtl8139SelectRegisterBar(RTL8139_DEVICE* r) {
if (!r || !r->Pdo)
return STATUS_INVALID_PARAMETER;
if (!gHal->Pci.FindDevice(RTL8139_VENDOR_REALTEK, RTL8139_DEVICE_ID,
&gDevice.Bus, &gDevice.Dev, &gDevice.Fn)) {
DbgPrint("RTL8139: no PCI device 10ec:8139 found; skipping\n");
PCI_BAR best;
PCI_BAR fallback;
memset(&best, 0, sizeof(best));
memset(&fallback, 0, sizeof(fallback));
best.Type = PciBarUnused;
fallback.Type = PciBarUnused;
for (uint8_t i = 0; i < 6; i++) {
PCI_BAR bar;
KSTATUS st = PciGetBar(r->Pdo, i, &bar);
if (!KSUCCESS(st))
continue;
if (bar.Type == PciBarMemory32 || bar.Type == PciBarMemory64) {
best = bar;
break;
}
if (bar.Type == PciBarIo && fallback.Type == PciBarUnused)
fallback = bar;
}
if (best.Type == PciBarUnused)
best = fallback;
if (best.Type == PciBarMemory32 || best.Type == PciBarMemory64) {
KSTATUS st = PciMapBar(r->Pdo,
best.Index,
PAGE_PRESENT | PAGE_WRITE | PAGE_NOCACHE,
(void**)&r->Mmio,
&r->RegisterBytes);
if (!KSUCCESS(st))
return st;
r->RegisterBar = best;
r->UseMmio = true;
DbgPrint("RTL8139: BAR%u MMIO base=0x%016llX len=0x%llx virt=0x%016llX\n",
best.Index,
(unsigned long long)best.Base,
(unsigned long long)r->RegisterBytes,
r->Mmio);
return STATUS_SUCCESS;
}
DbgPrint("RTL8139: found Realtek PCI device 10ec:8139 at %u:%u.%u\n",
gDevice.Bus, gDevice.Dev, gDevice.Fn);
if (best.Type == PciBarIo) {
if (best.Base > 0xFFFFu)
return STATUS_NOT_SUPPORTED;
KSTATUS st = Rtl8139SelectRegisterBar(&gDevice);
r->RegisterBar = best;
r->RegisterBytes = best.Length;
r->IoBase = (uint16_t)best.Base;
r->UseMmio = false;
DbgPrint("RTL8139: BAR%u I/O base=0x%04x len=0x%llx\n",
best.Index,
r->IoBase,
(unsigned long long)r->RegisterBytes);
return STATUS_SUCCESS;
}
return STATUS_NOT_FOUND;
}
static KSTATUS Rtl8139StartDevice(RTL8139_DEVICE* r) {
if (!r || r->Magic != RTL8139_DEVICE_MAGIC || !r->Pdo || !r->Fdo)
return STATUS_INVALID_PARAMETER;
if (r->Started)
return STATUS_SUCCESS;
KSTATUS st = PciGetDeviceInfo(r->Pdo, &r->PciInfo);
if (!KSUCCESS(st)) {
DbgPrint("RTL8139: PciGetDeviceInfo failed: 0x%x\n", st);
return st;
}
DbgPrint("RTL8139: controller at PCI %02x:%02x.%x vendor=%04x device=%04x\n",
r->PciInfo.Address.Bus,
r->PciInfo.Address.Device,
r->PciInfo.Address.Function,
r->PciInfo.VendorId,
r->PciInfo.DeviceId);
st = Rtl8139SelectRegisterBar(r);
if (!KSUCCESS(st)) {
DbgPrint("RTL8139: no usable register BAR (0x%x)\n", st);
return st;
}
Rtl8139EnablePci(&gDevice);
gDevice.Irq = hal->Pci.GetIrqLine(gDevice.Bus, gDevice.Dev, gDevice.Fn);
if (gDevice.Irq == 0xFFu) {
DbgPrint("RTL8139: no legacy PCI IRQ line wired\n");
return STATUS_NOT_SUPPORTED;
st = PciEnableDevice(r->Pdo,
PCI_ENABLE_BUSMASTER |
PCI_ENABLE_INTX |
(r->UseMmio ? PCI_ENABLE_MEMORY : PCI_ENABLE_IO));
if (!KSUCCESS(st)) {
DbgPrint("RTL8139: PciEnableDevice failed: 0x%x\n", st);
return st;
}
// Wake, reset, then read the station address.
Rtl8139Write8(&gDevice, RTL8139_REG_CONFIG1, 0x00);
st = Rtl8139Reset(&gDevice);
st = PciGetInterrupt(r->Pdo, &r->Irq);
if (!KSUCCESS(st) || r->Irq == 0xFFu) {
DbgPrint("RTL8139: no legacy PCI IRQ line wired\n");
return KSUCCESS(st) ? STATUS_NOT_SUPPORTED : st;
}
Rtl8139Write8(r, RTL8139_REG_CONFIG1, 0x00);
st = Rtl8139Reset(r);
if (!KSUCCESS(st)) {
DbgPrint("RTL8139: reset timed out\n");
return st;
}
Rtl8139ReadMac(&gDevice);
Rtl8139ReadMac(r);
DbgPrint("RTL8139: MAC %02x:%02x:%02x:%02x:%02x:%02x irq=%u\n",
gDevice.NetDevice.HardwareAddress[0], gDevice.NetDevice.HardwareAddress[1],
gDevice.NetDevice.HardwareAddress[2], gDevice.NetDevice.HardwareAddress[3],
gDevice.NetDevice.HardwareAddress[4], gDevice.NetDevice.HardwareAddress[5],
gDevice.Irq);
r->NetDevice.HardwareAddress[0], r->NetDevice.HardwareAddress[1],
r->NetDevice.HardwareAddress[2], r->NetDevice.HardwareAddress[3],
r->NetDevice.HardwareAddress[4], r->NetDevice.HardwareAddress[5],
r->Irq);
st = Rtl8139AllocateDma(&gDevice);
st = Rtl8139AllocateDma(r);
if (!KSUCCESS(st))
return st;
KeInitializeDpc(&gDevice.Dpc, Rtl8139DpcRoutine, &gDevice);
KeInitializeDpc(&r->Dpc, Rtl8139DpcRoutine, r);
gDevice.NetDevice.Mtu = NET_MTU_ETHERNET;
gDevice.NetDevice.DriverContext = &gDevice;
gDevice.NetDevice.SendFrame = Rtl8139SendFrame;
r->NetDevice.Mtu = NET_MTU_ETHERNET;
r->NetDevice.DriverContext = r;
r->NetDevice.SendFrame = Rtl8139SendFrame;
Rtl8139ProgramHardware(&gDevice);
gDevicePresent = true;
KeIrqRegister(gDevice.Irq, Rtl8139Isr);
st = NetRegisterDevice(&gDevice.NetDevice);
st = Rtl8139RegisterDevice(r);
if (!KSUCCESS(st))
return st;
DbgPrint("RTL8139: initialized; RX/TX enabled on IRQ %u\n", gDevice.Irq);
KeIrqRegister(r->Irq, Rtl8139Isr);
r->Started = true;
Rtl8139ProgramHardware(r);
r->Fdo->PnpState = DevicePnpStarted;
st = NetRegisterDevice(&r->NetDevice);
if (!KSUCCESS(st)) {
Rtl8139Write16(r, RTL8139_REG_IMR, 0);
r->Started = false;
Rtl8139UnregisterDevice(r);
return st;
}
DbgPrint("RTL8139: initialized; RX/TX enabled on IRQ %u\n", r->Irq);
return STATUS_SUCCESS;
}
KSTATUS Rtl8139DispatchPnp(DEVICE_OBJECT* device, IRP* irp) {
if (!device || !irp || !device->DeviceExtension)
return STATUS_INVALID_PARAMETER;
RTL8139_DEVICE* r = (RTL8139_DEVICE*)device->DeviceExtension;
if (r->Magic != RTL8139_DEVICE_MAGIC)
return STATUS_INVALID_PARAMETER;
IO_STACK_LOCATION* ios = IoGetCurrentIrpStackLocation(irp);
if (!ios || ios->MajorFunction != IRP_MJ_PNP)
return STATUS_INVALID_PARAMETER;
switch ((IO_PNP_MINOR_FUNCTION)ios->MinorFunction) {
case IRP_MN_START_DEVICE:
return Rtl8139StartDevice(r);
case IRP_MN_QUERY_REMOVE_DEVICE:
case IRP_MN_CANCEL_REMOVE_DEVICE:
return STATUS_SUCCESS;
case IRP_MN_SURPRISE_REMOVAL:
r->SurpriseRemoved = true;
device->PnpState = DevicePnpSurpriseRemoved;
if (r->Started)
Rtl8139Write16(r, RTL8139_REG_IMR, 0);
return STATUS_SUCCESS;
case IRP_MN_REMOVE_DEVICE:
r->Removed = true;
device->PnpState = DevicePnpDeleted;
if (r->Started)
Rtl8139Write16(r, RTL8139_REG_IMR, 0);
Rtl8139UnregisterDevice(r);
IoDetachDevice(device);
IoDeleteDevice(device);
return STATUS_SUCCESS;
default:
return IoForwardIrpToLower(device, irp);
}
}
KSTATUS Rtl8139AddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject) {
if (!driver || !physicalDeviceObject || physicalDeviceObject->Type != DeviceObjectPhysical)
return STATUS_INVALID_PARAMETER;
DEVICE_OBJECT* fdo = (DEVICE_OBJECT*)0;
KSTATUS st = IoCreateDevice(driver, sizeof(RTL8139_DEVICE), &fdo);
if (!KSUCCESS(st))
return st;
(void)IoSetDeviceName(fdo, SYS_SV_LITERAL("rtl8139"));
RTL8139_DEVICE* r = (RTL8139_DEVICE*)fdo->DeviceExtension;
memset(r, 0, sizeof(*r));
r->Magic = RTL8139_DEVICE_MAGIC;
r->Fdo = fdo;
r->Pdo = physicalDeviceObject;
r->Irq = 0xFFu;
r->TxLock = (SPINLOCK)SPINLOCK_INIT;
r->LowerDevice = IoAttachDeviceToDeviceStack(fdo, physicalDeviceObject);
if (!r->LowerDevice) {
IoDeleteDevice(fdo);
return STATUS_FAILURE;
}
DbgPrint("RTL8139: FDO attached to %v\n", physicalDeviceObject->Name);
return STATUS_SUCCESS;
}
KSTATUS DriverEntry(const HAL_API* hal) {
if (!hal)
return STATUS_INVALID_PARAMETER;
DbgPrint("RTL8139: driver loading...\n");
KSTATUS st = Rtl8139Initialize(hal);
gHal = hal;
gRtl8139DeviceCount = 0;
memset(&gRtl8139Driver, 0, sizeof(gRtl8139Driver));
IoInitializeDriverObject(&gRtl8139Driver, SYS_SV_LITERAL("rtl8139"));
gRtl8139Driver.IdTable = &gRtl8139IdTable;
gRtl8139Driver.DriverAddDevice = Rtl8139AddDevice;
gRtl8139Driver.MajorFunction[IRP_MJ_PNP] = Rtl8139DispatchPnp;
KSTATUS st = IoRegisterDriverObject(&gRtl8139Driver);
if (!KSUCCESS(st))
DbgPrint("RTL8139: init failed: 0x%x\n", st);
DbgPrint("RTL8139: IoRegisterDriverObject failed: 0x%x\n", st);
return st;
}