redo boot around an explicit system volume and fixed kernel/HAL images, redo volumes and filesystem paths around capabilities instead of drive numbers and kernel CWD state, add a capability/security model with derived and revocable handles and security contexts, add port IPC and rssrv to manage the userspace resource namespace and publish the system volume, move process, dll and path loading to userspace and add process builder syscalls, init now supervises rssrv and the session process, redo the syscall ABI around request structs and four arguments, add a volume manager and proper partition arrival/removal handling so FAT and NTFS mount dynamically, clean up the HAL/DDK boundary so drivers don't depend on HAL internals, save fpu state properly now, the serial driver doesn't hang on a missing port, fix AHCI startup races, fix timeout accounting, fix shared mmap writeback, more smoke tests
This commit is contained in:
1 parent
4add6789ba
commit
f882d339fb
232 files changed
+20934
-8898
No files matched your search
+62
-56
@@ -1,15 +1,16 @@
|
||||
// HAL APIC support. This file owns local APIC, I/O APIC, and interrupt-controller setup.
|
||||
|
||||
#include <kernel/hal/hal_apic.h>
|
||||
#include <ntlite/ddi/hal_api.h>
|
||||
#include <kernel/hal/hal_internal.h>
|
||||
#include <kernel/hal/hal_api.h>
|
||||
#include <kernel/hal/hal_timer.h>
|
||||
#include <stdint.h>
|
||||
#include <intrin.h>
|
||||
|
||||
extern HAL_API gApi;
|
||||
|
||||
// ---- Local APIC ----.
|
||||
static volatile uint32_t* gLapic = (volatile uint32_t *)0;
|
||||
#define LAPIC_REG(off) (*(volatile uint32_t *)((uint8_t *)gLapic + (off)))
|
||||
static volatile uint32_t* gLapic = (volatile uint32_t*)0;
|
||||
#define LAPIC_REG(off) (*(volatile uint32_t*)((uint8_t*)gLapic + (off)))
|
||||
#define LAPIC_ID 0x020
|
||||
#define LAPIC_EOI 0x0B0
|
||||
#define LAPIC_SPURIOUS 0x0F0
|
||||
@@ -27,10 +28,9 @@ static volatile uint32_t* gLapic = (volatile uint32_t *)0;
|
||||
|
||||
#define CPUID_FEATURE_ECX_X2APIC (1u << 21)
|
||||
|
||||
#define APIC_VECTOR_RESCHEDULE 0xF0u
|
||||
|
||||
// ---- I/O APIC ----.
|
||||
static volatile uint32_t* gIoapic = (volatile uint32_t *)0;
|
||||
static volatile uint32_t* gIoapic = (volatile uint32_t*)0;
|
||||
static uint32_t gBspLapicId = 0;
|
||||
static uint8_t gX2ApicSupported = 0;
|
||||
static uint8_t gX2ApicEnabled = 0;
|
||||
@@ -39,13 +39,13 @@ static uint8_t gX2ApicEnabled = 0;
|
||||
|
||||
// Implements the ioapic Read operation.
|
||||
static uint32_t IoapicRead(uint8_t reg) {
|
||||
*(volatile uint32_t *)((uint8_t *)gIoapic + IOAPIC_IDX) = reg;
|
||||
return *(volatile uint32_t *)((uint8_t *)gIoapic + IOAPIC_DATA);
|
||||
*(volatile uint32_t*)((uint8_t*)gIoapic + IOAPIC_IDX) = reg;
|
||||
return *(volatile uint32_t*)((uint8_t*)gIoapic + IOAPIC_DATA);
|
||||
}
|
||||
// Implements the ioapic Write operation.
|
||||
static void IoapicWrite(uint8_t reg, uint32_t val) {
|
||||
*(volatile uint32_t *)((uint8_t *)gIoapic + IOAPIC_IDX) = reg;
|
||||
*(volatile uint32_t *)((uint8_t *)gIoapic + IOAPIC_DATA) = val;
|
||||
*(volatile uint32_t*)((uint8_t*)gIoapic + IOAPIC_IDX) = reg;
|
||||
*(volatile uint32_t*)((uint8_t*)gIoapic + IOAPIC_DATA) = val;
|
||||
}
|
||||
|
||||
// Implements the apic Detect Mode operation.
|
||||
@@ -58,17 +58,9 @@ static void HalApicDetectMode(void) {
|
||||
gX2ApicEnabled = (gX2ApicSupported && (apicBase & IA32_APIC_BASE_X2APIC)) ? 1u : 0u;
|
||||
}
|
||||
|
||||
// Implements the apic Stall Fallback operation.
|
||||
static void HalApicStallFallback(uint32_t loops) {
|
||||
for (volatile uint32_t i = 0; i < loops; i++) {
|
||||
_mm_pause();
|
||||
}
|
||||
}
|
||||
|
||||
// Implements the apic Stall Us operation.
|
||||
// Stalls for the requested bootstrap interval using the HAL timer fallback chain.
|
||||
static void HalApicStallUs(uint32_t us) {
|
||||
if (gApi.Timer.Stall) gApi.Timer.Stall(us);
|
||||
else HalApicStallFallback(us * 128u + 1u);
|
||||
HalTimerStall(us);
|
||||
}
|
||||
|
||||
// Implements the apic Wait Icr Idle operation.
|
||||
@@ -102,25 +94,25 @@ static void HalApicSendIpi(uint32_t lapicId, uint32_t low) {
|
||||
// Interrupt vector base: IRQ 0 -> vector 0x20, IRQ 1 -> vector 0x21, ...
|
||||
#define IRQ_VECTOR_BASE 0x20
|
||||
|
||||
// Returns bsp Lapic Id.
|
||||
__declspec(dllexport) uint32_t HalGetBspLapicId(void) {
|
||||
// Returns the local interrupt-controller hardware ID of the boot processor.
|
||||
uint32_t HalApicGetBootProcessorId(void) {
|
||||
return gBspLapicId;
|
||||
}
|
||||
|
||||
// Implements the apic Using X2 Apic operation.
|
||||
__declspec(dllexport) uint8_t HalApicUsingX2Apic(void) {
|
||||
// Returns whether the local interrupt controller is using x2APIC mode.
|
||||
uint8_t HalApicUsingX2Apic(void) {
|
||||
return gX2ApicEnabled;
|
||||
}
|
||||
|
||||
// Implements the apic Can Address Id operation.
|
||||
__declspec(dllexport) uint8_t HalApicCanAddressId(uint32_t lapicId) {
|
||||
// Returns whether the active local interrupt-controller mode can address one hardware ID.
|
||||
uint8_t HalApicCanAddressId(uint32_t hardwareId) {
|
||||
if (gX2ApicEnabled)
|
||||
return 1u;
|
||||
return (lapicId < 256u) ? 1u : 0u;
|
||||
return (hardwareId < 256u) ? 1u : 0u;
|
||||
}
|
||||
|
||||
// Implements the apic Enable Current Cpu operation.
|
||||
__declspec(dllexport) void HalApicEnableCurrentCpu(void) {
|
||||
// Initializes the local interrupt controller on the current processor.
|
||||
void HalApicInitializeCurrentProcessor(void) {
|
||||
uint64_t apicBase = __readmsr(IA32_APIC_BASE) | IA32_APIC_BASE_ENABLE;
|
||||
|
||||
if (gX2ApicEnabled) {
|
||||
@@ -135,8 +127,8 @@ __declspec(dllexport) void HalApicEnableCurrentCpu(void) {
|
||||
LAPIC_REG(LAPIC_SPURIOUS) = LAPIC_ENABLE | 0xFF;
|
||||
}
|
||||
|
||||
// Implements the apic Send Panic Ipi operation.
|
||||
__declspec(dllexport) void HalApicSendPanicIpi(void) {
|
||||
// Broadcasts an NMI to every processor except the caller.
|
||||
void HalApicBroadcastNmi(void) {
|
||||
if (!gLapic && !gX2ApicEnabled) return;
|
||||
|
||||
// Stop-the-world panic IPI. Use NMI delivery instead of a normal fixed
|
||||
@@ -146,42 +138,56 @@ __declspec(dllexport) void HalApicSendPanicIpi(void) {
|
||||
HalApicSendIpi(0, (3u << 18) | (4u << 8)); // all-excluding-self, NMI
|
||||
}
|
||||
|
||||
// Implements the apic Send Reschedule Ipi operation.
|
||||
__declspec(dllexport) void HalApicSendRescheduleIpi(uint32_t lapicId) {
|
||||
if (!gLapic && !gX2ApicEnabled) return;
|
||||
HalApicSendIpi(lapicId, APIC_VECTOR_RESCHEDULE); // fixed delivery, physical destination
|
||||
// Sends one fixed-vector processor interrupt without exposing APIC mechanics.
|
||||
void HalApicSendProcessorInterrupt(uint32_t hardwareId, uint8_t vector) {
|
||||
if ((!gLapic && !gX2ApicEnabled) || vector < 0x20u || !HalApicCanAddressId(hardwareId))
|
||||
return;
|
||||
HalApicSendIpi(hardwareId, vector);
|
||||
}
|
||||
|
||||
// Implements the apic Send Tlb Shootdown Ipi operation.
|
||||
__declspec(dllexport) void HalApicSendTlbShootdownIpi(uint32_t lapicId) {
|
||||
if (!gLapic && !gX2ApicEnabled) return;
|
||||
|
||||
// TLB shootdown must reach CPUs that may be spinning with IF=0 inside
|
||||
// high-IRQL/spinlock regions, so use NMI delivery rather than a fixed
|
||||
// vector. The NMI stub handles active shootdowns and returns; unexpected
|
||||
// NMIs still go through the normal fault/panic path.
|
||||
HalApicSendIpi(lapicId, (4u << 8)); // NMI delivery, physical destination
|
||||
// Sends one non-maskable processor interrupt.
|
||||
void HalApicSendProcessorNmi(uint32_t hardwareId) {
|
||||
if ((!gLapic && !gX2ApicEnabled) || !HalApicCanAddressId(hardwareId))
|
||||
return;
|
||||
HalApicSendIpi(hardwareId, (4u << 8));
|
||||
}
|
||||
|
||||
// Starts application Processor.
|
||||
__declspec(dllexport) KSTATUS HalStartApplicationProcessor(uint32_t lapicId, uint8_t startupVector) {
|
||||
if ((!gLapic && !gX2ApicEnabled) || !startupVector || lapicId == gBspLapicId)
|
||||
// Starts one secondary processor through the local interrupt-controller startup protocol.
|
||||
KSTATUS HalApicStartProcessor(uint32_t hardwareId, uintptr_t startPhysical) {
|
||||
if ((!gLapic && !gX2ApicEnabled) || !startPhysical ||
|
||||
(startPhysical & 0xFFFu) != 0 || startPhysical >= 0x100000u ||
|
||||
hardwareId == gBspLapicId) {
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
if (!HalApicCanAddressId(lapicId))
|
||||
}
|
||||
if (!HalApicCanAddressId(hardwareId))
|
||||
return NTLSTATUS_NOT_SUPPORTED;
|
||||
|
||||
// INIT assert/deassert, then two SIPIs. The target begins at startupVector << 12.
|
||||
HalApicSendIpi(lapicId, 0x0000C500u); // INIT, level assert, level-triggered
|
||||
uint8_t startupVector = (uint8_t)(startPhysical >> 12);
|
||||
// INIT assert/deassert, then two SIPIs. The target begins at startPhysical.
|
||||
HalApicSendIpi(hardwareId, 0x0000C500u); // INIT, level assert, level-triggered
|
||||
HalApicStallUs(10000);
|
||||
HalApicSendIpi(lapicId, 0x00008500u); // INIT, level deassert
|
||||
HalApicSendIpi(hardwareId, 0x00008500u); // INIT, level deassert
|
||||
HalApicStallUs(200);
|
||||
HalApicSendIpi(lapicId, 0x00000600u | startupVector); // SIPI
|
||||
HalApicSendIpi(hardwareId, 0x00000600u | startupVector); // SIPI
|
||||
HalApicStallUs(200);
|
||||
HalApicSendIpi(lapicId, 0x00000600u | startupVector); // SIPI retry
|
||||
HalApicSendIpi(hardwareId, 0x00000600u | startupVector); // SIPI retry
|
||||
HalApicStallUs(200);
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Composes an MSI message targeting the boot processor without exposing APIC mode.
|
||||
KSTATUS HalApicComposeMsi(uint8_t vector, HAL_MSI_MESSAGE* messageOut) {
|
||||
if (!messageOut || vector < 0x20u)
|
||||
return NTLSTATUS_INVALID_PARAMETER;
|
||||
if (gBspLapicId >= 256u)
|
||||
return NTLSTATUS_NOT_SUPPORTED;
|
||||
|
||||
messageOut->Address = 0xFEE00000ull | ((uint64_t)(gBspLapicId & 0xFFu) << 12);
|
||||
messageOut->Data = vector;
|
||||
messageOut->Reserved = 0;
|
||||
return NTLSTATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Implements the apic Route Irq operation.
|
||||
void HalApicRouteIrq(uint8_t irq) {
|
||||
// Full initial setup of the redirection entry.
|
||||
@@ -220,8 +226,8 @@ void HalApicSendEoi(void) {
|
||||
void HalApicInitialize(uintptr_t lapicPhys, uintptr_t ioapicPhys) {
|
||||
HalApicDetectMode();
|
||||
|
||||
gLapic = (volatile uint32_t *)(gApi.PhysToVirt(lapicPhys));
|
||||
gIoapic = (volatile uint32_t *)(gApi.PhysToVirt(ioapicPhys));
|
||||
gLapic = (volatile uint32_t*)(HalPhysicalToVirtual(lapicPhys));
|
||||
gIoapic = (volatile uint32_t*)(HalPhysicalToVirtual(ioapicPhys));
|
||||
|
||||
// The BSP is the CPU executing HAL init. Keep all external/device IRQs
|
||||
// routed to this LAPIC; CPU-local IPIs use the local APIC directly.
|
||||
@@ -230,7 +236,7 @@ void HalApicInitialize(uintptr_t lapicPhys, uintptr_t ioapicPhys) {
|
||||
else
|
||||
gBspLapicId = (LAPIC_REG(LAPIC_ID) >> 24) & 0xFF;
|
||||
|
||||
HalApicEnableCurrentCpu();
|
||||
HalApicInitializeCurrentProcessor();
|
||||
|
||||
// Mask all IOAPIC lines initially.
|
||||
uint32_t maxRedir = (IoapicRead(1) >> 16) & 0xFF;
|
||||
|
||||
Reference in new issue
Block a user