diff --git a/sdk/xtdk/ketypes.h b/sdk/xtdk/ketypes.h index 0e8a3fc..0947c4b 100644 --- a/sdk/xtdk/ketypes.h +++ b/sdk/xtdk/ketypes.h @@ -478,8 +478,8 @@ typedef struct _KPROCESS ULONG_PTR DirectoryTable[2]; USHORT IopmOffset; UCHAR Iopl; - KAFFINITY_MAP Affinity; - VOLATILE KAFFINITY_MAP ActiveProcessors; + PKAFFINITY_MAP Affinity; + PKAFFINITY_MAP ActiveProcessors; ULONG KernelTime; ULONG UserTime; LIST_ENTRY ReadyListHead; @@ -603,9 +603,9 @@ typedef struct _KTHREAD CHAR PreviousMode; UCHAR ResourceIndex; UCHAR DisableBoost; - KAFFINITY_MAP UserAffinity; + PKAFFINITY_MAP UserAffinity; PKPROCESS Process; - KAFFINITY_MAP Affinity; + PKAFFINITY_MAP Affinity; PVOID ServiceTable; PKAPC_STATE ApcStatePointer[2]; KAPC_STATE SavedApcState; diff --git a/xtoskrnl/includes/ke/kprocess.hh b/xtoskrnl/includes/ke/kprocess.hh index ae7c370..57d0641 100644 --- a/xtoskrnl/includes/ke/kprocess.hh +++ b/xtoskrnl/includes/ke/kprocess.hh @@ -21,10 +21,12 @@ namespace KE STATIC EPROCESS InitialProcess; public: + STATIC XTAPI PKPROCESS GetIdleProcess(VOID); STATIC XTAPI PEPROCESS GetInitialProcess(VOID); + STATIC XTAPI VOID InitializeIdleProcess(IN OUT PKPROCESS Process, + IN PULONG_PTR DirectoryTable); STATIC XTAPI VOID InitializeProcess(IN OUT PKPROCESS Process, IN KPRIORITY Priority, - IN KAFFINITY Affinity, IN PULONG_PTR DirectoryTable, IN BOOLEAN Alignment); }; diff --git a/xtoskrnl/includes/ke/kthread.hh b/xtoskrnl/includes/ke/kthread.hh index 288ce99..37f1f12 100644 --- a/xtoskrnl/includes/ke/kthread.hh +++ b/xtoskrnl/includes/ke/kthread.hh @@ -22,6 +22,10 @@ namespace KE public: STATIC XTAPI PETHREAD GetInitialThread(VOID); + STATIC XTAPI VOID InitializeIdleThread(IN PKPROCESS IdleProcess, + IN OUT PKTHREAD IdleThread, + IN PKPROCESSOR_CONTROL_BLOCK Prcb, + IN PVOID Stack); STATIC XTAPI XTSTATUS InitializeThread(IN PKPROCESS Process, IN OUT PKTHREAD Thread, IN PKSYSTEM_ROUTINE SystemRoutine, diff --git a/xtoskrnl/ke/amd64/krnlinit.cc b/xtoskrnl/ke/amd64/krnlinit.cc index cc06462..45f6637 100644 --- a/xtoskrnl/ke/amd64/krnlinit.cc +++ b/xtoskrnl/ke/amd64/krnlinit.cc @@ -26,6 +26,8 @@ VOID KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock) { PKPROCESSOR_CONTROL_BLOCK ControlBlock; + PKPROCESS IdleProcess; + PKTHREAD IdleThread; /* Initialize application CPU */ AR::ProcessorSupport::InitializeProcessor(StartBlock->ProcessorStructures); @@ -57,6 +59,15 @@ KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlo /* Initialize local clock for this CPU */ HL::Timer::InitializeLocalClock(); + /* Allocate and wipe memory for Idle thread */ + MM::Allocator::AllocatePool(NonPagedPool, sizeof(KTHREAD), (PVOID *)&IdleThread); + RTL::Memory::ZeroMemory(IdleThread, sizeof(KTHREAD)); + + /* Initialize Idle thread */ + IdleProcess = KE::KProcess::GetIdleProcess(); + ControlBlock->CurrentThread = IdleThread; + KE::KThread::InitializeIdleThread(IdleProcess, IdleThread, ControlBlock, StartBlock->Stack); + /* Register DISPATCH interrupt handler */ HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_DPC, KE::Dispatcher::HandleDispatchInterrupt); @@ -106,30 +117,18 @@ KE::KernelInit::BootstrapKernel(VOID) /* 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::ProcessorSupport::GetBootStack(), TRUE); - CurrentThread->NextProcessor = Prcb->CpuNumber; - CurrentThread->Priority = THREAD_HIGH_PRIORITY; - CurrentThread->State = Running; - CurrentThread->Affinity.Count = 1; - CurrentThread->Affinity.Size = 1; - CurrentThread->Affinity.Bitmap[0] = (KAFFINITY)1 << Prcb->CpuNumber; - CurrentThread->WaitRunLevel = DISPATCH_LEVEL; - CurrentProcess->ActiveProcessors.Bitmap[0] |= (KAFFINITY)1 << Prcb->CpuNumber; - /* Initialize Memory Manager */ MM::Manager::InitializeMemoryManager(); /* Enable shadow buffer for framebuffer */ HL::FrameBuffer::EnableShadowBuffer(); + /* Initialize Idle process and Idle thread */ + PageDirectory[0] = 0; + PageDirectory[1] = 0; + KE::KProcess::InitializeIdleProcess(CurrentProcess, PageDirectory); + KE::KThread::InitializeIdleThread(CurrentProcess, CurrentThread, Prcb, AR::ProcessorSupport::GetBootStack()); + /* Start all application processors */ KE::Processor::InitializeProcessorBlocks(); HL::Cpu::StartAllProcessors(); diff --git a/xtoskrnl/ke/i686/krnlinit.cc b/xtoskrnl/ke/i686/krnlinit.cc index a87da8a..cacdbe6 100644 --- a/xtoskrnl/ke/i686/krnlinit.cc +++ b/xtoskrnl/ke/i686/krnlinit.cc @@ -26,6 +26,8 @@ VOID KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock) { PKPROCESSOR_CONTROL_BLOCK ControlBlock; + PKPROCESS IdleProcess; + PKTHREAD IdleThread; /* Initialize application CPU */ AR::ProcessorSupport::InitializeProcessor(StartBlock->ProcessorStructures); @@ -57,6 +59,15 @@ KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlo /* Initialize local clock for this CPU */ HL::Timer::InitializeLocalClock(); + /* Allocate and wipe memory for Idle thread */ + MM::Allocator::AllocatePool(NonPagedPool, sizeof(KTHREAD), (PVOID *)&IdleThread); + RTL::Memory::ZeroMemory(IdleThread, sizeof(KTHREAD)); + + /* Initialize Idle thread */ + IdleProcess = KE::KProcess::GetIdleProcess(); + ControlBlock->CurrentThread = IdleThread; + KE::KThread::InitializeIdleThread(IdleProcess, IdleThread, ControlBlock, StartBlock->Stack); + /* Register DISPATCH interrupt handler */ HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_DPC, KE::Dispatcher::HandleDispatchInterrupt); @@ -106,30 +117,18 @@ KE::KernelInit::BootstrapKernel(VOID) /* 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::ProcessorSupport::GetBootStack(), TRUE); - CurrentThread->NextProcessor = Prcb->CpuNumber; - CurrentThread->Priority = THREAD_HIGH_PRIORITY; - CurrentThread->State = Running; - CurrentThread->Affinity.Count = 1; - CurrentThread->Affinity.Size = 1; - CurrentThread->Affinity.Bitmap[0] = (KAFFINITY)1 << Prcb->CpuNumber; - CurrentThread->WaitRunLevel = DISPATCH_LEVEL; - CurrentProcess->ActiveProcessors.Bitmap[0] |= (KAFFINITY)1 << Prcb->CpuNumber; - /* Initialize Memory Manager */ MM::Manager::InitializeMemoryManager(); /* Enable shadow buffer for framebuffer */ HL::FrameBuffer::EnableShadowBuffer(); + /* Initialize Idle process and Idle thread */ + PageDirectory[0] = 0; + PageDirectory[1] = 0; + KE::KProcess::InitializeIdleProcess(CurrentProcess, PageDirectory); + KE::KThread::InitializeIdleThread(CurrentProcess, CurrentThread, Prcb, AR::ProcessorSupport::GetBootStack()); + /* Start all application processors */ KE::Processor::InitializeProcessorBlocks(); HL::Cpu::StartAllProcessors(); diff --git a/xtoskrnl/ke/kprocess.cc b/xtoskrnl/ke/kprocess.cc index 2626a7f..c414b16 100644 --- a/xtoskrnl/ke/kprocess.cc +++ b/xtoskrnl/ke/kprocess.cc @@ -9,6 +9,21 @@ #include +/** + * Retrieves the pointer to the global Idle process. + * + * @return Returns a pointer to the Idle process. + * + * @since XT 1.0 + */ +XTAPI +PKPROCESS +KE::KProcess::GetIdleProcess(VOID) +{ + /* Return pointer to the idle process */ + return &InitialProcess.ProcessControlBlock; +} + /** * Retrieves a pointer to the system's initial executive process object. * @@ -23,6 +38,55 @@ KE::KProcess::GetInitialProcess(VOID) return &InitialProcess; } +/** + * Initializes the system-wide Idle Process. + * + * @param Process + * Supplies a pointer to the KPROCESS structure representing the idle process. + * + * @param DirectoryTable + * Supplies a pointer to the initial hardware page directory table for the process. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KE::KProcess::InitializeIdleProcess(IN OUT PKPROCESS Process, + IN PULONG_PTR DirectoryTable) +{ + ULONG AffinitySize, MapSize; + PACPI_SYSTEM_INFO SysInfo; + + /* Retrieve hardware topology from ACPI */ + HL::Acpi::GetSystemInformation(&SysInfo); + + /* Calculate the required size for KAFFINITY_MAP structures */ + AffinitySize = (SysInfo->CpuCount + 63) / 64; + MapSize = sizeof(KAFFINITY_MAP) + (AffinitySize * sizeof(KAFFINITY)); + + /* Align size to the 8-byte boundary */ + MapSize = (MapSize + 7) & ~7; + + /* Allocate the process-level affinity structures */ + MM::Allocator::AllocatePool(NonPagedPool, MapSize, (PVOID*)&Process->Affinity); + MM::Allocator::AllocatePool(NonPagedPool, MapSize, (PVOID*)&Process->ActiveProcessors); + + /* Zero the process-level affinity structures */ + RTL::Memory::ZeroMemory(Process->Affinity, MapSize); + RTL::Memory::ZeroMemory(Process->ActiveProcessors, MapSize); + + /* Initialize size metadata */ + Process->Affinity->Count = (USHORT)AffinitySize; + Process->Affinity->Size = (USHORT)AffinitySize; + Process->ActiveProcessors->Size = (USHORT)AffinitySize; + + /* Initialize Idle process */ + KE::KProcess::InitializeProcess(Process, 0, DirectoryTable, FALSE); + Process->Quantum = MAXCHAR; +} + /** * Initializes the process. * @@ -49,7 +113,6 @@ XTAPI VOID KE::KProcess::InitializeProcess(IN OUT PKPROCESS Process, IN KPRIORITY Priority, - IN KAFFINITY Affinity, IN PULONG_PTR DirectoryTable, IN BOOLEAN Alignment) { @@ -68,11 +131,6 @@ KE::KProcess::InitializeProcess(IN OUT PKPROCESS Process, Process->BasePriority = Priority; Process->AutoAlignment = Alignment; - /* Initialize KAFFINITY_MAP for single-group affinity */ - Process->Affinity.Count = 1; - Process->Affinity.Size = 1; - Process->Affinity.Bitmap[0] = Affinity; - /* Set directory tables */ Process->DirectoryTable[0] = DirectoryTable[0]; Process->DirectoryTable[1] = DirectoryTable[1]; diff --git a/xtoskrnl/ke/kthread.cc b/xtoskrnl/ke/kthread.cc index 39c2533..936321f 100644 --- a/xtoskrnl/ke/kthread.cc +++ b/xtoskrnl/ke/kthread.cc @@ -23,6 +23,81 @@ KE::KThread::GetInitialThread(VOID) return &InitialThread; } +/** + * Initializes an Idle Thread. + * + * @param IdleProcess + * Supplies a pointer to the global Idle Process container. + * + * @param IdleThread + * Supplies a pointer to the KTHREAD structure being initialized. + * + * @param Prcb + * Supplies a pointer to the Processor Control Block of the target CPU. + * + * @param Stack + * Supplies a pointer to the pre-allocated kernel stack for this thread. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KE::KThread::InitializeIdleThread(IN PKPROCESS IdleProcess, + IN OUT PKTHREAD IdleThread, + IN PKPROCESSOR_CONTROL_BLOCK Prcb, + IN PVOID Stack) +{ + ULONG AffinitySize, CpuIndex, CpuTargetBit, MapSize; + PACPI_SYSTEM_INFO SysInfo; + + /* Retrieve hardware topology from ACPI */ + HL::Acpi::GetSystemInformation(&SysInfo); + + /* Calculate the required size for KAFFINITY_MAP structures */ + AffinitySize = (SysInfo->CpuCount + 63) / 64; + MapSize = sizeof(KAFFINITY_MAP) + (AffinitySize * sizeof(KAFFINITY)); + + /* Align size to the 8-byte boundary */ + MapSize = (MapSize + 7) & ~7; + + /* Allocate the thread-level affinity structures */ + MM::Allocator::AllocatePool(NonPagedPool, MapSize, (PVOID*)&IdleThread->Affinity); + MM::Allocator::AllocatePool(NonPagedPool, MapSize, (PVOID*)&IdleThread->UserAffinity); + + /* Zero the thread-level affinity structures */ + RTL::Memory::ZeroMemory(IdleThread->Affinity, MapSize); + RTL::Memory::ZeroMemory(IdleThread->UserAffinity, MapSize); + + /* Initialize Idle thread */ + KE::KThread::InitializeThread(IdleProcess, IdleThread, NULLPTR, NULLPTR, NULLPTR, + NULLPTR, NULLPTR, Stack, TRUE); + + /* Configure Idle thread scheduling parameters */ + IdleThread->NextProcessor = Prcb->CpuNumber; + IdleThread->Priority = THREAD_HIGH_PRIORITY; + IdleThread->State = Running; + IdleThread->WaitRunLevel = DISPATCH_LEVEL; + + /* Calculate exact block array index and bit offset for this specific CPU */ + CpuIndex = Prcb->CpuNumber / 64; + CpuTargetBit = Prcb->CpuNumber % 64; + + /* Configure Idle thread affinity */ + IdleThread->Affinity->Bitmap[CpuIndex] = ((KAFFINITY)1 << CpuTargetBit); + IdleThread->Affinity->Count = (USHORT)(CpuIndex + 1); + IdleThread->Affinity->Size = (USHORT)AffinitySize; + + /* Configure Idle thread user affinity */ + IdleThread->UserAffinity->Bitmap[CpuIndex] = ((KAFFINITY)1 << CpuTargetBit); + IdleThread->UserAffinity->Count = (USHORT)(CpuIndex + 1); + IdleThread->UserAffinity->Size = (USHORT)AffinitySize; + + /* Register this CPU as active in the Idle Process */ + IdleProcess->ActiveProcessors->Bitmap[CpuIndex] |= ((KAFFINITY)1 << CpuTargetBit); +} + /** * Initializes the thread. *