summaryrefslogtreecommitdiffhomepage
path: root/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-07-10 01:13:08 +0200
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-07-10 01:13:08 +0200
commit5f6549b7d46118ba416faa170ff088d98c9144f0 (patch)
tree23d19bc039a547f27275065d96c52551d8ca989f /Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp
parentdfaf137915094e7ba72f7d7f1f57dc5158d1b6ab (diff)
MHR-36: See below.
- Implement MSR functions has_msr, get_msr, set_msr. - Moved SMP interrupt to interrupt 34 in AMD64. - Fix syntax error in STB.hxx. Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp')
-rw-r--r--Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp93
1 files changed, 47 insertions, 46 deletions
diff --git a/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp b/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp
index 275a511b..8f619b4f 100644
--- a/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp
+++ b/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp
@@ -17,6 +17,10 @@
#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_ENABLE 0x800
+
/// @brief assembly routine. internal use only.
EXTERN_C void _hal_enable_smp(void);
@@ -57,8 +61,8 @@ namespace Kernel::HAL
} Selector;
};
- STATIC voidPtr kApicMadt = nullptr;
- STATIC const char* kApicSignature = "APIC";
+ STATIC VoidPtr kApicMadt = nullptr;
+ STATIC const Char* kApicSignature = "APIC";
/// @brief Multiple APIC Descriptor Table.
struct MadtType final : public SDT
@@ -122,11 +126,7 @@ namespace Kernel::HAL
UInt32 fKind{0};
} kApicMadtAddresses[255] = {};
- STATIC SizeT kApicMadtAddressesCount = 0UL;
- STATIC UIntPtr cBaseAddressAPIC = 0xFEE00000;
-
- /// @brief this will help us schedule our cores.
- STATIC Boolean* cProgramInitialized = nullptr;
+ STATIC SizeT kApicMadtAddressesCount = 0UL;
enum
{
@@ -142,7 +142,7 @@ namespace Kernel::HAL
/// @return
Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress)
{
- Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, apicId << 24);
+ Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, (apicId << 24));
Kernel::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_SIPI_Vector | vector);
}
@@ -160,14 +160,15 @@ namespace Kernel::HAL
}
STATIC HAL::StackFramePtr cFramePtr = nullptr;
- STATIC Int32 cSMPInterrupt = 0x40;
+ STATIC Int32 cSMPInterrupt = 34;
EXTERN_C Void hal_apic_acknowledge_cont(Void)
{
- kcout << "newoskrnl: stopping core...\r";
- ke_stop(RUNTIME_CHECK_BOOTSTRAP);
+ kcout << "newoskrnl: Acknowledged.\r";
}
+ /// @brief Current context getter.
+ /// @retval StackFramePtr the current context.
EXTERN_C StackFramePtr _hal_leak_current_context(Void)
{
return cFramePtr;
@@ -192,12 +193,30 @@ namespace Kernel::HAL
cFramePtr = stackFrame;
- /// yes the exception field contains the core id.
- hal_send_start_ipi(stackFrame->A0, cSMPInterrupt, cBaseAddressAPIC);
-
sem.Unlock();
}
+ STATIC auto cAPICAddress = 0x0FEC00000;
+
+ STATIC void cpu_set_apic_base(UIntPtr apic)
+ {
+ UInt32 edx = 0;
+ UInt32 eax = (apic & 0xfffff0000) | kAPIC_BASE_MSR_ENABLE;
+
+ edx = (apic >> 32) & 0x0f;
+
+ hal_set_msr(kAPIC_BASE_MSR, eax, edx);
+ }
+
+ STATIC UIntPtr cpu_get_apic_base()
+ {
+ UInt32 eax, edx;
+
+ hal_get_msr(kAPIC_BASE_MSR, &eax, &edx);
+
+ return (eax & 0xfffff000) | ((UIntPtr)(edx & 0x0f) << 32);
+ }
+
/// @brief Fetch and enable cores inside main CPU.
/// @param rsdPtr RSD PTR structure.
Void hal_system_get_cores(voidPtr rsdPtr)
@@ -209,47 +228,29 @@ namespace Kernel::HAL
{
MadtType* madt = reinterpret_cast<MadtType*>(kApicMadt);
- constexpr auto cMaxProbableCores = 4; // the amount of cores we want.
- constexpr auto cStartAt = 0; // start here to avoid boot core.
+ const auto cMaxProbableCores = madt->Length / sizeof(MadtType::MadtAddress); // the amount of cores we want.
+ constexpr auto cStartAt = 0; // start here to avoid boot core.
- for (SizeT coreAt = cStartAt; coreAt < cMaxProbableCores; ++coreAt)
- {
- if (madt->MadtRecords[coreAt].Flags < kThreadBoot) // if local apic.
- {
- MadtType::MadtAddress& madtRecord = madt->MadtRecords[coreAt];
+ cpu_set_apic_base(cpu_get_apic_base());
- // then register as a core for scheduler.
- kcout << "newoskrnl: Register APIC.\r";
-
- kApicMadtAddresses[kApicMadtAddressesCount].fAddress = madtRecord.Address;
- kApicMadtAddresses[kApicMadtAddressesCount].fKind = madt->MadtRecords[coreAt].Flags;
-
- ++kApicMadtAddressesCount;
- }
- }
+ // set SVR register to bit 8 to start recieve interrupts.
- ///////////////////////////////////////////////////////////////////////////
- /// Start local APIC now.
- ///////////////////////////////////////////////////////////////////////////
-
- auto flagsSet = Kernel::ke_dma_read(cBaseAddressAPIC, 0xF0); // SVR register.
-
- // enable APIC.
+ auto flagsSet = Kernel::ke_dma_read(cAPICAddress, 0xF0); // SVR register.
flagsSet |= 0x100;
- Kernel::ke_dma_write(cBaseAddressAPIC, 0xF0, flagsSet);
-
- /// Set sprurious interrupt vector.
- Kernel::ke_dma_write(cBaseAddressAPIC, 0xF0, 0x100 | 0xFF);
+ Kernel::ke_dma_write(cAPICAddress, 0xF0, flagsSet | 0x100);
- // highest task priority. for our realtime kernel.
- Kernel::ke_dma_write(cBaseAddressAPIC, 0x21, 0);
+ for (SizeT coreAt = cStartAt; coreAt < cMaxProbableCores; ++coreAt)
+ {
+ MadtType::MadtAddress& madtRecord = madt->MadtRecords[coreAt];
- cProgramInitialized = new Boolean(true);
+ kApicMadtAddresses[kApicMadtAddressesCount].fAddress = madtRecord.Address;
+ kApicMadtAddresses[kApicMadtAddressesCount].fKind = madt->MadtRecords[coreAt].RecordType;
- constexpr auto cWhatCore = 1;
+ kcout << "newoskrnl: register ipi...\r";
- hal_send_start_ipi(cWhatCore, cSMPInterrupt, cBaseAddressAPIC);
+ ++kApicMadtAddressesCount;
+ }
}
else
{