diff options
Diffstat (limited to 'dev/Kernel')
| -rw-r--r-- | dev/Kernel/ArchKit/ArchKit.h | 7 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc | 64 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalApplicationProcessorGNU.s | 8 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm | 77 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalCommonAPI.asm | 59 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/Processor.h | 10 | ||||
| -rwxr-xr-x | dev/Kernel/HALKit/AMD64/make_ap_blob.sh | 3 |
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 |
