diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-08-16 19:56:21 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-08-16 19:56:21 +0200 |
| commit | 1a32b9307357ac0fc9095e853b2b6d94f9fe62bb (patch) | |
| tree | f41f723659c8926e38182fbe062746d821ab487e /dev/kernel/HALKit/ARM64 | |
| parent | eb9df5eea339812513c25a8d3b2eeb03c633e7ac (diff) | |
| parent | b301047903b79560dce69085fc271a653a1eb4b6 (diff) | |
Merge pull request #55 from nekernel-org/dev
v0.0.4
Diffstat (limited to 'dev/kernel/HALKit/ARM64')
| -rw-r--r-- | dev/kernel/HALKit/ARM64/APM/APM+IO.cc | 2 | ||||
| -rw-r--r-- | dev/kernel/HALKit/ARM64/CxxAbi.cc | 87 | ||||
| -rw-r--r-- | dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc | 17 | ||||
| -rw-r--r-- | dev/kernel/HALKit/ARM64/HalKernelMain.cc | 3 | ||||
| -rw-r--r-- | dev/kernel/HALKit/ARM64/HalPagingMgr.cc | 66 | ||||
| -rw-r--r-- | dev/kernel/HALKit/ARM64/Paging.h | 6 | ||||
| -rw-r--r-- | dev/kernel/HALKit/ARM64/Processor.h | 3 |
7 files changed, 164 insertions, 20 deletions
diff --git a/dev/kernel/HALKit/ARM64/APM/APM+IO.cc b/dev/kernel/HALKit/ARM64/APM/APM+IO.cc index e58fb782..17a60515 100644 --- a/dev/kernel/HALKit/ARM64/APM/APM+IO.cc +++ b/dev/kernel/HALKit/ARM64/APM/APM+IO.cc @@ -9,7 +9,7 @@ using namespace Kernel; -/// @brief Send APM command to it's IO space. +/// @brief Send APM command to its IO space. /// @param base_dma the IO base port. /// @param cmd the command. /// @return status code. diff --git a/dev/kernel/HALKit/ARM64/CxxAbi.cc b/dev/kernel/HALKit/ARM64/CxxAbi.cc new file mode 100644 index 00000000..964fc2f4 --- /dev/null +++ b/dev/kernel/HALKit/ARM64/CxxAbi.cc @@ -0,0 +1,87 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include <KernelKit/DebugOutput.h> +#include <KernelKit/KPC.h> +#include <NeKit/CxxAbi.h> + +atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors]; + +uarch_t __atexit_func_count; + +/// @brief dynamic shared object Handle. +Kernel::UIntPtr __dso_handle; + +EXTERN_C void __chkstk(void) {} + +EXTERN_C int atexit(void (*f)(), void* arg, void* dso) { + if (__atexit_func_count >= kAtExitMacDestructors) return 1; + + __atexit_funcs[__atexit_func_count].destructor_func = f; + __atexit_funcs[__atexit_func_count].obj_ptr = arg; + __atexit_funcs[__atexit_func_count].dso_handle = dso; + + __atexit_func_count++; + + return 0; +} + +EXTERN_C void __cxa_finalize(void* f) { + uarch_t i = __atexit_func_count; + if (!f) { + while (i--) { + if (__atexit_funcs[i].destructor_func) { + (*__atexit_funcs[i].destructor_func)(); + __atexit_funcs[i].destructor_func = 0; + }; + } + + return; + } + + while (i--) { + if (__atexit_funcs[i].destructor_func) { + (*__atexit_funcs[i].destructor_func)(); + __atexit_funcs[i].destructor_func = 0; + }; + } +} + +namespace cxxabiv1 { +EXTERN_C int __cxa_guard_acquire(__guard* g) { + (void) g; + return 0; +} + +EXTERN_C int __cxa_guard_release(__guard* g) { + *(char*) g = 1; + return 0; +} + +EXTERN_C void __cxa_guard_abort(__guard* g) { + (void) g; +} +} // namespace cxxabiv1 + +EXTERN_C Kernel::Void _purecall(void* self) { + (Kernel::Void)(Kernel::kout << "object: " + << Kernel::number(reinterpret_cast<Kernel::UIntPtr>(self))); + (Kernel::Void)(Kernel::kout << ", has unimplemented virtual functions.\r"); +} + +EXTERN_C Kernel::Void _Init_thread_footer(Kernel::Int* thread_obj) { + NE_UNUSED(thread_obj); +} + +EXTERN_C Kernel::Void _Init_thread_epoch(Kernel::Void) { + NE_UNUSED(0); +} + +EXTERN_C Kernel::Void _Init_thread_header(Kernel::Int* thread_obj) { + NE_UNUSED(0); +} + +EXTERN_C Kernel::Int _tls_index = 0UL; diff --git a/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc b/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc index 61a82314..63a42de8 100644 --- a/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc +++ b/dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc @@ -11,16 +11,16 @@ #include <SignalKit/Signals.h> EXTERN_C Kernel::Void int_handle_breakpoint(Kernel::UIntPtr rip); - EXTERN_C BOOL mp_handle_gic_interrupt_el0(Void); +EXTERN_C BOOL mp_handle_gic_interrupt_el0(Void); -EXTERN_C BOOL kEndOfInterrupt; +EXTERN_C BOOL kEndOfInterrupt; EXTERN_C UInt8 kEndOfInterruptVector; STATIC BOOL kIsRunning = NO; /// @note This is managed by the system software. STATIC void hal_int_send_eoi(UInt8 vector) { - kEndOfInterrupt = YES; + kEndOfInterrupt = YES; kEndOfInterruptVector = vector; } @@ -56,8 +56,7 @@ EXTERN_C void int_handle_scheduler(Kernel::UIntPtr rsp) { hal_int_send_eoi(32); - while (kIsRunning) - ; + while (kIsRunning); kIsRunning = YES; @@ -143,10 +142,8 @@ EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_hash, /// @brief Enter Kernel call from assembly (libDDK only). /// @param stack the stack pushed from assembly routine. /// @return nothing. -EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash, - Kernel::UIntPtr rdx_kerncall_arg) { - hal_int_send_eoi(51); - +EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash, Kernel::SizeT cnt, + Kernel::UIntPtr arg, Kernel::SizeT sz) { if (!Kernel::kRootUser) return; if (Kernel::kCurrentUser != Kernel::kRootUser) return; if (!Kernel::kCurrentUser->IsSuperUser()) return; @@ -154,7 +151,7 @@ EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash, for (SizeT i = 0UL; i < kMaxDispatchCallCount; ++i) { if (kKernCalls[i].fHooked && rcx_hash == kKernCalls[rcx_hash].fHash) { if (kKernCalls[i].fProc) { - (kKernCalls[i].fProc)((Kernel::VoidPtr) rdx_kerncall_arg); + (kKernCalls[i].fProc)(cnt, (Kernel::VoidPtr) arg, sz); } } } diff --git a/dev/kernel/HALKit/ARM64/HalKernelMain.cc b/dev/kernel/HALKit/ARM64/HalKernelMain.cc index 20bd3d8a..d8e6843b 100644 --- a/dev/kernel/HALKit/ARM64/HalKernelMain.cc +++ b/dev/kernel/HALKit/ARM64/HalKernelMain.cc @@ -71,7 +71,6 @@ EXTERN_C void hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { Kernel::mp_init_cores(); - while (YES) - ; + while (YES); } #endif
\ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalPagingMgr.cc b/dev/kernel/HALKit/ARM64/HalPagingMgr.cc index faad6778..b7b0c10e 100644 --- a/dev/kernel/HALKit/ARM64/HalPagingMgr.cc +++ b/dev/kernel/HALKit/ARM64/HalPagingMgr.cc @@ -13,16 +13,74 @@ namespace Kernel::HAL { typedef UInt32 PageTableIndex; +EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virtual_address) { + if (!virtual_address) return 0; + + UInt64 ttbr0_val = 0; + + asm volatile("mrs %0, ttbr0_el1" : "=r"(ttbr0_val)); + volatile UInt64* l1_table = reinterpret_cast<volatile UInt64*>(ttbr0_val); + + UInt64 l1_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 39) & 0x1FF; + UInt64 l2_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 30) & 0x1FF; + UInt64 l3_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 21) & 0x1FF; + + if (!l1_table[l1_idx]) return 0; + + volatile UInt64* l2_table = reinterpret_cast<volatile UInt64*>(l1_table[l1_idx] & ~0xFFFUL); + + if (!l2_table[l2_idx]) return 0; + + volatile UInt64* l3_table = reinterpret_cast<volatile UInt64*>(l2_table[l2_idx] & ~0xFFFUL); + + if (!l3_table[l3_idx]) return 0; + + return (l3_table[l3_idx] & ~0xFFFUL); +} + /// @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 kErrorInvalidData; +EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags, + UInt32 level) { + if (!virtual_address || !flags || !physical_address) return kErrorInvalidData; + + UInt64 ttbr0_val = 0; + + asm volatile("mrs %0, ttbr0_el1" : "=r"(ttbr0_val)); + volatile UInt64* l1_table = reinterpret_cast<volatile UInt64*>(ttbr0_val); + + UInt64 l1_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 39) & 0x1FF; + UInt64 l2_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 30) & 0x1FF; + UInt64 l3_idx = (reinterpret_cast<UIntPtr>(virtual_address) >> 21) & 0x1FF; + + if (!l1_table[l1_idx]) return kErrorInvalidData; + + volatile UInt64* l2_table = reinterpret_cast<volatile UInt64*>(l1_table[l1_idx] & ~0xFFFUL); + + if (!l2_table[l2_idx]) return kErrorInvalidData; + + volatile UInt64* l3_table = reinterpret_cast<volatile UInt64*>(l2_table[l2_idx] & ~0xFFFUL); + + l3_table[l3_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags; - NE_UNUSED(physical_address); + switch (level) { + case 2: { + l3_table[l3_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags; + return kErrorSuccess; + } + case 1: { + l1_table[l1_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags; + return kErrorSuccess; + } + case 0: { + l1_table[l1_idx] = (reinterpret_cast<UInt64>(physical_address) & ~0xFFFUL) | flags; + return kErrorSuccess; + } + } - return kErrorSuccess; + return kErrorInvalidData; } } // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/ARM64/Paging.h b/dev/kernel/HALKit/ARM64/Paging.h index 5001871b..be9fb116 100644 --- a/dev/kernel/HALKit/ARM64/Paging.h +++ b/dev/kernel/HALKit/ARM64/Paging.h @@ -86,14 +86,16 @@ namespace Detail { PageEnable = 31, }; - inline UInt8 control_register_cast(ControlRegisterBits reg) { return static_cast<UInt8>(reg); } + 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_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page, SizeT pad = 0) -> VoidPtr; auto mm_free_bitmap(VoidPtr page_ptr) -> Bool; } // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/ARM64/Processor.h b/dev/kernel/HALKit/ARM64/Processor.h index 068b798d..68fe736c 100644 --- a/dev/kernel/HALKit/ARM64/Processor.h +++ b/dev/kernel/HALKit/ARM64/Processor.h @@ -36,7 +36,8 @@ enum { /// @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); +EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags, + UInt32 level = 2); EXTERN_C UIntPtr mm_get_page_addr(VoidPtr virtual_address); |
