summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/HALKit
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-08-16 19:56:21 +0200
committerGitHub <noreply@github.com>2025-08-16 19:56:21 +0200
commit1a32b9307357ac0fc9095e853b2b6d94f9fe62bb (patch)
treef41f723659c8926e38182fbe062746d821ab487e /dev/kernel/HALKit
parenteb9df5eea339812513c25a8d3b2eeb03c633e7ac (diff)
parentb301047903b79560dce69085fc271a653a1eb4b6 (diff)
Merge pull request #55 from nekernel-org/dev
v0.0.4
Diffstat (limited to 'dev/kernel/HALKit')
-rw-r--r--dev/kernel/HALKit/AMD64/CxxAbi.cc78
-rw-r--r--dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc38
-rw-r--r--dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc9
-rw-r--r--dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc9
-rw-r--r--dev/kernel/HALKit/AMD64/HalKernelMain.cc10
-rw-r--r--dev/kernel/HALKit/AMD64/HalPagingMgr.cc5
-rw-r--r--dev/kernel/HALKit/AMD64/HalTimer.cc18
-rw-r--r--dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc37
-rw-r--r--dev/kernel/HALKit/AMD64/Paging.h4
-rw-r--r--dev/kernel/HALKit/AMD64/Processor.h4
-rw-r--r--dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc23
-rw-r--r--dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc10
-rw-r--r--dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc13
-rw-r--r--dev/kernel/HALKit/ARM64/APM/APM+IO.cc2
-rw-r--r--dev/kernel/HALKit/ARM64/CxxAbi.cc87
-rw-r--r--dev/kernel/HALKit/ARM64/HalCoreInterruptHandler.cc17
-rw-r--r--dev/kernel/HALKit/ARM64/HalKernelMain.cc3
-rw-r--r--dev/kernel/HALKit/ARM64/HalPagingMgr.cc66
-rw-r--r--dev/kernel/HALKit/ARM64/Paging.h6
-rw-r--r--dev/kernel/HALKit/ARM64/Processor.h3
-rw-r--r--dev/kernel/HALKit/POWER/HalApplicationProcessor.cc3
-rw-r--r--dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc3
22 files changed, 346 insertions, 102 deletions
diff --git a/dev/kernel/HALKit/AMD64/CxxAbi.cc b/dev/kernel/HALKit/AMD64/CxxAbi.cc
new file mode 100644
index 00000000..cd135abc
--- /dev/null
+++ b/dev/kernel/HALKit/AMD64/CxxAbi.cc
@@ -0,0 +1,78 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/KPC.h>
+#include <KernelKit/UserProcessScheduler.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 Kernel::Void __cxa_pure_virtual(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 void ___chkstk_ms(PtrDiff frame_size) {
+ char* sp;
+ asm volatile("mov %%rsp, %0" : "=r"(sp));
+
+ for (PtrDiff offset = kPageSize; offset < frame_size; offset += kPageSize) {
+ sp[-offset] = 0;
+ }
+}
+
+EXTERN_C int atexit(void (*f)()) {
+ if (__atexit_func_count >= kAtExitMacDestructors) return 1;
+
+ __atexit_funcs[__atexit_func_count].destructor_func = f;
+
+ __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)();
+ };
+ }
+
+ 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
diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
index aeaeff52..64f146f3 100644
--- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
+++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
@@ -32,10 +32,9 @@
#include <modules/ACPI/ACPIFactoryInterface.h>
#include <modules/CoreGfx/TextGfx.h>
-/// @note: _hal_switch_context is internal
-
///////////////////////////////////////////////////////////////////////////////////////
+/// @note: _hal_switch_context is internal.
/// @brief The **HAL** namespace.
///////////////////////////////////////////////////////////////////////////////////////
@@ -45,15 +44,15 @@ struct HAL_APIC_MADT;
struct HAL_HARDWARE_THREAD;
struct HAL_HARDWARE_THREAD final {
- HAL::StackFramePtr mFramePtr;
- ProcessID mThreadID{0};
+ StackFramePtr mFramePtr;
+ ProcessID mThreadID{0};
};
-EXTERN_C Void sched_jump_to_task(HAL::StackFramePtr stack_frame);
+EXTERN_C Void sched_jump_to_task(StackFramePtr stack_frame);
-STATIC HAL_APIC_MADT* kMADTBlock = nullptr;
-STATIC Bool kSMPAware = false;
-STATIC Int64 kSMPCount = 0;
+STATIC HAL_APIC_MADT* kSMPBlock = nullptr;
+STATIC Bool kSMPAware = false;
+STATIC Int64 kSMPCount = 0;
EXTERN_C UIntPtr kApicBaseAddress;
@@ -70,6 +69,7 @@ struct HAL_APIC_MADT final SDT_OBJECT {
UInt8 List[1]; // Records List
};
+/// @brief Local APIC Descriptor Table.
struct LAPIC final {
UInt8 Type;
UInt8 Length;
@@ -113,17 +113,19 @@ EXTERN_C HAL::StackFramePtr mp_get_current_task(ThreadID thrdid) {
/***********************************************************************************/
EXTERN_C BOOL mp_register_task(HAL::StackFramePtr stack_frame, ThreadID thrdid) {
- if (thrdid > kSMPCount) return NO;
if (!stack_frame) return NO;
- kHWThread[thrdid].mFramePtr = stack_frame;
-
- HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO);
+ if (thrdid > kSMPCount) return NO;
if (!kSMPAware) {
sched_jump_to_task(kHWThread[thrdid].mFramePtr);
+
+ return YES;
}
+ HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO);
+ kHWThread[thrdid].mFramePtr = stack_frame;
+
return YES;
}
@@ -158,11 +160,11 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept {
return;
}
- kRawMADT = pwr.Leak().Leak();
- kMADTBlock = reinterpret_cast<HAL_APIC_MADT*>(kRawMADT);
- kSMPAware = NO;
+ kRawMADT = pwr.Leak().Leak();
+ kSMPBlock = reinterpret_cast<HAL_APIC_MADT*>(kRawMADT);
+ kSMPAware = NO;
- if (kMADTBlock) {
+ if (kSMPBlock) {
kSMPInterrupt = 0;
kSMPCount = 0;
@@ -189,8 +191,8 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept {
controller.Write(LAPIC_REG_TIMER_LVT, 0x20 | (1 << 17));
controller.Write(LAPIC_REG_TIMER_INITCNT, 1000000);
- volatile UInt8* entry_ptr = reinterpret_cast<volatile UInt8*>(kMADTBlock->List);
- volatile UInt8* end_ptr = ((UInt8*) kMADTBlock) + kMADTBlock->Length;
+ volatile UInt8* entry_ptr = reinterpret_cast<volatile UInt8*>(kSMPBlock->List);
+ volatile UInt8* end_ptr = ((UInt8*) kSMPBlock) + kSMPBlock->Length;
while (entry_ptr < end_ptr) {
UInt8 type = *entry_ptr;
diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc
index be6d0af5..0c2d0960 100644
--- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc
+++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandler.cc
@@ -61,8 +61,7 @@ EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) {
hal_idt_send_eoi(32);
- while (kIsRunning)
- ;
+ while (kIsRunning);
kIsRunning = YES;
@@ -148,8 +147,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) {
+EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_hash, Kernel::SizeT cnt,
+ Kernel::UIntPtr arg, Kernel::SizeT sz) {
hal_idt_send_eoi(51);
if (!Kernel::kRootUser) return;
@@ -159,7 +158,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/AMD64/HalDescriptorLoader.cc b/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc
index f9749946..56d46a15 100644
--- a/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc
+++ b/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc
@@ -30,10 +30,11 @@ Void IDTLoader::Load(Register64& idt) {
volatile UIntPtr** ptr_ivt = (volatile UIntPtr**) idt.Base;
for (SizeT idt_indx = 0; idt_indx < kKernelIdtSize; ++idt_indx) {
- Detail::kInterruptVectorTable[idt_indx].Selector = kIDTSelector;
- Detail::kInterruptVectorTable[idt_indx].Ist = 0;
- Detail::kInterruptVectorTable[idt_indx].TypeAttributes = kInterruptGate;
- Detail::kInterruptVectorTable[idt_indx].OffsetLow = ((UIntPtr) ptr_ivt[idt_indx] & 0xFFFF);
+ Detail::kInterruptVectorTable[idt_indx].Selector = kIDTSelector;
+ Detail::kInterruptVectorTable[idt_indx].Ist = 0;
+ Detail::kInterruptVectorTable[idt_indx].TypeAttributes =
+ kKernelInterruptId ? kUserInterruptGate : kInterruptGate;
+ Detail::kInterruptVectorTable[idt_indx].OffsetLow = ((UIntPtr) ptr_ivt[idt_indx] & 0xFFFF);
Detail::kInterruptVectorTable[idt_indx].OffsetMid =
(((UIntPtr) ptr_ivt[idt_indx] >> 16) & 0xFFFF);
Detail::kInterruptVectorTable[idt_indx].OffsetHigh =
diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc
index 446a1e85..c7a87b13 100644
--- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc
+++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc
@@ -14,7 +14,7 @@
#include <KernelKit/Timer.h>
#include <NetworkKit/IPC.h>
#include <StorageKit/AHCI.h>
-#include <generic_kits/BenchKit/X64Chrono.h>
+#include <misc/BenchKit/X64Chrono.h>
#include <modules/ACPI/ACPIFactoryInterface.h>
#include <modules/CoreGfx/TextGfx.h>
@@ -43,6 +43,11 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) {
kKernelVM = kHandoverHeader->f_PageStart;
+ if (!kKernelVM) {
+ MUST_PASS(kKernelVM);
+ return kEfiFail;
+ }
+
hal_write_cr3(kKernelVM);
/************************************** */
@@ -163,7 +168,6 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept {
idt_loader.Load(idt_reg);
- while (YES)
- ;
+ while (YES);
}
#endif // ifndef __NE_MODULAR_KERNEL_COMPONENTS__
diff --git a/dev/kernel/HALKit/AMD64/HalPagingMgr.cc b/dev/kernel/HALKit/AMD64/HalPagingMgr.cc
index 048cb7c2..ced4f268 100644
--- a/dev/kernel/HALKit/AMD64/HalPagingMgr.cc
+++ b/dev/kernel/HALKit/AMD64/HalPagingMgr.cc
@@ -117,9 +117,12 @@ EXTERN_C Int32 mm_memory_fence(VoidPtr virtual_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) {
+EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, VoidPtr physical_address, UInt32 flags,
+ UInt32 level) {
if (physical_address == 0) return kErrorInvalidData;
+ NE_UNUSED(level); /// @todo support PML4, and PDPT levels.
+
const UInt64 kVMAddr = (UInt64) virtual_address;
constexpr UInt64 kMask9 = 0x1FF;
constexpr UInt64 kPageMask = 0xFFF;
diff --git a/dev/kernel/HALKit/AMD64/HalTimer.cc b/dev/kernel/HALKit/AMD64/HalTimer.cc
index 13573880..22876a96 100644
--- a/dev/kernel/HALKit/AMD64/HalTimer.cc
+++ b/dev/kernel/HALKit/AMD64/HalTimer.cc
@@ -61,11 +61,8 @@ HardwareTimer::HardwareTimer(UInt64 ms) : fWaitFor(ms) {
// if not enabled yet.
if (!(*((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) & (1 << 0))) {
*((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) =
- *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) |
- (1 << 0); // enable timer
- *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) =
- *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) |
- (1 << 3); // one shot conf
+ *((volatile UInt64*) ((UInt8*) fDigitalTimer + kHPETConfigRegValue)) | (1 << 0) |
+ (1 << 3); // enable timer & one shot conf
}
}
@@ -80,18 +77,21 @@ HardwareTimer::~HardwareTimer() {
BOOL HardwareTimer::Wait() noexcept {
if (fWaitFor < 1) return NO;
+ if (fWaitFor > 1'000'000) return NO; // max 1000s = 16 minutes
- UInt64 hpet_cap = *((volatile UInt64*) (fDigitalTimer + kHPETCounterRegValue));
+ UInt64 hpet_cap = *((volatile UInt64*) (fDigitalTimer));
UInt64 femtoseconds_per_tick = (hpet_cap >> 32);
if (femtoseconds_per_tick == 0) return NO;
volatile UInt64* timer = (volatile UInt64*) (fDigitalTimer + kHPETCounterRegValue);
- UInt64 now = *timer;
- UInt64 prev = now + (fWaitFor / femtoseconds_per_tick);
+ UInt64 now = *timer;
+
+ UInt64 fs_wait = fWaitFor * 1'000'000'000'000ULL;
+ UInt64 stop_at = now + (fs_wait / femtoseconds_per_tick);
- while (*timer < (prev)) asm volatile("pause");
+ while (*timer < (stop_at)) asm volatile("pause");
return YES;
}
diff --git a/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc b/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc
index 3ccbfa24..be27915a 100644
--- a/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc
+++ b/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc
@@ -13,10 +13,9 @@ using namespace Kernel::HAL;
STATIC UInt16 kRTLIOBase = 0xFFFF;
-STATIC BOOL kTXEnabled = NO;
-
-STATIC UInt32 kRXOffset = 0UL;
+STATIC BOOL kTXRXEnabled = NO;
+STATIC UInt32 kRXOffset = 0UL;
STATIC constexpr CONST UInt32 kRXBufferSize = 8192 + 16 + 1500;
STATIC UInt8* kRXUpperLayer = nullptr;
@@ -26,8 +25,8 @@ STATIC UInt8* kRXBuffer = nullptr;
///@brief RTL8139 Init routine.
/***********************************************************************************/
-EXTERN_C Void rtl_init_nic_rtl8139(UInt16 io_base) noexcept {
- if (kTXEnabled) return;
+EXTERN_C BOOL rtl_init_nic_rtl8139(UInt16 io_base) noexcept {
+ if (kTXRXEnabled) return NO;
kRTLIOBase = io_base;
@@ -49,8 +48,7 @@ EXTERN_C Void rtl_init_nic_rtl8139(UInt16 io_base) noexcept {
}
if (timeout <= 0x1000) {
- ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "RTL8139: Reset failed");
- return;
+ return NO;
}
rt_out32(io_base + 0x30, (UInt32) (UIntPtr) kRXBuffer);
@@ -61,16 +59,21 @@ EXTERN_C Void rtl_init_nic_rtl8139(UInt16 io_base) noexcept {
rt_out16(io_base + 0x3C, 0x0005);
- kTXEnabled = YES;
+ kTXRXEnabled = YES;
+
+ return YES;
}
/***********************************************************************************/
/// @brief RTL8139 I/O interrupt handler.
+/// @param rsp stack pointer.
/// @note This function is called when the device interrupts to retrieve network data.
/***********************************************************************************/
-EXTERN_C void rtl_rtl8139_interrupt_handler() {
- if (kRTLIOBase == 0xFFFF) return;
+EXTERN_C Void rtl_rtl8139_interrupt_handler(UIntPtr rsp) {
+ if (kRTLIOBase == 0xFFFF || kRTLIOBase == 0) return;
+
+ NE_UNUSED(rsp);
UInt16 status = rt_in16(kRTLIOBase + 0x3E);
rt_out16(kRTLIOBase + 0x3E, status);
@@ -111,4 +114,16 @@ EXTERN_C void rtl_rtl8139_interrupt_handler() {
EXTERN_C UInt8* rtl_rtl8139_get_upper_layer() {
return kRXUpperLayer;
-} \ No newline at end of file
+}
+
+/***********************************************************************************/
+/// @brief RTL8139 set upper layer function
+/// @param layer the upper layer.
+/***********************************************************************************/
+
+EXTERN_C BOOL rtl_rtl8139_set_upper_layer(UInt8* layer) {
+ if (!layer) return NO;
+ kRXUpperLayer = layer;
+
+ return YES;
+}
diff --git a/dev/kernel/HALKit/AMD64/Paging.h b/dev/kernel/HALKit/AMD64/Paging.h
index 079acde4..cf297632 100644
--- a/dev/kernel/HALKit/AMD64/Paging.h
+++ b/dev/kernel/HALKit/AMD64/Paging.h
@@ -57,7 +57,9 @@ 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
auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page, SizeT pad = 0) -> VoidPtr;
diff --git a/dev/kernel/HALKit/AMD64/Processor.h b/dev/kernel/HALKit/AMD64/Processor.h
index 80dc7a1d..99f857b1 100644
--- a/dev/kernel/HALKit/AMD64/Processor.h
+++ b/dev/kernel/HALKit/AMD64/Processor.h
@@ -47,6 +47,7 @@
#define IsLevelTriggered(FLG) (FLG & 8)
#define kInterruptGate (0x8E)
+#define kUserInterruptGate (0xEE)
#define kTrapGate (0xEF)
#define kTaskGate (0b10001100)
#define kIDTSelector (0x08)
@@ -245,7 +246,8 @@ class LAPICDmaWrapper final {
/// @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 UInt8 rt_in8(UInt16 port);
EXTERN_C UInt16 rt_in16(UInt16 port);
diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
index cd41480a..3363e809 100644
--- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
+++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
@@ -136,7 +136,7 @@ template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify>
STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz,
SizeT size_buffer) noexcept {
if (sector_sz == 0) {
- kout << "Invalid sector size.\r";
+ kout << "ahci: Invalid sector size.\r";
err_global_get() = kErrorDisk;
return;
}
@@ -144,7 +144,7 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz
lba /= sector_sz;
if (!buffer || size_buffer == 0) {
- kout << "Invalid buffer for AHCI I/O.\r";
+ kout << "ahci: Invalid buffer for AHCI I/O.\r";
err_global_get() = kErrorDisk;
return;
}
@@ -157,7 +157,7 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz
while (slot == ~0UL) {
if (timeout > kTimeout) {
- kout << "No free command slot found, AHCI disk is busy!\r";
+ kout << "ahci: No free command slot found, AHCI disk is busy!\r";
err_global_get() = kErrorDisk;
return;
@@ -217,7 +217,7 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz
command_table->Prdt[prdt_index - 1].Ie = YES;
if (bytes_remaining > 0) {
- kout << "Warning: AHCI PRDT overflow, cannot map full buffer.\r";
+ kout << "ahci: AHCI PRDT overflow, cannot map full buffer.\r";
err_global_get() = kErrorDisk;
rtl_dma_free(size_buffer);
@@ -262,7 +262,7 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz
while (YES) {
if (timeout > kTimeout) {
- kout << "Disk hangup!\r";
+ kout << "ahci: disk-hangup, corrupted-disk.\r";
err_global_get() = kErrorDiskIsCorrupted;
rtl_dma_free(size_buffer);
@@ -277,7 +277,7 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz
rtl_dma_flush(ptr, size_buffer);
if (kSATAHba->Is & kSATAErrTaskFile) {
- kout << "AHCI Task File Error during I/O.\r";
+ kout << "ahci: Task File Error during I/O.\r";
rtl_dma_free(size_buffer);
err_global_get() = kErrorDiskIsCorrupted;
@@ -293,9 +293,8 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz
if ((kSATAHba->Ports[kSATAIndex].Tfd & (kSATASRBsy | kSATASRDrq)) == 0) {
goto ahci_io_end;
} else {
- kout << "Warning: Disk still busy after command completion!\r";
- while (kSATAHba->Ports[kSATAIndex].Tfd & (kSATASRBsy | kSATASRDrq))
- ;
+ kout << "ahci: Disk still busy after command completion!\r";
+ while (kSATAHba->Ports[kSATAIndex].Tfd & (kSATASRBsy | kSATASRDrq));
}
ahci_io_end:
@@ -308,13 +307,15 @@ STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz
@brief Gets the number of sectors inside the drive.
@return Sector size in bytes.
*/
-STATIC ATTRIBUTE(unused) SizeT drv_get_sector_count_ahci() {
+STATIC ATTRIBUTE(unused)
+SizeT drv_get_sector_count_ahci() {
return kSATASectorCount;
}
/// @brief Get the drive size.
/// @return Disk size in bytes.
-STATIC ATTRIBUTE(unused) SizeT drv_get_size_ahci() {
+STATIC ATTRIBUTE(unused)
+SizeT drv_get_size_ahci() {
return drv_std_get_sector_count() * kAHCISectorSize;
}
diff --git a/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc
index 39efb7d3..4688203f 100644
--- a/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc
+++ b/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc
@@ -105,7 +105,7 @@ Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz
rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz - 1) / SectorSz));
- rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF);
+ rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF);
rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8);
rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
@@ -123,8 +123,7 @@ Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz
rt_out8(kATADevice.Bar(0x20) + 0x00, 0x09); // Start DMA engine
- while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01)
- ;
+ while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01);
rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine
@@ -147,7 +146,7 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS
rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz - 1)) / SectorSz));
- rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF);
+ rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF);
rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8);
rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
@@ -163,8 +162,7 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS
rt_out8(IO + 0x00, 0x09); // Start DMA engine
- while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01)
- ;
+ while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01);
rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine
diff --git a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc
index 6fccbdfa..9c5b3931 100644
--- a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc
+++ b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc
@@ -83,8 +83,7 @@ ATAInit_Retry:
rt_out8(OutBus + ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
- while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ))
- ;
+ while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ));
/// fetch serial info
/// model, speed, number of sectors...
@@ -117,15 +116,14 @@ Void drv_pio_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT Sect
rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz));
- rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF);
+ rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF);
rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8);
rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO);
- while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ))
- ;
+ while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ));
for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) {
drv_pio_std_wait_io(IO);
@@ -149,15 +147,14 @@ Void drv_pio_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT Sec
rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz));
- rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF);
+ rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF);
rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8);
rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16);
rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24);
rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO);
- while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ))
- ;
+ while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ));
for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) {
drv_pio_std_wait_io(IO);
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);
diff --git a/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc b/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc
index daa26e53..6059e3be 100644
--- a/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc
+++ b/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc
@@ -10,8 +10,7 @@
namespace Kernel::Detail {
STATIC void mp_hang_fn(void) {
- while (YES)
- ;
+ while (YES);
}
} // namespace Kernel::Detail
diff --git a/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc b/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc
index 31d4a62e..e6fdddfb 100644
--- a/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc
+++ b/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc
@@ -13,8 +13,7 @@ using namespace Kernel;
namespace Kernel {
namespace Detail {
STATIC void mp_hang_fn(void) {
- while (YES)
- ;
+ while (YES);
}
} // namespace Detail