diff options
| author | Amlal El Mahrouss <zka-holder@mahrouss-logic.com> | 2024-10-14 05:58:38 +0000 |
|---|---|---|
| committer | Amlal El Mahrouss <zka-holder@mahrouss-logic.com> | 2024-10-14 05:58:38 +0000 |
| commit | 7ad3739afdfaa2466723467f5ef2526f171c87c3 (patch) | |
| tree | 37775f4299281598b0f5121df4c188392daebd04 /dev/zka/HALKit | |
| parent | 7477a0f942c374b652da4f80cdb36d4661aac3c8 (diff) | |
| parent | d9d82713326069478e6dd212763d1fac15e65370 (diff) | |
Merge branch 'port-stage1-hello-world' into 'unstable'
IMP: Basic ARM64 port.
See merge request mahrouss/zka-dev!20
Diffstat (limited to 'dev/zka/HALKit')
20 files changed, 394 insertions, 212 deletions
diff --git a/dev/zka/HALKit/AMD64/HalACPIFactoryInterface.cxx b/dev/zka/HALKit/AMD64/HalACPIFactoryInterface.cxx index 83f9993f..0d00b643 100644 --- a/dev/zka/HALKit/AMD64/HalACPIFactoryInterface.cxx +++ b/dev/zka/HALKit/AMD64/HalACPIFactoryInterface.cxx @@ -82,8 +82,8 @@ namespace Kernel }; } // namespace Detail - ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsdPtr) - : fRsdp(rsdPtr), fEntries(0) + ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) + : fRsdp(rsp_ptr), fEntries(0) { } @@ -123,86 +123,4 @@ namespace Kernel "jmp reset_wait ; " ".att_syntax; "); } - - /// @brief Finds a descriptor table inside ACPI XSDT. - ErrorOr<voidPtr> ACPIFactoryInterface::Find(const Char* signature) - { - MUST_PASS(fRsdp); - - if (!signature) - return ErrorOr<voidPtr>{-1}; - - if (*signature == 0) - return ErrorOr<voidPtr>{-1}; - - RSDP* rsdPtr = reinterpret_cast<RSDP*>(this->fRsdp); - - if (rsdPtr->Revision <= 1) - return ErrorOr<voidPtr>{-1}; - - RSDT* xsdt = reinterpret_cast<RSDT*>(rsdPtr->RsdtAddress); - - Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(UInt32); - - /*** - crucial to avoid - overflows. - */ - if (num < 1) - { - /// stop here, we should have entries... - ke_stop(RUNTIME_CHECK_ACPI); - return ErrorOr<voidPtr>{-1}; - } - - this->fEntries = num; - - kcout << "ACPI: Number of entries: " << number(this->fEntries) << endl; - kcout << "ACPI: Revision: " << number(xsdt->Revision) << endl; - kcout << "ACPI: Signature: " << xsdt->Signature << endl; - kcout << "ACPI: Address of XSDT: " << hex_number((UIntPtr)xsdt) << endl; - - const short cAcpiSignatureLength = 4; - - for (Size index = 0; index < this->fEntries; ++index) - { - SDT* sdt = reinterpret_cast<SDT*>(xsdt->AddressArr[index]); - - kcout << "ACPI: Checksum: " << number(sdt->Checksum) << endl; - kcout << "ACPI: Revision: " << number(sdt->Revision) << endl; - - for (short signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index) - { - if (sdt->Signature[signature_index] != signature[signature_index]) - break; - - if (signature_index == (cAcpiSignatureLength - 1)) - { - kcout << "ACPI: Found the SDT. " << endl; - return ErrorOr<voidPtr>(reinterpret_cast<voidPtr>(xsdt->AddressArr[index])); - } - } - } - - return ErrorOr<voidPtr>{-1}; - } - - /*** - @brief check SDT header - @param checksum the header to checksum - @param len the length of it. -*/ - bool ACPIFactoryInterface::Checksum(const Char* checksum, SSizeT len) - { - if (len == 0) - return -1; - - char chr = 0; - - for (int index = 0; index < len; ++index) - { - chr += checksum[index]; - } - - return chr == 0; - } } // namespace Kernel diff --git a/dev/zka/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx b/dev/zka/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx index c6b8303d..1167e861 100644 --- a/dev/zka/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx +++ b/dev/zka/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx @@ -4,6 +4,7 @@ ------------------------------------------- */ +#include "NewKit/Stop.hxx" #include <ArchKit/ArchKit.hxx> #include <KernelKit/UserProcessScheduler.hxx> #include <NewKit/String.hxx> @@ -43,13 +44,9 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) Kernel::ke_stop(RUNTIME_CHECK_PROCESS); } -EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) +/// @brief Handle scheduler interrupt. +EXTERN_C void idt_handle_scheduler() { - if (Kernel::cProcessScheduler == nullptr) - { - Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED); - } - Kernel::UserProcessHelper::StartScheduling(); } @@ -101,6 +98,8 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) /// @return nothing. EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx, Kernel::UIntPtr rdx) { + Kernel::HAL::Out8(0x20, 0x20); // Acknowledge interrupt to master PIC + if (rcx <= (kSyscalls.Count() - 1)) { kcout << "syscall: Enter Fn.\r"; @@ -117,6 +116,8 @@ EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx, Kernel::UIntPtr /// @return nothing. EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx, Kernel::UIntPtr rdx, Kernel::UIntPtr r8, Kernel::UIntPtr r9) { + Kernel::HAL::Out8(0x20, 0x20); // Acknowledge interrupt to master PIC + if (rcx <= (kSyscalls.Count() - 1)) { kcout << "kerncall: Enter Fn.\r"; diff --git a/dev/zka/HALKit/AMD64/HalCoreMPScheduler.cxx b/dev/zka/HALKit/AMD64/HalCoreMPScheduler.cxx index ae6dc905..44f1f60a 100644 --- a/dev/zka/HALKit/AMD64/HalCoreMPScheduler.cxx +++ b/dev/zka/HALKit/AMD64/HalCoreMPScheduler.cxx @@ -136,15 +136,6 @@ namespace Kernel::HAL EXTERN_C Bool mp_register_process(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_frame); - /// @brief Called when the AP is ready. - /// @internal - EXTERN_C Void hal_on_ap_startup(Void) - { - while (Yes) - { - } - } - struct PROCESS_CONTROL_BLOCK final { HAL::StackFramePtr f_Frame; @@ -157,18 +148,17 @@ namespace Kernel::HAL return fBlocks[UserProcessScheduler::The().CurrentProcess().Leak().ProcessId % kSchedProcessLimitPerTeam].f_Frame; } + EXTERN_C Void mp_do_task_switch(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_frame); + EXTERN_C Bool mp_register_process(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_frame) { - if (kSMPAware) - { - fBlocks[UserProcessScheduler::The().CurrentProcess().Leak().ProcessId % kSchedProcessLimitPerTeam].f_Frame = stack_frame; - fBlocks[UserProcessScheduler::The().CurrentProcess().Leak().ProcessId % kSchedProcessLimitPerTeam].f_Stack = stack_ptr; - fBlocks[UserProcessScheduler::The().CurrentProcess().Leak().ProcessId % kSchedProcessLimitPerTeam].f_Image = image; + fBlocks[UserProcessScheduler::The().CurrentProcess().Leak().ProcessId % kSchedProcessLimitPerTeam].f_Frame = stack_frame; + fBlocks[UserProcessScheduler::The().CurrentProcess().Leak().ProcessId % kSchedProcessLimitPerTeam].f_Stack = stack_ptr; + fBlocks[UserProcessScheduler::The().CurrentProcess().Leak().ProcessId % kSchedProcessLimitPerTeam].f_Image = image; - return Yes; - } + mp_do_task_switch(image, stack_ptr, stack_frame); - return No; + return Yes; } /***********************************************************************************/ diff --git a/dev/zka/HALKit/AMD64/HalDescriptorLoader.cxx b/dev/zka/HALKit/AMD64/HalDescriptorLoader.cxx index 44263a1c..bc06d01a 100644 --- a/dev/zka/HALKit/AMD64/HalDescriptorLoader.cxx +++ b/dev/zka/HALKit/AMD64/HalDescriptorLoader.cxx @@ -5,6 +5,7 @@ ------------------------------------------- */ #include <ArchKit/ArchKit.hxx> +#include <HALKit/AMD64/Processor.hxx> namespace Kernel::HAL { @@ -15,24 +16,32 @@ namespace Kernel::HAL STATIC Void hal_remap_intel_pic_ctrl(Void) noexcept { - auto a1 = HAL::In8(0xa1); // save masks - auto a2 = HAL::In8(0xa2); + uint8_t a1_saved = In8(kPICData); + uint8_t a2_saved = In8(kPIC2Data); - HAL::Out8(0x20, 0x11); + Out8(kPICCommand, 0x11); // Start initialization + Out8(kPICData, 0x20); // Master PIC offset + Out8(kPICData, 0x04); // Tell master PIC there is a slave + Out8(kPICData, 0x01); // 8086 mode - HAL::Out8(0xA0, 0x11); + Out8(kPIC2Command, 0x11); // Start initialization + Out8(kPIC2Data, 0x28); // Slave PIC offset + Out8(kPIC2Data, 0x02); // Tell slave PIC its cascade + Out8(kPIC2Data, 0x01); // 8086 mode - HAL::Out8(0x21, 32); - HAL::Out8(0xA1, 40); + Out8(kPICData, a1_saved); // Restore saved masks + Out8(kPIC2Data, a2_saved); + } - HAL::Out8(0x21, 4); - HAL::Out8(0xA1, 2); + STATIC Void hal_enable_pit() noexcept + { + // Configure PIT to receieve scheduler interrupts. - HAL::Out8(0x21, 0x01); - HAL::Out8(0xA1, 0x01); + UInt32 cCommonDivisor = kPITFrequency / 100; // 100 Hz. - HAL::Out8(0x21, a2); - HAL::Out8(0xA1, a1); + HAL::Out8(kPITControlPort, 0x36); // Command to PIT + HAL::Out8(kPITChannel0Port, cCommonDivisor & 0xFF); // Send low byte + HAL::Out8(kPITControlPort, (cCommonDivisor >> 8) & 0xFF); // Send high byte } } // namespace Detail @@ -46,6 +55,9 @@ namespace Kernel::HAL Void IDTLoader::Load(Register64& idt) { + Detail::hal_remap_intel_pic_ctrl(); + Detail::hal_enable_pit(); + volatile ::Kernel::UIntPtr** ptr_ivt = (volatile ::Kernel::UIntPtr**)idt.Base; for (UInt16 idt_indx = 0; idt_indx < (kKernelIdtSize); ++idt_indx) @@ -66,8 +78,6 @@ namespace Kernel::HAL (kKernelIdtSize)-1; hal_load_idt(idt); - - Detail::hal_remap_intel_pic_ctrl(); } void GDTLoader::Load(Ref<RegisterGDT>& gdt) diff --git a/dev/zka/HALKit/AMD64/HalInterruptAPI.asm b/dev/zka/HALKit/AMD64/HalInterruptAPI.asm index cdbb2d1f..d9e16f6c 100644 --- a/dev/zka/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/zka/HALKit/AMD64/HalInterruptAPI.asm @@ -131,8 +131,24 @@ IntNormal 28 IntNormal 29 IntExp 30 IntNormal 31 -IntNormal 32 + +[extern idt_handle_scheduler] + +__ZKA_INT_32: + cli + + push rsp + + jmp idt_handle_scheduler + + add rsp, 16 + pop rsp + + sti + o64 iret + IntNormal 33 + IntNormal 34 IntNormal 35 IntNormal 36 @@ -194,25 +210,7 @@ __ZKA_INT_51: std o64 iret -[extern hal_on_ap_startup] - -PRESENT equ 1 << 7 -NOT_SYS equ 1 << 4 -EXEC equ 1 << 3 -DC equ 1 << 2 -RW equ 1 << 1 -ACCESSED equ 1 << 0 - -; Flags bits -GRAN_4K equ 1 << 7 -SZ_32 equ 1 << 6 -LONG_MODE equ 1 << 5 - -__ZKA_INT_52: - cld - jmp hal_on_ap_startup - std - ret +IntNormal 52 IntNormal 53 IntNormal 54 diff --git a/dev/zka/HALKit/AMD64/HalKernelMain.cxx b/dev/zka/HALKit/AMD64/HalKernelMain.cxx index 30124932..ad32ada6 100644 --- a/dev/zka/HALKit/AMD64/HalKernelMain.cxx +++ b/dev/zka/HALKit/AMD64/HalKernelMain.cxx @@ -6,6 +6,7 @@ #include <ArchKit/ArchKit.hxx> #include <KernelKit/UserProcessScheduler.hxx> +#include <KernelKit/HardwareThreadScheduler.hxx> #include <KernelKit/CodeMgr.hxx> #include <modules/ACPI/ACPIFactoryInterface.hxx> #include <NetworkKit/IPC.hxx> @@ -15,13 +16,14 @@ namespace Kernel::HAL { /// @brief Gets the system cores using the MADT. - /// @param rsdPtr The 'RSD PTR' data structure. - EXTERN void mp_get_cores(Kernel::voidPtr rsdPtr) noexcept; + /// @param rsp_ptr The 'RSD PTR' data structure. + EXTERN void mp_get_cores(Kernel::voidPtr rsp_ptr) noexcept; } // namespace Kernel::HAL namespace Kernel { EXTERN UserProcessScheduler* cProcessScheduler; + EXTERN HardwareThreadScheduler* cHardwareThreadScheduler; } EXTERN_C Kernel::VoidPtr kInterruptVectorTable[]; @@ -35,6 +37,7 @@ EXTERN_C void hal_init_platform( kHandoverHeader = HandoverHeader; Kernel::cProcessScheduler = nullptr; + Kernel::cHardwareThreadScheduler = nullptr; if (kHandoverHeader->f_Magic != kHandoverMagic && kHandoverHeader->f_Version != kHandoverVersion) @@ -42,13 +45,18 @@ EXTERN_C void hal_init_platform( return; } - // get page size. - kKernelBitMpSize = kHandoverHeader->f_BitMapSize; + /************************************** */ + /* INITIALIZE BIT MAP. */ + /************************************** */ - // get virtual address start (for the heap) + kKernelBitMpSize = kHandoverHeader->f_BitMapSize; kKernelBitMpStart = reinterpret_cast<Kernel::VoidPtr>( reinterpret_cast<Kernel::UIntPtr>(kHandoverHeader->f_BitMapStart)); + /************************************** */ + /* INITIALIZE GDT AND SEGMENTS. */ + /************************************** */ + STATIC CONST auto cEntriesCount = 6; /* GDT, mostly descriptors for user and kernel segments. */ @@ -61,25 +69,25 @@ EXTERN_C void hal_init_platform( }; // Load memory descriptors. - Kernel::HAL::RegisterGDT gdtBase; + Kernel::HAL::RegisterGDT gdt_reg; - gdtBase.Base = reinterpret_cast<Kernel::UIntPtr>(cGdt); - gdtBase.Limit = (sizeof(Kernel::HAL::Detail::ZKA_GDT_ENTRY) * cEntriesCount) - 1; + gdt_reg.Base = reinterpret_cast<Kernel::UIntPtr>(cGdt); + gdt_reg.Limit = (sizeof(Kernel::HAL::Detail::ZKA_GDT_ENTRY) * cEntriesCount) - 1; //! GDT will load hal_read_init after it successfully loads the segments. - Kernel::HAL::GDTLoader gdtLoader; - gdtLoader.Load(gdtBase); + Kernel::HAL::GDTLoader gdt_loader; + gdt_loader.Load(gdt_reg); Kernel::ke_stop(RUNTIME_CHECK_BOOTSTRAP); } EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { - Kernel::HAL::Register64 idtBase; - idtBase.Base = (Kernel::UIntPtr)kInterruptVectorTable; + Kernel::HAL::Register64 idt_reg; + idt_reg.Base = (Kernel::UIntPtr)kInterruptVectorTable; - Kernel::HAL::IDTLoader idtLoader; - idtLoader.Load(idtBase); + Kernel::HAL::IDTLoader idt_loader; + idt_loader.Load(idt_reg); if (kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled) Kernel::HAL::mp_get_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); @@ -87,10 +95,7 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept Kernel::NeFileSystemMgr* mgr = Kernel::mm_new_class<Kernel::NeFileSystemMgr>(); Kernel::NeFileSystemMgr::Mount(mgr); - Kernel::HAL::mm_map_page(mp_user_switch_proc, Kernel::HAL::eFlagsUser | Kernel::HAL::eFlagsWr | Kernel::HAL::eFlagsPresent); - Kernel::HAL::mm_map_page(mp_user_switch_proc_stack_begin, Kernel::HAL::eFlagsUser | Kernel::HAL::eFlagsWr | Kernel::HAL::eFlagsPresent); - - mp_do_user_switch(); + Kernel::UserProcessHelper::InitializeScheduling(); Kernel::ke_stop(RUNTIME_CHECK_BOOTSTRAP); } diff --git a/dev/zka/HALKit/AMD64/HalMPContextSwitch.asm b/dev/zka/HALKit/AMD64/HalMPContextSwitch.asm index c6480778..2ad38107 100644 --- a/dev/zka/HALKit/AMD64/HalMPContextSwitch.asm +++ b/dev/zka/HALKit/AMD64/HalMPContextSwitch.asm @@ -9,7 +9,7 @@ [bits 64] -[global mp_do_user_switch] +[global mp_do_task_switch] [global mp_do_context_switch_pre] [global mp_user_switch_proc] [global mp_user_switch_proc_stack_begin] @@ -17,12 +17,9 @@ section .text ;; @brief Switch to user mode. -mp_do_user_switch: - mov rbp, rsp - mov rsp, mp_user_switch_proc_stack_end - - mov rdx, mp_user_switch_proc - invlpg [rdx] +mp_do_task_switch: + mov rbp, rdx + mov rsp, rdx mov ax, 0x18 | 3 mov ds, ax @@ -32,15 +29,15 @@ mp_do_user_switch: push 0x18 | 3 - mov rax, mp_user_switch_proc_stack_end + mov rax, rdx push rax o64 pushf push 0x20 | 3 - mov rdx, mp_user_switch_proc - push rdx + mov rax, rcx + push rax o64 iret diff --git a/dev/zka/HALKit/AMD64/HalPagingMgr.cxx b/dev/zka/HALKit/AMD64/HalPagingMgr.cxx index 06a8b7d2..78978bc7 100644 --- a/dev/zka/HALKit/AMD64/HalPagingMgr.cxx +++ b/dev/zka/HALKit/AMD64/HalPagingMgr.cxx @@ -57,7 +57,7 @@ namespace Kernel::HAL kcout << (pte->User ? "User" : "Not User") << endl; } - STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, ZKA_PTE* pt_entry); + STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry); /// @brief Maps or allocates a page from virtual_address. /// @param virtual_address a valid virtual address. @@ -121,7 +121,7 @@ namespace Kernel::HAL /// @brief Maps flags for a specific pte. /// @internal Internal function. - STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, ZKA_PTE* pt_entry) + STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry) { if (flags & ~eFlagsPresent) pt_entry->Present = false; diff --git a/dev/zka/HALKit/AMD64/HalSchedulerCore.cxx b/dev/zka/HALKit/AMD64/HalSchedulerCore.cxx index 9dcce147..d2f678e2 100644 --- a/dev/zka/HALKit/AMD64/HalSchedulerCore.cxx +++ b/dev/zka/HALKit/AMD64/HalSchedulerCore.cxx @@ -26,7 +26,7 @@ namespace Kernel EXTERN_C Void __zka_pure_call(void) { - asm volatile("mov %r8, 0; mov %r9, 1; syscall"); + UserProcessScheduler::The().CurrentProcess().Leak().Crash(); } Bool hal_check_stack(HAL::StackFramePtr stack_ptr) diff --git a/dev/zka/HALKit/AMD64/HalUtils.asm b/dev/zka/HALKit/AMD64/HalUtils.asm index 0e4caf2b..715859e8 100644 --- a/dev/zka/HALKit/AMD64/HalUtils.asm +++ b/dev/zka/HALKit/AMD64/HalUtils.asm @@ -25,9 +25,3 @@ rt_install_tib: [extern cBspDone] [extern kApicMadtAddressesCount] -[extern hal_on_ap_startup] -[global hal_ap_trampoline] - -hal_ap_trampoline: -hal_ap_trampoline_1: - jmp hal_on_ap_startup diff --git a/dev/zka/HALKit/AMD64/Processor.hxx b/dev/zka/HALKit/AMD64/Processor.hxx index b0a8aa0a..f01c73ab 100644 --- a/dev/zka/HALKit/AMD64/Processor.hxx +++ b/dev/zka/HALKit/AMD64/Processor.hxx @@ -19,6 +19,15 @@ #include <FirmwareKit/Handover.hxx> #include <HALKit/AMD64/Paging.hxx> +#define kPITControlPort 0x43 +#define kPITChannel0Port 0x40 +#define kPITFrequency 1193180 + +#define kPICCommand 0x20 +#define kPICData 0x21 +#define kPIC2Command 0xA0 +#define kPIC2Data 0xA1 + EXTERN_C { #include <cpuid.h> @@ -35,7 +44,7 @@ EXTERN_C #define IsActiveLow(FLG) (FLG & 2) #define IsLevelTriggered(FLG) (FLG & 8) -#define kInterruptGate (0x8E) +#define kInterruptGate (0x0E) #define kTrapGate (0xEF) #define kTaskGate (0b10001100) #define kIDTSelector (0x08) @@ -59,7 +68,7 @@ namespace Kernel namespace Kernel::HAL { - /// @brief Virtual memory flags. + /// @brief Memory Manager mapping flags. enum { eFlagsPresent = 1 << 0, @@ -168,7 +177,7 @@ namespace Kernel::HAL static Void Load(Ref<Register64>& idt); }; - Void mp_get_cores(VoidPtr rsdPtr) noexcept; + Void mp_get_cores(VoidPtr rsp_ptr) noexcept; Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress); Void hal_send_end_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress); diff --git a/dev/zka/HALKit/ARM64/APM/APM.cxx b/dev/zka/HALKit/ARM64/APM/APM.cxx new file mode 100644 index 00000000..7962aa16 --- /dev/null +++ b/dev/zka/HALKit/ARM64/APM/APM.cxx @@ -0,0 +1,37 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include <modules/APM/APM.hxx> +#include <KernelKit/LPC.hxx> + +using namespace Kernel; + +/// @brief Send a APM command into it's own IO space. +/// @param base_dma the IO base port. +/// @param cmd the command. +/// @return status code. +EXTERN_C Int32 apm_send_io_command(UInt16 cmd, APMPowerCmd value) +{ + switch (cmd) + { + case kAPMPowerCommandReboot: { + asm volatile( + "ldr x0, =0x84000009\n" + "hvc #0\n"); + + return kErrorSuccess; + } + case kAPMPowerCommandShutdown: { + asm volatile( + "ldr x0, =0x84000008\n" + "hvc #0\n"); + + return kErrorSuccess; + } + default: + return kErrorInvalidData; + } +} diff --git a/dev/zka/HALKit/ARM64/HalACPIFactoryInterface.cxx b/dev/zka/HALKit/ARM64/HalACPIFactoryInterface.cxx new file mode 100644 index 00000000..75ecefee --- /dev/null +++ b/dev/zka/HALKit/ARM64/HalACPIFactoryInterface.cxx @@ -0,0 +1,31 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include <modules/ACPI/ACPIFactoryInterface.hxx> +#include <NewKit/String.hxx> +#include <ArchKit/ArchKit.hxx> +#include <KernelKit/Heap.hxx> +#include <modules/APM/APM.hxx> + +namespace Kernel +{ + ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) + : fRsdp(rsp_ptr), fEntries(0) + { + } + + Void ACPIFactoryInterface::Shutdown() + { + apm_send_io_command(kAPMPowerCommandShutdown, 0); + } + + /// @brief Reboot machine in either ACPI or by triple faulting. + /// @return nothing it's a reboot. + Void ACPIFactoryInterface::Reboot() + { + apm_send_io_command(kAPMPowerCommandReboot, 0); + } +} // namespace Kernel diff --git a/dev/zka/HALKit/ARM64/HalCoreMPScheduler.cxx b/dev/zka/HALKit/ARM64/HalCoreMPScheduler.cxx new file mode 100644 index 00000000..102ca194 --- /dev/null +++ b/dev/zka/HALKit/ARM64/HalCoreMPScheduler.cxx @@ -0,0 +1,19 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include <modules/ACPI/ACPIFactoryInterface.hxx> +#include <KernelKit/UserProcessScheduler.hxx> + +using namespace Kernel; + +EXTERN_C Void mp_do_task_switch(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_frame); + +EXTERN_C Bool mp_register_process(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_frame) +{ + mp_do_task_switch(image, stack_ptr, stack_frame); + + return Yes; +} diff --git a/dev/zka/HALKit/ARM64/HalDebugOutput.cxx b/dev/zka/HALKit/ARM64/HalDebugOutput.cxx new file mode 100644 index 00000000..9dc7278c --- /dev/null +++ b/dev/zka/HALKit/ARM64/HalDebugOutput.cxx @@ -0,0 +1,81 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + +------------------------------------------- */ + +#include <ArchKit/ArchKit.hxx> +#include <KernelKit/DebugOutput.hxx> +#include <NewKit/Utils.hxx> +#include <NewKit/New.hxx> + +namespace Kernel +{ + EXTERN_C void ke_io_write(const Char* bytes) + { +#ifdef __DEBUG__ + if (*bytes == 0) + return; + + SizeT index = 0; + SizeT len = 0; + + index = 0; + len = rt_string_len(bytes, 255); + + volatile UInt8* uart_ptr = (UInt8*)0x09000000; + + while (index < len) + { + if (bytes[index] == '\r') + *uart_ptr = '\r'; + + *uart_ptr = bytes[index] == '\r' ? '\n' : bytes[index]; + ++index; + } +#endif // __DEBUG__ + } + + EXTERN_C void ke_io_read(const Char* bytes) + { +#ifdef __DEBUG__ + SizeT index = 0; + + volatile UInt8* uart_ptr = (UInt8*)0x09000000; + + ///! TODO: Look on how to wait for the UART to complete. + while (Yes) + { + auto in = *uart_ptr; + + ///! If enter pressed then break. + if (in == 0xD) + { + break; + } + + if (in < '0' || in < 'A' || in < 'a') + { + if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' || + in != ':') + { + continue; + } + } + + ((char*)bytes)[index] = in; + + ++index; + } + + ((char*)bytes)[index] = 0; +#endif // __DEBUG__ + } + + TerminalDevice TerminalDevice::The() noexcept + { + TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read); + return out; + } + +} // namespace Kernel diff --git a/dev/zka/HALKit/ARM64/HalKernelMain.cxx b/dev/zka/HALKit/ARM64/HalKernelMain.cxx index 56287733..4d0d0875 100644 --- a/dev/zka/HALKit/ARM64/HalKernelMain.cxx +++ b/dev/zka/HALKit/ARM64/HalKernelMain.cxx @@ -17,13 +17,6 @@ #include <NetworkKit/IPC.hxx> #include <CFKit/Property.hxx> -namespace Kernel::HAL -{ - /// @brief Gets the system cores using the MADT. - /// @param rsdPtr The 'RSD PTR' data structure. - EXTERN void mp_get_cores(Kernel::voidPtr rsdPtr) noexcept; -} // namespace Kernel::HAL - Kernel::Void hal_real_init(Kernel::Void) noexcept; EXTERN_C Kernel::Void ke_dll_entrypoint(Kernel::Void); @@ -38,24 +31,5 @@ EXTERN_C void hal_init_platform( return; } - // get page size. - kKernelBitMpSize = kHandoverHeader->f_BitMapSize; - - // get virtual address start (for the heap) - kKernelBitMpStart = reinterpret_cast<Kernel::VoidPtr>( - reinterpret_cast<Kernel::UIntPtr>(kHandoverHeader->f_BitMapStart)); - - if (kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled) - Kernel::HAL::mp_get_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); - - kcout << "Creating filesystem and such.\r"; - - if (kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled) - Kernel::HAL::mp_get_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); - - Kernel::NeFileSystemMgr::Mount(Kernel::mm_new_class<Kernel::NeFileSystemMgr>()); - - mp_do_user_switch(); - - Kernel::ke_stop(RUNTIME_CHECK_FAILED); + while (Yes) {} } diff --git a/dev/zka/HALKit/ARM64/HalPagingMgr.cxx b/dev/zka/HALKit/ARM64/HalPagingMgr.cxx new file mode 100644 index 00000000..7e686905 --- /dev/null +++ b/dev/zka/HALKit/ARM64/HalPagingMgr.cxx @@ -0,0 +1,87 @@ +/* ------------------------------------------- + + Copyright ZKA Technologies. + + File: HalPagingMgr.cxx + Purpose: Platform Paging Manager.. + +------------------------------------------- */ + +#include <HALKit/ARM64/Paging.hxx> +#include <HALKit/ARM64/Processor.hxx> + +namespace Kernel::HAL +{ + typedef UInt32 PageTableIndex; + + /// \brief Page store type. + struct ZKA_PAGE_STORE final + { + struct + { + PDE* fPde{nullptr}; + PTE* fPte{nullptr}; + VoidPtr fVAddr{nullptr}; + } fInternalStore; + + Bool fStoreOp{No}; // Store operation in progress. + + static ZKA_PAGE_STORE& The() + { + static ZKA_PAGE_STORE the; + return the; + } + }; + + /// \brief Retrieve the page status of a PTE. + STATIC Void mmi_page_status(PTE* pte) + { + + } + + STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry); + + /// @brief Maps or allocates a page from virtual_address. + /// @param virtual_address a valid virtual address. + /// @param phys_addr point to physical address. + /// @param flags the flags to put on the page. + /// @return Status code of page manipulation process. + EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, UInt32 flags) + { + if (!virtual_address || + !flags) + return 0; + + ZKA_PAGE_STORE& page_store = ZKA_PAGE_STORE::The(); + + while (page_store.fStoreOp) + ; + + page_store.fStoreOp = Yes; + + if (page_store.fInternalStore.fVAddr == virtual_address) + { + page_store.fStoreOp = No; + return mmi_map_page_table_entry(page_store.fInternalStore.fVAddr, flags, page_store.fInternalStore.fPte); + } + + return -1; + } + + /// @brief Maps flags for a specific pte. + /// @internal Internal function. + STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry) + { + ZKA_PAGE_STORE& page_store = ZKA_PAGE_STORE::The(); + + // Update Internal store. + + page_store.fInternalStore.fPde = nullptr; + page_store.fInternalStore.fPte = pt_entry; + page_store.fInternalStore.fVAddr = virtual_address; + + page_store.fStoreOp = No; + + return 0; + } +} // namespace Kernel::HAL diff --git a/dev/zka/HALKit/ARM64/HalSchedulerCore.cxx b/dev/zka/HALKit/ARM64/HalSchedulerCore.cxx index 630df4fd..30e2f1b5 100644 --- a/dev/zka/HALKit/ARM64/HalSchedulerCore.cxx +++ b/dev/zka/HALKit/ARM64/HalSchedulerCore.cxx @@ -8,6 +8,11 @@ namespace Kernel { + EXTERN_C Void __zka_pure_call(void) + { + UserProcessScheduler::The().CurrentProcess().Leak().Crash(); + } + Void UserProcess::SetImageStart(VoidPtr image_start) noexcept { if (image_start == 0) diff --git a/dev/zka/HALKit/ARM64/Processor.hxx b/dev/zka/HALKit/ARM64/Processor.hxx index 533457a9..68c305f3 100644 --- a/dev/zka/HALKit/ARM64/Processor.hxx +++ b/dev/zka/HALKit/ARM64/Processor.hxx @@ -11,8 +11,6 @@ #include <NewKit/Utils.hxx> #include <FirmwareKit/Handover.hxx> -#define kPageSize 512 /* 64-bit PT */ - #define kCPUBackendName "ARMv8" namespace Kernel::HAL @@ -23,6 +21,23 @@ namespace Kernel::HAL UIntPtr Base; }; + /// @brief Memory Manager mapping flags. + enum + { + eFlagsPresent = 1 << 0, + eFlagsWr = 1 << 1, + eFlagsUser = 1 << 2, + eFlagsNX = 1 << 3, + eFlagsCount = 3, + }; + + /// @brief Set a PTE from pd_base. + /// @param virt_addr a valid virtual address. + /// @param phys_addr point to physical address. + /// @param flags the flags to put on the page. + /// @return Status code of page manip. + EXTERN_C Int32 mm_map_page(VoidPtr virt_addr, UInt32 flags); + typedef UIntPtr Reg; typedef Register64 Register; @@ -37,9 +52,20 @@ namespace Kernel::HAL Reg R13{0}; Reg R14{0}; Reg R15{0}; + Reg SP{0}; + Reg BP{0}; }; typedef StackFrame* StackFramePtr; + + inline Void rt_halt() + { + while (Yes) + { + + } + } + } // namespace Kernel::HAL inline Kernel::VoidPtr kKernelBitMpStart = nullptr; diff --git a/dev/zka/HALKit/POWER/HalContextSwitchPowerPC.s b/dev/zka/HALKit/POWER/HalContextSwitchPowerPC.s index 588de23a..d90c1fa0 100644 --- a/dev/zka/HALKit/POWER/HalContextSwitchPowerPC.s +++ b/dev/zka/HALKit/POWER/HalContextSwitchPowerPC.s @@ -7,10 +7,10 @@ .align 4 .type name, @function .text -.globl mp_do_user_switch +.globl mp_do_task_switch /* r3 (3) = assigner stack, r4 (4) = assignee stack */ -mp_do_user_switch: +mp_do_task_switch: lwz 0(%4), 0(%3) lwz 4(%4), 4(%3) lwz 8(%4), 8(%3) |
