From 96034533348a39ab26d05c102a80a457ae3bf7e5 Mon Sep 17 00:00:00 2001 From: Aiken Harris Date: Sun, 17 May 2026 14:29:45 +0200 Subject: [PATCH] Implement Application Processor bootstrap function --- xtoskrnl/includes/ke/krnlinit.hh | 3 +- xtoskrnl/ke/amd64/krnlinit.cc | 173 +++++++++++++++++++------------ xtoskrnl/ke/i686/krnlinit.cc | 117 ++++++++++++++------- 3 files changed, 186 insertions(+), 107 deletions(-) diff --git a/xtoskrnl/includes/ke/krnlinit.hh b/xtoskrnl/includes/ke/krnlinit.hh index e92ccee..351890f 100644 --- a/xtoskrnl/includes/ke/krnlinit.hh +++ b/xtoskrnl/includes/ke/krnlinit.hh @@ -18,12 +18,13 @@ namespace KE class KernelInit { public: + STATIC XTAPI VOID BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock); STATIC XTAPI VOID InitializeMachine(VOID); STATIC XTAPI VOID SwitchBootStack(VOID); private: + STATIC XTAPI VOID BootstrapKernel(VOID); STATIC XTAPI VOID InitializeKernel(VOID); - STATIC XTAPI VOID StartKernel(VOID); }; } diff --git a/xtoskrnl/ke/amd64/krnlinit.cc b/xtoskrnl/ke/amd64/krnlinit.cc index d19742b..d56e301 100644 --- a/xtoskrnl/ke/amd64/krnlinit.cc +++ b/xtoskrnl/ke/amd64/krnlinit.cc @@ -9,6 +9,111 @@ #include +/** + * Bootstraps an Application Processor (AP) into the active kernel. This routine is executed exclusively by secondary + * processors after being awakened by the BSP. It is called directly from the startup trampoline. + * + * @param StartBlock + * Supplies a pointer to the processor start block containing initialization information provided by the kernel. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock) +{ + PKPROCESSOR_BLOCK ProcessorBlock; + + /* Initialize application CPU */ + AR::ProcSup::InitializeProcessor(StartBlock->ProcessorStructures); + + /* Initialize processor */ + HL::Cpu::InitializeProcessor(); + + /* Raise to HIGH runlevel */ + KE::RunLevel::RaiseRunLevel(HIGH_LEVEL); + + /* Mark processor as started */ + StartBlock->Started = TRUE; + + /* Get current processor block */ + ProcessorBlock = KE::Processor::GetCurrentProcessorBlock(); + + /* Enter infinite loop */ + DebugPrint(L"KernelInit::BootstrapApplicationProcessor() finished for CPU #%lu. Entering infinite loop.\n", + ProcessorBlock->CpuNumber); + KE::Crash::HaltSystem(); +} + +/** + * Bootstraps the XT kernel and global subsystems. This routine is executed exclusively by the Bootstrap Processor + * and it is called immediately after switching to the kernel boot stack. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KE::KernelInit::BootstrapKernel(VOID) +{ + PKPROCESSOR_CONTROL_BLOCK Prcb; + ULONG_PTR PageDirectory[2]; + PKPROCESS CurrentProcess; + PKTHREAD CurrentThread; + + /* Get processor control block and current thread */ + Prcb = KE::Processor::GetCurrentProcessorControlBlock(); + CurrentThread = KE::Processor::GetCurrentThread(); + + /* Get current process */ + CurrentProcess = CurrentThread->ApcState.Process; + + /* Initialize CPU power state structures */ + PO::Idle::InitializeProcessorIdleState(Prcb); + + /* Save processor state */ + KE::Processor::SaveProcessorState(&Prcb->ProcessorState); + + /* Initialize spin locks */ + KE::SpinLock::InitializeAllLocks(); + KE::SpinLock::InitializeLockQueues(); + + /* Lower to APC runlevel */ + KE::RunLevel::LowerRunLevel(APC_LEVEL); + + /* Initialize XTOS kernel */ + InitializeKernel(); + + /* Initialize Idle process */ + PageDirectory[0] = 0; + PageDirectory[1] = 0; + KE::KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE); + CurrentProcess->Quantum = MAXCHAR; + + /* Initialize Idle thread */ + KE::KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR, + NULLPTR, NULLPTR, AR::ProcSup::GetBootStack(), TRUE); + CurrentThread->NextProcessor = Prcb->CpuNumber; + CurrentThread->Priority = THREAD_HIGH_PRIORITY; + CurrentThread->State = Running; + CurrentThread->Affinity = (ULONG_PTR)1 << Prcb->CpuNumber; + CurrentThread->WaitRunLevel = DISPATCH_LEVEL; + CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber; + + /* Initialize Memory Manager */ + MM::Manager::InitializeMemoryManager(); + + /* Enable shadow buffer for framebuffer */ + HL::FrameBuffer::EnableShadowBuffer(); + + /* Enter infinite loop */ + DebugPrint(L"KernelInit::BootstrapKernel() finished. Entering infinite loop.\n"); + KE::Crash::HaltSystem(); +} + /** * This routine initializes XT kernel. * @@ -60,72 +165,6 @@ KE::KernelInit::InitializeMachine(VOID) HL::Cpu::InitializeProcessor(); } -/** - * This routine starts up the XT kernel. It is called after switching boot stack. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -KE::KernelInit::StartKernel(VOID) -{ - PKPROCESSOR_CONTROL_BLOCK Prcb; - ULONG_PTR PageDirectory[2]; - PKPROCESS CurrentProcess; - PKTHREAD CurrentThread; - - /* Get processor control block and current thread */ - Prcb = KE::Processor::GetCurrentProcessorControlBlock(); - CurrentThread = KE::Processor::GetCurrentThread(); - - /* Get current process */ - CurrentProcess = CurrentThread->ApcState.Process; - - /* Initialize CPU power state structures */ - PO::Idle::InitializeProcessorIdleState(Prcb); - - /* Save processor state */ - KE::Processor::SaveProcessorState(&Prcb->ProcessorState); - - /* Initialize spin locks */ - KE::SpinLock::InitializeAllLocks(); - KE::SpinLock::InitializeLockQueues(); - - /* Lower to APC runlevel */ - KE::RunLevel::LowerRunLevel(APC_LEVEL); - - /* Initialize XTOS kernel */ - InitializeKernel(); - - /* Initialize Idle process */ - PageDirectory[0] = 0; - PageDirectory[1] = 0; - KE::KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE); - CurrentProcess->Quantum = MAXCHAR; - - /* Initialize Idle thread */ - KE::KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR, - NULLPTR, NULLPTR, AR::ProcSup::GetBootStack(), TRUE); - CurrentThread->NextProcessor = Prcb->CpuNumber; - CurrentThread->Priority = THREAD_HIGH_PRIORITY; - CurrentThread->State = Running; - CurrentThread->Affinity = (ULONG_PTR)1 << Prcb->CpuNumber; - CurrentThread->WaitRunLevel = DISPATCH_LEVEL; - CurrentProcess->ActiveProcessors |= (ULONG_PTR)1 << Prcb->CpuNumber; - - /* Initialize Memory Manager */ - MM::Manager::InitializeMemoryManager(); - - /* Enable shadow buffer for framebuffer */ - HL::FrameBuffer::EnableShadowBuffer(); - - /* Enter infinite loop */ - DebugPrint(L"KernelInit::StartKernel() finished. Entering infinite loop.\n"); - KE::Crash::HaltSystem(); -} - /** * Switches execution to a new boot stack and transfers control to the KernelInit::StartKernel() routine. * @@ -144,7 +183,7 @@ KE::KernelInit::SwitchBootStack(VOID) Stack = ((ULONG_PTR)AR::ProcSup::GetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1); /* Get address of KernelInit::StartKernel() */ - StartKernel = (PVOID)KE::KernelInit::StartKernel; + StartKernel = (PVOID)KE::KernelInit::BootstrapKernel; /* Discard old stack frame, switch stack and jump to KernelInit::StartKernel() */ __asm__ volatile("movq %[Stack], %%rsp\n" diff --git a/xtoskrnl/ke/i686/krnlinit.cc b/xtoskrnl/ke/i686/krnlinit.cc index 955d618..78ce2b5 100644 --- a/xtoskrnl/ke/i686/krnlinit.cc +++ b/xtoskrnl/ke/i686/krnlinit.cc @@ -10,7 +10,11 @@ /** - * This routine initializes XT kernel. + * Bootstraps an Application Processor (AP) into the active kernel. This routine is executed exclusively by secondary + * processors after being awakened by the BSP. It is called directly from the startup trampoline. + * + * @param StartBlock + * Supplies a pointer to the processor start block containing initialization information provided by the kernel. * * @return This routine does not return any value. * @@ -18,50 +22,34 @@ */ XTAPI VOID -KE::KernelInit::InitializeKernel(VOID) +KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock) { - XTSTATUS Status; + PKPROCESSOR_BLOCK ProcessorBlock; - /* Initialize hardware layer subsystem */ - Status = HL::Init::InitializeSystem(); - if(Status != STATUS_SUCCESS) - { - /* Hardware layer initialization failed, kernel panic */ - DebugPrint(L"Failed to initialize hardware layer subsystem!\n"); - KE::Crash::Panic(0); - } -} - -/** - * Performs architecture-specific initialization for the kernel executive. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -KE::KernelInit::InitializeMachine(VOID) -{ - /* Re-enable IDE interrupts */ - HL::IoPort::WritePort8(0x376, 0); - HL::IoPort::WritePort8(0x3F6, 0); - - /* Initialize frame buffer */ - HL::FrameBuffer::InitializeFrameBuffer(); - - /* Initialize page map support */ - MM::Paging::InitializePageMapSupport(); - - /* Initialize Kernel Shared Data (KSD) */ - KE::SharedData::InitializeKernelSharedData(); + /* Initialize application CPU */ + AR::ProcSup::InitializeProcessor(StartBlock->ProcessorStructures); /* Initialize processor */ HL::Cpu::InitializeProcessor(); + + /* Raise to HIGH runlevel */ + KE::RunLevel::RaiseRunLevel(HIGH_LEVEL); + + /* Mark processor as started */ + StartBlock->Started = TRUE; + + /* Get current processor block */ + ProcessorBlock = KE::Processor::GetCurrentProcessorBlock(); + + /* Enter infinite loop */ + DebugPrint(L"KernelInit::BootstrapApplicationProcessor() finished for CPU #%lu. Entering infinite loop.\n", + ProcessorBlock->CpuNumber); + KE::Crash::HaltSystem(); } /** - * This routine starts up the XT kernel. It is called after switching boot stack. + * Bootstraps the XT kernel and global subsystems. This routine is executed exclusively by the Bootstrap Processor + * and it is called immediately after switching to the kernel boot stack. * * @return This routine does not return any value. * @@ -69,7 +57,7 @@ KE::KernelInit::InitializeMachine(VOID) */ XTAPI VOID -KE::KernelInit::StartKernel(VOID) +KE::KernelInit::BootstrapKernel(VOID) { PKPROCESSOR_CONTROL_BLOCK Prcb; ULONG_PTR PageDirectory[2]; @@ -126,6 +114,57 @@ KE::KernelInit::StartKernel(VOID) KE::Crash::HaltSystem(); } +/** + * This routine initializes XT kernel. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KE::KernelInit::InitializeKernel(VOID) +{ + XTSTATUS Status; + + /* Initialize hardware layer subsystem */ + Status = HL::Init::InitializeSystem(); + if(Status != STATUS_SUCCESS) + { + /* Hardware layer initialization failed, kernel panic */ + DebugPrint(L"Failed to initialize hardware layer subsystem!\n"); + KE::Crash::Panic(0); + } +} + +/** + * Performs architecture-specific initialization for the kernel executive. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KE::KernelInit::InitializeMachine(VOID) +{ + /* Re-enable IDE interrupts */ + HL::IoPort::WritePort8(0x376, 0); + HL::IoPort::WritePort8(0x3F6, 0); + + /* Initialize frame buffer */ + HL::FrameBuffer::InitializeFrameBuffer(); + + /* Initialize page map support */ + MM::Paging::InitializePageMapSupport(); + + /* Initialize Kernel Shared Data (KSD) */ + KE::SharedData::InitializeKernelSharedData(); + + /* Initialize processor */ + HL::Cpu::InitializeProcessor(); +} + /** * Switches execution to a new boot stack and transfers control to the KernelInit::StartKernel() routine. * @@ -144,7 +183,7 @@ KE::KernelInit::SwitchBootStack(VOID) Stack = ((ULONG_PTR)AR::ProcSup::GetBootStack() + KERNEL_STACK_SIZE) & ~(STACK_ALIGNMENT - 1); /* Get address of KernelInit::StartKernel() */ - StartKernel = (PVOID)KE::KernelInit::StartKernel; + StartKernel = (PVOID)KE::KernelInit::BootstrapKernel; /* Discard old stack frame, switch stack, make space for NPX and jump to KernelInit::StartKernel() */ __asm__ volatile("movl %[Stack], %%esp\n"