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:
maksw committed 2026-10-26 10:08:03 +01:00
1 parent c0ad63c27f
commit d36f19509c
160 files changed
+6563 -7366

No files matched your search

+77 -12
View File
@@ -5,6 +5,7 @@
#include <kernel/hal/hal_api.h>
#include <kernel/hal/hal_timer.h>
#include <stdint.h>
#include <stdbool.h>
#include <intrin.h>
@@ -34,6 +35,12 @@ static volatile uint32_t* gIoapic = (volatile uint32_t*)0;
static uint32_t gBspLapicId = 0;
static uint8_t gX2ApicSupported = 0;
static uint8_t gX2ApicEnabled = 0;
static uint32_t gIoapicGsiBase = 0;
static uint32_t gIoapicRedirectionCount = 0;
static uint32_t gIsaGsi[16];
static uint16_t gIsaFlags[16];
static uint16_t gSciIrq = UINT16_MAX;
static bool gIsaOverridesInitialized = false;
#define IOAPIC_IDX 0x00
#define IOAPIC_DATA 0x10
@@ -188,29 +195,86 @@ KSTATUS HalApicComposeMsi(uint8_t vector, HAL_MSI_MESSAGE* messageOut) {
return NTLSTATUS_SUCCESS;
}
// Initializes the identity ISA map before processing MADT source overrides.
static void HalApicInitializeIsaMap(void) {
if (gIsaOverridesInitialized) return;
for (uint32_t irq = 0; irq < 16; ++irq) {
gIsaGsi[irq] = irq;
gIsaFlags[irq] = 0;
}
gIsaOverridesInitialized = true;
}
// Records the global-system-interrupt base of the currently supported IOAPIC.
void HalApicSetGsiBase(uint32_t gsiBase) { gIoapicGsiBase = gsiBase; }
// Preserves MADT interrupt-source overrides for legacy ISA devices.
void HalApicSetIsaOverride(uint8_t irq, uint32_t gsi, uint16_t flags) {
if (irq >= 16) return;
HalApicInitializeIsaMap();
gIsaGsi[irq] = gsi;
gIsaFlags[irq] = flags;
}
// Marks the FADT SCI as a low-active, level-triggered interrupt by default.
void HalApicSetSciIrq(uint16_t irq) { gSciIrq = irq; }
// Resolves one logical IRQ to a physical pin on the selected IOAPIC.
static bool HalApicResolveIrq(uint8_t irq, uint32_t* pinOut, uint32_t* flagsOut) {
HalApicInitializeIsaMap();
uint32_t gsi = irq < 16 ? gIsaGsi[irq] : irq;
if (gsi < gIoapicGsiBase || gsi - gIoapicGsiBase >= gIoapicRedirectionCount)
return false;
uint32_t flags = 0;
if (irq == gSciIrq) flags = (1u << 13) | (1u << 15);
if (irq < 16) {
uint16_t override = gIsaFlags[irq];
// MADT 00 is bus-conformant; 11 selects active low or level triggered.
if ((override & 3u) == 3u) flags |= (1u << 13);
else if ((override & 3u) == 1u) flags &= ~(1u << 13);
if (((override >> 2) & 3u) == 3u) flags |= (1u << 15);
else if (((override >> 2) & 3u) == 1u) flags &= ~(1u << 15);
}
*pinOut = gsi - gIoapicGsiBase;
*flagsOut = flags;
return true;
}
// Reports whether a platform IRQ can be routed by the current IOAPIC.
bool HalApicCanRouteIrq(uint8_t irq) {
uint32_t pin, flags;
return irq < 24 && HalApicResolveIrq(irq, &pin, &flags);
}
// Implements the apic Route Irq operation.
void HalApicRouteIrq(uint8_t irq) {
// Full initial setup of the redirection entry.
// Sets the vector and clears the mask bit in one write.
uint32_t vector = IRQ_VECTOR_BASE + irq; // e.g. IRQ 1 -> vector 0x21
IoapicWrite(IOREDTBL_HI(irq), (gBspLapicId & 0xFFu) << 24); // external IRQs target the BSP
IoapicWrite(IOREDTBL_LO(irq), vector); // unmasked (bit 16 = 0), edge, fixed
uint32_t pin, flags;
if (!HalApicResolveIrq(irq, &pin, &flags)) return;
uint32_t vector = IRQ_VECTOR_BASE + irq;
IoapicWrite(IOREDTBL_HI(pin), (gBspLapicId & 0xFFu) << 24);
IoapicWrite(IOREDTBL_LO(pin), vector | flags);
}
// Implements the apic Mask Irq operation.
void HalApicMaskIrq(uint8_t irq) {
uint32_t lo = IoapicRead(IOREDTBL_LO(irq));
uint32_t pin, flags;
if (!HalApicResolveIrq(irq, &pin, &flags)) return;
uint32_t lo = IoapicRead(IOREDTBL_LO(pin));
lo |= (1 << 16);
IoapicWrite(IOREDTBL_LO(irq), lo);
IoapicWrite(IOREDTBL_LO(pin), lo);
}
// Implements the apic Unmask Irq operation.
void HalApicUnmaskIrq(uint8_t irq) {
uint32_t lo = IoapicRead(IOREDTBL_LO(irq));
lo &= ~(1 << 16); // clear mask bit
lo = (lo & ~0xFF) | (IRQ_VECTOR_BASE + irq);
IoapicWrite(IOREDTBL_HI(irq), (gBspLapicId & 0xFFu) << 24);
IoapicWrite(IOREDTBL_LO(irq), lo);
uint32_t pin, flags;
if (!HalApicResolveIrq(irq, &pin, &flags)) return;
uint32_t lo = IoapicRead(IOREDTBL_LO(pin));
lo = (lo & ~(0xFFu | (1u << 16) | (1u << 13) | (1u << 15))) |
(IRQ_VECTOR_BASE + irq) | flags;
IoapicWrite(IOREDTBL_HI(pin), (gBspLapicId & 0xFFu) << 24);
IoapicWrite(IOREDTBL_LO(pin), lo);
}
// Implements the apic Send Eoi operation.
@@ -240,8 +304,9 @@ void HalApicInitialize(uintptr_t lapicPhys, uintptr_t ioapicPhys) {
// Mask all IOAPIC lines initially.
uint32_t maxRedir = (IoapicRead(1) >> 16) & 0xFF;
for (uint8_t i = 0; i <= maxRedir; i++) {
IoapicWrite(IOREDTBL_LO(i), (1 << 16) | (IRQ_VECTOR_BASE + i));
gIoapicRedirectionCount = maxRedir + 1u;
for (uint32_t i = 0; i <= maxRedir; i++) {
IoapicWrite(IOREDTBL_LO(i), (1u << 16) | IRQ_VECTOR_BASE);
IoapicWrite(IOREDTBL_HI(i), (gBspLapicId & 0xFFu) << 24);
}
}