summaryrefslogtreecommitdiffhomepage
path: root/dev
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2025-01-11 10:47:49 +0100
committerAmlal El Mahrouss <amlal.elmahrouss@icloud.com>2025-01-11 10:47:49 +0100
commitc50d283019bfbc43d460e7a66ac58f187897d474 (patch)
treeacf20a746e92b3ea8c77bbc4ec41addc7fce2955 /dev
parent5fedb726774eb46d2aed9378b13bc296baf89333 (diff)
ADD: Tweaks on AMD64's SMP architecture, and almost done with it.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'dev')
-rw-r--r--dev/Kernel/ArchKit/ArchKit.h7
-rw-r--r--dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc64
-rw-r--r--dev/Kernel/HALKit/AMD64/HalApplicationProcessorGNU.s8
-rw-r--r--dev/Kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm77
-rw-r--r--dev/Kernel/HALKit/AMD64/HalCommonAPI.asm59
-rw-r--r--dev/Kernel/HALKit/AMD64/Processor.h10
-rwxr-xr-xdev/Kernel/HALKit/AMD64/make_ap_blob.sh3
7 files changed, 134 insertions, 94 deletions
diff --git a/dev/Kernel/ArchKit/ArchKit.h b/dev/Kernel/ArchKit/ArchKit.h
index af8aef1a..1a3e9c97 100644
--- a/dev/Kernel/ArchKit/ArchKit.h
+++ b/dev/Kernel/ArchKit/ArchKit.h
@@ -46,16 +46,17 @@ namespace Kernel
template <typename WordLength>
inline Void ke_dma_write(WordLength base, WordLength reg, WordLength value) noexcept
{
- *(volatile WordLength*)((UInt64)base + reg) = value;
+ *(volatile WordLength*)(base + reg) = value;
}
/// @brief read from mapped memory register.
/// @param base base address
/// @param reg the register.
/// @return the value inside the register.
- inline UInt32 ke_dma_read(UInt32 base, UInt32 reg) noexcept
+ template <typename WordLength>
+ inline UInt32 ke_dma_read(WordLength base, WordLength reg) noexcept
{
- return *(volatile UInt32*)((UInt64)base + reg);
+ return *(volatile WordLength*)((UInt64)base + reg);
}
namespace HAL
diff --git a/dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc
index 19f3a486..20d512f4 100644
--- a/dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc
+++ b/dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc
@@ -4,6 +4,7 @@
------------------------------------------- */
+#include "NewKit/Defines.h"
#include <Mod/ACPI/ACPIFactoryInterface.h>
#include <KernelKit/UserProcessScheduler.h>
#include <HALKit/AMD64/Processor.h>
@@ -36,7 +37,7 @@
namespace Kernel::HAL
{
- struct MADT_TABLE;
+ struct PROCESS_APIC_MADT;
struct PROCESS_CONTROL_BLOCK;
struct PROCESS_CONTROL_BLOCK final
@@ -46,9 +47,9 @@ namespace Kernel::HAL
EXTERN_C Void _hal_spin_core(Void);
- STATIC struct MADT_TABLE* kMADTBlock = nullptr;
- STATIC Bool kSMPAware = false;
- STATIC Int64 kSMPCount = 0;
+ STATIC struct PROCESS_APIC_MADT* kMADTBlock = nullptr;
+ STATIC Bool kSMPAware = false;
+ STATIC Int64 kSMPCount = 0;
STATIC UIntPtr kApicBaseAddress = 0UL;
@@ -57,7 +58,7 @@ namespace Kernel::HAL
STATIC VoidPtr kRawMADT = nullptr;
/// @brief Multiple APIC Descriptor Table.
- struct MADT_TABLE final : public SDT
+ struct PROCESS_APIC_MADT final : public SDT
{
UInt32 Address; // Madt address
UInt8 Flags; // Madt flags
@@ -118,10 +119,15 @@ namespace Kernel::HAL
/// @return
/***********************************************************************************/
- Void hal_send_start_ipi(UInt32 apic_id, UInt32 vector, UInt32 target)
+ 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, kAPIC_SIPI_Vector | vector);
+ 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)
+ {
+ ;
+ }
}
/***********************************************************************************/
@@ -131,10 +137,15 @@ namespace Kernel::HAL
/// @param target
/// @return
/***********************************************************************************/
- Void hal_send_sipi(UInt32 apic_id, UInt8 vector, UInt32 target)
+ 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, kAPIC_EIPI_Vector | 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)
+ {
+ ;
+ }
}
STATIC PROCESS_CONTROL_BLOCK kProcessBlocks[kSchedProcessLimitPerTeam] = {0};
@@ -155,12 +166,7 @@ namespace Kernel::HAL
auto first_id = kAPICLocales[0];
- hal_send_sipi(first_id, (stack_frame->BP >> 12), kApicBaseAddress);
-
- HardwareTimer timer(Kernel::Milliseconds(10));
- timer.Wait();
-
- hal_send_sipi(first_id, (stack_frame->BP >> 12), kApicBaseAddress);
+ hal_send_sipi(kApicBaseAddress, first_id, (UInt8)(((UIntPtr)stack_frame->BP) >> 12));
return YES;
}
@@ -177,7 +183,12 @@ namespace Kernel::HAL
/***********************************************************************************/
/// @brief Assembly symbol to bootstrap AP.
/***********************************************************************************/
- EXTERN_C Void hal_ap_start(Void);
+ 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.
@@ -197,7 +208,7 @@ namespace Kernel::HAL
auto hw_and_pow_int = PowerFactoryInterface(vendor_ptr);
kRawMADT = hw_and_pow_int.Find(kApicSignature).Leak().Leak();
- kMADTBlock = reinterpret_cast<MADT_TABLE*>(kRawMADT);
+ kMADTBlock = reinterpret_cast<PROCESS_APIC_MADT*>(kRawMADT);
kSMPAware = NO;
if (kMADTBlock)
@@ -207,10 +218,17 @@ namespace Kernel::HAL
kSMPInterrupt = 0;
kSMPCount = 0;
- kcout << "SMP: Probing Local APICs...\r";
+ kcout << "SMP: Starting APs...\r";
kApicBaseAddress = kMADTBlock->Address;
+ constexpr auto kMemoryAPStart = 0x7C000;
+ Char* ptr_ap_code = reinterpret_cast<Char*>(kMemoryAPStart);
+
+ SizeT hal_ap_blob_len = hal_ap_blob_end - hal_ap_blob_start;
+
+ rt_copy_memory((Char*)hal_ap_blob_start, ptr_ap_code, hal_ap_blob_len);
+
while (Yes)
{
if (kMADTBlock->List[index].Type > 9 ||
@@ -228,12 +246,14 @@ namespace Kernel::HAL
// I'll just make the AP start from scratch here.
- hal_send_sipi(kAPICLocales[kSMPCount], ((UIntPtr)hal_ap_start >> 12), kApicBaseAddress);
+ hal_send_start_ipi(kApicBaseAddress, kAPICLocales[kSMPCount]);
HardwareTimer timer(Kernel::Milliseconds(10));
timer.Wait();
- hal_send_sipi(kAPICLocales[kSMPCount], ((UIntPtr)hal_ap_start >> 12), kApicBaseAddress);
+ /// TODO: HAL helper to create an address.
+
+ hal_send_sipi(kApicBaseAddress, kAPICLocales[kSMPCount], (UInt8)(((UIntPtr)ptr_ap_code) >> 12));
++kSMPCount;
break;
diff --git a/dev/Kernel/HALKit/AMD64/HalApplicationProcessorGNU.s b/dev/Kernel/HALKit/AMD64/HalApplicationProcessorGNU.s
new file mode 100644
index 00000000..a8ad3b76
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalApplicationProcessorGNU.s
@@ -0,0 +1,8 @@
+.data
+
+.global hal_ap_blob_start /* Export the start symbol */
+.global hal_ap_blob_end /* Export the end symbol */
+
+hal_ap_blob_start:
+ .incbin "HALKit/AMD64/HalApplicationProcessorStartup.bin"
+hal_ap_blob_end:
diff --git a/dev/Kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm b/dev/Kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm
new file mode 100644
index 00000000..2d2f6fbb
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm
@@ -0,0 +1,77 @@
+;; /*
+;; * ========================================================
+;; *
+;; * ZKA
+;; * Copyright (C) 2024, Theater Quality Corp, all rights reserved., all rights reserved.
+;; *
+;; * ========================================================
+;; */
+
+[bits 16]
+[org 0x7c000]
+
+hal_ap_start:
+ mov ax, 0x0
+ mov ss, ax
+ mov esp, 0x7000
+
+ cli
+ mov eax, cr0
+ or eax, 1
+ mov cr0, eax
+ jmp .hal_ap_start_flush
+.hal_ap_start_flush:
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ mov eax, cr4
+ or eax, 1 << 5
+ mov cr4, eax
+
+ mov eax, cr3
+ mov cr3, eax
+
+ mov ecx, 0xC0000080
+ rdmsr
+ or eax, 1
+ wrmsr
+
+ mov eax, cr0
+ or eax, (1 << 31)
+ mov cr0, eax
+
+ jmp 0x08:hal_ap_64bit_entry
+hal_ap_end:
+
+hal_ap_length:
+ dq hal_ap_end - hal_ap_start
+
+[bits 64]
+
+hal_ap_64bit_entry:
+ mov ax, 0x23
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+ mov rsp, [hal_ap_64bit_entry_stack_end]
+
+ push 0x33
+ push qword [hal_ap_64bit_entry_loop]
+ o64 pushf
+ push rsp
+ push 0x33
+
+ o64 iret
+
+hal_ap_64bit_entry_loop:
+ jmp $
+
+hal_ap_64bit_entry_stack:
+ resb 8196*2
+hal_ap_64bit_entry_stack_end: \ No newline at end of file
diff --git a/dev/Kernel/HALKit/AMD64/HalCommonAPI.asm b/dev/Kernel/HALKit/AMD64/HalCommonAPI.asm
index 4a516d33..715f4bcf 100644
--- a/dev/Kernel/HALKit/AMD64/HalCommonAPI.asm
+++ b/dev/Kernel/HALKit/AMD64/HalCommonAPI.asm
@@ -80,62 +80,3 @@ mp_system_call_handler:
o64 sysret
[bits 16]
-
-section .text
-global hal_ap_start
-
-hal_ap_start:
- mov ax, 0x0
- mov ss, ax
- mov esp, 0x7000
-
- cli
- mov eax, cr0
- or eax, 1
- mov cr0, eax
- jmp .flush
-.flush:
- mov ax, 0x10
- mov ds, ax
- mov es, ax
- mov fs, ax
- mov gs, ax
- mov ss, ax
-
- mov eax, cr4
- or eax, 1 << 5
- mov cr4, eax
-
- mov eax, cr3
- mov cr3, eax
-
- mov ecx, 0xC0000080
- rdmsr
- or eax, 1
- wrmsr
-
- mov eax, cr0
- or eax, (1 << 31)
- mov cr0, eax
-
- jmp 0x08:hal_ap_64bit_entry
-
-[bits 64]
-
-; 64-bit entry point
-section .text
-global hal_ap_64bit_entry
-hal_ap_64bit_entry:
- mov ax, 0x10
- mov ds, ax
- mov es, ax
- mov fs, ax
- mov gs, ax
- mov ss, ax
-
- mov rsp, 0x8001000 ; Stack Address for scheduler AP.
-
- jmp hal_ap_64bit_entry_loop
-
-hal_ap_64bit_entry_loop:
- jmp $ \ No newline at end of file
diff --git a/dev/Kernel/HALKit/AMD64/Processor.h b/dev/Kernel/HALKit/AMD64/Processor.h
index def26fa9..0db498ec 100644
--- a/dev/Kernel/HALKit/AMD64/Processor.h
+++ b/dev/Kernel/HALKit/AMD64/Processor.h
@@ -192,16 +192,6 @@ namespace Kernel::HAL
Void mp_get_cores(VoidPtr vendor_ptr) noexcept;
/***********************************************************************************/
-
- Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress);
-
- /***********************************************************************************/
-
- Void hal_send_end_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress);
-
- /***********************************************************************************/
-
- /***********************************************************************************/
/// @brief Do a cpuid to check if MSR exists on CPU.
/// @retval true it does exists.
/// @retval false it doesn't.
diff --git a/dev/Kernel/HALKit/AMD64/make_ap_blob.sh b/dev/Kernel/HALKit/AMD64/make_ap_blob.sh
new file mode 100755
index 00000000..3f079187
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/make_ap_blob.sh
@@ -0,0 +1,3 @@
+# !/bin/sh
+
+nasm -f bin HalApplicationProcessorStartup.asm -o HalApplicationProcessorStartup.bin \ No newline at end of file