summaryrefslogtreecommitdiffhomepage
path: root/dev/Kernel
diff options
context:
space:
mode:
authorAmlal <amlal.elmahrouss@icloud.com>2025-01-24 10:38:36 +0100
committerAmlal <amlal.elmahrouss@icloud.com>2025-01-24 10:38:36 +0100
commit7b4bd3577a31d0f0adc7371840642791ae1567f4 (patch)
tree1a8afc973aaa739d0d763315cad2fd376d1cea9c /dev/Kernel
ADD: Open version, with important changes kept out.
Signed-off-by: Amlal <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'dev/Kernel')
-rw-r--r--dev/Kernel/ArchKit/ArchKit.h92
-rw-r--r--dev/Kernel/CFKit/GUIDWizard.h24
-rw-r--r--dev/Kernel/CFKit/GUIDWrapper.h60
-rw-r--r--dev/Kernel/CFKit/Property.h54
-rw-r--r--dev/Kernel/CFKit/Utils.h55
-rw-r--r--dev/Kernel/CompilerKit/CompilerKit.h13
-rw-r--r--dev/Kernel/CompilerKit/Detail.h27
-rw-r--r--dev/Kernel/CompilerKit/Version.h7
-rw-r--r--dev/Kernel/FSKit/Defines.h12
-rw-r--r--dev/Kernel/FSKit/HPFS.h30
-rw-r--r--dev/Kernel/FSKit/IndexableProperty.h63
-rw-r--r--dev/Kernel/FSKit/NeFS.h440
-rw-r--r--dev/Kernel/FirmwareKit/.gitkeep0
-rw-r--r--dev/Kernel/FirmwareKit/EFI.h11
-rw-r--r--dev/Kernel/FirmwareKit/EFI/API.h106
-rw-r--r--dev/Kernel/FirmwareKit/EFI/EFI.h922
-rw-r--r--dev/Kernel/FirmwareKit/EFI/NS.h20
-rw-r--r--dev/Kernel/FirmwareKit/GPT.h57
-rw-r--r--dev/Kernel/FirmwareKit/Handover.h108
-rw-r--r--dev/Kernel/HALKit/.gitkeep0
-rw-r--r--dev/Kernel/HALKit/AMD64/CPUID.h86
-rw-r--r--dev/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cc126
-rw-r--r--dev/Kernel/HALKit/AMD64/HalAPICController.cc39
-rw-r--r--dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc279
-rw-r--r--dev/Kernel/HALKit/AMD64/HalApplicationProcessorGNU.s8
-rw-r--r--dev/Kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm77
-rw-r--r--dev/Kernel/HALKit/AMD64/HalBoot.asm28
-rw-r--r--dev/Kernel/HALKit/AMD64/HalCPUAMD64.cc101
-rw-r--r--dev/Kernel/HALKit/AMD64/HalCommonAPI.asm82
-rw-r--r--dev/Kernel/HALKit/AMD64/HalControlRegister.s45
-rw-r--r--dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc235
-rw-r--r--dev/Kernel/HALKit/AMD64/HalDebugOutput.cc145
-rw-r--r--dev/Kernel/HALKit/AMD64/HalDebugPort.cc40
-rw-r--r--dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cc126
-rw-r--r--dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm410
-rw-r--r--dev/Kernel/HALKit/AMD64/HalKernelMain.cc110
-rw-r--r--dev/Kernel/HALKit/AMD64/HalKernelPanic.cc90
-rw-r--r--dev/Kernel/HALKit/AMD64/HalPagingMgrAMD64.cc168
-rw-r--r--dev/Kernel/HALKit/AMD64/HalRoutineWait.s11
-rw-r--r--dev/Kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc52
-rw-r--r--dev/Kernel/HALKit/AMD64/HalTimerAMD64.cc86
-rw-r--r--dev/Kernel/HALKit/AMD64/HalUtils.asm26
-rw-r--r--dev/Kernel/HALKit/AMD64/Hypervisor.h25
-rw-r--r--dev/Kernel/HALKit/AMD64/MBCI/HalMBCI.cc7
-rw-r--r--dev/Kernel/HALKit/AMD64/PCI/DMA.cc82
-rw-r--r--dev/Kernel/HALKit/AMD64/PCI/Database.cc11
-rw-r--r--dev/Kernel/HALKit/AMD64/PCI/Device.cc139
-rw-r--r--dev/Kernel/HALKit/AMD64/PCI/Express.cc11
-rw-r--r--dev/Kernel/HALKit/AMD64/PCI/IO.cc7
-rw-r--r--dev/Kernel/HALKit/AMD64/PCI/Iterator.cc41
-rw-r--r--dev/Kernel/HALKit/AMD64/PCI/PCI.cc7
-rw-r--r--dev/Kernel/HALKit/AMD64/Paging.h99
-rw-r--r--dev/Kernel/HALKit/AMD64/Processor.h326
-rw-r--r--dev/Kernel/HALKit/AMD64/ReadMe.md8
-rw-r--r--dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cc38
-rw-r--r--dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc195
-rw-r--r--dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc316
-rwxr-xr-xdev/Kernel/HALKit/AMD64/make_ap_blob.sh3
-rw-r--r--dev/Kernel/HALKit/ARM64/APM/APM+IO.cc37
-rw-r--r--dev/Kernel/HALKit/ARM64/ApplicationProcessor.h19
-rw-r--r--dev/Kernel/HALKit/ARM64/HalACPIFactoryInterface.cc31
-rw-r--r--dev/Kernel/HALKit/ARM64/HalApplicationProcessor.cc136
-rw-r--r--dev/Kernel/HALKit/ARM64/HalDebugOutput.cc83
-rw-r--r--dev/Kernel/HALKit/ARM64/HalKernelMain.cc52
-rw-r--r--dev/Kernel/HALKit/ARM64/HalKernelPanic.cc80
-rw-r--r--dev/Kernel/HALKit/ARM64/HalPageInternal.S5
-rw-r--r--dev/Kernel/HALKit/ARM64/HalPagingMgrARM64.cc86
-rw-r--r--dev/Kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc24
-rw-r--r--dev/Kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc35
-rw-r--r--dev/Kernel/HALKit/ARM64/HalTimerARM64.cc14
-rw-r--r--dev/Kernel/HALKit/ARM64/MBCI/MBCI.cc7
-rw-r--r--dev/Kernel/HALKit/ARM64/Paging.h120
-rw-r--r--dev/Kernel/HALKit/ARM64/Processor.h86
-rw-r--r--dev/Kernel/HALKit/ARM64/ReadMe.md3
-rw-r--r--dev/Kernel/HALKit/ARM64/Storage/MFlash+IO.cc84
-rw-r--r--dev/Kernel/HALKit/AXP/CR.s11
-rw-r--r--dev/Kernel/HALKit/AXP/CoreInterruptHandlerDEC.cpp0
-rw-r--r--dev/Kernel/HALKit/AXP/CoreSyscallHandlerDEC.cpp24
-rw-r--r--dev/Kernel/HALKit/AXP/HAL.s13
-rw-r--r--dev/Kernel/HALKit/AXP/Processor.h7
-rw-r--r--dev/Kernel/HALKit/AXP/README1
-rw-r--r--dev/Kernel/HALKit/AXP/README.TXT1
-rw-r--r--dev/Kernel/HALKit/AXP/SYSCALL.s10
-rw-r--r--dev/Kernel/HALKit/AXP/VM.s5
-rw-r--r--dev/Kernel/HALKit/POWER/.gitkeep0
-rw-r--r--dev/Kernel/HALKit/POWER/AP.h39
-rw-r--r--dev/Kernel/HALKit/POWER/APM/.gitkeep0
-rw-r--r--dev/Kernel/HALKit/POWER/HalAP.cc40
-rw-r--r--dev/Kernel/HALKit/POWER/HalDebugOutput.cc27
-rw-r--r--dev/Kernel/HALKit/POWER/HalStartSequence.s14
-rw-r--r--dev/Kernel/HALKit/POWER/HalThread.cc8
-rw-r--r--dev/Kernel/HALKit/POWER/HalVirtualMemory.cc49
-rw-r--r--dev/Kernel/HALKit/POWER/MBCI/.gitkeep0
-rw-r--r--dev/Kernel/HALKit/POWER/MBCI/HalMBCIHost.cc8
-rw-r--r--dev/Kernel/HALKit/POWER/Processor.h62
-rw-r--r--dev/Kernel/HALKit/POWER/ReadMe.md4
-rw-r--r--dev/Kernel/HALKit/RISCV/.keep0
-rw-r--r--dev/Kernel/HALKit/RISCV/AP.h36
-rw-r--r--dev/Kernel/HALKit/RISCV/APM/.gitkeep0
-rw-r--r--dev/Kernel/HALKit/RISCV/HalAP.cc40
-rw-r--r--dev/Kernel/HALKit/RISCV/ReadMe.md4
-rw-r--r--dev/Kernel/HALKit/RISCV/Storage/.gitkeep0
-rw-r--r--dev/Kernel/HALKit/X86S/.gitkeep0
-rw-r--r--dev/Kernel/HALKit/X86S/ACPI/.gitkeep0
-rw-r--r--dev/Kernel/HALKit/X86S/Storage/.gitkeep0
-rw-r--r--dev/Kernel/KernelKit/CodeMgr.h37
-rw-r--r--dev/Kernel/KernelKit/DebugOutput.h211
-rw-r--r--dev/Kernel/KernelKit/Defines.h15
-rw-r--r--dev/Kernel/KernelKit/DeviceMgr.h140
-rw-r--r--dev/Kernel/KernelKit/DriveMgr.h191
-rw-r--r--dev/Kernel/KernelKit/FileMgr.h392
-rw-r--r--dev/Kernel/KernelKit/HardwareThreadScheduler.h149
-rw-r--r--dev/Kernel/KernelKit/Heap.h86
-rw-r--r--dev/Kernel/KernelKit/IDylibObject.h48
-rw-r--r--dev/Kernel/KernelKit/IPEFDylibObject.h106
-rw-r--r--dev/Kernel/KernelKit/LPC.h70
-rw-r--r--dev/Kernel/KernelKit/LoaderInterface.h34
-rw-r--r--dev/Kernel/KernelKit/LockDelegate.h69
-rw-r--r--dev/Kernel/KernelKit/MSDOS.h52
-rw-r--r--dev/Kernel/KernelKit/PCI/DMA.h81
-rw-r--r--dev/Kernel/KernelKit/PCI/DMA.inl20
-rw-r--r--dev/Kernel/KernelKit/PCI/Database.h38
-rw-r--r--dev/Kernel/KernelKit/PCI/Device.h80
-rw-r--r--dev/Kernel/KernelKit/PCI/Express.h11
-rw-r--r--dev/Kernel/KernelKit/PCI/IO-Impl-AMD64.inl54
-rw-r--r--dev/Kernel/KernelKit/PCI/IO.h59
-rw-r--r--dev/Kernel/KernelKit/PCI/Iterator.h43
-rw-r--r--dev/Kernel/KernelKit/PCI/PCI.h59
-rw-r--r--dev/Kernel/KernelKit/PE.h143
-rw-r--r--dev/Kernel/KernelKit/PECodeMgr.h24
-rw-r--r--dev/Kernel/KernelKit/PEF.h117
-rw-r--r--dev/Kernel/KernelKit/PEFCodeMgr.h72
-rw-r--r--dev/Kernel/KernelKit/Semaphore.h43
-rw-r--r--dev/Kernel/KernelKit/ThreadLocalStorage.h69
-rw-r--r--dev/Kernel/KernelKit/ThreadLocalStorage.inl99
-rw-r--r--dev/Kernel/KernelKit/Timer.h81
-rw-r--r--dev/Kernel/KernelKit/User.h86
-rw-r--r--dev/Kernel/KernelKit/UserProcessScheduler.h341
-rw-r--r--dev/Kernel/KernelKit/UserProcessScheduler.inl51
-rw-r--r--dev/Kernel/KernelKit/XCOFF.h51
-rw-r--r--dev/Kernel/KernelRsrc.rsrc25
-rwxr-xr-xdev/Kernel/MoveAll.ARM64.sh7
-rwxr-xr-xdev/Kernel/MoveAll.X64.sh7
-rw-r--r--dev/Kernel/NetworkKit/IP.h83
-rw-r--r--dev/Kernel/NetworkKit/IPC.h106
-rw-r--r--dev/Kernel/NetworkKit/LTE.h16
-rw-r--r--dev/Kernel/NetworkKit/MAC.h29
-rw-r--r--dev/Kernel/NetworkKit/NetworkDevice.h83
-rw-r--r--dev/Kernel/NetworkKit/NetworkDevice.inl32
-rw-r--r--dev/Kernel/NewKit/Array.h58
-rw-r--r--dev/Kernel/NewKit/ArrayList.h58
-rw-r--r--dev/Kernel/NewKit/Atom.h46
-rw-r--r--dev/Kernel/NewKit/Crc32.h23
-rw-r--r--dev/Kernel/NewKit/CxxAbi.h28
-rw-r--r--dev/Kernel/NewKit/Defines.h188
-rw-r--r--dev/Kernel/NewKit/ErrorOr.h77
-rw-r--r--dev/Kernel/NewKit/Function.h53
-rw-r--r--dev/Kernel/NewKit/Json.h151
-rw-r--r--dev/Kernel/NewKit/KString.h94
-rw-r--r--dev/Kernel/NewKit/KernelPanic.h64
-rw-r--r--dev/Kernel/NewKit/Macros.h149
-rw-r--r--dev/Kernel/NewKit/MutableArray.h239
-rw-r--r--dev/Kernel/NewKit/New.h20
-rw-r--r--dev/Kernel/NewKit/NewKit.h20
-rw-r--r--dev/Kernel/NewKit/OwnPtr.h94
-rw-r--r--dev/Kernel/NewKit/PageMgr.h81
-rw-r--r--dev/Kernel/NewKit/Pair.h14
-rw-r--r--dev/Kernel/NewKit/Pmm.h44
-rw-r--r--dev/Kernel/NewKit/Ref.h108
-rw-r--r--dev/Kernel/NewKit/Stream.h58
-rw-r--r--dev/Kernel/NewKit/Utils.h29
-rw-r--r--dev/Kernel/NewKit/Variant.h70
-rw-r--r--dev/Kernel/POSIXKit/signal.h20
-rw-r--r--dev/Kernel/POSIXKit/unix_layer.h13
-rw-r--r--dev/Kernel/ReadMe.md3
-rw-r--r--dev/Kernel/StorageKit/AHCI.h33
-rw-r--r--dev/Kernel/StorageKit/ATA.h39
-rw-r--r--dev/Kernel/StorageKit/NVME.h34
-rw-r--r--dev/Kernel/StorageKit/PRDT.h36
-rw-r--r--dev/Kernel/StorageKit/SCSI.h11
-rw-r--r--dev/Kernel/StorageKit/StorageKit.h22
-rw-r--r--dev/Kernel/SystemKit/SwapDisk.h48
-rw-r--r--dev/Kernel/SystemKit/TeamScheduler.h20
-rw-r--r--dev/Kernel/amd64-desktop.make85
-rw-r--r--dev/Kernel/arm64-desktop.make64
-rw-r--r--dev/Kernel/doc/Explicit Partition Map.pdfbin0 -> 12364 bytes
-rw-r--r--dev/Kernel/doc/SPECIFICATION.md63
-rw-r--r--dev/Kernel/doc/TODO-LIST.md25
-rw-r--r--dev/Kernel/obj/.hgkeep0
-rw-r--r--dev/Kernel/power64-cb.make4
-rw-r--r--dev/Kernel/riscv64-cb.make0
-rw-r--r--dev/Kernel/src/ACPIFactoryInterface.cc96
-rw-r--r--dev/Kernel/src/Array.cc7
-rw-r--r--dev/Kernel/src/ArrayList.cc7
-rw-r--r--dev/Kernel/src/Atom.cc10
-rw-r--r--dev/Kernel/src/BitMapMgr.cc186
-rw-r--r--dev/Kernel/src/CodeMgr.cc28
-rw-r--r--dev/Kernel/src/Crc32.cc83
-rw-r--r--dev/Kernel/src/CxxAbi-AMD64.cc90
-rw-r--r--dev/Kernel/src/CxxAbi-ARM64.cc107
-rw-r--r--dev/Kernel/src/Defines.cc7
-rw-r--r--dev/Kernel/src/DeviceMgr.cc7
-rw-r--r--dev/Kernel/src/DriveMgr+IO.cc96
-rw-r--r--dev/Kernel/src/DriveMgr.cc230
-rw-r--r--dev/Kernel/src/ErrorOr.cc12
-rw-r--r--dev/Kernel/src/FS/HPFS.cc22
-rw-r--r--dev/Kernel/src/FileMgr.cc52
-rw-r--r--dev/Kernel/src/GUIDWizard.cc72
-rw-r--r--dev/Kernel/src/GUIDWrapper.cc11
-rw-r--r--dev/Kernel/src/HardwareThreadScheduler.cc219
-rw-r--r--dev/Kernel/src/Heap.cc301
-rw-r--r--dev/Kernel/src/IDylibObject.cc15
-rw-r--r--dev/Kernel/src/IPEFDylibObject.cc103
-rw-r--r--dev/Kernel/src/IndexableProperty.cc57
-rw-r--r--dev/Kernel/src/Json.cc10
-rw-r--r--dev/Kernel/src/KString.cc217
-rw-r--r--dev/Kernel/src/KernelMain.cc102
-rw-r--r--dev/Kernel/src/LPC.cc34
-rw-r--r--dev/Kernel/src/LockDelegate.cc12
-rw-r--r--dev/Kernel/src/MutableArray.cc7
-rw-r--r--dev/Kernel/src/Network/IPAddr.cc129
-rw-r--r--dev/Kernel/src/Network/IPCAddr.cc0
-rw-r--r--dev/Kernel/src/Network/IPCMsg.cc102
-rw-r--r--dev/Kernel/src/Network/NetworkDevice.cc35
-rw-r--r--dev/Kernel/src/New+Delete.cc50
-rw-r--r--dev/Kernel/src/OwnPtr.cc7
-rw-r--r--dev/Kernel/src/PEFCodeMgr.cc268
-rw-r--r--dev/Kernel/src/PRDT.cc24
-rw-r--r--dev/Kernel/src/PageMgr.cc110
-rw-r--r--dev/Kernel/src/Pmm.cc98
-rw-r--r--dev/Kernel/src/Property.cc45
-rw-r--r--dev/Kernel/src/Ref.cc7
-rw-r--r--dev/Kernel/src/Semaphore.cc69
-rw-r--r--dev/Kernel/src/SoftwareTimer.cc39
-rw-r--r--dev/Kernel/src/Storage/AHCIDeviceInterface.cc35
-rw-r--r--dev/Kernel/src/Storage/ATADeviceInterface.cc88
-rw-r--r--dev/Kernel/src/Storage/NVMEDeviceInterface.cc28
-rw-r--r--dev/Kernel/src/Storage/SCSIDeviceInterface.cc11
-rw-r--r--dev/Kernel/src/Stream.cc12
-rw-r--r--dev/Kernel/src/System/SwapDisk.cc47
-rw-r--r--dev/Kernel/src/ThreadLocalStorage.cc67
-rw-r--r--dev/Kernel/src/Timer.cc19
-rw-r--r--dev/Kernel/src/User.cc188
-rw-r--r--dev/Kernel/src/UserProcessScheduler.cc607
-rw-r--r--dev/Kernel/src/UserProcessTeam.cc58
-rw-r--r--dev/Kernel/src/Utils.cc219
-rw-r--r--dev/Kernel/src/Variant.cc33
247 files changed, 17582 insertions, 0 deletions
diff --git a/dev/Kernel/ArchKit/ArchKit.h b/dev/Kernel/ArchKit/ArchKit.h
new file mode 100644
index 00000000..7a0fbbcf
--- /dev/null
+++ b/dev/Kernel/ArchKit/ArchKit.h
@@ -0,0 +1,92 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Array.h>
+#include <NewKit/Defines.h>
+#include <NewKit/Function.h>
+
+#include <FirmwareKit/Handover.h>
+
+#ifdef __ZKA_AMD64__
+#include <HALKit/AMD64/Paging.h>
+#include <HALKit/AMD64/Hypervisor.h>
+#include <HALKit/AMD64/Processor.h>
+#elif defined(__ZKA_POWER64__)
+#include <HALKit/POWER/Processor.h>
+#elif defined(__ZKA_ARM64__)
+#include <HALKit/ARM64/Processor.h>
+#else
+#error !!! unknown architecture !!!
+#endif
+
+namespace Kernel
+{
+ inline SSizeT rt_hash_seed(const Char* seed, int mul)
+ {
+ SSizeT hash = 0;
+
+ for (SSizeT idx = 0; seed[idx] != 0; ++idx)
+ {
+ hash += seed[idx];
+ hash ^= mul;
+ }
+
+ return hash;
+ }
+
+ /// @brief write to mapped memory register
+ /// @param base the base address.
+ /// @param reg the register.
+ /// @param value the write to write on it.
+ template <typename WordLength>
+ inline Void ke_dma_write(WordLength base, WordLength reg, WordLength value) noexcept
+ {
+ *(volatile WordLength*)(base + reg) = value;
+ }
+
+ /// @brief read from mapped memory register.
+ /// @param base base address
+ /// @param reg the register.
+ /// @return the value inside the register.
+ template <typename WordLength>
+ inline UInt32 ke_dma_read(WordLength base, WordLength reg) noexcept
+ {
+ return *(volatile WordLength*)((UInt64)base + reg);
+ }
+
+ namespace HAL
+ {
+ auto mm_is_bitmap(VoidPtr ptr) -> Bool;
+ }
+} // namespace Kernel
+
+#define kKernelMaxSystemCalls (256)
+
+typedef Kernel::Void (*rt_syscall_proc)(Kernel::VoidPtr);
+
+struct HAL_SYSCALL_RECORD final
+{
+ Kernel::Int64 fHash;
+ Kernel::Bool fHooked;
+ rt_syscall_proc fProc;
+
+ operator bool()
+ {
+ return fHooked;
+ }
+};
+
+inline Kernel::Array<HAL_SYSCALL_RECORD,
+ kKernelMaxSystemCalls>
+ kSyscalls;
+
+inline Kernel::Array<HAL_SYSCALL_RECORD,
+ kKernelMaxSystemCalls>
+ kKerncalls;
+
+EXTERN_C Kernel::HAL::StackFramePtr mp_get_current_context(Kernel::Int64 pid);
diff --git a/dev/Kernel/CFKit/GUIDWizard.h b/dev/Kernel/CFKit/GUIDWizard.h
new file mode 100644
index 00000000..0a652310
--- /dev/null
+++ b/dev/Kernel/CFKit/GUIDWizard.h
@@ -0,0 +1,24 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <CFKit/GUIDWrapper.h>
+#include <NewKit/Array.h>
+#include <NewKit/ArrayList.h>
+#include <NewKit/Defines.h>
+#include <NewKit/ErrorOr.h>
+#include <NewKit/Ref.h>
+#include <NewKit/Stream.h>
+#include <NewKit/KString.h>
+
+namespace CFKit::XRN::Version1
+{
+ using namespace Kernel;
+
+ Ref<GUIDSequence*> cf_make_sequence(const ArrayList<UInt32>& seq);
+ ErrorOr<Ref<Kernel::KString>> cf_try_guid_to_string(Ref<GUIDSequence*>& guid);
+} // namespace CFKit::XRN::Version1
diff --git a/dev/Kernel/CFKit/GUIDWrapper.h b/dev/Kernel/CFKit/GUIDWrapper.h
new file mode 100644
index 00000000..e69aa82a
--- /dev/null
+++ b/dev/Kernel/CFKit/GUIDWrapper.h
@@ -0,0 +1,60 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+#include <NewKit/Ref.h>
+#include <NewKit/Stream.h>
+
+/* GUID for C++ Components */
+
+#define kXRNNil "@{........-....-M...-N...-............}"
+
+// eXtensible Resource Information
+namespace CFKit::XRN
+{
+ using namespace Kernel;
+
+ union GUIDSequence {
+ alignas(8) UShort u8[16];
+ alignas(8) UShort u16[8];
+ alignas(8) UInt u32[4];
+ alignas(8) ULong u64[2];
+
+ struct
+ {
+ alignas(8) UInt fMs1;
+ UShort fMs2;
+ UShort fMs3;
+ UChar fMs4[8];
+ };
+ };
+
+ class GUID final
+ {
+ public:
+ explicit GUID() = default;
+ ~GUID() = default;
+
+ public:
+ GUID& operator=(const GUID&) = default;
+ GUID(const GUID&) = default;
+
+ public:
+ GUIDSequence& operator->() noexcept
+ {
+ return fUUID;
+ }
+ GUIDSequence& Leak() noexcept
+ {
+ return fUUID;
+ }
+
+ private:
+ GUIDSequence fUUID;
+ };
+} // namespace CFKit::XRN
diff --git a/dev/Kernel/CFKit/Property.h b/dev/Kernel/CFKit/Property.h
new file mode 100644
index 00000000..162b757b
--- /dev/null
+++ b/dev/Kernel/CFKit/Property.h
@@ -0,0 +1,54 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifndef CFKIT_PROPS_H
+#define CFKIT_PROPS_H
+
+#include <NewKit/Array.h>
+#include <NewKit/Defines.h>
+#include <NewKit/Function.h>
+#include <NewKit/KString.h>
+
+#define kMaxPropLen 255
+
+namespace CFKit
+{
+ using namespace Kernel;
+
+ /// @brief handle to anything (number, ptr, string...)
+ using PropertyId = UIntPtr;
+
+ /// @brief Kernel property class.
+ /// @example \Properties\SmpCores or \Properties\KernelVersion
+ class Property
+ {
+ public:
+ Property();
+ virtual ~Property();
+
+ public:
+ Property& operator=(const Property&) = default;
+ Property(const Property&) = default;
+
+ bool StringEquals(KString& name);
+ PropertyId& GetValue();
+ KString& GetKey();
+
+ private:
+ KString fName{kMaxPropLen};
+ PropertyId fValue{0UL};
+ };
+
+ template <SizeT N>
+ using PropertyArray = Array<Property, N>;
+} // namespace CFKit
+
+namespace Kernel
+{
+ using namespace CFKit;
+}
+
+#endif // !CFKIT_PROPS_H
diff --git a/dev/Kernel/CFKit/Utils.h b/dev/Kernel/CFKit/Utils.h
new file mode 100644
index 00000000..370eca45
--- /dev/null
+++ b/dev/Kernel/CFKit/Utils.h
@@ -0,0 +1,55 @@
+#ifndef CFKIT_UTILS_H
+#define CFKIT_UTILS_H
+
+#include <KernelKit/PE.h>
+#include <KernelKit/MSDOS.h>
+
+namespace CFKit
+{
+ using namespace Kernel;
+
+ /// @brief Finds the PE header inside the blob.
+ inline auto ldr_find_exec_header(DosHeaderPtr ptrDos) -> LDR_EXEC_HEADER_PTR
+ {
+ if (!ptrDos)
+ return nullptr;
+
+ if (ptrDos->eMagic[0] != kMagMz0)
+ return nullptr;
+
+ if (ptrDos->eMagic[1] != kMagMz1)
+ return nullptr;
+
+ return (LDR_EXEC_HEADER_PTR)(VoidPtr)(&ptrDos->eLfanew + 1);
+ }
+
+ /// @brief Finds the PE optional header inside the blob.
+ inline auto ldr_find_opt_exec_header(DosHeaderPtr ptrDos) -> LDR_OPTIONAL_HEADER_PTR
+ {
+ if (!ptrDos)
+ return nullptr;
+
+ auto exec = ldr_find_exec_header(ptrDos);
+
+ if (!exec)
+ return nullptr;
+
+ return (LDR_OPTIONAL_HEADER_PTR)(VoidPtr)(&exec->mCharacteristics + 1);
+ }
+
+ /// @brief Finds the PE header inside the blob.
+ /// @note overloaded function.
+ inline auto ldr_find_exec_header(const Char* ptrDos) -> LDR_EXEC_HEADER_PTR
+ {
+ return ldr_find_exec_header((DosHeaderPtr)ptrDos);
+ }
+
+ /// @brief Finds the PE header inside the blob.
+ /// @note overloaded function.
+ inline auto ldr_find_opt_exec_header(const Char* ptrDos) -> LDR_OPTIONAL_HEADER_PTR
+ {
+ return ldr_find_opt_exec_header((DosHeaderPtr)ptrDos);
+ }
+} // namespace CFKit
+
+#endif // ifndef CFKIT_UTILS_H
diff --git a/dev/Kernel/CompilerKit/CompilerKit.h b/dev/Kernel/CompilerKit/CompilerKit.h
new file mode 100644
index 00000000..6431100b
--- /dev/null
+++ b/dev/Kernel/CompilerKit/CompilerKit.h
@@ -0,0 +1,13 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifndef _INC_CL_H
+#define _INC_CL_H
+
+#include <CompilerKit/Detail.h>
+#include <CompilerKit/Version.h>
+
+#endif /* ifndef _INC_CL_H */
diff --git a/dev/Kernel/CompilerKit/Detail.h b/dev/Kernel/CompilerKit/Detail.h
new file mode 100644
index 00000000..6f58c97f
--- /dev/null
+++ b/dev/Kernel/CompilerKit/Detail.h
@@ -0,0 +1,27 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#ifdef __MINOSKRNL__
+#include <NewKit/Defines.h>
+#endif // ifdef __MINOSKRNL__
+
+#define ZKA_COPY_DELETE(KLASS) \
+ KLASS& operator=(const KLASS&) = delete; \
+ KLASS(const KLASS&) = delete;
+
+#define ZKA_COPY_DEFAULT(KLASS) \
+ KLASS& operator=(const KLASS&) = default; \
+ KLASS(const KLASS&) = default;
+
+#define ZKA_MOVE_DELETE(KLASS) \
+ KLASS& operator=(KLASS&&) = delete; \
+ KLASS(KLASS&&) = delete;
+
+#define ZKA_MOVE_DEFAULT(KLASS) \
+ KLASS& operator=(KLASS&&) = default; \
+ KLASS(KLASS&&) = default;
diff --git a/dev/Kernel/CompilerKit/Version.h b/dev/Kernel/CompilerKit/Version.h
new file mode 100644
index 00000000..11854cd8
--- /dev/null
+++ b/dev/Kernel/CompilerKit/Version.h
@@ -0,0 +1,7 @@
+// (c) Amlal EL Mahrouss
+
+#pragma once
+
+/// <COMMIT NUMBER>.<YEAR>.<PROGRAM VERSION>
+#define BOOTLOADER_VERSION "1104.2025.110"
+#define KERNEL_VERSION "1104.2025.110"
diff --git a/dev/Kernel/FSKit/Defines.h b/dev/Kernel/FSKit/Defines.h
new file mode 100644
index 00000000..55198c17
--- /dev/null
+++ b/dev/Kernel/FSKit/Defines.h
@@ -0,0 +1,12 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+#define FSKIT_VERSION "1.0.0"
+#define FSKIT_VERSION_BCD 0x0100
diff --git a/dev/Kernel/FSKit/HPFS.h b/dev/Kernel/FSKit/HPFS.h
new file mode 100644
index 00000000..af3d2e01
--- /dev/null
+++ b/dev/Kernel/FSKit/HPFS.h
@@ -0,0 +1,30 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+/// @file HPFS.h
+/// @brief HPFS filesystem support.
+
+#define kHPFSVersion 0x0100
+#define kHPFSMagic " HPFS"
+#define kHPFSMagicLen 8
+
+#define kHPFSMinimumDiskSize (gib_cast(64))
+
+enum
+{
+ kHPFSInvalidDrive,
+ kHPFSHDDDrive,
+ kHPFSSSDDrive,
+ kHPFSMassStorageDrive,
+ kHPFSSCSIDrive,
+ kHPFSDriveCount,
+};
+
+struct HPFS_EXPLICIT_BOOT_SECTOR;
diff --git a/dev/Kernel/FSKit/IndexableProperty.h b/dev/Kernel/FSKit/IndexableProperty.h
new file mode 100644
index 00000000..9192994f
--- /dev/null
+++ b/dev/Kernel/FSKit/IndexableProperty.h
@@ -0,0 +1,63 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <CFKit/Property.h>
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/DriveMgr.h>
+
+#define kIndexerNodeNameLength 255
+#define kIndexerClaimed 0xCF
+
+namespace Kernel
+{
+ namespace Indexer
+ {
+ struct IndexProperty final
+ {
+ public:
+ Char Drive[kDriveNameLen];
+ Char Path[kIndexerNodeNameLength];
+ };
+
+ class IndexableProperty final : public Property
+ {
+ public:
+ explicit IndexableProperty()
+ : Property()
+ {
+ Kernel::KString strProp(kMaxPropLen);
+ strProp += "/prop/indexable";
+
+ this->GetKey() = strProp;
+ }
+
+ ~IndexableProperty() override = default;
+
+ ZKA_COPY_DEFAULT(IndexableProperty);
+
+ public:
+ IndexProperty& Leak() noexcept;
+
+ public:
+ void AddFlag(Int16 flag);
+ void RemoveFlag(Int16 flag);
+ Int16 HasFlag(Int16 flag);
+
+ private:
+ IndexProperty fIndex;
+ UInt32 fFlags;
+ };
+
+ /// @brief Index a file into the indexer instance.
+ /// @param filename path
+ /// @param filenameLen used bytes in path.
+ /// @param indexer the filesystem indexer.
+ /// @return none.
+ Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer);
+ } // namespace Indexer
+} // namespace Kernel
diff --git a/dev/Kernel/FSKit/NeFS.h b/dev/Kernel/FSKit/NeFS.h
new file mode 100644
index 00000000..26529241
--- /dev/null
+++ b/dev/Kernel/FSKit/NeFS.h
@@ -0,0 +1,440 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ FILE: NeFS.h
+ PURPOSE: NeFS (New extended File System) support.
+
+ Revision History:
+
+ ?/?/?: Added file (amlel)
+ 12/02/24: Add UUID macro for EPM and GPT partition schemes.
+ 3/16/24: Add mandatory sector size, kNeFSSectorSz is set to 2048 by
+default.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <Hints/CompilerHint.h>
+#include <KernelKit/DriveMgr.h>
+#include <NewKit/Defines.h>
+#include <NewKit/KString.h>
+
+/**
+ @brief New extended File System specification.
+ @author Amlal EL Mahrouss (Amlal EL Mahrouss, amlalelmahrouss at icloud dot com)
+*/
+
+#define kNeFSInvalidFork (-1)
+#define kNeFSInvalidCatalog (-1)
+#define kNeFSNodeNameLen (256)
+
+#define kNeFSMinimumDiskSize (gib_cast(4))
+
+#define kNeFSSectorSz (512)
+
+#define kNeFSIdentLen (8)
+#define kNeFSIdent " NeFS"
+#define kNeFSPadLen (392)
+
+#define kNeFSMetaFilePrefix '$'
+
+#define kNeFSVersionInteger (0x0129)
+#define kNeFSVerionString "1.2.9"
+
+/// @brief Standard fork types.
+#define kNeFSDataFork "main_data"
+#define kNeFSResourceFork "main_rsrc"
+
+#define kNeFSForkSize (sizeof(NFS_FORK_STRUCT))
+
+#define kNeFSPartitionTypeStandard (7)
+#define kNeFSPartitionTypePage (8)
+#define kNeFSPartitionTypeBoot (9)
+
+#define kNeFSCatalogKindFile (1)
+#define kNeFSCatalogKindDir (2)
+#define kNeFSCatalogKindAlias (3)
+
+//! Shared between network and/or partitions. Export forks as .zip when copying.
+#define kNeFSCatalogKindShared (4)
+
+#define kNeFSCatalogKindResource (5)
+#define kNeFSCatalogKindExecutable (6)
+
+#define kNeFSCatalogKindPage (8)
+
+#define kNeFSCatalogKindDevice (9)
+#define kNeFSCatalogKindLock (10)
+
+#define kNeFSCatalogKindRLE (11)
+#define kNeFSCatalogKindMetaFile (12)
+
+#define kNeFSCatalogKindTTF (13)
+#define kNeFSCatalogKindRIFF (14)
+#define kNeFSCatalogKindMPEG (15)
+#define kNeFSCatalogKindMOFF (16)
+
+#define kNeFSSeparator '/'
+#define kNeFSSeparatorAlt '/'
+
+#define kNeFSUpDir ".."
+#define kNeFSRoot "/"
+#define kNeFSRootAlt "/"
+
+#define kNeFSLF '\r'
+#define kNeFSEOF (-1)
+
+#define kNeFSBitWidth (sizeof(Kernel::Char))
+#define kNeFSLbaType (Kernel::Lba)
+
+/// @note Start after the partition map header. (Virtual addressing)
+#define kNeFSRootCatalogStartAddress (1024)
+#define kNeFSCatalogStartAddress ((2048) + sizeof(NFS_ROOT_PARTITION_BLOCK))
+
+#define kResourceTypeDialog (10)
+#define kResourceTypeString (11)
+#define kResourceTypeMenu (12)
+#define kResourceTypeSound (13)
+#define kResourceTypeFont (14)
+
+#define kConfigLen (64)
+#define kPartLen (32)
+
+#define kNeFSFlagDeleted (70)
+#define kNeFSFlagUnallocated (0)
+#define kNeFSFlagCreated (71)
+
+#define kNeFSMimeNameLen (200)
+#define kNeFSForkNameLen (200)
+
+#define kNeFSFrameworkExt ".fwrk"
+#define kNeFSStepsExt ".step"
+#define kNeFSApplicationExt ".app"
+#define kNeFSJournalExt ".jrnl"
+
+struct NFS_CATALOG_STRUCT;
+struct NFS_FORK_STRUCT;
+struct NFS_ROOT_PARTITION_BLOCK;
+
+enum
+{
+ kNeFSHardDrive = 0xC0, // Hard Drive
+ kNeFSSolidStateDrive = 0xC1, // Solid State Drive
+ kNeFSOpticalDrive = 0x0C, // Blu-Ray/DVD
+ kNeFSMassStorageDevice = 0xCC, // USB
+ kNeFSScsiDrive = 0xC4, // SCSI Hard Drive
+ kNeFSFlashDrive = 0xC6,
+ kNeFSUnknown = 0xFF, // Unknown device.
+ kNeFSDriveCount = 7,
+};
+
+enum
+{
+ kNeFSStatusUnlocked = 0x18,
+ kNeFSStatusLocked,
+ kNeFSStatusError,
+ kNeFSStatusInvalid,
+};
+
+/// @brief Catalog type.
+struct PACKED NFS_CATALOG_STRUCT final
+{
+ BOOL ForkOrCatalog : 1 {0};
+
+ Kernel::Char Name[kNeFSNodeNameLen] = {0};
+ Kernel::Char Mime[kNeFSMimeNameLen] = {0};
+
+ /// Catalog flags.
+ Kernel::UInt16 Flags;
+
+ /// Catalog allocation status.
+ Kernel::UInt16 Status;
+
+ /// Custom catalog flags.
+ Kernel::UInt16 CatalogFlags;
+
+ /// Catalog kind.
+ Kernel::Int32 Kind;
+
+ /// Size of the data fork.
+ Kernel::Lba DataForkSize;
+
+ /// Size of all resource forks.
+ Kernel::Lba ResourceForkSize;
+
+ /// Forks LBA.
+ Kernel::Lba DataFork;
+ Kernel::Lba ResourceFork;
+
+ Kernel::Lba NextSibling;
+ Kernel::Lba PrevSibling;
+};
+
+/// @brief Fork type, contains a data page.
+/// @note The way we store is way different than how other filesystems do, specific chunk of code are
+/// written into either the data fork or resource fork, the resource fork is reserved for file metadata.
+/// whereas the data fork is reserved for file data.
+struct PACKED NFS_FORK_STRUCT final
+{
+ BOOL ForkOrCatalog : 1 {1};
+
+ Kernel::Char ForkName[kNeFSForkNameLen] = {0};
+ Kernel::Char CatalogName[kNeFSNodeNameLen] = {0};
+
+ Kernel::Int32 Flags;
+ Kernel::Int32 Kind;
+
+ Kernel::Int64 ResourceId;
+ Kernel::Int32 ResourceKind;
+ Kernel::Int32 ResourceFlags;
+
+ Kernel::Lba DataOffset; // 8 Where to look for this data?
+ Kernel::SizeT DataSize; /// Data size according using sector count.
+
+ Kernel::Lba NextSibling;
+ Kernel::Lba PreviousSibling;
+
+ Kernel::Char Pad[2] = {0};
+};
+
+/// @brief Partition block type
+struct PACKED NFS_ROOT_PARTITION_BLOCK final
+{
+ Kernel::Char Ident[kNeFSIdentLen] = {0};
+ Kernel::Char PartitionName[kPartLen] = {0};
+
+ Kernel::Int32 Flags;
+ Kernel::Int32 Kind;
+
+ Kernel::Lba StartCatalog;
+ Kernel::SizeT CatalogCount;
+
+ Kernel::SizeT DiskSize;
+
+ Kernel::SizeT FreeCatalog;
+ Kernel::SizeT FreeSectors;
+
+ Kernel::SizeT SectorCount;
+ Kernel::SizeT SectorSize;
+
+ Kernel::UInt64 Version;
+
+ Kernel::Lba EpmBlock;
+
+ Kernel::Char Pad[kNeFSPadLen];
+};
+
+namespace Kernel
+{
+ class NeFileSystemParser;
+ class NeFileSystemJournal;
+ class NeFileSystemHelper;
+
+ enum
+ {
+ kNeFSSubDriveA,
+ kNeFSSubDriveB,
+ kNeFSSubDriveC,
+ kNeFSSubDriveD,
+ kNeFSSubDriveInvalid,
+ kNeFSSubDriveCount,
+ };
+
+ /// \brief Resource fork kind.
+ enum
+ {
+ kNeFSRsrcForkKind = 0,
+ kNeFSDataForkKind = 1
+ };
+
+ ///
+ /// \name NeFileSystemParser
+ /// \brief NeFS parser class. (catalog creation, remove removal, root,
+ /// forks...) Designed like the DOM, detects the filesystem automatically.
+ ///
+ class NeFileSystemParser final
+ {
+ public:
+ explicit NeFileSystemParser() = default;
+ ~NeFileSystemParser() = default;
+
+ public:
+ ZKA_COPY_DEFAULT(NeFileSystemParser);
+
+ public:
+ /// @brief Creates a new fork inside the NeFS partition.
+ /// @param catalog it's catalog
+ /// @param theFork the fork itself.
+ /// @return the fork
+ _Output BOOL CreateFork(_Input NFS_FORK_STRUCT& in);
+
+ /// @brief Find fork inside New filesystem.
+ /// @param catalog the catalog.
+ /// @param name the fork name.
+ /// @return the fork.
+ _Output NFS_FORK_STRUCT* FindFork(_Input NFS_CATALOG_STRUCT* catalog,
+ _Input const Char* name,
+ Boolean data);
+
+ _Output Void RemoveFork(_Input NFS_FORK_STRUCT* fork);
+
+ _Output Void CloseFork(_Input NFS_FORK_STRUCT* fork);
+
+ _Output NFS_CATALOG_STRUCT* FindCatalog(_Input const Char* catalog_name, Lba& ou_lba, Bool search_hidden = YES, Bool local_search = NO);
+
+ _Output NFS_CATALOG_STRUCT* GetCatalog(_Input const Char* name);
+
+ _Output NFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name,
+ _Input const Int32& flags,
+ _Input const Int32& kind);
+
+ _Output NFS_CATALOG_STRUCT* CreateCatalog(_Input const Char* name);
+
+ _Output Bool WriteCatalog(_Input const Char* catalog,
+ _Input Bool rsrc,
+ _Input VoidPtr data,
+ _Input SizeT sz,
+ _Input const Char* name);
+
+ _Output VoidPtr ReadCatalog(_Input _Output NFS_CATALOG_STRUCT* catalog,
+ _Input Bool isRsrcFork,
+ _Input SizeT dataSz,
+ _Input const Char* forkName);
+
+ _Output Bool Seek(_Input _Output NFS_CATALOG_STRUCT* catalog, SizeT off);
+
+ _Output SizeT Tell(_Input _Output NFS_CATALOG_STRUCT* catalog);
+
+ _Output Bool RemoveCatalog(_Input const Char* catalog);
+
+ _Output Bool CloseCatalog(_InOut NFS_CATALOG_STRUCT* catalog);
+
+ /// @brief Make a EPM+NeFS drive out of the disk.
+ /// @param drive The drive to write on.
+ /// @return If it was sucessful, see err_local_get().
+ _Output Bool Format(_Input _Output DriveTrait* drive, _Input const Lba endLba, _Input const Int32 flags, const Char* part_name);
+
+ public:
+ UInt32 mDriveIndex{kNeFSSubDriveA};
+ };
+
+ ///
+ /// \name NeFileSystemHelper
+ /// \brief Filesystem helper and utils.
+ ///
+
+ class NeFileSystemHelper final
+ {
+ public:
+ STATIC const Char* Root();
+ STATIC const Char* UpDir();
+ STATIC const Char Separator();
+ STATIC const Char MetaFile();
+ };
+
+ /// @brief Journal class for NeFS.
+ class NeFileSystemJournal final
+ {
+ private:
+ NFS_CATALOG_STRUCT* mNode{nullptr};
+
+ public:
+ explicit NeFileSystemJournal(const char* stamp = nullptr)
+ {
+ if (!stamp)
+ {
+ kcout << "Invalid: Journal Stamp, using default name.\r";
+ return;
+ }
+
+ kcout << "Info: Journal stamp: " << stamp << endl;
+ rt_copy_memory((VoidPtr)stamp, this->mStamp, rt_string_len(stamp));
+ }
+
+ ~NeFileSystemJournal() = default;
+
+ ZKA_COPY_DEFAULT(NeFileSystemJournal);
+
+ Bool CreateJournal(NeFileSystemParser* parser)
+ {
+ if (!parser)
+ return NO;
+
+ delete parser->CreateCatalog("/etc/xml/", 0, kNeFSCatalogKindDir);
+ mNode = parser->CreateCatalog(mStamp);
+
+ if (!mNode)
+ return NO;
+
+ return YES;
+ }
+
+ Bool GetJournal(NeFileSystemParser* parser)
+ {
+ if (!parser)
+ return NO;
+
+ auto node = parser->GetCatalog(mStamp);
+
+ if (node)
+ {
+ mNode = node;
+ return YES;
+ }
+
+ return NO;
+ }
+
+ Bool ReleaseJournal()
+ {
+ if (mNode)
+ {
+ delete mNode;
+ mNode = nullptr;
+ return YES;
+ }
+
+ return NO;
+ }
+
+ Bool CommitJournal(NeFileSystemParser* parser,
+ Char* xml_data,
+ Char* journal_name)
+ {
+ if (!parser ||
+ !mNode)
+ return NO;
+
+ NFS_FORK_STRUCT new_fork{};
+
+ rt_copy_memory(mStamp, new_fork.CatalogName, rt_string_len(mStamp));
+ rt_copy_memory(journal_name, new_fork.ForkName, rt_string_len(journal_name));
+
+ new_fork.ResourceKind = 0;
+ new_fork.ResourceId = 0;
+ new_fork.ResourceFlags = 0;
+ new_fork.DataSize = rt_string_len(xml_data);
+ new_fork.Kind = kNeFSRsrcForkKind;
+
+ if (!parser->CreateFork(new_fork))
+ return NO;
+
+ kcout << "XML Commited: " << xml_data << "\r\nTo Journal Fork: " << journal_name << endl;
+
+ auto ret = parser->WriteCatalog(new_fork.CatalogName, YES, xml_data, rt_string_len(xml_data), new_fork.ForkName);
+
+ return ret;
+ }
+
+ private:
+ Char mStamp[kNeFSNodeNameLen] = {"/etc/xml/journal" kNeFSJournalExt};
+ };
+
+ namespace NeFS
+ {
+ Boolean fs_init_nefs(Void) noexcept;
+ } // namespace NeFS
+} // namespace Kernel
diff --git a/dev/Kernel/FirmwareKit/.gitkeep b/dev/Kernel/FirmwareKit/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/FirmwareKit/.gitkeep
diff --git a/dev/Kernel/FirmwareKit/EFI.h b/dev/Kernel/FirmwareKit/EFI.h
new file mode 100644
index 00000000..b11a8e90
--- /dev/null
+++ b/dev/Kernel/FirmwareKit/EFI.h
@@ -0,0 +1,11 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <FirmwareKit/EFI/EFI.h>
+
+/// @note this header is used to reference the EFI/EFI.h
diff --git a/dev/Kernel/FirmwareKit/EFI/API.h b/dev/Kernel/FirmwareKit/EFI/API.h
new file mode 100644
index 00000000..58775ddd
--- /dev/null
+++ b/dev/Kernel/FirmwareKit/EFI/API.h
@@ -0,0 +1,106 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifndef __EFI_API__
+#define __EFI_API__
+
+#include <FirmwareKit/EFI/EFI.h>
+#include <FirmwareKit/Handover.h>
+#include <KernelKit/MSDOS.h>
+#include <KernelKit/PE.h>
+
+#define kZKASubsystem 17
+
+#ifdef __ZBAOSLDR__
+// forward decl.
+class BTextWriter;
+
+#define __BOOTKIT_NO_INCLUDE__ 1
+
+#include <BootKit/BootKit.h>
+#include <Mod/CoreGfx/FBMgr.h>
+#endif // ifdef __ZBAOSLDR__
+
+inline EfiSystemTable* ST = nullptr;
+inline EfiBootServices* BS = nullptr;
+
+EXTERN_C void rt_cli();
+EXTERN_C void rt_hlt();
+
+namespace EFI
+{
+ /// @brief Halt and clear interrupts.
+ /// @return
+ inline Void Stop() noexcept
+ {
+ while (YES)
+ {
+ rt_cli();
+ rt_hlt();
+ }
+ }
+
+ /**
+@brief Exit EFI API to let the OS load correctly.
+Bascially frees everything we have in the EFI side.
+*/
+ inline void ExitBootServices(UInt64 MapKey, EfiHandlePtr ImageHandle) noexcept
+ {
+ if (!ST)
+ return;
+
+ ST->BootServices->ExitBootServices(ImageHandle, MapKey);
+ }
+
+ inline UInt32 Platform() noexcept
+ {
+ return kPeMachineAMD64;
+ }
+
+ /***
+ * @brief Throw an error, stop execution as well.
+ * @param ErrorCode error code to be print.
+ * @param Reason reason to be print.
+ */
+ inline void ThrowError(const EfiCharType* ErrorCode,
+ const EfiCharType* Reason) noexcept
+ {
+ ST->ConOut->OutputString(ST->ConOut, L"\r*** STOP ***\r");
+
+ ST->ConOut->OutputString(ST->ConOut, L"*** ERROR: ");
+ ST->ConOut->OutputString(ST->ConOut, ErrorCode);
+
+ ST->ConOut->OutputString(ST->ConOut, L" ***\r *** REASON: ");
+ ST->ConOut->OutputString(ST->ConOut, Reason);
+
+ ST->ConOut->OutputString(ST->ConOut, L" ***\r");
+
+ EFI::Stop();
+ }
+} // namespace EFI
+
+inline void InitEFI(EfiSystemTable* SystemTable) noexcept
+{
+ if (!SystemTable)
+ return;
+
+ ST = SystemTable;
+ BS = ST->BootServices;
+
+ ST->ConOut->ClearScreen(SystemTable->ConOut);
+ ST->ConOut->SetAttribute(SystemTable->ConOut, kEFIYellow);
+
+ ST->BootServices->SetWatchdogTimer(0, 0, 0, nullptr);
+ ST->ConOut->EnableCursor(ST->ConOut, false);
+}
+
+#ifdef __ZBAOSLDR__
+
+#include <BootKit/Platform.h>
+
+#endif // ifdef __ZBAOSLDR__
+
+#endif /* ifndef __EFI_API__ */
diff --git a/dev/Kernel/FirmwareKit/EFI/EFI.h b/dev/Kernel/FirmwareKit/EFI/EFI.h
new file mode 100644
index 00000000..c96777d6
--- /dev/null
+++ b/dev/Kernel/FirmwareKit/EFI/EFI.h
@@ -0,0 +1,922 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifndef FIRMWARE_KIT_EFI_H
+#define FIRMWARE_KIT_EFI_H
+
+/**
+@brief Implementation of the main EFI protocols.
+*/
+
+#include <NewKit/Defines.h>
+
+using namespace Kernel;
+
+/* we always use stdcall in EFI, the pascal way of calling functions. */
+
+#ifndef EPI_API
+#define EFI_API __attribute__((ms_abi))
+#endif // ifndef EPI_API
+
+#define IN
+#define OUT
+#define OPTIONAL
+
+#define EFI_FINAL final
+
+// Forward decls
+
+struct EfiTableHeader;
+struct EfiLoadFileProtocol;
+struct EfiSimpleTextOutputProtocol;
+struct EfiDevicePathProtocol;
+struct EfiBootServices;
+struct EfiMemoryDescriptor;
+struct EfiSystemTable;
+struct EfiGUID;
+struct EfiFileDevicePathProtocol;
+struct EfiHandle;
+struct EfiGraphicsOutputProtocol;
+struct EfiBitmask;
+struct EfiFileProtocol;
+struct EfiSimpleTextInputProtocol;
+
+typedef UInt64 EfiStatusType;
+
+typedef Char16 EfiChar16Type;
+
+/// @brief Core Handle Kind
+/// Self is like NT's Win32 HANDLE type.
+typedef struct EfiHandle
+{
+}* EfiHandlePtr;
+
+/* UEFI uses wide characters by default. */
+typedef WideChar EfiCharType;
+
+typedef UInt64 EfiPhysicalAddress;
+typedef UIntPtr EfiVirtualAddress;
+
+/// What's BootBolicy?
+/// If TRUE, indicates that the request originates from the boot manager, and
+/// that the boot manager is attempting to load FilePath as a boot selection. If
+/// FALSE, then FilePath must match an exact file to be loaded.
+
+typedef UInt64(EFI_API* EfiTextString)(struct EfiSimpleTextOutputProtocol* Self,
+ const WideChar* OutputString);
+
+typedef UInt64(EFI_API* EfiTextAttrib)(struct EfiSimpleTextOutputProtocol* Self,
+ const WideChar Attribute);
+
+typedef UInt64(EFI_API* EfiTextClear)(struct EfiSimpleTextOutputProtocol* Self);
+
+typedef UInt64(EFI_API* EfiLoadFile)(EfiLoadFileProtocol* Self,
+ EfiFileDevicePathProtocol* FilePath,
+ Boolean BootPolicy,
+ UInt32* BufferSize,
+ VoidPtr Buffer);
+
+typedef UInt64(EFI_API* EfiCopyMem)(VoidPtr DstBuf, VoidPtr SrcBuf, SizeT Length);
+
+typedef UInt64(EFI_API* EfiSetMem)(VoidPtr DstBuf, Char Byte, SizeT Length);
+
+typedef UInt64(EFI_API* EfiHandleProtocol)(EfiHandlePtr Handle, EfiGUID* Guid, VoidPtr* Device);
+
+typedef UInt64(EFI_API* EfiLocateDevicePath)(EfiGUID* Protocol,
+ EfiDevicePathProtocol** DevicePath,
+ EfiHandlePtr Device);
+
+typedef UInt64(EFI_API* EfiStartImage)(EfiHandlePtr Handle, VoidPtr ArgsSize, VoidPtr ArgsPtr);
+
+typedef UInt64(EFI_API* EfiLoadImage)(Boolean BootPolicy,
+ EfiHandlePtr ParentHandle,
+ EfiFileDevicePathProtocol* DeviceFile,
+ VoidPtr buffer,
+ SizeT size,
+ EfiHandlePtr* ppHandle);
+
+/// EFI pool helpers, taken from iPXE.
+
+typedef enum EfiMemoryType
+{
+ ///
+ /// Not used.
+ ///
+ EfiReservedMemoryType,
+ ///
+ /// The code portions of a loaded application.
+ /// (Note that UEFI OS loaders are UEFI applications.)
+ ///
+ EfiLoaderCode,
+ ///
+ /// The data portions of a loaded application and the default data allocation
+ /// type used by an application to allocate pool memory.
+ ///
+ EfiLoaderData,
+ ///
+ /// The code portions of a loaded Boot Services Driver.
+ ///
+ EfiBootServicesCode,
+ ///
+ /// The data portions of a loaded Boot Serves Driver, and the default data
+ /// allocation type used by a Boot Services Driver to allocate pool memory.
+ ///
+ EfiBootServicesData,
+ ///
+ /// The code portions of a loaded Runtime Services Driver.
+ ///
+ EfiRuntimeServicesCode,
+ ///
+ /// The data portions of a loaded Runtime Services Driver and the default
+ /// data allocation type used by a Runtime Services Driver to allocate pool
+ /// memory.
+ ///
+ EfiRuntimeServicesData,
+ ///
+ /// Free (unallocated) memory.
+ ///
+ EfiConventionalMemory,
+ ///
+ /// Memory in which errors have been detected.
+ ///
+ EfiUnusableMemory,
+ ///
+ /// Memory that holds the ACPI tables.
+ ///
+ EfiACPIReclaimMemory,
+ ///
+ /// Address space reserved for use by the firmware.
+ ///
+ EfiACPIMemoryNVS,
+ ///
+ /// Used by system firmware to request that a memory-mapped IO region
+ /// be mapped by the OS to a virtual address so it can be accessed by EFI
+ /// runtime services.
+ ///
+ EfiMemoryMappedIO,
+ ///
+ /// System memory-mapped IO region that is used to translate memory
+ /// cycles to IO cycles by the processor.
+ ///
+ EfiMemoryMappedIOPortSpace,
+ ///
+ /// Address space reserved by the firmware for code that is part of the
+ /// processor.
+ ///
+ EfiPalCode,
+ ///
+ /// A memory region that operates as EfiConventionalMemory,
+ /// however it happens to also support byte-addressable non-volatility.
+ ///
+ EfiPersistentMemory,
+ ///
+ /// A memory region that describes system memory that has not been accepted
+ /// by a corresponding call to the underlying isolation architecture.
+ ///
+ EfiUnacceptedMemoryType,
+ ///
+ /// The last type of memory.
+ /// Not a real type.
+ ///
+ EfiMaxMemoryType,
+} EfiMemoryType;
+
+typedef enum EfiAllocateType
+{
+ /// Anything that satisfy the request.
+ AllocateAnyPages,
+ AllocateMaxAddress,
+ ///
+ /// Allocate pages at a specified address.
+ ///
+ AllocateAddress,
+ ///
+ /// Maximum enumeration value that may be used for bounds checking.
+ ///
+ MaxAllocateType
+} EfiAllocateType;
+
+typedef struct EfiMemoryDescriptor
+{
+ ///
+ /// Kind of the memory region.
+ /// Kind EFI_MEMORY_TYPE is defined in the
+ /// AllocatePages() function description.
+ ///
+ UInt32 Kind;
+ ///
+ /// Physical address of the first byte in the memory region. PhysicalStart
+ /// must be aligned on a 4 KiB boundary, and must not be above
+ /// 0xfffffffffffff000. Kind EFI_PHYSICAL_ADDRESS is defined in the
+ /// AllocatePages() function description
+ ///
+ EfiPhysicalAddress PhysicalStart;
+ ///
+ /// Virtual address of the first byte in the memory region.
+ /// VirtualStart must be aligned on a 4 KiB boundary,
+ /// and must not be above 0xfffffffffffff000.
+ ///
+ EfiVirtualAddress VirtualStart;
+ ///
+ /// NumberOfPagesNumber of 4 KiB pages in the memory region.
+ /// NumberOfPages must not be 0, and must not be any value
+ /// that would represent a memory page with a start address,
+ /// either physical or virtual, above 0xfffffffffffff000.
+ ///
+ UInt64 NumberOfPages;
+ ///
+ /// Attributes of the memory region that describe the bit mask of capabilities
+ /// for that memory region, and not necessarily the current settings for that
+ /// memory region.
+ ///
+ UInt64 Attribute;
+} EfiMemoryDescriptor;
+
+typedef UInt64(EFI_API* EfiAllocatePool)(EfiMemoryType PoolType, UInt32 Size, VoidPtr* Buffer);
+
+typedef UInt64(EFI_API* EfiFreePool)(VoidPtr Buffer);
+
+typedef UInt64(EFI_API* EfiCalculateCrc32)(VoidPtr Data, UInt32 DataSize, UInt32* CrcOut);
+
+/**
+@brief Present in every header, used to identify a UEFI structure.
+*/
+typedef struct EfiTableHeader
+{
+ UInt64 Signature;
+ UInt32 Revision;
+ UInt32 HeaderSize;
+ UInt32 Crc32;
+ UInt32 Reserved;
+} EfiTableHeader;
+
+#define EFI_ACPI_TABLE_PROTOCOL_GUID \
+ { \
+ 0xffe06bdd, 0x6107, 0x46a6, \
+ { \
+ 0x7b, 0xb2, 0x5a, 0x9c, 0x7e, 0xc5, 0x27, 0x5c \
+ } \
+ }
+
+#define EFI_LOAD_FILE_PROTOCOL_GUID \
+ { \
+ 0x56EC3091, 0x954C, 0x11d2, \
+ { \
+ 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \
+ } \
+ }
+
+#define EFI_LOAD_FILE2_PROTOCOL_GUID \
+ { \
+ 0x4006c0c1, 0xfcb3, 0x403e, \
+ { \
+ 0x99, 0x6d, 0x4a, 0x6c, 0x87, 0x24, 0xe0, 0x6d \
+ } \
+ }
+
+#define EFI_LOADED_IMAGE_PROTOCOL_GUID \
+ { \
+ 0x5B1B31A1, 0x9562, 0x11d2, \
+ { \
+ 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B \
+ } \
+ }
+
+#define EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID \
+ { \
+ 0x9042a9de, 0x23dc, 0x4a38, \
+ { \
+ 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a \
+ } \
+ }
+
+#define EFI_LOADED_IMAGE_PROTOCOL_REVISION 0x1000
+
+#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \
+ { \
+ 0x0964e5b22, 0x6459, 0x11d2, \
+ { \
+ 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \
+ } \
+ }
+
+#define EFI_LOADED_IMAGE_DEVICE_PATH_PROTOCOL_GUID \
+ { \
+ 0xbc62157e, 0x3e33, 0x4fec, \
+ { \
+ 0x99, 0x20, 0x2d, 0x3b, 0x36, 0xd7, 0x50, 0xdf \
+ } \
+ }
+
+#define EFI_DEVICE_PATH_PROTOCOL_GUID \
+ { \
+ 0x9576e91, 0x6d3f, 0x11d2, \
+ { \
+ 0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b \
+ } \
+ }
+
+#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \
+ { \
+ 0x0964e5b22, 0x6459, 0x11d2, \
+ { \
+ 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \
+ } \
+ }
+
+typedef UInt64(EfiImageUnload)(EfiHandlePtr ImageHandle);
+
+enum
+{
+ kPixelRedGreenBlueReserved8BitPerColor,
+ kPixelBlueGreenRedReserved8BitPerColor,
+ kPixelBitMask,
+ kPixelBltOnly,
+ kPixelFormatMax
+};
+
+typedef struct EfiBitmask
+{
+ UInt32 RedMask;
+ UInt32 GreenMask;
+ UInt32 BlueMask;
+ UInt32 ReservedMask;
+} EfiBitmask;
+
+typedef struct
+{
+ UInt8 Blue;
+ UInt8 Green;
+ UInt8 Red;
+ UInt8 Reserved;
+} EfiGraphicsOutputBltPixel;
+
+typedef enum EfiGraphicsOutputProtocolBltOperation
+{
+ EfiBltVideoFill,
+ EfiBltVideoToBltBuffer,
+ EfiBltBufferToVideo,
+ EfiBltVideoToVideo,
+ EfiGraphicsOutputBltOperationMax
+} EfiGraphicsOutputProtocolBltOperation;
+
+typedef struct EfiGraphicsOutputProtocolModeInformation
+{
+ UInt32 Version;
+ UInt32 HorizontalResolution;
+ UInt32 VerticalResolution;
+ UInt32 PixelFormat;
+ EfiBitmask PixelInformation;
+ UInt32 PixelsPerScanLine;
+} EfiGraphicsOutputProtocolModeInformation;
+
+typedef UInt64(EFI_API* EfiGraphicsOutputProtocolQueryMode)(
+ EfiGraphicsOutputProtocol* Self, UInt32 ModeNumber, UInt32* SizeOfInfo, EfiGraphicsOutputProtocolModeInformation** Info);
+
+typedef UInt64(EFI_API* EfiGraphicsOutputProtocolSetMode)(
+ EfiGraphicsOutputProtocol* Self, UInt32 ModeNumber);
+
+typedef UInt64(EFI_API* EfiGraphicsOutputProtocolBlt)(
+ EfiGraphicsOutputProtocol* Self, EfiGraphicsOutputBltPixel* BltBuffer, EfiGraphicsOutputProtocolBltOperation BltOperation, UInt32 SourceX, UInt32 SourceY, UInt32 DestinationX, UInt32 DestinationY, UInt32 Width, UInt32 Height, UInt32 Delta);
+
+typedef struct
+{
+ UInt32 MaxMode;
+ UInt32 Mode;
+ EfiGraphicsOutputProtocolModeInformation* Info;
+ UInt32 SizeOfInfo;
+ UIntPtr FrameBufferBase;
+ UInt32 FrameBufferSize;
+} EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE;
+
+typedef struct EfiGraphicsOutputProtocol
+{
+ EfiGraphicsOutputProtocolQueryMode QueryMode;
+ EfiGraphicsOutputProtocolSetMode SetMode;
+ EfiGraphicsOutputProtocolBlt Blt;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE* Mode;
+} EfiGraphicsOutputProtocol;
+
+typedef struct EfiLoadImageProtocol
+{
+ UInt32 Revision;
+ EfiHandlePtr ParentHandle;
+ EfiSystemTable* SystemTable;
+
+ // Source location of the image
+ EfiHandlePtr DeviceHandle;
+ EfiDevicePathProtocol* FilePath;
+ Void* Reserved;
+
+ // Image’s load options
+ UInt32 LoadOptionsSize;
+ Void* LoadOptions;
+
+ // Location where image was loaded
+ Void* ImageBase;
+ UInt64 ImageSize;
+ EfiMemoryType ImageCodeType;
+ EfiMemoryType ImageDataType;
+ EfiImageUnload Unload;
+} EfiLoadImageProtocol;
+
+typedef struct EfiLoadFileProtocol
+{
+ EfiLoadFile LoadFile;
+} EfiLoadFileProtocol;
+
+typedef struct EfiDevicePathProtocol
+{
+ UInt8 Kind;
+ UInt8 SubType;
+ UInt8 Length[2];
+} EfiDevicePathProtocol;
+
+typedef struct EfiFileDevicePathProtocol
+{
+ EfiDevicePathProtocol Proto;
+
+ ///
+ /// File Path of this struct
+ ///
+ WideChar Path[kPathLen];
+} EfiFileDevicePathProtocol;
+
+typedef UInt64(EFI_API* EfiExitBootServices)(VoidPtr ImageHandle,
+ UInt32 MapKey);
+
+typedef UInt64(EFI_API* EfiAllocatePages)(EfiAllocateType AllocType,
+ EfiMemoryType MemType,
+ UInt32 Count,
+ EfiPhysicalAddress* Memory);
+
+typedef UInt64(EFI_API* EfiFreePages)(EfiPhysicalAddress* Memory, UInt32 Pages);
+
+typedef UInt64(EFI_API* EfiGetMemoryMap)(UInt32* MapSize,
+ EfiMemoryDescriptor* DescPtr,
+ UInt32* MapKey,
+ UInt32* DescSize,
+ UInt32* DescVersion);
+
+/**
+ * @brief GUID type, something you can also find in CFKit.
+ */
+typedef struct EfiGUID EFI_FINAL
+{
+ UInt32 Data1;
+ UInt16 Data2;
+ UInt16 Data3;
+ UInt8 Data4[8];
+} EfiGUID;
+
+/***
+ * Protocol stuff...
+ */
+
+#define EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID \
+ { \
+ 0x387477c1, 0x69c7, 0x11d2, \
+ { \
+ 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \
+ } \
+ }
+
+/** some helpers */
+#define EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL 0x00000001
+#define EFI_OPEN_PROTOCOL_GET_PROTOCOL 0x00000002
+#define EFI_OPEN_PROTOCOL_TEST_PROTOCOL 0x00000004
+#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER 0x00000008
+#define EFI_OPEN_PROTOCOL_BY_DRIVER 0x00000010
+#define EFI_OPEN_PROTOCOL_EXCLUSIVE 0x00000020
+
+typedef UInt64(EFI_API* EfiLocateProtocol)(EfiGUID* Protocol,
+ VoidPtr Registration,
+ VoidPtr* Interface);
+
+typedef UInt64(EFI_API* EfiOpenProtocol)(EfiHandlePtr Handle, EfiGUID* Guid, VoidPtr* Interface, EfiHandlePtr AgentHandle, EfiHandlePtr ControllerHandle, UInt32 Attributes);
+
+typedef UInt64(EFI_API* EfiEnableCursor)(EfiSimpleTextOutputProtocol* Self, Boolean Visible);
+
+/**
+@name EfiBootServices
+@brief UEFI Boot Services record, it contains functions necessary to a
+firmware level application.
+*/
+typedef struct EfiBootServices
+{
+ EfiTableHeader SystemTable;
+ VoidPtr RaiseTPL;
+ VoidPtr RestoreTPL;
+ EfiAllocatePages AllocatePages;
+ EfiFreePages FreePages;
+ EfiGetMemoryMap GetMemoryMap;
+ EfiAllocatePool AllocatePool;
+ EfiFreePool FreePool;
+ VoidPtr CreateEvent;
+ VoidPtr SetTimer;
+ VoidPtr WaitForEvent;
+ VoidPtr SignalEvent;
+ VoidPtr CloseEvent;
+ VoidPtr CheckEvent;
+ VoidPtr InstallProtocolInterface;
+ VoidPtr ReinstallProtocolInterface;
+ VoidPtr UninstallProtocolInterface;
+ EfiHandleProtocol HandleProtocol;
+ VoidPtr Reserved;
+ VoidPtr RegisterProtocolNotify;
+ VoidPtr LocateHandle;
+ EfiLocateDevicePath LocateDevicePath;
+ VoidPtr InstallConfigurationTable;
+ EfiLoadImage LoadImage;
+ EfiStartImage StartImage;
+ VoidPtr Exit;
+ VoidPtr UnloadImage;
+ EfiExitBootServices ExitBootServices;
+ VoidPtr GetNextMonotonicCount;
+ VoidPtr Stall;
+ EfiStatusType(EFI_API* SetWatchdogTimer)(UInt32 Timeout, UInt64 WatchdogCode, UInt32 DataSize, EfiCharType* Data);
+ VoidPtr ConnectController;
+ VoidPtr DisconnectController;
+ EfiOpenProtocol OpenProtocol;
+ VoidPtr CloseProtocol;
+ VoidPtr OpenProtocolInformation;
+ VoidPtr ProtocolsPerHandle;
+ VoidPtr LocateHandleBuffer;
+ EfiLocateProtocol LocateProtocol;
+ VoidPtr InstallMultipleProtocolInterfaces;
+ VoidPtr UninstallMultipleProtocolInterfaces;
+ EfiCalculateCrc32 CalculateCrc32;
+ EfiCopyMem CopyMem;
+ EfiSetMem SetMem;
+ VoidPtr CreateEventEx;
+} EfiBootServices;
+
+#define kEntireDevPath 0xFF
+#define kThisInstancePath 0x01
+
+/**
+@brief PrintF like protocol.
+*/
+typedef struct EfiSimpleTextOutputProtocol
+{
+ VoidPtr Reset;
+ EfiTextString OutputString;
+ VoidPtr TestString;
+ VoidPtr QueryMode;
+ VoidPtr SetMode;
+ EfiTextAttrib SetAttribute;
+ EfiTextClear ClearScreen;
+ VoidPtr SetCursorPosition;
+ EfiEnableCursor EnableCursor;
+ VoidPtr Mode;
+} EfiSimpleTextOutputProtocol;
+
+typedef struct
+{
+ UInt16 ScanCode;
+ EfiChar16Type UnicodeChar;
+} EfiInputKey;
+
+typedef EfiStatusType(EFI_API* EfiInputReadKey)(
+ IN EfiSimpleTextInputProtocol* This,
+ OUT EfiInputKey* Key);
+
+typedef EfiStatusType(EFI_API* EfiInputReset)(
+ IN EfiSimpleTextInputProtocol* This,
+ IN Boolean ExtendedChk);
+
+typedef EfiStatusType(EFI_API* EfiWaitForEvent)(
+ IN UInt32 NumberOfEvents,
+ IN VoidPtr Event,
+ OUT UInt32* Index);
+
+typedef struct EfiSimpleTextInputProtocol
+{
+ EfiInputReset Reset;
+ EfiInputReadKey ReadKeyStroke;
+ EfiWaitForEvent WaitForKey;
+} EfiSimpleTextInputProtocol;
+
+/// @biref Open Volume procedure ptr.
+typedef UInt64(EFI_API* EfiOpenVolume)(struct EfiSimpleFilesystemProtocol*,
+ struct EfiFileProtocol**);
+
+struct EfiSimpleFilesystemProtocol
+{
+ UInt64 Revision;
+ EfiOpenVolume OpenVolume;
+};
+
+/**
+@brief The Structure that they give you when booting.
+*/
+typedef struct EfiSystemTable
+{
+ EfiTableHeader SystemHeader;
+ WideChar* FirmwareVendor;
+ UInt32 FirmwareRevision;
+ EfiHandlePtr ConsoleInHandle;
+ EfiSimpleTextInputProtocol* ConIn;
+ EfiHandlePtr ConsoleOutHandle;
+ EfiSimpleTextOutputProtocol* ConOut;
+ EfiHandlePtr StandardErrorHandle;
+ VoidPtr StdErr;
+ VoidPtr RuntimeServices;
+ EfiBootServices* BootServices;
+ UInt64 NumberOfTableEntries;
+ /// The configuration table (contains the RSD PTR entry.)
+ struct
+ {
+ EfiGUID VendorGUID;
+ VoidPtr VendorTable;
+ }* ConfigurationTable;
+} EfiSystemTable;
+
+#define kEfiOk 0
+#define kEfiFail -1
+#define kBufferTooSmall 5
+
+#define EFI_EXTERN_C extern "C"
+
+typedef struct EfiIPV4
+{
+ UInt8 Addr[4];
+} EfiIPV4;
+
+///
+/// 16-byte buffer. An IPv6 internet protocol address.
+///
+typedef struct EfiIPV6
+{
+ UInt8 Addr[16];
+} EfiIPV6;
+
+#define kEFIYellow (0x01 | 0x02 | 0x04 | 0x08)
+
+#ifdef __x86_64
+#define __EFI_x86_64__ 1
+#endif // __x86_64
+
+enum
+{
+ kEFIHwDevicePath = 0x01,
+ kEFIAcpiDevicePath = 0x02,
+ kEFIMessaingDevicePath = 0x03,
+ kEFIMediaDevicePath = 0x04,
+ kEFIBiosBootPath = 0x05,
+ kEFIEndOfPath = 0x06,
+ kEFICount = 6,
+};
+
+#define END_DEVICE_PATH_TYPE 0x7f
+#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xFF
+#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01
+
+#define kEfiOffsetOf(T, F) __builtin_offsetof(T, F)
+
+/// File I/O macros
+
+#define kEFIFileRead 0x0000000000000001
+#define kEFIFileWrite 0x0000000000000002
+#define kEFIFileCreate 0x0000000000000000
+
+#define kEFIReadOnly 0x01
+#define kEFIHidden 0x02
+#define kEFISystem 0x04
+#define kEFIReserved 0x08
+#define kEFIDirectory 0x10
+#define kEFIArchive 0x20
+
+#define EFI_FILE_PROTOCOL_REVISION 0x00010000
+#define EFI_FILE_PROTOCOL_REVISION2 0x00020000
+#define EFI_FILE_PROTOCOL_LATEST_REVISION EFI_FILE_PROTOCOL_REVISION2
+
+#define EFI_EXTRA_DESCRIPTOR_SIZE 8
+
+#define EFI_MP_SERVICES_PROTOCOL_GUID \
+ { \
+ 0x3fdda605, 0xa76e, 0x4f46, \
+ { \
+ 0xad, 0x29, 0x12, 0xf4, \
+ 0x53, 0x1b, 0x3d, 0x08 \
+ } \
+ }
+
+#define PROCESSOR_AS_BSP_BIT 0x00000001
+#define PROCESSOR_ENABLED_BIT 0x00000002
+#define PROCESSOR_HEALTH_STATUS_BIT 0x00000004
+
+#define END_OF_CPU_LIST 0xffffffff
+
+typedef struct EfiIOToken
+{
+ //
+ // If Event is NULL, then blocking I/O is performed.
+ // If Event is not NULL and non-blocking I/O is supported, then non-blocking
+ // I/O is performed, and Event will be signaled when the read request is
+ // completed. The caller must be prepared to handle the case where the
+ // callback associated with Event occurs before the original asynchronous I/O
+ // request call returns.
+ //
+ UInt64 Event;
+
+ //
+ // Defines whether or not the signaled event encountered an error.
+ //
+ UInt64 Status;
+
+ //
+ // For OpenEx(): Not Used, ignored.
+ // For ReadEx(): On input, the size of the Buffer. On output, the amount of
+ // data returned in Buffer.
+ // In both cases, the size is measured in bytes.
+ // For WriteEx(): On input, the size of the Buffer. On output, the amount of
+ // data actually written.
+ // In both cases, the size is measured in bytes.
+ // For FlushEx(): Not used, ignored.
+ //
+ UInt32 BufferSize;
+
+ //
+ // For OpenEx(): Not Used, ignored.
+ // For ReadEx(): The buffer into which the data is read.
+ // For WriteEx(): The buffer of data to write.
+ // For FlushEx(): Not Used, ignored.
+ //
+ Void* Buffer;
+} EfiIOToken;
+
+typedef struct EfiFileProtocol
+{
+ UInt64 Revision;
+
+ EfiStatusType(EFI_API* Open)(struct EfiFileProtocol* Self,
+ struct EfiFileProtocol** Out,
+ EfiCharType* CharType,
+ UInt64 OpenMode,
+ UInt64 Attrib);
+
+ EfiStatusType(EFI_API* Close)(struct EfiFileProtocol* Self);
+
+ EfiStatusType(EFI_API* Delete)(struct EfiFileProtocol* Self);
+
+ EfiStatusType(EFI_API* Read)(struct EfiFileProtocol* Self, UInt64* BufSize, VoidPtr BufOut);
+
+ EfiStatusType(EFI_API* Write)(struct EfiFileProtocol* Self, UInt64* BufSize, VoidPtr BufOut);
+
+ EfiStatusType(EFI_API* GetPosition)(EfiFileProtocol* Self, UInt64* Position);
+
+ EfiStatusType(EFI_API* SetPosition)(EfiFileProtocol* Self, UInt64* Position);
+
+ EfiStatusType(EFI_API* GetInfo)(struct EfiFileProtocol*, struct EfiGUID*, UInt32*, void*);
+
+ EfiStatusType(EFI_API* SetInfo)(struct EfiFileProtocol*, struct EfiGUID*, UInt32*, void*);
+
+ EfiStatusType(EFI_API* Flush)(EfiFileProtocol*);
+
+ EfiStatusType(EFI_API* OpenEx)(EfiFileProtocol* Self,
+ EfiFileProtocol** OutHandle,
+ EfiCharType* Path,
+ UInt64 Mode,
+ UInt64 Attrib,
+ struct EfiIOToken* Token);
+
+ EfiStatusType(EFI_API* ReadEx)(EfiFileProtocol* Self,
+ struct EfiIOToken* Token);
+
+ EfiStatusType(EFI_API* WriteEx)(EfiFileProtocol* Self,
+ struct EfiIOToken* Token);
+
+ EfiStatusType(EFI_API* FlushEx)(EfiFileProtocol* Self,
+ struct EfiIOToken* Token);
+} EfiFileProtocol, *EfiFileProtocolPtr;
+
+typedef UInt64 EfiCursorType;
+
+typedef struct EfiTime
+{
+ UInt16 Year;
+ UInt8 Month;
+ UInt8 Day;
+ UInt8 Hour;
+ UInt8 Minute;
+ UInt8 Second;
+ UInt8 Pad1;
+ UInt32 Nanosecond;
+ Int16 TimeZone;
+ UInt8 Daylight;
+ UInt8 Pad2;
+} EfiTime;
+
+#define EFI_FILE_INFO_GUID \
+ { \
+ 0x09576e92, 0x6d3f, 0x11d2, \
+ { \
+ 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b \
+ } \
+ }
+
+struct EfiFileInfo EFI_FINAL
+{
+ /// @brief Structure size.
+ UInt64 Size;
+ /// @brief File size.
+ UInt64 FileSize;
+ /// @brief Physical size on disk.
+ UInt64 PhysicalSize;
+ /// @brief Create time.
+ EfiTime CreateTime;
+ /// @brief Last access time.
+ EfiTime LastAccessTime;
+ /// @brief Edit time.
+ EfiTime EditTime;
+ /// @brief Attributes.
+ UInt64 Attribute;
+ /// @brief VLA file name.
+ WideChar FileName[1];
+};
+
+//*******************************************************
+// EFI_CPU_PHYSICAL_LOCATION
+// @note As in the EFI specs.
+//*******************************************************
+typedef struct _EfiCPUPhyiscalLocation
+{
+ UInt32 Package;
+ UInt32 Core;
+ UInt32 Thread;
+} EfiCPUPhyiscalLocation;
+
+typedef union _EfiExtendedProcessorInformation {
+ EfiCPUPhyiscalLocation Location2;
+} EfiExtendedProcessorInformation;
+
+typedef struct _EfiProcessorInformation
+{
+ UInt64 ProcessorId;
+ UInt32 StatusFlag;
+ EfiCPUPhyiscalLocation Location;
+ EfiExtendedProcessorInformation ExtendedInformation;
+} EfiProcessorInformation;
+
+typedef EfiStatusType EFI_API (*EfiMpServicesGetNumberOfProcessors)(
+ IN struct _EfiMpServicesProtocol* Self,
+ OUT UInt32* NumberOfProcessors,
+ OUT UInt32* NumberOfEnabledProcessors);
+
+typedef EfiStatusType EFI_API (*EfiMpServicesGetProcessorInfo)(
+ IN struct _EfiMpServicesProtocol* Self,
+ IN UInt32* ProcessorNumber,
+ OUT struct _EfiProcessorInformation* NumberOfEnabledProcessors);
+
+typedef void EFI_API (*EFI_AP_PROCEDURE)(
+ IN VoidPtr ProcedureArgument);
+
+typedef EfiStatusType EFI_API (*EfiMpServicesStartupAllAPS)(
+ IN struct _EfiMpServicesProtocol* Self,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN Boolean SingleThread,
+ IN VoidPtr WaitEvent OPTIONAL, // EFI_EVENT first, but unused here.
+ IN UInt32 TimeoutInMicroSeconds,
+ IN Void* ProcedureArgument OPTIONAL,
+ OUT UInt32** FailedCpuList OPTIONAL);
+
+typedef EfiStatusType EFI_API (*EfiMpServicesSwitchBSP)(
+ IN struct _EfiMpServicesProtocol* Self,
+ IN UInt32 ProcessorNumber,
+ IN Boolean EnableOldBSP);
+
+typedef EfiStatusType EFI_API (*EfiMpServicesStartupThisAP)(
+ IN struct _EfiMpServicesProtocol* Self,
+ IN EFI_AP_PROCEDURE Procedure,
+ IN UInt32 ProcessorNumber,
+ IN VoidPtr WaitEvent OPTIONAL,
+ IN UInt32 TimeoutInMicroseconds,
+ IN Void* ProcedureArgument OPTIONAL,
+ OUT Boolean* Finished OPTIONAL);
+
+typedef EfiStatusType EFI_API (*EfiMpServicesDisableThisAP)(
+ IN struct _EfiMpServicesProtocol* Self,
+ IN UInt32 ProcessorNumber,
+ IN Boolean EnableAP,
+ IN UInt32* HealthFlag OPTIONAL);
+
+typedef EfiStatusType EFI_API (*EfiMpServicesWhoAmI)(
+ IN struct _EfiMpServicesProtocol* Self,
+ OUT UInt32* ProcessorNumber);
+
+typedef struct _EfiMpServicesProtocol
+{
+ EfiMpServicesGetNumberOfProcessors GetNumberOfProcessors;
+ EfiMpServicesGetProcessorInfo GetProcessorInfo;
+ EfiMpServicesStartupAllAPS StartupAllAPs;
+ EfiMpServicesStartupThisAP StartupThisAP;
+ EfiMpServicesSwitchBSP SwitchBSP;
+ EfiMpServicesDisableThisAP EnableDisableAP;
+ EfiMpServicesWhoAmI WhoAmI;
+} EfiMpServicesProtocol;
+
+#endif // ifndef FIRMWARE_KIT_EFI_H
diff --git a/dev/Kernel/FirmwareKit/EFI/NS.h b/dev/Kernel/FirmwareKit/EFI/NS.h
new file mode 100644
index 00000000..a5f21f21
--- /dev/null
+++ b/dev/Kernel/FirmwareKit/EFI/NS.h
@@ -0,0 +1,20 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+namespace Firmware::Detail::EFI
+{
+ using namespace Kernel;
+
+ EXTERN_C
+ {
+#include <FirmwareKit/EFI/EFI.h>
+ }
+
+} // namespace Firmware::Detail::EFI
diff --git a/dev/Kernel/FirmwareKit/GPT.h b/dev/Kernel/FirmwareKit/GPT.h
new file mode 100644
index 00000000..590b63ef
--- /dev/null
+++ b/dev/Kernel/FirmwareKit/GPT.h
@@ -0,0 +1,57 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+#include <FirmwareKit/EFI/EFI.h>
+
+#define kSectorSizeGPT 512
+
+namespace Kernel
+{
+ struct GPT_GUID;
+ struct GPT_PARTITION_TABLE;
+ struct GPT_PARTITION_ENTRY;
+
+ /// @brief GPT GUID structure.
+ typedef struct GPT_GUID
+ {
+ Kernel::UInt32 Data1;
+ Kernel::UInt16 Data2;
+ Kernel::UInt16 Data3;
+ Kernel::UInt8 Data4[8];
+ } GPT_GUID;
+
+ struct PACKED GPT_PARTITION_TABLE final
+ {
+ Char PartitionName[8];
+ UInt32 Revision;
+ UInt32 HeaderSize;
+ UInt32 ChecksumCRC32;
+ UInt32 Reserved1;
+ UInt64 LBAHeader;
+ UInt64 LBAAltHeader;
+ UInt64 FirstGPTEntry;
+ UInt64 LastGPTEntry;
+ GPT_GUID Guid;
+ UInt64 StartingLBA;
+ UInt32 NumPartitionEntries;
+ UInt32 SizeOfEntries;
+ UInt32 CRC32PartEntry;
+ UInt8 Reserved2[kSectorSizeGPT];
+ };
+
+ struct PACKED GPT_PARTITION_ENTRY
+ {
+ GPT_GUID PartitionTypeGUID;
+ GPT_GUID UniquePartitionGUID;
+ UInt64 StartLBA;
+ UInt64 EndLBA;
+ UInt64 Attributes;
+ UInt8 Name[72];
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/FirmwareKit/Handover.h b/dev/Kernel/FirmwareKit/Handover.h
new file mode 100644
index 00000000..d9af3766
--- /dev/null
+++ b/dev/Kernel/FirmwareKit/Handover.h
@@ -0,0 +1,108 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+/**
+ * @file Handover.h
+ * @author Amlal EL Mahrouss (amlalelmahrouss@icloud.com)
+ * @brief The handover boot protocol.
+ * @version 1.15
+ * @date 2024-02-23
+ *
+ * @copyright Copyright (c) 2024, Amlal EL Mahrouss
+ *
+ */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+#define kHandoverMagic 0xBADCC
+#define kHandoverVersion 0x0117
+
+/* Initial bitmap pointer location and size. */
+#define kHandoverBitMapSz (gib_cast(4))
+#define kHandoverStructSz sizeof(HEL::BootInfoHeader)
+
+namespace Kernel::HEL
+{
+ /**
+ @brief The executable type enum.
+ */
+ enum
+ {
+ kTypeKernel = 100,
+ kTypeKernelDriver = 101,
+ kTypeRsrc = 102,
+ kTypeInvalid = 103,
+ kTypeCount = 4,
+ };
+
+ /**
+ @brief The executable architecture enum.
+ */
+
+ enum
+ {
+ kArchAMD64 = 122,
+ kArchARM64 = 123,
+ kArchRISCV = 124,
+ kArchCount = 3,
+ };
+
+ struct BootInfoHeader final
+ {
+ UInt64 f_Magic;
+ UInt64 f_Version;
+
+ VoidPtr f_BitMapStart;
+ SizeT f_BitMapSize;
+
+ VoidPtr f_PageStart;
+
+ VoidPtr f_KernelImage;
+ SizeT f_KernelSz;
+ VoidPtr f_StartupImage;
+ SizeT f_StartupSz;
+
+ WideChar f_FirmwareVendorName[32];
+ SizeT f_FirmwareVendorLen;
+
+ VoidPtr f_FirmwareCustomTables[2]; // On EFI 0: BS 1: ST
+
+ struct
+ {
+ VoidPtr f_SmBios;
+ VoidPtr f_VendorPtr;
+ VoidPtr f_MpPtr;
+ Bool f_MultiProcessingEnabled;
+ } f_HardwareTables;
+
+ struct
+ {
+ UIntPtr f_The;
+ SizeT f_Size;
+ UInt32 f_Width;
+ UInt32 f_Height;
+ UInt32 f_PixelFormat;
+ UInt32 f_PixelPerLine;
+ } f_GOP;
+
+ UInt64 f_FirmwareSpecific[8];
+ };
+
+ enum
+ {
+ kHandoverSpecificKind,
+ kHandoverSpecificAttrib,
+ kHandoverSpecificMemoryEfi,
+ };
+
+ /// @brief Alias of bootloader main type.
+ typedef Int32 (*HandoverProc)(BootInfoHeader* boot_info);
+} // namespace Kernel::HEL
+
+/// @brief Bootloader information header global variable.
+inline Kernel::HEL::BootInfoHeader* kHandoverHeader = nullptr;
diff --git a/dev/Kernel/HALKit/.gitkeep b/dev/Kernel/HALKit/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/HALKit/.gitkeep
diff --git a/dev/Kernel/HALKit/AMD64/CPUID.h b/dev/Kernel/HALKit/AMD64/CPUID.h
new file mode 100644
index 00000000..abe1cdc1
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/CPUID.h
@@ -0,0 +1,86 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: CPUID.h
+ Purpose: CPUID flags.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+enum CPUFeatureEnum
+{
+ kCPUFeatureSSE3 = 1 << 0,
+ kCPUFeaturePCLMUL = 1 << 1,
+ kCPUFeatureDTES64 = 1 << 2,
+ kCPUFeatureMONITOR = 1 << 3,
+ kCPUFeatureDS_CPL = 1 << 4,
+ kCPUFeatureVMX = 1 << 5,
+ kCPUFeatureSMX = 1 << 6,
+ kCPUFeatureEST = 1 << 7,
+ kCPUFeatureTM2 = 1 << 8,
+ kCPUFeatureSSSE3 = 1 << 9,
+ kCPUFeatureCID = 1 << 10,
+ kCPUFeatureSDBG = 1 << 11,
+ kCPUFeatureFMA = 1 << 12,
+ kCPUFeatureCX16 = 1 << 13,
+ kCPUFeatureXTPR = 1 << 14,
+ kCPUFeaturePDCM = 1 << 15,
+ kCPUFeaturePCID = 1 << 17,
+ kCPUFeatureDCA = 1 << 18,
+ kCPUFeatureSSE4_1 = 1 << 19,
+ kCPUFeatureSSE4_2 = 1 << 20,
+ kCPUFeatureX2APIC = 1 << 21,
+ kCPUFeatureMOVBE = 1 << 22,
+ kCPUFeaturePOP3C = 1 << 23,
+ kCPUFeatureECXTSC = 1 << 24,
+ kCPUFeatureAES = 1 << 25,
+ kCPUFeatureXSAVE = 1 << 26,
+ kCPUFeatureOSXSAVE = 1 << 27,
+ kCPUFeatureAVX = 1 << 28,
+ kCPUFeatureF16C = 1 << 29,
+ kCPUFeatureRDRAND = 1 << 30,
+ kCPUFeatureHYPERVISOR = 1 << 31,
+ kCPUFeatureFPU = 1 << 0,
+ kCPUFeatureVME = 1 << 1,
+ kCPUFeatureDE = 1 << 2,
+ kCPUFeaturePSE = 1 << 3,
+ kCPUFeatureEDXTSC = 1 << 4,
+ kCPUFeatureMSR = 1 << 5,
+ kCPUFeaturePAE = 1 << 6,
+ kCPUFeatureMCE = 1 << 7,
+ kCPUFeatureCX8 = 1 << 8,
+ kCPUFeatureAPIC = 1 << 9,
+ kCPUFeatureSEP = 1 << 11,
+ kCPUFeatureMTRR = 1 << 12,
+ kCPUFeaturePGE = 1 << 13,
+ kCPUFeatureMCA = 1 << 14,
+ kCPUFeatureCMOV = 1 << 15,
+ kCPUFeaturePAT = 1 << 16,
+ kCPUFeaturePSE36 = 1 << 17,
+ kCPUFeaturePSN = 1 << 18,
+ kCPUFeatureCLFLUSH = 1 << 19,
+ kCPUFeatureDS = 1 << 21,
+ kCPUFeatureACPI = 1 << 22,
+ kCPUFeatureMMX = 1 << 23,
+ kCPUFeatureFXSR = 1 << 24,
+ kCPUFeatureSSE = 1 << 25,
+ kCPUFeatureSSE2 = 1 << 26,
+ kCPUFeatureSS = 1 << 27,
+ kCPUFeatureHTT = 1 << 28,
+ kCPUFeatureTM = 1 << 29,
+ kCPUFeatureIA64 = 1 << 30,
+ kCPUFeaturePBE = 1 << 31
+};
+
+namespace Kernel
+{
+ typedef Int64 CPUID;
+} // namespace Kernel
diff --git a/dev/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cc b/dev/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cc
new file mode 100644
index 00000000..a1edf6f1
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalACPIFactoryInterface.cc
@@ -0,0 +1,126 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <Mod/ACPI/ACPIFactoryInterface.h>
+#include <HALKit/AMD64/Processor.h>
+#include <NewKit/KString.h>
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/Heap.h>
+
+namespace Kernel
+{
+ namespace Detail
+ {
+ struct FADT final : public SDT
+ {
+ UInt32 FirmwareCtrl;
+ UInt32 Dsdt;
+
+ // field used in ACPI 1.0; no longer in use, for compatibility only
+ UInt8 Reserved;
+
+ UInt8 PreferredPowerManagementProfile;
+ UInt16 SCI_Interrupt;
+ UInt32 SMI_CommandPort;
+ UInt8 AcpiEnable;
+ UInt8 AcpiDisable;
+ UInt8 S4BIOS_REQ;
+ UInt8 PSTATE_Control;
+ UInt32 PM1aEventBlock;
+ UInt32 PM1bEventBlock;
+ UInt32 PM1aControlBlock;
+ UInt32 PM1bControlBlock;
+ UInt32 PM2ControlBlock;
+ UInt32 PMTimerBlock;
+ UInt32 GPE0Block;
+ UInt32 GPE1Block;
+ UInt8 PM1EventLength;
+ UInt8 PM1ControlLength;
+ UInt8 PM2ControlLength;
+ UInt8 PMTimerLength;
+ UInt8 GPE0Length;
+ UInt8 GPE1Length;
+ UInt8 GPE1Base;
+ UInt8 CStateControl;
+ UInt16 WorstC2Latency;
+ UInt16 WorstC3Latency;
+ UInt16 FlushSize;
+ UInt16 FlushStride;
+ UInt8 DutyOffset;
+ UInt8 DutyWidth;
+ UInt8 DayAlarm;
+ UInt8 MonthAlarm;
+ UInt8 Century;
+
+ // reserved in ACPI 1.0; used since ACPI 2.0+
+ UInt16 BootArchitecturkMMFlags;
+
+ UInt8 Reserved2;
+ UInt32 Flags;
+
+ // 12 byte structure; see below for details
+ ACPI_ADDRESS ResetReg;
+
+ UInt8 ResetValue;
+ UInt8 Reserved3[3];
+
+ // 64bit pointers - Available on ACPI 2.0+
+ UInt64 X_FirmwareControl;
+ UInt64 X_Dsdt;
+
+ ACPI_ADDRESS X_PM1aEventBlock;
+ ACPI_ADDRESS X_PM1bEventBlock;
+ ACPI_ADDRESS X_PM1aControlBlock;
+ ACPI_ADDRESS X_PM1bControlBlock;
+ ACPI_ADDRESS X_PM2ControlBlock;
+ ACPI_ADDRESS X_PMTimerBlock;
+ ACPI_ADDRESS X_GPE0Block;
+ ACPI_ADDRESS X_GPE1Block;
+ };
+ } // namespace Detail
+
+ ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr)
+ : fRsdp(rsp_ptr), fEntries(0)
+ {
+ }
+
+ Void ACPIFactoryInterface::Shutdown()
+ {
+ failed_to_shutdown:
+ // in case no acpi mode, or it's not available.
+ while (Yes)
+ {
+ asm volatile("cli; hlt");
+ }
+ }
+
+ /// @brief Reboot machine in either ACPI or by triple faulting.
+ /// @return nothing it's a reboot.
+ Void ACPIFactoryInterface::Reboot()
+ {
+ failed_to_reboot:
+ asm volatile(".intel_syntax noprefix; "
+ "rt_reset_hardware:; "
+ "cli; "
+ "wait_gate1: ; "
+ "in al,0x64 ; "
+ "and al,2 ; "
+ "jnz wait_gate1 ; "
+ "mov al,0x0D1 ; "
+ "out 0x64,al ; "
+ "wait_gate2: ; "
+ "in al,0x64 ; "
+ "and al,2 ; "
+ "jnz wait_gate2 ; "
+ "mov al,0x0FE ; "
+ "out 0x60,al ; "
+ "xor rax,rax ; "
+ "lidt [rax] ; "
+ "reset_wait: ; "
+ "jmp reset_wait ; "
+ ".att_syntax; ");
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/HALKit/AMD64/HalAPICController.cc b/dev/Kernel/HALKit/AMD64/HalAPICController.cc
new file mode 100644
index 00000000..e4e35790
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalAPICController.cc
@@ -0,0 +1,39 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <Mod/ACPI/ACPIFactoryInterface.h>
+#include <HALKit/AMD64/Processor.h>
+
+#define cIOAPICRegVal (4)
+#define cIOAPICRegReg (0)
+
+namespace Kernel::HAL
+{
+ /// @brief Read from APIC controller.
+ /// @param reg register.
+ UInt32 APICController::Read(UInt32 reg) noexcept
+ {
+ MUST_PASS(this->fApic);
+
+ UInt32 volatile* io_apic = (UInt32 volatile*)this->fApic;
+ io_apic[cIOAPICRegReg] = (reg & 0xFF);
+
+ return io_apic[cIOAPICRegVal];
+ }
+
+ /// @brief Write to APIC controller.
+ /// @param reg register.
+ /// @param value value.
+ Void APICController::Write(UInt32 reg, UInt32 value) noexcept
+ {
+ MUST_PASS(this->fApic);
+
+ UInt32 volatile* io_apic = (UInt32 volatile*)this->fApic;
+
+ io_apic[cIOAPICRegReg] = (reg & 0xFF);
+ io_apic[cIOAPICRegVal] = value;
+ }
+} // namespace Kernel::HAL
diff --git a/dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc
new file mode 100644
index 00000000..4234f11e
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc
@@ -0,0 +1,279 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <Mod/ACPI/ACPIFactoryInterface.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <HALKit/AMD64/Processor.h>
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/Semaphore.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/Timer.h>
+#include <Mod/CoreGfx/TextMgr.h>
+#include <NewKit/KernelPanic.h>
+#include <KernelKit/HardwareThreadScheduler.h>
+
+#define kApicSignature "APIC"
+
+#define kAPIC_ICR_Low 0x300
+#define kAPIC_ICR_High 0x310
+#define kAPIC_SIPI_Vector 0x00500
+#define kAPIC_EIPI_Vector 0x00400
+
+#define kAPIC_BASE_MSR 0x1B
+#define kAPIC_BASE_MSR_BSP 0x100
+#define kAPIC_BASE_MSR_ENABLE 0x800
+
+/// @note: _hal_switch_context is internal
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+//! NOTE: fGSI stands 'Field Global System Interrupt'
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+namespace Kernel::HAL
+{
+ struct PROCESS_APIC_MADT;
+ struct PROCESS_CONTROL_BLOCK;
+
+ struct PROCESS_CONTROL_BLOCK final
+ {
+ HAL::StackFramePtr mFrame;
+ };
+
+ EXTERN_C Void _hal_spin_core(Void);
+
+ STATIC struct PROCESS_APIC_MADT* kMADTBlock = nullptr;
+ STATIC Bool kSMPAware = false;
+ STATIC Int64 kSMPCount = 0;
+
+ STATIC UIntPtr kApicBaseAddress = 0UL;
+
+ STATIC Int32 kSMPInterrupt = 0;
+ STATIC UInt64 kAPICLocales[kSchedProcessLimitPerTeam] = {0};
+ STATIC VoidPtr kRawMADT = nullptr;
+
+ /// @brief Multiple APIC Descriptor Table.
+ struct PROCESS_APIC_MADT final : public SDT
+ {
+ UInt32 Address; // Madt address
+ UInt8 Flags; // Madt flags
+
+ struct
+ {
+ UInt8 Type;
+ UInt8 Len;
+
+ union {
+ struct
+ {
+ UInt8 IoID;
+ UInt8 Resv;
+ UInt32 IoAddress;
+ UInt32 GISBase;
+ } IOAPIC;
+
+ struct
+ {
+ UInt8 Source;
+ UInt8 IRQSource;
+ UInt32 GSI;
+ UInt16 Flags;
+ } IOAPIC_NMI;
+
+ struct
+ {
+ UInt8 ProcessorID;
+ UInt16 Flags;
+ UInt8 LINT;
+ } LAPIC;
+
+ struct
+ {
+ UInt16 Reserved;
+ UInt64 Address;
+ } LAPIC_ADDRESS_OVERRIDE;
+
+ struct
+ {
+ UInt16 Reserved;
+ UInt32 x2APICID;
+ UInt32 Flags;
+ UInt32 AcpiID;
+ } LAPIC_ADDRESS;
+ };
+ } List[]; // Records List
+ };
+
+ ///////////////////////////////////////////////////////////////////////////////////////
+
+ /***********************************************************************************/
+ /// @brief Send IPI command to APIC.
+ /// @param apic_id programmable interrupt controller id.
+ /// @param vector vector interrupt.
+ /// @param target target APIC adress.
+ /// @return
+ /***********************************************************************************/
+
+ Void hal_send_start_ipi(UInt32 target, UInt32 apic_id)
+ {
+ Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_High, apic_id << 24);
+ Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_Low, 0x00000500 | 0x00004000 | 0x00000000);
+
+ while (Kernel::ke_dma_read<UInt32>(target, kAPIC_ICR_Low) & 0x1000)
+ {
+ ;
+ }
+ }
+
+ /***********************************************************************************/
+ /// @brief Send end IPI for CPU.
+ /// @param apic_id
+ /// @param vector
+ /// @param target
+ /// @return
+ /***********************************************************************************/
+ Void hal_send_sipi(UInt32 target, UInt32 apic_id, UInt8 vector)
+ {
+ Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_High, apic_id << 24);
+ Kernel::ke_dma_write<UInt32>(target, kAPIC_ICR_Low, 0x00000600 | 0x00004000 | 0x00000000 | vector);
+
+ while (Kernel::ke_dma_read<UInt32>(target, kAPIC_ICR_Low) & 0x1000)
+ {
+ ;
+ }
+ }
+
+ STATIC PROCESS_CONTROL_BLOCK kProcessBlocks[kSchedProcessLimitPerTeam] = {0};
+
+ EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 pid)
+ {
+ const auto process_index = pid % kSchedProcessLimitPerTeam;
+ return kProcessBlocks[process_index].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;
+
+ auto first_id = kAPICLocales[0];
+
+ hal_send_sipi(kApicBaseAddress, first_id, (UInt8)(((UIntPtr)stack_frame->BP) >> 12));
+
+ return YES;
+ }
+
+ /***********************************************************************************/
+ /// @brief Is the current config SMP aware?
+ /// @return True if YES, False if not.
+ /***********************************************************************************/
+ Bool mp_is_smp(Void) noexcept
+ {
+ return kSMPAware;
+ }
+
+ /***********************************************************************************/
+ /// @brief Assembly symbol to bootstrap AP.
+ /***********************************************************************************/
+ EXTERN_C Char* hal_ap_blob_start;
+
+ /***********************************************************************************/
+ /// @brief Assembly symbol to bootstrap AP.
+ /***********************************************************************************/
+ EXTERN_C Char* hal_ap_blob_end;
+
+ /***********************************************************************************/
+ /// @brief Fetch and enable SMP scheduler.
+ /// @param vendor_ptr SMP containing structure.
+ /***********************************************************************************/
+ Void mp_get_cores(VoidPtr vendor_ptr) noexcept
+ {
+ if (!vendor_ptr)
+ return;
+
+ if (!kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled)
+ {
+ kSMPAware = NO;
+ return;
+ }
+
+ auto hw_and_pow_int = PowerFactoryInterface(vendor_ptr);
+ kRawMADT = hw_and_pow_int.Find(kApicSignature).Leak().Leak();
+
+ kMADTBlock = reinterpret_cast<PROCESS_APIC_MADT*>(kRawMADT);
+ kSMPAware = NO;
+
+ if (kMADTBlock)
+ {
+ SizeT index = 0;
+
+ kSMPInterrupt = 0;
+ kSMPCount = 0;
+
+ kcout << "SMP: Starting APs...\r";
+
+ kApicBaseAddress = kMADTBlock->Address;
+
+ constexpr auto kMemoryAPStart = 0x7C000;
+ Char* ptr_ap_code = reinterpret_cast<Char*>(kMemoryAPStart);
+
+ SizeT hal_ap_blob_len = hal_ap_blob_end - hal_ap_blob_start;
+
+ rt_copy_memory((Char*)hal_ap_blob_start, ptr_ap_code, hal_ap_blob_len);
+
+ while (Yes)
+ {
+ if (kMADTBlock->List[index].Type > 9 ||
+ kSMPCount > kSchedProcessLimitPerTeam)
+ break;
+
+ switch (kMADTBlock->List[index].Type)
+ {
+ case 0x00: {
+ if (kMADTBlock->List[kSMPCount].LAPIC.ProcessorID < 1)
+ break;
+
+ kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].LAPIC.ProcessorID;
+ kcout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << endl;
+
+ // I'll just make the AP start from scratch here.
+
+ hal_send_start_ipi(kApicBaseAddress, kAPICLocales[kSMPCount]);
+
+ HardwareTimer timer(Kernel::Milliseconds(10));
+ timer.Wait();
+
+ /// TODO: HAL helper to create an address.
+
+ hal_send_sipi(kApicBaseAddress, kAPICLocales[kSMPCount], (UInt8)(((UIntPtr)ptr_ap_code) >> 12));
+
+ ++kSMPCount;
+ break;
+ }
+ default:
+ break;
+ }
+
+ ++index;
+ }
+
+ kcout << "SMP: number of APs: " << number(kSMPCount) << endl;
+
+ // Kernel is now SMP aware.
+ // That means that the scheduler is now available (on MP Kernels)
+
+ kSMPAware = true;
+
+ /// TODO: Notify Boot AP that it must start.
+ }
+ }
+} // namespace Kernel::HAL
+
+///////////////////////////////////////////////////////////////////////////////////////
diff --git a/dev/Kernel/HALKit/AMD64/HalApplicationProcessorGNU.s b/dev/Kernel/HALKit/AMD64/HalApplicationProcessorGNU.s
new file mode 100644
index 00000000..a8ad3b76
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalApplicationProcessorGNU.s
@@ -0,0 +1,8 @@
+.data
+
+.global hal_ap_blob_start /* Export the start symbol */
+.global hal_ap_blob_end /* Export the end symbol */
+
+hal_ap_blob_start:
+ .incbin "HALKit/AMD64/HalApplicationProcessorStartup.bin"
+hal_ap_blob_end:
diff --git a/dev/Kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm b/dev/Kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm
new file mode 100644
index 00000000..e0063965
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm
@@ -0,0 +1,77 @@
+;; /*
+;; * ========================================================
+;; *
+;; * ZKA
+;; * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+;; *
+;; * ========================================================
+;; */
+
+[bits 16]
+[org 0x7c000]
+
+hal_ap_start:
+ mov ax, 0x0
+ mov ss, ax
+ mov esp, 0x7000
+
+ cli
+ mov eax, cr0
+ or eax, 1
+ mov cr0, eax
+ jmp .hal_ap_start_flush
+.hal_ap_start_flush:
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ mov eax, cr4
+ or eax, 1 << 5
+ mov cr4, eax
+
+ mov eax, cr3
+ mov cr3, eax
+
+ mov ecx, 0xC0000080
+ rdmsr
+ or eax, 1
+ wrmsr
+
+ mov eax, cr0
+ or eax, (1 << 31)
+ mov cr0, eax
+
+ jmp 0x08:hal_ap_64bit_entry
+hal_ap_end:
+
+hal_ap_length:
+ dq hal_ap_end - hal_ap_start
+
+[bits 64]
+
+hal_ap_64bit_entry:
+ mov ax, 0x23
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+ mov rsp, [hal_ap_64bit_entry_stack_end]
+
+ push 0x33
+ push qword [hal_ap_64bit_entry_loop]
+ o64 pushf
+ push rsp
+ push 0x33
+
+ o64 iret
+
+hal_ap_64bit_entry_loop:
+ jmp $
+
+hal_ap_64bit_entry_stack:
+ resb 8196*2
+hal_ap_64bit_entry_stack_end: \ No newline at end of file
diff --git a/dev/Kernel/HALKit/AMD64/HalBoot.asm b/dev/Kernel/HALKit/AMD64/HalBoot.asm
new file mode 100644
index 00000000..59d9658e
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalBoot.asm
@@ -0,0 +1,28 @@
+;; /*
+;; * ========================================================
+;; *
+;; * ZKA
+;; * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+;; *
+;; * ========================================================
+;; */
+
+[bits 64]
+
+;; Global symbol of this unit
+[extern hal_init_platform]
+
+%define kTypeKernel 100
+%define kArchAmd64 122
+%define kHandoverMagic 0xBADCC
+
+section .ldr
+
+HandoverMagic:
+ dq kHandoverMagic
+HandoverType:
+ dw kTypeKernel
+HandoverPad:
+ dw 0
+HandoverArch:
+ dw kArchAmd64
diff --git a/dev/Kernel/HALKit/AMD64/HalCPUAMD64.cc b/dev/Kernel/HALKit/AMD64/HalCPUAMD64.cc
new file mode 100644
index 00000000..52ba46aa
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalCPUAMD64.cc
@@ -0,0 +1,101 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: HalCPU.cc
+ Purpose: Platform processor routines.
+
+------------------------------------------- */
+
+#include <HALKit/AMD64/Paging.h>
+#include <HALKit/AMD64/Processor.h>
+
+/**
+ * @file HalCPU.cc
+ * @brief Common CPU API.
+ */
+
+namespace Kernel::HAL
+{
+ Void lrt_out8(UInt16 port, UInt8 value)
+ {
+ asm volatile("outb %%al, %1"
+ :
+ : "a"(value), "Nd"(port)
+ : "memory");
+ }
+
+ Void lrt_out16(UInt16 port, UInt16 value)
+ {
+ asm volatile("outw %%ax, %1"
+ :
+ : "a"(value), "Nd"(port)
+ : "memory");
+ }
+
+ Void lrt_out32(UInt16 port, UInt32 value)
+ {
+ asm volatile("outl %%eax, %1"
+ :
+ : "a"(value), "Nd"(port)
+ : "memory");
+ }
+
+ UInt8 lrt_in8(UInt16 port)
+ {
+ UInt8 value = 0UL;
+ asm volatile("inb %1, %%al"
+ : "=a"(value)
+ : "Nd"(port)
+ : "memory");
+
+ return value;
+ }
+
+ UInt16 lrt_in16(UInt16 port)
+ {
+ UInt16 value = 0UL;
+ asm volatile("inw %1, %%ax"
+ : "=a"(value)
+ : "Nd"(port)
+ : "memory");
+
+ return value;
+ }
+
+ UInt32 lrt_in32(UInt16 port)
+ {
+ UInt32 value = 0UL;
+ asm volatile("inl %1, %%eax"
+ : "=a"(value)
+ : "Nd"(port)
+ : "memory");
+
+ return value;
+ }
+
+ Void rt_halt()
+ {
+ asm volatile("hlt");
+ }
+
+ Void rt_cli()
+ {
+ asm volatile("cli");
+ }
+
+ Void rt_sti()
+ {
+ asm volatile("sti");
+ }
+
+ Void rt_cld()
+ {
+ asm volatile("cld");
+ }
+
+ Void rt_std()
+ {
+ asm volatile("std");
+ }
+} // namespace Kernel::HAL
diff --git a/dev/Kernel/HALKit/AMD64/HalCommonAPI.asm b/dev/Kernel/HALKit/AMD64/HalCommonAPI.asm
new file mode 100644
index 00000000..8f6b242b
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalCommonAPI.asm
@@ -0,0 +1,82 @@
+;; /*
+;; * ========================================================
+;; *
+;; * ZKA
+;; * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+;; *
+;; * ========================================================
+;; */
+
+section .text
+
+extern rt_wait_400ns
+
+global rt_out8
+global rt_out16
+global rt_out32
+
+global rt_in8
+global rt_in16
+global rt_in32
+
+rt_out8:
+ mov al, dl
+ mov dx, cx
+ out dx, al
+ ret
+
+rt_out16:
+ mov ax, dx
+ mov dx, cx
+ out dx, ax
+ ret
+
+rt_out32:
+ mov eax, edx
+ mov edx, ecx
+ out dx, eax
+ ret
+
+rt_in8:
+ mov dx, cx
+ in al, dx
+ ret
+
+rt_in16:
+ mov edx, ecx
+ in ax, dx
+ ret
+
+rt_in32:
+ mov rdx, rcx
+ in eax, dx
+ ret
+
+extern hal_system_call_enter
+global mp_system_call_handler
+
+mp_system_call_handler:
+
+ push r8
+ push r9
+ push r10
+ push r11
+ push r12
+ push r13
+ push r14
+ push r15
+
+ jmp hal_system_call_enter
+
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop r11
+ pop r10
+ pop r9
+ pop r8
+
+ o64 sysret
+
+[bits 16]
diff --git a/dev/Kernel/HALKit/AMD64/HalControlRegister.s b/dev/Kernel/HALKit/AMD64/HalControlRegister.s
new file mode 100644
index 00000000..2115d6d1
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalControlRegister.s
@@ -0,0 +1,45 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+.globl hal_write_cr3
+.globl hal_write_cr0
+.globl hal_read_cr2
+.globl hal_read_cr3
+.globl hal_read_cr0
+.globl hal_flush_tlb
+.globl hal_invl_tlb
+
+.text
+
+hal_invl_tlb:
+ invlpg (%rcx)
+ retq
+
+hal_flush_tlb:
+ call hal_read_cr3
+ mov %rax, %rcx
+ call hal_write_cr3
+ retq
+
+hal_read_cr3:
+ movq %cr3, %rax
+ retq
+
+hal_read_cr0:
+ movq %cr0, %rax
+ retq
+
+hal_read_cr2:
+ movq %cr2, %rax
+ retq
+
+hal_write_cr3:
+ movq %rcx, %cr3
+ retq
+
+hal_write_cr0:
+ movq %rcx, %cr0
+ retq
diff --git a/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
new file mode 100644
index 00000000..a6c205f6
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
@@ -0,0 +1,235 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <NewKit/KString.h>
+#include <POSIXKit/signal.h>
+
+STATIC BOOL kIsScheduling = NO;
+
+/// @brief Handle GPF fault.
+/// @param rsp
+EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp)
+{
+ auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess();
+
+ if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning)
+ return;
+
+ kIsScheduling = NO;
+
+ kcout << "Kernel: GPF.\r";
+
+ process.Leak().ProcessSignal.SignalIP = 0UL;
+ process.Leak().ProcessSignal.SignalID = SIGKILL;
+ process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status;
+
+ kcout << "Kernel: PRCFROZE status set..\r";
+
+ process.Leak().Status = Kernel::ProcessStatusKind::kKilled;
+
+ process.Leak().Crash();
+}
+
+/// @brief Handle page fault.
+/// @param rsp
+EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp)
+{
+ auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess();
+
+ if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning)
+ return;
+
+ kIsScheduling = NO;
+
+ kcout << "Kernel: Page Fault.\r";
+ kcout << "Kernel: SIGKILL set.\r";
+
+ process.Leak().ProcessSignal.SignalIP = 0UL;
+ process.Leak().ProcessSignal.SignalID = SIGKILL;
+ process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status;
+
+ kcout << "Kernel: PRCFROZE status set..\r";
+
+ process.Leak().Status = Kernel::ProcessStatusKind::kKilled;
+
+ process.Leak().Crash();
+}
+
+/// @brief Handle scheduler interrupt.
+EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp)
+{
+ static Kernel::Int64 try_count_before_brute = 100000UL;
+
+ while (kIsScheduling)
+ {
+ --try_count_before_brute;
+
+ if (try_count_before_brute < 1)
+ break;
+ }
+
+ try_count_before_brute = 100000UL;
+ kIsScheduling = YES;
+
+ kcout << "Kernel: Timer IRQ (Scheduler Notification).\r";
+ Kernel::UserProcessHelper::StartScheduling();
+
+ kIsScheduling = NO;
+}
+
+/// @brief Handle math fault.
+/// @param rsp
+EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp)
+{
+ auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess();
+
+ if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning)
+ return;
+
+ kIsScheduling = NO;
+
+ kcout << "Kernel: Math error (division by zero?).\r";
+
+ process.Leak().ProcessSignal.SignalIP = 0UL;
+ process.Leak().ProcessSignal.SignalID = SIGKILL;
+ process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status;
+
+ kcout << "Kernel: PRCFROZE status set..\r";
+
+ process.Leak().Status = Kernel::ProcessStatusKind::kKilled;
+
+ process.Leak().Crash();
+}
+
+/// @brief Handle any generic fault.
+/// @param rsp
+EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp)
+{
+ auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess();
+
+ if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning)
+ return;
+
+ kIsScheduling = NO;
+
+ kcout << "Kernel: Generic Process Fault.\r";
+
+ process.Leak().ProcessSignal.SignalIP = 0UL;
+ process.Leak().ProcessSignal.SignalID = SIGKILL;
+ process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status;
+
+ kcout << "Kernel: PRCFROZE status set..\r";
+
+ process.Leak().Status = Kernel::ProcessStatusKind::kKilled;
+
+ process.Leak().Crash();
+}
+
+EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip)
+{
+ auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess();
+
+ if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning)
+ return;
+
+ kIsScheduling = NO;
+
+ kcout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << endl;
+ kcout << "Kernel: SIGTRAP set.\r";
+
+ process.Leak().ProcessSignal.SignalIP = rip;
+ process.Leak().ProcessSignal.SignalID = SIGTRAP;
+
+ process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status;
+
+ kcout << "Kernel: PRCFROZE status set..\r";
+
+ process.Leak().Status = Kernel::ProcessStatusKind::kFrozen;
+}
+
+/// @brief Handle #UD fault.
+/// @param rsp
+EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp)
+{
+ auto process = Kernel::UserProcessScheduler::The().GetCurrentProcess();
+
+ if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning)
+ return;
+
+ kIsScheduling = NO;
+
+ kcout << "Kernel: Undefined Opcode.\r";
+
+ process.Leak().ProcessSignal.SignalIP = 0UL;
+ process.Leak().ProcessSignal.SignalID = SIGKILL;
+ process.Leak().ProcessSignal.PreviousStatus = process.Leak().Status;
+
+ kcout << "Kernel: PRCFROZE status set..\r";
+
+ process.Leak().Status = Kernel::ProcessStatusKind::kKilled;
+
+ process.Leak().Crash();
+}
+
+/// @brief Enter syscall from assembly.
+/// @param stack the stack pushed from assembly routine.
+/// @return nothing.
+EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_syscall_index, Kernel::UIntPtr rdx_syscall_struct)
+{
+ if (rcx_syscall_index < kSyscalls.Count())
+ {
+ kcout << "syscall: Enter Syscall.\r";
+
+ if (kSyscalls[rcx_syscall_index].fHooked)
+ {
+ if (kSyscalls[rcx_syscall_index].fProc)
+ {
+ (kSyscalls[rcx_syscall_index].fProc)((Kernel::VoidPtr)rdx_syscall_struct);
+ }
+ else
+ {
+ kcout << "syscall: syscall isn't valid at all! (is nullptr)\r";
+ }
+ }
+ else
+ {
+ kcout << "syscall: syscall isn't hooked at all! (is set to false)\r";
+ }
+
+ kcout << "syscall: Exit Syscall.\r";
+ }
+}
+
+/// @brief Enter Kernel call from assembly (DDK only).
+/// @param stack the stack pushed from assembly routine.
+/// @return nothing.
+EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_kerncall_index, Kernel::UIntPtr rdx_kerncall_struct)
+{
+ if (rcx_kerncall_index < kKerncalls.Count())
+ {
+ kcout << "kerncall: Enter Kernel Call List.\r";
+
+ if (kKerncalls[rcx_kerncall_index].fHooked)
+ {
+ if (kKerncalls[rcx_kerncall_index].fProc)
+ {
+ (kKerncalls[rcx_kerncall_index].fProc)((Kernel::VoidPtr)rdx_kerncall_struct);
+ }
+ else
+ {
+ kcout << "kerncall: Kernel call isn't valid at all! (is nullptr)\r";
+ }
+ }
+ else
+ {
+ kcout << "kerncall: Kernel call isn't hooked at all! (is set to false)\r";
+ }
+
+ kcout << "kerncall: Exit Kernel Call List.\r";
+ }
+}
diff --git a/dev/Kernel/HALKit/AMD64/HalDebugOutput.cc b/dev/Kernel/HALKit/AMD64/HalDebugOutput.cc
new file mode 100644
index 00000000..041af9ed
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalDebugOutput.cc
@@ -0,0 +1,145 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/DebugOutput.h>
+#include <NewKit/Utils.h>
+#include <NewKit/New.h>
+
+namespace Kernel
+{
+ enum CommStatus
+ {
+ kStateInvalid,
+ kStateReady = 0xCF,
+ kStateTransmit = 0xFC,
+ kStateCnt = 3
+ };
+
+ namespace Detail
+ {
+ constexpr Int16 kPort = 0x3F8;
+ static Int32 kState = kStateInvalid;
+
+ /// @brief Init COM1.
+ /// @return
+ template <Int16 PORT>
+ bool hal_serial_init() noexcept
+ {
+ if (kState == kStateReady || kState == kStateTransmit)
+ return true;
+
+ HAL::rt_out8(PORT + 1, 0x00); // Disable all interrupts
+ HAL::rt_out8(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
+ HAL::rt_out8(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
+ HAL::rt_out8(PORT + 1, 0x00); // (hi byte)
+ HAL::rt_out8(PORT + 3, 0x03); // 8 bits, no parity, one stop bit
+ HAL::rt_out8(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
+ HAL::rt_out8(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
+ HAL::rt_out8(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip
+ HAL::rt_out8(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if
+ // serial returns same byte)
+
+ // Check if serial is faulty (i.e: not same byte as sent)
+ if (HAL::rt_in8(PORT) != 0xAE)
+ {
+ ke_panic(RUNTIME_CHECK_HANDSHAKE);
+ }
+
+ kState = kStateReady;
+
+ // If serial is not faulty set it in normal operation mode
+ // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled)
+ HAL::rt_out8(PORT + 4, 0x0F);
+
+ return true;
+ }
+ } // namespace Detail
+
+ TerminalDevice::~TerminalDevice() = default;
+
+ EXTERN_C void ke_io_write(const Char* bytes)
+ {
+#ifdef __DEBUG__
+ Detail::hal_serial_init<Detail::kPort>();
+
+ if (!bytes || Detail::kState != kStateReady)
+ return;
+
+ if (*bytes == 0)
+ return;
+
+ Detail::kState = kStateTransmit;
+
+ SizeT index = 0;
+ SizeT len = 0;
+
+ index = 0;
+ len = rt_string_len(bytes, 255);
+
+ while (index < len)
+ {
+ if (bytes[index] == '\r')
+ HAL::rt_out8(Detail::kPort, '\r');
+
+ HAL::rt_out8(Detail::kPort, bytes[index] == '\r' ? '\n' : bytes[index]);
+ ++index;
+ }
+
+ Detail::kState = kStateReady;
+#endif // __DEBUG__
+ }
+
+ EXTERN_C void ke_io_read(const Char* bytes)
+ {
+#ifdef __DEBUG__
+ Detail::hal_serial_init<Detail::kPort>();
+
+ if (!bytes || Detail::kState != kStateReady)
+ return;
+
+ Detail::kState = kStateTransmit;
+
+ SizeT index = 0;
+
+ ///! TODO: Look on how to wait for the UART to complete.
+ while (true)
+ {
+ auto in = HAL::rt_in8(Detail::kPort);
+
+ ///! 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;
+
+ Detail::kState = kStateReady;
+#endif // __DEBUG__
+ }
+
+ TerminalDevice TerminalDevice::The() noexcept
+ {
+ TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read);
+ return out;
+ }
+
+} // namespace Kernel
diff --git a/dev/Kernel/HALKit/AMD64/HalDebugPort.cc b/dev/Kernel/HALKit/AMD64/HalDebugPort.cc
new file mode 100644
index 00000000..546239c2
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalDebugPort.cc
@@ -0,0 +1,40 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+//! @file DebuggerPort.cc
+//! @brief UART debug via packets.
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/DebugOutput.h>
+
+// after that we have start of additional data.
+
+namespace Kernel
+{
+ void rt_debug_listen(DebuggerPortHeader* theHook) noexcept
+ {
+ if (theHook == nullptr)
+ return;
+
+ for (UInt32 i = 0U; i < kDebugMaxPorts; ++i)
+ {
+ HAL::rt_out16(theHook->fPort[i], kDebugMag0);
+ HAL::rt_wait_400ns();
+
+ HAL::rt_out16(theHook->fPort[i], kDebugMag1);
+ HAL::rt_wait_400ns();
+
+ HAL::rt_out16(theHook->fPort[i], kDebugMag2);
+ HAL::rt_wait_400ns();
+
+ HAL::rt_out16(theHook->fPort[i], kDebugMag3);
+ HAL::rt_wait_400ns();
+
+ if (HAL::rt_in16(theHook->fPort[i] != kDebugUnboundPort))
+ ++theHook->fBoundCnt;
+ }
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cc b/dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cc
new file mode 100644
index 00000000..6e3ab7bb
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalDescriptorLoader.cc
@@ -0,0 +1,126 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.h>
+#include <HALKit/AMD64/Processor.h>
+
+#define kPITDefaultTicks (1000U)
+
+namespace Kernel::HAL
+{
+ namespace Detail
+ {
+ STATIC ::Kernel::Detail::AMD64::InterruptDescriptorAMD64
+ kInterruptVectorTable[kKernelIdtSize] = {};
+
+ STATIC void hal_set_irq_mask(UInt8 irql);
+ STATIC void hal_clear_irq_mask(UInt8 irql);
+
+ STATIC Void hal_enable_pit(UInt16 ticks) noexcept
+ {
+ if (ticks == 0)
+ ticks = kPITDefaultTicks;
+
+ // Configure PIT to receieve scheduler interrupts.
+
+ UInt16 kPITCommDivisor = kPITFrequency / ticks; // 100 Hz.
+
+ HAL::rt_out8(kPITControlPort, 0x36); // Command to PIT
+ HAL::rt_out8(kPITChannel0Port, kPITCommDivisor & 0xFF); // Send low byte
+ HAL::rt_out8(kPITChannel0Port, (kPITCommDivisor >> 8) & 0xFF); // Send high byte
+
+ hal_clear_irq_mask(32);
+ }
+
+ STATIC void hal_set_irq_mask(UInt8 irql)
+ {
+ UInt16 port;
+ UInt8 value;
+
+ if (irql < 8)
+ {
+ port = kPICData;
+ }
+ else
+ {
+ port = kPIC2Data;
+ irql -= 8;
+ }
+
+ value = rt_in8(port) | (1 << irql);
+ rt_out8(port, value);
+ }
+
+ STATIC void hal_clear_irq_mask(UInt8 irql)
+ {
+ UInt16 port;
+ UInt8 value;
+
+ if (irql < 8)
+ {
+ port = kPICData;
+ }
+ else
+ {
+ port = kPIC2Data;
+ irql -= 8;
+ }
+
+ value = rt_in8(port) & ~(1 << irql);
+ rt_out8(port, value);
+ }
+ } // namespace Detail
+
+ /// @brief Loads the provided Global Descriptor Table.
+ /// @param gdt
+ /// @return
+ Void GDTLoader::Load(RegisterGDT& gdt)
+ {
+ hal_load_gdt(gdt);
+ }
+
+ Void IDTLoader::Load(Register64& idt)
+ {
+ rt_cli();
+
+ const Int16 kPITTickForScheduler = kPITDefaultTicks;
+
+ volatile ::Kernel::UIntPtr** ptr_ivt = (volatile ::Kernel::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].OffsetMid = (((UIntPtr)ptr_ivt[idt_indx] >> 16) & 0xFFFF);
+ Detail::kInterruptVectorTable[idt_indx].OffsetHigh =
+ (((UIntPtr)ptr_ivt[idt_indx] >> 32) & 0xFFFFFFFF);
+
+ Detail::kInterruptVectorTable[idt_indx].Zero = 0;
+ }
+
+ idt.Base = (UIntPtr)&Detail::kInterruptVectorTable[0];
+ idt.Limit = sizeof(::Kernel::Detail::AMD64::InterruptDescriptorAMD64) *
+ (kKernelIdtSize);
+
+ hal_load_idt(idt);
+
+ Detail::hal_enable_pit(kPITTickForScheduler);
+
+ rt_sti();
+ }
+
+ void GDTLoader::Load(Ref<RegisterGDT>& gdt)
+ {
+ GDTLoader::Load(gdt.Leak());
+ }
+
+ void IDTLoader::Load(Ref<Register64>& idt)
+ {
+ IDTLoader::Load(idt.Leak());
+ }
+} // namespace Kernel::HAL
diff --git a/dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm
new file mode 100644
index 00000000..b3d8d91f
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalInterruptAPI.asm
@@ -0,0 +1,410 @@
+;; /*
+;; * ---------------------------------------------------
+;; *
+;; * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+;; *
+;; * File: HalInterruptAPI.asm
+;; * Purpose: Interrupt API, redirect raw interrupts into their handlers.
+;; *
+;; * ---------------------------------------------------
+;; */
+
+[bits 64]
+
+%define kInterruptId 50
+
+%macro IntExp 1
+global __ZKA_INT_%1
+__ZKA_INT_%1:
+ cld
+
+ mov al, 0x20
+ out 0xA0, al
+ out 0x20, al
+
+ push rcx
+ call idt_handle_generic
+ pop rcx
+
+ std
+
+ o64 iret
+%endmacro
+
+%macro IntNormal 1
+global __ZKA_INT_%1
+__ZKA_INT_%1:
+ cld
+
+ mov al, 0x20
+ out 0xA0, al
+ out 0x20, al
+
+ std
+
+ o64 iret
+%endmacro
+
+; This file handles the core interrupt table
+; Last edited 31/01/24
+
+global ke_handle_irq
+global kInterruptVectorTable
+
+extern idt_handle_gpf
+extern idt_handle_pf
+extern ke_io_write
+extern idt_handle_ud
+extern idt_handle_generic
+extern idt_handle_breakpoint
+
+section .text
+
+__ZKA_INT_0:
+ cld
+
+ mov al, 0x20
+ out 0x20, al
+
+ std
+
+ o64 iret
+
+__ZKA_INT_1:
+ cld
+
+ mov al, 0x20
+ out 0x20, al
+
+ push rcx
+ call idt_handle_generic
+ pop rcx
+
+ std
+
+ o64 iret
+
+__ZKA_INT_2:
+ cld
+
+ mov al, 0x20
+ out 0x20, al
+
+ push rcx
+ call idt_handle_generic
+ pop rcx
+
+ std
+
+ o64 iret
+
+;; @brief Triggers a breakpoint and freeze the process. RIP is also fetched.
+__ZKA_INT_3:
+ cld
+
+ mov al, 0x20
+ out 0x20, al
+
+ push rcx
+ call idt_handle_generic
+ pop rcx
+
+ std
+
+ o64 iret
+
+__ZKA_INT_4:
+ cld
+
+ mov al, 0x20
+ out 0x20, al
+
+
+ push rcx
+ call idt_handle_generic
+ pop rcx
+
+ std
+
+ o64 iret
+
+__ZKA_INT_5:
+ cld
+
+ mov al, 0x20
+ out 0x20, al
+
+ std
+
+ o64 iret
+
+;; Invalid opcode interrupt
+__ZKA_INT_6:
+ cld
+
+ mov al, 0x20
+ out 0x20, al
+
+ push rcx
+ call idt_handle_generic
+ pop rcx
+
+ std
+
+ o64 iret
+
+__ZKA_INT_7:
+ cld
+
+ mov al, 0x20
+ out 0x20, al
+
+ push rcx
+ call idt_handle_generic
+ pop rcx
+
+ std
+
+ o64 iret
+
+;; Invalid opcode interrupt
+__ZKA_INT_8:
+ cld
+
+ mov al, 0x20
+ out 0xA0, al
+ out 0x20, al
+
+ push rcx
+ call idt_handle_generic
+ pop rcx
+
+ std
+
+ o64 iret
+
+IntNormal 9
+IntExp 10
+IntExp 11
+
+IntExp 12
+
+__ZKA_INT_13:
+ cld
+
+ mov al, 0x20
+ out 0xA0, al
+ out 0x20, al
+
+ push rcx
+ call idt_handle_gpf
+ pop rcx
+
+ std
+
+ o64 iret
+
+__ZKA_INT_14:
+ cld
+
+ mov al, 0x20
+ out 0xA0, al
+ out 0x20, al
+
+ push rcx
+ call idt_handle_pf
+ pop rcx
+
+ std
+
+ o64 iret
+
+IntNormal 15
+IntNormal 16
+IntExp 17
+IntNormal 18
+IntNormal 19
+IntNormal 20
+IntNormal 21
+
+IntNormal 22
+
+IntNormal 23
+IntNormal 24
+IntNormal 25
+IntNormal 26
+IntNormal 27
+IntNormal 28
+IntNormal 29
+IntExp 30
+IntNormal 31
+
+[extern idt_handle_scheduler]
+
+__ZKA_INT_32:
+ cld
+
+ mov al, 0x20
+ out 0xA0, al
+ out 0x20, al
+
+ push rax
+ mov rcx, rsp
+ call idt_handle_scheduler
+ pop rax
+
+ std
+
+ o64 iret
+
+IntNormal 33
+
+IntNormal 34
+IntNormal 35
+IntNormal 36
+IntNormal 37
+IntNormal 38
+IntNormal 39
+IntNormal 40
+
+IntNormal 41
+
+IntNormal 42
+IntNormal 43
+IntNormal 44
+IntNormal 45
+IntNormal 46
+IntNormal 47
+IntNormal 48
+IntNormal 49
+
+[extern hal_system_call_enter]
+[extern hal_kernel_call_enter]
+
+__ZKA_INT_50:
+ cld
+
+ mov al, 0x20
+ out 0xA0, al
+ out 0x20, al
+
+ push rax
+ mov rax, hal_system_call_enter
+
+ mov rcx, r8
+ mov rdx, r9
+
+ call rax
+ pop rax
+
+ std
+
+ o64 iret
+
+__ZKA_INT_51:
+ cld
+
+ mov al, 0x20
+ out 0xA0, al
+ out 0x20, al
+
+ push rax
+ mov rax, hal_kernel_call_enter
+
+ mov rcx, r8
+ mov rdx, r9
+
+ call rax
+ pop rax
+
+ std
+
+ o64 iret
+
+IntNormal 52
+
+IntNormal 53
+IntNormal 54
+IntNormal 55
+IntNormal 56
+IntNormal 57
+IntNormal 58
+IntNormal 59
+IntNormal 60
+
+%assign i 61
+%rep 195
+ IntNormal i
+%assign i i+1
+%endrep
+
+section .text
+
+[global hal_load_gdt]
+
+hal_load_gdt:
+ cld
+
+ lgdt [rcx]
+
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+
+ mov rax, 0x08
+ push rax
+ push hal_reload_segments
+
+ o64 retf
+
+extern hal_real_init
+
+hal_reload_segments:
+ std
+
+ jmp hal_real_init
+ ret
+
+global hal_load_idt
+
+hal_load_idt:
+ lidt [rcx]
+
+ ; Master PIC initialization
+ mov al, 0x11 ; Start initialization in cascade mode
+ out 0x20, al ; Send initialization command to Master PIC
+ out 0xA0, al ; Send initialization command to Slave PIC
+
+ ; Remap the PIC to use vectors 32-39 for Master and 40-47 for Slave
+ mov al, 0x20 ; Set Master PIC offset to 32
+ out 0x21, al ; Send offset to Master PIC
+
+ mov al, 0x28 ; Set Slave PIC offset to 40
+ out 0xA1, al ; Send offset to Slave PIC
+
+ ; Configure Master PIC to inform Slave PIC at IRQ2
+ mov al, 0x04 ; Tell Master PIC there is a Slave PIC at IRQ2
+ out 0x21, al
+
+ ; Configure Slave PIC identity
+ mov al, 0x02 ; Tell Slave PIC its cascade identity
+ out 0xA1, al
+
+ ; Set both PICs to 8086 mode
+ mov al, 0x01 ; 8086 mode
+ out 0x21, al
+ out 0xA1, al
+
+ ret
+
+section .data
+
+kInterruptVectorTable:
+ %assign i 0
+ %rep 256
+ dq __ZKA_INT_%+i
+ %assign i i+1
+ %endrep
diff --git a/dev/Kernel/HALKit/AMD64/HalKernelMain.cc b/dev/Kernel/HALKit/AMD64/HalKernelMain.cc
new file mode 100644
index 00000000..e982714d
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalKernelMain.cc
@@ -0,0 +1,110 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/HardwareThreadScheduler.h>
+#include <KernelKit/CodeMgr.h>
+#include <Mod/ACPI/ACPIFactoryInterface.h>
+#include <NetworkKit/IPC.h>
+#include <CFKit/Property.h>
+#include <Mod/CoreGfx/TextMgr.h>
+
+EXTERN_C Kernel::VoidPtr kInterruptVectorTable[];
+EXTERN_C Kernel::VoidPtr mp_user_switch_proc;
+EXTERN_C Kernel::Char mp_user_switch_proc_stack_begin[];
+
+EXTERN_C Kernel::rtl_ctor_kind __CTOR_LIST__[];
+EXTERN_C Kernel::VoidPtr __DTOR_LIST__;
+
+EXTERN_C Kernel::Void rtl_kernel_main(Kernel::SizeT argc, char** argv, char** envp, Kernel::SizeT envp_len);
+
+STATIC Kernel::Void hal_init_cxx_ctors()
+{
+ for (Kernel::SizeT i = 0U; i < Kernel::UserProcessScheduler::The().CurrentTeam().AsArray().Count(); ++i)
+ {
+ Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i] = Kernel::UserProcess();
+ Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i].Status = Kernel::ProcessStatusKind::kKilled;
+ }
+
+ Kernel::UserProcessScheduler::The().CurrentTeam().mProcessCount = 0UL;
+
+ for (Kernel::SizeT index = 0UL; __CTOR_LIST__[index] != __DTOR_LIST__; ++index)
+ {
+ Kernel::rtl_ctor_kind constructor_cxx = (Kernel::rtl_ctor_kind)__CTOR_LIST__[index];
+ constructor_cxx();
+ }
+}
+
+/// @brief Kernel init procedure.
+EXTERN_C void hal_init_platform(
+ Kernel::HEL::BootInfoHeader* handover_hdr)
+{
+ kHandoverHeader = handover_hdr;
+
+ if (kHandoverHeader->f_Magic != kHandoverMagic &&
+ kHandoverHeader->f_Version != kHandoverVersion)
+ {
+ return;
+ }
+
+ hal_init_cxx_ctors();
+
+ /************************************** */
+ /* INITIALIZE BIT MAP. */
+ /************************************** */
+
+ kKernelBitMpSize = kHandoverHeader->f_BitMapSize;
+ kKernelBitMpStart = reinterpret_cast<Kernel::VoidPtr>(
+ reinterpret_cast<Kernel::UIntPtr>(kHandoverHeader->f_BitMapStart));
+
+ /************************************** */
+ /* INITIALIZE GDT AND SEGMENTS. */
+ /************************************** */
+
+ STATIC CONST auto kGDTEntriesCount = 6;
+
+ /* GDT, mostly descriptors for user and kernel segments. */
+ STATIC Kernel::HAL::Detail::ZKA_GDT_ENTRY ALIGN(0x08) kGDTArray[kGDTEntriesCount] = {
+ {.fLimitLow = 0, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0x00, .fFlags = 0x00, .fBaseHigh = 0}, // Null entry
+ {.fLimitLow = 0x0, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0x9A, .fFlags = 0xAF, .fBaseHigh = 0}, // Kernel code
+ {.fLimitLow = 0x0, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0x92, .fFlags = 0xCF, .fBaseHigh = 0}, // Kernel data
+ {.fLimitLow = 0x0, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0xFA, .fFlags = 0xAF, .fBaseHigh = 0}, // User code
+ {.fLimitLow = 0x0, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0xF2, .fFlags = 0xCF, .fBaseHigh = 0}, // User data
+ };
+
+ // Load memory descriptors.
+ Kernel::HAL::RegisterGDT gdt_reg;
+
+ gdt_reg.Base = reinterpret_cast<Kernel::UIntPtr>(kGDTArray);
+ gdt_reg.Limit = (sizeof(Kernel::HAL::Detail::ZKA_GDT_ENTRY) * kGDTEntriesCount) - 1;
+
+ //! GDT will load hal_read_init after it successfully loads the segments.
+ Kernel::HAL::GDTLoader gdt_loader;
+ gdt_loader.Load(gdt_reg);
+
+ Kernel::ke_panic(RUNTIME_CHECK_BOOTSTRAP);
+}
+
+EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept
+{
+ rtl_kernel_main(0, nullptr, nullptr, 0);
+
+ Kernel::HAL::mp_get_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr);
+
+ Kernel::HAL::Register64 idt_reg;
+
+ idt_reg.Base = (Kernel::UIntPtr)kInterruptVectorTable;
+
+ Kernel::HAL::IDTLoader idt_loader;
+
+ idt_loader.Load(idt_reg);
+
+ while (YES)
+ {
+ continue;
+ }
+}
diff --git a/dev/Kernel/HALKit/AMD64/HalKernelPanic.cc b/dev/Kernel/HALKit/AMD64/HalKernelPanic.cc
new file mode 100644
index 00000000..594b475f
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalKernelPanic.cc
@@ -0,0 +1,90 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, 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 <Mod/CoreGfx/FBMgr.h>
+#include <Mod/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 Kernel
+{
+ /// @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 Kernel::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;
+
+ Char* message_cr2 = new Char[128];
+ rt_set_memory(message_cr2, 0, 128);
+
+ rt_copy_memory((VoidPtr) "cr2: ", message_cr2, rt_string_len("cr2: "));
+ rt_to_string(message_cr2 + rt_string_len("cr2: "), (UIntPtr)hal_read_cr2(), 10);
+
+ fb_render_string(message_cr2, 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)
+ {
+ kcout << "FAILED: FILE: " << file << endl;
+ kcout << "FAILED: LINE: " << line << endl;
+
+ ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed
+ }
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/HALKit/AMD64/HalPagingMgrAMD64.cc b/dev/Kernel/HALKit/AMD64/HalPagingMgrAMD64.cc
new file mode 100644
index 00000000..97bf07f8
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalPagingMgrAMD64.cc
@@ -0,0 +1,168 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: HalPagingMgr.cc
+ Purpose: Platform Paging Manager..
+
+------------------------------------------- */
+
+#include <HALKit/AMD64/Paging.h>
+#include <HALKit/AMD64/Processor.h>
+
+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 is in progress.
+
+ bool IsValidPage(PTE* pte)
+ {
+ return pte && pte->Present;
+ }
+
+ bool IsWRPage(PTE* pte)
+ {
+ return pte && pte->Wr;
+ }
+
+ bool IsUserPage(PTE* pte)
+ {
+ return pte && pte->User;
+ }
+
+ static ZKA_PAGE_STORE& The()
+ {
+ static ZKA_PAGE_STORE the;
+ return the;
+ }
+ };
+
+ /***********************************************************************************/
+ /// \brief Retrieve the page status of a PTE.
+ /// \param pte Page Table Entry pointer.
+ /***********************************************************************************/
+ STATIC Void mmi_page_status(PTE* pte)
+ {
+ kcout << (pte->Present ? "Present" : "Not Present") << endl;
+ kcout << (pte->Wr ? "W/R" : "Not W/R") << endl;
+ kcout << (pte->ExecDisable ? "NX" : "Not NX") << endl;
+ kcout << (pte->User ? "User" : "Not User") << endl;
+ }
+
+ STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, ZKA_PTE* pt_entry, ZKA_PDE* pd_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;
+
+ // Constants for table index bits
+ const UInt64 cPmlIndexMask = 0x1FFULL; // Mask for PML4, PDPT, PD, PT index (9 bits)
+ const UInt64 cPtIndexMask = 0xFFFULL; // Mask for page table index (12 bits)
+
+ UInt64 cr3 = (UInt64)hal_read_cr3();
+
+ ZKA_PAGE_STORE& page_store = ZKA_PAGE_STORE::The();
+
+ // Extract the indices from the virtual address
+ UInt64 pml4_index = ((UIntPtr)virtual_address >> 39) & cPmlIndexMask;
+ UInt64 pdpt_index = ((UIntPtr)virtual_address >> 30) & cPmlIndexMask;
+ UInt64 pd_index = ((UIntPtr)virtual_address >> 21) & cPmlIndexMask;
+ UInt64 pt_index = ((UIntPtr)virtual_address >> 12) & cPmlIndexMask;
+
+ 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, page_store.fInternalStore.fPde);
+ }
+
+ const auto cPmlEntrySize = 8;
+
+ // Read the PML4 entry from memory
+ UInt64 pml4_base = cr3 & ~cPtIndexMask; // CR3 points to the PML4 table base, mask off lower bits
+ UInt64 pml4_entry = (pml4_base + pml4_index * cPmlEntrySize); // Each entry is 8 bytes
+
+ // Read the PDPT entry
+ UInt64 pdpt_base = pml4_entry & ~cPtIndexMask; // Get the PDPT base physical address
+ UInt64 pdpt_entry = (pdpt_base + pdpt_index * cPmlEntrySize);
+
+ // Read the PD entry
+ UInt64 pd_base = pdpt_entry & ~cPtIndexMask; // Get the Page Directory base physical address
+ UInt64 pd_entry = (pd_base + pd_index * cPmlEntrySize);
+
+ // Read the PT entry
+ UInt64 pt_base = pd_entry & ~cPtIndexMask; // Get the Page Table base physical address
+ UInt64 pt_entry = (pt_base + pt_index * cPmlEntrySize);
+
+ // Lastly, grab the pte entry.
+ ZKA_PDE* pde_struct = reinterpret_cast<ZKA_PDE*>(pt_base);
+
+ return mmi_map_page_table_entry(virtual_address, flags, pde_struct->fEntries[pt_entry], pde_struct);
+ }
+
+ /***********************************************************************************/
+ /// @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, ZKA_PDE* pd_entry)
+ {
+ if (!pt_entry)
+ return 1;
+
+ pt_entry->Present = true;
+
+ if (flags & kMMFlagsWr)
+ pt_entry->Wr = true;
+ else if (flags & ~kMMFlagsWr)
+ pt_entry->Wr = false;
+
+ if (flags & kMMFlagsNX)
+ pt_entry->ExecDisable = true;
+ else if (flags & ~kMMFlagsNX)
+ pt_entry->ExecDisable = false;
+
+ if (flags & kMMFlagsUser)
+ pt_entry->User = true;
+ else if (flags & ~kMMFlagsUser)
+ pt_entry->User = false;
+
+ hal_invl_tlb(reinterpret_cast<VoidPtr>(pt_entry));
+
+ mmi_page_status(pt_entry);
+
+ ZKA_PAGE_STORE& page_store = ZKA_PAGE_STORE::The();
+
+ // Update Internal store.
+
+ page_store.fInternalStore.fPde = pd_entry;
+ 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/Kernel/HALKit/AMD64/HalRoutineWait.s b/dev/Kernel/HALKit/AMD64/HalRoutineWait.s
new file mode 100644
index 00000000..89051ba4
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalRoutineWait.s
@@ -0,0 +1,11 @@
+.globl rt_wait_400ns
+
+.section .text
+rt_wait_400ns:
+ jmp .loop
+ pause
+ .loop:
+ jmp .loop2
+ pause
+ .loop2:
+ ret
diff --git a/dev/Kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc b/dev/Kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc
new file mode 100644
index 00000000..b6ea7ca3
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc
@@ -0,0 +1,52 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <HALKit/AMD64/Processor.h>
+#include <KernelKit/UserProcessScheduler.h>
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /// @brief Unimplemented function (crashes by default)
+ /// @param
+ /***********************************************************************************/
+
+ 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;
+ }
+
+ /// @brief Wakes up thread.
+ /// Wakes up thread from the hang state.
+ Void mp_wakeup_thread(HAL::StackFrame* stack)
+ {
+ Kernel::UserProcessHelper::StartScheduling();
+ }
+
+ /// @brief makes the thread sleep on a loop.
+ /// hooks and hangs thread to prevent code from executing.
+ Void mp_hang_thread(HAL::StackFrame* stack)
+ {
+ while (Yes)
+ {
+ /* Nothing to do, code is spinning */
+ }
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/HALKit/AMD64/HalTimerAMD64.cc b/dev/Kernel/HALKit/AMD64/HalTimerAMD64.cc
new file mode 100644
index 00000000..bedbb237
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalTimerAMD64.cc
@@ -0,0 +1,86 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: HalTimer.cc
+ Purpose: HAL timer
+
+ Revision History:
+
+ 07/07/24: Added file (amlel)
+
+------------------------------------------- */
+
+#include <Mod/ACPI/ACPIFactoryInterface.h>
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/Timer.h>
+
+// timer slot 0
+
+#define cHPETCounterRegValue (0x00)
+#define cHPETConfigRegValue (0x20)
+#define cHPETCompRegValue (0x24)
+#define cHPETInterruptRegValue (0x2C)
+
+///! BUGS: 0
+///! @file HalTimer.cc
+///! @brief Hardware Timer (HPET)
+
+namespace Kernel::Detail
+{
+ struct HPET_BLOCK : public Kernel::SDT
+ {
+ Kernel::UInt8 hardware_rev_id;
+ Kernel::UInt8 comparator_count : 5;
+ Kernel::UInt8 counter_size : 1;
+ Kernel::UInt8 reserved : 1;
+ Kernel::UInt8 legacy_replacement : 1;
+ Kernel::UInt16 pci_vendor_id;
+ ACPI_ADDRESS address;
+ Kernel::UInt8 hpet_number;
+ Kernel::UInt16 minimum_tick;
+ Kernel::UInt8 page_protection;
+ } PACKED;
+} // namespace Kernel::Detail
+
+using namespace Kernel;
+
+HardwareTimer::HardwareTimer(Int64 ms)
+ : fWaitFor(ms)
+{
+ auto power = PowerFactoryInterface(kHandoverHeader->f_HardwareTables.f_VendorPtr);
+
+ auto hpet = (Detail::HPET_BLOCK*)power.Find("HPET").Leak().Leak();
+ MUST_PASS(hpet);
+
+ fDigitalTimer = (IntPtr*)hpet->address.Address;
+}
+
+HardwareTimer::~HardwareTimer()
+{
+ fDigitalTimer = nullptr;
+ fWaitFor = 0;
+}
+
+BOOL HardwareTimer::Wait() noexcept
+{
+ if (fWaitFor < 1)
+ return NO;
+
+ // if not enabled yet.
+ if (!(*(fDigitalTimer + cHPETConfigRegValue) & (1 << 0)))
+ {
+ *(fDigitalTimer + cHPETConfigRegValue) |= (1 << 0); // enable it
+ *(fDigitalTimer + cHPETConfigRegValue) |= (1 << 3); // one shot conf
+ }
+
+ UInt64 ticks = fWaitFor / ((*(fDigitalTimer) >> 32) & __UINT32_MAX__);
+ UInt64 prev = *(fDigitalTimer + cHPETCounterRegValue);
+
+ prev += ticks;
+
+ while (*(fDigitalTimer + cHPETCounterRegValue) < (ticks))
+ ;
+
+ return YES;
+}
diff --git a/dev/Kernel/HALKit/AMD64/HalUtils.asm b/dev/Kernel/HALKit/AMD64/HalUtils.asm
new file mode 100644
index 00000000..d3918190
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/HalUtils.asm
@@ -0,0 +1,26 @@
+;; /*
+;; * ========================================================
+;; *
+;; * ZKA
+;; * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+;; *
+;; * ========================================================
+;; */
+
+[bits 64]
+
+[global rt_install_tib]
+
+section .text
+
+;; changed: rs, fs
+;; expected: rcx, rdx
+
+rt_install_tib:
+ mov rcx, gs ;; TIB -> Thread Information Block
+ mov rdx, fs ;; PIB -> Process Information Block
+ ret
+
+;; //////////////////////////////////////////////////// ;;
+
+[extern kApicMadtAddressesCount]
diff --git a/dev/Kernel/HALKit/AMD64/Hypervisor.h b/dev/Kernel/HALKit/AMD64/Hypervisor.h
new file mode 100644
index 00000000..8f4a89d9
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/Hypervisor.h
@@ -0,0 +1,25 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+namespace Kernel
+{
+ MAKE_STRING_ENUM(HYPERVISOR)
+ ENUM_STRING(Qemu, "TCGTCGTCGTCG");
+ ENUM_STRING(KVM, " KVMKVMKVM ");
+ ENUM_STRING(VMWare, "VMwareVMware");
+ ENUM_STRING(VirtualBox, "VBoxVBoxVBox");
+ ENUM_STRING(Xen, "XenVMMXenVMM");
+ ENUM_STRING(Microsoft, "Microsoft Hv");
+ ENUM_STRING(Parallels, " prl hyperv ");
+ ENUM_STRING(ParallelsAlt, " lrpepyh vr ");
+ ENUM_STRING(Bhyve, "bhyve bhyve ");
+ ENUM_STRING(Qnx, " QNXQVMBSQG ");
+ END_STRING_ENUM()
+} // namespace Kernel
diff --git a/dev/Kernel/HALKit/AMD64/MBCI/HalMBCI.cc b/dev/Kernel/HALKit/AMD64/MBCI/HalMBCI.cc
new file mode 100644
index 00000000..3a268f8c
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/MBCI/HalMBCI.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <Mod/MBCI/MBCI.h>
diff --git a/dev/Kernel/HALKit/AMD64/PCI/DMA.cc b/dev/Kernel/HALKit/AMD64/PCI/DMA.cc
new file mode 100644
index 00000000..43b9bbdf
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/PCI/DMA.cc
@@ -0,0 +1,82 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/PCI/DMA.h>
+
+namespace Kernel
+{
+ DMAWrapper::operator bool()
+ {
+ return fAddress;
+ }
+
+ bool DMAWrapper::operator!()
+ {
+ return !fAddress;
+ }
+
+ Boolean DMAWrapper::Check(UIntPtr offset) const
+ {
+ if (!fAddress)
+ return false;
+ if (offset == 0)
+ return true;
+
+ kcout << "[DMAWrapper::IsIn] Checking offset..\n";
+ return reinterpret_cast<UIntPtr>(fAddress) >= offset;
+ }
+
+ bool DMAWrapper::Write(const UIntPtr& bit, const UIntPtr& offset)
+ {
+ if (!fAddress)
+ return false;
+
+ kcout << "[DMAWrapper::Write] Writing at address..\n";
+
+ auto addr =
+ (volatile UIntPtr*)(reinterpret_cast<UIntPtr>(fAddress) + offset);
+ *addr = bit;
+
+ return true;
+ }
+
+ UIntPtr DMAWrapper::Read(const UIntPtr& offset)
+ {
+ kcout << "[DMAWrapper::Read] checking fAddress..\n";
+ if (!fAddress)
+ return 0;
+
+ kcout << "[DMAWrapper::Read] Reading fAddress..\n";
+ return *(volatile UIntPtr*)(reinterpret_cast<UIntPtr>(fAddress) + offset);
+ ;
+ }
+
+ UIntPtr DMAWrapper::operator[](const UIntPtr& offset)
+ {
+ return this->Read(offset);
+ }
+
+ OwnPtr<IOBuf<Char*>> DMAFactory::Construct(OwnPtr<DMAWrapper>& dma)
+ {
+ if (!dma)
+ return {};
+
+ OwnPtr<IOBuf<Char*>> dmaOwnPtr =
+ make_ptr<IOBuf<Char*>, char*>(reinterpret_cast<char*>(dma->fAddress));
+
+ if (!dmaOwnPtr)
+ return {};
+
+ kcout << "Returning the new OwnPtr<IOBuf<Char*>>!\r";
+ return dmaOwnPtr;
+ }
+
+ DMAWrapper& DMAWrapper::operator=(voidPtr Ptr)
+ {
+ fAddress = Ptr;
+ return *this;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/HALKit/AMD64/PCI/Database.cc b/dev/Kernel/HALKit/AMD64/PCI/Database.cc
new file mode 100644
index 00000000..2db1c111
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/PCI/Database.cc
@@ -0,0 +1,11 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/PCI/Database.h>
+
+namespace Kernel
+{
+}
diff --git a/dev/Kernel/HALKit/AMD64/PCI/Device.cc b/dev/Kernel/HALKit/AMD64/PCI/Device.cc
new file mode 100644
index 00000000..7b0f64b3
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/PCI/Device.cc
@@ -0,0 +1,139 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/PCI/Device.h>
+
+Kernel::UInt ZKA_PCIReadRaw(Kernel::UInt bar, Kernel::UShort bus, Kernel::UShort dev, Kernel::UShort fun)
+{
+ Kernel::UInt target = 0x80000000 | ((Kernel::UInt)bus << 16) |
+ ((Kernel::UInt)dev << 11) | ((Kernel::UInt)fun << 8) |
+ (bar & 0xFC);
+
+ Kernel::HAL::rt_out32((Kernel::UShort)Kernel::PCI::PciConfigKind::ConfigAddress,
+ target);
+
+ return Kernel::HAL::rt_in32((Kernel::UShort)Kernel::PCI::PciConfigKind::ConfigData);
+}
+
+void ZKA_PCISetCfgTarget(Kernel::UInt bar, Kernel::UShort bus, Kernel::UShort dev, Kernel::UShort fun)
+{
+ Kernel::UInt target = 0x80000000 | ((Kernel::UInt)bus << 16) |
+ ((Kernel::UInt)dev << 11) | ((Kernel::UInt)fun << 8) |
+ (bar & ~3);
+
+ Kernel::HAL::rt_out32((Kernel::UShort)Kernel::PCI::PciConfigKind::ConfigAddress,
+ target);
+}
+
+#define PCI_BAR_IO 0x01
+#define PCI_BAR_LOWMEM 0x02
+#define PCI_BAR_64 0x04
+#define PCI_BAR_PREFETCH 0x08
+
+namespace Kernel::PCI
+{
+ Device::Device(UShort bus, UShort device, UShort func, UInt32 bar)
+ : fBus(bus), fDevice(device), fFunction(func), fBar(bar)
+ {
+ }
+
+ Device::~Device() = default;
+
+ UInt Device::Read(UInt bar, Size sz)
+ {
+ ZKA_PCISetCfgTarget(bar, fBus, fDevice, fFunction);
+
+ if (sz == 4)
+ return HAL::rt_in32((UShort)PciConfigKind::ConfigData + (bar & 3));
+ if (sz == 2)
+ return HAL::rt_in16((UShort)PciConfigKind::ConfigData + (bar & 3));
+ if (sz == 1)
+ return HAL::rt_in8((UShort)PciConfigKind::ConfigData + (bar & 3));
+
+ return 0xFFFF;
+ }
+
+ void Device::Write(UInt bar, UIntPtr data, Size sz)
+ {
+ ZKA_PCISetCfgTarget(bar, fBus, fDevice, fFunction);
+
+ if (sz == 4)
+ HAL::rt_out32((UShort)PciConfigKind::ConfigData + (fBar & 3), (UInt)data);
+ if (sz == 2)
+ HAL::rt_out16((UShort)PciConfigKind::ConfigData + (fBar & 3), (UShort)data);
+ if (sz == 1)
+ HAL::rt_out8((UShort)PciConfigKind::ConfigData + (fBar & 3), (UChar)data);
+ }
+
+ UShort Device::DeviceId()
+ {
+ return (UShort)(ZKA_PCIReadRaw(0x0 >> 16, fBus, fDevice, fFunction));
+ }
+
+ UShort Device::VendorId()
+ {
+ return (UShort)(ZKA_PCIReadRaw(0x0, fBus, fDevice, fFunction) >> 16);
+ }
+
+ UShort Device::InterfaceId()
+ {
+ return (UShort)(ZKA_PCIReadRaw(0x0, fBus, fDevice, fFunction) >> 16);
+ }
+
+ UChar Device::Class()
+ {
+ return (UChar)(ZKA_PCIReadRaw(0x08, fBus, fDevice, fFunction) >> 24);
+ }
+
+ UChar Device::Subclass()
+ {
+ return (UChar)(ZKA_PCIReadRaw(0x08, fBus, fDevice, fFunction) >> 16);
+ }
+
+ UChar Device::ProgIf()
+ {
+ return (UChar)(ZKA_PCIReadRaw(0x08, fBus, fDevice, fFunction) >> 8);
+ }
+
+ UChar Device::HeaderType()
+ {
+ return (UChar)(ZKA_PCIReadRaw(0xC, fBus, fDevice, fFunction) >> 16);
+ }
+
+ void Device::EnableMmio(UInt32 bar_in)
+ {
+ bool enable = Read(bar_in, sizeof(UChar)) | (1 << 1);
+ Write(bar_in, enable, sizeof(UShort));
+ }
+
+ void Device::BecomeBusMaster(UInt32 bar_in)
+ {
+ bool enable = Read(bar_in, sizeof(UShort)) | (1 << 2);
+ Write(bar_in, enable, sizeof(UShort));
+ }
+
+ UIntPtr Device::Bar(UInt32 bar_in)
+ {
+ UInt32 bar = ZKA_PCIReadRaw(bar_in, fBus, fDevice, fFunction);
+ return bar;
+ }
+
+ UShort Device::Vendor()
+ {
+ UShort vendor = VendorId();
+
+ if (vendor != (UShort)PciConfigKind::Invalid)
+ fDevice = (UShort)Read(0x0, sizeof(UShort));
+
+ return fDevice;
+ }
+
+ Device::operator bool()
+ {
+ return VendorId() != (UShort)PciConfigKind::Invalid;
+ }
+} // namespace Kernel::PCI
diff --git a/dev/Kernel/HALKit/AMD64/PCI/Express.cc b/dev/Kernel/HALKit/AMD64/PCI/Express.cc
new file mode 100644
index 00000000..f6b5ea4e
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/PCI/Express.cc
@@ -0,0 +1,11 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/PCI/Express.h>
+
+namespace Kernel
+{
+}
diff --git a/dev/Kernel/HALKit/AMD64/PCI/IO.cc b/dev/Kernel/HALKit/AMD64/PCI/IO.cc
new file mode 100644
index 00000000..c969498d
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/PCI/IO.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/PCI/IO.h>
diff --git a/dev/Kernel/HALKit/AMD64/PCI/Iterator.cc b/dev/Kernel/HALKit/AMD64/PCI/Iterator.cc
new file mode 100644
index 00000000..f0289cdf
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/PCI/Iterator.cc
@@ -0,0 +1,41 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/PCI/Iterator.h>
+
+namespace Kernel::PCI
+{
+ Iterator::Iterator(const Types::PciDeviceKind& type)
+ {
+ // probe devices.
+ for (int bus = 0; bus < ZKA_BUS_COUNT; ++bus)
+ {
+ for (int device = 0; device < ZKA_DEVICE_COUNT; ++device)
+ {
+ for (int function = 0; function < ZKA_FUNCTION_COUNT; ++function)
+ {
+ auto bar = 0x00;
+
+ Device dev(bus, device, function, bar);
+
+ if (dev.Class() == (UChar)type)
+ {
+ fDevices[bus] = dev;
+ }
+ }
+ }
+ }
+ }
+
+ Iterator::~Iterator()
+ {
+ }
+
+ Ref<PCI::Device> Iterator::operator[](const Size& at)
+ {
+ return fDevices[at];
+ }
+} // namespace Kernel::PCI
diff --git a/dev/Kernel/HALKit/AMD64/PCI/PCI.cc b/dev/Kernel/HALKit/AMD64/PCI/PCI.cc
new file mode 100644
index 00000000..0ade547c
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/PCI/PCI.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/PCI/PCI.h>
diff --git a/dev/Kernel/HALKit/AMD64/Paging.h b/dev/Kernel/HALKit/AMD64/Paging.h
new file mode 100644
index 00000000..e58d2466
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/Paging.h
@@ -0,0 +1,99 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+/** ---------------------------------------------------
+
+ * THIS FILE CONTAINS CODE FOR X86_64 PAGING.
+
+------------------------------------------------------- */
+
+#include <NewKit/Defines.h>
+
+#ifndef kPageMax
+#define kPageMax (0x200)
+#endif //! kPageMax
+
+#ifndef kPageAlign
+#define kPageAlign (0x08)
+#endif //! kPageAlign
+
+#ifndef kPageSize
+#define kPageSize (0x1000)
+#endif // !kPageSize
+
+#ifndef kAlign
+#define kAlign __BIGGEST_ALIGNMENT__
+#endif // !kAlign
+
+EXTERN_C void hal_flush_tlb();
+EXTERN_C void hal_invl_tlb(Kernel::VoidPtr addr);
+EXTERN_C void hal_write_cr3(Kernel::VoidPtr cr3);
+EXTERN_C void hal_write_cr0(Kernel::VoidPtr bit);
+
+EXTERN_C Kernel::VoidPtr hal_read_cr0(); // @brief CPU control register.
+EXTERN_C Kernel::VoidPtr hal_read_cr2(); // @brief Fault address.
+EXTERN_C Kernel::VoidPtr hal_read_cr3(); // @brief Page table.
+
+namespace Kernel::HAL
+{
+ /// @brief Final page entry (Not PML, PDPT)
+ struct PACKED ZKA_PTE final
+ {
+ UInt64 Present : 1;
+ UInt64 Wr : 1;
+ UInt64 User : 1;
+ UInt64 Wt : 1;
+ UInt64 Cache : 1;
+ UInt64 Accessed : 1;
+ UInt64 Dirty : 1;
+ UInt64 MemoryType : 1;
+ UInt64 Global : 1;
+ UInt64 Resvered1 : 3;
+ UInt64 PhysicalAddress : 36;
+ UInt64 Reserved2 : 10;
+ UInt64 ProtectionKey : 5;
+ UInt64 ExecDisable : 1;
+ };
+
+ 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 ZKA_PDE final
+ {
+ ZKA_PTE* 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 Kernel::HAL
+
+namespace Kernel
+{
+ typedef HAL::ZKA_PTE PTE;
+ typedef HAL::ZKA_PDE PDE;
+} // namespace Kernel
diff --git a/dev/Kernel/HALKit/AMD64/Processor.h b/dev/Kernel/HALKit/AMD64/Processor.h
new file mode 100644
index 00000000..0e6dcfff
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/Processor.h
@@ -0,0 +1,326 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: Prcoessor.h
+ Purpose: AMD64 processor abstraction.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Array.h>
+#include <NewKit/Defines.h>
+#include <NewKit/Utils.h>
+#include <FirmwareKit/Handover.h>
+#include <HALKit/AMD64/Paging.h>
+
+#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>
+}
+
+#include <HALKit/AMD64/CPUID.h>
+
+/// @brief Maximum entries of the interrupt descriptor table.
+#define kKernelIdtSize (0x100)
+
+/// @brief interrupt for system call.
+#define kKernelInterruptId (0x32)
+
+#define IsActiveLow(FLG) (FLG & 2)
+#define IsLevelTriggered(FLG) (FLG & 8)
+
+#define kInterruptGate (0x8E)
+#define kTrapGate (0xEF)
+#define kTaskGate (0b10001100)
+#define kIDTSelector (0x08)
+
+namespace Kernel
+{
+ namespace Detail::AMD64
+ {
+ struct PACKED InterruptDescriptorAMD64 final
+ {
+ UInt16 OffsetLow; // offset bits 0..15
+ UInt16 Selector; // a code segment selector in GDT or LDT
+ UInt8 Ist;
+ UInt8 TypeAttributes;
+ UInt16 OffsetMid;
+ UInt32 OffsetHigh;
+ UInt32 Zero; // reserved
+ };
+ } // namespace Detail::AMD64
+} // namespace Kernel
+
+namespace Kernel::HAL
+{
+ /// @brief Memory Manager mapping flags.
+ enum
+ {
+ kMMFlagsInvalid = 0 << 0,
+ kMMFlagsPresent = 1 << 0,
+ kMMFlagsWr = 1 << 1,
+ kMMFlagsUser = 1 << 2,
+ kMMFlagsNX = 1 << 3,
+ kMMFlagsCount = 4,
+ };
+
+ struct PACKED Register64 final
+ {
+ UShort Limit;
+ UIntPtr Base;
+ };
+
+ struct PACKED RegisterGDT final
+ {
+ UShort Limit;
+ UIntPtr Base;
+ };
+
+ using RawRegister = UInt64;
+ using Reg = RawRegister;
+ using InterruptId = UInt16; /* For each element in the IVT */
+
+ /// @brief Stack frame (as retrieved from assembly.)
+ struct PACKED StackFrame final
+ {
+ RawRegister R8{0};
+ RawRegister R9{0};
+ RawRegister R10{0};
+ RawRegister FS{0};
+ RawRegister R12{0};
+ RawRegister R13{0};
+ RawRegister R14{0};
+ RawRegister R15{0};
+ RawRegister GS{0};
+ RawRegister SP{0};
+ RawRegister BP{0};
+ };
+
+ typedef StackFrame* StackFramePtr;
+
+ class InterruptDescriptor final
+ {
+ public:
+ UShort Offset;
+ UShort Selector;
+ UChar Ist;
+ UChar Atrributes;
+
+ UShort SecondOffset;
+ UInt ThirdOffset;
+ UInt Zero;
+
+ operator bool()
+ {
+ return Offset != 0xFFFF;
+ }
+ };
+
+ using InterruptDescriptorArray = Array<InterruptDescriptor, 256>;
+
+ class SegmentDescriptor final
+ {
+ public:
+ UInt16 Base;
+ UInt8 BaseMiddle;
+ UInt8 BaseHigh;
+
+ UShort Limit;
+ UChar Gran;
+ UChar AccessByte;
+ };
+
+ /***
+ * @brief Segment Boolean operations
+ */
+ class SegmentDescriptorComparator final
+ {
+ public:
+ Bool IsValid(SegmentDescriptor& seg)
+ {
+ return seg.Base > seg.Limit;
+ }
+
+ Bool Equals(SegmentDescriptor& seg, SegmentDescriptor& segRight)
+ {
+ return seg.Base == segRight.Base && seg.Limit == segRight.Limit;
+ }
+ };
+
+ using SegmentArray = Array<SegmentDescriptor, 6>;
+
+ class GDTLoader final
+ {
+ public:
+ static Void Load(RegisterGDT& gdt);
+ static Void Load(Ref<RegisterGDT>& gdt);
+ };
+
+ class IDTLoader final
+ {
+ public:
+ static Void Load(Register64& idt);
+ static Void Load(Ref<Register64>& idt);
+ };
+
+ /***********************************************************************************/
+ /// @brief Is the current config SMP aware?
+ /// @return True if YES, False if not.
+ /***********************************************************************************/
+
+ Bool mp_is_smp(Void) noexcept;
+
+ /***********************************************************************************/
+ /// @brief Fetch and enable SMP scheduler.
+ /// @param vendor_ptr SMP containing structure.
+ /***********************************************************************************/
+ Void mp_get_cores(VoidPtr vendor_ptr) noexcept;
+
+ /***********************************************************************************/
+ /// @brief Do a cpuid to check if MSR exists on CPU.
+ /// @retval true it does exists.
+ /// @retval false it doesn't.
+ /***********************************************************************************/
+ inline Bool hal_has_msr() noexcept
+ {
+ static UInt32 eax, unused, edx; // eax, edx
+
+ __get_cpuid(1, &eax, &unused, &unused, &edx);
+
+ // edx returns the flag for MSR (which is 1 shifted to 5.)
+ return edx & (1 << 5);
+ }
+
+ /***********************************************************************************/
+ /// @brief Get Model specific register inside core.
+ /// @param msr MSR
+ /// @param lo low byte
+ /// @param hi high byte
+ /***********************************************************************************/
+ inline Void hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept
+ {
+ if (!lo || !hi)
+ return;
+
+ asm volatile("rdmsr"
+ : "=a"(*lo), "=d"(*hi)
+ : "c"(msr));
+ }
+
+ /// @brief Set Model-specific register.
+ /// @param msr MSR
+ /// @param lo low byte
+ /// @param hi high byte
+ inline Void hal_set_msr(UInt32 msr, UInt32 lo, UInt32 hi) noexcept
+ {
+ asm volatile("wrmsr"
+ :
+ : "a"(lo), "d"(hi), "c"(msr));
+ }
+
+ /// @brief Processor specific namespace.
+ namespace Detail
+ {
+ /* @brief TSS struct. */
+ struct ZKA_TSS final
+ {
+ UInt32 fReserved1;
+ UInt64 fRsp0;
+ UInt64 fRsp1;
+ UInt64 fRsp2;
+ UInt64 fReserved2;
+ UInt64 fIst1;
+ UInt64 fIst2;
+ UInt64 fIst3;
+ UInt64 fIst4;
+ UInt64 fIst5;
+ UInt64 fIst6;
+ UInt64 fIst7;
+ UInt64 fReserved3;
+ UInt16 fReserved4;
+ UInt16 fIopb;
+ };
+
+ /**
+ @brief Global descriptor table entry, either null, code or data.
+ */
+
+ struct PACKED ZKA_GDT_ENTRY final
+ {
+ UInt16 fLimitLow;
+ UInt16 fBaseLow;
+ UInt8 fBaseMid;
+ UInt8 fAccessByte;
+ UInt8 fFlags;
+ UInt8 fBaseHigh;
+ };
+ } // namespace Detail
+
+ class APICController
+ {
+ public:
+ explicit APICController(VoidPtr base)
+ : fApic(base)
+ {
+ }
+
+ ~APICController() = default;
+
+ ZKA_COPY_DEFAULT(APICController);
+
+ public:
+ UInt32 Read(UInt32 reg) noexcept;
+ Void Write(UInt32 reg, UInt32 value) noexcept;
+
+ private:
+ VoidPtr fApic{nullptr};
+ };
+
+ /// @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);
+
+ EXTERN_C UInt8 rt_in8(UInt16 port);
+ EXTERN_C UInt16 rt_in16(UInt16 port);
+ EXTERN_C UInt32 rt_in32(UInt16 port);
+
+ EXTERN_C void rt_out16(UShort port, UShort byte);
+ EXTERN_C void rt_out8(UShort port, UChar byte);
+ EXTERN_C void rt_out32(UShort port, UInt byte);
+
+ EXTERN_C void rt_wait_400ns();
+ EXTERN_C void rt_halt();
+ EXTERN_C void rt_cli();
+ EXTERN_C void rt_sti();
+ EXTERN_C void rt_cld();
+ EXTERN_C void rt_std();
+} // namespace Kernel::HAL
+
+EXTERN_C Kernel::Void idt_handle_generic(Kernel::UIntPtr rsp);
+EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp);
+EXTERN_C Kernel::Void idt_handle_math(Kernel::UIntPtr rsp);
+EXTERN_C Kernel::Void idt_handle_pf(Kernel::UIntPtr rsp);
+
+EXTERN_C ATTRIBUTE(naked) Kernel::Void hal_load_idt(Kernel::HAL::Register64 ptr);
+EXTERN_C ATTRIBUTE(naked) Kernel::Void hal_load_gdt(Kernel::HAL::RegisterGDT ptr);
+
+inline Kernel::VoidPtr kKernelBitMpStart = nullptr;
+inline Kernel::UIntPtr kKernelBitMpSize = 0UL;
diff --git a/dev/Kernel/HALKit/AMD64/ReadMe.md b/dev/Kernel/HALKit/AMD64/ReadMe.md
new file mode 100644
index 00000000..5ea0a19f
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/ReadMe.md
@@ -0,0 +1,8 @@
+# AMD64 Hardware Abstraction Layer
+
+## Brief
+
+- Supported CPU: AMD64 BASED CPUs.
+- Supported Firmware: EDK 2.
+
+###### Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. All rights reserved.
diff --git a/dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cc b/dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cc
new file mode 100644
index 00000000..5f765d03
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cc
@@ -0,0 +1,38 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+/**
+ * @file ATA-DMA.cc
+ * @author Amlal EL Mahrouss (amlalelmahrouss@icloud.com)
+ * @brief ATA driver (DMA mode).
+ * @version 0.1
+ * @date 2024-02-02
+ *
+ * @copyright Copyright (c) Amlal EL Mahrouss
+ *
+ */
+
+#include <StorageKit/PRDT.h>
+
+#include <Mod/ATA/ATA.h>
+#include <ArchKit/ArchKit.h>
+
+using namespace Kernel;
+
+EXTERN_C Int32 kPRDTTransferStatus;
+STATIC PRDT kPRDT;
+
+#ifdef __ATA_DMA__
+
+#ifdef __ATA_PIO__
+#error !!! You cant have both PIO and DMA enabled! !!!
+#endif /* ifdef __ATA_PIO__ */
+
+#ifdef __AHCI__
+#error !!! You cant have both ATA and AHCI enabled! !!!
+#endif /* ifdef __AHCI__ */
+
+#endif /* ifdef __ATA_DMA__ */
diff --git a/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc b/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc
new file mode 100644
index 00000000..6e523cb7
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc
@@ -0,0 +1,195 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+/**
+ * @file ATA-PIO.cc
+ * @author Amlal EL Mahrouss (amlalelmahrouss@icloud.com)
+ * @brief ATA driver (PIO mode).
+ * @version 0.1
+ * @date 2024-02-02
+ *
+ * @copyright Copyright (c) Amlal EL Mahrouss
+ *
+ */
+
+#include <Mod/ATA/ATA.h>
+#include <ArchKit/ArchKit.h>
+
+#ifdef __ATA_PIO__
+
+using namespace Kernel;
+using namespace Kernel::HAL;
+
+/// bugs: 0
+
+#define kATADataLen 256
+
+STATIC Boolean kATADetected = false;
+STATIC Int32 kATADeviceType = kATADeviceCount;
+STATIC Char kATAData[kATADataLen] = {0};
+
+Boolean drv_std_wait_io(UInt16 IO)
+{
+ for (int i = 0; i < 400; i++)
+ rt_in8(IO + ATA_REG_STATUS);
+
+ATAWaitForIO_Retry:
+ auto rdy = rt_in8(IO + ATA_REG_STATUS);
+
+ if ((rdy & ATA_SR_BSY))
+ goto ATAWaitForIO_Retry;
+
+ATAWaitForIO_Retry2:
+ rdy = rt_in8(IO + ATA_REG_STATUS);
+
+ if (rdy & ATA_SR_ERR)
+ return false;
+
+ if (!(rdy & ATA_SR_DRDY))
+ goto ATAWaitForIO_Retry2;
+
+ return true;
+}
+
+Void drv_std_select(UInt16 Bus)
+{
+ if (Bus == ATA_PRIMARY_IO)
+ rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL);
+ else
+ rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL);
+}
+
+Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster)
+{
+ UInt16 IO = Bus;
+
+ drv_std_select(IO);
+
+ATAInit_Retry:
+ // Bus init, NEIN bit.
+ rt_out8(IO + ATA_REG_NEIN, 1);
+
+ // identify until it's good
+
+ auto rdy = rt_in8(IO + ATA_REG_STATUS);
+
+ if (rdy & ATA_SR_ERR)
+ {
+ kcout << "ATA Error, aborting...\r";
+
+ return false;
+ }
+
+ if ((rdy & ATA_SR_BSY))
+ {
+ kcout << "Retrying as controller is busy...\r";
+ goto ATAInit_Retry;
+ }
+
+ rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
+
+ /// fetch serial info
+ /// model, speed, number of sectors...
+
+ drv_std_wait_io(IO);
+
+ for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData)
+ {
+ kATAData[indexData] = rt_in16(IO + ATA_REG_DATA);
+ }
+
+ OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO;
+
+ OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE;
+
+ return YES;
+}
+
+Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size)
+{
+ Lba /= SectorSz;
+
+ UInt8 Command = ((!Master) ? 0xE0 : 0xF0);
+
+ drv_std_wait_io(IO);
+ drv_std_select(IO);
+
+ rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F));
+
+ rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz));
+
+ 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);
+
+ drv_std_wait_io(IO);
+
+ for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff)
+ {
+ drv_std_wait_io(IO);
+ Buf[IndexOff] = rt_in16(IO + ATA_REG_DATA);
+ drv_std_wait_io(IO);
+ }
+
+ drv_std_wait_io(IO);
+}
+
+Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size)
+{
+ Lba /= SectorSz;
+
+ UInt8 Command = ((!Master) ? 0xE0 : 0xF0);
+
+ drv_std_wait_io(IO);
+ drv_std_select(IO);
+
+ rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F));
+
+ rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz)) / SectorSz));
+
+ 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);
+
+ drv_std_wait_io(IO);
+
+ for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff)
+ {
+ drv_std_wait_io(IO);
+ rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]);
+ drv_std_wait_io(IO);
+ }
+
+ drv_std_wait_io(IO);
+}
+
+/// @brief is ATA detected?
+Boolean drv_std_detected(Void)
+{
+ return kATADetected;
+}
+
+/***
+ @brief Getter, gets the number of sectors inside the drive.
+*/
+Kernel::SizeT drv_get_sector_count()
+{
+ return (kATAData[61] << 16) | kATAData[60];
+}
+
+/// @brief Get the drive size.
+Kernel::SizeT drv_get_size()
+{
+ return (drv_get_sector_count()) * kATASectorSize;
+}
+
+#endif /* ifdef __ATA_PIO__ */
diff --git a/dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc b/dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc
new file mode 100644
index 00000000..74afcde3
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc
@@ -0,0 +1,316 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+/**
+ * @file AHCI.cc
+ * @author Amlal EL Mahrouss (amlalelmahrouss@icloud.com)
+ * @brief AHCI driver.
+ * @version 0.1
+ * @date 2024-02-02
+ *
+ * @Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+ *
+ */
+
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/LPC.h>
+
+#include <Mod/ATA/ATA.h>
+#include <Mod/AHCI/AHCI.h>
+#include <KernelKit/PCI/Iterator.h>
+#include <NewKit/Utils.h>
+#include <KernelKit/LockDelegate.h>
+
+#ifdef __AHCI__
+
+#define kHBAErrTaskFile (1 << 30)
+#define kHBAPxCmdST 0x0001
+#define kHBAPxCmdFre 0x0010
+#define kHBAPxCmdFR 0x4000
+#define kHBAPxCmdCR 0x8000
+
+#define kSataLBAMode (1 << 6)
+
+#define kAhciSRBsy (0x80)
+#define kAhciSRDrq (0x08)
+
+#define kAhciPortCnt 32
+
+enum
+{
+ kSATAProgIfAHCI = 0x01,
+ kSATASubClass = 0x06,
+ kSATABar5 = 0x24,
+};
+
+STATIC Kernel::PCI::Device kPCIDevice;
+STATIC HbaMem* kSATAPort = nullptr;
+STATIC Kernel::SizeT kSATAPortIdx = 0UL;
+STATIC Kernel::Lba kCurrentDiskSectorCount = 0UL;
+
+template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify>
+static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) noexcept;
+
+static Kernel::Int32 drv_find_cmd_slot(HbaPort* port) noexcept;
+
+static Kernel::Void drv_calculate_disk_geometry() noexcept;
+
+static Kernel::Void drv_calculate_disk_geometry() noexcept
+{
+ kCurrentDiskSectorCount = 0UL;
+
+ Kernel::UInt8 identify_data[kib_cast(4)] = {};
+
+ drv_std_input_output<NO, YES, YES>(0, identify_data, 0, kib_cast(8));
+
+ kCurrentDiskSectorCount = (identify_data[61] << 16) | identify_data[60];
+
+ kcout << "Disk Size: " << Kernel::number(drv_get_size()) << endl;
+ kcout << "Highest LBA: " << Kernel::number(kCurrentDiskSectorCount) << endl;
+}
+
+/// @brief Initializes an AHCI disk.
+/// @param PortsImplemented the amount of kSATAPort that have been detected.
+/// @return if the disk was successfully initialized or not.
+Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
+{
+ using namespace Kernel;
+
+ PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController);
+
+ for (SizeT device_index = 0; device_index < ZKA_BUS_COUNT; ++device_index)
+ {
+ kPCIDevice = iterator[device_index].Leak(); // And then leak the reference.
+
+ // if SATA and then interface is AHCI...
+ if (kPCIDevice.Subclass() == kSATASubClass &&
+ kPCIDevice.ProgIf() == kSATAProgIfAHCI)
+ {
+ kPCIDevice.EnableMmio(0x24); // Enable the memory index_byte/o for this ahci device.
+ kPCIDevice.BecomeBusMaster(0x24); // Become bus master for this ahci device, so that we can control it.
+
+ HbaMem* mem_ahci = (HbaMem*)kPCIDevice.Bar(0x24);
+
+ Kernel::UInt32 ports_implemented = mem_ahci->Pi;
+ Kernel::UInt16 ahci_index = 0;
+
+ const Kernel::UInt16 kMaxPortsImplemented = kAhciPortCnt;
+ const Kernel::UInt32 kSATASignature = 0x00000101;
+ const Kernel::UInt8 kAhciPresent = 0x03;
+ const Kernel::UInt8 kAhciIPMActive = 0x01;
+
+ Kernel::Boolean detected = false;
+
+ while (ahci_index < kMaxPortsImplemented)
+ {
+ if (ports_implemented)
+ {
+ kcout << "Port is implemented.\r";
+
+ Kernel::UInt8 ipm = (mem_ahci->Ports[ahci_index].Ssts >> 8) & 0x0F;
+ Kernel::UInt8 det = mem_ahci->Ports[ahci_index].Ssts & 0x0F;
+
+ if (mem_ahci->Ports[ahci_index].Sig == kSATASignature)
+ {
+ kcout << "Port is SATA.\r";
+
+ kSATAPortIdx = ahci_index;
+ kSATAPort = mem_ahci;
+
+ kSATAPort->Ports[kSATAPortIdx].Cmd &= ~kHBAPxCmdST;
+ kSATAPort->Ports[kSATAPortIdx].Cmd &= ~kHBAPxCmdFre;
+
+ while (YES)
+ {
+ if (kSATAPort->Ports[kSATAPortIdx].Cmd & kHBAPxCmdFR)
+ continue;
+ if (kSATAPort->Ports[kSATAPortIdx].Cmd & kHBAPxCmdCR)
+ continue;
+
+ break;
+ }
+
+ const auto kAHCIBaseAddress = mib_cast(4);
+
+ kSATAPort->Ports[kSATAPortIdx].Clb = kAHCIBaseAddress + (kSATAPortIdx << 10);
+ kSATAPort->Ports[kSATAPortIdx].Clbu = 0;
+
+ rt_set_memory((VoidPtr)((UIntPtr)kSATAPort->Ports[kSATAPortIdx].Clb), 0, 1024);
+
+ kSATAPort->Ports[kSATAPortIdx].Fb = kAHCIBaseAddress + (32 << 10) + (kSATAPortIdx << 8);
+ kSATAPort->Ports[kSATAPortIdx].Fbu = 0;
+
+ rt_set_memory((VoidPtr)((UIntPtr)kSATAPort->Ports[kSATAPortIdx].Fb), 0, 256);
+
+ HbaCmdHeader* cmdheader = (HbaCmdHeader*)((UIntPtr)kSATAPort->Ports[kSATAPortIdx].Clb);
+
+ for (int i = 0; i < 32; i++)
+ {
+ cmdheader[i].Prdtl = 8;
+
+ cmdheader[i].Ctba = kAHCIBaseAddress + (40 << 10) + (kSATAPortIdx << 13) + (i << 8);
+ cmdheader[i].Ctbau = 0;
+
+ rt_set_memory((VoidPtr)(UIntPtr)cmdheader[i].Ctba, 0, 256);
+ }
+
+ while (kSATAPort->Ports[kSATAPortIdx].Cmd & kHBAPxCmdCR)
+ {
+ }
+
+ kSATAPort->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdFre;
+ kSATAPort->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdST;
+
+ drv_calculate_disk_geometry();
+
+ detected = YES;
+
+ break;
+ }
+ }
+
+ ports_implemented >>= 1;
+ ++ahci_index;
+ }
+
+ return detected;
+ }
+ }
+
+ return No;
+}
+
+Kernel::Boolean drv_std_detected(Kernel::Void)
+{
+ return kPCIDevice.DeviceId() != 0xFFFF;
+}
+
+Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer)
+{
+ drv_std_input_output<YES, YES, NO>(lba, (Kernel::UInt8*)buffer, sector_sz, size_buffer);
+}
+
+Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer)
+{
+ drv_std_input_output<NO, YES, NO>(lba, (Kernel::UInt8*)buffer, sector_sz, size_buffer);
+}
+
+static Kernel::Int32 drv_find_cmd_slot(HbaPort* port) noexcept
+{
+ if (port == nullptr)
+ return -1;
+
+ Kernel::UInt32 slots = (kSATAPort->Ports[kSATAPortIdx].Sact | kSATAPort->Ports[kSATAPortIdx].Ci);
+
+ for (Kernel::Int32 i = 0; i < ((kSATAPort->Cap & 0x1F) + 1); i++)
+ {
+ if ((slots & 1) == 0)
+ return i;
+
+ slots >>= 1;
+ }
+
+ return -1;
+}
+
+template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify>
+static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) noexcept
+{
+ if (!CommandOrCTRL)
+ return;
+
+ kSATAPort->Ports[kSATAPortIdx].Is = -1;
+
+ auto slot = 0L;
+
+ slot = drv_find_cmd_slot(&kSATAPort->Ports[kSATAPortIdx]);
+
+ if (slot == -1)
+ return;
+
+ volatile HbaCmdHeader* command_header = ((volatile HbaCmdHeader*)((Kernel::UInt64)kSATAPort->Ports[kSATAPortIdx].Clb + kSATAPort->Ports[kSATAPortIdx].Clbu));
+
+ command_header += slot;
+
+ MUST_PASS(command_header);
+
+ command_header->Cfl = sizeof(FisRegH2D) / sizeof(Kernel::UInt32);
+ command_header->Write = Write;
+ command_header->Prdtl = (Kernel::UInt16)((size_buffer - 1) >> 4) + 1;
+
+ volatile HbaCmdTbl* command_table = (volatile HbaCmdTbl*)((Kernel::UInt64)command_header->Ctba + command_header->Ctbau);
+
+ MUST_PASS(command_table);
+
+ for (Kernel::SizeT i = 0; i < (command_header->Prdtl - 1); i++)
+ {
+ command_table->PrdtEntries[i].Dba = ((Kernel::UInt32)(Kernel::UInt64)buffer & 0xFFFFFFFF);
+ command_table->PrdtEntries[i].Dbau = (((Kernel::UInt64)buffer >> 32) & 0xFFFFFFFF);
+ command_table->PrdtEntries[i].Dbc = (size_buffer - 1);
+ command_table->PrdtEntries[i].InterruptBit = YES;
+
+ size_buffer -= 16;
+ buffer += kib_cast(4);
+ }
+
+ volatile FisRegH2D* h2d_fis = (volatile FisRegH2D*)((Kernel::UInt64)command_table->Cfis);
+
+ h2d_fis->FisType = kFISTypeRegH2D;
+
+ h2d_fis->CmdOrCtrl = YES;
+
+ h2d_fis->Command = Write ? kAHCICmdWriteDmaEx : kAHCICmdReadDmaEx;
+
+ if (Identify)
+ h2d_fis->Command = kAHCICmdIdentify;
+
+ h2d_fis->Lba0 = lba;
+ h2d_fis->Lba1 = lba >> 8;
+ h2d_fis->Lba2 = lba >> 16;
+ h2d_fis->Lba3 = lba >> 24;
+
+ h2d_fis->Device = kSataLBAMode;
+
+ h2d_fis->CountLow = sector_sz & 0xFF;
+ h2d_fis->CountHigh = (sector_sz >> 8) & 0xFF;
+
+ while ((kSATAPort->Ports[kSATAPortIdx].Tfd & (kAhciSRBsy | kAhciSRDrq)))
+ {
+ kcout << "waiting for slot to be ready\r\n";
+ }
+
+ kSATAPort->Is = -1;
+ kSATAPort->Ports[kSATAPortIdx].Ci |= 1 << slot;
+
+ while (kSATAPort->Ports[kSATAPortIdx].Ci & (1 << slot))
+ {
+ kcout << Kernel::number(slot) << endl;
+
+ if (kSATAPort->Is & kHBAErrTaskFile) // check for task file error.
+ {
+ Kernel::ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "AHCI Read disk failure, faulty component.");
+ return;
+ }
+ }
+}
+
+/***
+ @brief Gets the number of sectors inside the drive.
+ @return Sector size in bytes.
+ */
+Kernel::SizeT drv_get_sector_count()
+{
+ return kCurrentDiskSectorCount;
+}
+
+/// @brief Get the drive size.
+/// @return Disk size in bytes.
+Kernel::SizeT drv_get_size()
+{
+ return (drv_get_sector_count()) * kAHCISectorSize;
+}
+
+#endif // ifdef __AHCI__
diff --git a/dev/Kernel/HALKit/AMD64/make_ap_blob.sh b/dev/Kernel/HALKit/AMD64/make_ap_blob.sh
new file mode 100755
index 00000000..3f079187
--- /dev/null
+++ b/dev/Kernel/HALKit/AMD64/make_ap_blob.sh
@@ -0,0 +1,3 @@
+# !/bin/sh
+
+nasm -f bin HalApplicationProcessorStartup.asm -o HalApplicationProcessorStartup.bin \ No newline at end of file
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..ba29bd61
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/APM/APM+IO.cc
@@ -0,0 +1,37 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <Mod/APM/APM.h>
+#include <KernelKit/LPC.h>
+
+using namespace Kernel;
+
+/// @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..cccb9d77
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/ApplicationProcessor.h
@@ -0,0 +1,19 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+#include <HALKit/ARM64/Processor.h>
+
+/************************************************** */
+/* INITIALIZE THE GIC ON CPU. */
+/************************************************** */
+
+namespace Kernel
+{
+ BOOL mp_initialize_gic(Kernel::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..69459f66
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/HalACPIFactoryInterface.cc
@@ -0,0 +1,31 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <Mod/ACPI/ACPIFactoryInterface.h>
+#include <NewKit/KString.h>
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/Heap.h>
+#include <Mod/APM/APM.h>
+
+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/Kernel/HALKit/ARM64/HalApplicationProcessor.cc b/dev/Kernel/HALKit/ARM64/HalApplicationProcessor.cc
new file mode 100644
index 00000000..6b09a415
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/HalApplicationProcessor.cc
@@ -0,0 +1,136 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, 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 Kernel
+{
+ 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)
+ ;
+ }
+
+ Void mp_setup_gic_el0(Void)
+ {
+ // enable distributor.
+ HAL::hal_mmio_write(GICD_BASE + GICD_CTLR, YES);
+
+ UInt32 gicc_ctlr = HAL::hal_mmio_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
+
+ HAL::hal_mmio_write(GICC_BASE + GICC_CTLR, gicc_ctlr);
+
+ // Set priority mask (accept all priorities)
+ HAL::hal_mmio_write(GICC_BASE + GICC_PMR, 0xFF);
+
+ UInt32 icfgr = HAL::hal_mmio_read<UInt32>(GICD_BASE + GICD_ICFGR + (32 / 16) * 4);
+
+ icfgr |= (0x2 << ((32 % 16) * 2)); // Edge-triggered
+ HAL::hal_mmio_write(GICD_BASE + GICD_ICFGR + (32 / 16) * 4, icfgr);
+
+ // Target interrupt 32 to CPU 1
+ HAL::hal_mmio_write(GICD_BASE + GICD_ITARGETSR + (32 / 4) * 4, 0x2 << ((32 % 4) * 8));
+
+ // Set interrupt 32 priority to lowest (0xFF)
+ HAL::hal_mmio_write(GICD_BASE + GICD_IPRIORITYR + (32 / 4) * 4, 0xFF << ((32 % 4) * 8));
+
+ // Enable interrupt 32 for AP.
+ HAL::hal_mmio_write(GICD_BASE + GICD_ISENABLER + (32 / 32) * 4, 0x01 << (32 % 32));
+
+ kcout << "AP's GIC configured in ISR 32." << endl;
+ }
+
+ BOOL mp_handle_gic_interrupt_el0(Void)
+ {
+ // Read the interrupt ID
+ UInt32 interrupt_id = HAL::hal_mmio_read<UInt32>(GICC_BASE + GICC_IAR);
+
+ // Check if it's a valid interrupt (not spurious)
+ if ((interrupt_id & 0x3FF) < 1020)
+ {
+ kcout << "Handling interrupt for AP: " << (interrupt_id & 0x3FF) << endl;
+
+ // TODO: Handle code here.
+
+ // End the interrupt
+
+ HAL::hal_mmio_write(GICC_BASE + GICC_EOIR, interrupt_id);
+
+ 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 YES;
+ }
+
+ return NO;
+ }
+} // namespace Kernel \ 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..e2b2db88
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/HalDebugOutput.cc
@@ -0,0 +1,83 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/DebugOutput.h>
+#include <NewKit/Utils.h>
+#include <NewKit/New.h>
+
+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__
+ }
+
+ TerminalDevice::~TerminalDevice() = default;
+
+ 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/Kernel/HALKit/ARM64/HalKernelMain.cc b/dev/Kernel/HALKit/ARM64/HalKernelMain.cc
new file mode 100644
index 00000000..7756facd
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/HalKernelMain.cc
@@ -0,0 +1,52 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.h>
+#include <Mod/CoreGfx/FBMgr.h>
+#include <FirmwareKit/Handover.h>
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/Heap.h>
+#include <KernelKit/PEFCodeMgr.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <NewKit/Json.h>
+#include <KernelKit/CodeMgr.h>
+#include <Mod/ACPI/ACPIFactoryInterface.h>
+#include <NetworkKit/IPC.h>
+#include <HALKit/ARM64/Processor.h>
+#include <CFKit/Property.h>
+
+EXTERN_C void hal_init_platform(
+ Kernel::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<Kernel::VoidPtr>(
+ reinterpret_cast<Kernel::UIntPtr>(kHandoverHeader->f_BitMapStart));
+
+ /// @note do initialize the interrupts after it.
+
+ Kernel::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..8be2db2f
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/HalKernelPanic.cc
@@ -0,0 +1,80 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, 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 <Mod/CoreGfx/FBMgr.h>
+#include <Mod/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 Kernel
+{
+ /// @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 Kernel::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)
+ {
+ kcout << "FAILED: FILE: " << file << endl;
+ kcout << "FAILED: LINE: " << line << endl;
+
+ ke_panic(RUNTIME_CHECK_FAILED, file); // Runtime Check failed
+ }
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/HALKit/ARM64/HalPageInternal.S b/dev/Kernel/HALKit/ARM64/HalPageInternal.S
new file mode 100644
index 00000000..8fcf40ff
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/HalPageInternal.S
@@ -0,0 +1,5 @@
+.text
+
+hal_flush_tlb:
+ tlbi
+ ret
diff --git a/dev/Kernel/HALKit/ARM64/HalPagingMgrARM64.cc b/dev/Kernel/HALKit/ARM64/HalPagingMgrARM64.cc
new file mode 100644
index 00000000..0991fd37
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/HalPagingMgrARM64.cc
@@ -0,0 +1,86 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: HalPagingMgr.cc
+ Purpose: Platform Paging Manager..
+
+------------------------------------------- */
+
+#include <HALKit/ARM64/Paging.h>
+#include <HALKit/ARM64/Processor.h>
+
+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/Kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc b/dev/Kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc
new file mode 100644
index 00000000..ff1dd448
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/HalSchedulerCoreARM64.cc
@@ -0,0 +1,24 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/UserProcessScheduler.h>
+
+namespace Kernel
+{
+ /// @brief Wakes up thread.
+ /// Wakes up thread from the hang state.
+ Void mp_wakeup_thread(HAL::StackFrame* stack)
+ {
+ ZKA_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)
+ {
+ ZKA_UNUSED(stack);
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc b/dev/Kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc
new file mode 100644
index 00000000..b254e670
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc
@@ -0,0 +1,35 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <HALKit/ARM64/Processor.h>
+#include <KernelKit/UserProcessScheduler.h>
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /// @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 Kernel
diff --git a/dev/Kernel/HALKit/ARM64/HalTimerARM64.cc b/dev/Kernel/HALKit/ARM64/HalTimerARM64.cc
new file mode 100644
index 00000000..f860c5a2
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/HalTimerARM64.cc
@@ -0,0 +1,14 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, 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..d9c39f4a
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/MBCI/MBCI.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2025, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <Mod/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..f20c9fcf
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/Paging.h
@@ -0,0 +1,120 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, 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 Kernel::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 Kernel::HAL
+
+namespace Kernel
+{
+ typedef HAL::PTE_4KB PTE;
+ typedef HAL::PDE_4KB PDE;
+} // namespace Kernel
+
+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..2e640a7f
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/Processor.h
@@ -0,0 +1,86 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, 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 Kernel::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 virt_addr, 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_mmio_write(UIntPtr address, DataKind value)
+ {
+ *reinterpret_cast<volatile DataKind*>(address) = value;
+ }
+
+ template <typename DataKind>
+ inline DataKind hal_mmio_read(UIntPtr address)
+ {
+ return *reinterpret_cast<volatile DataKind*>(address);
+ }
+} // namespace Kernel::HAL
+
+inline Kernel::VoidPtr kKernelBitMpStart = nullptr;
+inline Kernel::UIntPtr kKernelBitMpSize = 0UL;
+
+inline Kernel::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/MFlash+IO.cc b/dev/Kernel/HALKit/ARM64/Storage/MFlash+IO.cc
new file mode 100644
index 00000000..bcde2435
--- /dev/null
+++ b/dev/Kernel/HALKit/ARM64/Storage/MFlash+IO.cc
@@ -0,0 +1,84 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024-2025, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifdef ZKA_USE_MBCI_FLASH
+
+#include <NewKit/Defines.h>
+#include <ArchKit/ArchKit.h>
+#include <Mod/MFlash/MFlash.h>
+#include <Mod/MBCI/MBCI.h>
+
+/// @file MFlash.cc
+/// @brief MBCI Flash support.
+
+#define kMaxFlashSlots (8U)
+
+namespace Kernel
+{
+ /// /Mount/Flash/n
+ constexpr auto kFlashBridgeMagic = "FLSH";
+ constexpr auto kFlashBridgeRevision = 1;
+
+ STATIC BOOL kFlashEnabled = NO;
+ STATIC SizeT kFlashSize[kMaxFlashSlots] = {};
+ STATIC SizeT kFlashSectorSz[kMaxFlashSlots] = {};
+ STATIC IMBCIHost* kFlashMetaPackets[kMaxFlashSlots] = {};
+ STATIC IMBCIHost* kFlashDataPackets[kMaxFlashSlots] = {};
+
+ /// @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 > kMaxFlashSlots)
+ return 0;
+
+ return kFlashSectorSz[slot];
+ }
+
+ /// @brief get slot full size (in bytes).
+ /// @return drive slot size
+ SizeT drv_get_size(Int32 slot)
+ {
+ if (slot > kMaxFlashSlots)
+ return 0;
+
+ return kFlashSize[slot];
+ }
+
+ /// @brief Enable flash memory at slot.
+ BOOL drv_enable_at(Int32 slot)
+ {
+ if (slot > kMaxFlashSlots)
+ return NO;
+
+ kFlashMetaPackets[slot]->InterruptEnable = YES;
+
+ kcout << "Enabled hardware slot at: " << number(slot) << endl;
+
+ return YES;
+ }
+
+ /// @brief Disable flash memory at slot.
+ BOOL drv_disable_at(Int32 slot)
+ {
+ if (slot > kMaxFlashSlots)
+ return NO;
+
+ kFlashMetaPackets[slot]->InterruptEnable = NO;
+
+ kcout << "Disabled hardware slot at: " << number(slot) << endl;
+
+ return YES;
+ }
+} // namespace Kernel
+
+#endif // if ZKA_USE_MBCI_FLASH
diff --git a/dev/Kernel/HALKit/AXP/CR.s b/dev/Kernel/HALKit/AXP/CR.s
new file mode 100644
index 00000000..4d68257d
--- /dev/null
+++ b/dev/Kernel/HALKit/AXP/CR.s
@@ -0,0 +1,11 @@
+.globl read_lr1
+.globl read_lr0
+
+.section .text
+ read_lr0:
+ movq %r30, %cr3
+ ret
+
+ hal_read_cr0:
+ movq %r30, %cr0
+ ret \ No newline at end of file
diff --git a/dev/Kernel/HALKit/AXP/CoreInterruptHandlerDEC.cpp b/dev/Kernel/HALKit/AXP/CoreInterruptHandlerDEC.cpp
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/HALKit/AXP/CoreInterruptHandlerDEC.cpp
diff --git a/dev/Kernel/HALKit/AXP/CoreSyscallHandlerDEC.cpp b/dev/Kernel/HALKit/AXP/CoreSyscallHandlerDEC.cpp
new file mode 100644
index 00000000..76f90c82
--- /dev/null
+++ b/dev/Kernel/HALKit/AXP/CoreSyscallHandlerDEC.cpp
@@ -0,0 +1,24 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.h>
+#include <HALKit/AXP/Processor.h>
+
+/// @brief Internal call for syscall, to work with C++.
+/// @param stack
+/// @return nothing.
+EXTERN_C void rt_syscall_handle(Kernel::HAL::StackFrame* stack)
+{
+ if (stack->Rcx <= (kSyscalls.Count() - 1))
+ {
+ kcout << "syscall: enter.\r";
+
+ if (kSyscalls[stack->Rcx].Leak().Leak().fHooked)
+ (kSyscalls[stack->Rcx].Leak().Leak().fProc)(stack);
+
+ kcout << "syscall: exit.\r";
+ }
+}
diff --git a/dev/Kernel/HALKit/AXP/HAL.s b/dev/Kernel/HALKit/AXP/HAL.s
new file mode 100644
index 00000000..0178527f
--- /dev/null
+++ b/dev/Kernel/HALKit/AXP/HAL.s
@@ -0,0 +1,13 @@
+.globl rt_wait_400ns
+
+.section .text
+rt_wait_400ns:
+ jmp .L
+.L:
+ jmp .L2
+ wtint ;; wait for interrupt
+.L2:
+
+ ret
+
+
diff --git a/dev/Kernel/HALKit/AXP/Processor.h b/dev/Kernel/HALKit/AXP/Processor.h
new file mode 100644
index 00000000..f183c100
--- /dev/null
+++ b/dev/Kernel/HALKit/AXP/Processor.h
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
diff --git a/dev/Kernel/HALKit/AXP/README b/dev/Kernel/HALKit/AXP/README
new file mode 100644
index 00000000..91e7b134
--- /dev/null
+++ b/dev/Kernel/HALKit/AXP/README
@@ -0,0 +1 @@
+This is for DEC Alpha.
diff --git a/dev/Kernel/HALKit/AXP/README.TXT b/dev/Kernel/HALKit/AXP/README.TXT
new file mode 100644
index 00000000..11e138f9
--- /dev/null
+++ b/dev/Kernel/HALKit/AXP/README.TXT
@@ -0,0 +1 @@
+An toy HAL to test the Kernel portability.
diff --git a/dev/Kernel/HALKit/AXP/SYSCALL.s b/dev/Kernel/HALKit/AXP/SYSCALL.s
new file mode 100644
index 00000000..19cab808
--- /dev/null
+++ b/dev/Kernel/HALKit/AXP/SYSCALL.s
@@ -0,0 +1,10 @@
+.section .text
+system_handle_user_call:
+ .cfi_startproc
+
+ push %r0
+ jmp %r1
+ mov %r30, %r2
+
+ .cfi_endproc
+ retsys \ No newline at end of file
diff --git a/dev/Kernel/HALKit/AXP/VM.s b/dev/Kernel/HALKit/AXP/VM.s
new file mode 100644
index 00000000..7024086b
--- /dev/null
+++ b/dev/Kernel/HALKit/AXP/VM.s
@@ -0,0 +1,5 @@
+.global hal_flush_tlb
+
+.section .text
+hal_flush_tlb:
+ swppal \ No newline at end of file
diff --git a/dev/Kernel/HALKit/POWER/.gitkeep b/dev/Kernel/HALKit/POWER/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/HALKit/POWER/.gitkeep
diff --git a/dev/Kernel/HALKit/POWER/AP.h b/dev/Kernel/HALKit/POWER/AP.h
new file mode 100644
index 00000000..ba79b888
--- /dev/null
+++ b/dev/Kernel/HALKit/POWER/AP.h
@@ -0,0 +1,39 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: AP.h
+ Purpose: POWER hardware threads.
+
+ Revision History:
+
+ 14/04/24: Added file (amlel)
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+namespace Kernel
+{
+ struct HAL_HARDWARE_THREAD;
+
+ /// @brief hardware thread indentification type.
+ typedef Kernel::Int32 hal_ap_kind;
+
+ /// @brief Hardware thread information structure.
+ typedef struct HAL_HARDWARE_THREAD
+ {
+ Kernel::UIntPtr fStartAddress;
+ Kernel::UInt8 fPrivleged : 1;
+ Kernel::UInt32 fPageMemoryFlags;
+ hal_ap_kind fIdentNumber;
+ } HAL_HARDWARE_THREAD;
+
+ /// @brief Set PC to specific hart.
+ /// @param hart the hart
+ /// @param epc the pc.
+ /// @return
+ EXTERN_C Kernel::Void hal_set_pc_to_hart(HAL_HARDWARE_THREAD* hart, Kernel::VoidPtr epc);
+} // namespace Kernel
diff --git a/dev/Kernel/HALKit/POWER/APM/.gitkeep b/dev/Kernel/HALKit/POWER/APM/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/HALKit/POWER/APM/.gitkeep
diff --git a/dev/Kernel/HALKit/POWER/HalAP.cc b/dev/Kernel/HALKit/POWER/HalAP.cc
new file mode 100644
index 00000000..2475bfba
--- /dev/null
+++ b/dev/Kernel/HALKit/POWER/HalAP.cc
@@ -0,0 +1,40 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <HALKit/POWER/Processor.h>
+#include <KernelKit/DebugOutput.h>
+#include <HALKit/POWER/AP.h>
+
+using namespace Kernel;
+
+namespace Kernel::Detail
+{
+ STATIC void mp_hang_fn(void)
+ {
+ while (YES)
+ ;
+ }
+} // namespace Kernel::Detail
+
+/// @brief wakes up thread.
+/// wakes up thread from hang.
+void mp_wakeup_thread(HAL::StackFramePtr stack)
+{
+ if (!stack)
+ return;
+
+ hal_set_pc_to_hart(reinterpret_cast<HAL_HARDWARE_THREAD*>(stack->R15), reinterpret_cast<VoidPtr>(stack->BP));
+}
+
+/// @brief makes thread sleep.
+/// hooks and hangs thread to prevent code from executing.
+void mp_hang_thread(HAL::StackFramePtr stack)
+{
+ if (!stack)
+ return;
+
+ hal_set_pc_to_hart(reinterpret_cast<HAL_HARDWARE_THREAD*>(stack->R15), reinterpret_cast<VoidPtr>(Kernel::Detail::mp_hang_fn));
+}
diff --git a/dev/Kernel/HALKit/POWER/HalDebugOutput.cc b/dev/Kernel/HALKit/POWER/HalDebugOutput.cc
new file mode 100644
index 00000000..91805d87
--- /dev/null
+++ b/dev/Kernel/HALKit/POWER/HalDebugOutput.cc
@@ -0,0 +1,27 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <HALKit/POWER/Processor.h>
+#include <KernelKit/DebugOutput.h>
+
+using namespace Kernel;
+
+/// @brief Writes to COM1.
+/// @param bytes
+void ke_io_write(const Char* bytes)
+{
+ if (!bytes)
+ return;
+
+ SizeT index = 0;
+ SizeT len = rt_string_len(bytes, 255);
+
+ while (index < len)
+ {
+ // TODO
+ ++index;
+ }
+}
diff --git a/dev/Kernel/HALKit/POWER/HalStartSequence.s b/dev/Kernel/HALKit/POWER/HalStartSequence.s
new file mode 100644
index 00000000..a8124dce
--- /dev/null
+++ b/dev/Kernel/HALKit/POWER/HalStartSequence.s
@@ -0,0 +1,14 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+.globl __ImageStart
+.extern hal_init_platform
+.align 4
+.text
+
+__ImageStart:
+ bl hal_init_platform
+ blr
diff --git a/dev/Kernel/HALKit/POWER/HalThread.cc b/dev/Kernel/HALKit/POWER/HalThread.cc
new file mode 100644
index 00000000..2e650b30
--- /dev/null
+++ b/dev/Kernel/HALKit/POWER/HalThread.cc
@@ -0,0 +1,8 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <HALKit/POWER/Processor.h>
+#include <KernelKit/DebugOutput.h>
diff --git a/dev/Kernel/HALKit/POWER/HalVirtualMemory.cc b/dev/Kernel/HALKit/POWER/HalVirtualMemory.cc
new file mode 100644
index 00000000..3ed0ef3d
--- /dev/null
+++ b/dev/Kernel/HALKit/POWER/HalVirtualMemory.cc
@@ -0,0 +1,49 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <HALKit/POWER/Processor.h>
+#include <KernelKit/DebugOutput.h>
+#include <HALKit/POWER/MMU.h>
+
+/// @note Refer to SoC documentation.
+
+using namespace Kernel;
+
+EXTERN_C Void hal_write_tlb(UInt32 mas0, UInt32 mas1, UInt32 mas2, UInt32 mas3, UInt32 mas7)
+{
+ hal_mtspr(MAS0, mas0);
+ hal_mtspr(MAS1, mas1);
+ hal_mtspr(MAS2, mas2);
+ hal_mtspr(MAS3, mas3);
+ hal_mtspr(MAS7, mas7);
+
+ hal_flush_tlb();
+}
+
+EXTERN_C Bool hal_set_tlb(UInt8 tlb, UInt32 epn, UInt64 rpn, UInt8 perms, UInt8 wimge, UInt8 ts, UInt8 esel, UInt8 tsize, UInt8 iprot)
+{
+ if ((hal_mfspr(SPRN_MMUCFG) & MMUCFG_MAVN) == MMUCFG_MAVN_V1 && (tsize & 1))
+ {
+ // this MMU does not allow odd tsize values
+ return false;
+ }
+
+ UInt32 mas0 = FSL_BOOKE_MAS0(tlb, esel, 0);
+ UInt32 mas1 = FSL_BOOKE_MAS1(1, iprot, 0, ts, tsize);
+ UInt32 mas2 = FSL_BOOKE_MAS2(epn, wimge);
+ UInt32 mas3 = FSL_BOOKE_MAS3(rpn, 0, perms);
+ UInt32 mas7 = FSL_BOOKE_MAS7(rpn);
+
+ hal_write_tlb(mas0, mas1, mas2, mas3, mas7);
+
+ return true;
+}
+
+/// @brief Flush TLB
+EXTERN_C void hal_flush_tlb()
+{
+ asm volatile("isync;tlbwe;msync;isync");
+}
diff --git a/dev/Kernel/HALKit/POWER/MBCI/.gitkeep b/dev/Kernel/HALKit/POWER/MBCI/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/HALKit/POWER/MBCI/.gitkeep
diff --git a/dev/Kernel/HALKit/POWER/MBCI/HalMBCIHost.cc b/dev/Kernel/HALKit/POWER/MBCI/HalMBCIHost.cc
new file mode 100644
index 00000000..2e650b30
--- /dev/null
+++ b/dev/Kernel/HALKit/POWER/MBCI/HalMBCIHost.cc
@@ -0,0 +1,8 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <HALKit/POWER/Processor.h>
+#include <KernelKit/DebugOutput.h>
diff --git a/dev/Kernel/HALKit/POWER/Processor.h b/dev/Kernel/HALKit/POWER/Processor.h
new file mode 100644
index 00000000..10908b35
--- /dev/null
+++ b/dev/Kernel/HALKit/POWER/Processor.h
@@ -0,0 +1,62 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ Purpose: POWER processor header.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+#include <NewKit/Utils.h>
+
+#define NoOp() asm volatile("mr 0, 0")
+#define kHalPPCAlignment __attribute__((aligned(4)))
+
+namespace Kernel::HAL
+{
+ typedef UIntPtr Reg;
+
+ /// @brief Stack frame (as retrieved from assembly.)
+ 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()
+ {
+ while (true)
+ {
+ NoOp(); // no oop.
+ }
+ }
+
+ inline void rt_cli()
+ {
+ NoOp(); // no oop
+ }
+} // namespace Kernel::HAL
+
+EXTERN_C Kernel::Void int_handle_math(Kernel::UIntPtr sp);
+EXTERN_C Kernel::Void int_handle_pf(Kernel::UIntPtr sp);
+
+/// @brief Set TLB.
+Kernel::Bool hal_set_tlb(Kernel::UInt8 tlb, Kernel::UInt32 epn, Kernel::UInt64 rpn, Kernel::UInt8 perms, Kernel::UInt8 wimge, Kernel::UInt8 ts, Kernel::UInt8 esel, Kernel::UInt8 tsize, Kernel::UInt8 iprot);
+
+/// @brief Write TLB.
+Kernel::Void hal_write_tlb(Kernel::UInt32 mas0, Kernel::UInt32 mas1, Kernel::UInt32 mas2, Kernel::UInt32 mas3, Kernel::UInt32 mas7);
+
+/// @brief Flush TLB.
+EXTERN_C Kernel::Void hal_flush_tlb();
diff --git a/dev/Kernel/HALKit/POWER/ReadMe.md b/dev/Kernel/HALKit/POWER/ReadMe.md
new file mode 100644
index 00000000..a9751581
--- /dev/null
+++ b/dev/Kernel/HALKit/POWER/ReadMe.md
@@ -0,0 +1,4 @@
+POWER Hardware Abstraction Layer
+
+- Supported CPU: POWER
+- Supported Firmware: CoreBoot \ No newline at end of file
diff --git a/dev/Kernel/HALKit/RISCV/.keep b/dev/Kernel/HALKit/RISCV/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/HALKit/RISCV/.keep
diff --git a/dev/Kernel/HALKit/RISCV/AP.h b/dev/Kernel/HALKit/RISCV/AP.h
new file mode 100644
index 00000000..05de4727
--- /dev/null
+++ b/dev/Kernel/HALKit/RISCV/AP.h
@@ -0,0 +1,36 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: AP.h
+ Purpose: RISC-V hardware threads.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+namespace Kernel
+{
+ typedef Int64 hal_ap_kind;
+
+ typedef struct HAL_HARDWARE_THREAD
+ {
+ Kernel::UIntPtr fStartAddress;
+ Kernel::UInt8 fPrivleged : 1;
+ Kernel::UInt32 fPageMemoryFlags;
+ hal_ap_kind fIdentNumber;
+ } HAL_HARDWARE_THREAD;
+
+ /// @brief Set PC to specific hart.
+ /// @param hart the hart
+ /// @param epc the pc.
+ /// @return
+ EXTERN_C Kernel::Void hal_set_pc_to_hart(HAL_HARDWARE_THREAD* hart, Kernel::VoidPtr epc);
+
+} // namespace Kernel
diff --git a/dev/Kernel/HALKit/RISCV/APM/.gitkeep b/dev/Kernel/HALKit/RISCV/APM/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/HALKit/RISCV/APM/.gitkeep
diff --git a/dev/Kernel/HALKit/RISCV/HalAP.cc b/dev/Kernel/HALKit/RISCV/HalAP.cc
new file mode 100644
index 00000000..619a03d4
--- /dev/null
+++ b/dev/Kernel/HALKit/RISCV/HalAP.cc
@@ -0,0 +1,40 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <HALKit/RISCV/Processor.h>
+#include <KernelKit/DebugOutput.h>
+#include <HALKit/RISCV/AP.h>
+
+using namespace Kernel;
+
+namespace Kernel::Detail
+{
+ STATIC void mp_hang_fn(void)
+ {
+ while (YES)
+ ;
+ }
+} // namespace Kernel::Detail
+
+/// @brief wakes up thread.
+/// wakes up thread from hang.
+void mp_wakeup_thread(HAL::StackFramePtr stack)
+{
+ if (!stack)
+ return;
+
+ hal_set_pc_to_hart(reinterpret_cast<HAL_HARDWARE_THREAD*>(stack->R15), reinterpret_cast<VoidPtr>(stack->BP));
+}
+
+/// @brief makes thread sleep.
+/// hooks and hangs thread to prevent code from executing.
+void mp_hang_thread(HAL::StackFramePtr stack)
+{
+ if (!stack)
+ return;
+
+ hal_set_pc_to_hart(reinterpret_cast<HAL_HARDWARE_THREAD*>(stack->R15), reinterpret_cast<VoidPtr>(Kernel::Detail::mp_hang_fn));
+}
diff --git a/dev/Kernel/HALKit/RISCV/ReadMe.md b/dev/Kernel/HALKit/RISCV/ReadMe.md
new file mode 100644
index 00000000..b099aa31
--- /dev/null
+++ b/dev/Kernel/HALKit/RISCV/ReadMe.md
@@ -0,0 +1,4 @@
+RISCV64 Hardware Abstraction Layer
+
+- Supported CPU: RISCV64
+- Supported Firmware: CoreBoot \ No newline at end of file
diff --git a/dev/Kernel/HALKit/RISCV/Storage/.gitkeep b/dev/Kernel/HALKit/RISCV/Storage/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/HALKit/RISCV/Storage/.gitkeep
diff --git a/dev/Kernel/HALKit/X86S/.gitkeep b/dev/Kernel/HALKit/X86S/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/HALKit/X86S/.gitkeep
diff --git a/dev/Kernel/HALKit/X86S/ACPI/.gitkeep b/dev/Kernel/HALKit/X86S/ACPI/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/HALKit/X86S/ACPI/.gitkeep
diff --git a/dev/Kernel/HALKit/X86S/Storage/.gitkeep b/dev/Kernel/HALKit/X86S/Storage/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/HALKit/X86S/Storage/.gitkeep
diff --git a/dev/Kernel/KernelKit/CodeMgr.h b/dev/Kernel/KernelKit/CodeMgr.h
new file mode 100644
index 00000000..eb5b316d
--- /dev/null
+++ b/dev/Kernel/KernelKit/CodeMgr.h
@@ -0,0 +1,37 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: CodeMgr.h
+ Purpose: Code Mgr.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+ 3/8/24: Add UPP struct.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <KernelKit/PECodeMgr.h>
+#include <KernelKit/PEFCodeMgr.h>
+#include <KernelKit/IPEFDylibObject.h>
+
+namespace Kernel
+{
+ /// @brief Main process entrypoint.
+ typedef void (*rtl_main_kind)(const SizeT argc, Char** argv, Char** envp, const SizeT envp_len);
+
+ /// @brief C++ Constructor entrypoint.
+ typedef void (*rtl_ctor_kind)(void);
+
+ /// @brief C++ Destructor entrypoint.
+ typedef void (*rtl_dtor_kind)(void);
+
+ /// @brief Executes a new process from a function. Kernel code only.
+ /// @note This sets up a new stack, anything on the main function that calls the Kernel will not be accessible.
+ /// @param main the start of the process.
+ /// @return The team's process id.
+ ProcessID rtl_create_process(rtl_main_kind main, const Char* process_name) noexcept;
+} // namespace Kernel
diff --git a/dev/Kernel/KernelKit/DebugOutput.h b/dev/Kernel/KernelKit/DebugOutput.h
new file mode 100644
index 00000000..0f02ecb1
--- /dev/null
+++ b/dev/Kernel/KernelKit/DebugOutput.h
@@ -0,0 +1,211 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <KernelKit/DeviceMgr.h>
+#include <CompilerKit/CompilerKit.h>
+#include <NewKit/OwnPtr.h>
+#include <NewKit/Stream.h>
+
+#define kDebugMaxPorts 56
+
+#define kDebugUnboundPort 0x0FEED
+
+#define kDebugMag0 'Z'
+#define kDebugMag1 'D'
+#define kDebugMag2 'B'
+#define kDebugMag3 'G'
+
+#define kDebugSourceFile 0
+#define kDebugLine 33
+#define kDebugTeam 43
+#define kDebugEOP 49
+
+namespace Kernel
+{
+ class TerminalDevice;
+ class DTraceDevice;
+
+ inline TerminalDevice end_line();
+ inline TerminalDevice number(const Long& x);
+ inline TerminalDevice hex_number(const Long& x);
+
+ // @brief Emulates a VT100 terminal.
+ class TerminalDevice final ZKA_DEVICE<const Char*>
+ {
+ public:
+ TerminalDevice(void (*print)(const Char*), void (*gets)(const Char*))
+ : IDeviceObject<const Char*>(print, gets)
+ {
+ }
+
+ ~TerminalDevice() override;
+
+ /// @brief returns device name (terminal name)
+ /// @return string type (const Char*)
+ const Char* Name() const override
+ {
+ return ("TerminalDevice");
+ }
+
+ ZKA_COPY_DEFAULT(TerminalDevice);
+
+ STATIC TerminalDevice The() noexcept;
+ };
+
+ inline TerminalDevice end_line()
+ {
+ TerminalDevice self = TerminalDevice::The();
+
+ self.operator<<("\r");
+ return self;
+ }
+
+ inline TerminalDevice carriage_return()
+ {
+ TerminalDevice self = TerminalDevice::The();
+
+ self.operator<<("\r");
+ return self;
+ }
+
+ inline TerminalDevice tabulate()
+ {
+ TerminalDevice self = TerminalDevice::The();
+
+ self.operator<<("\t");
+ return self;
+ }
+
+ /// @brief emulate a terminal bell, like the VT100 does.
+ inline TerminalDevice bell()
+ {
+ TerminalDevice self = TerminalDevice::The();
+
+ self.operator<<("\a");
+ return self;
+ }
+
+ namespace Detail
+ {
+ inline TerminalDevice _write_number(const Long& x, TerminalDevice& term)
+ {
+ UInt64 y = (x > 0 ? x : -x) / 10;
+ UInt64 h = (x > 0 ? x : -x) % 10;
+
+ if (y)
+ _write_number(y, term);
+
+ /* fail if the number is not base-10 */
+ if (h > 10)
+ {
+ _write_number('?', term);
+ return term;
+ }
+
+ if (y < 0)
+ y = -y;
+
+ const Char kNumbers[11] = "0123456789";
+
+ Char buf[2];
+ buf[0] = kNumbers[h];
+ buf[1] = 0;
+
+ term.operator<<(buf);
+ return term;
+ }
+
+ inline TerminalDevice _write_number_hex(const Long& x, TerminalDevice& term)
+ {
+ UInt64 y = (x > 0 ? x : -x) / 16;
+ UInt64 h = (x > 0 ? x : -x) % 16;
+
+ if (y)
+ _write_number_hex(y, term);
+
+ /* fail if the hex number is not base-16 */
+ if (h > 16)
+ {
+ _write_number_hex('?', term);
+ return term;
+ }
+
+ if (y < 0)
+ y = -y;
+
+ const Char kNumbers[17] = "0123456789ABCDEF";
+
+ Char buf[2];
+ buf[0] = kNumbers[h];
+ buf[1] = 0;
+
+ term.operator<<(buf);
+ return term;
+ }
+ } // namespace Detail
+
+ inline TerminalDevice hex_number(const Long& x)
+ {
+ TerminalDevice self = TerminalDevice::The();
+
+ Detail::_write_number_hex(x, self);
+ self.operator<<("h");
+
+ return self;
+ }
+
+ inline TerminalDevice number(const Char* x)
+ {
+ TerminalDevice self = TerminalDevice::The();
+
+ self << "?";
+
+ return self;
+ }
+
+ inline TerminalDevice number(const Long& x)
+ {
+ TerminalDevice self = TerminalDevice::The();
+
+ Detail::_write_number(x, self);
+
+ return self;
+ }
+
+ inline TerminalDevice get_console_in(Char* buf)
+ {
+ TerminalDevice self = TerminalDevice::The();
+
+ self >> buf;
+
+ return self;
+ }
+
+ typedef Char rt_debug_type[255];
+
+ class DebuggerPortHeader final
+ {
+ public:
+ Int16 fPort[kDebugMaxPorts];
+ Int16 fBoundCnt;
+ };
+
+ inline TerminalDevice& operator<<(TerminalDevice& src, auto number)
+ {
+ number(number, src);
+ return src;
+ }
+} // namespace Kernel
+
+#ifdef kcout
+#undef kcout
+#endif // ifdef kcout
+
+#define kcout Kernel::TerminalDevice::The() << "\e[0;31m [NeKernel] " << __FILE__ << " \e[0m: "
+
+#define endl Kernel::TerminalDevice::The() << Kernel::end_line()
diff --git a/dev/Kernel/KernelKit/Defines.h b/dev/Kernel/KernelKit/Defines.h
new file mode 100644
index 00000000..8fa90619
--- /dev/null
+++ b/dev/Kernel/KernelKit/Defines.h
@@ -0,0 +1,15 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+#define KERNELKIT_VERSION "1.0.2"
+#define KERNELKIT_VERSION_BCD 0x01020
+
+class UserProcessScheduler;
+class UserProcess;
diff --git a/dev/Kernel/KernelKit/DeviceMgr.h b/dev/Kernel/KernelKit/DeviceMgr.h
new file mode 100644
index 00000000..9e867561
--- /dev/null
+++ b/dev/Kernel/KernelKit/DeviceMgr.h
@@ -0,0 +1,140 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+/* -------------------------------------------
+
+ Revision History:
+
+ 31/01/24: Add kDeviceCnt (amlel)
+ 15/11/24: Add ZKA_DEVICE macro, to inherit from device object.
+
+ ------------------------------------------- */
+
+#pragma once
+
+/* @note Device Mgr. */
+/* @file KernelKit/DeviceMgr.h */
+/* @brief Device abstraction and I/O buffer. */
+
+#include <NewKit/ErrorOr.h>
+#include <NewKit/Ref.h>
+
+#define kDeviceMgrRootDirPath "/Devices/"
+
+#define ZKA_DEVICE : public ::Kernel::IDeviceObject
+
+// Last Rev: Wed, Apr 3, 2024 9:09:41 AM
+
+namespace Kernel
+{
+ template <typename T>
+ class IDeviceObject;
+
+ /***********************************************************************************/
+ /// @brief Device contract interface, represents an HW device.
+ /***********************************************************************************/
+ template <typename T>
+ class IDeviceObject
+ {
+ public:
+ explicit IDeviceObject(void (*Out)(T), void (*In)(T))
+ : fOut(Out), fIn(In)
+ {
+ }
+
+ virtual ~IDeviceObject() = default;
+
+ public:
+ IDeviceObject& operator=(const IDeviceObject<T>&) = default;
+ IDeviceObject(const IDeviceObject<T>&) = default;
+
+ public:
+ virtual IDeviceObject<T>& operator<<(T Data)
+ {
+ fOut(Data);
+ return *this;
+ }
+
+ virtual IDeviceObject<T>& operator>>(T Data)
+ {
+ fIn(Data);
+ return *this;
+ }
+
+ virtual const char* Name() const
+ {
+ return "IDeviceObject";
+ }
+
+ operator bool()
+ {
+ return fOut && fIn;
+ }
+
+ Bool operator!()
+ {
+ return !fOut || !fIn;
+ }
+
+ protected:
+ Void (*fOut)(T Data) = {nullptr};
+ Void (*fIn)(T Data) = {nullptr};
+ };
+
+ ///
+ /// @brief Input Output abstract class.
+ /// Used mainly to communicate between OS to hardware.
+ ///
+ template <typename T>
+ class IOBuf final
+ {
+ public:
+ explicit IOBuf(T dma_addr)
+ : fData(dma_addr)
+ {
+ // At least pass something valid when instancating this struct.
+ MUST_PASS(fData);
+ }
+
+ IOBuf& operator=(const IOBuf<T>&) = default;
+ IOBuf(const IOBuf<T>&) = default;
+
+ ~IOBuf() = default;
+
+ public:
+ template <typename R>
+ R operator->() const
+ {
+ return fData;
+ }
+
+ template <typename R>
+ R& operator[](Size index) const
+ {
+ return fData[index];
+ }
+
+ private:
+ T fData;
+ };
+
+ ///! @brief Device enum types.
+ enum
+ {
+ kDeviceTypeIDE,
+ kDeviceTypeEthernet,
+ kDeviceTypeWiFi,
+ kDeviceTypeFW,
+ kDeviceTypeBT,
+ kDeviceTypeRS232,
+ kDeviceTypeSCSI,
+ kDeviceTypeAHCI,
+ kDeviceTypeMBCI,
+ kDeviceTypeUSB,
+ kDeviceTypeMediaCtrl, // MM controller
+ kDeviceTypeCount,
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/KernelKit/DriveMgr.h b/dev/Kernel/KernelKit/DriveMgr.h
new file mode 100644
index 00000000..e28e7cb7
--- /dev/null
+++ b/dev/Kernel/KernelKit/DriveMgr.h
@@ -0,0 +1,191 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifndef INC_DRIVE_MANAGER_H
+#define INC_DRIVE_MANAGER_H
+
+#include <KernelKit/UserProcessScheduler.h>
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/DeviceMgr.h>
+#include <KernelKit/LPC.h>
+#include <NewKit/Defines.h>
+#include <NewKit/KString.h>
+#include <NewKit/Ref.h>
+
+#define kDriveMaxCount (4U)
+#define kDriveSectorSz (512U)
+#define kDriveInvalidID (-1)
+#define kDriveNameLen (32)
+
+#define drv_sector_cnt(SIZE, SECTOR_SZ) (((SIZE) + (SECTOR_SZ)) / (SECTOR_SZ))
+
+namespace Kernel
+{
+ enum
+ {
+ kInvalidDisc = -1,
+
+ /// Storage types, combine with flags.
+ kBlockDevice = 0xAD,
+ kMassStorageDisc = 0xDA,
+ kFloppyDisc = 0xCD,
+ kOpticalDisc = 0xDC, // CD-ROM/DVD-ROM/Blu-Ray
+ kTapeDisc = 0xD7,
+
+ /// Storage flags, combine with types.
+ kReadOnlyDrive = 0x10, // Read only drive
+ kEPMDrive = 0x11, // Explicit Partition Map.
+ kEPTDrive = 0x12, // ESP w/ EPM partition.
+ kMBRDrive = 0x13, // PC classic partition scheme
+ kGPTDrive = 0x14, // PC new partition scheme
+ kUnformattedDrive = 0x15,
+ kStorageCount = 9,
+ };
+
+ /// @brief Media drive trait type.
+ struct DriveTrait final
+ {
+ Char fName[kDriveNameLen]; // /System, /Boot, //./Devices/USB...
+ Int32 fKind; // fMassStorage, fFloppy, fOpticalDisc.
+ Int32 fFlags; // fReadOnly, fEPMDrive...
+
+ /// @brief Packet drive (StorageKit compilant.)
+ struct DrivePacket final
+ {
+ VoidPtr fPacketContent{nullptr}; //! packet body.
+ Char fPacketMime[kDriveNameLen] = "*/*"; //! identify what we're sending.
+ SizeT fPacketSize{0UL}; //! packet size
+ UInt32 fPacketCRC32{0UL}; //! sanity crc, in case if good is set to false
+ Boolean fPacketGood{YES};
+ Lba fPacketLba{0UL};
+ Boolean fPacketReadOnly{NO};
+ } fPacket;
+
+ Lba fLbaStart{0}, fLbaEnd{0};
+ SizeT fSectorSz{512};
+
+ Void (*fInput)(DrivePacket packet);
+ Void (*fOutput)(DrivePacket packet);
+ Void (*fVerify)(DrivePacket packet);
+ Void (*fInit)(DrivePacket packet);
+ const Char* (*fDriveKind)(Void);
+ };
+
+ ///! drive as a device.
+ typedef DriveTrait* DriveTraitPtr;
+
+ /**
+ * @brief Mounted drives interface.
+ * @note This class has all of it's drive set to nullptr, allocate them using
+ * GetAddressOf(index).
+ */
+ class MountpointInterface final
+ {
+ public:
+ explicit MountpointInterface() = default;
+ ~MountpointInterface() = default;
+
+ ZKA_COPY_DEFAULT(MountpointInterface);
+
+ public:
+ DriveTrait& A()
+ {
+ return mA;
+ }
+
+ DriveTrait& B()
+ {
+ return mB;
+ }
+
+ DriveTrait& C()
+ {
+ return mC;
+ }
+
+ DriveTrait& D()
+ {
+ return mD;
+ }
+
+ enum
+ {
+ kDriveIndexA = 0,
+ kDriveIndexB,
+ kDriveIndexC,
+ kDriveIndexD,
+ kDriveIndexInvalid,
+ };
+
+ DriveTraitPtr GetAddressOf(const Int32& index)
+ {
+ err_local_get() = kErrorSuccess;
+
+ switch (index)
+ {
+ case kDriveIndexA:
+ return &mA;
+ case kDriveIndexB:
+ return &mB;
+ case kDriveIndexC:
+ return &mC;
+ case kDriveIndexD:
+ return &mD;
+ default: {
+ err_local_get() = kErrorNoSuchDisk;
+ kcout << "No such disc letter.\n";
+
+ break;
+ }
+ }
+
+ return nullptr;
+ }
+
+ private:
+ DriveTrait mA, mB, mC, mD;
+ };
+
+ /// @brief Unimplemented drive.
+ /// @param pckt the packet to read.
+ /// @return
+ Void io_drv_unimplemented(DriveTrait::DrivePacket* pckt) noexcept;
+
+ /// @brief Gets the drive kind (ATA, SCSI, AHCI...)
+ /// @param void none.
+ /// @return the drive kind (ATA, Flash, NVM)
+ const Char* io_drv_kind(Void);
+
+ /// @brief Makes a new drive.
+ /// @return the new drive as a trait.
+ DriveTrait io_construct_blank_drive(Void) noexcept;
+
+ /// @brief Fetches the main drive.
+ /// @return the new drive as a trait.
+ DriveTrait io_construct_main_drive(Void) noexcept;
+
+ namespace Detect
+ {
+ Void io_detect_drive(DriveTrait& trait);
+ }
+
+ /// @brief Read from newfs disk.
+ /// @param Mnt mounted interface.
+ /// @param DrvTrait drive info
+ /// @param DrvIndex drive index.
+ /// @return
+ Int32 fs_ifs_read(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex);
+
+ /// @brief Write to ifs disk.
+ /// @param Mnt mounted interface.
+ /// @param DrvTrait drive info
+ /// @param DrvIndex drive index.
+ /// @return
+ Int32 fs_ifs_write(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex);
+} // namespace Kernel
+
+#endif /* ifndef INC_DRIVE_MANAGER_H */
diff --git a/dev/Kernel/KernelKit/FileMgr.h b/dev/Kernel/KernelKit/FileMgr.h
new file mode 100644
index 00000000..c78c0b97
--- /dev/null
+++ b/dev/Kernel/KernelKit/FileMgr.h
@@ -0,0 +1,392 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024-2025, Amlal EL Mahrouss Labs, all rights reserved.
+
+ File: FileMgr.h
+ Purpose: Kernel file manager.
+
+------------------------------------------- */
+
+/* -------------------------------------------
+
+ Revision History:
+
+ 31/01/24: Update documentation (amlel)
+ 05/07/24: NeFS support, and fork support, updated constants and specs
+ as well.
+ 18/01/25: Patches to FileStream class.
+
+ ------------------------------------------- */
+
+#ifndef INC_FILEMGR_H
+#define INC_FILEMGR_H
+
+#ifdef __FSKIT_INCLUDES_NEFS__
+#include <FSKit/NeFS.h>
+#endif // __FSKIT_INCLUDES_NEFS__
+
+#ifdef __FSKIT_INCLUDES_HPFS__
+#include <FSKit/HPFS.h>
+#endif // __FSKIT_INCLUDES_HPFS__
+
+#include <CompilerKit/CompilerKit.h>
+#include <Hints/CompilerHint.h>
+#include <KernelKit/LPC.h>
+#include <KernelKit/DebugOutput.h>
+#include <NewKit/Stream.h>
+#include <NewKit/ErrorOr.h>
+#include <KernelKit/Heap.h>
+#include <NewKit/Ref.h>
+
+/// @brief Filesystem manager, abstraction over mounted filesystem.
+/// Works like the VFS or IFS.
+
+#define kRestrictR "r"
+#define kRestrictRB "rb"
+#define kRestrictW "w"
+#define kRestrictWB "rw"
+#define kRestrictRWB "rwb"
+
+#define kRestrictMax (5U)
+
+#define node_cast(PTR) reinterpret_cast<Kernel::NodePtr>(PTR)
+
+/**
+ @note Refer to first enum.
+*/
+#define kFileOpsCount (4U)
+#define kFileMimeGeneric "n-application-kind/all"
+
+/** @brief invalid position. (n-pos) */
+#define kNPos (SizeT)(-1);
+
+namespace Kernel
+{
+ enum
+ {
+ kFileWriteAll = 100,
+ kFileReadAll = 101,
+ kFileReadChunk = 102,
+ kFileWriteChunk = 103,
+ kFileIOCnt = (kFileWriteChunk - kFileWriteAll) + 1,
+ // file flags
+ kFileFlagRsrc = 104,
+ kFileFlagData = 105,
+ };
+
+ typedef VoidPtr NodePtr;
+
+ /**
+ @brief Filesystem Mgr Interface class
+ @brief Used to provide common I/O for a specific filesystem.
+*/
+ class IFilesystemMgr
+ {
+ public:
+ explicit IFilesystemMgr() = default;
+ virtual ~IFilesystemMgr() = default;
+
+ public:
+ ZKA_COPY_DEFAULT(IFilesystemMgr);
+
+ public:
+ /// @brief Mounts a new filesystem into an active state.
+ /// @param interface the filesystem interface
+ /// @return
+ static bool Mount(IFilesystemMgr* interface);
+
+ /// @brief Unmounts the active filesystem
+ /// @return
+ static IFilesystemMgr* Unmount();
+
+ /// @brief Getter, gets the active filesystem.
+ /// @return
+ static IFilesystemMgr* GetMounted();
+
+ public:
+ virtual NodePtr Create(_Input const Char* path) = 0;
+ virtual NodePtr CreateAlias(_Input const Char* path) = 0;
+ virtual NodePtr CreateDirectory(_Input const Char* path) = 0;
+ virtual NodePtr CreateSwapFile(const Char* path) = 0;
+
+ public:
+ virtual bool Remove(_Input const Char* path) = 0;
+
+ public:
+ virtual NodePtr Open(_Input const Char* path, _Input const Char* r) = 0;
+
+ public:
+ virtual Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, _Input SizeT size) = 0;
+
+ virtual _Output VoidPtr Read(_Input NodePtr node,
+ _Input Int32 flags,
+ _Input SizeT sz) = 0;
+
+ virtual Void Write(_Input const Char* name,
+ _Input NodePtr node,
+ _Input VoidPtr data,
+ _Input Int32 flags,
+ _Input SizeT size) = 0;
+
+ virtual _Output VoidPtr Read(_Input const Char* name,
+ _Input NodePtr node,
+ _Input Int32 flags,
+ _Input SizeT sz) = 0;
+
+ public:
+ virtual bool Seek(_Input NodePtr node, _Input SizeT off) = 0;
+
+ public:
+ virtual SizeT Tell(_Input NodePtr node) = 0;
+ virtual bool Rewind(_Input NodePtr node) = 0;
+ };
+
+#ifdef __FSKIT_INCLUDES_NEFS__
+ /**
+ * @brief Based of IFilesystemMgr, takes care of managing NeFS
+ * disks.
+ */
+ class NeFileSystemMgr final : public IFilesystemMgr
+ {
+ public:
+ explicit NeFileSystemMgr();
+ ~NeFileSystemMgr() override;
+
+ public:
+ ZKA_COPY_DEFAULT(NeFileSystemMgr);
+
+ public:
+ NodePtr Create(const Char* path) override;
+ NodePtr CreateAlias(const Char* path) override;
+ NodePtr CreateDirectory(const Char* path) override;
+ NodePtr CreateSwapFile(const Char* path) override;
+
+ public:
+ bool Remove(_Input const Char* path) override;
+ NodePtr Open(_Input const Char* path, _Input const Char* r) override;
+ Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, _Input SizeT sz) override;
+ VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) override;
+ bool Seek(_Input NodePtr node, _Input SizeT off) override;
+ SizeT Tell(_Input NodePtr node) override;
+ bool Rewind(_Input NodePtr node) override;
+
+ Void Write(_Input const Char* name,
+ _Input NodePtr node,
+ _Input VoidPtr data,
+ _Input Int32 flags,
+ _Input SizeT size) override;
+
+ _Output VoidPtr Read(_Input const Char* name,
+ _Input NodePtr node,
+ _Input Int32 flags,
+ _Input SizeT sz) override;
+
+ public:
+ /// @brief Get NeFS parser class.
+ /// @return The filesystem parser class.
+ NeFileSystemParser* GetParser() noexcept;
+
+ private:
+ NeFileSystemParser* mParser{nullptr};
+ };
+
+#endif // ifdef __FSKIT_INCLUDES_NEFS__
+
+ /**
+ * FileStream class.
+ * @tparam Encoding file encoding (char, wchar_t...)
+ * @tparam FSClass Filesystem contract who takes care of it.
+ */
+ template <typename Encoding = Char,
+ typename FSClass = IFilesystemMgr>
+ class FileStream final
+ {
+ public:
+ explicit FileStream(const Encoding* path, const Encoding* restrict_type);
+ ~FileStream();
+
+ public:
+ FileStream& operator=(const FileStream&);
+ FileStream(const FileStream&);
+
+ public:
+ ErrorOr<Int64> Write(const SizeT offset, const VoidPtr data, SizeT len) noexcept
+ {
+ if (this->fFileRestrict != kFileMgrRestrictReadWrite &&
+ this->fFileRestrict != kFileMgrRestrictReadWriteBinary &&
+ this->fFileRestrict != kFileMgrRestrictWrite &&
+ this->fFileRestrict != kFileMgrRestrictWriteBinary)
+ return ErrorOr<Int64>(kErrorInvalidData);
+
+ if (data == nullptr)
+ return ErrorOr<Int64>(kErrorInvalidData);
+
+ auto man = FSClass::GetMounted();
+
+ if (man)
+ {
+ man->Write(offset, fFile, data, len);
+ return ErrorOr<Int64>(0);
+ }
+
+ return ErrorOr<Int64>(kErrorInvalidData);
+ }
+
+ ErrorOr<Int64> Write(const Char* name, const VoidPtr data, SizeT len) noexcept
+ {
+ if (this->fFileRestrict != kFileMgrRestrictReadWrite &&
+ this->fFileRestrict != kFileMgrRestrictReadWriteBinary &&
+ this->fFileRestrict != kFileMgrRestrictWrite &&
+ this->fFileRestrict != kFileMgrRestrictWriteBinary)
+ return ErrorOr<Int64>(kErrorInvalidData);
+
+ if (data == nullptr)
+ return ErrorOr<Int64>(kErrorInvalidData);
+
+ auto man = FSClass::GetMounted();
+
+ if (man)
+ {
+ man->Write(name, fFile, data, 0, len);
+ return ErrorOr<Int64>(0);
+ }
+
+ return ErrorOr<Int64>(kErrorInvalidData);
+ }
+
+ VoidPtr Read(const Char* name, const SizeT sz) noexcept
+ {
+ if (this->fFileRestrict != kFileMgrRestrictReadWrite &&
+ this->fFileRestrict != kFileMgrRestrictReadWriteBinary &&
+ this->fFileRestrict != kFileMgrRestrictRead &&
+ this->fFileRestrict != kFileMgrRestrictReadBinary)
+ return nullptr;
+
+ auto man = FSClass::GetMounted();
+
+ if (man)
+ {
+ VoidPtr ret = man->Read(name, fFile, kFileReadAll, 0);
+ return ret;
+ }
+
+ return nullptr;
+ }
+
+ VoidPtr Read(SizeT offset, const SizeT sz)
+ {
+ if (this->fFileRestrict != kFileMgrRestrictReadWrite &&
+ this->fFileRestrict != kFileMgrRestrictReadWriteBinary &&
+ this->fFileRestrict != kFileMgrRestrictRead &&
+ this->fFileRestrict != kFileMgrRestrictReadBinary)
+ return nullptr;
+
+ auto man = FSClass::GetMounted();
+
+ if (man)
+ {
+ man->Seek(fFile, offset);
+ auto ret = man->Read(fFile, kFileReadChunk, sz);
+
+ return ret;
+ }
+
+ return nullptr;
+ }
+
+ public:
+ /// @brief Leak node pointer.
+ /// @return The node pointer.
+ NodePtr Leak()
+ {
+ return fFile;
+ }
+
+ /// @brief Leak MIME.
+ /// @return The MIME.
+ Char* MIME() noexcept
+ {
+ return const_cast<Char*>(fMime);
+ }
+
+ enum
+ {
+ kFileMgrRestrictRead,
+ kFileMgrRestrictReadBinary,
+ kFileMgrRestrictWrite,
+ kFileMgrRestrictWriteBinary,
+ kFileMgrRestrictReadWrite,
+ kFileMgrRestrictReadWriteBinary,
+ };
+
+ private:
+ NodePtr fFile{nullptr};
+ Int32 fFileRestrict{kFileMgrRestrictReadBinary};
+ const Char* fMime{kFileMimeGeneric};
+ };
+
+ using FileStreamUTF8 = FileStream<Char>;
+ using FileStreamUTF16 = FileStream<WideChar>;
+
+ typedef UInt64 CursorType;
+
+ inline static const auto kRestrictStrLen = 8U;
+
+ /// @brief restrict information about the file descriptor.
+ struct FileRestrictKind final
+ {
+ Char fRestrict[kRestrictStrLen];
+ Int32 fMappedTo;
+ };
+
+ /// @brief constructor
+ template <typename Encoding, typename Class>
+ inline FileStream<Encoding, Class>::FileStream(const Encoding* path,
+ const Encoding* restrict_type)
+ : fFile(Class::GetMounted()->Open(path, restrict_type))
+ {
+ const SizeT kRestrictCount = kRestrictMax;
+ const FileRestrictKind kRestrictList[] = {
+ {
+ .fRestrict = kRestrictR,
+ .fMappedTo = kFileMgrRestrictRead,
+ },
+ {
+ .fRestrict = kRestrictRB,
+ .fMappedTo = kFileMgrRestrictReadBinary,
+ },
+ {
+ .fRestrict = kRestrictRWB,
+ .fMappedTo = kFileMgrRestrictReadWriteBinary,
+ },
+ {
+ .fRestrict = kRestrictW,
+ .fMappedTo = kFileMgrRestrictWrite,
+ },
+ {
+ .fRestrict = kRestrictWB,
+ .fMappedTo = kFileMgrRestrictReadWrite,
+ }};
+
+ for (SizeT index = 0; index < kRestrictCount; ++index)
+ {
+ if (rt_string_cmp(restrict_type, kRestrictList[index].fRestrict,
+ rt_string_len(kRestrictList[index].fRestrict)) == 0)
+ {
+ fFileRestrict = kRestrictList[index].fMappedTo;
+ break;
+ }
+ }
+
+ kcout << "new file: " << path << ".\r";
+ }
+
+ /// @brief destructor of the file stream.
+ template <typename Encoding, typename Class>
+ inline FileStream<Encoding, Class>::~FileStream()
+ {
+ mm_delete_heap(fFile);
+ }
+} // namespace Kernel
+
+#endif // ifndef INC_FILEMGR_H
diff --git a/dev/Kernel/KernelKit/HardwareThreadScheduler.h b/dev/Kernel/KernelKit/HardwareThreadScheduler.h
new file mode 100644
index 00000000..81a137e1
--- /dev/null
+++ b/dev/Kernel/KernelKit/HardwareThreadScheduler.h
@@ -0,0 +1,149 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifndef __INC_MP_MANAGER_H__
+#define __INC_MP_MANAGER_H__
+
+#include <ArchKit/ArchKit.h>
+#include <CompilerKit/CompilerKit.h>
+#include <NewKit/Ref.h>
+
+/// @note Last Rev Sun 28 Jul CET 2024
+/// @note Last Rev Thu, Aug 1, 2024 9:07:38 AM
+
+#define kMaxAPInsideSched (8U)
+
+namespace Kernel
+{
+ class HardwareThread;
+ class HardwareThreadScheduler;
+
+ using ThreadID = UInt32;
+
+ enum ThreadKind
+ {
+ kAPSystemReserved, // System reserved thread, well user can't use it
+ kAPStandard, // user thread, cannot be used by Kernel
+ kAPFallback, // fallback thread, cannot be used by user if not clear or
+ // used by Kernel.
+ kAPBoot, // The core we booted from, the mama.
+ kInvalidAP,
+ kAPCount,
+ };
+
+ typedef enum ThreadKind ThreadKind;
+ typedef ThreadID ThreadID;
+
+ /***********************************************************************************/
+ ///
+ /// \name HardwareThread
+ /// \brief Abstraction over the CPU's core, used to run processes or threads.
+ ///
+ /***********************************************************************************/
+
+ class HardwareThread final
+ {
+ public:
+ explicit HardwareThread();
+ ~HardwareThread();
+
+ public:
+ ZKA_COPY_DEFAULT(HardwareThread)
+
+ public:
+ operator bool();
+
+ public:
+ void Wake(const bool wakeup = false) noexcept;
+ void Busy(const bool busy = false) noexcept;
+
+ public:
+ bool Switch(VoidPtr image, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ThreadID& pid);
+ bool IsWakeup() noexcept;
+
+ public:
+ HAL::StackFramePtr StackFrame() noexcept;
+ const ThreadKind& Kind() noexcept;
+ bool IsBusy() noexcept;
+ const ThreadID& ID() noexcept;
+
+ private:
+ HAL::StackFramePtr fStack{nullptr};
+ ThreadKind fKind{ThreadKind::kAPStandard};
+ ThreadID fID{0};
+ ThreadID fSourcePID{0};
+ Bool fWakeup{NO};
+ Bool fBusy{NO};
+ UInt64 fPTime{0};
+
+ private:
+ friend class HardwareThreadScheduler;
+ friend class UserProcessHelper;
+ };
+
+ ///
+ /// \name HardwareThreadScheduler
+ /// \brief Class to manage the thread scheduling.
+ ///
+
+ class HardwareThreadScheduler final : public ISchedulable
+ {
+ private:
+ friend class UserProcessHelper;
+
+ public:
+ explicit HardwareThreadScheduler();
+ ~HardwareThreadScheduler();
+ ZKA_COPY_DEFAULT(HardwareThreadScheduler);
+
+ public:
+ HAL::StackFramePtr Leak() noexcept;
+
+ public:
+ Ref<HardwareThread*> operator[](const SizeT& idx);
+ bool operator!() noexcept;
+ operator bool() noexcept;
+
+ const Bool IsUser() override
+ {
+ return Yes;
+ }
+
+ const Bool IsKernel() override
+ {
+ return No;
+ }
+
+ const Bool HasMP() override
+ {
+ return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled;
+ }
+
+ public:
+ /// @brief Shared instance of the MP Mgr.
+ /// @return the reference to the mp manager class.
+ STATIC HardwareThreadScheduler& The();
+
+ public:
+ /// @brief Returns the amount of threads present in the system.
+ /// @returns SizeT the amount of cores present.
+ SizeT Capacity() noexcept;
+
+ private:
+ Array<HardwareThread, kMaxAPInsideSched> fThreadList;
+ ThreadID fCurrentThread{0};
+ };
+
+ /// @brief wakes up thread.
+ /// wakes up thread from hang.
+ Void mp_wakeup_thread(HAL::StackFramePtr stack);
+
+ /// @brief makes thread sleep.
+ /// hooks and hangs thread to prevent code from executing.
+ Void mp_hang_thread(HAL::StackFramePtr stack);
+} // namespace Kernel
+
+#endif // !__INC_MP_MANAGER_H__
diff --git a/dev/Kernel/KernelKit/Heap.h b/dev/Kernel/KernelKit/Heap.h
new file mode 100644
index 00000000..ac6cac41
--- /dev/null
+++ b/dev/Kernel/KernelKit/Heap.h
@@ -0,0 +1,86 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifndef INC_KERNEL_HEAP_H
+#define INC_KERNEL_HEAP_H
+
+/// @date 30/01/24
+/// @file: Heap.h
+/// @brief: heap allocation support.
+
+#include <NewKit/KernelPanic.h>
+#include <KernelKit/LPC.h>
+#include <Hints/CompilerHint.h>
+
+namespace Kernel
+{
+ /// @brief Declare pointer as free.
+ /// @param heap_ptr the pointer.
+ /// @return a status code regarding the deallocation.
+ Int32 mm_delete_heap(VoidPtr heap_ptr);
+
+ /// @brief Declare a new size for heap_ptr.
+ /// @param heap_ptr the pointer.
+ /// @return unsupported always returns nullptr.
+ VoidPtr mm_realloc_heap(VoidPtr heap_ptr, SizeT new_sz);
+
+ /// @brief Check if pointer is a valid Kernel pointer.
+ /// @param heap_ptr the pointer
+ /// @return if it exists it returns true.
+ Boolean mm_is_valid_heap(VoidPtr heap_ptr);
+
+ /// @brief Allocate chunk of memory.
+ /// @param sz Size of pointer
+ /// @param wr Read Write bit.
+ /// @param user User enable bit.
+ /// @return The newly allocated pointer, or nullptr.
+ VoidPtr mm_new_heap(const SizeT sz, const Bool wr, const Bool user);
+
+ /// @brief Protect the heap with a CRC value.
+ /// @param heap_ptr pointer.
+ /// @return if it valid: point has crc now., otherwise fail.
+ Boolean mm_protect_heap(VoidPtr heap_ptr);
+
+ /// @brief Makes a Kernel page.
+ /// @param heap_ptr the page pointer.
+ /// @return status code
+ Int32 mm_make_page(VoidPtr heap_ptr);
+
+ /// @brief Overwrites and set the flags of a heap header.
+ /// @param heap_ptr the pointer to update.
+ /// @param flags the flags to set.
+ Int32 mm_make_flags(VoidPtr heap_ptr, UInt64 flags);
+
+ /// @brief Gets the flags of a heap header.
+ /// @param heap_ptr the pointer to get.
+ UInt64 mm_get_flags(VoidPtr heap_ptr);
+
+ /// @brief Allocate C++ class.
+ /// @param cls The class to allocate.
+ /// @param args The args to pass.
+ template <typename T, typename... Args>
+ inline Void mm_new_class(_Input _Output T** cls, _Input Args&&... args)
+ {
+ if (*cls)
+ {
+ err_global_get() = Kernel::kErrorInvalidData;
+ return;
+ }
+
+ *cls = new T(move(args)...);
+ }
+
+ /// @brief Delete and nullify C++ class.
+ /// @param cls The class to delete.
+ template <typename T>
+ inline Void mm_delete_class(_Input _Output T** cls)
+ {
+ delete *cls;
+ *cls = nullptr;
+ }
+} // namespace Kernel
+
+#endif // !INC_KERNEL_HEAP_H
diff --git a/dev/Kernel/KernelKit/IDylibObject.h b/dev/Kernel/KernelKit/IDylibObject.h
new file mode 100644
index 00000000..a7602be6
--- /dev/null
+++ b/dev/Kernel/KernelKit/IDylibObject.h
@@ -0,0 +1,48 @@
+/*
+ * ========================================================
+ *
+ * Kernel
+ * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+ *
+ * ========================================================
+ */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+#include <CompilerKit/CompilerKit.h>
+
+#define ZKA_DLL_OBJECT : public IDylibObject
+
+namespace Kernel
+{
+ /// @brief DLL class object. A handle to a shared library.
+ class IDylibObject
+ {
+ public:
+ explicit IDylibObject() = default;
+ virtual ~IDylibObject() = default;
+
+ struct DLL_TRAITS final
+ {
+ VoidPtr ImageObject{nullptr};
+ VoidPtr ImageEntrypointOffset{nullptr};
+
+ Bool IsValid()
+ {
+ return ImageObject && ImageEntrypointOffset;
+ }
+ };
+
+ ZKA_COPY_DEFAULT(IDylibObject);
+
+ virtual DLL_TRAITS** GetAddressOf() = 0;
+ virtual DLL_TRAITS* Get() = 0;
+
+ virtual Void Mount(DLL_TRAITS* to_mount) = 0;
+ virtual Void Unmount() = 0;
+ };
+
+ /// @brief Pure implementation, missing method/function handler.
+ EXTERN_C void __zka_pure_call(void);
+} // namespace Kernel
diff --git a/dev/Kernel/KernelKit/IPEFDylibObject.h b/dev/Kernel/KernelKit/IPEFDylibObject.h
new file mode 100644
index 00000000..68493c86
--- /dev/null
+++ b/dev/Kernel/KernelKit/IPEFDylibObject.h
@@ -0,0 +1,106 @@
+/*
+ * ========================================================
+ *
+ * Kernel
+ * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+ *
+ * ========================================================
+ */
+
+#ifndef __KERNELKIT_SHARED_OBJECT_H__
+#define __KERNELKIT_SHARED_OBJECT_H__
+
+#include <KernelKit/PEF.h>
+#include <NewKit/Defines.h>
+#include <KernelKit/PEFCodeMgr.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/IDylibObject.h>
+
+namespace Kernel
+{
+ /**
+ * @brief Shared Library class
+ * Load library from this class
+ */
+ class IPEFDylibObject final ZKA_DLL_OBJECT
+ {
+ public:
+ explicit IPEFDylibObject() = default;
+ ~IPEFDylibObject() = default;
+
+ public:
+ ZKA_COPY_DEFAULT(IPEFDylibObject);
+
+ private:
+ DLL_TRAITS* fMounted{nullptr};
+
+ public:
+ DLL_TRAITS** GetAddressOf()
+ {
+ return &fMounted;
+ }
+
+ DLL_TRAITS* Get()
+ {
+ return fMounted;
+ }
+
+ public:
+ void Mount(DLL_TRAITS* to_mount)
+ {
+ if (!to_mount || !to_mount->ImageObject)
+ return;
+
+ fMounted = to_mount;
+
+ if (fLoader && to_mount)
+ {
+ delete fLoader;
+ fLoader = nullptr;
+ }
+
+ if (!fLoader)
+ {
+ fLoader = new PEFLoader(fMounted->ImageObject);
+ }
+ }
+
+ void Unmount()
+ {
+ if (fMounted)
+ fMounted = nullptr;
+ };
+
+ template <typename SymbolType>
+ SymbolType Load(const Char* symbol_name, SizeT len, Int32 kind)
+ {
+ if (symbol_name == nullptr || *symbol_name == 0)
+ return nullptr;
+ if (len > kPathLen || len < 1)
+ return nullptr;
+
+ auto ret =
+ reinterpret_cast<SymbolType>(fLoader->FindSymbol(symbol_name, kind));
+
+ if (!ret)
+ {
+ if (kind == kPefCode)
+ return (VoidPtr)&__zka_pure_call;
+
+ return nullptr;
+ }
+
+ return ret;
+ }
+
+ private:
+ PEFLoader* fLoader{nullptr};
+ };
+
+ typedef IPEFDylibObject* IDylibRef;
+
+ EXTERN_C IDylibRef rtl_init_dylib(UserProcess& header);
+ EXTERN_C Void rtl_fini_dylib(UserProcess& header, IDylibRef lib, Bool* successful);
+} // namespace Kernel
+
+#endif /* ifndef __KERNELKIT_SHARED_OBJECT_H__ */
diff --git a/dev/Kernel/KernelKit/LPC.h b/dev/Kernel/KernelKit/LPC.h
new file mode 100644
index 00000000..434a3efc
--- /dev/null
+++ b/dev/Kernel/KernelKit/LPC.h
@@ -0,0 +1,70 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+/// @file LPC.h
+/// @brief Local Process Codes.
+
+#define err_local_ok() (Kernel::UserProcessScheduler::The().GetCurrentProcess().Leak().GetLocalCode() == Kernel::kErrorSuccess)
+#define err_local_fail() (Kernel::UserProcessScheduler::The().GetCurrentProcess().Leak().GetLocalCode() != Kernel::kErrorSuccess)
+#define err_local_get() (Kernel::UserProcessScheduler::The().GetCurrentProcess().Leak().GetLocalCode())
+
+#define err_global_ok() (Kernel::kErrorLocalNumber == Kernel::kErrorSuccess)
+#define err_global_fail() (Kernel::kErrorLocalNumber != Kernel::kErrorSuccess)
+#define err_global_get() (Kernel::kErrorLocalNumber)
+
+namespace Kernel
+{
+ typedef Int32 HError;
+
+ inline HError kErrorLocalNumber = 0UL;
+
+ inline constexpr HError kErrorSuccess = 0;
+ inline constexpr HError kErrorExecutable = 33;
+ inline constexpr HError kErrorExecutableLib = 34;
+ inline constexpr HError kErrorFileNotFound = 35;
+ inline constexpr HError kErrorDirectoryNotFound = 36;
+ inline constexpr HError kErrorDiskReadOnly = 37;
+ inline constexpr HError kErrorDiskIsFull = 38;
+ inline constexpr HError kErrorProcessFault = 39;
+ inline constexpr HError kErrorSocketHangUp = 40;
+ inline constexpr HError kErrorThreadLocalStorage = 41;
+ inline constexpr HError kErrorMath = 42;
+ inline constexpr HError kErrorNoNetwork = 43;
+ inline constexpr HError kErrorHeapOutOfMemory = 44;
+ inline constexpr HError kErrorNoSuchDisk = 45;
+ inline constexpr HError kErrorFileExists = 46;
+ inline constexpr HError kErrorFormatFailed = 47;
+ inline constexpr HError kErrorNetworkTimeout = 48;
+ inline constexpr HError kErrorInternal = 49;
+ inline constexpr HError kErrorForkAlreadyExists = 50;
+ inline constexpr HError kErrorOutOfTeamSlot = 51;
+ inline constexpr HError kErrorHeapNotPresent = 52;
+ inline constexpr HError kErrorNoEntrypoint = 53;
+ inline constexpr HError kErrorDiskIsCorrupted = 54;
+ inline constexpr HError kErrorDisk = 55;
+ inline constexpr HError kErrorInvalidData = 56;
+ inline constexpr HError kErrorAsync = 57;
+ inline constexpr HError kErrorNonBlocking = 58;
+ inline constexpr HError kErrorIPC = 59;
+ inline constexpr HError kErrorSign = 60;
+ inline constexpr HError kErrorInvalidCreds = 61;
+ inline constexpr HError kErrorCDTrayBroken = 62;
+ inline constexpr HError kErrorUnrecoverableDisk = 63;
+ inline constexpr HError kErrorFileLocked = 64;
+ inline constexpr HError kErrorUnimplemented = 0;
+
+ /// @brief Raises a bug check stop code.
+ Void err_bug_check_raise(Void) noexcept;
+
+ /// @brief Does a system wide bug check.
+ /// @param void no params are needed.
+ /// @return if error-free: false, otherwise true.
+ Boolean err_bug_check(Void) noexcept;
+} // namespace Kernel
diff --git a/dev/Kernel/KernelKit/LoaderInterface.h b/dev/Kernel/KernelKit/LoaderInterface.h
new file mode 100644
index 00000000..29a1b928
--- /dev/null
+++ b/dev/Kernel/KernelKit/LoaderInterface.h
@@ -0,0 +1,34 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <Hints/CompilerHint.h>
+#include <NewKit/Defines.h>
+#include <NewKit/ErrorOr.h>
+
+namespace Kernel
+{
+ /// @brief This interface is used to make loader contracts (MSCOFF, PEF).
+ /// @author @Amlal-El-Mahrouss
+ class LoaderInterface
+ {
+ public:
+ explicit LoaderInterface() = default;
+ virtual ~LoaderInterface() = default;
+
+ ZKA_COPY_DEFAULT(LoaderInterface);
+
+ public:
+ virtual _Output ErrorOr<VoidPtr> GetBlob() = 0;
+ virtual _Output const Char* AsString() = 0;
+ virtual _Output const Char* MIME() = 0;
+ virtual _Output const Char* Path() = 0;
+ virtual _Output ErrorOr<VoidPtr> FindStart() = 0;
+ virtual _Output VoidPtr FindSymbol(_Input const Char* name, _Input Int32 kind) = 0;
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/KernelKit/LockDelegate.h b/dev/Kernel/KernelKit/LockDelegate.h
new file mode 100644
index 00000000..2ee4bb25
--- /dev/null
+++ b/dev/Kernel/KernelKit/LockDelegate.h
@@ -0,0 +1,69 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Atom.h>
+#include <NewKit/Defines.h>
+
+namespace Kernel
+{
+ enum
+ {
+ kLockDone = 200,
+ kLockTimedOut,
+ };
+
+ /// @brief Lock condition pointer.
+ typedef Boolean* LockPtr;
+
+ /// @brief Locking delegate class, hangs until limit.
+ /// @tparam N the amount of cycles to wait.
+ template <SizeT N>
+ class LockDelegate final
+ {
+ public:
+ LockDelegate() = delete;
+
+ public:
+ explicit LockDelegate(LockPtr expr)
+ {
+ auto spin = 0U;
+
+ while (spin < N)
+ {
+ if (*expr)
+ {
+ fLockStatus | kLockDone;
+ break;
+ }
+
+ ++spin;
+ }
+
+ if (spin > N)
+ fLockStatus | kLockTimedOut;
+ }
+
+ ~LockDelegate() = default;
+
+ LockDelegate& operator=(const LockDelegate&) = delete;
+ LockDelegate(const LockDelegate&) = delete;
+
+ bool Done()
+ {
+ return fLockStatus[kLockDone] == kLockDone;
+ }
+
+ bool HasTimedOut()
+ {
+ return fLockStatus[kLockTimedOut] != kLockTimedOut;
+ }
+
+ private:
+ Atom<UInt> fLockStatus;
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/KernelKit/MSDOS.h b/dev/Kernel/KernelKit/MSDOS.h
new file mode 100644
index 00000000..3da68dae
--- /dev/null
+++ b/dev/Kernel/KernelKit/MSDOS.h
@@ -0,0 +1,52 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: MSDOS.h
+ Purpose: MS-DOS header for Kernel.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+
+------------------------------------------- */
+
+#ifndef __MSDOS_EXEC__
+#define __MSDOS_EXEC__
+
+#include <KernelKit/PE.h>
+#include <NewKit/Defines.h>
+
+// Last Rev
+// Sat Feb 24 CET 2024
+
+#define kMagMz0 'M'
+#define kMagMz1 'Z'
+
+typedef Kernel::UInt32 DosWord;
+typedef Kernel::Long DosLong;
+
+typedef struct _DosHeader
+{
+ Kernel::UInt8 eMagic[2];
+ DosWord eMagLen;
+ DosWord ePagesCount;
+ DosWord eCrlc;
+ DosWord eCParHdr;
+ DosWord eMinAlloc;
+ DosWord eMaxAlloc;
+ DosWord eStackSeg;
+ DosWord eStackPtr;
+ DosWord eChksum;
+ DosWord eIp;
+ DosWord eCs;
+ DosWord eLfarlc;
+ DosWord eOvno;
+ DosWord eRes[4];
+ DosWord eOemid;
+ DosWord eOeminfo;
+ DosWord eRes2[10];
+ DosLong eLfanew;
+} DosHeader, *DosHeaderPtr;
+
+#endif /* ifndef __MSDOS_EXEC__ */
diff --git a/dev/Kernel/KernelKit/PCI/DMA.h b/dev/Kernel/KernelKit/PCI/DMA.h
new file mode 100644
index 00000000..0ad2c344
--- /dev/null
+++ b/dev/Kernel/KernelKit/PCI/DMA.h
@@ -0,0 +1,81 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <KernelKit/DeviceMgr.h>
+#include <KernelKit/PCI/Device.h>
+#include <NewKit/Array.h>
+#include <NewKit/OwnPtr.h>
+#include <NewKit/Ref.h>
+
+namespace Kernel
+{
+ enum class DmaKind
+ {
+ PCI, // Bus mastering is required to be turned on. Basiaclly a request
+ // control system. 64-Bit access depends on the PAE bit and the device
+ // (if Double Address Cycle is available)
+ ISA, // Four DMA channels 0-3; 8 bit transfers and only a megabyte of RAM.
+ Invalid,
+ };
+
+ class DMAWrapper final
+ {
+ public:
+ explicit DMAWrapper() = delete;
+
+ public:
+ explicit DMAWrapper(nullPtr) = delete;
+ explicit DMAWrapper(voidPtr Ptr, DmaKind Kind = DmaKind::PCI)
+ : fAddress(Ptr), fKind(Kind)
+ {
+ }
+
+ public:
+ DMAWrapper& operator=(voidPtr Ptr);
+
+ public:
+ DMAWrapper& operator=(const DMAWrapper&) = default;
+ DMAWrapper(const DMAWrapper&) = default;
+
+ public:
+ ~DMAWrapper() = default;
+
+ template <class T>
+ T* operator->();
+
+ template <class T>
+ T* Get(const UIntPtr off = 0);
+
+ public:
+ operator bool();
+ bool operator!();
+
+ public:
+ bool Write(const UIntPtr& bit, const UIntPtr& offset);
+ UIntPtr Read(const UIntPtr& offset);
+ Boolean Check(UIntPtr offset) const;
+
+ public:
+ UIntPtr operator[](const UIntPtr& offset);
+
+ private:
+ voidPtr fAddress{nullptr};
+ DmaKind fKind{DmaKind::Invalid};
+
+ private:
+ friend class DMAFactory;
+ };
+
+ class DMAFactory final
+ {
+ public:
+ static OwnPtr<IOBuf<Char*>> Construct(OwnPtr<DMAWrapper>& dma);
+ };
+} // namespace Kernel
+
+#include <KernelKit/PCI/DMA.inl>
diff --git a/dev/Kernel/KernelKit/PCI/DMA.inl b/dev/Kernel/KernelKit/PCI/DMA.inl
new file mode 100644
index 00000000..49c950a6
--- /dev/null
+++ b/dev/Kernel/KernelKit/PCI/DMA.inl
@@ -0,0 +1,20 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+namespace Kernel
+{
+ template <class T>
+ T* DMAWrapper::operator->()
+ {
+ return fAddress;
+ }
+
+ template <class T>
+ T* DMAWrapper::Get(const UIntPtr offset)
+ {
+ return reinterpret_cast<T*>((UIntPtr)fAddress + offset);
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/KernelKit/PCI/Database.h b/dev/Kernel/KernelKit/PCI/Database.h
new file mode 100644
index 00000000..6cf27521
--- /dev/null
+++ b/dev/Kernel/KernelKit/PCI/Database.h
@@ -0,0 +1,38 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+#pragma once
+
+#include <KernelKit/PCI/Device.h>
+#include <NewKit/Defines.h>
+
+namespace Kernel
+{
+ namespace Types
+ {
+ // https://wiki.osdev.org/PCI
+ enum class PciDeviceKind : UChar
+ {
+ MassStorageController = 0x1,
+ NetworkController = 0x2,
+ DisplayController = 0x3,
+ MultimediaController = 0x4,
+ MemoryController = 0x5,
+ Bridge = 0x6,
+ CommunicationController = 0x7,
+ GenericSystemPeripheral = 0x8,
+ InputDeviceController = 0x9,
+ DockingStation = 0xa,
+ Processor = 0xb,
+ SerialBusController = 0xc,
+ WirelessController = 0xd,
+ IntelligentController = 0xe,
+ SatelliteCommunicationsController = 0xf,
+ CoProcessor = 0x40,
+ Unassgined = 0xf,
+ Invalid = Unassgined,
+ };
+ } // namespace Types
+} // namespace Kernel
diff --git a/dev/Kernel/KernelKit/PCI/Device.h b/dev/Kernel/KernelKit/PCI/Device.h
new file mode 100644
index 00000000..75a84308
--- /dev/null
+++ b/dev/Kernel/KernelKit/PCI/Device.h
@@ -0,0 +1,80 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+#pragma once
+
+#include <NewKit/Defines.h>
+
+namespace Kernel::PCI
+{
+ enum class PciConfigKind : UShort
+ {
+ ConfigAddress = 0xCF8,
+ ConfigData = 0xCFC,
+ Invalid = 0xFFF
+ };
+
+ class Device final
+ {
+ public:
+ Device() = default;
+
+ public:
+ explicit Device(UShort bus, UShort device, UShort function, UInt32 bar);
+
+ Device& operator=(const Device&) = default;
+
+ Device(const Device&) = default;
+
+ ~Device();
+
+ public:
+ UInt Read(UInt bar, Size szData);
+ void Write(UInt bar, UIntPtr data, Size szData);
+
+ public:
+ operator bool();
+
+ public:
+ template <typename T>
+ UInt Read(UInt bar)
+ {
+ static_assert(sizeof(T) <= 4, "64-bit PCI addressing is unsupported");
+ return Read(bar, sizeof(T));
+ }
+
+ template <typename T>
+ void Write(UInt bar, UIntPtr data)
+ {
+ static_assert(sizeof(T) <= 4, "64-bit PCI addressing is unsupported");
+ Write(bar, data, sizeof(T));
+ }
+
+ public:
+ UShort DeviceId();
+ UShort VendorId();
+ UShort InterfaceId();
+ UChar Class();
+ UChar Subclass();
+ UChar ProgIf();
+ UChar HeaderType();
+ UIntPtr Bar(UInt32 bar_in);
+
+ public:
+ void EnableMmio(UInt32 bar_in);
+ void BecomeBusMaster(UInt32 bar_in); // for PCI-DMA, PC-DMA does not need that.
+
+ UShort Vendor();
+
+ private:
+ UShort fBus;
+ UShort fDevice;
+ UShort fFunction;
+ UInt32 fBar;
+ };
+} // namespace Kernel::PCI
+
+EXTERN_C void NewOSPCISetCfgTarget(Kernel::UInt bar);
+EXTERN_C Kernel::UInt NewOSPCIReadRaw(Kernel::UInt bar);
diff --git a/dev/Kernel/KernelKit/PCI/Express.h b/dev/Kernel/KernelKit/PCI/Express.h
new file mode 100644
index 00000000..f8b24289
--- /dev/null
+++ b/dev/Kernel/KernelKit/PCI/Express.h
@@ -0,0 +1,11 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+#define PCI_EXPRESS_BUS_COUNT (4096)
diff --git a/dev/Kernel/KernelKit/PCI/IO-Impl-AMD64.inl b/dev/Kernel/KernelKit/PCI/IO-Impl-AMD64.inl
new file mode 100644
index 00000000..7eb5b405
--- /dev/null
+++ b/dev/Kernel/KernelKit/PCI/IO-Impl-AMD64.inl
@@ -0,0 +1,54 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: IO-Impl-AMD64.h
+ Purpose: I/O for AMD64.
+
+ Revision History:
+
+ 30/01/24: Add file. (amlel)
+ 02/02/24: Update I/O routines. (amlel)
+
+------------------------------------------- */
+
+namespace Kernel
+{
+ template <SizeT Sz>
+ template <typename T>
+ T IOArray<Sz>::In(SizeT index)
+ {
+ switch (sizeof(T))
+ {
+#ifdef __ZKA_AMD64__
+ case 4:
+ return HAL::rt_in32(fPorts[index].Leak());
+ case 2:
+ return HAL::rt_in16(fPorts[index].Leak());
+ case 1:
+ return HAL::rt_in8(fPorts[index].Leak());
+#endif
+ default:
+ return 0xFFFF;
+ }
+ }
+
+ template <SizeT Sz>
+ template <typename T>
+ void IOArray<Sz>::Out(SizeT index, T value)
+ {
+ switch (sizeof(T))
+ {
+#ifdef __ZKA_AMD64__
+ case 4:
+ HAL::rt_out32(fPorts[index].Leak(), value);
+ case 2:
+ HAL::rt_out16(fPorts[index].Leak(), value);
+ case 1:
+ HAL::rt_out8(fPorts[index].Leak(), value);
+#endif
+ default:
+ break;
+ }
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/KernelKit/PCI/IO.h b/dev/Kernel/KernelKit/PCI/IO.h
new file mode 100644
index 00000000..b947a739
--- /dev/null
+++ b/dev/Kernel/KernelKit/PCI/IO.h
@@ -0,0 +1,59 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <ArchKit/ArchKit.h>
+#include <NewKit/Array.h>
+#include <NewKit/Defines.h>
+#include <NewKit/Ref.h>
+
+namespace Kernel
+{
+ template <SizeT Sz>
+ class IOArray final
+ {
+ public:
+ IOArray() = delete;
+
+ IOArray(nullPtr) = delete;
+
+ explicit IOArray(Array<UShort, Sz>& ports)
+ : fPorts(ports)
+ {
+ }
+ ~IOArray()
+ {
+ }
+
+ IOArray& operator=(const IOArray&) = default;
+
+ IOArray(const IOArray&) = default;
+
+ operator bool()
+ {
+ return !fPorts.Empty();
+ }
+
+ public:
+ template <typename T>
+ T In(SizeT index);
+
+ template <typename T>
+ void Out(SizeT index, T value);
+
+ private:
+ Array<UShort, Sz> fPorts;
+ };
+
+ using IOArray16 = IOArray<16>;
+} // namespace Kernel
+
+#ifdef __x86_64__
+#include <KernelKit/PCI/IO-Impl-AMD64.inl>
+#else
+#error Please provide platform specific code for the I/O
+#endif // ifdef __x86_64__
diff --git a/dev/Kernel/KernelKit/PCI/Iterator.h b/dev/Kernel/KernelKit/PCI/Iterator.h
new file mode 100644
index 00000000..012d5f00
--- /dev/null
+++ b/dev/Kernel/KernelKit/PCI/Iterator.h
@@ -0,0 +1,43 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifndef __PCI_ITERATOR_H__
+#define __PCI_ITERATOR_H__
+
+#include <KernelKit/PCI/Database.h>
+#include <KernelKit/PCI/Device.h>
+#include <NewKit/Array.h>
+#include <NewKit/Defines.h>
+#include <NewKit/Ref.h>
+
+#define ZKA_BUS_COUNT (256)
+#define ZKA_DEVICE_COUNT (33)
+#define ZKA_FUNCTION_COUNT (8)
+
+namespace Kernel::PCI
+{
+ class Iterator final
+ {
+ public:
+ Iterator() = delete;
+
+ public:
+ explicit Iterator(const Types::PciDeviceKind& deviceType);
+
+ Iterator& operator=(const Iterator&) = default;
+ Iterator(const Iterator&) = default;
+
+ ~Iterator();
+
+ public:
+ Ref<PCI::Device> operator[](const Size& sz);
+
+ private:
+ Array<PCI::Device, ZKA_BUS_COUNT> fDevices;
+ };
+} // namespace Kernel::PCI
+
+#endif // __PCI_ITERATOR_H__
diff --git a/dev/Kernel/KernelKit/PCI/PCI.h b/dev/Kernel/KernelKit/PCI/PCI.h
new file mode 100644
index 00000000..230ec6c6
--- /dev/null
+++ b/dev/Kernel/KernelKit/PCI/PCI.h
@@ -0,0 +1,59 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+#define cPCIConfigAddressPort (0xCF8)
+#define cPCIConfigDataPort (0xCFC)
+
+#define cPCIDeviceCount (32)
+#define cPCIFuncCount (8)
+#define cPCIBusCount (255)
+
+namespace Kernel::PCI
+{
+ // model
+ struct DeviceHeader
+ {
+ UInt16 VendorId;
+ UInt16 DeviceId;
+ UInt8 Command;
+ UInt8 Status;
+ UInt8 RevisionId;
+ UInt8 ProgIf;
+ UInt8 SubClass;
+ UInt8 Class;
+ UInt8 CacheLineSz;
+ UInt8 LatencyTimer;
+ UInt8 HeaderType;
+ UInt8 Bist;
+ UInt8 Bus;
+ UInt8 Device;
+ UInt8 Function;
+ };
+
+ namespace Detail
+ {
+ class BAR
+ {
+ public:
+ UIntPtr BAR;
+ SizeT Size;
+ };
+ } // namespace Detail
+
+ class BAR
+ {
+ public:
+ Detail::BAR BAR1;
+ Detail::BAR BAR2;
+ Detail::BAR BAR3;
+ Detail::BAR BAR4;
+ Detail::BAR BAR5;
+ };
+} // namespace Kernel::PCI
diff --git a/dev/Kernel/KernelKit/PE.h b/dev/Kernel/KernelKit/PE.h
new file mode 100644
index 00000000..90406a5d
--- /dev/null
+++ b/dev/Kernel/KernelKit/PE.h
@@ -0,0 +1,143 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: PE.h
+ Purpose: Portable Executable for Kernel.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+
+------------------------------------------- */
+
+#ifndef __KERNELKIT_INC_PE_H__
+#define __KERNELKIT_INC_PE_H__
+
+#include <NewKit/Defines.h>
+
+#define kPeSignature 0x00004550
+
+#define kPeDLLBase 0x4000000
+#define kPeEXEBase 0x1000000
+
+#define kPeMagic32 0x010b
+#define kPeMagic64 0x020b
+
+#define kPeMachineAMD64 0x8664
+#define kPeMachineARM64 0xaa64
+
+typedef struct LDR_EXEC_HEADER final
+{
+ Kernel::UInt32 mSignature;
+ Kernel::UInt16 mMachine;
+ Kernel::UInt16 mNumberOfSections;
+ Kernel::UInt32 mTimeDateStamp;
+ Kernel::UInt32 mPointerToSymbolTable;
+ Kernel::UInt32 mNumberOfSymbols;
+ Kernel::UInt16 mSizeOfOptionalHeader;
+ Kernel::UInt16 mCharacteristics;
+} LDR_EXEC_HEADER, *LDR_EXEC_HEADER_PTR;
+
+typedef struct LDR_OPTIONAL_HEADER final
+{
+ Kernel::UInt16 mMagic; // 0x010b - PE32, 0x020b - PE32+ (64 bit)
+ Kernel::UInt8 mMajorLinkerVersion;
+ Kernel::UInt8 mMinorLinkerVersion;
+ Kernel::UInt32 mSizeOfCode;
+ Kernel::UInt32 mSizeOfInitializedData;
+ Kernel::UInt32 mSizeOfUninitializedData;
+ Kernel::UInt32 mAddressOfEntryPoint;
+ Kernel::UInt32 mBaseOfCode;
+ Kernel::UInt32 mBaseOfData;
+ Kernel::UInt32 mImageBase;
+ Kernel::UInt32 mSectionAlignment;
+ Kernel::UInt32 mFileAlignment;
+ Kernel::UInt16 mMajorOperatingSystemVersion;
+ Kernel::UInt16 mMinorOperatingSystemVersion;
+ Kernel::UInt16 mMajorImageVersion;
+ Kernel::UInt16 mMinorImageVersion;
+ Kernel::UInt16 mMajorSubsystemVersion;
+ Kernel::UInt16 mMinorSubsystemVersion;
+ Kernel::UInt32 mWin32VersionValue;
+ Kernel::UInt32 mSizeOfImage;
+ Kernel::UInt32 mSizeOfHeaders;
+ Kernel::UInt32 mCheckSum;
+ Kernel::UInt16 mSubsystem;
+ Kernel::UInt16 mDllCharacteristics;
+ Kernel::UInt32 mSizeOfStackReserve;
+ Kernel::UInt32 mSizeOfStackCommit;
+ Kernel::UInt32 mSizeOfHeapReserve;
+ Kernel::UInt32 mSizeOfHeapCommit;
+ Kernel::UInt32 mLoaderFlags;
+ Kernel::UInt32 mNumberOfRvaAndSizes;
+} LDR_OPTIONAL_HEADER, *LDR_OPTIONAL_HEADER_PTR;
+
+typedef struct LDR_SECTION_HEADER final
+{
+ Kernel::Char mName[8];
+ Kernel::UInt32 mVirtualSize;
+ Kernel::UInt32 mVirtualAddress;
+ Kernel::UInt32 mSizeOfRawData;
+ Kernel::UInt32 mPointerToRawData;
+ Kernel::UInt32 mPointerToRelocations;
+ Kernel::UInt32 mPointerToLineNumbers;
+ Kernel::UInt16 mNumberOfRelocations;
+ Kernel::UInt16 mNumberOfLinenumbers;
+ Kernel::UInt32 mCharacteristics;
+} LDR_SECTION_HEADER, *LDR_SECTION_HEADER_PTR;
+
+enum kExecDataDirParams
+{
+ kExecExport,
+ kExecImport,
+ kExecInvalid,
+ kExecCount,
+};
+
+typedef struct LDR_EXPORT_DIRECTORY
+{
+ Kernel::UInt32 mCharacteristics;
+ Kernel::UInt32 mTimeDateStamp;
+ Kernel::UInt16 mMajorVersion;
+ Kernel::UInt16 mMinorVersion;
+ Kernel::UInt32 mName;
+ Kernel::UInt32 mBase;
+ Kernel::UInt32 mNumberOfFunctions;
+ Kernel::UInt32 mNumberOfNames;
+ Kernel::UInt32 mAddressOfFunctions; // export table rva
+ Kernel::UInt32 mAddressOfNames;
+ Kernel::UInt32 mAddressOfNameOrdinal; // ordinal table rva
+} LDR_EXPORT_DIRECTORY, *LDR_EXPORT_DIRECTORY_PTR;
+
+typedef struct LDR_IMPORT_DIRECTORY
+{
+ union {
+ Kernel::UInt32 mCharacteristics;
+ Kernel::UInt32 mOriginalFirstThunk;
+ };
+ Kernel::UInt32 mTimeDateStamp;
+ Kernel::UInt32 mForwarderChain;
+ Kernel::UInt32 mNameRva;
+ Kernel::UInt32 mThunkTableRva;
+} LDR_IMPORT_DIRECTORY, *LDR_IMPORT_DIRECTORY_PTR;
+
+typedef struct LDR_DATA_DIRECTORY
+{
+ Kernel::UInt32 VirtualAddress;
+ Kernel::UInt32 Size;
+} LDR_DATA_DIRECTORY, *LDR_DATA_DIRECTORY_PTR;
+
+typedef struct LDR_IMAGE_HEADER
+{
+ LDR_EXEC_HEADER mHeader;
+ LDR_OPTIONAL_HEADER mOptHdr;
+} LDR_IMAGE_HEADER, *LDR_IMAGE_HEADER_PTR;
+
+enum
+{
+ eUserSection = 0x00000020,
+ cPEResourceId = 0xFFaadd00,
+};
+
+#endif /* ifndef __KERNELKIT_INC_PE_H__ */
diff --git a/dev/Kernel/KernelKit/PECodeMgr.h b/dev/Kernel/KernelKit/PECodeMgr.h
new file mode 100644
index 00000000..f0f1b719
--- /dev/null
+++ b/dev/Kernel/KernelKit/PECodeMgr.h
@@ -0,0 +1,24 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: PECodeMgr.h
+ Purpose: PE32+ Code Mgr and DLL mgr.
+
+ Revision History:
+
+ 12/02/24: Added file (amlel)
+
+------------------------------------------- */
+
+#pragma once
+
+////////////////////////////////////////////////////
+
+// LAST REV: Mon Feb 12 13:52:01 CET 2024
+
+////////////////////////////////////////////////////
+
+#include <KernelKit/PE.h>
+#include <NewKit/ErrorOr.h>
+#include <NewKit/KString.h>
diff --git a/dev/Kernel/KernelKit/PEF.h b/dev/Kernel/KernelKit/PEF.h
new file mode 100644
index 00000000..79d237fe
--- /dev/null
+++ b/dev/Kernel/KernelKit/PEF.h
@@ -0,0 +1,117 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: PEF.h
+ Purpose: Preferred Executable Format for Kernel.
+
+ Revision History:
+
+ ?/?/23: Added file (amlel)
+
+------------------------------------------- */
+
+#ifndef KERNELKIT_PEF_H
+#define KERNELKIT_PEF_H
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/LoaderInterface.h>
+#include <NewKit/Defines.h>
+
+#define kPefMagic "Joy!"
+#define kPefMagicFat "yoJ!"
+
+#define kPefMagicLen 5
+
+#define kPefVersion 3
+#define kPefNameLen 255
+
+/* not mandatory, only for non fork based filesystems. */
+#define kPefExt ".o"
+#define kPefDylibExt ".dylib"
+#define kPefLibExt ".lib"
+#define kPefObjectExt ".obj"
+#define kPefDebugExt ".dbg"
+#define kPefDriverExt ".sys"
+
+// Kernel System Binary Interface.
+#define kPefAbi (0x5046)
+
+#define kPefBaseOrigin (0x40000000)
+
+#define kPefStart "__ImageStart"
+
+#define kPefForkKind kPefMagic
+#define kPefForkKindFAT kPefMagicFat
+
+namespace Kernel
+{
+ enum
+ {
+ kPefArchIntel86S,
+ kPefArchAMD64,
+ kPefArchRISCV,
+ kPefArch64x0, /* 64x0. ISA */
+ kPefArch32x0, /* 32x0. ISA */
+ kPefArchPowerPC,
+ kPefArchARM64,
+ kPefArchCount = (kPefArchPowerPC - kPefArchIntel86S) + 1,
+ kPefArchInvalid = 0xFF,
+ };
+
+ enum
+ {
+ kPefSubArchAMD,
+ kPefSubArchIntel,
+ kPefSubArchARM,
+ kPefSubArchGeneric,
+ kPefSubArchIBM,
+ };
+
+ enum
+ {
+ kPefKindExec = 1, /* .o */
+ kPefKindDylib = 2, /* .dylib */
+ kPefKindObject = 4, /* .obj */
+ kPefKindDebug = 5, /* .dbg */
+ kPefKindDriver = 6,
+ kPefKindCount,
+ };
+
+ typedef struct PEFContainer final
+ {
+ Char Magic[kPefMagicLen];
+ UInt32 Linker;
+ UInt32 Version;
+ UInt32 Kind;
+ UInt32 Abi;
+ UInt32 Cpu;
+ UInt32 SubCpu; /* Cpu specific information */
+ UIntPtr Start;
+ SizeT HdrSz; /* Size of header */
+ SizeT Count; /* container header count */
+ } PACKED PEFContainer;
+
+ /* First PEFCommandHeader starts after PEFContainer */
+
+ typedef struct PEFCommandHeader final
+ {
+ Char Name[kPefNameLen]; /* container name */
+ UInt32 Cpu; /* container cpu */
+ UInt32 SubCpu; /* container sub-cpu */
+ UInt32 Flags; /* container flags */
+ UInt16 Kind; /* container kind */
+ UIntPtr Offset; /* content offset */
+ SizeT Size; /* content Size */
+ } PACKED PEFCommandHeader;
+
+ enum
+ {
+ kPefCode = 0xC,
+ kPefData = 0xD,
+ kPefZero = 0xE,
+ kPefLinkerID = 0x1,
+ };
+} // namespace Kernel
+
+#endif /* ifndef KERNELKIT_PEF_H */
diff --git a/dev/Kernel/KernelKit/PEFCodeMgr.h b/dev/Kernel/KernelKit/PEFCodeMgr.h
new file mode 100644
index 00000000..25fb7f9b
--- /dev/null
+++ b/dev/Kernel/KernelKit/PEFCodeMgr.h
@@ -0,0 +1,72 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifndef _INC_CODE_MANAGER_PEF_H_
+#define _INC_CODE_MANAGER_PEF_H_
+
+#include <KernelKit/PEF.h>
+#include <NewKit/ErrorOr.h>
+#include <NewKit/KString.h>
+#include <KernelKit/FileMgr.h>
+
+#ifndef INC_PROCESS_SCHEDULER_H
+#include <KernelKit/UserProcessScheduler.h>
+#endif
+
+#define kPefApplicationMime "application/vnd-zka-executable"
+
+namespace Kernel
+{
+ ///
+ /// \name PEFLoader
+ /// \brief PEF loader class.
+ ///
+ class PEFLoader : public LoaderInterface
+ {
+ private:
+ explicit PEFLoader() = delete;
+
+ public:
+ explicit PEFLoader(const VoidPtr blob);
+ explicit PEFLoader(const Char* path);
+ ~PEFLoader() override;
+
+ public:
+ ZKA_COPY_DEFAULT(PEFLoader);
+
+ public:
+ const Char* Path() override;
+ const Char* AsString() override;
+ const Char* MIME() override;
+
+ public:
+ ErrorOr<VoidPtr> FindStart() override;
+ VoidPtr FindSymbol(const Char* name, Int32 kind) override;
+ ErrorOr<VoidPtr> GetBlob() override;
+
+ public:
+ bool IsLoaded() noexcept;
+
+ private:
+#ifdef __FSKIT_INCLUDES_NEFS__
+ OwnPtr<FileStream<Char, NeFileSystemMgr>> fFile;
+#else
+ OwnPtr<FileStream<Char>> fFile;
+#endif // __FSKIT_INCLUDES_NEFS__
+
+ Ref<KString> fPath;
+ VoidPtr fCachedBlob;
+ bool fFatBinary;
+ bool fBad;
+ };
+
+ namespace Utils
+ {
+ ProcessID rtl_create_process(PEFLoader& exec, const Int32& procKind) noexcept;
+ } // namespace Utils
+} // namespace Kernel
+
+#endif // ifndef _INC_CODE_MANAGER_PEF_H_
diff --git a/dev/Kernel/KernelKit/Semaphore.h b/dev/Kernel/KernelKit/Semaphore.h
new file mode 100644
index 00000000..7d149027
--- /dev/null
+++ b/dev/Kernel/KernelKit/Semaphore.h
@@ -0,0 +1,43 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+#include <KernelKit/Timer.h>
+#include <CompilerKit/CompilerKit.h>
+
+namespace Kernel
+{
+ class UserProcess;
+
+ typedef UserProcess& UserProcessRef;
+
+ /// @brief Access control class, which locks a task until one is done.
+ class Semaphore final
+ {
+ public:
+ explicit Semaphore() = default;
+ ~Semaphore() = default;
+
+ public:
+ bool IsLocked() const;
+ bool Unlock() noexcept;
+
+ public:
+ void WaitForProcess() noexcept;
+
+ public:
+ bool Lock(UserProcess& process);
+ bool LockOrWait(UserProcess& process, TimerInterface* timer);
+
+ public:
+ ZKA_COPY_DEFAULT(Semaphore);
+
+ private:
+ UserProcessRef fLockingProcess;
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/KernelKit/ThreadLocalStorage.h b/dev/Kernel/KernelKit/ThreadLocalStorage.h
new file mode 100644
index 00000000..bce26b26
--- /dev/null
+++ b/dev/Kernel/KernelKit/ThreadLocalStorage.h
@@ -0,0 +1,69 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifndef KERNELKIT_TLS_H
+#define KERNELKIT_TLS_H
+
+#include <NewKit/Defines.h>
+#include <NewKit/ErrorOr.h>
+
+///! @brief Thread Local Storage for minoskrnl.
+
+#define kCookieMag0Idx 0
+#define kCookieMag1Idx 1
+#define kCookieMag2Idx 2
+
+#define kCookieMag0 'Z'
+#define kCookieMag1 'K'
+#define kCookieMag2 'A'
+
+#define kTLSCookieLen (3U)
+
+struct THREAD_INFORMATION_BLOCK;
+
+/// @brief Thread Information Block.
+/// Located in GS on AMD64, other architectures have their own stuff. (64x0, 32x0, ARM64)
+struct PACKED THREAD_INFORMATION_BLOCK final
+{
+ Kernel::Char Cookie[kTLSCookieLen]{0}; //! Thread magic number.
+ Kernel::VoidPtr Record{nullptr}; //! Thread information record.
+};
+
+///! @brief Cookie Sanity check.
+Kernel::Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* the_tib);
+
+///! @brief new ptr syscall.
+template <typename T>
+T* tls_new_ptr(void) noexcept;
+
+///! @brief delete ptr syscall.
+template <typename T>
+Kernel::Boolean tls_delete_ptr(T* ptr) noexcept;
+
+//! @brief Delete process pointer.
+//! @param obj The pointer to delete.
+template <typename T>
+inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T> obj) noexcept;
+
+//! @brief Delete process pointer.
+//! @param obj The pointer to delete.
+template <typename T>
+inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T*> obj) noexcept;
+
+template <typename T, typename... Args>
+T* tls_new_class(Args&&... args);
+
+/// @brief TLS install TIB and PIB. (syscall)
+EXTERN_C Kernel::Void rt_install_tib(THREAD_INFORMATION_BLOCK* TIB, THREAD_INFORMATION_BLOCK* PIB);
+
+/// @brief TLS check (syscall)
+EXTERN_C Kernel::Bool tls_check_syscall_impl(Kernel::VoidPtr TIB) noexcept;
+
+#include <KernelKit/ThreadLocalStorage.inl>
+
+// last rev 7/7/24
+
+#endif /* ifndef KERNELKIT_TLS_H */
diff --git a/dev/Kernel/KernelKit/ThreadLocalStorage.inl b/dev/Kernel/KernelKit/ThreadLocalStorage.inl
new file mode 100644
index 00000000..6573209a
--- /dev/null
+++ b/dev/Kernel/KernelKit/ThreadLocalStorage.inl
@@ -0,0 +1,99 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+//! @file ThreadLocalStorage.inl
+//! @brief Allocate resources from the process's heap storage.
+
+#ifndef INC_PROCESS_SCHEDULER_H
+#include <KernelKit/UserProcessScheduler.h>
+#endif
+
+template <typename T>
+inline T* tls_new_ptr(void) noexcept
+{
+ using namespace Kernel;
+
+ auto ref_process = UserProcessScheduler::The().GetCurrentProcess();
+ MUST_PASS(ref_process);
+
+ auto pointer = ref_process.Leak().New(sizeof(T));
+
+ if (pointer.Error())
+ return nullptr;
+
+ return reinterpret_cast<T*>(pointer.Leak().Leak());
+}
+
+//! @brief Delete process pointer.
+//! @param obj The pointer to delete.
+template <typename T>
+inline Kernel::Bool tls_delete_ptr(T* obj) noexcept
+{
+ using namespace Kernel;
+
+ if (!obj)
+ return No;
+
+ auto ref_process = UserProcessScheduler::The().GetCurrentProcess();
+ MUST_PASS(ref_process);
+
+ ErrorOr<T*> obj_wrapped{obj};
+
+ return ref_process.Leak().Delete(obj_wrapped, sizeof(T));
+}
+
+//! @brief Delete process pointer.
+//! @param obj The pointer to delete.
+template <typename T>
+inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T> obj) noexcept
+{
+ return tls_delete_ptr(obj.Leak());
+}
+
+//! @brief Delete process pointer.
+//! @param obj The pointer to delete.
+template <typename T>
+inline Kernel::Bool tls_delete_ptr(Kernel::ErrorOr<T*> obj) noexcept
+{
+ return tls_delete_ptr(obj->Leak());
+}
+
+/// @brief Allocate a C++ class, and then call the constructor of it.
+/// @tparam T class type.
+/// @tparam ...Args varg class type.
+/// @param args arguments list.
+/// @return Class instance.
+template <typename T, typename... Args>
+T* tls_new_class(Args&&... args)
+{
+ using namespace Kernel;
+
+ T* obj = tls_new_ptr<T>();
+
+ if (obj)
+ {
+ *obj = T(forward(args)...);
+ return obj;
+ }
+
+ return nullptr;
+}
+
+/// @brief Delete a C++ class (call constructor first.)
+/// @tparam T
+/// @param obj
+/// @return
+template <typename T>
+inline Kernel::Bool tls_delete_class(T* obj)
+{
+ using namespace Kernel;
+
+ if (!obj)
+ return No;
+
+ obj->~T();
+ return tls_delete_ptr(obj);
+}
diff --git a/dev/Kernel/KernelKit/Timer.h b/dev/Kernel/KernelKit/Timer.h
new file mode 100644
index 00000000..2fa2dfa6
--- /dev/null
+++ b/dev/Kernel/KernelKit/Timer.h
@@ -0,0 +1,81 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/LPC.h>
+
+namespace Kernel
+{
+ class SoftwareTimer;
+ class TimerInterface;
+
+ class TimerInterface
+ {
+ public:
+ /// @brief Default constructor
+ explicit TimerInterface() = default;
+ virtual ~TimerInterface() = default;
+
+ public:
+ ZKA_COPY_DEFAULT(TimerInterface);
+
+ public:
+ virtual BOOL Wait() noexcept;
+ };
+
+ class SoftwareTimer final : public TimerInterface
+ {
+ public:
+ explicit SoftwareTimer(Int64 seconds);
+ ~SoftwareTimer() override;
+
+ public:
+ ZKA_COPY_DEFAULT(SoftwareTimer);
+
+ public:
+ BOOL Wait() noexcept override;
+
+ private:
+ IntPtr* fDigitalTimer{nullptr};
+ Int64 fWaitFor{0};
+ };
+
+ class HardwareTimer final : public TimerInterface
+ {
+ public:
+ explicit HardwareTimer(Int64 seconds);
+ ~HardwareTimer() override;
+
+ public:
+ ZKA_COPY_DEFAULT(HardwareTimer);
+
+ public:
+ BOOL Wait() noexcept override;
+
+ private:
+ IntPtr* fDigitalTimer{nullptr};
+ Int64 fWaitFor{0};
+ };
+
+ inline Int64 Milliseconds(Int64 time)
+ {
+ if (time < 0)
+ return 0;
+
+ // TODO: nanoseconds maybe?
+ return 1000 * 1000 * time;
+ }
+
+ inline Int64 Seconds(Int64 time)
+ {
+ if (time < 0)
+ return 0;
+
+ return 1000 * Milliseconds(time);
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/KernelKit/User.h b/dev/Kernel/KernelKit/User.h
new file mode 100644
index 00000000..2fb832d4
--- /dev/null
+++ b/dev/Kernel/KernelKit/User.h
@@ -0,0 +1,86 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifndef INC_USER_H
+#define INC_USER_H
+
+#include <CompilerKit/CompilerKit.h>
+#include <KernelKit/LPC.h>
+#include <NewKit/KString.h>
+#include <NewKit/Defines.h>
+
+///! We got the Super, standard user (%s format) and guest user,
+///! all are used to make authorization operations on the OS.
+#define kSuperUser "OS AUTHORITY/SUPER/%s"
+#define kGuestUser "OS AUTHORITY/GUEST/%s"
+#define kFmtUser "OS AUTHORITY/STD/%s"
+
+#define kUsersDir "/usr/"
+
+#define kMaxUserNameLen (255U)
+#define kMaxUserTokenLen (255U)
+
+namespace Kernel
+{
+ class User;
+
+ enum class UserRingKind
+ {
+ kRingInvalid = 0,
+ kRingStdUser = 1,
+ kRingSuperUser = 2,
+ kRingGuestUser = 5,
+ kRingCount = 3,
+ };
+
+ typedef Char* UserPublicKey;
+
+ /// @brief User class.
+ class User final
+ {
+ public:
+ explicit User() = delete;
+
+ User(const Int32& sel, const Char* username);
+ User(const UserRingKind& kind, const Char* username);
+
+ ~User();
+
+ public:
+ ZKA_COPY_DEFAULT(User);
+
+ public:
+ bool operator==(const User& lhs);
+ bool operator!=(const User& lhs);
+
+ public:
+ /// @brief Get software ring
+ const UserRingKind& Ring() noexcept;
+
+ /// @brief Get user name
+ Char* Name() noexcept;
+
+ /// @brief Is he a standard user?
+ Bool IsStdUser() noexcept;
+
+ /// @brief Is she a super user?
+ Bool IsSuperUser() noexcept;
+
+ /// @brief Saves a password from the public key.
+ Bool Save(const UserPublicKey password) noexcept;
+
+ /// @brief Checks if a password matches the **password**.
+ /// @param password the password to check.
+ Bool Matches(const UserPublicKey password) noexcept;
+
+ private:
+ UserRingKind mUserRing{UserRingKind::kRingStdUser};
+ Char mUserName[kMaxUserNameLen] = {0};
+ Char mUserKey[kMaxUserTokenLen] = {0};
+ };
+} // namespace Kernel
+
+#endif /* ifndef INC_USER_H */
diff --git a/dev/Kernel/KernelKit/UserProcessScheduler.h b/dev/Kernel/KernelKit/UserProcessScheduler.h
new file mode 100644
index 00000000..0682a9cd
--- /dev/null
+++ b/dev/Kernel/KernelKit/UserProcessScheduler.h
@@ -0,0 +1,341 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifndef INC_PROCESS_SCHEDULER_H
+#define INC_PROCESS_SCHEDULER_H
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/LockDelegate.h>
+#include <KernelKit/User.h>
+#include <NewKit/MutableArray.h>
+
+#define kSchedMinMicroTime (AffinityKind::kStandard)
+#define kSchedInvalidPID (-1)
+#define kSchedProcessLimitPerTeam (32U)
+
+#define kSchedMaxMemoryLimit gib_cast(128)
+#define kSchedMaxStackSz mib_cast(8)
+
+#define kProcessInvalidID (-1)
+#define kProcessNameLen (128U)
+
+////////////////////////////////////////////////////
+// The current date is: Thu 11/28/2024 //
+////////////////////////////////////////////////////
+
+namespace Kernel
+{
+ //! @note Forward class declarations.
+
+ class IDylibObject;
+ class UserProcess;
+ class UserProcessTeam;
+ class UserProcessScheduler;
+ class UserProcessHelper;
+
+ //! @brief Local Process identifier.
+ typedef Int64 ProcessID;
+
+ //! @brief Local Process status enum.
+ enum class ProcessStatusKind : Int32
+ {
+ kInvalid,
+ kStarting,
+ kRunning,
+ kKilled,
+ kFrozen,
+ kFinished,
+ kCount,
+ };
+
+ //! @brief Affinity is the amount of nano-seconds this process is going
+ //! to run.
+ enum class AffinityKind : Int32
+ {
+ kRealTime = 500,
+ kVeryHigh = 250,
+ kHigh = 200,
+ kStandard = 1000,
+ kLowUsage = 1500,
+ kVeryLowUsage = 2000,
+ };
+
+ // operator overloading.
+
+ inline bool operator<(AffinityKind lhs, AffinityKind rhs)
+ {
+ Int32 lhs_int = static_cast<Int>(lhs);
+ Int32 rhs_int = static_cast<Int>(rhs);
+
+ return lhs_int < rhs_int;
+ }
+
+ inline bool operator>(AffinityKind lhs, AffinityKind rhs)
+ {
+ Int32 lhs_int = static_cast<Int>(lhs);
+ Int32 rhs_int = static_cast<Int>(rhs);
+
+ return lhs_int > rhs_int;
+ }
+
+ inline bool operator<=(AffinityKind lhs, AffinityKind rhs)
+ {
+ Int32 lhs_int = static_cast<Int>(lhs);
+ Int32 rhs_int = static_cast<Int>(rhs);
+
+ return lhs_int <= rhs_int;
+ }
+
+ inline bool operator>=(AffinityKind lhs, AffinityKind rhs)
+ {
+ Int32 lhs_int = static_cast<Int>(lhs);
+ Int32 rhs_int = static_cast<Int>(rhs);
+
+ return lhs_int >= rhs_int;
+ }
+
+ // end of operator overloading.
+
+ enum class ProcessSubsystem : Int32
+ {
+ kProcessSubsystemSecurity = 100,
+ kProcessSubsystemApplication,
+ kProcessSubsystemService,
+ kProcessSubsystemDriver,
+ kProcessSubsystemInvalid = 255,
+ kProcessSubsystemCount = 4,
+ };
+
+ using ProcessTime = UInt64;
+ using PID = Int64;
+
+ // for permission manager, tells where we run the code.
+ enum class ProcessLevelRing : Int32
+ {
+ kRingStdUser = 1,
+ kRingSuperUser = 2,
+ kRingGuestUser = 5,
+ kRingCount = 5,
+ };
+
+ /// @brief Helper type to describe a code image.
+ using ImagePtr = VoidPtr;
+
+ struct UserProcessImage final
+ {
+ explicit UserProcessImage() = default;
+
+ ImagePtr fCode;
+ ImagePtr fBlob;
+
+ Bool HasCode()
+ {
+ return this->fCode != nullptr;
+ }
+
+ Bool HasImage()
+ {
+ return this->fBlob != nullptr;
+ }
+ };
+
+ /// @name UserProcess
+ /// @brief User process class, holds information about the running process/thread.
+ class UserProcess final
+ {
+ public:
+ explicit UserProcess();
+ ~UserProcess();
+
+ public:
+ ZKA_COPY_DEFAULT(UserProcess);
+
+ public:
+ Char Name[kProcessNameLen] = {"Process"};
+ ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemInvalid};
+ User* Owner{nullptr};
+ HAL::StackFramePtr StackFrame{nullptr};
+ AffinityKind Affinity{AffinityKind::kStandard};
+ ProcessStatusKind Status{ProcessStatusKind::kFinished};
+ UInt8* StackReserve{nullptr};
+ UserProcessImage Image{};
+ SizeT StackSize{kSchedMaxStackSz};
+ IDylibObject* DylibDelegate{nullptr};
+ SizeT MemoryCursor{0UL};
+ SizeT MemoryLimit{kSchedMaxMemoryLimit};
+ SizeT UsedMemory{0UL};
+
+ struct ProcessMemoryHeapList final
+ {
+ VoidPtr MemoryEntry{nullptr};
+ SizeT MemoryEntrySize{0UL};
+ SizeT MemoryEntryPad{0UL};
+
+ struct ProcessMemoryHeapList* MemoryPrev{nullptr};
+ struct ProcessMemoryHeapList* MemoryNext{nullptr};
+ };
+
+ struct UserProcessSignal final
+ {
+ UIntPtr SignalIP;
+ ProcessStatusKind PreviousStatus;
+ UIntPtr SignalID;
+ };
+
+ UserProcessSignal ProcessSignal;
+ ProcessMemoryHeapList* ProcessMemoryHeap{nullptr};
+ UserProcessTeam* ProcessParentTeam;
+
+ VoidPtr VMRegister{0UL};
+
+ enum
+ {
+ kInvalidExecutableKind,
+ kExectuableKind,
+ kExectuableDylibKind,
+ kExectuableKindCount,
+ };
+
+ ProcessTime PTime{0}; //! @brief Process allocated tine.
+
+ PID ProcessId{kSchedInvalidPID};
+ Int32 Kind{kExectuableKind};
+
+ public:
+ //! @brief boolean operator, check status.
+ operator bool();
+
+ ///! @brief Crashes the app, exits with code ~0.
+ Void Crash();
+
+ ///! @brief Exits the app.
+ Void Exit(const Int32& exit_code = 0);
+
+ ///! @brief TLS allocate.
+ ///! @param sz size of new ptr.
+ ErrorOr<VoidPtr> New(const SizeT& sz, const SizeT& pad_amount = 0);
+
+ ///! @brief TLS free.
+ ///! @param ptr the pointer to free.
+ ///! @param sz the size of it.
+ template <typename T>
+ Boolean Delete(ErrorOr<T*> ptr, const SizeT& sz);
+
+ ///! @brief Wakes up threads.
+ Void Wake(const Bool wakeup = false);
+
+ public:
+ //! @brief Gets the local exit code.
+ const UInt32& GetExitCode() noexcept;
+
+ ///! @brief Get the process's name
+ ///! @example 'C Runtime Library'
+ const Char* GetName() noexcept;
+
+ //! @brief return local error code of process.
+ //! @return Int32 local error code.
+ Int32& GetLocalCode() noexcept;
+
+ const User* GetOwner() noexcept;
+ const ProcessStatusKind& GetStatus() noexcept;
+ const AffinityKind& GetAffinity() noexcept;
+
+ private:
+ UInt32 fLastExitCode{0};
+ Int32 fLocalCode{0};
+
+ friend UserProcessScheduler;
+ friend UserProcessHelper;
+ };
+
+ /// \brief Processs Team (contains multiple processes inside it.)
+ /// Equivalent to a process batch
+ class UserProcessTeam final
+ {
+ public:
+ explicit UserProcessTeam();
+ ~UserProcessTeam() = default;
+
+ ZKA_COPY_DEFAULT(UserProcessTeam);
+
+ Array<UserProcess, kSchedProcessLimitPerTeam>& AsArray();
+ Ref<UserProcess>& AsRef();
+ ProcessID& Id() noexcept;
+
+ public:
+ Array<UserProcess, kSchedProcessLimitPerTeam> mProcessList;
+ Ref<UserProcess> mCurrentProcess;
+ ProcessID mTeamId{0};
+ ProcessID mProcessCount{0};
+ };
+
+ typedef Array<UserProcess, kSchedProcessLimitPerTeam> UserThreadArray;
+
+ using UserProcessRef = UserProcess&;
+
+ /// @brief Process scheduler class.
+ /// The main class which you call to schedule user processes.
+ class UserProcessScheduler final : public ISchedulable
+ {
+ friend class UserProcessHelper;
+
+ public:
+ explicit UserProcessScheduler() = default;
+ ~UserProcessScheduler() override = default;
+
+ ZKA_COPY_DEFAULT(UserProcessScheduler)
+
+ operator bool();
+ bool operator!();
+
+ public:
+ UserProcessTeam& CurrentTeam();
+
+ public:
+ ProcessID Spawn(const Char* name, VoidPtr code, VoidPtr image);
+ const Bool Remove(ProcessID process_id);
+
+ const Bool IsUser() override;
+ const Bool IsKernel() override;
+ const Bool HasMP() override;
+
+ public:
+ Ref<UserProcess>& GetCurrentProcess();
+ const SizeT Run() noexcept;
+
+ public:
+ STATIC UserProcessScheduler& The();
+
+ private:
+ UserProcessTeam mTeam{};
+ };
+
+ /*
+ * \brief UserProcess helper class, which contains needed utilities for the scheduler.
+ */
+
+ class UserProcessHelper final
+ {
+ public:
+ STATIC Bool Switch(VoidPtr image_ptr, UInt8* stack_ptr, HAL::StackFramePtr frame_ptr, const PID& new_pid);
+ STATIC Bool CanBeScheduled(const UserProcess& process);
+ STATIC ErrorOr<PID> TheCurrentPID();
+ STATIC SizeT StartScheduling();
+ };
+
+ const UInt32& sched_get_exit_code(void) noexcept;
+} // namespace Kernel
+
+#include <KernelKit/ThreadLocalStorage.h>
+#include <KernelKit/UserProcessScheduler.inl>
+
+////////////////////////////////////////////////////
+
+// END
+
+////////////////////////////////////////////////////
+
+#endif /* ifndef INC_PROCESS_SCHEDULER_H */
diff --git a/dev/Kernel/KernelKit/UserProcessScheduler.inl b/dev/Kernel/KernelKit/UserProcessScheduler.inl
new file mode 100644
index 00000000..6f1f3f4a
--- /dev/null
+++ b/dev/Kernel/KernelKit/UserProcessScheduler.inl
@@ -0,0 +1,51 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ FILE: UserProcessScheduler.inl
+ PURPOSE: Low level/Ring-3 Process scheduler.
+
+------------------------------------------- */
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /** @brief Free pointer from usage. */
+ /***********************************************************************************/
+
+ template <typename T>
+ Boolean UserProcess::Delete(ErrorOr<T*> ptr, const SizeT& sz)
+ {
+ if (!ptr ||
+ sz == 0)
+ return No;
+
+ ProcessMemoryHeapList* entry = this->ProcessMemoryHeap;
+
+ while (entry != nullptr)
+ {
+ if (entry->MemoryEntry == ptr.Leak().Leak())
+ {
+ this->UsedMemory -= entry->MemoryEntrySize;
+
+#ifdef __ZKA_AMD64__
+ auto pd = hal_read_cr3();
+ hal_write_cr3(this->VMRegister);
+
+ auto ret = mm_delete_heap(entry->MemoryEntry);
+
+ hal_write_cr3(pd);
+
+ return ret;
+#else
+ Bool ret = mm_delete_heap(ptr.Leak().Leak());
+ return ret;
+#endif
+ }
+
+ entry = entry->MemoryNext;
+ }
+
+ return No;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/KernelKit/XCOFF.h b/dev/Kernel/KernelKit/XCOFF.h
new file mode 100644
index 00000000..2bc45dfa
--- /dev/null
+++ b/dev/Kernel/KernelKit/XCOFF.h
@@ -0,0 +1,51 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: XCOFF.h
+ Purpose: XCOFF for Kernel.
+
+ Revision History:
+
+ 04/07/24: Added file (amlel)
+
+------------------------------------------- */
+
+#ifndef INC_XOCFF_H
+#define INC_XOCFF_H
+
+#include <NewKit/Defines.h>
+
+#define kXCOFF64Magic (0x01F7)
+
+#define kXCOFFRelFlg (0x0001)
+#define kXCOFFExecutable (0x0002)
+#define kXCOFFLnno (0x0004)
+#define kXCOFFLSyms (0x0008)
+
+struct XCoffFileHeader;
+struct XCoffForkHeader;
+
+/// @brief XCoff file header, meant for POWER apps.
+typedef struct XCoffFileHeader
+{
+ Kernel::UInt16 fMagic;
+ Kernel::UInt16 fTarget;
+ Kernel::UInt16 fNumSecs;
+ Kernel::UInt32 fTimeDat;
+ Kernel::UIntPtr fSymPtr;
+ Kernel::UInt32 fNumSyms;
+ Kernel::UInt16 fOptHdr; // ?: Number of bytes in optional header
+} XCoffFileHeader64;
+
+#define cForkNameLen (255)
+
+/// @brief This the executable manifest fork.
+typedef struct XCoffForkHeader
+{
+ Kernel::Char fPropertiesXMLFork[cForkNameLen];
+ Kernel::Char fDynamicLoaderFork[cForkNameLen];
+ Kernel::Char fCodeSignFork[cForkNameLen];
+} XCoffForkHeader;
+
+#endif // ifndef INC_XOCFF_H
diff --git a/dev/Kernel/KernelRsrc.rsrc b/dev/Kernel/KernelRsrc.rsrc
new file mode 100644
index 00000000..4c786c15
--- /dev/null
+++ b/dev/Kernel/KernelRsrc.rsrc
@@ -0,0 +1,25 @@
+#include "CompilerKit/Version.h"
+
+1 VERSIONINFO
+FILEVERSION 1,0,0,0
+PRODUCTVERSION 1,0,0,0
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "080904E4"
+ BEGIN
+ VALUE "CompanyName", "Amlal EL Mahrouss."
+ VALUE "FileDescription", "ZKA Minimal Kernel."
+ VALUE "FileVersion", KERNEL_VERSION
+ VALUE "InternalName", "minoskrnl"
+ VALUE "LegalCopyright", "(c) 2024 Amlal EL Mahrouss, all rights reserved."
+ VALUE "OriginalFilename", "minoskrnl.exe"
+ VALUE "ProductName", "ZKA Minimal Kernel."
+ VALUE "ProductVersion", KERNEL_VERSION
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x809, 1252
+ END
+END
diff --git a/dev/Kernel/MoveAll.ARM64.sh b/dev/Kernel/MoveAll.ARM64.sh
new file mode 100755
index 00000000..35e0909e
--- /dev/null
+++ b/dev/Kernel/MoveAll.ARM64.sh
@@ -0,0 +1,7 @@
+#! /bin/sh
+
+for file in *.o; do
+ mv -- "$file" "${file%.o}.obj"
+done
+
+mv *.obj obj/
diff --git a/dev/Kernel/MoveAll.X64.sh b/dev/Kernel/MoveAll.X64.sh
new file mode 100755
index 00000000..1c135d06
--- /dev/null
+++ b/dev/Kernel/MoveAll.X64.sh
@@ -0,0 +1,7 @@
+#! /bin/sh
+
+for file in *.o; do
+ mv -- "$file" "${file%.o}.obj"
+done
+
+mv *.obj HALKit/AMD64/*.obj obj/
diff --git a/dev/Kernel/NetworkKit/IP.h b/dev/Kernel/NetworkKit/IP.h
new file mode 100644
index 00000000..f04a6bca
--- /dev/null
+++ b/dev/Kernel/NetworkKit/IP.h
@@ -0,0 +1,83 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <KernelKit/DebugOutput.h>
+#include <NewKit/Defines.h>
+#include <NewKit/Ref.h>
+#include <NewKit/KString.h>
+
+namespace Kernel
+{
+ class RawIPAddress6;
+ class RawIPAddress;
+ class IPFactory;
+
+ class RawIPAddress final
+ {
+ private:
+ explicit RawIPAddress(char bytes[4]);
+ ~RawIPAddress() = default;
+
+ RawIPAddress& operator=(const RawIPAddress&) = delete;
+ RawIPAddress(const RawIPAddress&) = default;
+
+ public:
+ char* Address();
+
+ char& operator[](const Size& index);
+
+ bool operator==(const RawIPAddress& ipv6);
+ bool operator!=(const RawIPAddress& ipv6);
+
+ private:
+ char fAddr[4];
+
+ friend IPFactory; // it is the one creating these addresses, thus this
+ // is why the constructors are private.
+ };
+
+ /**
+ * @brief IPv6 address.
+ */
+ class RawIPAddress6 final
+ {
+ private:
+ explicit RawIPAddress6(char Bytes[8]);
+ ~RawIPAddress6() = default;
+
+ RawIPAddress6& operator=(const RawIPAddress6&) = delete;
+ RawIPAddress6(const RawIPAddress6&) = default;
+
+ public:
+ char* Address()
+ {
+ return fAddr;
+ }
+
+ char& operator[](const Size& index);
+
+ bool operator==(const RawIPAddress6& ipv6);
+ bool operator!=(const RawIPAddress6& ipv6);
+
+ private:
+ char fAddr[8];
+
+ friend IPFactory;
+ };
+
+ /**
+ * @brief IP Creation helpers
+ */
+ class IPFactory final
+ {
+ public:
+ static ErrorOr<KString> ToKString(Ref<RawIPAddress6>& ipv6);
+ static ErrorOr<KString> ToKString(Ref<RawIPAddress>& ipv4);
+ static bool IpCheckVersion4(const Char* ip);
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/NetworkKit/IPC.h b/dev/Kernel/NetworkKit/IPC.h
new file mode 100644
index 00000000..a615adc9
--- /dev/null
+++ b/dev/Kernel/NetworkKit/IPC.h
@@ -0,0 +1,106 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved..
+
+ File: IPC.h.
+ Purpose: IPC protocol.
+
+------------------------------------------- */
+
+#ifndef INC_IPC_H
+#define INC_IPC_H
+
+#include <NewKit/Defines.h>
+#include <NewKit/KString.h>
+#include <Hints/CompilerHint.h>
+
+/// @file IPC.h
+/// @brief IPC comm. protocol.
+
+/// IA separator.
+#define kIPCRemoteSeparator ":"
+
+/// Interchange address, consists of PID:TEAM.
+#define kIPCRemoteInvalid "00:00"
+
+#define kIPCHeaderMagic (0x4950434)
+
+namespace Kernel
+{
+ struct IPC_ADDR;
+ struct IPC_MSG;
+
+ /// @brief 128-bit IPC address.
+ struct PACKED IPC_ADDR final
+ {
+ UInt64 UserProcessID;
+ UInt64 UserProcessTeam;
+
+ ////////////////////////////////////
+ // some operators.
+ ////////////////////////////////////
+
+ bool operator==(const IPC_ADDR& addr) noexcept
+ {
+ return addr.UserProcessID == this->UserProcessID && addr.UserProcessTeam == this->UserProcessTeam;
+ }
+
+ bool operator==(IPC_ADDR& addr) noexcept
+ {
+ return addr.UserProcessID == this->UserProcessID && addr.UserProcessTeam == this->UserProcessTeam;
+ }
+ };
+
+ typedef struct IPC_ADDR IPC_ADDR;
+
+ enum
+ {
+ kIPCLittleEndian = 0,
+ kIPCBigEndian = 1,
+ kIPCMixedEndian = 2,
+ };
+
+ constexpr inline auto kIPCMsgSize = 6094U;
+
+ /// @brief IPC connection header, message cannot be greater than 6K.
+ typedef struct IPC_MSG final
+ {
+ UInt32 IpcHeaderMagic; // cRemoteHeaderMagic
+ UInt8 IpcEndianess; // 0 : LE, 1 : BE
+ SizeT IpcPacketSize;
+ IPC_ADDR IpcFrom;
+ IPC_ADDR IpcTo;
+ UInt32 IpcCRC32;
+ UInt32 IpcMsg;
+ UInt32 IpcMsgSz;
+ UInt8 IpcData[kIPCMsgSize];
+
+ /// @brief Passes the message to target, could be anything, HTTP packet, JSON or whatever.
+ Bool Pass(IPC_MSG* target) noexcept
+ {
+ if (target && target->IpcFrom == this->IpcTo)
+ {
+ if (this->IpcMsgSz > target->IpcMsgSz)
+ return No;
+
+ rt_copy_memory(this->IpcData, target->IpcData, this->IpcMsgSz);
+
+ return Yes;
+ }
+
+ return No;
+ }
+ } PACKED IPC_MSG;
+
+ /// @brief Sanitize packet function
+ /// @retval true packet is correct.
+ /// @retval false packet is incorrect and process has crashed.
+ Bool ipc_sanitize_packet(_Input IPC_MSG* pckt_in);
+
+ /// @brief Construct packet function
+ /// @retval true packet is correct.
+ /// @retval false packet is incorrect and process has crashed.
+ Bool ipc_construct_packet(_Output _Input IPC_MSG** pckt_in);
+} // namespace Kernel
+
+#endif // INC_IPC_H
diff --git a/dev/Kernel/NetworkKit/LTE.h b/dev/Kernel/NetworkKit/LTE.h
new file mode 100644
index 00000000..7aa99ec6
--- /dev/null
+++ b/dev/Kernel/NetworkKit/LTE.h
@@ -0,0 +1,16 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved..
+
+ File: LTE.h.
+ Purpose: LTE protocol classes.
+
+------------------------------------------- */
+
+#ifndef _INC_NETWORK_LTE_H_
+#define _INC_NETWORK_LTE_H_
+
+#include <NewKit/Defines.h>
+#include <NewKit/KString.h>
+
+#endif // ifndef _INC_NETWORK_LTE_H_
diff --git a/dev/Kernel/NetworkKit/MAC.h b/dev/Kernel/NetworkKit/MAC.h
new file mode 100644
index 00000000..916e3348
--- /dev/null
+++ b/dev/Kernel/NetworkKit/MAC.h
@@ -0,0 +1,29 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Array.h>
+#include <NewKit/Defines.h>
+#include <NewKit/KString.h>
+
+namespace Kernel
+{
+ class MacAddressGetter;
+
+ /// \brief This retrieves the MAC address of the device.
+ /// \note Listens for the current NIC.
+ class MacAddressGetter final
+ {
+ public:
+ explicit MacAddressGetter() = default;
+
+ public:
+ KString& AsString();
+ Array<WideChar, 12>& AsBytes();
+ };
+
+} // namespace Kernel
diff --git a/dev/Kernel/NetworkKit/NetworkDevice.h b/dev/Kernel/NetworkKit/NetworkDevice.h
new file mode 100644
index 00000000..c55c2f37
--- /dev/null
+++ b/dev/Kernel/NetworkKit/NetworkDevice.h
@@ -0,0 +1,83 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifndef __INC_NETWORK_DEVICE_H__
+#define __INC_NETWORK_DEVICE_H__
+
+#include <KernelKit/DeviceMgr.h>
+#include <NetworkKit/IP.h>
+
+/// @note Can either work with: Ethernet, GPRS, WiFi
+
+namespace Kernel
+{
+ struct NetworkDeviceCommand;
+ class NetworkDevice;
+
+ /**
+ * \brief Network device interface, establishes a connection to the NIC.
+ */
+ class NetworkDevice final : public IDeviceObject<NetworkDeviceCommand>
+ {
+ public:
+ NetworkDevice(void (*out)(NetworkDeviceCommand),
+ void (*in)(NetworkDeviceCommand),
+ void (*onCleanup)(void) = nullptr);
+
+ ~NetworkDevice() override;
+
+ public:
+ NetworkDevice& operator=(const NetworkDevice&) = default;
+ NetworkDevice(const NetworkDevice&) = default;
+
+ public:
+ const Char* Name() const override;
+ Boolean Name(const Char* newStr);
+
+ private:
+ static constexpr auto cNetworkNameLen = 512;
+
+ Void (*fCleanup)(void);
+ Char fNetworkName[cNetworkNameLen];
+ };
+
+ struct NetworkDeviceCommand final
+ {
+ UInt32 CommandName;
+ UInt32 CommandType;
+ UInt32 CommandFlags;
+ VoidPtr CommandBuffer;
+ SizeT CommandSizeBuffer;
+ };
+
+ /// @brief TCP device.
+ using TCPNetworkDevice = NetworkDevice;
+
+ /// @brief UDP device.
+ using UDPNetworkDevice = NetworkDevice;
+
+ /// @brief PPP device.
+ using PPPNetworkDevice = NetworkDevice;
+
+ /// @brief IPC device.
+ using IPCNetworkDevice = NetworkDevice;
+
+ /// @brief GRPS device.
+ using GPRSNetworkDevice = NetworkDevice;
+
+ /// @brief GSM device.
+ using GSMNetworkDevice = NetworkDevice;
+
+ /// @brief Bluetooth device.
+ using BTNetworkDevice = NetworkDevice;
+
+ /// @brief LTE device.
+ using LTENetworkDevice = NetworkDevice;
+} // namespace Kernel
+
+#include <NetworkKit/NetworkDevice.inl>
+
+#endif // !__INC_NETWORK_DEVICE_H__
diff --git a/dev/Kernel/NetworkKit/NetworkDevice.inl b/dev/Kernel/NetworkKit/NetworkDevice.inl
new file mode 100644
index 00000000..8d6bf6cb
--- /dev/null
+++ b/dev/Kernel/NetworkKit/NetworkDevice.inl
@@ -0,0 +1,32 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+/***
+ Dtor and ctors.
+*/
+
+namespace Kernel
+{
+ NetworkDevice::NetworkDevice(void (*out)(NetworkDeviceCommand),
+ void (*in)(NetworkDeviceCommand),
+ void (*on_cleanup)(void))
+ : IDeviceObject<NetworkDeviceCommand>(out, in), fCleanup(on_cleanup)
+ {
+ kcout << "NetworkDevice initialized.\r";
+
+ MUST_PASS(out && in && on_cleanup);
+ }
+
+ NetworkDevice::~NetworkDevice()
+ {
+ MUST_PASS(fCleanup);
+
+ kcout << "NetworkDevice cleanup.\r";
+
+ if (fCleanup)
+ fCleanup();
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/NewKit/Array.h b/dev/Kernel/NewKit/Array.h
new file mode 100644
index 00000000..c8ac6f55
--- /dev/null
+++ b/dev/Kernel/NewKit/Array.h
@@ -0,0 +1,58 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <KernelKit/DebugOutput.h>
+#include <NewKit/ErrorOr.h>
+#include <NewKit/Defines.h>
+
+namespace Kernel
+{
+ template <typename T, SizeT N>
+ class Array final
+ {
+ public:
+ explicit Array() = default;
+ ~Array() = default;
+
+ Array& operator=(const Array&) = default;
+ Array(const Array&) = default;
+
+ T& operator[](const SizeT& at)
+ {
+ return fArray[at];
+ }
+
+ Boolean Empty()
+ {
+ return this->Count() > 0;
+ }
+
+ const SizeT Capacity()
+ {
+ return N;
+ }
+
+ const SizeT Count()
+ {
+ return N;
+ }
+
+ const T* CData()
+ {
+ return fArray;
+ }
+
+ operator bool()
+ {
+ return !Empty();
+ }
+
+ private:
+ T fArray[N];
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/NewKit/ArrayList.h b/dev/Kernel/NewKit/ArrayList.h
new file mode 100644
index 00000000..29ef946a
--- /dev/null
+++ b/dev/Kernel/NewKit/ArrayList.h
@@ -0,0 +1,58 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+namespace Kernel
+{
+ template <typename T>
+ class ArrayList final
+ {
+ public:
+ explicit ArrayList(T* list)
+ : fList(reinterpret_cast<T>(list))
+ {
+ }
+
+ ~ArrayList() = default;
+
+ ArrayList& operator=(const ArrayList&) = default;
+ ArrayList(const ArrayList&) = default;
+
+ T* Data()
+ {
+ return fList;
+ }
+
+ const T* CData()
+ {
+ return fList;
+ }
+
+ T& operator[](int index) const
+ {
+ return fList[index];
+ }
+
+ operator bool()
+ {
+ return fList;
+ }
+
+ private:
+ T* fList;
+
+ friend class InitHelpers;
+ };
+
+ template <typename ValueType>
+ ArrayList<ValueType> make_list(ValueType val)
+ {
+ return ArrayList<ValueType>{val};
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/NewKit/Atom.h b/dev/Kernel/NewKit/Atom.h
new file mode 100644
index 00000000..1a13315a
--- /dev/null
+++ b/dev/Kernel/NewKit/Atom.h
@@ -0,0 +1,46 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+#pragma once
+
+#include <NewKit/Defines.h>
+
+namespace Kernel
+{
+ template <typename T>
+ class Atom final
+ {
+ public:
+ explicit Atom() = default;
+ ~Atom() = default;
+
+ public:
+ Atom& operator=(const Atom&) = delete;
+ Atom(const Atom&) = delete;
+
+ public:
+ T operator[](Size sz)
+ {
+ return (fArrayOfAtoms & sz);
+ }
+ void operator|(Size sz)
+ {
+ fArrayOfAtoms |= sz;
+ }
+
+ friend Boolean operator==(Atom<T>& atomic, const T& idx)
+ {
+ return atomic[idx] == idx;
+ }
+
+ friend Boolean operator!=(Atom<T>& atomic, const T& idx)
+ {
+ return atomic[idx] == idx;
+ }
+
+ private:
+ T fArrayOfAtoms;
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/NewKit/Crc32.h b/dev/Kernel/NewKit/Crc32.h
new file mode 100644
index 00000000..8a8222e5
--- /dev/null
+++ b/dev/Kernel/NewKit/Crc32.h
@@ -0,0 +1,23 @@
+/*
+ * ========================================================
+ *
+ * ZKA
+ * Date Added: 13/02/2023
+ * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+ *
+ * ========================================================
+ */
+
+#ifndef CRC32_H
+#define CRC32_H
+
+#include <NewKit/Defines.h>
+
+#define kCrcCnt (256)
+
+namespace Kernel
+{
+ UInt ke_calculate_crc32(const Char* crc, UInt len) noexcept;
+} // namespace Kernel
+
+#endif // !CRC32_H
diff --git a/dev/Kernel/NewKit/CxxAbi.h b/dev/Kernel/NewKit/CxxAbi.h
new file mode 100644
index 00000000..1eec5891
--- /dev/null
+++ b/dev/Kernel/NewKit/CxxAbi.h
@@ -0,0 +1,28 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+#pragma once
+
+#include <NewKit/Defines.h>
+
+#ifndef __TOOLCHAINKIT__
+
+#define kAtExitMacDestructors (128)
+
+struct atexit_func_entry_t
+{
+ void (*destructor_func)(void*);
+ void* obj_ptr;
+ void* dso_handle;
+};
+
+typedef unsigned uarch_t;
+
+namespace cxxabiv1
+{
+ typedef void* __guard;
+}
+
+#endif // __GNUC__
diff --git a/dev/Kernel/NewKit/Defines.h b/dev/Kernel/NewKit/Defines.h
new file mode 100644
index 00000000..a221bdad
--- /dev/null
+++ b/dev/Kernel/NewKit/Defines.h
@@ -0,0 +1,188 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Macros.h>
+
+#define NEWKIT_VERSION_STR "1.1.0"
+#define NEWKIT_VERSION_BCD 0x01100
+
+#ifdef __has_feature
+#if !__has_feature(cxx_nullptr)
+#if !__has_nullptr
+#error !!! You must at least have nullptr featured on your C++ compiler. !!!
+#endif
+#endif
+#endif
+
+/// @brief The **Kernel** namespace where it's API resides.
+namespace Kernel
+{
+ using voidPtr = void*;
+ using VoidPtr = void*;
+ using nullPtr = decltype(nullptr);
+ using NullPtr = decltype(nullptr);
+
+ using Int = int;
+ using Int32 = int;
+ using UShort = unsigned short;
+ using UInt16 = unsigned short;
+ using Short = short;
+ using Int16 = short;
+ using UInt = unsigned int;
+ using UInt32 = unsigned int;
+ using Long = __INT64_TYPE__;
+ using Int64 = __INT64_TYPE__;
+ using ULong = __UINT64_TYPE__;
+ using UInt64 = __UINT64_TYPE__;
+ using Boolean = bool;
+ using Bool = bool;
+ using Char = char;
+ using UChar = unsigned char;
+ using UInt8 = unsigned char;
+
+ using SSize = Int64;
+ using SSizeT = Int64;
+ using Size = __SIZE_TYPE__;
+ using SizeT = __SIZE_TYPE__;
+ using IntPtr = __INTPTR_TYPE__;
+ using UIntPtr = __UINTPTR_TYPE__;
+ using IntFast = __INT_FAST32_TYPE__;
+ using IntFast64 = __INT_FAST64_TYPE__;
+ using PtrDiff = __PTRDIFF_TYPE__;
+
+ using SInt16 = Int16;
+ using SInt32 = Int32;
+ using SInt64 = Int64;
+
+ typedef UIntPtr* Ptr64;
+ typedef UInt32* Ptr32;
+ typedef UInt8* Ptr8;
+
+ using Utf8Char = char8_t;
+ using Utf16Char = char16_t;
+ using WideChar = wchar_t;
+ using Utf32Char = char32_t;
+
+ typedef UInt32 PhysicalAddressKind;
+ typedef UIntPtr VirtualAddressKind;
+
+ using Void = void;
+
+ using Lba = UInt64;
+
+ using Char16 = char16_t;
+
+ enum class Endian : UInt8
+ {
+ kEndianInvalid,
+ kEndianBig,
+ kEndianLittle,
+ kEndianMixed,
+ kEndianCount
+ };
+
+ /// @brief Forward object.
+ /// @tparam Args the object type.
+ /// @param arg the object.
+ /// @return object's rvalue
+ template <typename Args>
+ inline Args&& forward(Args& arg)
+ {
+ return static_cast<Args&&>(arg);
+ }
+
+ /// @brief Move object.
+ /// @tparam Args the object type.
+ /// @param arg the object.
+ /// @return object's rvalue
+ template <typename Args>
+ inline Args&& move(Args&& arg)
+ {
+ return static_cast<Args&&>(arg);
+ }
+
+ /// @brief Encoding interface, used as a proxy to convert T to Char*
+ /// Used to cast A to B or B to A.
+ class ICodec
+ {
+ public:
+ explicit ICodec() = default;
+ virtual ~ICodec() = default;
+
+ ICodec& operator=(const ICodec&) = default;
+ ICodec(const ICodec&) = default;
+
+ public:
+ /// @brief Convert type to bytes.
+ /// @tparam T the type.
+ /// @param type (a1) the data.
+ /// @return a1 as Char*
+ template <typename T>
+ Char* AsBytes(T type) noexcept
+ {
+ return nullptr;
+ }
+
+ /// @brief Construct from type to class.
+ /// @tparam T the type to convert.
+ /// @param type (a1) the data.
+ /// @return a1 as Char*
+ template <typename OutputClass, typename FactoryClass>
+ OutputClass* Construct(Char* type) noexcept
+ {
+ FactoryClass class_fac;
+ return class_fac.template From<OutputClass>(type);
+ }
+
+ /// @brief Convert T class to Y class.
+ /// @tparam T the class type of type.
+ /// @tparam Y the result class.
+ /// @param type the class to cast.
+ /// @return the class as Y.
+ template <typename T, typename Y>
+ Y As(T type) noexcept
+ {
+ if (type.template IsSerializable())
+ {
+ return reinterpret_cast<Char*>(type);
+ }
+
+ return type.template As<Y>();
+ }
+ };
+
+ /// \brief Scheduler interface, represents a scheduler object.
+ /// @note This is used to schedule tasks, such as threads, drivers, user threads, etc.
+ class ISchedulable
+ {
+ public:
+ explicit ISchedulable() = default;
+ virtual ~ISchedulable() = default;
+
+ ISchedulable& operator=(const ISchedulable&) = default;
+ ISchedulable(const ISchedulable&) = default;
+
+ /// @brief Is this object only accepting user tasks?
+ virtual const Bool IsUser()
+ {
+ return NO;
+ }
+
+ /// @brief Is this object only accepting kernel tasks?
+ virtual const Bool IsKernel()
+ {
+ return NO;
+ }
+
+ /// @brief Is this object offloading to another CPU?
+ virtual const Bool HasMP()
+ {
+ return NO;
+ }
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/NewKit/ErrorOr.h b/dev/Kernel/NewKit/ErrorOr.h
new file mode 100644
index 00000000..958bf739
--- /dev/null
+++ b/dev/Kernel/NewKit/ErrorOr.h
@@ -0,0 +1,77 @@
+/*
+ * ========================================================
+ *
+ * ZKA
+ * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+ *
+ * ========================================================
+ */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+#include <NewKit/Ref.h>
+
+namespace Kernel
+{
+ using ErrorT = UInt;
+
+ template <typename T>
+ class ErrorOr final
+ {
+ public:
+ ErrorOr() = default;
+ ~ErrorOr() = default;
+
+ public:
+ explicit ErrorOr(Int32 err)
+ : mId(err)
+ {
+ }
+
+ explicit ErrorOr(nullPtr Null)
+ {
+ }
+
+ explicit ErrorOr(T* Class)
+ : mRef(Class)
+ {
+ }
+
+ explicit ErrorOr(T Class)
+ : mRef(Class)
+ {
+ }
+
+ ErrorOr& operator=(const ErrorOr&) = default;
+ ErrorOr(const ErrorOr&) = default;
+
+ ErrorOr& operator=(const Ref<T>& refErr)
+ {
+ mRef = refErr;
+ return *this;
+ }
+
+ Ref<T>& Leak()
+ {
+ return mRef;
+ }
+
+ Int32 Error()
+ {
+ return mId;
+ }
+
+ operator bool()
+ {
+ return mRef;
+ }
+
+ private:
+ Ref<T> mRef;
+ Int32 mId{0};
+ };
+
+ using ErrorOrAny = ErrorOr<voidPtr>;
+
+} // namespace Kernel
diff --git a/dev/Kernel/NewKit/Function.h b/dev/Kernel/NewKit/Function.h
new file mode 100644
index 00000000..9fa218af
--- /dev/null
+++ b/dev/Kernel/NewKit/Function.h
@@ -0,0 +1,53 @@
+#ifndef _INC_FUNCTION_H__
+#define _INC_FUNCTION_H__
+
+#include <NewKit/Defines.h>
+
+namespace Kernel
+{
+ template <typename T, typename... Args>
+ class Function final
+ {
+ public:
+ Function() = default;
+
+ public:
+ explicit Function(T (*Fn)(Args... args))
+ : fFn(Fn)
+ {
+ }
+
+ ~Function() = default;
+
+ Function& operator=(const Function&) = default;
+ Function(const Function&) = default;
+
+ template <typename... XArgs>
+ T operator()(Args... args)
+ {
+ return fFn(args...);
+ }
+
+ template <typename... XArgs>
+ T Call(Args... args)
+ {
+ return fFn(args...);
+ }
+
+ operator bool()
+ {
+ return fFn;
+ }
+
+ bool operator!()
+ {
+ return !fFn;
+ }
+
+ private:
+ T(*fFn)
+ (Args... args);
+ };
+} // namespace Kernel
+
+#endif // !_INC_FUNCTION_H__
diff --git a/dev/Kernel/NewKit/Json.h b/dev/Kernel/NewKit/Json.h
new file mode 100644
index 00000000..250bc716
--- /dev/null
+++ b/dev/Kernel/NewKit/Json.h
@@ -0,0 +1,151 @@
+
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+// last-rev: 30/01/24
+
+#include <CompilerKit/CompilerKit.h>
+#include <NewKit/Defines.h>
+#include <NewKit/Stream.h>
+#include <NewKit/KString.h>
+#include <NewKit/Utils.h>
+
+#define kMaxJsonPath 4096
+#define kJSONLen 32
+#define kJSONNull "null"
+
+namespace Kernel
+{
+ /// @brief Json class
+ class JSON final
+ {
+ public:
+ explicit JSON()
+ {
+ auto len = kJSONLen;
+ KString key = KString(len);
+ key += kJSONNull;
+
+ this->AsKey() = key;
+ this->AsValue() = key;
+ }
+
+ explicit JSON(SizeT lhsLen, SizeT rhsLen)
+ : fKey(lhsLen), fValue(rhsLen)
+ {
+ }
+
+ ~JSON() = default;
+
+ ZKA_COPY_DEFAULT(JSON);
+
+ const Bool& IsUndefined()
+ {
+ return fUndefined;
+ }
+
+ private:
+ Bool fUndefined; // is this instance undefined?
+ KString fKey;
+ KString fValue;
+
+ public:
+ /// @brief returns the key of the json
+ /// @return the key as string view.
+ KString& AsKey()
+ {
+ return fKey;
+ }
+
+ /// @brief returns the value of the json.
+ /// @return the key as string view.
+ KString& AsValue()
+ {
+ return fValue;
+ }
+
+ static JSON kNull;
+ };
+
+ /// @brief Json stream reader helper.
+ struct JsonStreamReader final
+ {
+ STATIC JSON In(const Char* full_array)
+ {
+ auto start_val = '{';
+ auto end_val = '}';
+ Boolean probe_value = false;
+
+ if (full_array[0] != start_val)
+ {
+ if (full_array[0] != '[')
+ return JSON::kNull;
+
+ start_val = '[';
+ end_val = ']';
+
+ probe_value = true;
+ }
+
+ SizeT len = rt_string_len(full_array);
+
+ SizeT key_len = 0;
+ SizeT value_len = 0;
+
+ JSON type(kMaxJsonPath, kMaxJsonPath);
+
+ for (SizeT i = 1; i < len; ++i)
+ {
+ if (full_array[i] == '\r' ||
+ full_array[i] == '\n')
+ continue;
+
+ if (probe_value)
+ {
+ if (full_array[i] == end_val ||
+ full_array[i] == ',')
+ {
+ probe_value = false;
+
+ ++value_len;
+ }
+ else
+ {
+ type.AsValue().Data()[value_len] = full_array[i];
+
+ ++value_len;
+ }
+ }
+ else
+ {
+ if (start_val == '[')
+ continue;
+
+ if (full_array[i] == ':')
+ {
+ probe_value = true;
+ type.AsKey().Data()[key_len] = 0;
+ ++key_len;
+ }
+ else
+ {
+ type.AsKey().Data()[key_len] = full_array[i];
+
+ ++key_len;
+ }
+ }
+ }
+
+ type.AsValue().Data()[value_len] = 0;
+
+ return type;
+ }
+ };
+
+ using JsonStream = Stream<JsonStreamReader, JSON>;
+} // namespace Kernel
diff --git a/dev/Kernel/NewKit/KString.h b/dev/Kernel/NewKit/KString.h
new file mode 100644
index 00000000..350623d7
--- /dev/null
+++ b/dev/Kernel/NewKit/KString.h
@@ -0,0 +1,94 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <NewKit/Defines.h>
+#include <NewKit/ErrorOr.h>
+#include <NewKit/Utils.h>
+#include <NewKit/KernelPanic.h>
+
+#define cMinimumStringSize 8196
+
+namespace Kernel
+{
+ /// @brief KString static string class.
+ class KString final
+ {
+ public:
+ explicit KString()
+ {
+ fDataSz = cMinimumStringSize;
+
+ fData = new Char[fDataSz];
+ MUST_PASS(fData);
+
+ rt_set_memory(fData, 0, fDataSz);
+ }
+
+ explicit KString(const SizeT& Sz)
+ : fDataSz(Sz)
+ {
+ MUST_PASS(Sz > 1);
+
+ fData = new Char[Sz];
+ MUST_PASS(fData);
+
+ rt_set_memory(fData, 0, Sz);
+ }
+
+ ~KString()
+ {
+ if (fData)
+ {
+ delete[] fData;
+ fData = nullptr;
+ }
+ }
+
+ ZKA_COPY_DEFAULT(KString);
+
+ Char* Data();
+ const Char* CData() const;
+ Size Length() const;
+
+ bool operator==(const Char* rhs) const;
+ bool operator!=(const Char* rhs) const;
+
+ bool operator==(const KString& rhs) const;
+ bool operator!=(const KString& rhs) const;
+
+ KString& operator+=(const Char* rhs);
+ KString& operator+=(const KString& rhs);
+
+ operator bool()
+ {
+ return fData;
+ }
+
+ bool operator!()
+ {
+ return fData;
+ }
+
+ private:
+ Char* fData{nullptr};
+ Size fDataSz{0};
+ Size fCur{0};
+
+ friend class StringBuilder;
+ };
+
+ struct StringBuilder final
+ {
+ static ErrorOr<KString> Construct(const Char* data);
+ static const Char* FromBool(const Char* fmt, bool n);
+ static const Char* Format(const Char* fmt, const Char* from);
+ static bool Equals(const Char* lhs, const Char* rhs);
+ static bool Equals(const WideChar* lhs, const WideChar* rhs);
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/NewKit/KernelPanic.h b/dev/Kernel/NewKit/KernelPanic.h
new file mode 100644
index 00000000..9255d9cc
--- /dev/null
+++ b/dev/Kernel/NewKit/KernelPanic.h
@@ -0,0 +1,64 @@
+
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+namespace Kernel
+{
+ void ke_runtime_check(bool expr, const Char* file, const Char* line);
+}
+
+#define MUST_PASS_COMPILER(EXPR, MSG) static_assert(EXPR, MSG)
+
+#define __MUST_PASS(EXPR, FILE, LINE) \
+ Kernel::ke_runtime_check(EXPR, FILE, STRINGIFY(LINE))
+
+#ifdef __DEBUG__
+#define MUST_PASS(EXPR) __MUST_PASS((EXPR), __FILE__, __LINE__)
+#define assert(EXPR) MUST_PASS(EXPR, RUNTIME_CHECK_EXPRESSION)
+#else
+#define MUST_PASS(EXPR) (Kernel::Void)(EXPR)
+#define assert(EXPR) (Kernel::Void)(EXPR)
+#endif
+
+enum RUNTIME_CHECK
+{
+ RUNTIME_CHECK_FAILED = 1111,
+ RUNTIME_CHECK_POINTER,
+ RUNTIME_CHECK_EXPRESSION,
+ RUNTIME_CHECK_FILE,
+ RUNTIME_CHECK_IPC,
+ RUNTIME_CHECK_TLS,
+ RUNTIME_CHECK_HANDSHAKE,
+ RUNTIME_CHECK_ACPI,
+ RUNTIME_CHECK_INVALID_PRIVILEGE,
+ RUNTIME_CHECK_PROCESS,
+ RUNTIME_CHECK_BAD_BEHAVIOR,
+ RUNTIME_CHECK_BOOTSTRAP,
+ RUNTIME_CHECK_UNEXCPECTED,
+ RUNTIME_CHECK_FILESYSTEM,
+ RUNTIME_CHECK_VIRTUAL_OUT_OF_MEM,
+ RUNTIME_CHECK_PAGE,
+ RUNTIME_CHECK_COUNT,
+};
+
+namespace Kernel
+{
+ void ke_panic(const Int32& id, const Char* message = nullptr);
+} // namespace Kernel
+
+#ifdef TRY
+#undef TRY
+#endif
+
+#define TRY(FN) \
+ if (!FN()) \
+ { \
+ MUST_PASS(false); \
+ }
diff --git a/dev/Kernel/NewKit/Macros.h b/dev/Kernel/NewKit/Macros.h
new file mode 100644
index 00000000..f2a92b68
--- /dev/null
+++ b/dev/Kernel/NewKit/Macros.h
@@ -0,0 +1,149 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#ifndef KIB
+#define KIB(X) (Kernel::UInt64)((X) / 1024)
+#endif
+
+#ifndef kib_cast
+#define kib_cast(X) (Kernel::UInt64)((X) * 1024)
+#endif
+
+#ifndef MIB
+#define MIB(X) (Kernel::UInt64)((Kernel::UInt64)KIB(X) / 1024)
+#endif
+
+#ifndef mib_cast
+#define mib_cast(X) (Kernel::UInt64)((Kernel::UInt64)kib_cast(X) * 1024)
+#endif
+
+#ifndef GIB
+#define GIB(X) (Kernel::UInt64)((Kernel::UInt64)MIB(X) / 1024)
+#endif
+
+#ifndef gib_cast
+#define gib_cast(X) (Kernel::UInt64)((Kernel::UInt64)mib_cast(X) * 1024)
+#endif
+
+#ifndef TIB
+#define TIB(X) (Kernel::UInt64)((Kernel::UInt64)GIB(X) / 1024)
+#endif
+
+#ifndef tib_cast
+#define tib_cast(X) ((Kernel::UInt64)gib_cast(X) * 1024)
+#endif
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(a) \
+ (((sizeof(a) / sizeof(*(a))) / \
+ (static_cast<Kernel::Size>(!(sizeof(a) % sizeof(*(a)))))))
+#endif
+
+#define DEPRECATED ATTRIBUTE(deprecated)
+
+#ifndef ALIGN
+#define ALIGN(X) __attribute__((aligned(X)))
+#endif // #ifndef ALIGN
+
+#ifndef ATTRIBUTE
+#define ATTRIBUTE(X) __attribute__((X))
+#endif // #ifndef ATTRIBUTE
+
+#ifndef __ZKA_VER__
+#define __ZKA_VER__ (2024)
+#endif // !__ZKA_VER__
+
+#ifndef EXTERN
+#define EXTERN extern
+#endif
+
+#ifndef EXTERN_C
+#define EXTERN_C extern "C"
+#endif
+
+#ifndef MAKE_ENUM
+#define MAKE_ENUM(NAME) \
+ enum NAME \
+ {
+#endif
+
+#ifndef END_ENUM
+#define END_ENUM() \
+ } \
+ ;
+#endif
+
+#ifndef MAKE_STRING_ENUM
+#define MAKE_STRING_ENUM(NAME) \
+ namespace NAME \
+ {
+#endif
+
+#ifndef ENUM_STRING
+#define ENUM_STRING(NAME, VAL) inline constexpr const char* e##NAME = VAL
+#endif
+
+#ifndef END_STRING_ENUM
+#define END_STRING_ENUM() }
+#endif
+
+#ifndef rtl_alloca
+#define rtl_alloca(sz) __builtin_alloca(sz)
+#endif // #ifndef rtl_alloca
+
+#ifndef CANT_REACH
+#define CANT_REACH() __builtin_unreachable()
+#endif
+
+#define kInvalidAddress 0xFBFBFBFBFBFBFBFB
+#define kBadAddress 0x0000000000000000
+#define kMaxAddr 0xFFFFFFFFFFFFFFFF
+#define kPathLen 0x100
+
+#define PACKED ATTRIBUTE(packed)
+#define NO_EXEC ATTRIBUTE(noexec)
+
+#define EXTERN extern
+#define STATIC static
+
+#define CONST const
+
+#define STRINGIFY(X) #X
+#define ZKA_UNUSED(X) ((Kernel::Void)X)
+
+#ifndef RGB
+#define RGB(R, G, B) (Kernel::UInt32)(R | G << 0x8 | B << 0x10)
+#endif // !RGB
+
+#ifdef __ZKA_AMD64__
+#define dbg_break_point() asm volatile("int $3")
+#else
+#define dbg_break_point() ((void)0)
+#endif
+
+#define rtl_deduce_endianess(address, value) \
+ (((reinterpret_cast<Kernel::Char*>(address)[0]) == (value)) \
+ ? (Kernel::Endian::kEndianBig) \
+ : (Kernel::Endian::kEndianLittle))
+
+#define Yes true
+#define No false
+
+#define YES true
+#define NO false
+
+#define TRUE true
+#define FALSE false
+
+#define BOOL Kernel::Boolean
+
+#ifdef RTL_INIT_OBJECT
+#undef RTL_INIT_OBJECT
+#endif // ifdef RTL_INIT_OBJECT
+
+#define RTL_INIT_OBJECT(OBJ, TYPE, ...) TYPE OBJ = TYPE(__VA_ARGS__)
diff --git a/dev/Kernel/NewKit/MutableArray.h b/dev/Kernel/NewKit/MutableArray.h
new file mode 100644
index 00000000..36159212
--- /dev/null
+++ b/dev/Kernel/NewKit/MutableArray.h
@@ -0,0 +1,239 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+#pragma once
+
+#include <CompilerKit/CompilerKit.h>
+#include <NewKit/Array.h>
+#include <NewKit/Defines.h>
+
+#define TRY_FIND_NODE(NAME, NODE) \
+ auto* NAME = NODE; \
+ while (NAME) \
+ { \
+ if (NAME->fIndex == Index) \
+ return NAME->fVal; \
+ NAME = NAME->fNext; \
+ }
+
+#define TRY_FIND_NODE2(NAME, NODE) \
+ auto* NAME = NODE; \
+ while (NAME) \
+ { \
+ if (NAME->fIndex == Index) \
+ return Ref<T>{NAME->fVal}; \
+ NAME = NAME->fNext; \
+ }
+
+#define TRY_REMOVE_NODE(NODE) \
+ if (NODE && NODE->fIndex == Index) \
+ { \
+ NODE->fUsed = false; \
+ NODE->fIndex = 0; \
+ \
+ return true; \
+ }
+
+// FIXME: this is a shitty algorithm, which is consumer hungry.
+// Remove and occurences of that, and remove that class.
+namespace Kernel
+{
+ template <typename T>
+ class MutableArray;
+
+ template <typename T, T _PlaceHolderValue>
+ class NullableMutableArray;
+
+ template <typename T>
+ class MutableLinkedList
+ {
+ public:
+ T fVal;
+ SizeT fIndex{0};
+ Boolean fUsed{false};
+
+ MutableLinkedList* fPrev{nullptr};
+ MutableLinkedList* fNext{nullptr};
+ };
+
+ template <typename T, T _PlaceHolderValue>
+ class NullableMutableArray
+ {
+ public:
+ // explicit this.
+ explicit NullableMutableArray()
+ : fFirstNode(new MutableLinkedList<T>())
+ {
+ }
+
+ /*
+ * We free all the nodes allocated by the array
+ * and store the next one inside "NextIt"
+ */
+
+ virtual ~NullableMutableArray()
+ {
+ auto* It = fFirstNode;
+ MutableLinkedList<T>* NextIt = nullptr;
+
+ while (It)
+ {
+ NextIt = It->fNext;
+ delete It;
+
+ It = NextIt;
+ }
+ }
+
+ NullableMutableArray& operator=(const NullableMutableArray&) = default;
+ NullableMutableArray(const NullableMutableArray&) = default;
+
+ operator bool()
+ {
+ return Count() > 1;
+ }
+
+ public:
+ T operator[](const SizeT& Index) const
+ {
+ TRY_FIND_NODE(first, fFirstNode);
+ TRY_FIND_NODE(last, fLastNode);
+
+ return _PlaceHolderValue;
+ }
+
+ SizeT Count() const
+ {
+ return fNodeCount;
+ }
+
+ public:
+ Boolean Remove(const SizeT& Index)
+ {
+ TRY_REMOVE_NODE(fFirstNode);
+ TRY_REMOVE_NODE(fLastNode);
+
+ return false;
+ }
+
+ Boolean Add(const T val)
+ {
+ auto* iterationNode = fFirstNode;
+ MUST_PASS(iterationNode);
+
+ while (iterationNode)
+ {
+ if (!iterationNode->fUsed)
+ {
+ iterationNode->fVal = val;
+ iterationNode->fIndex = 0;
+
+ iterationNode->fUsed = true;
+
+ ++fNodeCount;
+
+ return true;
+ }
+
+ iterationNode = iterationNode->fNext;
+ }
+
+ return false;
+ }
+
+ private:
+ /* Avoid useless lookups */
+ MutableLinkedList<T>* fLastNode{nullptr};
+ MutableLinkedList<T>* fFirstNode{nullptr};
+
+ /* Number of nodes inside of this dynamic array. */
+ Kernel::SizeT fNodeCount{0};
+
+ private:
+ // don't remove that
+ friend MutableArray<T>;
+ };
+
+ template <typename T>
+ class MutableArray : public NullableMutableArray<voidPtr, nullptr>
+ {
+ public:
+ // explicit this.
+ explicit MutableArray() = default;
+ virtual ~MutableArray() = default;
+
+ ZKA_COPY_DEFAULT(MutableArray)
+
+ public:
+ Boolean Add(const T val)
+ {
+ auto* iterationNode = fFirstNode;
+
+ if (!iterationNode)
+ {
+ fFirstNode = new MutableLinkedList<T>();
+ iterationNode = fFirstNode;
+ }
+
+ MUST_PASS(iterationNode);
+
+ while (iterationNode)
+ {
+ if (!iterationNode->fUsed)
+ {
+ iterationNode->fVal = val;
+ iterationNode->fIndex = 0;
+
+ iterationNode->fUsed = true;
+
+ ++fNodeCount;
+
+ return true;
+ }
+
+ iterationNode = iterationNode->fNext;
+ }
+
+ return false;
+ }
+
+ public:
+ Ref<T> operator[](const SizeT& Index) const
+ {
+ TRY_FIND_NODE2(first, fFirstNode);
+ TRY_FIND_NODE2(last, fLastNode);
+
+ return {};
+ }
+
+ SizeT Count() const
+ {
+ return fNodeCount;
+ }
+
+ bool Contains(T& value) noexcept
+ {
+ MutableLinkedList<T>* first = fFirstNode;
+
+ while (first)
+ {
+ if (first->fVal == value && first->fUsed)
+ return true;
+
+ first = first->fNext;
+ }
+
+ return false;
+ }
+
+ private:
+ /* Avoid useless lookups */
+ MutableLinkedList<T>* fLastNode{nullptr};
+ MutableLinkedList<T>* fFirstNode{nullptr};
+
+ /* Number of nodes inside of this dynamic array. */
+ Kernel::SizeT fNodeCount{0};
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/NewKit/New.h b/dev/Kernel/NewKit/New.h
new file mode 100644
index 00000000..989f72e2
--- /dev/null
+++ b/dev/Kernel/NewKit/New.h
@@ -0,0 +1,20 @@
+
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <KernelKit/Heap.h>
+
+/// @note compatible with tk too.
+typedef __SIZE_TYPE__ size_t;
+
+void* operator new(size_t ptr);
+void* operator new[](size_t ptr);
+
+void operator delete(void* ptr);
+void operator delete(void* ptr, unsigned long);
+void operator delete[](void* ptr);
diff --git a/dev/Kernel/NewKit/NewKit.h b/dev/Kernel/NewKit/NewKit.h
new file mode 100644
index 00000000..0b4eb00b
--- /dev/null
+++ b/dev/Kernel/NewKit/NewKit.h
@@ -0,0 +1,20 @@
+
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Array.h>
+#include <NewKit/ArrayList.h>
+#include <NewKit/ErrorOr.h>
+#include <NewKit/Json.h>
+#include <NewKit/KernelPanic.h>
+#include <NewKit/MutableArray.h>
+#include <NewKit/New.h>
+#include <NewKit/OwnPtr.h>
+#include <NewKit/Ref.h>
+#include <NewKit/Stream.h>
+#include <NewKit/Utils.h>
diff --git a/dev/Kernel/NewKit/OwnPtr.h b/dev/Kernel/NewKit/OwnPtr.h
new file mode 100644
index 00000000..7e0c6ef9
--- /dev/null
+++ b/dev/Kernel/NewKit/OwnPtr.h
@@ -0,0 +1,94 @@
+
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+#include <NewKit/KernelPanic.h>
+#include <NewKit/Ref.h>
+
+namespace Kernel
+{
+ template <typename T>
+ class OwnPtr;
+
+ template <typename T>
+ class NonNullRefPtr;
+
+ template <typename T>
+ class OwnPtr final
+ {
+ public:
+ OwnPtr()
+ {
+ }
+ ~OwnPtr()
+ {
+ this->Delete();
+ }
+
+ OwnPtr& operator=(const OwnPtr&) = default;
+ OwnPtr(const OwnPtr&) = default;
+
+ public:
+ template <typename... Args>
+ bool New(Args&&... arg)
+ {
+ if (fCls)
+ {
+ return false;
+ }
+
+ fCls = new T(arg...);
+ return fCls;
+ }
+
+ void Delete()
+ {
+ if (fCls)
+ delete fCls;
+
+ fCls = nullptr;
+ }
+
+ T* operator->() const
+ {
+ return fCls;
+ };
+ T* Raw()
+ {
+ return fCls;
+ }
+
+ Ref<T> AsRef()
+ {
+ return Ref<T>(fCls);
+ }
+
+ operator bool()
+ {
+ return fCls;
+ }
+ bool operator!()
+ {
+ return !fCls;
+ }
+
+ private:
+ T* fCls;
+ };
+
+ template <typename T, typename... Args>
+ OwnPtr<T> make_ptr(Args... args)
+ {
+ OwnPtr<T> ret;
+ ret.template New<Args...>(forward(args)...);
+ MUST_PASS(ret);
+
+ return ret;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/NewKit/PageMgr.h b/dev/Kernel/NewKit/PageMgr.h
new file mode 100644
index 00000000..f12aa875
--- /dev/null
+++ b/dev/Kernel/NewKit/PageMgr.h
@@ -0,0 +1,81 @@
+// a way to create and find our pages.
+// I'm thinking about a separate way of getting a paged area.
+
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+#include <NewKit/Ref.h>
+
+namespace Kernel
+{
+ class PageMgr;
+
+ class PTEWrapper final
+ {
+ public:
+ explicit PTEWrapper(Boolean Rw = false, Boolean User = false, Boolean ExecDisable = false, UIntPtr Address = 0);
+
+ ~PTEWrapper();
+
+ PTEWrapper& operator=(const PTEWrapper&) = default;
+ PTEWrapper(const PTEWrapper&) = default;
+
+ public:
+ const UIntPtr VirtualAddress();
+
+ Void NoExecute(const bool enable = false);
+ Bool NoExecute();
+
+ operator bool()
+ {
+ return fVirtAddr;
+ }
+
+ bool Reclaim();
+ bool Shareable();
+ bool Present();
+ bool Access();
+
+ private:
+ Boolean fRw;
+ Boolean fUser;
+ Boolean fExecDisable;
+ UIntPtr fVirtAddr;
+ Boolean fCache;
+ Boolean fShareable;
+ Boolean fWt;
+ Boolean fPresent;
+ Boolean fAccessed;
+
+ private:
+ friend class PageMgr;
+ friend class Pmm;
+ };
+
+ struct PageMgr final
+ {
+ public:
+ PageMgr() = default;
+ ~PageMgr() = default;
+
+ PageMgr& operator=(const PageMgr&) = default;
+ PageMgr(const PageMgr&) = default;
+
+ public:
+ PTEWrapper Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz);
+ bool Free(Ref<PTEWrapper>& wrapper);
+
+ private:
+ void FlushTLB();
+
+ private:
+ friend PTEWrapper;
+ friend class Pmm;
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/NewKit/Pair.h b/dev/Kernel/NewKit/Pair.h
new file mode 100644
index 00000000..851fe45b
--- /dev/null
+++ b/dev/Kernel/NewKit/Pair.h
@@ -0,0 +1,14 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+namespace Kernel
+{
+ class Pair;
+} // namespace Kernel
diff --git a/dev/Kernel/NewKit/Pmm.h b/dev/Kernel/NewKit/Pmm.h
new file mode 100644
index 00000000..0eb749c1
--- /dev/null
+++ b/dev/Kernel/NewKit/Pmm.h
@@ -0,0 +1,44 @@
+
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/PageMgr.h>
+#include <NewKit/Ref.h>
+
+namespace Kernel
+{
+ class Pmm;
+ class PTEWrapper;
+
+ class Pmm final
+ {
+ public:
+ explicit Pmm();
+ ~Pmm();
+
+ Pmm& operator=(const Pmm&) = delete;
+ Pmm(const Pmm&) = default;
+
+ Ref<PTEWrapper> RequestPage(Boolean user = false, Boolean readWrite = false);
+ Boolean FreePage(Ref<PTEWrapper> refPage);
+
+ Boolean ToggleRw(Ref<PTEWrapper> refPage, Boolean enable = true);
+ Boolean TogglePresent(Ref<PTEWrapper> refPage, Boolean enable = true);
+ Boolean ToggleUser(Ref<PTEWrapper> refPage, Boolean enable = true);
+ Boolean ToggleShare(Ref<PTEWrapper> refPage, Boolean enable = true);
+
+ /// @brief Get the page manager of this.
+ Ref<PageMgr>& Leak()
+ {
+ return fPageMgr;
+ }
+
+ private:
+ Ref<PageMgr> fPageMgr;
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/NewKit/Ref.h b/dev/Kernel/NewKit/Ref.h
new file mode 100644
index 00000000..f91d0c1d
--- /dev/null
+++ b/dev/Kernel/NewKit/Ref.h
@@ -0,0 +1,108 @@
+
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifndef _NEWKIT_REF_H_
+#define _NEWKIT_REF_H_
+
+#include <NewKit/Defines.h>
+#include <NewKit/KernelPanic.h>
+#include <KernelKit/Heap.h>
+
+namespace Kernel
+{
+ template <typename T>
+ class Ref final
+ {
+ public:
+ Ref() = default;
+
+ ~Ref()
+ {
+ if (mm_is_valid_heap(fClass))
+ delete fClass;
+ }
+
+ public:
+ Ref(T* cls)
+ : fClass(cls)
+ {
+ }
+
+ Ref(T cls)
+ : fClass(&cls)
+ {
+ }
+
+ Ref& operator=(T ref)
+ {
+ if (!fClass)
+ return *this;
+
+ fClass = &ref;
+ return *this;
+ }
+
+ public:
+ T operator->() const
+ {
+ MUST_PASS(*fClass);
+ return *fClass;
+ }
+
+ T& Leak() noexcept
+ {
+ return *fClass;
+ }
+
+ T& TryLeak() const noexcept
+ {
+ MUST_PASS(*fClass);
+ return *fClass;
+ }
+
+ T operator*()
+ {
+ return *fClass;
+ }
+
+ operator bool() noexcept
+ {
+ return fClass;
+ }
+
+ private:
+ T* fClass{nullptr};
+ };
+
+ template <typename T>
+ class NonNullRef final
+ {
+ public:
+ NonNullRef() = delete;
+ NonNullRef(nullPtr) = delete;
+
+ NonNullRef(T* ref)
+ : fRef(ref)
+ {
+ MUST_PASS(ref);
+ }
+
+ Ref<T>& operator->()
+ {
+ MUST_PASS(fRef);
+ return fRef;
+ }
+
+ NonNullRef& operator=(const NonNullRef<T>& ref) = delete;
+ NonNullRef(const NonNullRef<T>& ref) = default;
+
+ private:
+ Ref<T> fRef{nullptr};
+ };
+} // namespace Kernel
+
+#endif // ifndef _NEWKIT_REF_H_
diff --git a/dev/Kernel/NewKit/Stream.h b/dev/Kernel/NewKit/Stream.h
new file mode 100644
index 00000000..90b828a5
--- /dev/null
+++ b/dev/Kernel/NewKit/Stream.h
@@ -0,0 +1,58 @@
+
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+#include <NewKit/Ref.h>
+
+namespace Kernel
+{
+ template <typename StreamTrait, typename Kind>
+ class Stream final
+ {
+ public:
+ explicit Stream(Ref<Stream> ref)
+ : fStream(ref)
+ {
+ }
+
+ ~Stream() = default;
+
+ Stream& operator=(const Stream&) = default;
+ Stream(const Stream&) = default;
+
+ template <typename Data>
+ friend Stream<StreamTrait, Kind>& operator>>(Stream<StreamTrait, Kind>& Ks, Ref<Data>& Buf)
+ {
+ Ks.fKind = Ks.fStream->In(Buf);
+ return *Ks;
+ }
+
+ template <typename Data>
+ friend Stream<StreamTrait, Kind>& operator<<(Stream<StreamTrait, Kind>& Ks, Ref<Data>& Buf)
+ {
+ Ks.fKind = Buf;
+ Ks.fStream->Out(Buf.Leak());
+ return *Ks;
+ }
+
+ Ref<StreamTrait>& AsStreamTrait()
+ {
+ return fStream;
+ }
+
+ Ref<Kind>& AsType()
+ {
+ return fKind;
+ }
+
+ private:
+ Ref<StreamTrait> fStream;
+ Ref<Kind> fKind;
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/NewKit/Utils.h b/dev/Kernel/NewKit/Utils.h
new file mode 100644
index 00000000..6b99fec4
--- /dev/null
+++ b/dev/Kernel/NewKit/Utils.h
@@ -0,0 +1,29 @@
+
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+namespace Kernel
+{
+ Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len);
+ Int rt_move_memory(const voidPtr src, voidPtr dst, Size len);
+ voidPtr rt_set_memory(voidPtr dst, UInt32 val, Size len);
+ void rt_zero_memory(voidPtr pointer, Size len);
+ Int rt_string_cmp(const Char* src, const Char* cmp, Size len);
+ const Char* rt_alloc_string(const Char* text);
+ Size rt_string_len(const Char* str);
+ Size rt_string_len(const Char* str, SizeT _len);
+ Boolean rt_to_string(Char* buf, UInt64 base, Int32 limit);
+ Boolean is_newln(Char chr);
+ Boolean is_space(Char chr);
+ Int rt_to_uppercase(Int c);
+ Int rt_to_lower(Int c);
+ voidPtr rt_string_in_string(const Char* in, const Char* needle);
+ char* rt_string_has_char(Char* str, const Char chr);
+} // namespace Kernel
diff --git a/dev/Kernel/NewKit/Variant.h b/dev/Kernel/NewKit/Variant.h
new file mode 100644
index 00000000..c603773f
--- /dev/null
+++ b/dev/Kernel/NewKit/Variant.h
@@ -0,0 +1,70 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+#include <NewKit/KString.h>
+#include <NewKit/Json.h>
+
+namespace Kernel
+{
+ class Variant final
+ {
+ public:
+ enum class VariantKind
+ {
+ kString,
+ kBlob,
+ kNull,
+ kJson,
+ kXML,
+ };
+
+ public:
+ explicit Variant() = delete;
+
+ public:
+ ZKA_COPY_DEFAULT(Variant);
+
+ ~Variant() = default;
+
+ public:
+ explicit Variant(KString* stringView)
+ : fPtr((VoidPtr)stringView), fKind(VariantKind::kString)
+ {
+ }
+
+ explicit Variant(JSON* json)
+ : fPtr((VoidPtr)json), fKind(VariantKind::kJson)
+ {
+ }
+
+ explicit Variant(nullPtr)
+ : fPtr(nullptr), fKind(VariantKind::kNull)
+ {
+ }
+
+ explicit Variant(VoidPtr ptr)
+ : fPtr(ptr), fKind(VariantKind::kBlob)
+ {
+ }
+
+ public:
+ const Char* ToString();
+ VoidPtr Leak();
+
+ template <typename T>
+ T* As()
+ {
+ return reinterpret_cast<T*>(fPtr);
+ }
+
+ private:
+ voidPtr fPtr{nullptr};
+ VariantKind fKind{VariantKind::kNull};
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/POSIXKit/signal.h b/dev/Kernel/POSIXKit/signal.h
new file mode 100644
index 00000000..75e6bf59
--- /dev/null
+++ b/dev/Kernel/POSIXKit/signal.h
@@ -0,0 +1,20 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+/** https://pubs.opengroup.org/onlinepubs/009695399/basedefs/signal.h.html */
+
+#include <POSIXKit/unix_layer.h>
+
+typedef Kernel::UInt32 signal_t;
+
+#define SIGKILL 0
+#define SIGPAUS 1
+#define SIGEXEC 2
+#define SIGTRAP 3
+#define SIGABRT 4
+#define SIGCONT 5
diff --git a/dev/Kernel/POSIXKit/unix_layer.h b/dev/Kernel/POSIXKit/unix_layer.h
new file mode 100644
index 00000000..f543ed41
--- /dev/null
+++ b/dev/Kernel/POSIXKit/unix_layer.h
@@ -0,0 +1,13 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/PEFCodeMgr.h>
+#include <SystemKit/TeamScheduler.h>
+#include <SystemKit/SwapDisk.h> \ No newline at end of file
diff --git a/dev/Kernel/ReadMe.md b/dev/Kernel/ReadMe.md
new file mode 100644
index 00000000..f90bc5e5
--- /dev/null
+++ b/dev/Kernel/ReadMe.md
@@ -0,0 +1,3 @@
+# ZkaOS Minimal Kernel DLL.
+
+An EXE which takes the role of the Minimal Kernel Image.
diff --git a/dev/Kernel/StorageKit/AHCI.h b/dev/Kernel/StorageKit/AHCI.h
new file mode 100644
index 00000000..5641898a
--- /dev/null
+++ b/dev/Kernel/StorageKit/AHCI.h
@@ -0,0 +1,33 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <KernelKit/DeviceMgr.h>
+#include <KernelKit/DriveMgr.h>
+#include <NewKit/OwnPtr.h>
+
+namespace Kernel
+{
+ class AHCIDeviceInterface ZKA_DEVICE<MountpointInterface*>
+ {
+ public:
+ explicit AHCIDeviceInterface(void (*Out)(MountpointInterface* outpacket),
+ void (*In)(MountpointInterface* inpacket),
+ void (*Cleanup)(void));
+
+ virtual ~AHCIDeviceInterface();
+
+ public:
+ AHCIDeviceInterface& operator=(const AHCIDeviceInterface&) = default;
+ AHCIDeviceInterface(const AHCIDeviceInterface&) = default;
+
+ const Char* Name() const override;
+
+ private:
+ void (*fCleanup)(void) = {nullptr};
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/StorageKit/ATA.h b/dev/Kernel/StorageKit/ATA.h
new file mode 100644
index 00000000..5551d96b
--- /dev/null
+++ b/dev/Kernel/StorageKit/ATA.h
@@ -0,0 +1,39 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <KernelKit/DeviceMgr.h>
+#include <KernelKit/DriveMgr.h>
+#include <NewKit/OwnPtr.h>
+#include <NewKit/Utils.h>
+
+namespace Kernel
+{
+ /// @brief ATA device interface type.
+ class ATADeviceInterface : public IDeviceObject<MountpointInterface*>
+ {
+ public:
+ explicit ATADeviceInterface(void (*Out)(MountpointInterface* outpacket),
+ void (*In)(MountpointInterface* inpacket),
+ void (*Cleanup)(void));
+
+ virtual ~ATADeviceInterface();
+
+ public:
+ ATADeviceInterface& operator<<(MountpointInterface* Data) override;
+ ATADeviceInterface& operator>>(MountpointInterface* Data) override;
+
+ public:
+ ATADeviceInterface& operator=(const ATADeviceInterface&) = default;
+ ATADeviceInterface(const ATADeviceInterface&) = default;
+
+ const Char* Name() const override;
+
+ private:
+ void (*fCleanup)(void) = {nullptr};
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/StorageKit/NVME.h b/dev/Kernel/StorageKit/NVME.h
new file mode 100644
index 00000000..f4a8393a
--- /dev/null
+++ b/dev/Kernel/StorageKit/NVME.h
@@ -0,0 +1,34 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <KernelKit/DeviceMgr.h>
+#include <KernelKit/DriveMgr.h>
+
+namespace Kernel
+{
+ class NVMEDeviceInterface final ZKA_DEVICE<MountpointInterface*>
+ {
+ public:
+ explicit NVMEDeviceInterface(Void (*out)(MountpointInterface* out_packet),
+ Void (*in)(MountpointInterface* in_packet),
+ Void (*cleanup)(Void));
+
+ ~NVMEDeviceInterface() override;
+
+ public:
+ ZKA_COPY_DEFAULT(NVMEDeviceInterface);
+
+ const Char* Name() const override;
+
+ public:
+ OwnPtr<MountpointInterface*> operator()(UInt32 dma_low, UInt32 dma_high, SizeT dma_sz);
+
+ private:
+ Void (*fCleanup)(Void) = {nullptr};
+ };
+} // namespace Kernel
diff --git a/dev/Kernel/StorageKit/PRDT.h b/dev/Kernel/StorageKit/PRDT.h
new file mode 100644
index 00000000..ef9b9d4a
--- /dev/null
+++ b/dev/Kernel/StorageKit/PRDT.h
@@ -0,0 +1,36 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <KernelKit/PCI/DMA.h>
+#include <KernelKit/PCI/Iterator.h>
+#include <NewKit/Ref.h>
+
+#define kPrdtTransferSize (sizeof(Kernel::UShort))
+
+namespace Kernel
+{
+ /// @brief Tranfer information about PRD.
+ enum kPRDTTransfer
+ {
+ kPRDTTransferInProgress,
+ kPRDTTransferIsDone,
+ kPRDTTransferCount,
+ };
+
+ /// @brief Physical Region Descriptor Table.
+ struct PRDT
+ {
+ UInt32 fPhysAddress;
+ UInt32 fSectorCount;
+ UInt8 fEndBit;
+ };
+
+ void construct_prdt(Ref<PRDT>& prd);
+
+ EXTERN_C Int32 kPRDTTransferStatus;
+} // namespace Kernel
diff --git a/dev/Kernel/StorageKit/SCSI.h b/dev/Kernel/StorageKit/SCSI.h
new file mode 100644
index 00000000..51ee0609
--- /dev/null
+++ b/dev/Kernel/StorageKit/SCSI.h
@@ -0,0 +1,11 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <Mod/SCSI/SCSI.h>
+
+extern const scsi_packet_type<12> kCDRomPacketTemplate;
diff --git a/dev/Kernel/StorageKit/StorageKit.h b/dev/Kernel/StorageKit/StorageKit.h
new file mode 100644
index 00000000..ad358e90
--- /dev/null
+++ b/dev/Kernel/StorageKit/StorageKit.h
@@ -0,0 +1,22 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#define kDriveSectorSizeHDD (512U)
+#define kDriveSectorSizeSSD (512U)
+#define kDriveSectorSizeOptical (2048)
+
+namespace Kernel
+{
+ template <typename T>
+ class IDeviceObject;
+
+ class NVMEDeviceInterface;
+ class AHCIDeviceInterface;
+ class ATADeviceInterface;
+ class SCSIDeviceInterface;
+} // namespace Kernel
diff --git a/dev/Kernel/SystemKit/SwapDisk.h b/dev/Kernel/SystemKit/SwapDisk.h
new file mode 100644
index 00000000..05f7b2d5
--- /dev/null
+++ b/dev/Kernel/SystemKit/SwapDisk.h
@@ -0,0 +1,48 @@
+
+/* -------------------------------------------
+
+ Copyright (C) 2024-2025 Amlal EL Mahrouss Labs, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+#include <CompilerKit/CompilerKit.h>
+
+#define kSwapBlockMaxSize (mib_cast(16))
+#define kSwapPageFile "/boot/pagefile.sys"
+
+/// @file SwapDisk.h
+/// @brief Virtual memory swap disk.
+
+namespace Kernel
+{
+ struct SWAP_DISK_HEADER;
+
+ /// @brief This class is a disk swap delegate for any data. available as a syscall too.
+ class SwapDisk final
+ {
+ public:
+ explicit SwapDisk() = default;
+ ~SwapDisk() = default;
+
+ ZKA_COPY_DEFAULT(SwapDisk);
+
+ BOOL Write(const Char* fork_name, const SizeT fork_name_len, SWAP_DISK_HEADER* data, const SizeT data_len);
+ SWAP_DISK_HEADER* Read(const Char* fork_name, const SizeT fork_name_len, const SizeT data_len);
+ };
+
+ typedef struct SWAP_DISK_HEADER
+ {
+ UInt32 fMagic;
+ SizeT fHeaderSz;
+ UInt64 fTeamID;
+ UInt64 fProcessID;
+ UInt64 fVirtualAddress;
+ SizeT fBlobSz;
+ Char fBlob[];
+ } PACKED SWAP_DISK_HEADER;
+
+ typedef SWAP_DISK_HEADER* SWAP_DISK_HEADER_REF;
+} // namespace Kernel
diff --git a/dev/Kernel/SystemKit/TeamScheduler.h b/dev/Kernel/SystemKit/TeamScheduler.h
new file mode 100644
index 00000000..92d3b5d6
--- /dev/null
+++ b/dev/Kernel/SystemKit/TeamScheduler.h
@@ -0,0 +1,20 @@
+
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.h>
+
+/// @file TeamScheduler.h
+/// @brief This file takes care of creating processes/threads from a subsystem context.
+
+namespace Kernel
+{
+ class UserSubsystem;
+ class UserEnvVar;
+ class UserEnv;
+} // namespace Kernel \ No newline at end of file
diff --git a/dev/Kernel/amd64-desktop.make b/dev/Kernel/amd64-desktop.make
new file mode 100644
index 00000000..9f6e94e3
--- /dev/null
+++ b/dev/Kernel/amd64-desktop.make
@@ -0,0 +1,85 @@
+##################################################
+# (c) Amlal EL Mahrouss, all rights reserved.
+# This is the minoskrnl's makefile.
+##################################################
+
+CXX = x86_64-w64-mingw32-g++
+LD = x86_64-w64-mingw32-ld
+CCFLAGS = -fshort-wchar -c -D__ZKA_AMD64__ -mno-red-zone -fno-rtti -fno-exceptions -std=c++20 -D__ZKA_SUPPORT_NX__ -O0 -I../Vendor -D__FSKIT_INCLUDES_NEFS__ -D__MINOSKRNL__ -D__HAVE_ZKA_APIS__ -D__FREESTANDING__ -D__ZKA_VIRTUAL_MEMORY_SUPPORT__ -D__ZKA_AUTO_FORMAT__ -D__ZKA__ -I./ -I../ -I../zba
+
+ASM = nasm
+
+DISK_DRV =
+
+ifneq ($(ATA_PIO_SUPPORT), )
+DISK_DRV = -D__ATA_PIO__
+endif
+
+ifneq ($(ATA_DMA_SUPPORT), )
+DISK_DRV = -D__ATA_DMA__
+endif
+
+ifneq ($(AHCI_SUPPORT), )
+DISK_DRV = -D__AHCI__
+endif
+
+ifneq ($(DEBUG_SUPPORT), )
+DEBUG_MACRO = -D__DEBUG__
+endif
+
+COPY = cp
+
+# Add assembler, linker, and object files variables.
+ASMFLAGS = -f win64
+
+# Kernel subsystem is 17 and entrypoint is hal_init_platform
+LDFLAGS = -e hal_init_platform --subsystem=17 --image-base 0x4000000
+LDOBJ = obj/*.obj
+
+# This file is the Kernel, responsible of task, memory, driver, sci, disk and device management.
+KERNEL_IMG = minoskrnl.exe
+
+.PHONY: error
+error:
+ @echo "=== ERROR ==="
+ @echo "=> Use a specific target."
+
+MOVEALL=./MoveAll.X64.sh
+WINDRES=x86_64-w64-mingw32-windres
+
+.PHONY: newos-amd64-epm
+newos-amd64-epm: clean
+ clear
+ @echo "!!! Please build what is needed by HALKit/AMD64/HalApplicationProcessorGNU.s !!!"
+ @echo "!!! Please build what is needed by HALKit/AMD64/HalApplicationProcessorGNU.s !!!"
+ @echo "!!! Please build what is needed by HALKit/AMD64/HalApplicationProcessorGNU.s !!!"
+ @sleep 3
+
+ $(WINDRES) KernelRsrc.rsrc -O coff -o KernelRsrc.obj
+ $(CXX) $(CCFLAGS) $(DISK_DRV) $(DEBUG_MACRO) $(wildcard src/*.cc) $(wildcard HALKit/AMD64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) $(wildcard src/FS/*.cc) $(wildcard HALKit/AMD64/Storage/*.cc) $(wildcard HALKit/AMD64/*.cc) $(wildcard src/System/*.cc) $(wildcard HALKit/AMD64/*.s)
+ $(ASM) $(ASMFLAGS) HALKit/AMD64/HalInterruptAPI.asm
+ $(ASM) $(ASMFLAGS) HALKit/AMD64/HalCommonAPI.asm
+ $(ASM) $(ASMFLAGS) HALKit/AMD64/HalBoot.asm
+ $(ASM) $(ASMFLAGS) HALKit/AMD64/HalUtils.asm
+ $(MOVEALL)
+
+OBJCOPY=x86_64-w64-mingw32-objcopy
+
+.PHONY: link-amd64-epm
+link-amd64-epm:
+ $(LD) $(LDFLAGS) $(LDOBJ) -o $(KERNEL_IMG)
+
+.PHONY: all
+all: newos-amd64-epm link-amd64-epm
+ @echo "Kernel => OK."
+
+.PHONY: help
+help:
+ @echo "=== HELP ==="
+ @echo "all: Build Kernel and link it."
+ @echo "link-amd64-epm: Link Kernel for EPM based disks."
+ @echo "newos-amd64-epm: Build Kernel for EPM based disks."
+
+.PHONY: clean
+clean:
+ rm -f $(LDOBJ) $(wildcard *.o) $(KERNEL_IMG)
diff --git a/dev/Kernel/arm64-desktop.make b/dev/Kernel/arm64-desktop.make
new file mode 100644
index 00000000..4cfb1076
--- /dev/null
+++ b/dev/Kernel/arm64-desktop.make
@@ -0,0 +1,64 @@
+##################################################
+# (c) Amlal EL Mahrouss, all rights reserved.
+# This is the microKernel makefile.
+##################################################
+
+CC = clang++
+LD = lld-link
+CCFLAGS = -fshort-wchar -c -ffreestanding -MMD -mno-red-zone -D__ZKA_ARM64__ -fno-rtti -fno-exceptions -I./ \
+ -target aarch64-unknown-windows \
+ -std=c++20 -O3 -D__MINOSKRNL__ -D__ZKA_MINIMAL_OS__ -D__ZKA_NO_BUILTIN__ -D__HAVE_ZKA_APIS__ -D__ZKA__ -I../
+
+ASM = clang++
+
+DISKDRIVER = -D__USE_FLASH_MEM__
+
+ifneq ($(DEBUG_SUPPORT), )
+DEBUG = -D__DEBUG__
+endif
+
+COPY = cp
+
+LDFLAGS = -subsystem:efi_application -entry:hal_init_platform /nodefaultlib
+LDOBJ = obj/*.obj
+
+# This file is the Kernel, responsible of task management and memory.
+KERNEL = minoskrnl.exe
+
+.PHONY: error
+error:
+ @echo "=== ERROR ==="
+ @echo "=> Use a specific target."
+
+MOVEALL=./MoveAll.ARM64.sh
+
+.PHONY: newos-arm64-epm
+newos-arm64-epm: clean
+ $(CC) $(CCFLAGS) $(DISKDRIVER) $(DEBUG) $(wildcard src/*.cc) \
+ $(wildcard src/FS/*.cc) $(wildcard HALKit/ARM64/Storage/*.cc) \
+ $(wildcard HALKit/ARM64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) \
+ $(wildcard HALKit/ARM64/*.cc) $(wildcard HALKit/ARM64/*.cpp) \
+ $(wildcard HALKit/ARM64/*.s) $(wildcard HALKit/ARM64/APM/*.cc)
+
+ $(MOVEALL)
+
+OBJCOPY=x86_64-w64-mingw32-objcopy
+
+.PHONY: link-arm64-epm
+link-arm64-epm:
+ $(LD) $(LDFLAGS) $(LDOBJ) /out:$(KERNEL)
+
+.PHONY: all
+all: newos-arm64-epm link-arm64-epm
+ @echo "Kernel => OK."
+
+.PHONY: help
+help:
+ @echo "=== HELP ==="
+ @echo "all: Build Kernel and link it."
+ @echo "link-arm64-epm: Link Kernel for EPM based disks."
+ @echo "newos-arm64-epm: Build Kernel for EPM based disks."
+
+.PHONY: clean
+clean:
+ rm -f $(LDOBJ) $(wildcard *.o) $(KERNEL)
diff --git a/dev/Kernel/doc/Explicit Partition Map.pdf b/dev/Kernel/doc/Explicit Partition Map.pdf
new file mode 100644
index 00000000..a73834cd
--- /dev/null
+++ b/dev/Kernel/doc/Explicit Partition Map.pdf
Binary files differ
diff --git a/dev/Kernel/doc/SPECIFICATION.md b/dev/Kernel/doc/SPECIFICATION.md
new file mode 100644
index 00000000..0233643a
--- /dev/null
+++ b/dev/Kernel/doc/SPECIFICATION.md
@@ -0,0 +1,63 @@
+===================================
+
+# 0: General Information
+
+===================================
+
+- ABI and Format: PEF/PE32+.
+- Kernel architecture: Portable hybrid Kernel.
+- Language: C++/(Assembly (AMD64, X64000, X86S, ARM64, POWER, RISCV))
+
+===================================
+
+# 1: The Kernel
+
+===================================
+
+- Drive/Device Abstraction.
+- SMP, Preemptive Multi Threading.
+- Separation of Files/Devices.
+- Networking.
+- Hardware Abstraction Layer.
+- Native Filesystem support (NeFS, FAT32 and ffs2).
+- Program Loaders interfaces.
+- TLS (Thread Local Storage) support.
+- Semaphore, Locks, Timers.
+- Canary mechanisms.
+- Dynamic Sys.
+- Cross Platform.
+- Permission Selectors.
+
+===================================
+
+# 2: The Filesystem
+
+===================================
+
+- Catalog object with associated forks.
+- Large storage support.
+- Long file names.
+- UNIX path style.
+
+==================================
+
+# 3: Common naming conventions:
+
+==================================
+
+- Kernel -> ke_init_x
+- RunTime -> rt_copy_mem
+- Hal -> hal_foo_bar
+- Class methods -> Class::FooBar
+
+===================================
+
+# 4: The zbaosldr
+
+===================================
+
+- Capable of booting from a network drive.
+- Loads a PE file which is the Kernel.
+- Sanity checks, based on the number of sections.
+- Handover compliant.
+- Does check for a valid partition (useful in the case of recovering)
diff --git a/dev/Kernel/doc/TODO-LIST.md b/dev/Kernel/doc/TODO-LIST.md
new file mode 100644
index 00000000..6e8e4b4d
--- /dev/null
+++ b/dev/Kernel/doc/TODO-LIST.md
@@ -0,0 +1,25 @@
+# TODO list
+
+- We need preemptive multi-threading. [ X ]
+- We then need sync primitives. [ X ]
+- We also need a system library for the OS. [ X ]
+- We need a bootloader for AMD64 [ X ]
+ - Implement Boot Services [ X ]
+ - Design Handover [ X ]
+ - Load Kernel into memory [ X ]
+ - Fix bug in Kernel loader, which causes a 06 #UD. [ X ]
+ - Load Kernel [ X ]
+ - Add IDT [ X ]
+ - AHCI driver [ WiP ]
+- Context switch x87/SSE/AVX registers [ X ]
+- Framebuffer [ X ]
+- ATA support [ X ]
+- Make installer [ X ]
+
+Status:
+
+BootZ: Need to boot from EPM partition. [ X ]
+<br>
+minoskrnl: New Filesystem is done. [ X ]
+
+**Refer to Jira please!**
diff --git a/dev/Kernel/obj/.hgkeep b/dev/Kernel/obj/.hgkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/obj/.hgkeep
diff --git a/dev/Kernel/power64-cb.make b/dev/Kernel/power64-cb.make
new file mode 100644
index 00000000..83ab3235
--- /dev/null
+++ b/dev/Kernel/power64-cb.make
@@ -0,0 +1,4 @@
+##################################################
+# (c) Amlal EL Mahrouss, all rights reserved.
+# This is the microKernel makefile.
+##################################################
diff --git a/dev/Kernel/riscv64-cb.make b/dev/Kernel/riscv64-cb.make
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/riscv64-cb.make
diff --git a/dev/Kernel/src/ACPIFactoryInterface.cc b/dev/Kernel/src/ACPIFactoryInterface.cc
new file mode 100644
index 00000000..cbfded4e
--- /dev/null
+++ b/dev/Kernel/src/ACPIFactoryInterface.cc
@@ -0,0 +1,96 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <Mod/ACPI/ACPIFactoryInterface.h>
+#include <NewKit/KString.h>
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/Heap.h>
+
+namespace Kernel
+{
+ /// @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* rsp_ptr = reinterpret_cast<RSDP*>(this->fRsdp);
+
+ if (rsp_ptr->Revision <= 1)
+ return ErrorOr<voidPtr>{-1};
+
+ RSDT* xsdt = reinterpret_cast<RSDT*>(rsp_ptr->RsdtAddress);
+
+ Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(Int64);
+
+ /***
+ crucial to avoid underflows.
+ */
+ if (num < 1)
+ {
+ /// stop here, we should have entries...
+ ke_panic(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: SDT Signature: " << sdt->Signature << endl;
+ kcout << "ACPI: SDT OEM ID: " << sdt->OemId << endl;
+ return ErrorOr<voidPtr>(reinterpret_cast<voidPtr>(xsdt->AddressArr[index]));
+ }
+ }
+ }
+
+ return ErrorOr<voidPtr>{-1};
+ }
+
+ /***
+ @brief Checksum on 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/Kernel/src/Array.cc b/dev/Kernel/src/Array.cc
new file mode 100644
index 00000000..71f65c06
--- /dev/null
+++ b/dev/Kernel/src/Array.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Array.h>
diff --git a/dev/Kernel/src/ArrayList.cc b/dev/Kernel/src/ArrayList.cc
new file mode 100644
index 00000000..a43fd4e0
--- /dev/null
+++ b/dev/Kernel/src/ArrayList.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/ArrayList.h>
diff --git a/dev/Kernel/src/Atom.cc b/dev/Kernel/src/Atom.cc
new file mode 100644
index 00000000..92937411
--- /dev/null
+++ b/dev/Kernel/src/Atom.cc
@@ -0,0 +1,10 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Atom.h>
+
+// @file Atom.cpp
+// @brief Atomic primitives
diff --git a/dev/Kernel/src/BitMapMgr.cc b/dev/Kernel/src/BitMapMgr.cc
new file mode 100644
index 00000000..a098322c
--- /dev/null
+++ b/dev/Kernel/src/BitMapMgr.cc
@@ -0,0 +1,186 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.h>
+
+#ifdef __ZKA_AMD64__
+#include <HALKit/AMD64/Paging.h>
+#elif defined(__ZKA_ARM64__)
+#include <HALKit/ARM64/Paging.h>
+#endif
+
+#include <NewKit/Defines.h>
+#include <NewKit/KernelPanic.h>
+
+#define kBitMapMagic (0x10210U)
+#define kBitMapPadSize (mib_cast(16))
+
+#define kBitMapMagIdx (0U)
+#define kBitMapSizeIdx (1U)
+#define kBitMapUsedIdx (2U)
+
+namespace Kernel
+{
+ namespace HAL
+ {
+ namespace Detail
+ {
+ /// \brief Proxy Interface to allocate a bitmap.
+ class IBitMapAllocator final
+ {
+ public:
+ explicit IBitMapAllocator() = default;
+ ~IBitMapAllocator() = default;
+
+ ZKA_COPY_DELETE(IBitMapAllocator);
+
+ auto IsBitMap(VoidPtr page_ptr) -> Bool
+ {
+ if (!page_ptr)
+ return No;
+
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(page_ptr);
+
+ if (!ptr_bit_set[kBitMapMagIdx] ||
+ ptr_bit_set[kBitMapMagIdx] != kBitMapMagic)
+ return No;
+
+ return Yes;
+ }
+
+ auto FreeBitMap(VoidPtr page_ptr) -> Bool
+ {
+ if (this->IsBitMap(page_ptr) == No)
+ return No;
+
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(page_ptr);
+
+ ptr_bit_set[kBitMapMagIdx] = kBitMapMagic;
+ ptr_bit_set[kBitMapUsedIdx] = No;
+
+ this->GetBitMapStatus(ptr_bit_set);
+
+ return Yes;
+ }
+
+ UInt32 MakeMMFlags(Bool wr, Bool user)
+ {
+ UInt32 flags = kMMFlagsPresent;
+
+ if (wr)
+ flags |= kMMFlagsWr;
+
+ if (user)
+ flags |= kMMFlagsUser;
+
+ return flags;
+ }
+
+ /// @brief Iterate over availables pages for a free one.
+ /// @return The new address which was found.
+ auto FindBitMap(VoidPtr base_ptr, SizeT size, Bool wr, Bool user) -> VoidPtr
+ {
+ if (!size)
+ return nullptr;
+
+ VoidPtr base = reinterpret_cast<VoidPtr>(((UIntPtr)base_ptr) + kPageSize);
+
+ while (YES)
+ {
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(base);
+
+ if (ptr_bit_set[kBitMapMagIdx] == kBitMapMagic &&
+ ptr_bit_set[kBitMapSizeIdx] <= size)
+ {
+ if (ptr_bit_set[kBitMapUsedIdx] == No)
+ {
+ ptr_bit_set[kBitMapSizeIdx] = size;
+ ptr_bit_set[kBitMapUsedIdx] = Yes;
+
+ this->GetBitMapStatus(ptr_bit_set);
+
+ UInt32 flags = this->MakeMMFlags(wr, user);
+ mm_map_page(ptr_bit_set, flags);
+
+ return (VoidPtr)ptr_bit_set;
+ }
+
+ kcout << "Missed potential BitMap as it is already used!\r\n";
+ }
+ else if (ptr_bit_set[kBitMapMagIdx] != kBitMapMagic)
+ {
+ ptr_bit_set[kBitMapMagIdx] = kBitMapMagic;
+ ptr_bit_set[kBitMapSizeIdx] = size;
+ ptr_bit_set[kBitMapUsedIdx] = Yes;
+
+ this->GetBitMapStatus(ptr_bit_set);
+
+ UInt32 flags = this->MakeMMFlags(wr, user);
+ mm_map_page(ptr_bit_set, flags);
+
+ return (VoidPtr)ptr_bit_set;
+ }
+
+ base = reinterpret_cast<VoidPtr>(reinterpret_cast<UIntPtr>(base) + ((ptr_bit_set[kBitMapMagIdx] != kBitMapMagic) ? (size) : ptr_bit_set[kBitMapSizeIdx]));
+ }
+
+ return nullptr;
+ }
+
+ /// @brief Print Bitmap status
+ auto GetBitMapStatus(UIntPtr* ptr_bit_set) -> Void
+ {
+ if (!this->IsBitMap(ptr_bit_set))
+ {
+ kcout << "Not a BitMap: " << hex_number((UIntPtr)ptr_bit_set) << endl;
+ return;
+ }
+
+ kcout << "Magic Number: " << hex_number(ptr_bit_set[kBitMapMagIdx]) << endl;
+ kcout << "Is Allocated: " << (ptr_bit_set[kBitMapUsedIdx] ? "Yes" : "No") << endl;
+ kcout << "Size of BitMap (B): " << number(ptr_bit_set[kBitMapSizeIdx]) << endl;
+ kcout << "Size of BitMap (KIB): " << number(KIB(ptr_bit_set[kBitMapSizeIdx])) << endl;
+ kcout << "Size of BitMap (MIB): " << number(MIB(ptr_bit_set[kBitMapSizeIdx])) << endl;
+ kcout << "Size of BitMap (GIB): " << number(GIB(ptr_bit_set[kBitMapSizeIdx])) << endl;
+ kcout << "Size of BitMap (TIB): " << number(TIB(ptr_bit_set[kBitMapSizeIdx])) << endl;
+ kcout << "Address Of BitMap Header: " << hex_number((UIntPtr)ptr_bit_set) << endl;
+ }
+ };
+ } // namespace Detail
+
+ auto mm_is_bitmap(VoidPtr ptr) -> Bool
+ {
+ Detail::IBitMapAllocator traits;
+ return traits.IsBitMap(ptr);
+ }
+
+ /// @brief Allocate a new page to be used by the OS.
+ /// @param wr read/write bit.
+ /// @param user user bit.
+ /// @return a new bitmap allocated pointer.
+ auto mm_alloc_bitmap(Boolean wr, Boolean user, SizeT size, Bool is_page) -> VoidPtr
+ {
+ VoidPtr ptr_new = nullptr;
+ Detail::IBitMapAllocator traits;
+
+ ptr_new = traits.FindBitMap(kKernelBitMpStart, size, wr, user);
+
+ return (UIntPtr*)ptr_new;
+ }
+
+ /// @brief Free Bitmap, and mark it a absent in page terms.
+ auto mm_free_bitmap(VoidPtr page_ptr) -> Bool
+ {
+ if (!page_ptr)
+ return No;
+
+ Detail::IBitMapAllocator traits;
+ Bool ret = traits.FreeBitMap(page_ptr);
+
+ return ret;
+ }
+ } // namespace HAL
+} // namespace Kernel
diff --git a/dev/Kernel/src/CodeMgr.cc b/dev/Kernel/src/CodeMgr.cc
new file mode 100644
index 00000000..de35f846
--- /dev/null
+++ b/dev/Kernel/src/CodeMgr.cc
@@ -0,0 +1,28 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/CodeMgr.h>
+#include <NewKit/Utils.h>
+#include <KernelKit/UserProcessScheduler.h>
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /// @brief Executes a new process from a function. Kernel code only.
+ /// @note This sets up a new stack, anything on the main function that calls the Kernel will not be accessible.
+ /// @param main the start of the process.
+ /// @return if the process was started or not.
+ /***********************************************************************************/
+
+ ProcessID rtl_create_process(rtl_main_kind main, const Char* process_name) noexcept
+ {
+ if (!process_name ||
+ *process_name == 0)
+ return kProcessInvalidID;
+
+ return UserProcessScheduler::The().Spawn(process_name, reinterpret_cast<VoidPtr>(main), nullptr);
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/Crc32.cc b/dev/Kernel/src/Crc32.cc
new file mode 100644
index 00000000..fcc2bf3f
--- /dev/null
+++ b/dev/Kernel/src/Crc32.cc
@@ -0,0 +1,83 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Crc32.h>
+
+// @file CRC32.cpp
+// @brief Check sequence implementation.
+
+namespace Kernel
+{
+ /// @brief The CRC32 seed table.
+ UInt32 kCrcTbl[kCrcCnt] = {
+ 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, 0xC79A971FL,
+ 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, 0x8AD958CFL, 0x78B2DBCCL,
+ 0x6BE22838L, 0x9989AB3BL, 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L,
+ 0x5E133C24L, 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
+ 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, 0x9A879FA0L,
+ 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, 0x5D1D08BFL, 0xAF768BBCL,
+ 0xBC267848L, 0x4E4DFB4BL, 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L,
+ 0x33ED7D2AL, 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
+ 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, 0x6DFE410EL,
+ 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, 0x30E349B1L, 0xC288CAB2L,
+ 0xD1D83946L, 0x23B3BA45L, 0xF779DEAEL, 0x05125DADL, 0x1642AE59L,
+ 0xE4292D5AL, 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
+ 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, 0x417B1DBCL,
+ 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, 0x86E18AA3L, 0x748A09A0L,
+ 0x67DAFA54L, 0x95B17957L, 0xCBA24573L, 0x39C9C670L, 0x2A993584L,
+ 0xD8F2B687L, 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
+ 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, 0x96BF4DCCL,
+ 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, 0xDBFC821CL, 0x2997011FL,
+ 0x3AC7F2EBL, 0xC8AC71E8L, 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L,
+ 0x0F36E6F7L, 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
+ 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, 0xEB1FCBADL,
+ 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, 0x2C855CB2L, 0xDEEEDFB1L,
+ 0xCDBE2C45L, 0x3FD5AF46L, 0x7198540DL, 0x83F3D70EL, 0x90A324FAL,
+ 0x62C8A7F9L, 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
+ 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, 0x3CDB9BDDL,
+ 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, 0x82F63B78L, 0x709DB87BL,
+ 0x63CD4B8FL, 0x91A6C88CL, 0x456CAC67L, 0xB7072F64L, 0xA457DC90L,
+ 0x563C5F93L, 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
+ 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, 0x92A8FC17L,
+ 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, 0x55326B08L, 0xA759E80BL,
+ 0xB4091BFFL, 0x466298FCL, 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL,
+ 0x0B21572CL, 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
+ 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, 0x65D122B9L,
+ 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, 0x2892ED69L, 0xDAF96E6AL,
+ 0xC9A99D9EL, 0x3BC21E9DL, 0xEF087A76L, 0x1D63F975L, 0x0E330A81L,
+ 0xFC588982L, 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
+ 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, 0x38CC2A06L,
+ 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, 0xFF56BD19L, 0x0D3D3E1AL,
+ 0x1E6DCDEEL, 0xEC064EEDL, 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L,
+ 0xD0DDD530L, 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
+ 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, 0x8ECEE914L,
+ 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, 0xD3D3E1ABL, 0x21B862A8L,
+ 0x32E8915CL, 0xC083125FL, 0x144976B4L, 0xE622F5B7L, 0xF5720643L,
+ 0x07198540L, 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
+ 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, 0xE330A81AL,
+ 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, 0x24AA3F05L, 0xD6C1BC06L,
+ 0xC5914FF2L, 0x37FACCF1L, 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L,
+ 0x7AB90321L, 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
+ 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, 0x34F4F86AL,
+ 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, 0x79B737BAL, 0x8BDCB4B9L,
+ 0x988C474DL, 0x6AE7C44EL, 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L,
+ 0xAD7D5351L};
+
+ /// @brief Calculate CRC32 of p
+ /// @param p the data to compute.
+ /// @param len the length of the data.
+ /// @return the CRC32.
+ UInt ke_calculate_crc32(const Char* p, UInt len) noexcept
+ {
+ UInt crc = 0xffffffff;
+
+ while (len-- != 0)
+ crc = kCrcTbl[((UInt8)crc ^ *(p++))] ^ (crc >> 8);
+
+ // return (~crc); also works, does the same thing.
+ return (crc ^ 0xffffffff);
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/CxxAbi-AMD64.cc b/dev/Kernel/src/CxxAbi-AMD64.cc
new file mode 100644
index 00000000..9065ece5
--- /dev/null
+++ b/dev/Kernel/src/CxxAbi-AMD64.cc
@@ -0,0 +1,90 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifdef __ZKA_AMD64__
+
+#include <KernelKit/DebugOutput.h>
+#include <NewKit/CxxAbi.h>
+#include <KernelKit/LPC.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)
+{
+ kcout << "object: " << Kernel::number(reinterpret_cast<Kernel::UIntPtr>(self));
+ kcout << ", has unimplemented virtual functions.\r";
+}
+
+EXTERN_C void ___chkstk_ms(void)
+{
+}
+
+EXTERN_C int atexit(void (*f)(void*), 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].obj_ptr);
+ };
+ }
+
+ return;
+ }
+
+ while (i--)
+ {
+ if (__atexit_funcs[i].destructor_func)
+ {
+ (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
+ __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
+
+#endif // ifdef __ZKA_AMD64__
diff --git a/dev/Kernel/src/CxxAbi-ARM64.cc b/dev/Kernel/src/CxxAbi-ARM64.cc
new file mode 100644
index 00000000..127e12c6
--- /dev/null
+++ b/dev/Kernel/src/CxxAbi-ARM64.cc
@@ -0,0 +1,107 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifdef __ZKA_ARM64__
+
+#include <KernelKit/DebugOutput.h>
+#include <NewKit/CxxAbi.h>
+#include <KernelKit/LPC.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*), 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].obj_ptr);
+ };
+ }
+
+ return;
+ }
+
+ while (i--)
+ {
+ if (__atexit_funcs[i].destructor_func)
+ {
+ (*__atexit_funcs[i].destructor_func)(__atexit_funcs[i].obj_ptr);
+ __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)
+{
+ kcout << "object: " << Kernel::number(reinterpret_cast<Kernel::UIntPtr>(self));
+ kcout << ", has unimplemented virtual functions.\r";
+}
+
+EXTERN_C Kernel::Void _Init_thread_footer(Kernel::Int* thread_obj)
+{
+ ZKA_UNUSED(thread_obj);
+}
+
+EXTERN_C Kernel::Void _Init_thread_epoch(Kernel::Void)
+{
+ ZKA_UNUSED(0);
+}
+
+EXTERN_C Kernel::Void _Init_thread_header(Kernel::Int* thread_obj)
+{
+ ZKA_UNUSED(0);
+}
+
+EXTERN_C Kernel::Int _tls_index = 0UL;
+
+#endif // ifdef __ZKA_ARM64__
diff --git a/dev/Kernel/src/Defines.cc b/dev/Kernel/src/Defines.cc
new file mode 100644
index 00000000..2252d68d
--- /dev/null
+++ b/dev/Kernel/src/Defines.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Defines.h>
diff --git a/dev/Kernel/src/DeviceMgr.cc b/dev/Kernel/src/DeviceMgr.cc
new file mode 100644
index 00000000..88bed209
--- /dev/null
+++ b/dev/Kernel/src/DeviceMgr.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DeviceMgr.h>
diff --git a/dev/Kernel/src/DriveMgr+IO.cc b/dev/Kernel/src/DriveMgr+IO.cc
new file mode 100644
index 00000000..ee857ed4
--- /dev/null
+++ b/dev/Kernel/src/DriveMgr+IO.cc
@@ -0,0 +1,96 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DriveMgr.h>
+#include <KernelKit/FileMgr.h>
+
+/*************************************************************
+ *
+ * File: DriveMgr+IO.cc
+ * Purpose: Filesystem to mountpoint interface.
+ * Date: 3/26/24
+ *
+ * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+ *
+ *************************************************************/
+
+/// Useful macros.
+
+#define rtl_nefs_write(DRV, TRAITS, MP) (MP->DRV()).fOutput(TRAITS)
+#define rtl_nefs_read(DRV, TRAITS, MP) (MP->DRV()).fInput(TRAITS)
+
+namespace Kernel
+{
+ /// @brief Read from newfs disk.
+ /// @param Mnt mounted interface.
+ /// @param DrvTrait drive info
+ /// @param DrvIndex drive index.
+ /// @return
+ Int32 fs_ifs_read(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex)
+ {
+ if (!Mnt)
+ return 1;
+
+ DrvTrait.fPacket.fPacketGood = false;
+
+ switch (DrvIndex)
+ {
+ case MountpointInterface::kDriveIndexA: {
+ rtl_nefs_read(A, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexB: {
+ rtl_nefs_read(B, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexC: {
+ rtl_nefs_read(C, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexD: {
+ rtl_nefs_read(D, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ }
+
+ return DrvTrait.fPacket.fPacketGood;
+ }
+
+ /// @brief Write to newfs disk.
+ /// @param Mnt mounted interface.
+ /// @param DrvTrait drive info
+ /// @param DrvIndex drive index.
+ /// @return
+ Int32 fs_ifs_write(MountpointInterface* Mnt, DriveTrait& DrvTrait, Int32 DrvIndex)
+ {
+ if (!Mnt)
+ return 1;
+
+ DrvTrait.fPacket.fPacketGood = false;
+
+ switch (DrvIndex)
+ {
+ case MountpointInterface::kDriveIndexA: {
+ rtl_nefs_write(A, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexB: {
+ rtl_nefs_write(B, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexC: {
+ rtl_nefs_write(C, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ case MountpointInterface::kDriveIndexD: {
+ rtl_nefs_write(D, DrvTrait.fPacket, Mnt);
+ break;
+ }
+ }
+
+ return DrvTrait.fPacket.fPacketGood;
+ }
+} // namespace Kernel \ No newline at end of file
diff --git a/dev/Kernel/src/DriveMgr.cc b/dev/Kernel/src/DriveMgr.cc
new file mode 100644
index 00000000..9968e2e6
--- /dev/null
+++ b/dev/Kernel/src/DriveMgr.cc
@@ -0,0 +1,230 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/DriveMgr.h>
+#include <NewKit/Utils.h>
+#include <FirmwareKit/EPM.h>
+#include <Mod/ATA/ATA.h>
+#include <Mod/AHCI/AHCI.h>
+#include <Mod/NVME/NVME.h>
+
+/***********************************************************************************/
+/// @file DriveMgr.cc
+/// @brief Drive Manager of minoskrnl.
+/***********************************************************************************/
+
+namespace Kernel
+{
+#if defined(__ATA_PIO__) || defined(__ATA_DMA__)
+ STATIC UInt16 kATAIO = 0U;
+ STATIC UInt8 kATAMaster = 0U;
+#endif
+
+ /// @brief reads from an ATA drive.
+ /// @param pckt Packet structure (fPacketContent must be non null)
+ /// @return
+ Void io_drv_input(DriveTrait::DrivePacket pckt)
+ {
+#ifdef __AHCI__
+ drv_std_read(pckt.fPacketLba, (Char*)pckt.fPacketContent, kAHCISectorSize, pckt.fPacketSize);
+#elif defined(__ATA_PIO__) || defined(__ATA_DMA__)
+ drv_std_read(pckt.fPacketLba, kATAIO, kATAMaster, (Char*)pckt.fPacketContent, kATASectorSize, pckt.fPacketSize);
+#endif
+ }
+
+ /// @brief Writes to an ATA drive.
+ /// @param pckt the packet to write.
+ /// @return
+ Void io_drv_output(DriveTrait::DrivePacket pckt)
+ {
+ if (pckt.fPacketReadOnly)
+ return;
+
+ kcout << "Writing blob to disk...\r";
+
+#ifdef __AHCI__
+ drv_std_write(pckt.fPacketLba, (Char*)pckt.fPacketContent, kAHCISectorSize, pckt.fPacketSize);
+#elif defined(__ATA_PIO__) || defined(__ATA_DMA__)
+ drv_std_write(pckt.fPacketLba, kATAIO, kATAMaster, (Char*)pckt.fPacketContent, kATASectorSize, pckt.fPacketSize);
+#endif
+ }
+
+ /// @brief Executes a disk check on the ATA drive.
+ /// @param pckt the packet to read.
+ /// @return
+ Void io_drv_init(DriveTrait::DrivePacket pckt)
+ {
+#if defined(__ATA_PIO__) || defined(__ATA_DMA__)
+ kATAMaster = 0;
+ kATAIO = 0;
+#endif
+
+#if defined(__ATA_PIO__) || defined(__ATA_DMA__)
+ kATAMaster = true;
+ kATAIO = ATA_PRIMARY_IO;
+
+ if (drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster))
+ {
+ pckt.fPacketGood = YES;
+ return;
+ }
+
+ kATAMaster = false;
+ kATAIO = ATA_SECONDARY_IO;
+
+ if (!drv_std_init(kATAIO, kATAMaster, kATAIO, kATAMaster))
+ {
+ return;
+ }
+
+ pckt.fPacketGood = YES;
+#elif defined(__AHCI__)
+ UInt16 pi = 0;
+
+ if (!drv_std_init(pi))
+ {
+ return;
+ }
+#endif // if defined(__ATA_PIO__) || defined (__ATA_DMA__)
+ }
+
+/// @brief Gets the drive kind (ATA, SCSI, AHCI...)
+/// @param no arguments.
+/// @return no arguments.
+#ifdef __ATA_PIO__
+ const Char* io_drv_kind(Void)
+ {
+ return "ATA-PIO";
+ }
+#endif
+#ifdef __ATA_DMA__
+ const Char* io_drv_kind(Void)
+ {
+ return "ATA-DMA";
+ }
+#endif
+#ifdef __AHCI__
+ const Char* io_drv_kind(Void)
+ {
+ return "AHCI";
+ }
+#endif
+#ifdef __ZKA_MINIMAL_OS__
+ const Char* io_drv_kind(Void)
+ {
+ return "Not Loaded";
+ }
+#endif
+
+ /// @brief Unimplemented drive function.
+ /// @param pckt the packet to read.
+ Void io_drv_unimplemented(DriveTrait::DrivePacket pckt) noexcept
+ {
+ ZKA_UNUSED(pckt);
+ }
+
+ /// @brief Makes a new drive.
+ /// @return the new blank drive.
+ DriveTrait io_construct_blank_drive() noexcept
+ {
+ DriveTrait trait;
+
+ constexpr auto kBlankDrive = "/media/blank/";
+
+ rt_copy_memory((VoidPtr)kBlankDrive, trait.fName, rt_string_len(kBlankDrive));
+ trait.fKind = kInvalidDisc;
+
+ trait.fInput = io_drv_unimplemented;
+ trait.fOutput = io_drv_unimplemented;
+ trait.fVerify = io_drv_unimplemented;
+ trait.fInit = io_drv_unimplemented;
+ trait.fDriveKind = io_drv_kind;
+
+ kcout << "Construct: " << trait.fName << "\r";
+
+ return trait;
+ }
+
+ namespace Detect
+ {
+ Void io_detect_drive(DriveTrait& trait)
+ {
+ EPM_PART_BLOCK block_struct;
+
+ trait.fPacket.fPacketLba = kEPMBootBlockLba;
+ trait.fPacket.fPacketSize = sizeof(EPM_PART_BLOCK);
+ trait.fPacket.fPacketContent = &block_struct;
+
+ rt_copy_memory((VoidPtr) "fs/detect-packet", trait.fPacket.fPacketMime,
+ rt_string_len("fs/detect-packet"));
+
+ trait.fInit(trait.fPacket);
+
+ trait.fInput(trait.fPacket);
+
+ if (rt_string_cmp(((BOOT_BLOCK_STRUCT*)trait.fPacket.fPacketContent)->Magic, kEPMMagic, kEPMMagicLength) == 0)
+ {
+ trait.fPacket.fPacketReadOnly = NO;
+ trait.fKind = kMassStorageDisc | kEPMDrive;
+
+ kcout << "Formatted Disk is EPM (Mass Storage)\r";
+
+ trait.fSectorSz = block_struct.SectorSz;
+ trait.fLbaEnd = block_struct.LbaEnd;
+ trait.fLbaStart = block_struct.LbaStart;
+
+ if (trait.fSectorSz == 0 ||
+ trait.fLbaEnd == 0)
+ {
+ ke_panic(RUNTIME_CHECK_FAILED, "Invalid EPM partition!");
+ }
+ }
+ else
+ {
+ trait.fPacket.fPacketReadOnly = YES;
+ trait.fKind = kMassStorageDisc | kUnformattedDrive | kReadOnlyDrive;
+
+ kcout << "Scheme Found: " << block_struct.Name << endl;
+
+ if (block_struct.Name[0] == 0)
+ kcout << "Disk partition is empty (Read Only)\r";
+ }
+
+ rt_copy_memory((VoidPtr) "*/*", trait.fPacket.fPacketMime,
+ rt_string_len("*/*"));
+
+ trait.fPacket.fPacketLba = 0;
+ trait.fPacket.fPacketSize = 0UL;
+ trait.fPacket.fPacketContent = nullptr;
+ }
+ } // namespace Detect
+
+ /// @brief Fetches the main drive.
+ /// @return the new drive. (returns kEPMDrive if EPM formatted)
+ DriveTrait io_construct_main_drive() noexcept
+ {
+ DriveTrait trait;
+
+ constexpr auto kMainDrive = "/media/sda/";
+
+ rt_copy_memory((VoidPtr)kMainDrive, trait.fName, rt_string_len(kMainDrive));
+
+ MUST_PASS(trait.fName[0] != 0);
+
+ trait.fVerify = io_drv_unimplemented;
+ trait.fOutput = io_drv_output;
+ trait.fInput = io_drv_input;
+ trait.fInit = io_drv_init;
+ trait.fDriveKind = io_drv_kind;
+
+ kcout << "Detecting partition scheme of: " << trait.fName << ".\r";
+
+ Detect::io_detect_drive(trait);
+
+ return trait;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/ErrorOr.cc b/dev/Kernel/src/ErrorOr.cc
new file mode 100644
index 00000000..f365277f
--- /dev/null
+++ b/dev/Kernel/src/ErrorOr.cc
@@ -0,0 +1,12 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/ErrorOr.h>
+
+/***********************************************************************************/
+/// @file ErrorOr.cc ///
+/// @brief ErrorOr container class. ///
+/***********************************************************************************/
diff --git a/dev/Kernel/src/FS/HPFS.cc b/dev/Kernel/src/FS/HPFS.cc
new file mode 100644
index 00000000..984ca243
--- /dev/null
+++ b/dev/Kernel/src/FS/HPFS.cc
@@ -0,0 +1,22 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#ifdef __FSKIT_INCLUDES_HPFS__
+
+#include <Mod/AHCI/AHCI.h>
+#include <Mod/ATA/ATA.h>
+#include <Mod/Flash/Flash.h>
+#include <FSKit/HPFS.h>
+#include <KernelKit/LPC.h>
+#include <NewKit/Crc32.h>
+#include <NewKit/KernelPanic.h>
+#include <NewKit/KString.h>
+#include <NewKit/Utils.h>
+#include <FirmwareKit/EPM.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/User.h>
+
+#endif // ifdef __FSKIT_INCLUDES_HPFS__
diff --git a/dev/Kernel/src/FileMgr.cc b/dev/Kernel/src/FileMgr.cc
new file mode 100644
index 00000000..0e05daa1
--- /dev/null
+++ b/dev/Kernel/src/FileMgr.cc
@@ -0,0 +1,52 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/FileMgr.h>
+#include <NewKit/Utils.h>
+
+/// @file FileMgr.cc
+//! @brief File System Manager API.
+
+namespace Kernel
+{
+ STATIC IFilesystemMgr* kMountedFilesystem = nullptr;
+
+ /// @brief FilesystemMgr getter.
+ /// @return The mounted filesystem.
+ _Output IFilesystemMgr* IFilesystemMgr::GetMounted()
+ {
+ return kMountedFilesystem;
+ }
+
+ /// @brief Unmount filesystem.
+ /// @return The unmounted filesystem.
+ _Output IFilesystemMgr* IFilesystemMgr::Unmount()
+ {
+ if (kMountedFilesystem)
+ {
+ auto mount = kMountedFilesystem;
+ kMountedFilesystem = nullptr;
+
+ return mount;
+ }
+
+ return nullptr;
+ }
+
+ /// @brief Mount filesystem.
+ /// @param mount_ptr The filesystem to mount.
+ /// @return if it succeeded true, otherwise false.
+ _Output Bool IFilesystemMgr::Mount(_Input IFilesystemMgr* mount_ptr)
+ {
+ if (mount_ptr != nullptr)
+ {
+ kMountedFilesystem = mount_ptr;
+ return Yes;
+ }
+
+ return No;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/GUIDWizard.cc b/dev/Kernel/src/GUIDWizard.cc
new file mode 100644
index 00000000..854a0db7
--- /dev/null
+++ b/dev/Kernel/src/GUIDWizard.cc
@@ -0,0 +1,72 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: GUIDWizard.cc
+ Purpose: GUID helper code
+
+ Revision History:
+
+------------------------------------------- */
+
+#include <CFKit/GUIDWizard.h>
+#include <NewKit/Ref.h>
+
+// begin of ascii 'readable' characters. (A, C, C, 1, 2)
+#define kUUIDAsciiBegin 47
+// @brief Size of UUID.
+#define kUUIDSize 37
+
+namespace CFKit::XRN::Version1
+{
+ auto cf_make_sequence(const ArrayList<UInt32>& uuidSeq) -> Ref<GUIDSequence*>
+ {
+ GUIDSequence* seq = new GUIDSequence();
+ MUST_PASS(seq);
+
+ Ref<GUIDSequence*> seq_ref{seq};
+
+ seq_ref.Leak()->fMs1 = uuidSeq[0];
+ seq_ref.Leak()->fMs2 = uuidSeq[1];
+ seq_ref.Leak()->fMs3 = uuidSeq[2];
+ seq_ref.Leak()->fMs4[0] = uuidSeq[3];
+ seq_ref.Leak()->fMs4[1] = uuidSeq[4];
+ seq_ref.Leak()->fMs4[2] = uuidSeq[5];
+ seq_ref.Leak()->fMs4[3] = uuidSeq[6];
+ seq_ref.Leak()->fMs4[4] = uuidSeq[7];
+ seq_ref.Leak()->fMs4[5] = uuidSeq[8];
+ seq_ref.Leak()->fMs4[6] = uuidSeq[9];
+ seq_ref.Leak()->fMs4[7] = uuidSeq[10];
+
+ return seq_ref;
+ }
+
+ // @brief Tries to make a guid out of a string.
+ // This function is not complete for now
+ auto cf_try_guid_to_string(Ref<GUIDSequence*>& seq) -> ErrorOr<Ref<KString>>
+ {
+ Char buf[kUUIDSize];
+
+ for (SizeT index = 0; index < 16; ++index)
+ {
+ buf[index] = seq.Leak()->u8[index] + kUUIDAsciiBegin;
+ }
+
+ for (SizeT index = 16; index < 24; ++index)
+ {
+ buf[index] = seq.Leak()->u16[index] + kUUIDAsciiBegin;
+ }
+
+ for (SizeT index = 24; index < 28; ++index)
+ {
+ buf[index] = seq.Leak()->u32[index] + kUUIDAsciiBegin;
+ }
+
+ auto view = StringBuilder::Construct(buf);
+
+ if (view)
+ return ErrorOr<Ref<KString>>{view.Leak()};
+
+ return ErrorOr<Ref<KString>>{-1};
+ }
+} // namespace CFKit::XRN::Version1
diff --git a/dev/Kernel/src/GUIDWrapper.cc b/dev/Kernel/src/GUIDWrapper.cc
new file mode 100644
index 00000000..eda9cf29
--- /dev/null
+++ b/dev/Kernel/src/GUIDWrapper.cc
@@ -0,0 +1,11 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <CFKit/GUIDWrapper.h>
+
+namespace CFKit::XRN
+{
+}
diff --git a/dev/Kernel/src/HardwareThreadScheduler.cc b/dev/Kernel/src/HardwareThreadScheduler.cc
new file mode 100644
index 00000000..66500f73
--- /dev/null
+++ b/dev/Kernel/src/HardwareThreadScheduler.cc
@@ -0,0 +1,219 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/HardwareThreadScheduler.h>
+#include <CFKit/Property.h>
+
+/***********************************************************************************/
+///! @file HardwareThreadScheduler.cc
+///! @brief This file handles multi processing in the Kernel.
+///! @brief Multi processing is needed for multi-tasking operations.
+/***********************************************************************************/
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /// @note Those symbols are needed in order to switch and validate the stack.
+ /***********************************************************************************/
+
+ EXTERN_C Bool hal_check_stack(HAL::StackFramePtr frame);
+ EXTERN_C Bool mp_register_process(HAL::StackFramePtr frame, ProcessID pid);
+
+ STATIC HardwareThreadScheduler kHardwareThreadScheduler;
+
+ ///! A HardwareThread class takes care of it's owned hardware thread.
+ ///! It has a stack for it's core.
+
+ /***********************************************************************************/
+ ///! @brief C++ constructor.
+ /***********************************************************************************/
+ HardwareThread::HardwareThread() = default;
+
+ /***********************************************************************************/
+ ///! @brief C++ destructor.
+ /***********************************************************************************/
+ HardwareThread::~HardwareThread() = default;
+
+ /***********************************************************************************/
+ //! @brief returns the id of the thread.
+ /***********************************************************************************/
+ const ThreadID& HardwareThread::ID() noexcept
+ {
+ return fID;
+ }
+
+ /***********************************************************************************/
+ //! @brief returns the kind of thread we have.
+ /***********************************************************************************/
+ const ThreadKind& HardwareThread::Kind() noexcept
+ {
+ return fKind;
+ }
+
+ /***********************************************************************************/
+ //! @brief is the thread busy?
+ //! @return whether the thread is busy or not.
+ /***********************************************************************************/
+ Bool HardwareThread::IsBusy() noexcept
+ {
+ STATIC Int64 busy_timer = 0U;
+
+ if (fBusy && busy_timer > this->fPTime)
+ {
+ busy_timer = 0U;
+ fBusy = No;
+ }
+
+ ++busy_timer;
+
+ return fBusy;
+ }
+
+ /***********************************************************************************/
+ /// @brief Get processor stack frame.
+ /***********************************************************************************/
+
+ HAL::StackFramePtr HardwareThread::StackFrame() noexcept
+ {
+ MUST_PASS(fStack);
+ return fStack;
+ }
+
+ Void HardwareThread::Busy(const Bool busy) noexcept
+ {
+ fBusy = busy;
+ }
+
+ HardwareThread::operator bool()
+ {
+ return this->fStack && !this->fBusy;
+ }
+
+ /***********************************************************************************/
+ /// @brief Wakeup the processor.
+ /***********************************************************************************/
+
+ Void HardwareThread::Wake(const bool wakeup) noexcept
+ {
+ fWakeup = wakeup;
+ }
+
+ /***********************************************************************************/
+ /// @brief Switch to hardware thread.
+ /// @param stack the new hardware thread.
+ /// @retval true stack was changed, code is running.
+ /// @retval false stack is invalid, previous code is running.
+ /***********************************************************************************/
+ Bool HardwareThread::Switch(VoidPtr image_ptr, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ThreadID& pid)
+ {
+ this->fStack = frame;
+ this->fSourcePID = pid;
+
+ fStack->BP = reinterpret_cast<UIntPtr>(image_ptr);
+ fStack->SP = reinterpret_cast<UIntPtr>(stack_ptr);
+
+ Bool ret = mp_register_process(fStack, this->fSourcePID);
+
+ if (ret)
+ this->Busy(YES);
+
+ return ret;
+ }
+
+ /***********************************************************************************/
+ ///! @brief Tells if processor is waked up.
+ /***********************************************************************************/
+ bool HardwareThread::IsWakeup() noexcept
+ {
+ return fWakeup;
+ }
+
+ /***********************************************************************************/
+ ///! @brief Constructor and destructors.
+ ///! @brief Default constructor.
+ /***********************************************************************************/
+
+ HardwareThreadScheduler::HardwareThreadScheduler() = default;
+
+ /***********************************************************************************/
+ ///! @brief Default destructor.
+ /***********************************************************************************/
+ HardwareThreadScheduler::~HardwareThreadScheduler() = default;
+
+ /***********************************************************************************/
+ /// @brief Shared singleton function
+ /***********************************************************************************/
+ HardwareThreadScheduler& HardwareThreadScheduler::The()
+ {
+ return kHardwareThreadScheduler;
+ }
+
+ /***********************************************************************************/
+ /// @brief Get Stack Frame of AP.
+ /***********************************************************************************/
+ HAL::StackFramePtr HardwareThreadScheduler::Leak() noexcept
+ {
+ return fThreadList[fCurrentThread].fStack;
+ }
+
+ /***********************************************************************************/
+ /**
+ * Get Hardware thread at index.
+ * @param idx the index
+ * @return the reference to the hardware thread.
+ */
+ /***********************************************************************************/
+ Ref<HardwareThread*> HardwareThreadScheduler::operator[](const SizeT& idx)
+ {
+ if (idx == 0)
+ {
+ if (fThreadList[idx].Kind() != kAPSystemReserved)
+ {
+ fThreadList[idx].fKind = kAPBoot;
+ }
+ }
+ else if (idx >= kMaxAPInsideSched)
+ {
+ static HardwareThread* fakeThread = nullptr;
+ return {fakeThread};
+ }
+
+ return &fThreadList[idx];
+ }
+
+ /***********************************************************************************/
+ /**
+ * Check if thread pool isn't empty.
+ * @return
+ */
+ /***********************************************************************************/
+ HardwareThreadScheduler::operator bool() noexcept
+ {
+ return !fThreadList.Empty();
+ }
+
+ /***********************************************************************************/
+ /**
+ * Reverse operator bool
+ * @return
+ */
+ /***********************************************************************************/
+ bool HardwareThreadScheduler::operator!() noexcept
+ {
+ return fThreadList.Empty();
+ }
+
+ /***********************************************************************************/
+ /// @brief Returns the amount of core present.
+ /// @return the number of APs.
+ /***********************************************************************************/
+ SizeT HardwareThreadScheduler::Capacity() noexcept
+ {
+ return fThreadList.Count();
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/Heap.cc b/dev/Kernel/src/Heap.cc
new file mode 100644
index 00000000..7b2da96d
--- /dev/null
+++ b/dev/Kernel/src/Heap.cc
@@ -0,0 +1,301 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/LPC.h>
+#include <KernelKit/Heap.h>
+#include <NewKit/Crc32.h>
+#include <NewKit/PageMgr.h>
+#include <NewKit/Utils.h>
+#include <ArchKit/ArchKit.h>
+
+/* -------------------------------------------
+
+ Revision History:
+ 10/8/24: FIX: Fix useless long name, alongside a new WR (WriteRead) field.
+ 20/10/24: Fix mm_new_ and mm_delete_ APIs inside Heap.h header. (amlal)
+
+ ------------------------------------------- */
+
+//! @file Heap.cc
+//! @brief This serves as the main memory manager.
+
+#define kKernelHeapMagic (0xD4D7D5)
+#define kKernelHeapAlignSz (__BIGGEST_ALIGNMENT__)
+#define kKernelHeapMaxSize (gib_cast(2))
+
+namespace Kernel
+{
+ /// @brief Contains data structures and algorithms for the heap.
+ namespace Detail
+ {
+ struct PACKED HEAP_INFORMATION_BLOCK;
+
+ /// @brief Kernel heap information block.
+ /// Located before the address bytes.
+ /// | HIB | CLASS/STRUCT/DATA TYPES... |
+ struct PACKED HEAP_INFORMATION_BLOCK final
+ {
+ ///! @brief 32-bit value which contains the magic number of the heap.
+ UInt64 fMagic;
+
+ ///! @brief Boolean value which tells if the heap is allocated.
+ Boolean fPresent : 1;
+
+ /// @brief Is this valued owned by the user?
+ Boolean fWriteRead : 1;
+
+ /// @brief Is this valued owned by the user?
+ Boolean fUser : 1;
+
+ /// @brief Is this a page pointer?
+ Boolean fPagePtr : 1;
+
+ /// @brief 32-bit CRC checksum.
+ UInt32 fCRC32;
+
+ /// @brief 64-bit Allocation flags.
+ UInt64 fFlags;
+
+ /// @brief 64-bit pointer size.
+ SizeT fHeapSize;
+
+ /// @brief 64-bit target offset pointer.
+ UIntPtr fHeapPtr;
+
+ /// @brief Padding bytes for header.
+ UInt8 fPadding[kKernelHeapAlignSz];
+ };
+
+ /// @brief Check for heap address validity.
+ /// @param heap_ptr The address_ptr to check.
+ /// @return Bool if the pointer is valid or not.
+ _Output auto mm_check_heap_address(VoidPtr heap_ptr) -> Bool
+ {
+ if (!heap_ptr)
+ return false;
+
+ /// Add that check in case we're having an integer underflow. ///
+
+ auto base_heap = (IntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK);
+
+ if (base_heap < 0)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ typedef HEAP_INFORMATION_BLOCK* HEAP_INFORMATION_BLOCK_PTR;
+ } // namespace Detail
+
+ /// @brief Declare a new size for ptr_heap.
+ /// @param ptr_heap the pointer.
+ /// @return Newly allocated heap header.
+ _Output VoidPtr mm_realloc_heap(VoidPtr ptr_heap, SizeT new_sz)
+ {
+ if (Detail::mm_check_heap_address(ptr_heap) == No)
+ return nullptr;
+
+ if (!ptr_heap || new_sz < 1)
+ return nullptr;
+
+ kcout << "This function is not implemented by minOSKrnl, please use the BSD's realloc instead.\r";
+ ke_panic(RUNTIME_CHECK_PROCESS);
+
+ return nullptr;
+ }
+
+ /// @brief Allocate chunk of memory.
+ /// @param sz Size of pointer
+ /// @param wr Read Write bit.
+ /// @param user User enable bit.
+ /// @return The newly allocated pointer.
+ _Output VoidPtr mm_new_heap(const SizeT sz, const bool wr, const bool user)
+ {
+ auto sz_fix = sz;
+
+ if (sz_fix == 0)
+ return nullptr;
+
+ // We can't allocate that big now.
+ MUST_PASS(sz < kKernelHeapMaxSize);
+
+ sz_fix += sizeof(Detail::HEAP_INFORMATION_BLOCK);
+
+ PageMgr heap_mgr;
+ auto wrapper = heap_mgr.Request(wr, user, No, sz_fix);
+
+ Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>(
+ wrapper.VirtualAddress() + sizeof(Detail::HEAP_INFORMATION_BLOCK));
+
+ heap_info_ptr->fHeapSize = sz_fix;
+ heap_info_ptr->fMagic = kKernelHeapMagic;
+ heap_info_ptr->fCRC32 = 0; // dont fill it for now.
+ heap_info_ptr->fHeapPtr = reinterpret_cast<UIntPtr>(heap_info_ptr) + sizeof(Detail::HEAP_INFORMATION_BLOCK);
+ heap_info_ptr->fPagePtr = No;
+ heap_info_ptr->fWriteRead = wr;
+ heap_info_ptr->fUser = user;
+ heap_info_ptr->fPresent = Yes;
+
+ rt_set_memory(heap_info_ptr->fPadding, 0, kKernelHeapAlignSz);
+
+ auto result = reinterpret_cast<VoidPtr>(heap_info_ptr->fHeapPtr);
+
+ kcout << "Created Heap address: " << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr)) << endl;
+
+ return result;
+ }
+
+ /// @brief Makes a page heap.
+ /// @param heap_ptr the pointer to make a page heap.
+ /// @return kErrorSuccess if successful, otherwise an error code.
+ _Output Int32 mm_make_page(VoidPtr heap_ptr)
+ {
+ if (Detail::mm_check_heap_address(heap_ptr) == No)
+ return kErrorHeapNotPresent;
+
+ Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>(
+ (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK));
+
+ if (!heap_info_ptr)
+ return kErrorHeapNotPresent;
+
+ heap_info_ptr->fPagePtr = true;
+
+ kcout << "Created page address: " << hex_number(reinterpret_cast<UIntPtr>(heap_info_ptr)) << endl;
+
+ return kErrorSuccess;
+ }
+
+ /// @brief Overwrites and set the flags of a heap header.
+ /// @param heap_ptr the pointer to update.
+ /// @param flags the flags to set.
+ _Output Int32 mm_make_flags(VoidPtr heap_ptr, UInt64 flags)
+ {
+ if (Detail::mm_check_heap_address(heap_ptr) == No)
+ return kErrorHeapNotPresent;
+
+ Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>(
+ (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK));
+
+ if (!heap_info_ptr)
+ return kErrorHeapNotPresent;
+
+ heap_info_ptr->fFlags = flags;
+
+ return kErrorSuccess;
+ }
+
+ /// @brief Gets the flags of a heap header.
+ /// @param heap_ptr the pointer to get.
+ _Output UInt64 mm_get_flags(VoidPtr heap_ptr)
+ {
+ Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>(
+ (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK));
+
+ if (!heap_info_ptr)
+ return kErrorHeapNotPresent;
+
+ return heap_info_ptr->fFlags;
+ }
+
+ /// @brief Declare pointer as free.
+ /// @param heap_ptr the pointer.
+ /// @return
+ _Output Int32 mm_delete_heap(VoidPtr heap_ptr)
+ {
+ if (Detail::mm_check_heap_address(heap_ptr) == No)
+ return kErrorHeapNotPresent;
+
+ Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>(
+ (UIntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK));
+
+ if (heap_info_ptr && heap_info_ptr->fMagic == kKernelHeapMagic)
+ {
+ if (!heap_info_ptr->fPresent)
+ {
+ return kErrorHeapNotPresent;
+ }
+
+ heap_info_ptr->fHeapSize = 0UL;
+ heap_info_ptr->fPresent = No;
+ heap_info_ptr->fHeapPtr = 0;
+ heap_info_ptr->fCRC32 = 0;
+ heap_info_ptr->fWriteRead = No;
+ heap_info_ptr->fUser = No;
+ heap_info_ptr->fMagic = 0;
+
+ PTEWrapper pageWrapper(No, No, No, reinterpret_cast<UIntPtr>(heap_info_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK));
+ Ref<PTEWrapper> pteAddress{pageWrapper};
+
+ PageMgr heap_mgr;
+ heap_mgr.Free(pteAddress);
+
+ kcout << "Freed Heap address successfully." << endl;
+
+ return kErrorSuccess;
+ }
+
+ return kErrorInternal;
+ }
+
+ /// @brief Check if pointer is a valid Kernel pointer.
+ /// @param heap_ptr the pointer
+ /// @return if it exists.
+ _Output Boolean mm_is_valid_heap(VoidPtr heap_ptr)
+ {
+ if (heap_ptr && HAL::mm_is_bitmap(heap_ptr))
+ {
+ Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>(
+ (UIntPtr)(heap_ptr) - sizeof(Detail::HEAP_INFORMATION_BLOCK));
+
+ if (heap_info_ptr && heap_info_ptr->fPresent && heap_info_ptr->fMagic == kKernelHeapMagic)
+ {
+ if (heap_info_ptr->fCRC32 !=
+ ke_calculate_crc32((Char*)heap_info_ptr->fHeapPtr,
+ heap_info_ptr->fHeapSize))
+ {
+ return No;
+ }
+
+ return Yes;
+ }
+ }
+
+ return No;
+ }
+
+ /// @brief Protect the heap with a CRC value.
+ /// @param heap_ptr HIB pointer.
+ /// @return if it valid: point has crc now., otherwise fail.
+ _Output Boolean mm_protect_heap(VoidPtr heap_ptr)
+ {
+ if (heap_ptr)
+ {
+ Detail::HEAP_INFORMATION_BLOCK_PTR heap_info_ptr =
+ reinterpret_cast<Detail::HEAP_INFORMATION_BLOCK_PTR>(
+ (UIntPtr)heap_ptr - sizeof(Detail::HEAP_INFORMATION_BLOCK));
+
+ if (heap_info_ptr && heap_info_ptr->fPresent && kKernelHeapMagic == heap_info_ptr->fMagic)
+ {
+ heap_info_ptr->fCRC32 =
+ ke_calculate_crc32((Char*)heap_info_ptr->fHeapPtr, heap_info_ptr->fHeapSize);
+
+ return Yes;
+ }
+ }
+
+ return No;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/IDylibObject.cc b/dev/Kernel/src/IDylibObject.cc
new file mode 100644
index 00000000..2bd84a2c
--- /dev/null
+++ b/dev/Kernel/src/IDylibObject.cc
@@ -0,0 +1,15 @@
+/*
+ * ========================================================
+ *
+ * minoskrnl
+ * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+ *
+ * ========================================================
+ */
+
+#include <KernelKit/IDylibObject.h>
+#include <KernelKit/DebugOutput.h>
+
+#include <KernelKit/UserProcessScheduler.h>
+
+using namespace Kernel;
diff --git a/dev/Kernel/src/IPEFDylibObject.cc b/dev/Kernel/src/IPEFDylibObject.cc
new file mode 100644
index 00000000..a28f2a94
--- /dev/null
+++ b/dev/Kernel/src/IPEFDylibObject.cc
@@ -0,0 +1,103 @@
+/*
+ * ========================================================
+ *
+ * minoskrnl
+ * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+ *
+ * ========================================================
+ */
+
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/PEF.h>
+#include <KernelKit/IPEFDylibObject.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/ThreadLocalStorage.h>
+#include <NewKit/Defines.h>
+
+/* -------------------------------------------
+
+ Revision History:
+
+ 01/02/24: Reworked dll ABI, expect a rtl_init_dylib and
+ rtl_fini_dylib (amlel) 15/02/24: Breaking changes, changed the name of the
+ routines. (amlel)
+
+ 07/28/24: Replace rt_library_free with rtl_fini_dylib
+
+ 10/8/24: FIX: Fix log comment.
+
+ ------------------------------------------- */
+
+using namespace Kernel;
+
+/***********************************************************************************/
+/// @file IPEFDylibObject.cc
+/// @brief PEF's Dylib runtime.
+/***********************************************************************************/
+
+/***********************************************************************************/
+/** @brief Library initializer. */
+/***********************************************************************************/
+
+EXTERN_C IDylibRef rtl_init_dylib(UserProcess& thread)
+{
+ IDylibRef dll_obj = tls_new_class<IPEFDylibObject>();
+
+ if (!dll_obj)
+ {
+ thread.Crash();
+ return nullptr;
+ }
+
+ dll_obj->Mount(new IPEFDylibObject::DLL_TRAITS());
+
+ if (!dll_obj->Get())
+ {
+ tls_delete_class(dll_obj);
+ thread.Crash();
+
+ return nullptr;
+ }
+
+ dll_obj->Get()->ImageObject =
+ thread.Image.fBlob;
+
+ if (!dll_obj->Get()->ImageObject)
+ {
+ tls_delete_class(dll_obj);
+ thread.Crash();
+
+ return nullptr;
+ }
+
+ dll_obj->Get()->ImageEntrypointOffset =
+ dll_obj->Load<VoidPtr>(kPefStart, rt_string_len(kPefStart, 0), kPefCode);
+
+ return dll_obj;
+}
+
+/***********************************************************************************/
+/** @brief Frees the dll_obj. */
+/** @note Please check if the dll_obj got freed! */
+/** @param dll_obj The dll_obj to free. */
+/** @param successful Reports if successful or not. */
+/***********************************************************************************/
+
+EXTERN_C Void rtl_fini_dylib(UserProcess& thread, IDylibRef dll_obj, Bool* successful)
+{
+ MUST_PASS(successful);
+
+ // sanity check (will also trigger a bug check if this fails)
+ if (dll_obj == nullptr)
+ {
+ *successful = false;
+ thread.Crash();
+ }
+
+ delete dll_obj->Get();
+ delete dll_obj;
+
+ dll_obj = nullptr;
+
+ *successful = true;
+}
diff --git a/dev/Kernel/src/IndexableProperty.cc b/dev/Kernel/src/IndexableProperty.cc
new file mode 100644
index 00000000..2d64e4d7
--- /dev/null
+++ b/dev/Kernel/src/IndexableProperty.cc
@@ -0,0 +1,57 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <CompilerKit/CompilerKit.h>
+#include <FSKit/IndexableProperty.h>
+#include <NewKit/MutableArray.h>
+#include <NewKit/Utils.h>
+
+/// @brief File indexer API for fast path access.
+/// BUGS: 0
+
+#define kMaxLenIndexer (256U)
+
+namespace Kernel
+{
+ namespace Indexer
+ {
+ IndexProperty& IndexableProperty::Leak() noexcept
+ {
+ return fIndex;
+ }
+
+ Void IndexableProperty::AddFlag(Int16 flag)
+ {
+ fFlags |= flag;
+ }
+
+ Void IndexableProperty::RemoveFlag(Int16 flag)
+ {
+ fFlags &= flag;
+ }
+
+ Int16 IndexableProperty::HasFlag(Int16 flag)
+ {
+ return fFlags & flag;
+ }
+
+ /// @brief Index a file into the indexer instance.
+ /// @param filename filesystem path to access.
+ /// @param filenameLen used bytes in path.
+ /// @param indexer the filesystem indexer.
+ /// @return none, check before if indexer can be claimed (using indexer.HasFlag(kIndexerClaimed)).
+ Void fs_index_file(const Char* filename, SizeT filenameLen, IndexableProperty& indexer)
+ {
+ if (!indexer.HasFlag(kIndexerClaimed))
+ {
+ indexer.AddFlag(kIndexerClaimed);
+ rt_copy_memory((VoidPtr)indexer.Leak().Path, (VoidPtr)filename, filenameLen);
+
+ kcout << "FSKit: Indexed new file: " << filename << endl;
+ }
+ }
+ } // namespace Indexer
+} // namespace Kernel
diff --git a/dev/Kernel/src/Json.cc b/dev/Kernel/src/Json.cc
new file mode 100644
index 00000000..9dff3959
--- /dev/null
+++ b/dev/Kernel/src/Json.cc
@@ -0,0 +1,10 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Json.h>
+
+/// @brief Undefined object, is null in length.
+RTL_INIT_OBJECT(Kernel::JSON::kNull, Kernel::JSON);
diff --git a/dev/Kernel/src/KString.cc b/dev/Kernel/src/KString.cc
new file mode 100644
index 00000000..64429c1e
--- /dev/null
+++ b/dev/Kernel/src/KString.cc
@@ -0,0 +1,217 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/KString.h>
+#include <NewKit/Utils.h>
+
+/// @file KString.cc
+/// @brief Kernel String manipulation file.
+
+namespace Kernel
+{
+ Char* KString::Data()
+ {
+ return fData;
+ }
+
+ const Char* KString::CData() const
+ {
+ return fData;
+ }
+
+ Size KString::Length() const
+ {
+ return fDataSz;
+ }
+
+ bool KString::operator==(const KString& rhs) const
+ {
+ if (rhs.Length() != this->Length())
+ return false;
+
+ for (Size index = 0; index < this->Length(); ++index)
+ {
+ if (rhs.fData[index] != fData[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ bool KString::operator==(const Char* rhs) const
+ {
+ if (rt_string_len(rhs) != this->Length())
+ return false;
+
+ for (Size index = 0; index < rt_string_len(rhs); ++index)
+ {
+ if (rhs[index] != fData[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ bool KString::operator!=(const KString& rhs) const
+ {
+ if (rhs.Length() != this->Length())
+ return false;
+
+ for (Size index = 0; index < rhs.Length(); ++index)
+ {
+ if (rhs.fData[index] == fData[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ bool KString::operator!=(const Char* rhs) const
+ {
+ if (rt_string_len(rhs) != this->Length())
+ return false;
+
+ for (Size index = 0; index < rt_string_len(rhs); ++index)
+ {
+ if (rhs[index] == fData[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ ErrorOr<KString> StringBuilder::Construct(const Char* data)
+ {
+ if (!data || *data == 0)
+ return {};
+
+ KString* view = new KString(rt_string_len(data));
+ (*view) += data;
+
+ return ErrorOr<KString>(*view);
+ }
+
+ const Char* StringBuilder::FromBool(const Char* fmt, bool i)
+ {
+ if (!fmt)
+ return ("?");
+
+ const Char* boolean_expr = i ? "YES" : "NO";
+ Char* ret = (Char*)rtl_alloca((sizeof(char) * i) ? 4 : 5 + rt_string_len(fmt));
+
+ if (!ret)
+ return ("?");
+
+ const auto fmt_len = rt_string_len(fmt);
+ const auto res_len = rt_string_len(boolean_expr);
+
+ for (Size idx = 0; idx < fmt_len; ++idx)
+ {
+ if (fmt[idx] == '%')
+ {
+ SizeT result_cnt = idx;
+
+ for (auto y_idx = idx; y_idx < res_len; ++y_idx)
+ {
+ ret[result_cnt] = boolean_expr[y_idx];
+ ++result_cnt;
+ }
+
+ break;
+ }
+
+ ret[idx] = fmt[idx];
+ }
+
+ return ret;
+ }
+
+ bool StringBuilder::Equals(const Char* lhs, const Char* rhs)
+ {
+ if (rt_string_len(rhs) != rt_string_len(lhs))
+ return false;
+
+ for (Size index = 0; index < rt_string_len(rhs); ++index)
+ {
+ if (rhs[index] != lhs[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ bool StringBuilder::Equals(const WideChar* lhs, const WideChar* rhs)
+ {
+ for (Size index = 0; rhs[index] != 0; ++index)
+ {
+ if (rhs[index] != lhs[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ const Char* StringBuilder::Format(const Char* fmt, const Char* fmt2)
+ {
+ if (!fmt || !fmt2)
+ return ("?");
+
+ Char* ret =
+ (Char*)rtl_alloca(sizeof(char) * rt_string_len(fmt2) + rt_string_len(fmt));
+
+ if (!ret)
+ return ("?");
+
+ for (Size idx = 0; idx < rt_string_len(fmt); ++idx)
+ {
+ if (fmt[idx] == '%')
+ {
+ Size result_cnt = idx;
+ for (Size y_idx = 0; y_idx < rt_string_len(fmt2); ++y_idx)
+ {
+ ret[result_cnt] = fmt2[y_idx];
+ ++result_cnt;
+ }
+
+ break;
+ }
+
+ ret[idx] = fmt[idx];
+ }
+
+ return ret;
+ }
+
+ STATIC void rt_string_append(Char* lhs, const Char* rhs, Int32 cur)
+ {
+ SizeT sz_rhs = rt_string_len(rhs);
+ SizeT rhs_i = 0;
+
+ for (; rhs_i < sz_rhs; ++rhs_i)
+ {
+ lhs[rhs_i + cur] = rhs[rhs_i];
+ }
+ }
+
+ KString& KString::operator+=(const Char* rhs)
+ {
+ rt_string_append(this->fData, rhs, this->fCur);
+ this->fCur += rt_string_len(rhs);
+
+ return *this;
+ }
+
+ KString& KString::operator+=(const KString& rhs)
+ {
+ if (rt_string_len(rhs.fData) > this->Length())
+ return *this;
+
+ rt_string_append(this->fData, const_cast<Char*>(rhs.fData), this->fCur);
+ this->fCur += rt_string_len(const_cast<Char*>(rhs.fData));
+
+ return *this;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/KernelMain.cc b/dev/Kernel/src/KernelMain.cc
new file mode 100644
index 00000000..7875fa7c
--- /dev/null
+++ b/dev/Kernel/src/KernelMain.cc
@@ -0,0 +1,102 @@
+/* -------------------------------------------
+
+ Copyright Amlal EL Mahrouss
+
+ File: Main.cxx
+ Purpose: Main entrypoint of kernel.
+
+------------------------------------------- */
+
+#include <KernelKit/PE.h>
+#include <ArchKit/ArchKit.h>
+#include <CompilerKit/Detail.h>
+#include <FirmwareKit/Handover.h>
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/Heap.h>
+#include <KernelKit/PEF.h>
+#include <KernelKit/PEFCodeMgr.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/Heap.h>
+#include <NewKit/Json.h>
+#include <NewKit/KString.h>
+#include <NewKit/Utils.h>
+#include <KernelKit/CodeMgr.h>
+#include <CFKit/Property.h>
+#include <KernelKit/Timer.h>
+
+#ifdef __ZKA_AUTO_FORMAT__
+namespace Kernel::Detail
+{
+ /// @brief Filesystem auto formatter, additional checks are also done by the class.
+ class NeFilesystemInstaller final
+ {
+ private:
+ Kernel::NeFileSystemParser* mNeFS{nullptr};
+ Kernel::NeFileSystemJournal mJournal;
+
+ public:
+ /// @brief wizard constructor.
+ explicit NeFilesystemInstaller()
+ {
+ mNeFS = new Kernel::NeFileSystemParser();
+
+ if (mNeFS)
+ {
+ const SizeT kFolderCount = 13;
+ const Char* kFolderStr[kFolderCount] = {
+ "/", "/boot/", "/sys/", "/media/", "/etc/",
+ "/usr/", "/lib/", "/mnt/", "/sbin/", "/n/", "/dev/", "/run/", "/root/"};
+
+ for (Kernel::SizeT dir_index = 0UL; dir_index < kFolderCount; ++dir_index)
+ {
+ auto catalog_folder = mNeFS->GetCatalog(kFolderStr[dir_index]);
+
+ if (catalog_folder)
+ {
+ delete catalog_folder;
+ catalog_folder = nullptr;
+
+ continue;
+ }
+
+ catalog_folder = mNeFS->CreateCatalog(kFolderStr[dir_index], 0,
+ kNeFSCatalogKindDir);
+
+ if (!catalog_folder)
+ continue;
+
+ delete catalog_folder;
+ catalog_folder = nullptr;
+ }
+
+ if (!mJournal.GetJournal(mNeFS))
+ mJournal.CreateJournal(mNeFS);
+
+ mJournal.CommitJournal(mNeFS, "<LOG_XML><FS>NeFS</FS></LOG_XML>", "NeFS Format System");
+ mJournal.ReleaseJournal();
+ }
+ }
+
+ ~NeFilesystemInstaller()
+ {
+ if (mNeFS)
+ delete mNeFS;
+
+ mNeFS = nullptr;
+ }
+
+ ZKA_COPY_DEFAULT(NeFilesystemInstaller);
+ };
+} // namespace Kernel::Detail
+#endif // ifdef __ZKA_AUTO_FORMAT__
+
+/// @brief Kernel entrypoint.
+/// @param Void
+/// @return Void
+EXTERN_C Kernel::Void rtl_kernel_main(Kernel::SizeT argc, char** argv, char** envp, Kernel::SizeT envp_len)
+{
+#ifdef __ZKA_AUTO_FORMAT__
+ Kernel::NeFS::fs_init_nefs();
+ Kernel::Detail::NeFilesystemInstaller installer{};
+#endif // __ZKA_AUTO_FORMAT__
+}
diff --git a/dev/Kernel/src/LPC.cc b/dev/Kernel/src/LPC.cc
new file mode 100644
index 00000000..6d614672
--- /dev/null
+++ b/dev/Kernel/src/LPC.cc
@@ -0,0 +1,34 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/LPC.h>
+#include <NewKit/KernelPanic.h>
+
+namespace Kernel
+{
+ STATIC Bool kRaiseOnBugCheck = false;
+
+ /// @brief Does a system wide bug check.
+ /// @param void no params.
+ /// @return if error-free: false, otherwise true.
+ Boolean err_bug_check(void) noexcept
+ {
+ if (kRaiseOnBugCheck)
+ {
+ ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR);
+ }
+
+ return No;
+ }
+
+ /// @brief Tells if we should raise a bug check not.
+ /// @param void
+ /// @return void
+ Void err_bug_check_raise(Void) noexcept
+ {
+ kRaiseOnBugCheck = true;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/LockDelegate.cc b/dev/Kernel/src/LockDelegate.cc
new file mode 100644
index 00000000..8f9a4b1a
--- /dev/null
+++ b/dev/Kernel/src/LockDelegate.cc
@@ -0,0 +1,12 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/LockDelegate.h>
+
+namespace Kernel
+{
+ /// @note Leave it empty for now.
+} // namespace Kernel
diff --git a/dev/Kernel/src/MutableArray.cc b/dev/Kernel/src/MutableArray.cc
new file mode 100644
index 00000000..aa3c76a2
--- /dev/null
+++ b/dev/Kernel/src/MutableArray.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/MutableArray.h>
diff --git a/dev/Kernel/src/Network/IPAddr.cc b/dev/Kernel/src/Network/IPAddr.cc
new file mode 100644
index 00000000..ee9cbc43
--- /dev/null
+++ b/dev/Kernel/src/Network/IPAddr.cc
@@ -0,0 +1,129 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NetworkKit/IP.h>
+#include <NewKit/Utils.h>
+
+namespace Kernel
+{
+ char* RawIPAddress::Address()
+ {
+ return fAddr;
+ }
+
+ RawIPAddress::RawIPAddress(char bytes[4])
+ {
+ rt_copy_memory(bytes, fAddr, 4);
+ }
+
+ bool RawIPAddress::operator==(const RawIPAddress& ipv4)
+ {
+ for (Size index = 0; index < 4; ++index)
+ {
+ if (ipv4.fAddr[index] != fAddr[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ bool RawIPAddress::operator!=(const RawIPAddress& ipv4)
+ {
+ for (Size index = 0; index < 4; ++index)
+ {
+ if (ipv4.fAddr[index] == fAddr[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ char& RawIPAddress::operator[](const Size& index)
+ {
+ kcout << "[RawIPAddress::operator[]] Fetching Index...\r";
+
+ static char IP_PLACEHOLDER = '0';
+ if (index > 4)
+ return IP_PLACEHOLDER;
+
+ return fAddr[index];
+ }
+
+ RawIPAddress6::RawIPAddress6(char bytes[8])
+ {
+ rt_copy_memory(bytes, fAddr, 8);
+ }
+
+ char& RawIPAddress6::operator[](const Size& index)
+ {
+ kcout << "[RawIPAddress6::operator[]] Fetching Index...\r";
+
+ static char IP_PLACEHOLDER = '0';
+ if (index > 8)
+ return IP_PLACEHOLDER;
+
+ return fAddr[index];
+ }
+
+ bool RawIPAddress6::operator==(const RawIPAddress6& ipv6)
+ {
+ for (SizeT index = 0; index < 8; ++index)
+ {
+ if (ipv6.fAddr[index] != fAddr[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ bool RawIPAddress6::operator!=(const RawIPAddress6& ipv6)
+ {
+ for (SizeT index = 0; index < 8; ++index)
+ {
+ if (ipv6.fAddr[index] == fAddr[index])
+ return false;
+ }
+
+ return true;
+ }
+
+ ErrorOr<KString> IPFactory::ToKString(Ref<RawIPAddress6>& ipv6)
+ {
+ auto str = StringBuilder::Construct(ipv6.Leak().Address());
+ return str;
+ }
+
+ ErrorOr<KString> IPFactory::ToKString(Ref<RawIPAddress>& ipv4)
+ {
+ auto str = StringBuilder::Construct(ipv4.Leak().Address());
+ return str;
+ }
+
+ bool IPFactory::IpCheckVersion4(const Char* ip)
+ {
+ if (!ip)
+ return NO;
+
+ Int32 cnter = 0;
+
+ for (SizeT base = 0; base < rt_string_len(ip); ++base)
+ {
+ if (ip[base] == '.')
+ {
+ cnter = 0;
+ }
+ else
+ {
+ if (cnter == 3)
+ return false;
+
+ ++cnter;
+ }
+ }
+
+ return true;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/Network/IPCAddr.cc b/dev/Kernel/src/Network/IPCAddr.cc
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/Kernel/src/Network/IPCAddr.cc
diff --git a/dev/Kernel/src/Network/IPCMsg.cc b/dev/Kernel/src/Network/IPCMsg.cc
new file mode 100644
index 00000000..5e94b050
--- /dev/null
+++ b/dev/Kernel/src/Network/IPCMsg.cc
@@ -0,0 +1,102 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NetworkKit/IPC.h>
+#include <KernelKit/LPC.h>
+#include <KernelKit/UserProcessScheduler.h>
+
+namespace Kernel
+{
+ /// @internal
+ /// @brief The internal sanitize function.
+ Bool ipc_int_sanitize_packet(IPC_MSG* pckt)
+ {
+ auto endian = rtl_deduce_endianess(pckt, ((Char*)pckt)[0]);
+
+ switch (endian)
+ {
+ case Endian::kEndianBig: {
+ if (pckt->IpcEndianess == kIPCLittleEndian)
+ goto ipc_check_failed;
+
+ break;
+ }
+ case Endian::kEndianLittle: {
+ if (pckt->IpcEndianess == kIPCBigEndian)
+ goto ipc_check_failed;
+
+ break;
+ }
+ case Endian::kEndianMixed: {
+ if (pckt->IpcEndianess == kIPCMixedEndian)
+ goto ipc_check_failed;
+
+ break;
+ }
+ default:
+ goto ipc_check_failed;
+ }
+
+ if (pckt->IpcFrom == pckt->IpcTo ||
+ pckt->IpcPacketSize > kIPCMsgSize)
+ {
+ goto ipc_check_failed;
+ }
+
+ return pckt->IpcPacketSize > 1 && pckt->IpcHeaderMagic == kIPCHeaderMagic;
+
+ ipc_check_failed:
+ err_local_get() = kErrorIPC;
+ return false;
+ }
+
+ /// @brief Sanitize packet function
+ /// @retval true packet is correct.
+ /// @retval false packet is incorrect and process has crashed.
+ Bool ipc_sanitize_packet(IPC_MSG* pckt)
+ {
+ if (!pckt ||
+ !ipc_int_sanitize_packet(pckt))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /// @brief Construct packet function
+ /// @retval true packet is correct.
+ /// @retval false packet is incorrect and process has crashed.
+ Bool ipc_construct_packet(_Output IPC_MSG** pckt_in)
+ {
+ // don't act if it's not even valid.
+ if (!pckt_in)
+ return false;
+
+ if (!*pckt_in)
+ *pckt_in = new IPC_MSG();
+
+ if (*pckt_in)
+ {
+ auto endian = rtl_deduce_endianess((*pckt_in), ((Char*)(*pckt_in))[0]);
+
+ (*pckt_in)->IpcHeaderMagic = kIPCHeaderMagic;
+
+ (*pckt_in)->IpcEndianess = static_cast<UInt8>(endian);
+ (*pckt_in)->IpcPacketSize = sizeof(IPC_MSG);
+
+ (*pckt_in)->IpcTo.UserProcessID = 0;
+ (*pckt_in)->IpcTo.UserProcessTeam = 0;
+
+ (*pckt_in)->IpcFrom.UserProcessID = 0;
+ (*pckt_in)->IpcFrom.UserProcessTeam = 0;
+
+ return Yes;
+ }
+
+ return No;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/Network/NetworkDevice.cc b/dev/Kernel/src/Network/NetworkDevice.cc
new file mode 100644
index 00000000..2df3af0b
--- /dev/null
+++ b/dev/Kernel/src/Network/NetworkDevice.cc
@@ -0,0 +1,35 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NetworkKit/NetworkDevice.h>
+#include <NewKit/Utils.h>
+
+namespace Kernel
+{
+ /// \brief Getter for fNetworkName.
+ const Char* NetworkDevice::Name() const
+ {
+ return this->fNetworkName;
+ }
+
+ /// \brief Setter for fNetworkName.
+ Boolean NetworkDevice::Name(const Char* strView)
+ {
+ if (strView == nullptr)
+ return false;
+
+ if (*strView == 0)
+ return false;
+
+ if (rt_string_len(strView) > cNetworkNameLen)
+ return false;
+
+ rt_copy_memory((VoidPtr)strView,
+ (VoidPtr)this->fNetworkName, rt_string_len(strView));
+
+ return true;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/New+Delete.cc b/dev/Kernel/src/New+Delete.cc
new file mode 100644
index 00000000..0394112e
--- /dev/null
+++ b/dev/Kernel/src/New+Delete.cc
@@ -0,0 +1,50 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/Heap.h>
+#include <NewKit/New.h>
+
+void* operator new[](size_t sz)
+{
+ if (sz == 0)
+ ++sz;
+
+ return Kernel::mm_new_heap(sz, true, false);
+}
+
+void* operator new(size_t sz)
+{
+ if (sz == 0)
+ ++sz;
+
+ return Kernel::mm_new_heap(sz, true, false);
+}
+
+void operator delete[](void* ptr)
+{
+ if (ptr == nullptr)
+ return;
+
+ Kernel::mm_delete_heap(ptr);
+}
+
+void operator delete(void* ptr)
+{
+ if (ptr == nullptr)
+ return;
+
+ Kernel::mm_delete_heap(ptr);
+}
+
+void operator delete(void* ptr, size_t sz)
+{
+ if (ptr == nullptr)
+ return;
+
+ ZKA_UNUSED(sz);
+
+ Kernel::mm_delete_heap(ptr);
+}
diff --git a/dev/Kernel/src/OwnPtr.cc b/dev/Kernel/src/OwnPtr.cc
new file mode 100644
index 00000000..4feac5b6
--- /dev/null
+++ b/dev/Kernel/src/OwnPtr.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/OwnPtr.h>
diff --git a/dev/Kernel/src/PEFCodeMgr.cc b/dev/Kernel/src/PEFCodeMgr.cc
new file mode 100644
index 00000000..8bcceeee
--- /dev/null
+++ b/dev/Kernel/src/PEFCodeMgr.cc
@@ -0,0 +1,268 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DebugOutput.h>
+#include <KernelKit/Heap.h>
+#include <KernelKit/PEFCodeMgr.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <NewKit/Defines.h>
+#include <NewKit/KernelPanic.h>
+#include <NewKit/OwnPtr.h>
+#include <NewKit/KString.h>
+
+/// @brief PEF stack size symbol.
+#define kPefStackSizeSymbol "__PEFSizeOfReserveStack"
+#define kPefHeapSizeSymbol "__PEFSizeOfReserveHeap"
+#define kPefNameSymbol "__PEFProgramName"
+
+namespace Kernel
+{
+ namespace Detail
+ {
+ /***********************************************************************************/
+ /// @brief Get the PEF platform signature according to the compiled architecture.
+ /***********************************************************************************/
+ UInt32 ldr_get_platform(void) noexcept
+ {
+#if defined(__ZKA_32X0__)
+ return kPefArch32x0;
+#elif defined(__ZKA_64X0__)
+ return kPefArch64x0;
+#elif defined(__ZKA_AMD64__)
+ return kPefArchAMD64;
+#elif defined(__ZKA_PPC64__)
+ return kPefArchPowerPC;
+#elif defined(__ZKA_ARM64__)
+ return kPefArchARM64;
+#else
+ return kPefArchInvalid;
+#endif // __32x0__ || __64x0__ || __x86_64__
+ }
+ } // namespace Detail
+
+ /***********************************************************************************/
+ /// @brief PEF loader constructor w/ blob.
+ /// @param blob file blob.
+ /***********************************************************************************/
+ PEFLoader::PEFLoader(const VoidPtr blob)
+ : fCachedBlob(blob)
+ {
+ MUST_PASS(fCachedBlob);
+ fBad = false;
+ }
+
+ /***********************************************************************************/
+ /// @brief PEF loader constructor.
+ /// @param path the filesystem path.
+ /***********************************************************************************/
+ PEFLoader::PEFLoader(const Char* path)
+ : fCachedBlob(nullptr), fBad(false), fFatBinary(false)
+ {
+ fFile.New(const_cast<Char*>(path), kRestrictRB);
+ fPath = StringBuilder::Construct(path).Leak();
+
+ auto kPefHeader = "PEF_CONTAINER";
+
+ fCachedBlob = fFile->Read(kPefHeader, mib_cast(16));
+
+ PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
+
+ if (container->Cpu == Detail::ldr_get_platform() &&
+ container->Magic[0] == kPefMagic[0] &&
+ container->Magic[1] == kPefMagic[1] &&
+ container->Magic[2] == kPefMagic[2] &&
+ container->Magic[3] == kPefMagic[3] &&
+ container->Magic[4] == kPefMagic[4] && container->Abi == kPefAbi)
+ {
+ return;
+ }
+ else if (container->Magic[4] == kPefMagic[0] &&
+ container->Magic[3] == kPefMagic[1] &&
+ container->Magic[2] == kPefMagic[2] &&
+ container->Magic[1] == kPefMagic[3] &&
+ container->Magic[0] == kPefMagic[4] && container->Abi == kPefAbi)
+ {
+ /// This is a fat binary.
+ this->fFatBinary = true;
+ return;
+ }
+
+ fBad = true;
+
+ if (fCachedBlob)
+ mm_delete_heap(fCachedBlob);
+
+ kcout << "PEFLoader: warn: Executable format error!\r";
+
+ fCachedBlob = nullptr;
+ }
+
+ /***********************************************************************************/
+ /// @brief PEF destructor.
+ /***********************************************************************************/
+ PEFLoader::~PEFLoader()
+ {
+ if (fCachedBlob)
+ mm_delete_heap(fCachedBlob);
+
+ fFile.Delete();
+ }
+
+ /***********************************************************************************/
+ /// @brief Finds the symbol according to it's name.
+ /// @param name name of symbol.
+ /// @param kind kind of symbol we want.
+ /***********************************************************************************/
+ VoidPtr PEFLoader::FindSymbol(const Char* name, Int32 kind)
+ {
+ if (!fCachedBlob || fBad || !name)
+ return nullptr;
+
+ PEFContainer* container = reinterpret_cast<PEFContainer*>(fCachedBlob);
+
+ auto blob = fFile->Read(name, mib_cast(16));
+
+ PEFCommandHeader* container_header = reinterpret_cast<PEFCommandHeader*>(blob);
+
+ constexpr auto cMangleCharacter = '$';
+ const Char* cContainerKinds[] = {".code64", ".data64", ".zero64", nullptr};
+
+ ErrorOr<KString> error_or_symbol;
+
+ switch (kind)
+ {
+ case kPefCode: {
+ error_or_symbol = StringBuilder::Construct(cContainerKinds[0]); // code symbol.
+ break;
+ }
+ case kPefData: {
+ error_or_symbol = StringBuilder::Construct(cContainerKinds[1]); // data symbol.
+ break;
+ }
+ case kPefZero: {
+ error_or_symbol = StringBuilder::Construct(cContainerKinds[2]); // block starting symbol.
+ break;
+ }
+ default:
+ return nullptr; // prevent that from the kernel's mode perspective, let that happen if it were
+ // a user process.
+ }
+
+ Char* unconst_symbol = const_cast<Char*>(name);
+
+ for (SizeT i = 0UL; i < rt_string_len(unconst_symbol, kPefNameLen); ++i)
+ {
+ if (unconst_symbol[i] == ' ')
+ {
+ unconst_symbol[i] = cMangleCharacter;
+ }
+ }
+
+ error_or_symbol.Leak().Leak() += name;
+
+ for (SizeT index = 0; index < container->Count; ++index)
+ {
+ if (StringBuilder::Equals(container_header->Name,
+ error_or_symbol.Leak().Leak().CData()))
+ {
+ if (container_header->Kind == kind)
+ {
+ if (container_header->Cpu != Detail::ldr_get_platform())
+ {
+ if (!this->fFatBinary)
+ {
+ mm_delete_heap(blob);
+ return nullptr;
+ }
+ }
+
+ Char* container_blob_value = new Char[container_header->Size];
+
+ rt_copy_memory((VoidPtr)((Char*)blob + sizeof(PEFCommandHeader)), container_blob_value, container_header->Size);
+ mm_delete_heap(blob);
+
+ kcout << "PEFLoader: INFO: Load stub: " << container_header->Name << "!\r";
+
+ return container_blob_value;
+ }
+ }
+ }
+
+ mm_delete_heap(blob);
+ return nullptr;
+ }
+
+ /// @brief Finds the executable entrypoint.
+ /// @return
+ ErrorOr<VoidPtr> PEFLoader::FindStart()
+ {
+ if (auto sym = this->FindSymbol(kPefStart, kPefCode); sym)
+ return ErrorOr<VoidPtr>(sym);
+
+ return ErrorOr<VoidPtr>(kErrorExecutable);
+ }
+
+ /// @brief Tells if the executable is loaded or not.
+ /// @return
+ bool PEFLoader::IsLoaded() noexcept
+ {
+ return !fBad && fCachedBlob;
+ }
+
+ const Char* PEFLoader::Path()
+ {
+ return fPath.Leak().CData();
+ }
+
+ const Char* PEFLoader::AsString()
+ {
+#ifdef __32x0__
+ return "32x0 PEF executable.";
+#elif defined(__64x0__)
+ return "64x0 PEF executable.";
+#elif defined(__x86_64__)
+ return "x86_64 PEF executable.";
+#elif defined(__aarch64__)
+ return "AARCH64 PEF executable.";
+#elif defined(__powerpc64__)
+ return "POWER64 PEF executable.";
+#else
+ return "???? PEF executable.";
+#endif // __32x0__ || __64x0__ || __x86_64__ || __powerpc64__
+ }
+
+ const Char* PEFLoader::MIME()
+ {
+ return kPefApplicationMime;
+ }
+
+ ErrorOr<VoidPtr> PEFLoader::GetBlob()
+ {
+ return ErrorOr<VoidPtr>{this->fCachedBlob};
+ }
+
+ namespace Utils
+ {
+ ProcessID rtl_create_process(PEFLoader& exec, const Int32& process_kind) noexcept
+ {
+ auto errOrStart = exec.FindStart();
+
+ if (errOrStart.Error() != kErrorSuccess)
+ return kProcessInvalidID;
+
+ auto id = UserProcessScheduler::The().Spawn(reinterpret_cast<const Char*>(exec.FindSymbol(kPefNameSymbol, kPefData)), errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak());
+
+ if (id != kProcessInvalidID)
+ {
+ UserProcessScheduler::The().CurrentTeam().AsArray()[id].Kind = process_kind;
+ UserProcessScheduler::The().CurrentTeam().AsArray()[id].StackSize = *(UIntPtr*)exec.FindSymbol(kPefStackSizeSymbol, kPefData);
+ UserProcessScheduler::The().CurrentTeam().AsArray()[id].MemoryLimit = *(UIntPtr*)exec.FindSymbol(kPefHeapSizeSymbol, kPefData);
+ }
+
+ return id;
+ }
+ } // namespace Utils
+} // namespace Kernel
diff --git a/dev/Kernel/src/PRDT.cc b/dev/Kernel/src/PRDT.cc
new file mode 100644
index 00000000..e0403bce
--- /dev/null
+++ b/dev/Kernel/src/PRDT.cc
@@ -0,0 +1,24 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DebugOutput.h>
+#include <NewKit/KString.h>
+#include <StorageKit/PRDT.h>
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /// @brief constructs a new PRD.
+ /// @param prd PRD reference.
+ /// @note This doesnt construct a valid, please fill it by yourself.
+ /***********************************************************************************/
+ void construct_prdt(Ref<PRDT>& prd)
+ {
+ prd.Leak().fPhysAddress = 0x0;
+ prd.Leak().fSectorCount = 0x0;
+ prd.Leak().fEndBit = 0x0;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/PageMgr.cc b/dev/Kernel/src/PageMgr.cc
new file mode 100644
index 00000000..9ba0ed4a
--- /dev/null
+++ b/dev/Kernel/src/PageMgr.cc
@@ -0,0 +1,110 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DebugOutput.h>
+#include <NewKit/PageMgr.h>
+
+#ifdef __ZKA_AMD64__
+#include <HALKit/AMD64/Paging.h>
+#elif defined(__ZKA_ARM64__)
+#include <HALKit/ARM64/Paging.h>
+#endif // ifdef __ZKA_AMD64__ || defined(__ZKA_ARM64__)
+
+namespace Kernel
+{
+ PTEWrapper::PTEWrapper(Boolean Rw, Boolean User, Boolean ExecDisable, UIntPtr VirtAddr)
+ : fRw(Rw),
+ fUser(User),
+ fExecDisable(ExecDisable),
+ fVirtAddr(VirtAddr),
+ fCache(false),
+ fShareable(false),
+ fWt(false),
+ fPresent(true),
+ fAccessed(false)
+ {
+ }
+
+ PTEWrapper::~PTEWrapper() = default;
+
+ /// @brief Flush virtual address.
+ /// @param VirtAddr
+ Void PageMgr::FlushTLB()
+ {
+#ifndef __ZKA_MINIMAL_OS__
+ hal_flush_tlb();
+#endif // !__ZKA_MINIMAL_OS__
+ }
+
+ /// @brief Reclaim freed page.
+ /// @return
+ Bool PTEWrapper::Reclaim()
+ {
+ if (!this->fPresent)
+ {
+ this->fPresent = true;
+ return true;
+ }
+
+ return false;
+ }
+
+ /// @brief Request a PTE.
+ /// @param Rw r/w?
+ /// @param User user mode?
+ /// @param ExecDisable disable execution on page?
+ /// @return
+ PTEWrapper PageMgr::Request(Boolean Rw, Boolean User, Boolean ExecDisable, SizeT Sz)
+ {
+ // Store PTE wrapper right after PTE.
+ VoidPtr ptr = Kernel::HAL::mm_alloc_bitmap(Rw, User, Sz, false);
+
+ return PTEWrapper{Rw, User, ExecDisable, reinterpret_cast<UIntPtr>(ptr)};
+ }
+
+ /// @brief Disable BitMap.
+ /// @param wrapper the wrapper.
+ /// @return If the page bitmap was cleared or not.
+ Bool PageMgr::Free(Ref<PTEWrapper>& wrapper)
+ {
+ if (!Kernel::HAL::mm_free_bitmap((VoidPtr)wrapper.Leak().VirtualAddress()))
+ return false;
+
+ return true;
+ }
+
+ /// @brief Virtual PTE address.
+ /// @return The virtual address of the page.
+ const UIntPtr PTEWrapper::VirtualAddress()
+ {
+ return (fVirtAddr);
+ }
+
+ Bool PTEWrapper::Shareable()
+ {
+ return fShareable;
+ }
+
+ Bool PTEWrapper::Present()
+ {
+ return fPresent;
+ }
+
+ Bool PTEWrapper::Access()
+ {
+ return fAccessed;
+ }
+
+ Void PTEWrapper::NoExecute(const bool enable)
+ {
+ fExecDisable = enable;
+ }
+
+ Bool PTEWrapper::NoExecute()
+ {
+ return fExecDisable;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/Pmm.cc b/dev/Kernel/src/Pmm.cc
new file mode 100644
index 00000000..ffe58a26
--- /dev/null
+++ b/dev/Kernel/src/Pmm.cc
@@ -0,0 +1,98 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/DebugOutput.h>
+#include <NewKit/Pmm.h>
+
+#if defined(__ZKA_ARM64__)
+#include <HALKit/ARM64/Processor.h>
+#endif // defined(__ZKA_ARM64__)
+
+#if defined(__ZKA_AMD64__)
+#include <HALKit/AMD64/Processor.h>
+#endif // defined(__ZKA_AMD64__)
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /// @brief Pmm constructor.
+ /***********************************************************************************/
+ Pmm::Pmm()
+ : fPageMgr()
+ {
+ kcout << "[PMM] Allocate PageMemoryMgr";
+ }
+
+ Pmm::~Pmm() = default;
+
+ /***********************************************************************************/
+ /// @param If this returns Null pointer, enter emergency mode.
+ /// @param user is this a user page?
+ /// @param readWrite is it r/w?
+ /***********************************************************************************/
+ Ref<PTEWrapper> Pmm::RequestPage(Boolean user, Boolean readWrite)
+ {
+ PTEWrapper pt = fPageMgr.Leak().Request(user, readWrite, false, kPageSize);
+
+ if (pt.fPresent)
+ {
+ kcout << "[PMM]: Allocation failed.\r";
+ return {};
+ }
+
+ return Ref<PTEWrapper>(pt);
+ }
+
+ Boolean Pmm::FreePage(Ref<PTEWrapper> PageRef)
+ {
+ if (!PageRef)
+ return false;
+
+ PageRef.Leak().fPresent = false;
+
+ return true;
+ }
+
+ Boolean Pmm::TogglePresent(Ref<PTEWrapper> PageRef, Boolean Enable)
+ {
+ if (!PageRef)
+ return false;
+
+ PageRef.Leak().fPresent = Enable;
+
+ return true;
+ }
+
+ Boolean Pmm::ToggleUser(Ref<PTEWrapper> PageRef, Boolean Enable)
+ {
+ if (!PageRef)
+ return false;
+
+ PageRef.Leak().fRw = Enable;
+
+ return true;
+ }
+
+ Boolean Pmm::ToggleRw(Ref<PTEWrapper> PageRef, Boolean Enable)
+ {
+ if (!PageRef)
+ return false;
+
+ PageRef.Leak().fRw = Enable;
+
+ return true;
+ }
+
+ Boolean Pmm::ToggleShare(Ref<PTEWrapper> PageRef, Boolean Enable)
+ {
+ if (!PageRef)
+ return false;
+
+ PageRef.Leak().fShareable = Enable;
+
+ return true;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/Property.cc b/dev/Kernel/src/Property.cc
new file mode 100644
index 00000000..6ff430c1
--- /dev/null
+++ b/dev/Kernel/src/Property.cc
@@ -0,0 +1,45 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <CFKit/Property.h>
+
+namespace CFKit
+{
+ /***********************************************************************************/
+ /// @brief Destructor.
+ /***********************************************************************************/
+ Property::~Property() = default;
+
+ /***********************************************************************************/
+ /// @brief Constructor.
+ /***********************************************************************************/
+ Property::Property() = default;
+
+ /***********************************************************************************/
+ /// @brief Check if property's name equals to name.
+ /// @param name string to check.
+ /***********************************************************************************/
+ Bool Property::StringEquals(KString& name)
+ {
+ return this->fName && this->fName == name;
+ }
+
+ /***********************************************************************************/
+ /// @brief Gets the key (name) of property.
+ /***********************************************************************************/
+ KString& Property::GetKey()
+ {
+ return this->fName;
+ }
+
+ /***********************************************************************************/
+ /// @brief Gets the value of the property.
+ /***********************************************************************************/
+ PropertyId& Property::GetValue()
+ {
+ return fValue;
+ }
+} // namespace CFKit
diff --git a/dev/Kernel/src/Ref.cc b/dev/Kernel/src/Ref.cc
new file mode 100644
index 00000000..c25aa786
--- /dev/null
+++ b/dev/Kernel/src/Ref.cc
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Ref.h>
diff --git a/dev/Kernel/src/Semaphore.cc b/dev/Kernel/src/Semaphore.cc
new file mode 100644
index 00000000..b82efbfe
--- /dev/null
+++ b/dev/Kernel/src/Semaphore.cc
@@ -0,0 +1,69 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/Semaphore.h>
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /// @brief Unlocks process out of the semaphore.
+ /***********************************************************************************/
+ Bool Semaphore::Unlock() noexcept
+ {
+ if (fLockingProcess)
+ fLockingProcess = UserProcess();
+ else
+ return No;
+
+ return Yes;
+ }
+
+ /***********************************************************************************/
+ /// @brief Locks process in the semaphore.
+ /***********************************************************************************/
+ Bool Semaphore::Lock(UserProcess& process)
+ {
+ if (!process || fLockingProcess)
+ return No;
+
+ fLockingProcess = process;
+
+ return Yes;
+ }
+
+ /***********************************************************************************/
+ /// @brief Checks if process is locked.
+ /***********************************************************************************/
+ Bool Semaphore::IsLocked() const
+ {
+ return fLockingProcess;
+ }
+
+ /***********************************************************************************/
+ /// @brief Try lock or wait.
+ /***********************************************************************************/
+ Bool Semaphore::LockOrWait(UserProcess& process, TimerInterface* timer)
+ {
+ if (timer == nullptr)
+ return No;
+
+ this->Lock(process);
+
+ timer->Wait();
+
+ return this->Lock(process);
+ }
+
+ /***********************************************************************************/
+ /// @brief Wait for process to be free.
+ /***********************************************************************************/
+ Void Semaphore::WaitForProcess() noexcept
+ {
+ while (fLockingProcess)
+ ;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/SoftwareTimer.cc b/dev/Kernel/src/SoftwareTimer.cc
new file mode 100644
index 00000000..445ede07
--- /dev/null
+++ b/dev/Kernel/src/SoftwareTimer.cc
@@ -0,0 +1,39 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/Timer.h>
+
+/// @brief SoftwareTimer class, meant to be generic.
+
+using namespace Kernel;
+
+SoftwareTimer::SoftwareTimer(Int64 seconds)
+ : fWaitFor(seconds)
+{
+ fDigitalTimer = new IntPtr();
+ MUST_PASS(fDigitalTimer);
+}
+
+SoftwareTimer::~SoftwareTimer()
+{
+ delete fDigitalTimer;
+ fDigitalTimer = nullptr;
+
+ fWaitFor = 0;
+}
+
+BOOL SoftwareTimer::Wait() noexcept
+{
+ if (fWaitFor < 1)
+ return NO;
+
+ while (*fDigitalTimer < (*fDigitalTimer + fWaitFor))
+ {
+ ++(*fDigitalTimer);
+ }
+
+ return YES;
+}
diff --git a/dev/Kernel/src/Storage/AHCIDeviceInterface.cc b/dev/Kernel/src/Storage/AHCIDeviceInterface.cc
new file mode 100644
index 00000000..7f7392a2
--- /dev/null
+++ b/dev/Kernel/src/Storage/AHCIDeviceInterface.cc
@@ -0,0 +1,35 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <StorageKit/AHCI.h>
+
+using namespace Kernel;
+
+/// @brief Class constructor
+/// @param Out Drive output
+/// @param In Drive input
+/// @param Cleanup Drive cleanup.
+AHCIDeviceInterface::AHCIDeviceInterface(void (*Out)(MountpointInterface* outpacket),
+ void (*In)(MountpointInterface* inpacket),
+ void (*Cleanup)(void))
+ : IDeviceObject(Out, In), fCleanup(Cleanup)
+{
+}
+
+/// @brief Class desctructor
+AHCIDeviceInterface::~AHCIDeviceInterface()
+{
+ MUST_PASS(fCleanup);
+ if (fCleanup)
+ fCleanup();
+}
+
+/// @brief Returns the name of the device interface.
+/// @return it's name as a string.
+const Char* AHCIDeviceInterface::Name() const
+{
+ return "AHCIDeviceInterface";
+}
diff --git a/dev/Kernel/src/Storage/ATADeviceInterface.cc b/dev/Kernel/src/Storage/ATADeviceInterface.cc
new file mode 100644
index 00000000..01443939
--- /dev/null
+++ b/dev/Kernel/src/Storage/ATADeviceInterface.cc
@@ -0,0 +1,88 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <StorageKit/ATA.h>
+
+using namespace Kernel;
+
+/// @brief Class constructor
+/// @param Out Drive output
+/// @param In Drive input
+/// @param Cleanup Drive cleanup.
+ATADeviceInterface::ATADeviceInterface(
+ void (*Out)(MountpointInterface* outpacket),
+ void (*In)(MountpointInterface* inpacket),
+ void (*Cleanup)(void))
+ : IDeviceObject(Out, In), fCleanup(Cleanup)
+{
+}
+
+/// @brief Class desctructor
+ATADeviceInterface::~ATADeviceInterface()
+{
+ MUST_PASS(fCleanup);
+ if (fCleanup)
+ fCleanup();
+}
+
+/// @brief Returns the name of the device interface.
+/// @return it's name as a string.
+const Char* ATADeviceInterface::Name() const
+{
+ return "ATADeviceInterface";
+}
+
+/// @brief Output operator.
+/// @param Data
+/// @return
+ATADeviceInterface& ATADeviceInterface::operator<<(MountpointInterface* Data)
+{
+ if (!Data)
+ return *this;
+
+ for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount)
+ {
+ auto interface = Data->GetAddressOf(driveCount);
+ if ((interface) && rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) == 0)
+ {
+ continue;
+ }
+ else if ((interface) &&
+ rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) != 0)
+ {
+ return *this;
+ }
+ }
+
+ return (ATADeviceInterface&)IDeviceObject<MountpointInterface*>::operator<<(
+ Data);
+}
+
+/// @brief Input operator.
+/// @param Data
+/// @return
+ATADeviceInterface& ATADeviceInterface::operator>>(MountpointInterface* Data)
+{
+ if (!Data)
+ return *this;
+
+ for (SizeT driveCount = 0; driveCount < kDriveMaxCount; ++driveCount)
+ {
+ auto interface = Data->GetAddressOf(driveCount);
+ if ((interface) && rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) == 0)
+ {
+ continue;
+ }
+ else if ((interface) &&
+ rt_string_cmp((interface)->fDriveKind(), "ATA-", 5) != 0)
+ {
+ return *this;
+ }
+ }
+
+ return (ATADeviceInterface&)IDeviceObject<MountpointInterface*>::operator>>(
+ Data);
+}
diff --git a/dev/Kernel/src/Storage/NVMEDeviceInterface.cc b/dev/Kernel/src/Storage/NVMEDeviceInterface.cc
new file mode 100644
index 00000000..642e581a
--- /dev/null
+++ b/dev/Kernel/src/Storage/NVMEDeviceInterface.cc
@@ -0,0 +1,28 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <StorageKit/NVME.h>
+
+namespace Kernel
+{
+ NVMEDeviceInterface::NVMEDeviceInterface(void (*out)(MountpointInterface* outpacket),
+ void (*in)(MountpointInterface* inpacket),
+ void (*cleanup)(void))
+ : IDeviceObject(out, in), fCleanup(cleanup)
+ {
+ }
+
+ NVMEDeviceInterface::~NVMEDeviceInterface()
+ {
+ if (fCleanup)
+ fCleanup();
+ }
+
+ const Char* NVMEDeviceInterface::Name() const
+ {
+ return ("NVMEDeviceInterface");
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/Storage/SCSIDeviceInterface.cc b/dev/Kernel/src/Storage/SCSIDeviceInterface.cc
new file mode 100644
index 00000000..d1d27c9d
--- /dev/null
+++ b/dev/Kernel/src/Storage/SCSIDeviceInterface.cc
@@ -0,0 +1,11 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <StorageKit/SCSI.h>
+
+///! @brief ATAPI SCSI packet.
+const scsi_packet_type<12> kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0,
+ 0, 12, 0x40, 0, 0};
diff --git a/dev/Kernel/src/Stream.cc b/dev/Kernel/src/Stream.cc
new file mode 100644
index 00000000..d898c706
--- /dev/null
+++ b/dev/Kernel/src/Stream.cc
@@ -0,0 +1,12 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ File: Stream.cc
+ Purpose: Stream object
+
+ Revision History:
+
+------------------------------------------- */
+
+#include <NewKit/Stream.h>
diff --git a/dev/Kernel/src/System/SwapDisk.cc b/dev/Kernel/src/System/SwapDisk.cc
new file mode 100644
index 00000000..590666e0
--- /dev/null
+++ b/dev/Kernel/src/System/SwapDisk.cc
@@ -0,0 +1,47 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024-2025 Amlal EL Mahrouss Labs, all rights reserved.
+
+------------------------------------------- */
+
+#include <SystemKit/SwapDisk.h>
+#include <KernelKit/FileMgr.h>
+
+namespace Kernel
+{
+ BOOL SwapDisk::Write(const Char* fork_name, const SizeT fork_name_len, SWAP_DISK_HEADER_REF data, const SizeT data_len)
+ {
+ if (!fork_name || !fork_name_len)
+ return NO;
+
+ if (data_len > kSwapBlockMaxSize)
+ return NO;
+
+ if (!data)
+ return NO;
+
+ FileStream file(kSwapPageFile, "wb");
+
+ auto ret = file.Write(fork_name, data, sizeof(SWAP_DISK_HEADER) + data_len);
+
+ if (ret.Error())
+ return NO;
+
+ return YES;
+ }
+
+ SWAP_DISK_HEADER_REF SwapDisk::Read(const Char* fork_name, const SizeT fork_name_len, const SizeT data_len)
+ {
+ if (!fork_name || !fork_name_len)
+ return nullptr;
+
+ if (data_len > kSwapBlockMaxSize)
+ return nullptr;
+
+ FileStream file(kSwapPageFile, "rb");
+
+ VoidPtr blob = file.Read(fork_name, sizeof(SWAP_DISK_HEADER) + data_len);
+
+ return (SWAP_DISK_HEADER_REF)blob;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/ThreadLocalStorage.cc b/dev/Kernel/src/ThreadLocalStorage.cc
new file mode 100644
index 00000000..8bcfe616
--- /dev/null
+++ b/dev/Kernel/src/ThreadLocalStorage.cc
@@ -0,0 +1,67 @@
+/*
+ * ========================================================
+ *
+ * minoskrnl
+ * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+ *
+ * ========================================================
+ */
+
+#include <NewKit/KString.h>
+#include <CFKit/Property.h>
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/ThreadLocalStorage.h>
+
+/***********************************************************************************/
+/// @bugs: 0
+/// @file ThreadLocalStorage.cc
+/// @brief Process Thread Local Storage.
+/***********************************************************************************/
+
+using namespace Kernel;
+
+/**
+ * @brief Checks for cookie inside the TIB.
+ * @param tib_ptr the TIB to check.
+ * @return if the cookie is enabled, true; false otherwise
+ */
+
+Boolean tls_check_tib(THREAD_INFORMATION_BLOCK* tib_ptr)
+{
+ if (!tib_ptr ||
+ !tib_ptr->Record)
+ return false;
+
+ ICodec encoder;
+ const Char* tib_as_bytes = encoder.AsBytes(tib_ptr);
+
+ kcout << "TLS: Validating the TIB...\r";
+
+ return tib_as_bytes[kCookieMag0Idx] == kCookieMag0 && tib_as_bytes[kCookieMag1Idx] == kCookieMag1 &&
+ tib_as_bytes[kCookieMag2Idx] == kCookieMag2;
+}
+
+/**
+ * @brief System call implementation of the TLS check.
+ * @param tib_ptr The TIB record.
+ * @return if the TIB record is valid or not.
+ */
+EXTERN_C Bool tls_check_syscall_impl(Kernel::VoidPtr tib_ptr) noexcept
+{
+ if (!tib_ptr)
+ {
+ kcout << "TLS: Failing because of an invalid TIB...\r";
+ return false;
+ }
+
+ THREAD_INFORMATION_BLOCK* tib = reinterpret_cast<THREAD_INFORMATION_BLOCK*>(tib_ptr);
+
+ if (!tls_check_tib(tib))
+ {
+ kcout << "TLS: Failing because of an invalid TIB...\r";
+ return false;
+ }
+
+ kcout << "TLS Passed checked.\r";
+ return true;
+}
diff --git a/dev/Kernel/src/Timer.cc b/dev/Kernel/src/Timer.cc
new file mode 100644
index 00000000..b33a91d8
--- /dev/null
+++ b/dev/Kernel/src/Timer.cc
@@ -0,0 +1,19 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <KernelKit/Timer.h>
+
+///! BUGS: 0
+///! @file Timer.cc
+///! @brief Software Timer implementation
+
+using namespace Kernel;
+
+/// @brief Unimplemented as it is an interface.
+BOOL TimerInterface::Wait() noexcept
+{
+ return NO;
+}
diff --git a/dev/Kernel/src/User.cc b/dev/Kernel/src/User.cc
new file mode 100644
index 00000000..51aa3c72
--- /dev/null
+++ b/dev/Kernel/src/User.cc
@@ -0,0 +1,188 @@
+/*
+ * ========================================================
+ *
+ * ZKA
+ * Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved., all rights reserved.
+ *
+ * File: User.cc
+ * Purpose: User class, used to provide authentication and security.
+ *
+ * ========================================================
+ */
+
+#include <KernelKit/User.h>
+#include <KernelKit/LPC.h>
+#include <NewKit/KernelPanic.h>
+#include <KernelKit/FileMgr.h>
+#include <KernelKit/Heap.h>
+
+#define kStdUserType (0xCE)
+#define kSuperUserType (0xEC)
+
+/// @file User.cc
+/// @brief User support.
+
+namespace Kernel
+{
+ namespace Detail
+ {
+ ////////////////////////////////////////////////////////////
+ /// \brief Constructs a password by hashing the password.
+ /// \param password password to hash.
+ /// \return the hashed password
+ ////////////////////////////////////////////////////////////
+ const Int32 cred_construct_token(Char* password, const Char* in_password, User* user, SizeT length)
+ {
+ if (!password || !user)
+ return 1;
+
+ kcout << "cred_construct_token: Hashing user password...\r";
+
+ for (Size i_pass = 0; i_pass < length; ++i_pass)
+ {
+ const Char& cur_chr = in_password[i_pass];
+
+ if (cur_chr == 0)
+ break;
+
+ password[i_pass] = cur_chr | (user->IsStdUser() ? kStdUserType : kSuperUserType);
+ }
+
+ kcout << "cred_construct_token: Hashed user password.\r";
+
+ return 0;
+ }
+ } // namespace Detail
+
+ ////////////////////////////////////////////////////////////
+ /// @brief User ring constructor.
+ ////////////////////////////////////////////////////////////
+ User::User(const Int32& sel, const Char* userName)
+ : mUserRing((UserRingKind)sel)
+ {
+ MUST_PASS(sel >= 0);
+ rt_copy_memory((VoidPtr)userName, this->mUserName, rt_string_len(userName));
+ }
+
+ ////////////////////////////////////////////////////////////
+ /// @brief User ring constructor.
+ ////////////////////////////////////////////////////////////
+ User::User(const UserRingKind& ringKind, const Char* userName)
+ : mUserRing(ringKind)
+ {
+ rt_copy_memory((VoidPtr)userName, this->mUserName, rt_string_len(userName));
+ }
+
+ ////////////////////////////////////////////////////////////
+ /// @brief User destructor class.
+ ////////////////////////////////////////////////////////////
+ User::~User() = default;
+
+ Bool User::Save(const UserPublicKey password_to_fill) noexcept
+ {
+ if (!password_to_fill ||
+ *password_to_fill == 0)
+ return No;
+
+ SizeT len = rt_string_len(password_to_fill);
+
+ Char* password = new Char[len];
+ MUST_PASS(password);
+
+ // fill data first, generate hash.
+ // return false on error.
+
+ rt_copy_memory((VoidPtr)password_to_fill, password, len);
+
+ if (!Detail::cred_construct_token(password, password_to_fill, this, len))
+ {
+ delete[] password;
+ password = nullptr;
+
+ return No;
+ }
+
+ // then store password.
+
+ rt_copy_memory(password, this->mUserKey, rt_string_len(password_to_fill));
+
+ delete[] password;
+ password = nullptr;
+
+ kcout << "User::Save: Saved password successfully...\r";
+
+ return Yes;
+ }
+
+ Bool User::Matches(const UserPublicKey password_to_fill) noexcept
+ {
+ if (!password_to_fill ||
+ *password_to_fill)
+ return No;
+
+ SizeT len = rt_string_len(password_to_fill);
+
+ Char* password = new Char[len];
+ MUST_PASS(password);
+
+ // fill data first, generate hash.
+ // return false on error.
+
+ rt_copy_memory((VoidPtr)password_to_fill, password, len);
+
+ if (!Detail::cred_construct_token(password, password_to_fill, this, len))
+ {
+ delete[] password;
+ password = nullptr;
+
+ return No;
+ }
+
+ kcout << "User::Matches: Validating hashed passwords...\r";
+
+ // now check if the password matches.
+ if (rt_string_cmp(password, this->mUserKey, rt_string_len(this->mUserKey)) == 0)
+ {
+ kcout << "User::Matches: Password is valid.\r";
+ return Yes;
+ }
+
+ kcout << "User::Matches: Password isn't valid.\r";
+ return No;
+ }
+
+ Bool User::operator==(const User& lhs)
+ {
+ return lhs.mUserRing == this->mUserRing;
+ }
+
+ Bool User::operator!=(const User& lhs)
+ {
+ return lhs.mUserRing != this->mUserRing;
+ }
+
+ Char* User::Name() noexcept
+ {
+ return this->mUserName;
+ }
+
+ ////////////////////////////////////////////////////////////
+ /// @brief Returns the user's ring.
+ /// @return The king of ring the user is attached to.
+ ////////////////////////////////////////////////////////////
+
+ const UserRingKind& User::Ring() noexcept
+ {
+ return this->mUserRing;
+ }
+
+ Bool User::IsStdUser() noexcept
+ {
+ return this->Ring() == UserRingKind::kRingStdUser;
+ }
+
+ Bool User::IsSuperUser() noexcept
+ {
+ return this->Ring() == UserRingKind::kRingSuperUser;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/UserProcessScheduler.cc b/dev/Kernel/src/UserProcessScheduler.cc
new file mode 100644
index 00000000..068e190a
--- /dev/null
+++ b/dev/Kernel/src/UserProcessScheduler.cc
@@ -0,0 +1,607 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+ FILE: UserProcessScheduler.cc
+ PURPOSE: Low level/Ring-3 Process scheduler.
+
+------------------------------------------- */
+
+/***********************************************************************************/
+/// @file UserProcessScheduler.cc
+/// @brief Low level/Ring-3 process scheduler.
+/***********************************************************************************/
+
+#include <KernelKit/UserProcessScheduler.h>
+#include <KernelKit/HardwareThreadScheduler.h>
+#include <KernelKit/IPEFDylibObject.h>
+#include <ArchKit/ArchKit.h>
+#include <KernelKit/Heap.h>
+#include <NewKit/KString.h>
+#include <KernelKit/LPC.h>
+
+///! BUGS: 0
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /// @brief Exit Code global variable.
+ /***********************************************************************************/
+
+ STATIC UInt32 kLastExitCode = 0U;
+
+ /***********************************************************************************/
+ /// @brief User Process scheduler global and external reference of thread scheduler.
+ /***********************************************************************************/
+
+ STATIC UserProcessScheduler kProcessScheduler;
+
+ UserProcess::UserProcess() = default;
+ UserProcess::~UserProcess() = default;
+
+ /// @brief Gets the last exit code.
+ /// @note Not thread-safe.
+ /// @return Int32 the last exit code.
+
+ const UInt32& sched_get_exit_code(void) noexcept
+ {
+ return kLastExitCode;
+ }
+
+ /***********************************************************************************/
+ /// @brief Crashes the current process.
+ /***********************************************************************************/
+
+ Void UserProcess::Crash()
+ {
+ if (this->Status != ProcessStatusKind::kRunning)
+ return;
+
+ kcout << this->Name << ": crashed, error id: " << number(kErrorProcessFault) << endl;
+ this->Exit(kErrorProcessFault);
+ }
+
+ /***********************************************************************************/
+ /// @brief boolean operator, check status.
+ /***********************************************************************************/
+
+ UserProcess::operator bool()
+ {
+ return this->Status == ProcessStatusKind::kRunning;
+ }
+
+ /***********************************************************************************/
+ /// @brief Gets the local last exit code.
+ /// @note Not thread-safe.
+ /// @return Int32 the last exit code.
+ /***********************************************************************************/
+
+ const UInt32& UserProcess::GetExitCode() noexcept
+ {
+ return this->fLastExitCode;
+ }
+
+ /***********************************************************************************/
+ /// @brief Error code variable getter.
+ /***********************************************************************************/
+
+ Int32& UserProcess::GetLocalCode() noexcept
+ {
+ return this->fLocalCode;
+ }
+
+ /***********************************************************************************/
+ /// @brief Wakes process header.
+ /// @param should_wakeup if the program shall wakeup or not.
+ /***********************************************************************************/
+
+ Void UserProcess::Wake(const bool should_wakeup)
+ {
+ this->Status =
+ should_wakeup ? ProcessStatusKind::kRunning : ProcessStatusKind::kFrozen;
+ }
+
+ /***********************************************************************************/
+ /** @brief Add pointer to entry. */
+ /***********************************************************************************/
+
+ ErrorOr<VoidPtr> UserProcess::New(const SizeT& sz, const SizeT& pad_amount)
+ {
+#ifdef __ZKA_VIRTUAL_MEMORY_SUPPORT__
+ auto vm_register = hal_read_cr3();
+ hal_write_cr3(this->VMRegister);
+
+ auto ptr = mm_new_heap(sz + pad_amount, Yes, Yes);
+
+ hal_write_cr3(vm_register);
+#else
+ auto ptr = mm_new_heap(sz + pad_amount, Yes, Yes);
+#endif
+
+ if (!this->ProcessMemoryHeap)
+ {
+ this->ProcessMemoryHeap = new UserProcess::ProcessMemoryHeapList();
+
+ this->ProcessMemoryHeap->MemoryEntryPad = pad_amount;
+ this->ProcessMemoryHeap->MemoryEntrySize = sz;
+
+ this->ProcessMemoryHeap->MemoryEntry = ptr;
+
+ this->ProcessMemoryHeap->MemoryPrev = nullptr;
+ this->ProcessMemoryHeap->MemoryNext = nullptr;
+ }
+ else
+ {
+ ProcessMemoryHeapList* entry = this->ProcessMemoryHeap;
+ ProcessMemoryHeapList* prev_entry = nullptr;
+
+ while (!entry)
+ {
+ if (entry->MemoryEntry == nullptr)
+ break; // chose to break here, when we get an already allocated memory entry for our needs.
+
+ prev_entry = entry;
+ entry = entry->MemoryNext;
+ }
+
+ entry->MemoryNext = new ProcessMemoryHeapList();
+ entry->MemoryNext->MemoryEntry = ptr;
+
+ entry->MemoryNext->MemoryPrev = entry;
+ entry->MemoryNext->MemoryNext = nullptr;
+ }
+
+ this->UsedMemory += sz;
+
+ return ErrorOr<VoidPtr>(ptr);
+ }
+
+ /***********************************************************************************/
+ /// @brief Gets the name of the current process.
+ /***********************************************************************************/
+
+ const Char* UserProcess::GetName() noexcept
+ {
+ return this->Name;
+ }
+
+ /***********************************************************************************/
+ /// @brief Gets the owner of the process.
+ /***********************************************************************************/
+
+ const User* UserProcess::GetOwner() noexcept
+ {
+ return this->Owner;
+ }
+
+ /// @brief UserProcess status getter.
+ const ProcessStatusKind& UserProcess::GetStatus() noexcept
+ {
+ return this->Status;
+ }
+
+ /***********************************************************************************/
+ /**
+ @brief Affinity is the time slot allowed for the process.
+ */
+ /***********************************************************************************/
+
+ const AffinityKind& UserProcess::GetAffinity() noexcept
+ {
+ return this->Affinity;
+ }
+
+ /***********************************************************************************/
+ /**
+ @brief Exit process method.
+ @param exit_code The process's exit code.
+ */
+ /***********************************************************************************/
+
+ Void UserProcess::Exit(const Int32& exit_code)
+ {
+ this->Status = exit_code > 0 ? ProcessStatusKind::kKilled : ProcessStatusKind::kFrozen;
+ this->fLastExitCode = exit_code;
+
+ kLastExitCode = exit_code;
+
+ auto memory_heap_list = this->ProcessMemoryHeap;
+
+#ifdef __ZKA_VIRTUAL_MEMORY_SUPPORT__
+ auto pd = hal_read_cr3();
+ hal_write_cr3(this->VMRegister);
+#endif
+
+ // Deleting memory lists. Make sure to free all of them.
+ while (memory_heap_list)
+ {
+ if (memory_heap_list->MemoryEntry)
+ {
+ MUST_PASS(mm_delete_heap(memory_heap_list->MemoryEntry));
+ }
+
+#ifdef __ZKA_VIRTUAL_MEMORY_SUPPORT__
+ hal_write_cr3(pd);
+#endif
+
+ auto next = memory_heap_list->MemoryNext;
+
+ mm_delete_heap(memory_heap_list);
+
+ memory_heap_list = nullptr;
+ memory_heap_list = next;
+ }
+
+ //! Free the memory's page directory.
+ HAL::mm_free_bitmap(this->VMRegister);
+
+ //! Delete image if not done already.
+ if (this->Image.fCode && mm_is_valid_heap(this->Image.fCode))
+ mm_delete_heap(this->Image.fCode);
+
+ if (this->Image.fBlob && mm_is_valid_heap(this->Image.fBlob))
+ mm_delete_heap(this->Image.fBlob);
+
+ if (this->StackFrame && mm_is_valid_heap(this->StackFrame))
+ mm_delete_heap((VoidPtr)this->StackFrame);
+
+ this->Image.fBlob = nullptr;
+ this->Image.fCode = nullptr;
+ this->StackFrame = nullptr;
+
+ if (this->Kind == kExectuableDylibKind)
+ {
+ Bool success = false;
+
+ rtl_fini_dylib(*this, reinterpret_cast<IPEFDylibObject*>(this->DylibDelegate), &success);
+
+ if (!success)
+ {
+ ke_panic(RUNTIME_CHECK_PROCESS);
+ }
+
+ this->DylibDelegate = nullptr;
+ }
+
+ if (this->StackReserve)
+ mm_delete_heap(reinterpret_cast<VoidPtr>(this->StackReserve));
+
+ this->ProcessId = 0;
+ this->Status = ProcessStatusKind::kFinished;
+
+ --this->ProcessParentTeam->mProcessCount;
+
+ delete this;
+ }
+
+ /***********************************************************************************/
+ /// @brief Add process to team.
+ /// @param process the process *Ref* class.
+ /// @return the process index inside the team.
+ /***********************************************************************************/
+
+ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr image)
+ {
+ ProcessID pid = this->mTeam.mProcessCount;
+
+ if (pid > kSchedProcessLimitPerTeam)
+ {
+ return kErrorProcessFault;
+ }
+
+ ++this->mTeam.mProcessCount;
+
+ UserProcess& process = this->mTeam.mProcessList[pid];
+
+ process.Image.fCode = code;
+ process.Image.fBlob = image;
+
+ rt_copy_memory(reinterpret_cast<VoidPtr>(const_cast<Char*>(name)), process.Name, rt_string_len(name));
+
+#ifdef __ZKA_VIRTUAL_MEMORY_SUPPORT__
+ process.VMRegister = new PDE();
+
+ if (!process.VMRegister)
+ {
+ process.Crash();
+ return kErrorProcessFault;
+ }
+
+ UInt32 flags = HAL::kMMFlagsPresent;
+ flags |= HAL::kMMFlagsWr;
+ flags |= HAL::kMMFlagsUser;
+
+ HAL::mm_map_page((VoidPtr)process.VMRegister, flags);
+#endif // __ZKA_VIRTUAL_MEMORY_SUPPORT__
+
+ process.StackFrame = new HAL::StackFrame();
+
+ if (!process.StackFrame)
+ {
+ process.Crash();
+ return kErrorProcessFault;
+ }
+
+#ifdef __ZKA_VIRTUAL_MEMORY_SUPPORT__
+ flags = HAL::kMMFlagsPresent;
+ flags |= HAL::kMMFlagsWr;
+ flags |= HAL::kMMFlagsUser;
+
+ HAL::mm_map_page((VoidPtr)process.StackFrame, flags);
+#endif // __ZKA_VIRTUAL_MEMORY_SUPPORT__
+
+ // React according to process kind.
+ switch (process.Kind)
+ {
+ case UserProcess::kExectuableDylibKind: {
+ process.DylibDelegate = rtl_init_dylib(process);
+ MUST_PASS(process.DylibDelegate);
+ }
+ default: {
+ kcout << "Unknown process kind: " << number(process.Kind) << endl;
+ break;
+ }
+ }
+
+ process.StackReserve = new UInt8[process.StackSize];
+
+ if (!process.StackReserve)
+ {
+ process.Crash();
+ return kErrorProcessFault;
+ }
+
+#ifdef __ZKA_VIRTUAL_MEMORY_SUPPORT__
+ flags = HAL::kMMFlagsPresent;
+ flags |= HAL::kMMFlagsWr;
+ flags |= HAL::kMMFlagsUser;
+
+ HAL::mm_map_page((VoidPtr)process.StackReserve, flags);
+#endif // __ZKA_VIRTUAL_MEMORY_SUPPORT__
+
+ process.ProcessParentTeam = &mTeam;
+
+ process.ProcessId = pid;
+ process.Status = ProcessStatusKind::kStarting;
+ process.PTime = (UIntPtr)AffinityKind::kStandard;
+
+ kcout << "PID: " << number(process.ProcessId) << endl;
+ kcout << "Name: " << process.Name << endl;
+
+ return pid;
+ }
+
+ /***********************************************************************************/
+ /// @brief Retrieves the singleton of the process scheduler.
+ /***********************************************************************************/
+
+ UserProcessScheduler& UserProcessScheduler::The()
+ {
+ return kProcessScheduler;
+ }
+
+ /***********************************************************************************/
+
+ /// @brief Remove process from list.
+ /// @param process_id process slot inside team.
+ /// @retval true process was removed.
+ /// @retval false process doesn't exist in team.
+
+ /***********************************************************************************/
+
+ const Bool UserProcessScheduler::Remove(ProcessID process_id)
+ {
+ // check if process is within range.
+ if (process_id > mTeam.mProcessList.Count())
+ return No;
+
+ mTeam.mProcessList[process_id].Exit(0);
+
+ return Yes;
+ }
+
+ const Bool UserProcessScheduler::IsUser()
+ {
+ return Yes;
+ }
+
+ const Bool UserProcessScheduler::IsKernel()
+ {
+ return No;
+ }
+
+ const Bool UserProcessScheduler::HasMP()
+ {
+ MUST_PASS(kHandoverHeader);
+ return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled;
+ }
+
+ /***********************************************************************************/
+ /// @brief Run User scheduler object.
+ /// @return Process count executed within a team.
+ /***********************************************************************************/
+
+ const SizeT UserProcessScheduler::Run() noexcept
+ {
+ SizeT process_index = 0; //! we store this guy to tell the scheduler how many
+ //! things we have scheduled.
+
+ if (mTeam.mProcessCount < 1)
+ {
+ kcout << "UserProcessScheduler::Run(): This team doesn't have any process!\r";
+ return 0;
+ }
+
+ kcout << "UserProcessScheduler::Run(): This team has a process capacity of: " << number(mTeam.mProcessList.Capacity()) << endl;
+
+ for (; process_index < mTeam.AsArray().Capacity(); ++process_index)
+ {
+ auto& process = mTeam.AsArray()[process_index];
+
+ //! check if the process needs to be run.
+ if (UserProcessHelper::CanBeScheduled(process))
+ {
+ // Set current process header.
+ this->GetCurrentProcess() = process;
+
+ process.PTime = static_cast<Int32>(process.Affinity);
+
+ kcout << "Switch to: '" << process.Name << "'.\r";
+
+ // tell helper to find a core to schedule on.
+ if (!UserProcessHelper::Switch(process.Image.fCode, &process.StackReserve[process.StackSize - 1], process.StackFrame,
+ process.ProcessId))
+ {
+ kcout << "Invalid process (UH OH)\r";
+ process.Crash();
+ }
+ }
+ else
+ {
+ --process.PTime;
+ }
+ }
+
+ return process_index;
+ }
+
+ /// @brief Gets the current scheduled team.
+ /// @return
+ UserProcessTeam& UserProcessScheduler::CurrentTeam()
+ {
+ return mTeam;
+ }
+
+ /// @internal
+
+ /// @brief Gets current running process.
+ /// @return
+ Ref<UserProcess>& UserProcessScheduler::GetCurrentProcess()
+ {
+ return mTeam.AsRef();
+ }
+
+ /// @brief Current proccess id getter.
+ /// @return UserProcess ID integer.
+ ErrorOr<PID> UserProcessHelper::TheCurrentPID()
+ {
+ if (!kProcessScheduler.GetCurrentProcess())
+ return ErrorOr<PID>{kErrorProcessFault};
+
+ kcout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r";
+ return ErrorOr<PID>{kProcessScheduler.GetCurrentProcess().Leak().ProcessId};
+ }
+
+ /// @brief Check if process can be schedulded.
+ /// @param process the process reference.
+ /// @retval true can be schedulded.
+ /// @retval false cannot be schedulded.
+ Bool UserProcessHelper::CanBeScheduled(const UserProcess& process)
+ {
+ if (process.Status == ProcessStatusKind::kKilled ||
+ process.Status == ProcessStatusKind::kFinished ||
+ process.Status == ProcessStatusKind::kStarting ||
+ process.Status == ProcessStatusKind::kFrozen)
+ return No;
+
+ if (process.Status == ProcessStatusKind::kInvalid)
+ return No;
+
+ if (!process.Image.fCode)
+ return No;
+
+ if (!process.Name[0])
+ return No;
+
+ return process.PTime < 1;
+ }
+
+ /***********************************************************************************/
+ /**
+ * @brief Start scheduling current AP.
+ */
+ /***********************************************************************************/
+
+ SizeT UserProcessHelper::StartScheduling()
+ {
+ return kProcessScheduler.Run();
+ }
+
+ /***********************************************************************************/
+ /**
+ * \brief Does a context switch in a CPU.
+ * \param the_stack the stackframe of the running app.
+ * \param new_pid the process's PID.
+ */
+ /***********************************************************************************/
+
+ Bool UserProcessHelper::Switch(VoidPtr image_ptr, UInt8* stack, HAL::StackFramePtr frame_ptr, const PID& new_pid)
+ {
+ for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index)
+ {
+ if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kInvalidAP ||
+ HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPBoot)
+ continue;
+
+ // a fallback is a special core for real-time tasks which needs immediate execution.
+ if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPFallback)
+ {
+ if (UserProcessScheduler::The().GetCurrentProcess().Leak().Affinity != AffinityKind::kRealTime)
+ continue;
+
+ if (HardwareThreadScheduler::The()[index].Leak()->Switch(image_ptr, stack, frame_ptr, new_pid))
+ return YES;
+
+ continue;
+ }
+
+ PID prev_pid = UserProcessHelper::TheCurrentPID();
+ UserProcessHelper::TheCurrentPID().Leak().Leak() = new_pid;
+
+ ////////////////////////////////////////////////////////////
+ /// Prepare task switch. ///
+ ////////////////////////////////////////////////////////////
+
+ HardwareThreadScheduler::The()[index].Leak()->Wake(YES);
+ HardwareThreadScheduler::The()[index].Leak()->Busy(NO);
+
+ auto prev_ptime = HardwareThreadScheduler::The()[index].Leak()->fPTime;
+ HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].PTime;
+
+ Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(image_ptr, stack, frame_ptr, new_pid);
+
+ ////////////////////////////////////////////////////////////
+ /// Rollback on fail. ///
+ ////////////////////////////////////////////////////////////
+ if (!ret)
+ {
+ HardwareThreadScheduler::The()[index].Leak()->fPTime = prev_ptime;
+ UserProcessHelper::TheCurrentPID().Leak().Leak() = prev_pid;
+
+ HardwareThreadScheduler::The()[index].Leak()->Busy(NO);
+ }
+
+ HardwareThreadScheduler::The()[index].Leak()->Wake(NO);
+
+ return Yes;
+ }
+
+ return No;
+ }
+
+ ////////////////////////////////////////////////////////////
+ /// @brief this checks if any process is on the team.
+ ////////////////////////////////////////////////////////////
+ UserProcessScheduler::operator bool()
+ {
+ return mTeam.AsArray().Count() > 0;
+ }
+
+ ////////////////////////////////////////////////////////////
+ /// @brief this checks if no process is on the team.
+ ////////////////////////////////////////////////////////////
+ Bool UserProcessScheduler::operator!()
+ {
+ return mTeam.AsArray().Count() == 0;
+ }
+} // namespace Kernel
diff --git a/dev/Kernel/src/UserProcessTeam.cc b/dev/Kernel/src/UserProcessTeam.cc
new file mode 100644
index 00000000..918a62bb
--- /dev/null
+++ b/dev/Kernel/src/UserProcessTeam.cc
@@ -0,0 +1,58 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+/***********************************************************************************/
+/// @file UserProcessTeam.cc
+/// @brief Process teams implementation.
+/***********************************************************************************/
+
+#include <KernelKit/UserProcessScheduler.h>
+
+namespace Kernel
+{
+ UserProcessTeam::UserProcessTeam()
+ {
+ for (SizeT i = 0U; i < this->mProcessList.Count(); ++i)
+ {
+ this->mProcessList[i] = UserProcess();
+ this->mProcessList[i].Status = ProcessStatusKind::kKilled;
+ }
+
+ this->mProcessCount = 0UL;
+ }
+
+ /***********************************************************************************/
+ /// @brief UserProcess list array getter.
+ /// @return The list of process to schedule.
+ /***********************************************************************************/
+
+ Array<UserProcess, kSchedProcessLimitPerTeam>& UserProcessTeam::AsArray()
+ {
+ return this->mProcessList;
+ }
+
+ /***********************************************************************************/
+ /// @brief Get team ID.
+ /// @return The team's ID.
+ /***********************************************************************************/
+
+ ProcessID& UserProcessTeam::Id() noexcept
+ {
+ return this->mTeamId;
+ }
+
+ /***********************************************************************************/
+ /// @brief Get current process getter as Ref.
+ /// @return The current process header.
+ /***********************************************************************************/
+
+ Ref<UserProcess>& UserProcessTeam::AsRef()
+ {
+ return this->mCurrentProcess;
+ }
+} // namespace Kernel
+
+// last rev 05-03-24
diff --git a/dev/Kernel/src/Utils.cc b/dev/Kernel/src/Utils.cc
new file mode 100644
index 00000000..c5a82305
--- /dev/null
+++ b/dev/Kernel/src/Utils.cc
@@ -0,0 +1,219 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Utils.h>
+
+namespace Kernel
+{
+ Int32 rt_string_cmp(const Char* src, const Char* cmp, Size size)
+ {
+ Int32 counter = 0;
+
+ for (Size index = 0; index < size; ++index)
+ {
+ if (src[index] != cmp[index])
+ ++counter;
+ }
+
+ return counter;
+ }
+
+ Void rt_zero_memory(voidPtr pointer, Size len)
+ {
+ rt_set_memory(pointer, 0, len);
+ }
+
+ SizeT rt_string_len(const Char* str, SizeT _len)
+ {
+ SizeT len{0};
+
+ do
+ {
+ if (len > _len)
+ {
+ return _len;
+ }
+
+ ++len;
+ } while (str[len] != '\0');
+
+ return len;
+ }
+
+ Size rt_string_len(const Char* ptr)
+ {
+ SizeT cnt{0};
+
+ while (ptr[cnt] != 0)
+ ++cnt;
+
+ return cnt;
+ }
+
+ voidPtr rt_set_memory(voidPtr src, UInt32 value, Size len)
+ {
+ UInt32* start = reinterpret_cast<UInt32*>(src);
+
+ while (len)
+ {
+ *start = value;
+ ++start;
+ --len;
+ }
+
+ return (voidPtr)start;
+ }
+
+ Int rt_move_memory(const voidPtr src, voidPtr dst, Size len)
+ {
+ Char* srcChr = reinterpret_cast<Char*>(src);
+ Char* dstChar = reinterpret_cast<Char*>(dst);
+ SizeT index = 0;
+
+ while (index < len)
+ {
+ dstChar[index] = srcChr[index];
+ srcChr[index] = 0;
+
+ ++index;
+ }
+
+ return 0;
+ }
+
+ Int rt_copy_memory(const voidPtr src, voidPtr dst, Size len)
+ {
+ char* srcChr = reinterpret_cast<char*>(src);
+ char* dstChar = reinterpret_cast<char*>(dst);
+ Size index = 0;
+
+ while (index < len)
+ {
+ dstChar[index] = srcChr[index];
+ ++index;
+ }
+
+ dstChar[index] = 0;
+
+ return index;
+ }
+
+ const Char* rt_alloc_string(const Char* src)
+ {
+ const Char* string = new Char[rt_string_len(src) + 1];
+
+ if (!string)
+ return nullptr;
+
+ voidPtr v_src = reinterpret_cast<voidPtr>(const_cast<char*>(src));
+ voidPtr v_dst = reinterpret_cast<voidPtr>(const_cast<char*>(string));
+
+ rt_copy_memory(v_src, v_dst, rt_string_len(src) + 1);
+
+ return string;
+ }
+
+ Int32 rt_to_uppercase(Int32 character)
+ {
+ if (character >= 'a' && character <= 'z')
+ return character - 0x20;
+
+ return character;
+ }
+
+ Int32 rt_to_lower(Int32 character)
+ {
+ if (character >= 'A' && character <= 'Z')
+ return character + 0x20;
+
+ return character;
+ }
+
+ Boolean is_space(Char chr)
+ {
+ return chr == ' ';
+ }
+
+ Boolean is_newln(Char chr)
+ {
+ return chr == '\n';
+ }
+
+ VoidPtr rt_string_in_string(const Char* in, const Char* needle)
+ {
+ for (SizeT i = 0; i < rt_string_len(in); ++i)
+ {
+ if (rt_string_cmp(in + i, needle, rt_string_len(needle)) == 0)
+ return reinterpret_cast<voidPtr>(const_cast<char*>(in + i));
+ }
+
+ return nullptr;
+ }
+
+ Char rt_to_char(UInt64 base, Int32 limit)
+ {
+ const Char kNumbers[17] = "0123456789ABCDEF";
+ return kNumbers[base % limit];
+ }
+
+ Bool rt_to_string(Char* str, UInt64 base, Int32 limit)
+ {
+#ifdef __ZKA_AMD64__
+ auto i = 0;
+
+ auto final_number = base;
+
+ auto mult = 1;
+ auto elems = 0L;
+
+ base /= 10;
+
+ while (base > 0)
+ {
+ elems++;
+ mult *= 10;
+ base /= 10;
+ }
+
+ while (elems > -1)
+ {
+ final_number = (final_number % mult) * 10 + final_number / mult;
+ str[i] = rt_to_char(final_number, limit);
+
+ --elems;
+ ++i;
+ }
+#endif
+
+ return YES;
+ }
+
+ /// @brief Checks for a string start at the character.
+
+ Char* rt_string_has_char(Char* str, const Char chr)
+ {
+ while (*str != chr)
+ {
+ ++str;
+
+ if (*str == 0)
+ return nullptr;
+ }
+
+ return str;
+ }
+} // namespace Kernel
+
+EXTERN_C void* memset(void* dst, int c, long long unsigned int len)
+{
+ return Kernel::rt_set_memory(dst, c, len);
+}
+
+EXTERN_C void* memcpy(void* dst, const void* src, long long unsigned int len)
+{
+ Kernel::rt_copy_memory(const_cast<void*>(src), dst, len);
+ return dst;
+}
diff --git a/dev/Kernel/src/Variant.cc b/dev/Kernel/src/Variant.cc
new file mode 100644
index 00000000..7d62cb98
--- /dev/null
+++ b/dev/Kernel/src/Variant.cc
@@ -0,0 +1,33 @@
+/* -------------------------------------------
+
+ Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved.
+
+------------------------------------------- */
+
+#include <NewKit/Variant.h>
+
+namespace Kernel
+{
+ const Char* Variant::ToString()
+ {
+ switch (fKind)
+ {
+ case VariantKind::kXML:
+ return ("Class:{XML}");
+ case VariantKind::kJson:
+ return ("Class:{Json}");
+ case VariantKind::kString:
+ return ("Class:{String}");
+ case VariantKind::kBlob:
+ return ("Class:{Blob}");
+ default:
+ return ("Class:{Null}");
+ }
+ }
+
+ /// @brief Leak variant's instance.
+ VoidPtr Variant::Leak()
+ {
+ return fPtr;
+ }
+} // namespace Kernel