summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
diff options
context:
space:
mode:
authorAmlal <amlal@nekernel.org>2025-04-25 13:08:33 +0200
committerAmlal <amlal@nekernel.org>2025-04-25 13:08:33 +0200
commitfb790b07aeba8e22e4190cf3e1834d11ecde6c96 (patch)
tree4cec7d1b321307b1d5935577631dae116a658a37 /dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
parent63a2d92c5dfe976175cda024ec01905d11b43738 (diff)
dev: better .clang-format, ran format command.
Signed-off-by: Amlal <amlal@nekernel.org>
Diffstat (limited to 'dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc')
-rw-r--r--dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc436
1 files changed, 206 insertions, 230 deletions
diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
index fc50380a..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,231 +33,208 @@
///////////////////////////////////////////////////////////////////////////////////////
-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;
-
- kHWThread[process_index].mFramePtr = stack_frame;
- kHWThread[process_index].mProcessID = pid;
-
- kHWThread[process_index].mCoreID = kAPICLocales[0];
-
- hal_send_sipi(kApicBaseAddress, kHWThread[process_index].mCoreID, (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;
- }
-
- auto hw_and_pow_int = PowerFactoryInterface(vendor_ptr);
- kRawMADT = hw_and_pow_int.Find(kAPIC_Signature).Leak().Leak();
-
- kMADTBlock = reinterpret_cast<HAL_APIC_MADT*>(kRawMADT);
- kSMPAware = NO;
-
- if (kMADTBlock)
- {
- SizeT index = 1;
-
- kSMPInterrupt = 0;
- kSMPCount = 0;
-
- kout << "SMP: Starting APs...\r";
-
- kApicBaseAddress = kMADTBlock->Address;
-
- while (Yes)
- {
- /// @note Anything bigger than x2APIC type doesn't exist.
- if (kMADTBlock->List[index].Type > 9 ||
- kSMPCount > kSchedProcessLimitPerTeam)
- break;
-
- switch (kMADTBlock->List[index].Type)
- {
- case 0x00: {
- if (kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID < 1)
- break;
-
- kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID;
- (Void)(kout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << kendl);
+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;
+
+ kHWThread[process_index].mFramePtr = stack_frame;
+ kHWThread[process_index].mProcessID = pid;
+
+ kHWThread[process_index].mCoreID = kAPICLocales[0];
+
+ hal_send_sipi(kApicBaseAddress, kHWThread[process_index].mCoreID,
+ (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;
+ }
+
+ auto hw_and_pow_int = PowerFactoryInterface(vendor_ptr);
+ kRawMADT = hw_and_pow_int.Find(kAPIC_Signature).Leak().Leak();
+
+ kMADTBlock = reinterpret_cast<HAL_APIC_MADT*>(kRawMADT);
+ kSMPAware = NO;
+
+ if (kMADTBlock) {
+ SizeT index = 1;
+
+ kSMPInterrupt = 0;
+ kSMPCount = 0;
+
+ kout << "SMP: Starting APs...\r";
+
+ kApicBaseAddress = kMADTBlock->Address;
+
+ while (Yes) {
+ /// @note Anything bigger than x2APIC type doesn't exist.
+ if (kMADTBlock->List[index].Type > 9 || kSMPCount > kSchedProcessLimitPerTeam) break;
+
+ switch (kMADTBlock->List[index].Type) {
+ case 0x00: {
+ if (kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID < 1) break;
+
+ 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
///////////////////////////////////////////////////////////////////////////////////////