diff options
Diffstat (limited to 'dev/Kernel/HALKit')
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc | 104 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalCommonAPI.asm | 61 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalKernelMain.cc | 2 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/ARM64/HalApplicationProcessor.cc | 14 |
4 files changed, 128 insertions, 53 deletions
diff --git a/dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc index 6563f23c..19f3a486 100644 --- a/dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -17,8 +17,6 @@ #define kApicSignature "APIC" -#define kApicBaseAddress (0xFEE00000) - #define kAPIC_ICR_Low 0x300 #define kAPIC_ICR_High 0x310 #define kAPIC_SIPI_Vector 0x00500 @@ -28,8 +26,6 @@ #define kAPIC_BASE_MSR_BSP 0x100 #define kAPIC_BASE_MSR_ENABLE 0x800 -#define kSMPMax (32U) - /// @note: _hal_switch_context is internal /////////////////////////////////////////////////////////////////////////////////////// @@ -41,6 +37,12 @@ namespace Kernel::HAL { struct MADT_TABLE; + struct PROCESS_CONTROL_BLOCK; + + struct PROCESS_CONTROL_BLOCK final + { + HAL::StackFramePtr mFrame; + }; EXTERN_C Void _hal_spin_core(Void); @@ -48,14 +50,11 @@ namespace Kernel::HAL STATIC Bool kSMPAware = false; STATIC Int64 kSMPCount = 0; - STATIC Int32 kSMPInterrupt = 0; - STATIC UInt64 kAPICLocales[kSMPMax] = {0}; - STATIC struct - { - UInt64 mAddress; - BOOL mUsed; - } kAPICAddresses[kSMPMax]; - STATIC VoidPtr kRawMADT = nullptr; + STATIC UIntPtr kApicBaseAddress = 0UL; + + STATIC Int32 kSMPInterrupt = 0; + STATIC UInt64 kAPICLocales[kSchedProcessLimitPerTeam] = {0}; + STATIC VoidPtr kRawMADT = nullptr; /// @brief Multiple APIC Descriptor Table. struct MADT_TABLE final : public SDT @@ -113,36 +112,31 @@ namespace Kernel::HAL /***********************************************************************************/ /// @brief Send IPI command to APIC. - /// @param apicId programmable interrupt controller id. + /// @param apic_id programmable interrupt controller id. /// @param vector vector interrupt. - /// @param targetAddress target APIC adress. + /// @param target target APIC adress. /// @return /***********************************************************************************/ - Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress) + Void hal_send_start_ipi(UInt32 apic_id, UInt32 vector, UInt32 target) { - Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, (apicId << 24)); - Kernel::ke_dma_write(targetAddress, 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, kAPIC_SIPI_Vector | vector); } /***********************************************************************************/ /// @brief Send end IPI for CPU. - /// @param apicId + /// @param apic_id /// @param vector - /// @param targetAddress + /// @param target /// @return /***********************************************************************************/ - Void hal_send_sipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress) + Void hal_send_sipi(UInt32 apic_id, UInt8 vector, UInt32 target) { - Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, (apicId << 24)); - Kernel::ke_dma_write(targetAddress, 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, kAPIC_EIPI_Vector | vector); } - struct PROCESS_CONTROL_BLOCK final - { - HAL::StackFramePtr mFrame; - }; - STATIC PROCESS_CONTROL_BLOCK kProcessBlocks[kSchedProcessLimitPerTeam] = {0}; EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 pid) @@ -151,14 +145,23 @@ namespace Kernel::HAL return kProcessBlocks[process_index].mFrame; } - EXTERN_C BOOL mp_register_process(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_frame, ProcessID pid) + EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) { - MUST_PASS(image && stack_ptr && stack_frame); + MUST_PASS(stack_frame); const auto process_index = pid % kSchedProcessLimitPerTeam; kProcessBlocks[process_index].mFrame = stack_frame; + 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); + return YES; } @@ -172,6 +175,11 @@ namespace Kernel::HAL } /***********************************************************************************/ + /// @brief Assembly symbol to bootstrap AP. + /***********************************************************************************/ + EXTERN_C Void hal_ap_start(Void); + + /***********************************************************************************/ /// @brief Fetch and enable SMP scheduler. /// @param vendor_ptr SMP containing structure. /***********************************************************************************/ @@ -194,48 +202,50 @@ namespace Kernel::HAL if (kMADTBlock) { - SizeT index_address = 0; - SizeT index_local = 0; - SizeT index = 0; - - // reset values. + SizeT index = 0; kSMPInterrupt = 0; kSMPCount = 0; kcout << "SMP: Probing Local APICs...\r"; - UIntPtr madt_address = kMADTBlock->Address; + kApicBaseAddress = kMADTBlock->Address; while (Yes) { if (kMADTBlock->List[index].Type > 9 || - kSMPCount > kSMPMax) + kSMPCount > kSchedProcessLimitPerTeam) break; switch (kMADTBlock->List[index].Type) { case 0x00: { - kAPICLocales[index_local] = kMADTBlock->List[index_local].LAPIC.ProcessorID; - kcout << "SMP: APIC ID: " << number(kAPICLocales[index_local]) << endl; + if (kMADTBlock->List[kSMPCount].LAPIC.ProcessorID < 1) + break; + + kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].LAPIC.ProcessorID; + kcout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << endl; + + // I'll just make the AP start from scratch here. + + hal_send_sipi(kAPICLocales[kSMPCount], ((UIntPtr)hal_ap_start >> 12), kApicBaseAddress); + + HardwareTimer timer(Kernel::Milliseconds(10)); + timer.Wait(); + + hal_send_sipi(kAPICLocales[kSMPCount], ((UIntPtr)hal_ap_start >> 12), kApicBaseAddress); + ++kSMPCount; break; } - case 0x05: { - kAPICAddresses[index_address].mAddress = kMADTBlock->List[index_address].LAPIC_ADDRESS_OVERRIDE.Address; - kAPICAddresses[index_address].mUsed = NO; - - kcout << "SMP: APIC address: " << number(madt_address) << endl; + default: break; } - } ++index; - ++index_address; - ++index_local; } - kcout << "SMP: number of cores: " << number(kSMPCount) << endl; + kcout << "SMP: number of APs: " << number(kSMPCount) << endl; // Kernel is now SMP aware. // That means that the scheduler is now available (on MP Kernels) diff --git a/dev/Kernel/HALKit/AMD64/HalCommonAPI.asm b/dev/Kernel/HALKit/AMD64/HalCommonAPI.asm index dd3901e8..4a516d33 100644 --- a/dev/Kernel/HALKit/AMD64/HalCommonAPI.asm +++ b/dev/Kernel/HALKit/AMD64/HalCommonAPI.asm @@ -78,3 +78,64 @@ mp_system_call_handler: pop r8 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/HalKernelMain.cc b/dev/Kernel/HALKit/AMD64/HalKernelMain.cc index e27e2efb..a61fef84 100644 --- a/dev/Kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/Kernel/HALKit/AMD64/HalKernelMain.cc @@ -96,9 +96,11 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept Kernel::HAL::mp_get_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); Kernel::HAL::Register64 idt_reg; + idt_reg.Base = (Kernel::UIntPtr)kInterruptVectorTable; Kernel::HAL::IDTLoader idt_loader; + idt_loader.Load(idt_reg); while (YES) diff --git a/dev/Kernel/HALKit/ARM64/HalApplicationProcessor.cc b/dev/Kernel/HALKit/ARM64/HalApplicationProcessor.cc index 4174057c..1d6dceaf 100644 --- a/dev/Kernel/HALKit/ARM64/HalApplicationProcessor.cc +++ b/dev/Kernel/HALKit/ARM64/HalApplicationProcessor.cc @@ -50,12 +50,14 @@ namespace Kernel Void mp_setup_gic_el0(Void)
{
// enable distributor.
- HAL::hal_mmio_write(GICD_BASE + GICD_CTLR, 0x1);
+ HAL::hal_mmio_write(GICD_BASE + GICD_CTLR, YES);
UInt32 gicc_ctlr = HAL::hal_mmio_read<UInt32>(GICC_BASE + GICC_CTLR);
- gicc_ctlr |= 0x1; // Enable signaling of interrupts
- gicc_ctlr |= (1 << 1); // Allow Group 1 interrupts in EL0
+ const auto kEnableSignalInt = YES;
+
+ gicc_ctlr |= kEnableSignalInt; // Enable signaling of interrupts
+ gicc_ctlr |= (kEnableSignalInt << 1); // Allow Group 1 interrupts in EL0
HAL::hal_mmio_write(GICC_BASE + GICC_CTLR, gicc_ctlr);
@@ -76,7 +78,7 @@ namespace Kernel // Enable interrupt 32 for AP.
HAL::hal_mmio_write(GICD_BASE + GICD_ISENABLER + (32 / 32) * 4, 0x01 << (32 % 32));
- kcout << "AP's GIC configured for interrupt 32." << endl;
+ kcout << "AP's GIC configured in ISR 32." << endl;
}
BOOL mp_handle_gic_interrupt_el0(Void)
@@ -108,9 +110,9 @@ namespace Kernel return kProcessBlocks[pid % kSchedProcessLimitPerTeam].mFrame;
}
- EXTERN_C Bool mp_register_process(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_frame, ProcessID pid)
+ EXTERN_C Bool mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid)
{
- MUST_PASS(image && stack_ptr && stack_frame);
+ MUST_PASS(stack_frame);
const auto process_index = pid % kSchedProcessLimitPerTeam;
|
