From 8d3b4ff95a63a51eb9b63e7e002e9294669247d5 Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Wed, 31 Jul 2024 21:16:39 +0200 Subject: [PATCH] Start application processors --- xtoskrnl/hl/init.c | 3 ++ xtoskrnl/hl/x86/cpu.c | 80 +++++++++++++++++++++++++++++++++++++++++ xtoskrnl/includes/hli.h | 9 +++++ 3 files changed, 92 insertions(+) diff --git a/xtoskrnl/hl/init.c b/xtoskrnl/hl/init.c index 6119f9a..6d526c3 100644 --- a/xtoskrnl/hl/init.c +++ b/xtoskrnl/hl/init.c @@ -36,6 +36,9 @@ HlInitializeSystem(VOID) return Status; } + /* Start all application processors */ + HlStartAllProcessors(); + /* Return success */ return STATUS_SUCCESS; } diff --git a/xtoskrnl/hl/x86/cpu.c b/xtoskrnl/hl/x86/cpu.c index b585ca6..4bec2db 100644 --- a/xtoskrnl/hl/x86/cpu.c +++ b/xtoskrnl/hl/x86/cpu.c @@ -78,3 +78,83 @@ HlStartProcessor(IN ULONG CpuId, /* Return success */ return STATUS_SUCCESS; } + +XTAPI +XTSTATUS +HlStartAllProcessors(VOID) +{ + PHYSICAL_ADDRESS ApPhysicalAddress; + PVOID ApVirtualAddress; + BOOLEAN Interrupts; + XTSTATUS Status; + USHORT Cpu; + +/* Temp bootstrap code size */ +#define AP_SPINUP_PAGE_COUNT 5 + + /* Check if at least one AP is present */ + if(HlpSystemInfo.CpuCount > 1) + { + /* Allocate 5 pages for AP bootstrap code and ensure it is low memory */ + Status = MmAllocateHardwareMemory(AP_SPINUP_PAGE_COUNT, FALSE, &ApPhysicalAddress); + if(Status != STATUS_SUCCESS || ApPhysicalAddress.QuadPart > (0x100000 - AP_SPINUP_PAGE_COUNT * MM_PAGE_SIZE)) + { + /* Not enough free pages at low memory available, return error */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Map AP bootstrap code */ + Status = MmMapHardwareMemory(ApPhysicalAddress, AP_SPINUP_PAGE_COUNT, TRUE, &ApVirtualAddress); + if(Status != STATUS_SUCCESS) + { + /* Failed to map AP bootstrap code, return error */ + return STATUS_INSUFFICIENT_RESOURCES; + } + + /* Copy AP bootstrap code into low memory */ + RtlCopyMemory(ApVirtualAddress, &ArStartApplicationProcessor, AP_SPINUP_PAGE_COUNT * MM_PAGE_SIZE); + + /* Iterate over all CPUs and start them */ + for(Cpu = 0; Cpu < HlpSystemInfo.CpuCount; Cpu++) + { + /* Check if this CPU is the BSP */ + if(HlpSystemInfo.CpuInfo[Cpu].ApicId == HlpGetCpuApicId()) + { + /* This is the BSP, set proper flag and mark as started */ + HlpSystemInfo.CpuInfo[Cpu].Bsp = TRUE; + HlpSystemInfo.CpuInfo[Cpu].Started = TRUE; + + /* Continue with next CPU */ + continue; + } + + /* Temp debugging */ + DebugPrint(L"Starting CPU #%lu (ACPI ID: %u, APIC ID: %u)\n", Cpu, HlpSystemInfo.CpuInfo[Cpu].AcpiId, HlpSystemInfo.CpuInfo[Cpu].ApicId); + + /* Check if interrupts are enabled and disable them */ + Interrupts = ArInterruptsEnabled(); + ArClearInterruptFlag(); + + /* Start the AP */ + Status = HlStartProcessor(HlpSystemInfo.CpuInfo[Cpu].ApicId, ApPhysicalAddress); + if(Status == STATUS_SUCCESS) + { + /* Mark AP as started */ + HlpSystemInfo.CpuInfo[Cpu].Started = TRUE; + } + + /* Check if interrupts were originally enabled */ + if(Interrupts) + { + /* Re-enable interrupts */ + ArSetInterruptFlag(); + } + } + + /* Unmap AP bootstrap code */ + MmUnmapHardwareMemory(ApVirtualAddress, AP_SPINUP_PAGE_COUNT, TRUE); + } + + /* Return success */ + return STATUS_SUCCESS; +} diff --git a/xtoskrnl/includes/hli.h b/xtoskrnl/includes/hli.h index b32c9a3..bca7e06 100644 --- a/xtoskrnl/includes/hli.h +++ b/xtoskrnl/includes/hli.h @@ -82,6 +82,15 @@ XTFASTCALL VOID HlSetRunLevel(IN KRUNLEVEL RunLevel); +XTAPI +XTSTATUS +HlStartAllProcessors(VOID); + +XTAPI +XTSTATUS +HlStartProcessor(IN ULONG CpuId, + IN PHYSICAL_ADDRESS ApEntryPoint); + XTAPI VOID HlpCacheAcpiTable(IN PACPI_DESCRIPTION_HEADER AcpiTable);