replace nob with ms' build, move disk creation to build.bat, major comment cleanup, remove old and stupid tests, overhaul interrupt management with per-CPU vector allocation, affinity migration and safe teardown, add proper IOAPIC routing and PCI MSI/MSI-X/INTx support, migrate drivers to the new interrupt API, integrate ACPICA with a proper OS services layer, move ACPI firmware events, power button handling and S5 shutdown into acpi.sys, add parallel driver startup and atomic publication, replace PnP arrays with dynamic lists, redesign service startup again to be asynchronous, add delayed startup mode for services, allow omitting keys in services.ini, fix acpi ec deferred work handling, fix kernel threads having garbage exit code.
This commit is contained in:
1 parent
d36f19509c
commit
36eef8f58d
696 files changed
+147281
-7530
No files matched your search
@@ -0,0 +1 @@
|
||||
!include $(BASEDIR)\makefile.def
|
||||
@@ -4,9 +4,6 @@
|
||||
#include "rtl8139.h"
|
||||
|
||||
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 } },
|
||||
@@ -17,53 +14,45 @@ static const IO_DRIVER_ID_TABLE gRtl8139IdTable = {
|
||||
sizeof(gRtl8139Ids) / sizeof(gRtl8139Ids[0]),
|
||||
};
|
||||
|
||||
// Implements the memory Barrier operation.
|
||||
static __forceinline void Rtl8139MemoryBarrier(void) {
|
||||
_ReadWriteBarrier();
|
||||
_mm_mfence();
|
||||
_ReadWriteBarrier();
|
||||
}
|
||||
|
||||
// Implements the read8 operation.
|
||||
static uint8_t Rtl8139Read8(RTL8139_DEVICE* r, uint32_t reg) {
|
||||
if (r->UseMmio)
|
||||
return *(volatile uint8_t*)(r->Mmio + reg);
|
||||
return __inbyte((unsigned short)(r->IoBase + reg));
|
||||
}
|
||||
|
||||
// Implements the read16 operation.
|
||||
static uint16_t Rtl8139Read16(RTL8139_DEVICE* r, uint32_t reg) {
|
||||
if (r->UseMmio)
|
||||
return *(volatile uint16_t*)(r->Mmio + reg);
|
||||
return __inword((unsigned short)(r->IoBase + reg));
|
||||
}
|
||||
|
||||
// Implements the read32 operation.
|
||||
static uint32_t Rtl8139Read32(RTL8139_DEVICE* r, uint32_t reg) {
|
||||
if (r->UseMmio)
|
||||
return *(volatile uint32_t*)(r->Mmio + reg);
|
||||
return __indword((unsigned short)(r->IoBase + reg));
|
||||
}
|
||||
|
||||
// Implements the write8 operation.
|
||||
static void Rtl8139Write8(RTL8139_DEVICE* r, uint32_t reg, uint8_t value) {
|
||||
if (r->UseMmio) *(volatile uint8_t*)(r->Mmio + reg) = value;
|
||||
else __outbyte((unsigned short)(r->IoBase + reg), value);
|
||||
}
|
||||
|
||||
// Implements the write16 operation.
|
||||
static void Rtl8139Write16(RTL8139_DEVICE* r, uint32_t reg, uint16_t value) {
|
||||
if (r->UseMmio) *(volatile uint16_t*)(r->Mmio + reg) = value;
|
||||
else __outword((unsigned short)(r->IoBase + reg), value);
|
||||
}
|
||||
|
||||
// Implements the write32 operation.
|
||||
static void Rtl8139Write32(RTL8139_DEVICE* r, uint32_t reg, uint32_t value) {
|
||||
if (r->UseMmio) *(volatile uint32_t*)(r->Mmio + reg) = value;
|
||||
else __outdword((unsigned short)(r->IoBase + reg), value);
|
||||
}
|
||||
|
||||
// Implements the reset operation.
|
||||
static KSTATUS Rtl8139Reset(RTL8139_DEVICE* r) {
|
||||
Rtl8139Write8(r, RTL8139_REG_CMD, RTL8139_CMD_RST);
|
||||
for (uint32_t i = 0; i < 1000; i++) {
|
||||
@@ -157,7 +146,6 @@ static KSTATUS Rtl8139AllocateDma(RTL8139_DEVICE* r) {
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Implements the rx Read16 operation.
|
||||
static uint16_t Rtl8139RxRead16(RTL8139_DEVICE* r, uint32_t offset) {
|
||||
offset %= RTL8139_RX_RING_SIZE;
|
||||
uint16_t lo = r->RxBuffer[offset];
|
||||
@@ -165,7 +153,6 @@ static uint16_t Rtl8139RxRead16(RTL8139_DEVICE* r, uint32_t offset) {
|
||||
return (uint16_t)(lo | (hi << 8));
|
||||
}
|
||||
|
||||
// Implements the rx Copy operation.
|
||||
static void Rtl8139RxCopy(RTL8139_DEVICE* r, uint32_t offset, void* dst, uint32_t length) {
|
||||
uint8_t* out = (uint8_t*)dst;
|
||||
offset %= RTL8139_RX_RING_SIZE;
|
||||
@@ -178,7 +165,6 @@ static void Rtl8139RxCopy(RTL8139_DEVICE* r, uint32_t offset, void* dst, uint32_
|
||||
memcpy(out + first, r->RxBuffer, length - first);
|
||||
}
|
||||
|
||||
// Implements the program Hardware operation.
|
||||
static void Rtl8139ProgramHardware(RTL8139_DEVICE* r) {
|
||||
// Wake the device and clear stale interrupts before installing buffers.
|
||||
Rtl8139Write8(r, RTL8139_REG_CONFIG1, 0x00);
|
||||
@@ -252,7 +238,6 @@ static void Rtl8139HandleRx(RTL8139_DEVICE* r) {
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the dpc Routine operation.
|
||||
static void Rtl8139DpcRoutine(KDPC* dpc, void* context, void* systemArgument1, void* systemArgument2) {
|
||||
(void)dpc;
|
||||
(void)systemArgument1;
|
||||
@@ -273,74 +258,19 @@ static void Rtl8139DpcRoutine(KDPC* dpc, void* context, void* systemArgument1, v
|
||||
DbgPrint("RTL8139: interrupt error bits=0x%04x\n", status);
|
||||
}
|
||||
|
||||
// Registers device.
|
||||
static KSTATUS Rtl8139RegisterDevice(RTL8139_DEVICE* r) {
|
||||
if (!r) return NTLSTATUS_INVALID_PARAMETER;
|
||||
static void Rtl8139Isr(void* context) {
|
||||
RTL8139_DEVICE* r = (RTL8139_DEVICE*)context;
|
||||
if (!r || !r->Started || r->Removed || r->SurpriseRemoved) return;
|
||||
uint16_t status = Rtl8139Read16(r, RTL8139_REG_ISR);
|
||||
status &= RTL8139_INTR_ENABLES;
|
||||
if (!status || status == 0xFFFFu)
|
||||
return;
|
||||
|
||||
uintptr_t flags = KeAcquireSpinlock(&gRtl8139RegistryLock);
|
||||
for (uint32_t i = 0; i < gRtl8139DeviceCount; i++) {
|
||||
if (gRtl8139Devices[i] == r) {
|
||||
KeReleaseSpinlock(&gRtl8139RegistryLock, flags);
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (gRtl8139DeviceCount >= RTL8139_MAX_DEVICES) {
|
||||
KeReleaseSpinlock(&gRtl8139RegistryLock, flags);
|
||||
return NTLSTATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
gRtl8139Devices[gRtl8139DeviceCount++] = r;
|
||||
KeReleaseSpinlock(&gRtl8139RegistryLock, flags);
|
||||
return NTLSTATUS_SUCCESS;
|
||||
Rtl8139Write16(r, RTL8139_REG_ISR, status);
|
||||
r->PendingIsr |= status;
|
||||
KeInsertQueueDpc(&r->Dpc, (void*)0, (void*)0);
|
||||
}
|
||||
|
||||
// Implements the unregister Device operation.
|
||||
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);
|
||||
}
|
||||
|
||||
// Implements the isr operation.
|
||||
static void Rtl8139Isr(void) {
|
||||
RTL8139_DEVICE* snapshot[RTL8139_MAX_DEVICES];
|
||||
uint32_t count = 0;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the send Frame operation.
|
||||
static KSTATUS Rtl8139SendFrame(NET_DEVICE* device, const void* frame, size_t length) {
|
||||
if (!device || !frame)
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
@@ -377,7 +307,6 @@ static KSTATUS Rtl8139SendFrame(NET_DEVICE* device, const void* frame, size_t le
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Implements the select Register Bar operation.
|
||||
static KSTATUS Rtl8139SelectRegisterBar(RTL8139_DEVICE* r) {
|
||||
if (!r || !r->Pdo)
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
@@ -478,12 +407,10 @@ static KSTATUS Rtl8139StartDevice(RTL8139_DEVICE* r) {
|
||||
return st;
|
||||
}
|
||||
|
||||
st = PciGetInterrupt(r->Pdo, &r->Irq);
|
||||
if (!KSUCCESS(st) || r->Irq == 0xFFu) {
|
||||
DbgPrint("RTL8139: no legacy PCI IRQ line wired\n");
|
||||
return KSUCCESS(st) ? NTLSTATUS_NOT_SUPPORTED : st;
|
||||
}
|
||||
|
||||
r->InterruptRequest.Routine = Rtl8139Isr;
|
||||
r->InterruptRequest.Context = r;
|
||||
r->InterruptRequest.Affinity = 0;
|
||||
r->InterruptRequest.Interrupt = (KE_INTERRUPT*)0;
|
||||
Rtl8139Write8(r, RTL8139_REG_CONFIG1, 0x00);
|
||||
st = Rtl8139Reset(r);
|
||||
if (!KSUCCESS(st)) {
|
||||
@@ -492,11 +419,10 @@ static KSTATUS Rtl8139StartDevice(RTL8139_DEVICE* r) {
|
||||
}
|
||||
|
||||
Rtl8139ReadMac(r);
|
||||
DbgPrint("RTL8139: MAC %02x:%02x:%02x:%02x:%02x:%02x irq=%u\n",
|
||||
DbgPrint("RTL8139: MAC %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
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);
|
||||
r->NetDevice.HardwareAddress[4], r->NetDevice.HardwareAddress[5]);
|
||||
|
||||
st = Rtl8139AllocateDma(r);
|
||||
if (!KSUCCESS(st))
|
||||
@@ -508,13 +434,16 @@ static KSTATUS Rtl8139StartDevice(RTL8139_DEVICE* r) {
|
||||
r->NetDevice.DriverContext = r;
|
||||
r->NetDevice.SendFrame = Rtl8139SendFrame;
|
||||
|
||||
st = Rtl8139RegisterDevice(r);
|
||||
bool message;
|
||||
st = PciConnectInterrupts(r->Pdo, &r->InterruptRequest, 1u, &message);
|
||||
if (!KSUCCESS(st)) {
|
||||
Rtl8139ReleaseDma(r);
|
||||
return st;
|
||||
}
|
||||
|
||||
KeIrqRegister(r->Irq, Rtl8139Isr);
|
||||
KE_INTERRUPT_INFO route;
|
||||
if (KSUCCESS(KeInterruptQuery(r->InterruptRequest.Interrupt, &route)))
|
||||
DbgPrint("RTL8139: cpu=%u vector=0x%02x mode=%s\n",
|
||||
route.CpuIndex, route.Vector, message ? "MSI/MSI-X" : "INTx");
|
||||
r->Started = true;
|
||||
Rtl8139ProgramHardware(r);
|
||||
r->Fdo->PnpState = DevicePnpStarted;
|
||||
@@ -522,12 +451,13 @@ static KSTATUS Rtl8139StartDevice(RTL8139_DEVICE* r) {
|
||||
st = NetRegisterDevice(&r->NetDevice);
|
||||
if (!KSUCCESS(st)) {
|
||||
Rtl8139StopDma(r);
|
||||
Rtl8139UnregisterDevice(r);
|
||||
if (r->InterruptRequest.Interrupt)
|
||||
PciDisconnectInterrupts(r->Pdo, &r->InterruptRequest, 1u);
|
||||
Rtl8139ReleaseDma(r);
|
||||
return st;
|
||||
}
|
||||
|
||||
DbgPrint("RTL8139: initialized; RX/TX enabled on IRQ %u\n", r->Irq);
|
||||
DbgPrint("RTL8139: initialized; RX/TX interrupt connected\n");
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -562,7 +492,8 @@ KSTATUS Rtl8139DispatchPnp(DEVICE_OBJECT* device, IRP* irp) {
|
||||
r->Removed = true;
|
||||
device->PnpState = DevicePnpDeleted;
|
||||
Rtl8139StopDma(r);
|
||||
Rtl8139UnregisterDevice(r);
|
||||
if (r->InterruptRequest.Interrupt)
|
||||
PciDisconnectInterrupts(r->Pdo, &r->InterruptRequest, 1u);
|
||||
Rtl8139ReleaseDma(r);
|
||||
IoDetachDevice(device);
|
||||
IoDeleteDevice(device);
|
||||
@@ -573,7 +504,6 @@ KSTATUS Rtl8139DispatchPnp(DEVICE_OBJECT* device, IRP* irp) {
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the add Device operation.
|
||||
KSTATUS Rtl8139AddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObject) {
|
||||
if (!driver || !physicalDeviceObject || physicalDeviceObject->Type != DeviceObjectPhysical)
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
@@ -589,7 +519,7 @@ KSTATUS Rtl8139AddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObj
|
||||
r->Magic = RTL8139_DEVICE_MAGIC;
|
||||
r->Fdo = fdo;
|
||||
r->Pdo = physicalDeviceObject;
|
||||
r->Irq = 0xFFu;
|
||||
r->PciInfo.InterruptLine = 0xFFu;
|
||||
r->TxLock = (SPINLOCK)SPINLOCK_INIT;
|
||||
|
||||
r->LowerDevice = IoAttachDeviceToDeviceStack(fdo, physicalDeviceObject);
|
||||
@@ -605,9 +535,7 @@ KSTATUS Rtl8139AddDevice(DRIVER_OBJECT* driver, DEVICE_OBJECT* physicalDeviceObj
|
||||
static KSTATUS DriverInitialize(NTL_MODULE* module) {
|
||||
(void)module;
|
||||
|
||||
DbgPrint("RTL8139: driver loading...\n");
|
||||
|
||||
gRtl8139DeviceCount = 0;
|
||||
|
||||
memset(&gRtl8139Driver, 0, sizeof(gRtl8139Driver));
|
||||
IoInitializeDriverObject(&gRtl8139Driver, SYS_SV_LITERAL("rtl8139"));
|
||||
|
||||
@@ -105,7 +105,7 @@ typedef struct RTL8139_DEVICE {
|
||||
PCI_DEVICE_INFO PciInfo;
|
||||
PCI_BAR RegisterBar;
|
||||
uint64_t RegisterBytes;
|
||||
uint8_t Irq;
|
||||
PCI_INTERRUPT_REQUEST InterruptRequest;
|
||||
|
||||
bool Started;
|
||||
bool Removed;
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
TARGETNAME=rtl8139
|
||||
TARGETPATH=obj
|
||||
TARGETTYPE=DRIVER
|
||||
FLAVOR=DRIVER
|
||||
TARGETLIBS="$(BASEDIR)\bin\kernel.lib" "$(BASEDIR)\bin\libc.lib" "$(BASEDIR)\bin\pci.lib"
|
||||
EXTRA_LFLAGS=/NOENTRY
|
||||
SOURCES=@/code/drivers/net/rtl8139/rtl8139.c
|
||||
Reference in new issue
Block a user