diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2025-03-23 19:13:48 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2025-03-23 19:15:17 +0100 |
| commit | a13e1c0911c0627184bc38f18c7fdda64447b3ad (patch) | |
| tree | 073a62c09bf216e85a3f310376640fa1805147f9 /dev/kernel/HALKit/ARM64 | |
| parent | 149fa096eb306d03686b3b67e813cf1a78e08cd0 (diff) | |
meta(kernel): Reworked repository's filesystem structure.
Removing useless parts of the project too.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'dev/kernel/HALKit/ARM64')
18 files changed, 965 insertions, 0 deletions
diff --git a/dev/kernel/HALKit/ARM64/APM/APM+IO.cc b/dev/kernel/HALKit/ARM64/APM/APM+IO.cc new file mode 100644 index 00000000..752f29f9 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/APM/APM+IO.cc @@ -0,0 +1,37 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <modules/APM/APM.h> +#include <KernelKit/LPC.h> + +using namespace NeOS; + +/// @brief Send APM command to it's 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, =0x84000004\n" + "svc #0\n"); + + return kErrorSuccess; + } + case kAPMPowerCommandShutdown: { + asm volatile( + "ldr x0, =0x84000008\n" + "svc #0\n"); + + return kErrorSuccess; + } + default: + return kErrorInvalidData; + } +} diff --git a/dev/kernel/HALKit/ARM64/ApplicationProcessor.h b/dev/kernel/HALKit/ARM64/ApplicationProcessor.h new file mode 100644 index 00000000..d263f9b8 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/ApplicationProcessor.h @@ -0,0 +1,19 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include <NewKit/Defines.h> +#include <HALKit/ARM64/Processor.h> + +/************************************************** */ +/* INITIALIZE THE GIC ON CPU. */ +/************************************************** */ + +namespace NeOS +{ + BOOL mp_initialize_gic(NeOS::Void); +}
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc b/dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc new file mode 100644 index 00000000..a25112ae --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalACPIFactoryInterface.cc @@ -0,0 +1,32 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <modules/ACPI/ACPIFactoryInterface.h> +#include <NewKit/KString.h> +#include <ArchKit/ArchKit.h> +#include <KernelKit/MemoryMgr.h> +#include <modules/APM/APM.h> + +namespace NeOS +{ + ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr) + : fRsdp(rsp_ptr), fEntries(0) + { + } + + BOOL ACPIFactoryInterface::Shutdown() + { + apm_send_io_command(kAPMPowerCommandShutdown, 0); + return NO; + } + + /// @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 NeOS diff --git a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc new file mode 100644 index 00000000..660af502 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc @@ -0,0 +1,145 @@ +/* -------------------------------------------
+
+ Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <HALKit/ARM64/Processor.h>
+#include <KernelKit/DebugOutput.h>
+#include <HALKit/ARM64/ApplicationProcessor.h>
+#include <KernelKit/UserProcessScheduler.h>
+
+#define GICD_BASE 0x08000000 // Distributor base address
+#define GICC_BASE 0x08010000 // CPU interface base address
+
+#define GICD_CTLR 0x000 // Distributor Control Register
+#define GICD_ISENABLER 0x100 // Interrupt Set-Enable Registers
+#define GICD_ICENABLER 0x180 // Interrupt Clear-Enable Registers
+#define GICD_ISPENDR 0x200 // Interrupt Set-Pending Registers
+#define GICD_ICPENDR 0x280 // Interrupt Clear-Pending Registers
+#define GICD_IPRIORITYR 0x400 // Interrupt Priority Registers
+#define GICD_ITARGETSR 0x800 // Interrupt Processor Targets Registers
+#define GICD_ICFGR 0xC00 // Interrupt Configuration Registers
+
+#define GICC_CTLR 0x000 // CPU Interface Control Register
+#define GICC_PMR 0x004 // Interrupt Priority Mask Register
+#define GICC_IAR 0x00C // Interrupt Acknowledge Register
+#define GICC_EOIR 0x010 // End of Interrupt Register
+
+// ================================================================= //
+
+namespace NeOS
+{
+ struct PROCESS_CONTROL_BLOCK final
+ {
+ HAL::StackFramePtr mFrame;
+ };
+
+ STATIC PROCESS_CONTROL_BLOCK kProcessBlocks[kSchedProcessLimitPerTeam] = {0};
+
+ namespace Detail
+ {
+ STATIC BOOL kGICEnabled = NO;
+
+ STATIC void mp_hang_fn(void)
+ {
+ while (YES)
+ ;
+
+ dbg_break_point();
+ }
+
+ Void mp_setup_gic_el0(Void)
+ {
+ // enable distributor.
+ ke_dma_write<UInt32>(GICD_BASE, GICD_CTLR, YES);
+
+ UInt32 gicc_ctlr = ke_dma_read<UInt32>(GICC_BASE, GICC_CTLR);
+
+ const auto kEnableSignalInt = YES;
+
+ gicc_ctlr |= kEnableSignalInt; // Enable signaling of interrupts
+ gicc_ctlr |= (kEnableSignalInt << 1); // Allow Group 1 interrupts in EL0
+
+ ke_dma_write<UInt32>(GICC_BASE, GICC_CTLR, gicc_ctlr);
+
+ // Set priority mask (accept all priorities)
+ ke_dma_write<UInt32>(GICC_BASE, GICC_PMR, 0xFF);
+
+ UInt32 icfgr = ke_dma_read<UInt32>(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4);
+
+ icfgr |= (0x2 << ((32 % 16) * 2)); // Edge-triggered
+ ke_dma_write<UInt32>(GICD_BASE, GICD_ICFGR + (0x20 / 0x10) * 4, icfgr);
+
+ // Target interrupt 32 to CPU 1
+ ke_dma_write<UInt32>(GICD_BASE, GICD_ITARGETSR + (0x20 / 0x04) * 4, 0x2 << ((32 % 4) * 8));
+
+ // Set interrupt 32 priority to lowest (0xFF)
+ ke_dma_write<UInt32>(GICD_BASE, GICD_IPRIORITYR + (0x20 / 0x04) * 4, 0xFF << ((32 % 4) * 8));
+
+ // Enable interrupt 32 for AP.
+ ke_dma_write<UInt32>(GICD_BASE, GICD_ISENABLER + 4, 0x01);
+ }
+
+ BOOL mp_handle_gic_interrupt_el0(Void)
+ {
+ // Read the interrupt ID
+ UInt32 interrupt_id = ke_dma_read<UInt32>(GICC_BASE, GICC_IAR);
+
+ // Check if it's a valid interrupt (not spurious)
+ if ((interrupt_id & 0x3FF) < 1020)
+ {
+ auto interrupt = interrupt_id & 0x3FF;
+
+ const UInt16 kInterruptScheduler = 0x20;
+
+ kout << "Handling interrupt for AP: " << interrupt << kendl;
+
+ switch (interrupt)
+ {
+ case kInterruptScheduler: {
+ ke_dma_write<UInt32>(GICC_BASE, GICC_EOIR, interrupt_id);
+ UserProcessHelper::StartScheduling();
+ break;
+ }
+ default: {
+ ke_dma_write<UInt32>(GICC_BASE, GICC_EOIR, interrupt_id);
+ break;
+ }
+ }
+
+ return YES;
+ }
+
+ // spurious interrupt
+ return NO;
+ }
+ } // namespace Detail
+
+ EXTERN_C HAL::StackFramePtr mp_get_current_context(ProcessID pid)
+ {
+ return kProcessBlocks[pid % kSchedProcessLimitPerTeam].mFrame;
+ }
+
+ EXTERN_C Bool mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid)
+ {
+ MUST_PASS(stack_frame);
+
+ const auto process_index = pid % kSchedProcessLimitPerTeam;
+
+ kProcessBlocks[process_index].mFrame = stack_frame;
+
+ return YES;
+ }
+
+ BOOL mp_initialize_gic(Void)
+ {
+ if (!Detail::kGICEnabled)
+ {
+ Detail::kGICEnabled = YES;
+ Detail::mp_setup_gic_el0();
+ }
+
+ return Detail::kGICEnabled;
+ }
+} // namespace NeOS
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalDebugOutput.cc b/dev/kernel/HALKit/ARM64/HalDebugOutput.cc new file mode 100644 index 00000000..8d54739f --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalDebugOutput.cc @@ -0,0 +1,83 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <ArchKit/ArchKit.h> +#include <KernelKit/DebugOutput.h> +#include <NewKit/Utils.h> +#include <NewKit/New.h> + +namespace NeOS +{ + EXTERN_C void ke_io_write(IDeviceObject<const Char*>* self, const Char* bytes) + { +#ifdef __DEBUG__ + if (*bytes == 0) + return; + + SizeT index = 0; + SizeT len = 0; + + index = 0; + len = rt_string_len(bytes, 256U); + + 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__ + } + + TerminalDevice::~TerminalDevice() = default; + + EXTERN_C void ke_io_read(IDeviceObject<const Char*>* self, 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(NeOS::ke_io_write, NeOS::ke_io_read); + return out; + } + +} // namespace NeOS diff --git a/dev/kernel/HALKit/ARM64/HalFlushTLB.S b/dev/kernel/HALKit/ARM64/HalFlushTLB.S new file mode 100644 index 00000000..8fcf40ff --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalFlushTLB.S @@ -0,0 +1,5 @@ +.text + +hal_flush_tlb: + tlbi + ret diff --git a/dev/kernel/HALKit/ARM64/HalKernelMain.cc b/dev/kernel/HALKit/ARM64/HalKernelMain.cc new file mode 100644 index 00000000..55caca94 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalKernelMain.cc @@ -0,0 +1,54 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <ArchKit/ArchKit.h> +#include <modules/CoreGfx/FBMgr.h> +#include <FirmwareKit/Handover.h> +#include <KernelKit/FileMgr.h> +#include <KernelKit/MemoryMgr.h> +#include <KernelKit/PEFCodeMgr.h> +#include <KernelKit/UserProcessScheduler.h> +#include <NewKit/Json.h> +#include <KernelKit/CodeMgr.h> +#include <modules/ACPI/ACPIFactoryInterface.h> +#include <NetworkKit/IPC.h> +#include <HALKit/ARM64/Processor.h> +#include <CFKit/Property.h> + +#include <HALKit/ARM64/ApplicationProcessor.h> + +EXTERN_C void hal_init_platform( + NeOS::HEL::BootInfoHeader* handover_hdr) +{ + + /************************************************** */ + /* INITIALIZE AND VALIDATE HEADER. */ + /************************************************** */ + + kHandoverHeader = handover_hdr; + + if (kHandoverHeader->f_Magic != kHandoverMagic && + kHandoverHeader->f_Version != kHandoverVersion) + { + return; + } + + /************************************** */ + /* INITIALIZE BIT MAP. */ + /************************************** */ + + kKernelBitMpSize = kHandoverHeader->f_BitMapSize; + kKernelBitMpStart = reinterpret_cast<NeOS::VoidPtr>( + reinterpret_cast<NeOS::UIntPtr>(kHandoverHeader->f_BitMapStart)); + + /// @note do initialize the interrupts after it. + + NeOS::mp_initialize_gic(); + + while (YES) + { + } +} diff --git a/dev/kernel/HALKit/ARM64/HalKernelPanic.cc b/dev/kernel/HALKit/ARM64/HalKernelPanic.cc new file mode 100644 index 00000000..5037f440 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalKernelPanic.cc @@ -0,0 +1,80 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <NewKit/KernelPanic.h> +#include <ArchKit/ArchKit.h> +#include <KernelKit/Timer.h> +#include <KernelKit/DebugOutput.h> +#include <NewKit/KString.h> +#include <FirmwareKit/Handover.h> +#include <KernelKit/FileMgr.h> +#include <modules/CoreGfx/FBMgr.h> +#include <modules/CoreGfx/TextMgr.h> +#include <NewKit/Utils.h> + +/* Each error code is attributed with an ID, which will prompt a string onto the + * screen. Wait for debugger... */ + +namespace NeOS +{ + /// @brief Dumping factory class. + class RecoveryFactory final + { + public: + STATIC Void Recover() noexcept; + }; + + /***********************************************************************************/ + /// @brief Stops execution of the kernel. + /// @param id kernel stop ID. + /***********************************************************************************/ + Void ke_panic(const NeOS::Int32& id, const Char* message) + { + fb_init(); + + auto panic_text = RGB(0xff, 0xff, 0xff); + + auto y = 10; + auto x = 10; + + Char* message_apicid = new Char[128]; + rt_set_memory(message_apicid, 0, 128); + + rt_copy_memory((VoidPtr) "panic id: ", message_apicid, rt_string_len("panic id: ")); + rt_to_string(message_apicid + rt_string_len("panic id: "), (UIntPtr)id, 10); + + fb_render_string(message_apicid, y, x, panic_text); + + y += 10; + + fb_render_string((message ? message : "message: panic raised, going nowhere after this!"), y, x, panic_text); + + y += 10; + + fb_clear(); + + RecoveryFactory::Recover(); + } + + Void RecoveryFactory::Recover() noexcept + { + while (YES) + { + HAL::rt_halt(); + } + } + + void ke_runtime_check(bool expr, const Char* file, const Char* line) + { + if (!expr) + { + kout << "FAILED: FILE: " << file << kendl; + kout << "FAILED: LINE: " << line << kendl; + + ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed + } + } +} // namespace NeOS diff --git a/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc b/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc new file mode 100644 index 00000000..4ec45b51 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalPagingMgrARM64.cc @@ -0,0 +1,86 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + + File: HalPagingMgr.cc + Purpose: Platform Paging Manager. + +------------------------------------------- */ + +#include <HALKit/ARM64/Paging.h> +#include <HALKit/ARM64/Processor.h> + +namespace NeOS::HAL +{ + typedef UInt32 PageTableIndex; + + /// \brief Page store type. + struct NE_PAGE_STORE final + { + struct + { + PDE* fPde{nullptr}; + PTE* fPte{nullptr}; + VoidPtr fVAddr{nullptr}; + } fInternalStore; + + Bool fStoreOp{No}; // Store operation in progress. + + static NE_PAGE_STORE& The() + { + static NE_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, VoidPtr physical_address, UInt32 flags) + { + if (!virtual_address || + !flags) + return 0; + + NE_PAGE_STORE& page_store = NE_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) + { + NE_PAGE_STORE& page_store = NE_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 NeOS::HAL diff --git a/dev/kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc b/dev/kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc new file mode 100644 index 00000000..55c8aab5 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc @@ -0,0 +1,24 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <KernelKit/UserProcessScheduler.h> + +namespace NeOS +{ + /// @brief Wakes up thread. + /// Wakes up thread from the hang state. + Void mp_wakeup_thread(HAL::StackFrame* stack) + { + NE_UNUSED(stack); + } + + /// @brief makes the thread sleep on a loop. + /// hooks and hangs thread to prevent code from executing. + Void mp_hang_thread(HAL::StackFrame* stack) + { + NE_UNUSED(stack); + } +} // namespace NeOS diff --git a/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc b/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc new file mode 100644 index 00000000..3a9b7074 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc @@ -0,0 +1,35 @@ +/* -------------------------------------------
+
+ Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <HALKit/ARM64/Processor.h>
+#include <KernelKit/UserProcessScheduler.h>
+
+namespace NeOS
+{
+ /***********************************************************************************/
+ /// @brief Unimplemented function (crashes by default)
+ /// @param void
+ /***********************************************************************************/
+
+ EXTERN_C Void __zka_pure_call(UserProcess* process)
+ {
+ if (process)
+ process->Crash();
+ }
+
+ /***********************************************************************************/
+ /// @brief Validate user stack.
+ /// @param stack_ptr the frame pointer.
+ /***********************************************************************************/
+
+ EXTERN_C Bool hal_check_stack(HAL::StackFramePtr stack_ptr)
+ {
+ if (!stack_ptr)
+ return No;
+
+ return stack_ptr->SP != 0 && stack_ptr->BP != 0;
+ }
+} // namespace NeOS
diff --git a/dev/kernel/HALKit/ARM64/HalTimerARM64.cc b/dev/kernel/HALKit/ARM64/HalTimerARM64.cc new file mode 100644 index 00000000..785d2d5c --- /dev/null +++ b/dev/kernel/HALKit/ARM64/HalTimerARM64.cc @@ -0,0 +1,14 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + + File: HalTimer.cc + Purpose: HAL timer + + Revision History: + + 07/07/24: Added file (amlel) + +------------------------------------------- */ + +#include <ArchKit/ArchKit.h> diff --git a/dev/kernel/HALKit/ARM64/MBCI/MBCI.cc b/dev/kernel/HALKit/ARM64/MBCI/MBCI.cc new file mode 100644 index 00000000..d2df66e6 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/MBCI/MBCI.cc @@ -0,0 +1,7 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <modules/MBCI/MBCI.h>
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/Paging.h b/dev/kernel/HALKit/ARM64/Paging.h new file mode 100644 index 00000000..3c24f757 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/Paging.h @@ -0,0 +1,120 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#pragma once + +/** --------------------------------------------------- + + * THIS FILE CONTAINS CODE FOR ARMV8 PAGING. + +------------------------------------------------------- */ + +#include <NewKit/Defines.h> + +#ifndef kPageMax +#define kPageMax (0x200) +#endif //! kPageMax + +#ifndef kPageAlign +#define kPageAlign (0x1000) +#endif //! kPageAlign + +#ifndef kPageSize +#define kPageSize (0x1000) +#endif // !kPageSize + +//! short format address range + +#define c16KBPage 0b000 +#define c8KBPage 0b001 +#define c4KBPage 0b010 +#define c2KBPage 0b011 +#define c1KBPage 0b100 +#define c512BPage 0b101 +#define c256BPage 0b110 +#define c128BPage 0b111 + +/// Long format address range + +#define cPageMAll \ + { \ + 0b000, 0b000 \ + } +#define cPageMToMax(M) \ + { \ + M, 0b000 \ + } +#define cPageMaxToM(M) \ + { \ + 0b000, M \ + } +#define cPageMToN(M, N) \ + { \ + M, N \ + } + +namespace NeOS::HAL +{ + struct PACKED PTE_4KB final + { + UInt64 Valid : 1; + UInt64 Table : 1; + UInt64 AttrIndex : 3; + UInt64 NS : 1; + UInt64 AP : 2; + UInt64 SH : 2; + UInt64 AF : 1; + UInt64 NG : 1; + UInt64 Reserved1 : 1; + UInt64 Contiguous : 1; + UInt64 Dirty : 1; + UInt64 Reserved : 2; + UInt64 PhysicalAddress : 36; + UInt64 Reserved3 : 4; + UInt64 PXN : 1; + UInt64 XN : 1; + UInt64 Reserved4 : 9; + }; + + namespace Detail + { + enum class ControlRegisterBits + { + ProtectedModeEnable = 0, + MonitorCoProcessor = 1, + Emulation = 2, + TaskSwitched = 3, + ExtensionType = 4, + NumericError = 5, + WriteProtect = 16, + AlignementMask = 18, + NotWriteThrough = 29, + CacheDisable = 30, + PageEnable = 31, + }; + + inline UInt8 control_register_cast(ControlRegisterBits reg) + { + return static_cast<UInt8>(reg); + } + } // namespace Detail + + struct PDE_4KB final + { + PTE_4KB ALIGN(kPageAlign) fEntries[kPageMax]; + }; + + auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr; + auto mm_free_bitmap(VoidPtr page_ptr) -> Bool; +} // namespace NeOS::HAL + +namespace NeOS +{ + typedef HAL::PTE_4KB PTE; + typedef HAL::PDE_4KB PDE; +} // namespace NeOS + +EXTERN_C void hal_flush_tlb(); diff --git a/dev/kernel/HALKit/ARM64/Processor.h b/dev/kernel/HALKit/ARM64/Processor.h new file mode 100644 index 00000000..940cfbe9 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/Processor.h @@ -0,0 +1,91 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include <NewKit/Array.h> +#include <NewKit/Defines.h> +#include <NewKit/Utils.h> +#include <FirmwareKit/Handover.h> + +#define kCPUBackendName "ARMv8" + +namespace NeOS::HAL +{ + struct PACKED Register64 final + { + UShort Limit; + UIntPtr Base; + }; + + /// @brief Memory Manager mapping flags. + enum + { + kMMFlagsPresent = 1 << 0, + kMMFlagsWr = 1 << 1, + kMMFlagsUser = 1 << 2, + kMMFlagsNX = 1 << 3, + kMMFlagsCount = 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 virtual_address, VoidPtr physical_address, UInt32 flags); + + typedef UIntPtr Reg; + typedef Register64 Register; + + /// @note let's keep the same name as AMD64 HAL. + struct PACKED StackFrame final + { + Reg R8{0}; + Reg R9{0}; + Reg R10{0}; + Reg R11{0}; + Reg R12{0}; + Reg R13{0}; + Reg R14{0}; + Reg R15{0}; + Reg SP{0}; + Reg BP{0}; + }; + + typedef StackFrame* StackFramePtr; + + inline Void rt_halt() noexcept + { + while (Yes) + { + } + } + + template <typename DataKind> + inline void hal_dma_write(UIntPtr address, DataKind value) + { + *reinterpret_cast<volatile DataKind*>(address) = value; + } + + template <typename DataKind> + inline DataKind hal_dma_read(UIntPtr address) + { + return *reinterpret_cast<volatile DataKind*>(address); + } + + inline Void hal_wfi(Void) + { + asm volatile("wfi"); + } +} // namespace NeOS::HAL + +inline NeOS::VoidPtr kKernelBitMpStart = nullptr; +inline NeOS::UIntPtr kKernelBitMpSize = 0UL; + +inline NeOS::VoidPtr kKernelPhysicalStart = nullptr; + +#include <HALKit/ARM64/Paging.h> diff --git a/dev/kernel/HALKit/ARM64/ReadMe.md b/dev/kernel/HALKit/ARM64/ReadMe.md new file mode 100644 index 00000000..c51229f2 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/ReadMe.md @@ -0,0 +1,3 @@ +# ARM64 Hardware Abstraction Layer + +- Supported Firmware: CoreBoot/EDK/OpenMobileBoot diff --git a/dev/kernel/HALKit/ARM64/Storage/MBCI+Flash+IO+Generic.cc b/dev/kernel/HALKit/ARM64/Storage/MBCI+Flash+IO+Generic.cc new file mode 100644 index 00000000..94d20878 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/Storage/MBCI+Flash+IO+Generic.cc @@ -0,0 +1,119 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +#ifdef NE_USE_MBCI_FLASH + +#include <NewKit/Defines.h> +#include <ArchKit/ArchKit.h> +#include <modules/MFlash/MFlash.h> +#include <modules/MBCI/MBCI.h> + +/// @file MBCI+Flash.cc +/// @brief MBCI Flash support. + +#define MBCI_MAX_SLOTS (8U) + +namespace NeOS +{ + /// /Mount/Flash/n + constexpr auto kFlashBridgeMagic = 0x70768372; + constexpr auto kFlashBridgeRevision = 1; + + STATIC BOOL kFlashEnabled = NO; + STATIC SizeT kFlashSize[MBCI_MAX_SLOTS] = {}; + STATIC SizeT kFlashSectorSz[MBCI_MAX_SLOTS] = {}; + STATIC IMBCIHost* kFlashMetaPackets[MBCI_MAX_SLOTS] = {}; + STATIC IMBCIHost* kFlashDataPackets[MBCI_MAX_SLOTS] = {}; + + STATIC Void drv_std_io(Int32 slot, UInt64 lba, Char* buf, SizeT sector_sz, SizeT buf_sz); + + /// @brief Enable flash memory builtin. + STATIC Void drv_enable_flash(Int32 slot); + + /// @brief Disable flash memory builtin. + STATIC Void drv_disable_flash(Int32 slot); + + /// @brief get slot sector count. + /// @return slot sector count. + SizeT drv_get_sector_count(Int32 slot) + { + if (slot > MBCI_MAX_SLOTS) + return 0; + + return kFlashSectorSz[slot]; + } + + /// @brief get slot full size (in bytes). + /// @return drive slot size + SizeT drv_get_size(Int32 slot) + { + if (slot > MBCI_MAX_SLOTS) + return 0; + + return kFlashSize[slot]; + } + + /// @brief Enable flash memory at slot. + BOOL drv_enable_at(Int32 slot) + { + if (slot > MBCI_MAX_SLOTS) + return NO; + + kFlashMetaPackets[slot]->InterruptEnable = YES; + + kout << "Enabled hardware slot at: " << number(slot) << kendl; + + return YES; + } + + /// @brief Disable flash memory at slot. + BOOL drv_disable_at(Int32 slot) + { + if (slot > MBCI_MAX_SLOTS) + return NO; + + kFlashMetaPackets[slot]->InterruptEnable = NO; + + kout << "Disabled hardware slot at: " << number(slot) << kendl; + + return YES; + } + + STATIC Void drv_std_io(Int32 slot, UInt64 lba, Char* buf, SizeT sector_sz, SizeT buf_sz) + { + UInt64* packet_frame = (UInt64*)kFlashDataPackets[slot]->BaseAddressRegister; + + if (packet_frame[0] != (UInt64)kFlashBridgeMagic) + return; + + if (packet_frame[8] != (UInt64)kFlashBridgeRevision) + return; + + packet_frame[16 + 0] = lba; + packet_frame[16 + 4] = sector_sz; + packet_frame[16 + 8] = lba; + packet_frame[16 + 12] = buf_sz; + packet_frame[16 + 14] = (UIntPtr)HAL::hal_get_phys_address(buf); + + while (packet_frame[0] == lba) + ; + } + + Void drv_std_read(Int32 slot, UInt64 lba, Char* buf, SizeT sector_sz, SizeT buf_sz) + { + rt_set_memory(buf, 0, buf_sz); + + drv_std_io(slot, lba, buf, sector_sz, buf_sz); + } + + Void drv_std_write(Int32 slot, UInt64 lba, Char* buf, SizeT sector_sz, SizeT buf_sz) + { + drv_std_io(slot, lba, buf, sector_sz, buf_sz); + } + +} // namespace NeOS + +#endif // if NE_USE_MBCI_FLASH diff --git a/dev/kernel/HALKit/ARM64/Storage/UFS+Generic.cc b/dev/kernel/HALKit/ARM64/Storage/UFS+Generic.cc new file mode 100644 index 00000000..20d06671 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/Storage/UFS+Generic.cc @@ -0,0 +1,11 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +/// @file UFS.cc +/// @brief UFS Flash Memory support. + +#define UFS_PCI_VENDOR_ID (0x01001) /* AKER */ +#define UFS_PCI_DEVICE_ID (0xAEAEA) /* AKER */
\ No newline at end of file |
