diff options
Diffstat (limited to 'dev/Kernel')
| -rw-r--r-- | dev/Kernel/ArchKit/ArchKit.h | 5 | ||||
| -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 | ||||
| -rw-r--r-- | dev/Kernel/src/HardwareThreadScheduler.cc | 9 | ||||
| -rw-r--r-- | dev/Kernel/src/UserProcessScheduler.cc | 8 |
7 files changed, 141 insertions, 62 deletions
diff --git a/dev/Kernel/ArchKit/ArchKit.h b/dev/Kernel/ArchKit/ArchKit.h index b67cc29e..af8aef1a 100644 --- a/dev/Kernel/ArchKit/ArchKit.h +++ b/dev/Kernel/ArchKit/ArchKit.h @@ -43,9 +43,10 @@ namespace Kernel /// @param base the base address. /// @param reg the register. /// @param value the write to write on it. - inline Void ke_dma_write(UInt32 base, UInt32 reg, UInt32 value) noexcept + template <typename WordLength> + inline Void ke_dma_write(WordLength base, WordLength reg, WordLength value) noexcept { - *(volatile UInt32*)((UInt64)base + reg) = value; + *(volatile WordLength*)((UInt64)base + reg) = value; } /// @brief read from mapped memory register. 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;
diff --git a/dev/Kernel/src/HardwareThreadScheduler.cc b/dev/Kernel/src/HardwareThreadScheduler.cc index a94ad64c..0e9a2865 100644 --- a/dev/Kernel/src/HardwareThreadScheduler.cc +++ b/dev/Kernel/src/HardwareThreadScheduler.cc @@ -22,7 +22,7 @@ namespace Kernel /***********************************************************************************/ EXTERN Bool hal_check_stack(HAL::StackFramePtr frame_ptr); - EXTERN_C Bool mp_register_process(VoidPtr image, Ptr8 stack_ptr, HAL::StackFramePtr frame, ProcessID pid); + EXTERN_C Bool mp_register_process(HAL::StackFramePtr frame, ProcessID pid); STATIC HardwareThreadScheduler kHardwareThreadScheduler; @@ -109,12 +109,15 @@ namespace Kernel /// @retval true stack was changed, code is running. /// @retval false stack is invalid, previous code is running. /***********************************************************************************/ - Bool HardwareThread::Switch(VoidPtr image, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ThreadID& pid) + Bool HardwareThread::Switch(VoidPtr image_ptr, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ThreadID& pid) { this->fStack = frame; this->fSourcePID = pid; - Bool ret = mp_register_process(image, stack_ptr, fStack, this->fSourcePID); + fStack->BP = reinterpret_cast<UIntPtr>(image_ptr); + fStack->SP = reinterpret_cast<UIntPtr>(stack_ptr); + + Bool ret = mp_register_process(fStack, this->fSourcePID); if (ret) this->Busy(YES); diff --git a/dev/Kernel/src/UserProcessScheduler.cc b/dev/Kernel/src/UserProcessScheduler.cc index 2d3101f2..f21e90d9 100644 --- a/dev/Kernel/src/UserProcessScheduler.cc +++ b/dev/Kernel/src/UserProcessScheduler.cc @@ -330,7 +330,7 @@ namespace Kernel #endif // __ZKA_VIRTUAL_MEMORY_SUPPORT__ // React according to process kind. - switch (process.kind) + switch (process.Kind) { case UserThread::kExectuableDylibKind: { @@ -439,9 +439,9 @@ namespace Kernel for (; process_index < mTeam.AsArray().Capacity(); ++process_index) { - auto process = mTeam.AsArray()[process_index]; + auto& process = mTeam.AsArray()[process_index]; - //! check if process needs to be scheduled. + //! check if the process needs to be run. if (UserProcessHelper::CanBeScheduled(process)) { // Set current process header. @@ -455,7 +455,7 @@ namespace Kernel if (!UserProcessHelper::Switch(process.Image.fCode, &process.StackReserve[process.StackSize - 1], process.StackFrame, process.ProcessId)) { - kcout << "Invalid process.\r"; + kcout << "Invalid process (UH OH)\r"; process.Crash(); } } |
