summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-05-02 19:38:46 +0200
committerGitHub <noreply@github.com>2025-05-02 19:38:46 +0200
commit997be16e5ac9a68d54882ab69529815860d62955 (patch)
tree19d6129c2d776bb1edc5d4a7325e39ca176c3403 /dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
parent618104e74c195d7508a18450524f8ed7f9af8cc6 (diff)
parentb3b4b1ebdcd6adeac914869017c86d892b7a8ced (diff)
Merge pull request #28 from nekernel-org/dev
0.0.2
Diffstat (limited to 'dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc')
-rw-r--r--dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc415
1 files changed, 188 insertions, 227 deletions
diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
index 3b98e9e8..dd9a36ed 100644
--- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
+++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
@@ -1,29 +1,28 @@
/* -------------------------------------------
- Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
-#include <modules/ACPI/ACPIFactoryInterface.h>
-#include <KernelKit/ProcessScheduler.h>
-#include <HALKit/AMD64/Processor.h>
#include <ArchKit/ArchKit.h>
+#include <HALKit/AMD64/Processor.h>
#include <KernelKit/BinaryMutex.h>
+#include <KernelKit/HardwareThreadScheduler.h>
#include <KernelKit/ProcessScheduler.h>
#include <KernelKit/Timer.h>
-#include <modules/CoreGfx/TextGfx.h>
#include <NewKit/KernelPanic.h>
-#include <KernelKit/HardwareThreadScheduler.h>
+#include <modules/ACPI/ACPIFactoryInterface.h>
+#include <modules/CoreGfx/TextGfx.h>
#define kAPIC_Signature "APIC"
-#define kAPIC_ICR_Low 0x300
-#define kAPIC_ICR_High 0x310
+#define kAPIC_ICR_Low 0x300
+#define kAPIC_ICR_High 0x310
#define kAPIC_SIPI_Vector 0x00500
#define kAPIC_EIPI_Vector 0x00400
-#define kAPIC_BASE_MSR 0x1B
-#define kAPIC_BASE_MSR_BSP 0x100
+#define kAPIC_BASE_MSR 0x1B
+#define kAPIC_BASE_MSR_BSP 0x100
#define kAPIC_BASE_MSR_ENABLE 0x800
/// @note: _hal_switch_context is internal
@@ -34,246 +33,208 @@
///////////////////////////////////////////////////////////////////////////////////////
-namespace Kernel::HAL
-{
- struct PROCESS_APIC_MADT;
- struct PROCESS_CONTROL_BLOCK;
-
- struct PROCESS_CONTROL_BLOCK final
- {
- HAL::StackFramePtr mFrame;
- };
-
- STATIC PROCESS_APIC_MADT* kMADTBlock = nullptr;
- STATIC Bool kSMPAware = false;
- STATIC Int64 kSMPCount = 0;
-
- STATIC UIntPtr kApicBaseAddress = 0UL;
-
- STATIC Int32 kSMPInterrupt = 0;
- STATIC UInt64 kAPICLocales[kSchedProcessLimitPerTeam] = {0};
- STATIC VoidPtr kRawMADT = nullptr;
-
- /// @brief Multiple APIC Descriptor Table.
- struct PROCESS_APIC_MADT final SDT_OBJECT
- {
- UInt32 Address; // Madt address
- UInt8 Flags; // Madt flags
-
- struct
- {
- UInt8 Type;
- UInt8 Len;
-
- union {
- struct
- {
- UInt8 IoID;
- UInt8 Zero;
- UInt32 IoAddress;
- UInt32 GISBase;
- } IOAPIC;
-
- struct
- {
- UInt8 Source;
- UInt8 IRQSource;
- UInt32 GSI;
- UInt16 Flags;
- } LApicNMI;
-
- struct
- {
- UInt8 ProcessorID;
- UInt16 Flags;
- UInt8 LINT;
- } LAPIC;
-
- struct
- {
- UInt16 Reserved;
- UInt64 Address;
- } LApicOverride;
-
- struct
- {
- UInt16 Reserved;
- UInt32 x2APICID;
- UInt32 Flags;
- UInt32 AcpiID;
- } LApic;
- };
- } List[1]; // Records List
- };
-
- ///////////////////////////////////////////////////////////////////////////////////////
-
- /***********************************************************************************/
- /// @brief Send IPI command to APIC.
- /// @param apic_id programmable interrupt controller id.
- /// @param vector vector interrupt.
- /// @param target target APIC adress.
- /// @return
- /***********************************************************************************/
-
- Void hal_send_start_ipi(UInt32 target, UInt32 apic_id)
- {
- Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_High, apic_id << 24);
- Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_Low, 0x00000500 | 0x00004000 | 0x00000000);
-
- while (Kernel::ke_dma_read<UInt32>(target, kAPIC_ICR_Low) & 0x1000)
- {
- ;
- }
- }
-
- /***********************************************************************************/
- /// @brief Send end IPI for CPU.
- /// @param apic_id
- /// @param vector
- /// @param target
- /// @return
- /***********************************************************************************/
- Void hal_send_sipi(UInt32 target, UInt32 apic_id, UInt8 vector)
- {
- Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_High, apic_id << 24);
- Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_Low, 0x00000600 | 0x00004000 | 0x00000000 | vector);
-
- while (Kernel::ke_dma_read<UInt32>(target, kAPIC_ICR_Low) & 0x1000)
- {
- NE_UNUSED(0);
- }
- }
-
- STATIC PROCESS_CONTROL_BLOCK kProcessBlocks[kSchedProcessLimitPerTeam] = {0};
-
- EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 pid)
- {
- const auto process_index = pid % kSchedProcessLimitPerTeam;
- return kProcessBlocks[process_index].mFrame;
- }
-
- EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid)
- {
- MUST_PASS(stack_frame);
-
- const auto process_index = pid % kSchedProcessLimitPerTeam;
-
- kProcessBlocks[process_index].mFrame = stack_frame;
-
- auto first_id = kAPICLocales[0];
-
- hal_send_sipi(kApicBaseAddress, first_id, (UInt8)(((UIntPtr)stack_frame->BP) >> 12));
-
- return YES;
- }
-
- /***********************************************************************************/
- /// @brief Is the current config SMP aware?
- /// @return True if YES, False if not.
- /***********************************************************************************/
- Bool mp_is_smp(Void) noexcept
- {
- return kSMPAware;
- }
-
- /***********************************************************************************/
- /// @brief Assembly symbol to bootstrap AP.
- /***********************************************************************************/
- EXTERN_C Char* hal_ap_blob_start;
-
- /***********************************************************************************/
- /// @brief Assembly symbol to bootstrap AP.
- /***********************************************************************************/
- EXTERN_C Char* hal_ap_blob_end;
-
- /***********************************************************************************/
- /// @brief Fetch and enable SMP scheduler.
- /// @param vendor_ptr SMP containing structure.
- /***********************************************************************************/
- Void mp_init_cores(VoidPtr vendor_ptr) noexcept
- {
- if (!vendor_ptr)
- return;
-
- if (!kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled)
- {
- kSMPAware = NO;
- return;
- }
+namespace Kernel::HAL {
+struct HAL_APIC_MADT;
+struct HAL_HARDWARE_THREAD;
+
+struct HAL_HARDWARE_THREAD final {
+ HAL::StackFramePtr mFramePtr;
+ ProcessID mProcessID{0};
+ UInt8 mCoreID{0};
+};
+
+STATIC HAL_APIC_MADT* kMADTBlock = nullptr;
+STATIC Bool kSMPAware = false;
+STATIC Int64 kSMPCount = 0;
+
+STATIC UIntPtr kApicBaseAddress = 0UL;
+
+STATIC Int32 kSMPInterrupt = 0;
+STATIC UInt64 kAPICLocales[kSchedProcessLimitPerTeam] = {0};
+STATIC VoidPtr kRawMADT = nullptr;
+
+/// @brief Multiple APIC Descriptor Table.
+struct HAL_APIC_MADT final SDT_OBJECT {
+ UInt32 Address; // Madt address
+ UInt8 Flags; // Madt flags
+
+ struct {
+ UInt8 Type;
+ UInt8 Len;
+
+ union APIC {
+ struct IOAPIC {
+ UInt8 IoID;
+ UInt8 Zero;
+ UInt32 IoAddress;
+ UInt32 GISBase;
+ } IOAPIC;
+
+ struct LAPIC_NMI {
+ UInt8 Source;
+ UInt8 IRQSource;
+ UInt32 GSI;
+ UInt16 Flags;
+ } LApicNMI;
+
+ struct LAPIC {
+ UInt8 ProcessorID;
+ UInt16 Flags;
+ UInt8 LINT;
+ } LAPIC;
+
+ struct LAPIC_OVERRIDE {
+ UInt16 Reserved;
+ UInt64 Address;
+ } LApicOverride;
+
+ struct LAPIC_X2 {
+ UInt16 Reserved;
+ UInt32 x2APICID;
+ UInt32 Flags;
+ UInt32 AcpiID;
+ } LocalApicX2;
+ } Apic;
+ } List[1]; // Records List
+};
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+/***********************************************************************************/
+/// @brief Send IPI command to APIC.
+/// @param apic_id programmable interrupt controller id.
+/// @param vector vector interrupt.
+/// @param target target APIC adress.
+/// @return
+/***********************************************************************************/
+
+Void hal_send_start_ipi(UInt32 target, UInt32 apic_id) {
+ Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_High, apic_id << 24);
+ Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_Low, 0x00000500 | 0x00004000 | 0x00000000);
+
+ while (Kernel::ke_dma_read<UInt32>(target, kAPIC_ICR_Low) & 0x1000) {
+ ;
+ }
+}
+
+/***********************************************************************************/
+/// @brief Send end IPI for CPU.
+/// @param apic_id
+/// @param vector
+/// @param target
+/// @return
+/***********************************************************************************/
+Void hal_send_sipi(UInt32 target, UInt32 apic_id, UInt8 vector) {
+ Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_High, apic_id << 24);
+ Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_Low,
+ 0x00000600 | 0x00004000 | 0x00000000 | vector);
+
+ while (Kernel::ke_dma_read<UInt32>(target, kAPIC_ICR_Low) & 0x1000) {
+ NE_UNUSED(0);
+ }
+}
+
+STATIC HAL_HARDWARE_THREAD kHWThread[kSchedProcessLimitPerTeam] = {{}};
+
+EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 pid) {
+ const auto process_index = pid % kSchedProcessLimitPerTeam;
+
+ return kHWThread[process_index].mFramePtr;
+}
+
+EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) {
+ MUST_PASS(stack_frame);
+
+ const auto process_index = pid % kSchedProcessLimitPerTeam;
- auto hw_and_pow_int = PowerFactoryInterface(vendor_ptr);
- kRawMADT = hw_and_pow_int.Find(kAPIC_Signature).Leak().Leak();
+ kHWThread[process_index].mFramePtr = stack_frame;
+ kHWThread[process_index].mProcessID = pid;
- kMADTBlock = reinterpret_cast<PROCESS_APIC_MADT*>(kRawMADT);
- kSMPAware = NO;
+ kHWThread[process_index].mCoreID = kAPICLocales[0];
- if (kMADTBlock)
- {
- SizeT index = 1;
+ hal_send_sipi(kApicBaseAddress, kHWThread[process_index].mCoreID,
+ (UInt8) (((UIntPtr) stack_frame->BP) >> 12));
- kSMPInterrupt = 0;
- kSMPCount = 0;
+ return YES;
+}
- kout << "SMP: Starting APs...\r";
+/***********************************************************************************/
+/// @brief Is the current config SMP aware?
+/// @return True if YES, False if not.
+/***********************************************************************************/
+Bool mp_is_smp(Void) noexcept {
+ return kSMPAware;
+}
- kApicBaseAddress = kMADTBlock->Address;
+/***********************************************************************************/
+/// @brief Assembly symbol to bootstrap AP.
+/***********************************************************************************/
+EXTERN_C Char* hal_ap_blob_start;
- constexpr auto kMemoryAPStart = 0x7C000;
- Char* ptr_ap_code = reinterpret_cast<Char*>(kMemoryAPStart);
+/***********************************************************************************/
+/// @brief Assembly symbol to bootstrap AP.
+/***********************************************************************************/
+EXTERN_C Char* hal_ap_blob_end;
- mm_map_page(ptr_ap_code, ptr_ap_code, kMMFlagsWr | kMMFlagsPCD);
+/***********************************************************************************/
+/// @brief Fetch and enable SMP scheduler.
+/// @param vendor_ptr SMP containing structure.
+/***********************************************************************************/
+Void mp_init_cores(VoidPtr vendor_ptr) noexcept {
+ if (!vendor_ptr) return;
- SizeT hal_ap_blob_len = hal_ap_blob_end - hal_ap_blob_start;
+ if (!kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled) {
+ kSMPAware = NO;
+ return;
+ }
- rt_copy_memory((Char*)hal_ap_blob_start, ptr_ap_code, hal_ap_blob_len);
+ auto hw_and_pow_int = PowerFactoryInterface(vendor_ptr);
+ kRawMADT = hw_and_pow_int.Find(kAPIC_Signature).Leak().Leak();
- while (Yes)
- {
- if (kMADTBlock->List[index].Type > 9 ||
- kSMPCount > kSchedProcessLimitPerTeam)
- break;
+ kMADTBlock = reinterpret_cast<HAL_APIC_MADT*>(kRawMADT);
+ kSMPAware = NO;
- switch (kMADTBlock->List[index].Type)
- {
- case 0x00: {
- if (kMADTBlock->List[kSMPCount].LAPIC.ProcessorID < 1)
- break;
+ if (kMADTBlock) {
+ SizeT index = 1;
- kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].LAPIC.ProcessorID;
- (void)(kout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << kendl);
+ kSMPInterrupt = 0;
+ kSMPCount = 0;
- // I'll just make the AP start from scratch here.
+ kout << "SMP: Starting APs...\r";
- hal_send_start_ipi(kApicBaseAddress, kAPICLocales[kSMPCount]);
+ kApicBaseAddress = kMADTBlock->Address;
- HardwareTimer timer(Kernel::rtl_ms(10));
- timer.Wait();
+ while (Yes) {
+ /// @note Anything bigger than x2APIC type doesn't exist.
+ if (kMADTBlock->List[index].Type > 9 || kSMPCount > kSchedProcessLimitPerTeam) break;
- /// TODO: HAL helper to create an address.
+ switch (kMADTBlock->List[index].Type) {
+ case 0x00: {
+ if (kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID < 1) break;
- hal_send_sipi(kApicBaseAddress, kAPICLocales[kSMPCount], (UInt8)(((UIntPtr)ptr_ap_code) >> 12));
+ kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID;
+ (Void)(kout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << kendl);
- ++kSMPCount;
- break;
- }
- default:
- break;
- }
+ ++kSMPCount;
+ break;
+ }
+ default:
+ break;
+ }
- ++index;
- }
+ ++index;
+ }
- (void)(kout << "SMP: number of APs: " << number(kSMPCount) << kendl);
+ (Void)(kout << "SMP: Number of APs: " << number(kSMPCount) << kendl);
- // Kernel is now SMP aware.
- // That means that the scheduler is now available (on MP Kernels)
+ // Kernel is now SMP aware.
+ // That means that the scheduler is now available (on MP Kernels)
- kSMPAware = true;
+ kSMPAware = true;
- /// TODO: Notify Boot AP that it must start.
- }
- }
-} // namespace Kernel::HAL
+ /// TODO: Notify Boot AP that it must start.
+ }
+}
+} // namespace Kernel::HAL
///////////////////////////////////////////////////////////////////////////////////////