summaryrefslogtreecommitdiffhomepage
path: root/Kernel/HALKit
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-06-12 14:42:29 +0200
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2024-06-12 14:42:29 +0200
commit6a3b080067ff47f84c400987982cfa44927fe7e0 (patch)
tree82351e411eccd00c0e4217f82e711a5cba75fd5a /Kernel/HALKit
parent07c35bb2e8462b45feddcc98f3a512eee29c69b3 (diff)
MHR-23: SMP support inside kernel, need to add I/O for the scheduler
now. Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'Kernel/HALKit')
-rw-r--r--Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp92
-rw-r--r--Kernel/HALKit/AMD64/HalInterruptAPI.asm50
-rw-r--r--Kernel/HALKit/AMD64/HalKernelMain.cxx9
-rw-r--r--Kernel/HALKit/AMD64/HalSMPCoreManager.asm21
4 files changed, 152 insertions, 20 deletions
diff --git a/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp b/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp
index 02f654ab..2824b176 100644
--- a/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp
+++ b/Kernel/HALKit/AMD64/HalCoreMultiProcessingAMD64.cpp
@@ -14,6 +14,8 @@
#define kAPIC_SIPI_Vector 0x00500
#define kAPIC_EIPI_Vector 0x00400
+EXTERN_C void AppMain();
+
///////////////////////////////////////////////////////////////////////////////////////
//! NOTE: fGSI stands 'Field Global System Interrupt'
@@ -104,7 +106,18 @@ namespace NewOS::HAL
///////////////////////////////////////////////////////////////////////////////////////
- STATIC MadtType* kApicInfoBlock = nullptr;
+ STATIC MadtType* kApicInfoBlock = nullptr;
+ STATIC UIntPtr kApicMadtAddresses[255] = {0};
+ STATIC SizeT kApicMadtAddressesCount = 0UL;
+ STATIC UIntPtr cBaseAddressAPIC = 0xFEE00000;
+
+ /// @brief this will help us schedule our cores.
+ STATIC Boolean* cProgramInitialized = nullptr;
+
+ enum
+ {
+ cAPICEOI = 0xb0,
+ };
///////////////////////////////////////////////////////////////////////////////////////
@@ -119,6 +132,8 @@ namespace NewOS::HAL
NewOS::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_SIPI_Vector | vector);
}
+ EXTERN_C Void _hal_spin_core(Void);
+
/// @brief Send end IPI for CPU.
/// @param apicId
/// @param vector
@@ -130,6 +145,42 @@ namespace NewOS::HAL
NewOS::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_EIPI_Vector | vector);
}
+ /// @brief assembly routine. internal use only.
+ EXTERN_C Void _hal_enable_smp(Void);
+
+ EXTERN_C Void hal_apic_acknowledge_cont(Void)
+ {
+ kcout << "newoskrnl: finish kernel init... \r";
+
+ if (cProgramInitialized &&
+ *cProgramInitialized)
+ {
+ *cProgramInitialized = false;
+
+ AppMain();
+
+ while (true)
+ {
+
+ }
+ }
+ else
+ {
+ kcout << "newoskrnl: putting thread to sleep...\r";
+
+ AppMain();
+
+ while (true)
+ {
+ }
+ }
+ }
+
+ EXTERN_C Void hal_apic_acknowledge(Void)
+ {
+ hal_apic_acknowledge_cont();
+ }
+
Void hal_system_get_cores(voidPtr rsdPtr)
{
auto acpi = ACPIFactoryInterface(rsdPtr);
@@ -139,16 +190,37 @@ namespace NewOS::HAL
{
MadtType* madt = (MadtType*)kApicMadt;
- constexpr auto cMaxProbableCores = 4;
+ constexpr auto cMaxProbableCores = 4;
+
+ for (SizeT i = 2; i < cMaxProbableCores; ++i)
+ {
+ if (madt->MadtRecords[i].Flags == 0x01) // if local apic.
+ {
+ MadtType::MadtAddress& madtRecord = madt->MadtRecords[i];
+ // then register as a core for scheduler.
+ kcout << "newoskrnl: register core as scheduler thread.\r";
+
+ kApicMadtAddresses[kApicMadtAddressesCount] = madtRecord.Address;
+ ++kApicMadtAddressesCount;
+
+ auto flagsSet = NewOS::ke_dma_read(madtRecord.Address, 0xF0); // SVR register.
+
+ // enable APIC.
+ flagsSet |= 0x100;
+
+ NewOS::ke_dma_write(cBaseAddressAPIC, 0xF0, flagsSet);
+
+ /// Set sprurious interrupt vector.
+ NewOS::ke_dma_write(cBaseAddressAPIC, 0xF0, 0x100 | 0xFF);
+
+ // highest task priority. for our realtime kernel.
+ NewOS::ke_dma_write(cBaseAddressAPIC, 0x21, 0);
+
+ cProgramInitialized = new Boolean(true);
- for (SizeT i = 0; i < cMaxProbableCores; ++i)
- {
- if (madt->MadtRecords[i].Flags == 0x01) // if local apic.
- {
- // then register as a core for scheduler.
- kcout << "newoskrnl: register core as scheduler thread.\r";
- }
- }
+ hal_send_start_ipi(kApicMadtAddressesCount, 0x40, cBaseAddressAPIC);
+ }
+ }
}
else
{
diff --git a/Kernel/HALKit/AMD64/HalInterruptAPI.asm b/Kernel/HALKit/AMD64/HalInterruptAPI.asm
index 074ba472..ef5a8319 100644
--- a/Kernel/HALKit/AMD64/HalInterruptAPI.asm
+++ b/Kernel/HALKit/AMD64/HalInterruptAPI.asm
@@ -14,7 +14,7 @@
%define kInterruptId 0x21
%macro IntExp 1
-global __NEW_INT_%1
+global __NEW_INT_%1
__NEW_INT_%1:
cld
@@ -22,7 +22,7 @@ __NEW_INT_%1:
%endmacro
%macro IntNormal 1
-global __NEW_INT_%1
+global __NEW_INT_%1
__NEW_INT_%1:
cld
@@ -100,7 +100,7 @@ __NEW_INT_14:
sti
iretq
-
+
IntNormal 15
IntNormal 16
IntExp 17
@@ -120,7 +120,49 @@ IntExp 30
IntNormal 31
-IntNormal 32
+[extern hal_apic_acknowledge]
+
+__NEW_INT_32:
+ push rax
+ push rcx
+ push rdx
+ push rbx
+ push rbp
+ push rsi
+ push rdi
+ push r8
+ push r9
+ push r10
+ push r11
+ push r12
+ push r13
+ push r14
+ push r15
+
+ jmp hal_apic_acknowledge
+
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+ pop rdi
+ pop rsi
+ pop rbp
+ pop rbx
+ pop rdx
+ pop rcx
+ pop rax
+
+ mov eax, 0
+
+ ;; tell there local apic that we're done.
+ mov dword [0xFEE00000 + 0xB0], eax ; LAPIC_EOI
+
+ iretq
IntNormal 33
diff --git a/Kernel/HALKit/AMD64/HalKernelMain.cxx b/Kernel/HALKit/AMD64/HalKernelMain.cxx
index 9d7125d2..708004b3 100644
--- a/Kernel/HALKit/AMD64/HalKernelMain.cxx
+++ b/Kernel/HALKit/AMD64/HalKernelMain.cxx
@@ -16,7 +16,6 @@
#include <NewKit/Json.hpp>
EXTERN_C NewOS::VoidPtr kInterruptVectorTable[];
-EXTERN_C void AppMain();
namespace NewOS::HAL
{
@@ -77,9 +76,9 @@ EXTERN_C void hal_init_platform(
NewOS::HAL::hal_system_get_cores(kHandoverHeader->f_HardwareTables.f_RsdPtr);
- /// END POST
+ NewOS::kcout << "newoskrnl: We're done here...\r";
- AppMain();
-
- NewOS::ke_stop(RUNTIME_CHECK_BOOTSTRAP);
+ while (true)
+ {
+ }
}
diff --git a/Kernel/HALKit/AMD64/HalSMPCoreManager.asm b/Kernel/HALKit/AMD64/HalSMPCoreManager.asm
index abf12228..5ecc2370 100644
--- a/Kernel/HALKit/AMD64/HalSMPCoreManager.asm
+++ b/Kernel/HALKit/AMD64/HalSMPCoreManager.asm
@@ -11,6 +11,8 @@
[global rt_get_current_context]
[global rt_do_context_switch]
+[global _hal_enable_smp]
+[global _hal_spin_core]
section .text
@@ -18,9 +20,26 @@ section .text
;; rcx: Stack Pointer
;; rdx: SMP core address.
rt_do_context_switch:
-
retfq
;; gets the current stack frame.
rt_get_current_context:
retfq
+
+;; @brief enables a smp core to run.
+_hal_enable_smp:
+; Read the APIC base MSR
+ mov ecx, 0x1B ; IA32_APIC_BASE MSR
+ rdmsr
+ ; Enable the APIC by setting bit 11 (APIC Global Enable)
+ or rdx, 0x800
+ ; Set the base address (0xFEE00000)
+ mov eax, 0xFEE
+ shl rax, 12
+ or rax, rdx
+ wrmsr
+ ret
+
+_hal_spin_core:
+ jmp $
+ ret