summaryrefslogtreecommitdiffhomepage
path: root/dev/zka/HALKit
diff options
context:
space:
mode:
authorAmlal <amlal@el-mahrouss-logic.com>2024-09-22 17:46:11 +0200
committerAmlal <amlal@el-mahrouss-logic.com>2024-09-22 17:46:11 +0200
commit8719b4570a2d10dd49a0d3a47e24f5c55bdda85e (patch)
treeba095740888f3768e08b2ea058b0ea6da2d0403d /dev/zka/HALKit
parent45944b3d2dab04b763fcc6d10164fe8069e60b08 (diff)
:boom: A big refactor on the filesystem structure.
Signed-off-by: Amlal <amlal@el-mahrouss-logic.com>
Diffstat (limited to 'dev/zka/HALKit')
-rw-r--r--dev/zka/HALKit/.gitkeep0
-rw-r--r--dev/zka/HALKit/64x0/.hgkeep0
-rw-r--r--dev/zka/HALKit/64x0/APM/.hgkeep0
-rw-r--r--dev/zka/HALKit/64x0/HalVirtualMemory.cxx17
-rw-r--r--dev/zka/HALKit/64x0/MBCI/.gitkeep0
-rw-r--r--dev/zka/HALKit/64x0/ReadMe.md4
-rw-r--r--dev/zka/HALKit/AMD64/CPUID.hxx81
-rw-r--r--dev/zka/HALKit/AMD64/HalACPIFactoryInterface.cxx208
-rw-r--r--dev/zka/HALKit/AMD64/HalAPICMgr.cxx36
-rw-r--r--dev/zka/HALKit/AMD64/HalBMPMgr.cxx182
-rw-r--r--dev/zka/HALKit/AMD64/HalBoot.asm22
-rw-r--r--dev/zka/HALKit/AMD64/HalCommAPI.cxx116
-rw-r--r--dev/zka/HALKit/AMD64/HalControlRegister.s45
-rw-r--r--dev/zka/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx129
-rw-r--r--dev/zka/HALKit/AMD64/HalCoreMPScheduler.cxx241
-rw-r--r--dev/zka/HALKit/AMD64/HalDebugOutput.cxx145
-rw-r--r--dev/zka/HALKit/AMD64/HalDebugPort.cxx40
-rw-r--r--dev/zka/HALKit/AMD64/HalDescriptorLoader.cxx82
-rw-r--r--dev/zka/HALKit/AMD64/HalInterruptAPI.asm323
-rw-r--r--dev/zka/HALKit/AMD64/HalKernelMain.cxx95
-rw-r--r--dev/zka/HALKit/AMD64/HalMPContextSwitch.asm59
-rw-r--r--dev/zka/HALKit/AMD64/HalRoutineWait.s9
-rw-r--r--dev/zka/HALKit/AMD64/HalSchedulerCore.cxx56
-rw-r--r--dev/zka/HALKit/AMD64/HalTimer.cxx86
-rw-r--r--dev/zka/HALKit/AMD64/HalUtils.asm33
-rw-r--r--dev/zka/HALKit/AMD64/Hypervisor.hxx25
-rw-r--r--dev/zka/HALKit/AMD64/MBCI/.gitkeep0
-rw-r--r--dev/zka/HALKit/AMD64/PCI/Database.cxx11
-rw-r--r--dev/zka/HALKit/AMD64/PCI/Device.cxx141
-rw-r--r--dev/zka/HALKit/AMD64/PCI/Dma.cxx82
-rw-r--r--dev/zka/HALKit/AMD64/PCI/Express.cxx11
-rw-r--r--dev/zka/HALKit/AMD64/PCI/IO.cxx7
-rw-r--r--dev/zka/HALKit/AMD64/PCI/Iterator.cxx39
-rw-r--r--dev/zka/HALKit/AMD64/PCI/PCI.cxx7
-rw-r--r--dev/zka/HALKit/AMD64/Paging.hxx99
-rw-r--r--dev/zka/HALKit/AMD64/Processor.hxx296
-rw-r--r--dev/zka/HALKit/AMD64/ReadMe.md4
-rw-r--r--dev/zka/HALKit/AMD64/Storage/AHCI.cxx123
-rw-r--r--dev/zka/HALKit/AMD64/Storage/ATA-DMA.cxx38
-rw-r--r--dev/zka/HALKit/AMD64/Storage/ATA-PIO.cxx199
-rw-r--r--dev/zka/HALKit/ARM64/.gitkeep0
-rw-r--r--dev/zka/HALKit/ARM64/APM/.gitkeep0
-rw-r--r--dev/zka/HALKit/ARM64/HalKernelMain.cxx68
-rw-r--r--dev/zka/HALKit/ARM64/HalPageInternal.S5
-rw-r--r--dev/zka/HALKit/ARM64/HalSchedulerCore.cxx48
-rw-r--r--dev/zka/HALKit/ARM64/HalTimer.cxx16
-rw-r--r--dev/zka/HALKit/ARM64/MBCI/.keepme0
-rw-r--r--dev/zka/HALKit/ARM64/Paging.hxx120
-rw-r--r--dev/zka/HALKit/ARM64/Processor.hxx50
-rw-r--r--dev/zka/HALKit/ARM64/ReadMe.md3
-rw-r--r--dev/zka/HALKit/ARM64/Storage/.gitkeep0
-rw-r--r--dev/zka/HALKit/ARM64/Storage/HalFlash.cxx66
-rw-r--r--dev/zka/HALKit/AXP/CR.s11
-rw-r--r--dev/zka/HALKit/AXP/CoreInterruptHandlerDEC.cpp0
-rw-r--r--dev/zka/HALKit/AXP/CoreSyscallHandlerDEC.cpp24
-rw-r--r--dev/zka/HALKit/AXP/HAL.s13
-rw-r--r--dev/zka/HALKit/AXP/Processor.hxx7
-rw-r--r--dev/zka/HALKit/AXP/README1
-rw-r--r--dev/zka/HALKit/AXP/README.TXT1
-rw-r--r--dev/zka/HALKit/AXP/SYSCALL.s10
-rw-r--r--dev/zka/HALKit/AXP/VM.s5
-rw-r--r--dev/zka/HALKit/POWER/.gitkeep0
-rw-r--r--dev/zka/HALKit/POWER/APM/.gitkeep0
-rw-r--r--dev/zka/HALKit/POWER/HalContextSwitchPowerPC.s30
-rw-r--r--dev/zka/HALKit/POWER/HalHart.cxx25
-rw-r--r--dev/zka/HALKit/POWER/HalSerialPort.cxx27
-rw-r--r--dev/zka/HALKit/POWER/HalStartSequence.s14
-rw-r--r--dev/zka/HALKit/POWER/HalThread.cxx8
-rw-r--r--dev/zka/HALKit/POWER/HalVirtualMemory.cxx51
-rw-r--r--dev/zka/HALKit/POWER/Hart.hxx36
-rw-r--r--dev/zka/HALKit/POWER/MBCI/.gitkeep0
-rw-r--r--dev/zka/HALKit/POWER/MBCI/HalMBCIHost.cxx8
-rw-r--r--dev/zka/HALKit/POWER/Processor.hxx60
-rw-r--r--dev/zka/HALKit/POWER/ReadMe.md4
-rw-r--r--dev/zka/HALKit/RISCV/.keep0
-rw-r--r--dev/zka/HALKit/RISCV/APM/.gitkeep0
-rw-r--r--dev/zka/HALKit/RISCV/Hart.hxx24
-rw-r--r--dev/zka/HALKit/RISCV/ReadMe.md4
-rw-r--r--dev/zka/HALKit/RISCV/Storage/.gitkeep0
-rw-r--r--dev/zka/HALKit/X86S/.gitkeep0
-rw-r--r--dev/zka/HALKit/X86S/ACPI/.gitkeep0
-rw-r--r--dev/zka/HALKit/X86S/Storage/.gitkeep0
82 files changed, 3830 insertions, 0 deletions
diff --git a/dev/zka/HALKit/.gitkeep b/dev/zka/HALKit/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/.gitkeep
diff --git a/dev/zka/HALKit/64x0/.hgkeep b/dev/zka/HALKit/64x0/.hgkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/64x0/.hgkeep
diff --git a/dev/zka/HALKit/64x0/APM/.hgkeep b/dev/zka/HALKit/64x0/APM/.hgkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/64x0/APM/.hgkeep
diff --git a/dev/zka/HALKit/64x0/HalVirtualMemory.cxx b/dev/zka/HALKit/64x0/HalVirtualMemory.cxx
new file mode 100644
index 00000000..1b0c9153
--- /dev/null
+++ b/dev/zka/HALKit/64x0/HalVirtualMemory.cxx
@@ -0,0 +1,17 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <HALKit/POWER/Processor.hxx>
+#include <KernelKit/DebugOutput.hxx>
+
+using namespace Kernel;
+
+/// @brief Flush system TLB, looks like the POWER version, as it acts the same, no specific instruction for that.
+/// @note The 88K MMU should be present as well.
+EXTERN_C void hal_flush_tlb()
+{
+ asm volatile("invltlb");
+}
diff --git a/dev/zka/HALKit/64x0/MBCI/.gitkeep b/dev/zka/HALKit/64x0/MBCI/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/64x0/MBCI/.gitkeep
diff --git a/dev/zka/HALKit/64x0/ReadMe.md b/dev/zka/HALKit/64x0/ReadMe.md
new file mode 100644
index 00000000..2e72d5bf
--- /dev/null
+++ b/dev/zka/HALKit/64x0/ReadMe.md
@@ -0,0 +1,4 @@
+64x0 Hardware Abstraction Layer
+
+- Supported CPU: ZKA Technologies 64x0
+- Supported Firmware: CoreBoot \ No newline at end of file
diff --git a/dev/zka/HALKit/AMD64/CPUID.hxx b/dev/zka/HALKit/AMD64/CPUID.hxx
new file mode 100644
index 00000000..ae6e42c5
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/CPUID.hxx
@@ -0,0 +1,81 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ File: CPUID.hxx
+ Purpose: CPUID flags.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+
+------------------------------------------- */
+
+#pragma once
+
+enum
+{
+ eCPU_FEATURE_ECX_SSE3 = 1 << 0,
+ eCPU_FEATURE_ECX_PCLMUL = 1 << 1,
+ eCPU_FEATURE_ECX_DTES64 = 1 << 2,
+ eCPU_FEATURE_ECX_MONITOR = 1 << 3,
+ eCPU_FEATURE_ECX_DS_CPL = 1 << 4,
+ eCPU_FEATURE_ECX_VMX = 1 << 5,
+ eCPU_FEATURE_ECX_SMX = 1 << 6,
+ eCPU_FEATURE_ECX_EST = 1 << 7,
+ eCPU_FEATURE_ECX_TM2 = 1 << 8,
+ eCPU_FEATURE_ECX_SSSE3 = 1 << 9,
+ eCPU_FEATURE_ECX_CID = 1 << 10,
+ eCPU_FEATURE_ECX_SDBG = 1 << 11,
+ eCPU_FEATURE_ECX_FMA = 1 << 12,
+ eCPU_FEATURE_ECX_CX16 = 1 << 13,
+ eCPU_FEATURE_ECX_XTPR = 1 << 14,
+ eCPU_FEATURE_ECX_PDCM = 1 << 15,
+ eCPU_FEATURE_ECX_PCID = 1 << 17,
+ eCPU_FEATURE_ECX_DCA = 1 << 18,
+ eCPU_FEATURE_ECX_SSE4_1 = 1 << 19,
+ eCPU_FEATURE_ECX_SSE4_2 = 1 << 20,
+ eCPU_FEATURE_ECX_X2APIC = 1 << 21,
+ eCPU_FEATURE_ECX_MOVBE = 1 << 22,
+ eCPU_FEATURE_ECX_POP3C = 1 << 23,
+ eCPU_FEATURE_ECX_TSC = 1 << 24,
+ eCPU_FEATURE_ECX_AES = 1 << 25,
+ eCPU_FEATURE_ECX_XSAVE = 1 << 26,
+ eCPU_FEATURE_ECX_OSXSAVE = 1 << 27,
+ eCPU_FEATURE_ECX_AVX = 1 << 28,
+ eCPU_FEATURE_ECX_F16C = 1 << 29,
+ eCPU_FEATURE_ECX_RDRAND = 1 << 30,
+ eCPU_FEATURE_ECX_HYPERVISOR = 1 << 31,
+ eCPU_FEATURE_EDX_FPU = 1 << 0,
+ eCPU_FEATURE_EDX_VME = 1 << 1,
+ eCPU_FEATURE_EDX_DE = 1 << 2,
+ eCPU_FEATURE_EDX_PSE = 1 << 3,
+ eCPU_FEATURE_EDX_TSC = 1 << 4,
+ eCPU_FEATURE_EDX_MSR = 1 << 5,
+ eCPU_FEATURE_EDX_PAE = 1 << 6,
+ eCPU_FEATURE_EDX_MCE = 1 << 7,
+ eCPU_FEATURE_EDX_CX8 = 1 << 8,
+ eCPU_FEATURE_EDX_APIC = 1 << 9,
+ eCPU_FEATURE_EDX_SEP = 1 << 11,
+ eCPU_FEATURE_EDX_MTRR = 1 << 12,
+ eCPU_FEATURE_EDX_PGE = 1 << 13,
+ eCPU_FEATURE_EDX_MCA = 1 << 14,
+ eCPU_FEATURE_EDX_CMOV = 1 << 15,
+ eCPU_FEATURE_EDX_PAT = 1 << 16,
+ eCPU_FEATURE_EDX_PSE36 = 1 << 17,
+ eCPU_FEATURE_EDX_PSN = 1 << 18,
+ eCPU_FEATURE_EDX_CLFLUSH = 1 << 19,
+ eCPU_FEATURE_EDX_DS = 1 << 21,
+ eCPU_FEATURE_EDX_ACPI = 1 << 22,
+ eCPU_FEATURE_EDX_MMX = 1 << 23,
+ eCPU_FEATURE_EDX_FXSR = 1 << 24,
+ eCPU_FEATURE_EDX_SSE = 1 << 25,
+ eCPU_FEATURE_EDX_SSE2 = 1 << 26,
+ eCPU_FEATURE_EDX_SS = 1 << 27,
+ eCPU_FEATURE_EDX_HTT = 1 << 28,
+ eCPU_FEATURE_EDX_TM = 1 << 29,
+ eCPU_FEATURE_EDX_IA64 = 1 << 30,
+ eCPU_FEATURE_EDX_PBE = 1 << 31
+};
+
+typedef long long int hal_cpu_feature_type; \ No newline at end of file
diff --git a/dev/zka/HALKit/AMD64/HalACPIFactoryInterface.cxx b/dev/zka/HALKit/AMD64/HalACPIFactoryInterface.cxx
new file mode 100644
index 00000000..1cb8ce07
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalACPIFactoryInterface.cxx
@@ -0,0 +1,208 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <Modules/ACPI/ACPIFactoryInterface.hxx>
+#include <HALKit/AMD64/Processor.hxx>
+#include <NewKit/String.hxx>
+#include <ArchKit/ArchKit.hxx>
+#include <KernelKit/Heap.hxx>
+
+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 BootArchitectureFlags;
+
+ 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 rsdPtr)
+ : fRsdp(rsdPtr), 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; ");
+ }
+
+ /// @brief Finds a descriptor table inside ACPI XSDT.
+ ErrorOr<voidPtr> ACPIFactoryInterface::Find(const Char* signature)
+ {
+ MUST_PASS(fRsdp);
+
+ if (!signature)
+ return ErrorOr<voidPtr>{-1};
+
+ if (*signature == 0)
+ return ErrorOr<voidPtr>{-1};
+
+ RSDP* rsdPtr = reinterpret_cast<RSDP*>(this->fRsdp);
+
+ if (rsdPtr->Revision <= 1)
+ return ErrorOr<voidPtr>{-1};
+
+ RSDT* xsdt = reinterpret_cast<RSDT*>(rsdPtr->RsdtAddress);
+
+ Int64 num = (xsdt->Length - sizeof(SDT)) / sizeof(UInt32);
+
+ /***
+ crucial to avoid - overflows.
+ */
+ if (num < 1)
+ {
+ /// stop here, we should have entries...
+ ke_stop(RUNTIME_CHECK_ACPI);
+ return ErrorOr<voidPtr>{-1};
+ }
+
+ this->fEntries = num;
+
+ kcout << "ACPI: Number of entries: " << number(this->fEntries) << endl;
+ kcout << "ACPI: Revision: " << number(xsdt->Revision) << endl;
+ kcout << "ACPI: Signature: " << xsdt->Signature << endl;
+ kcout << "ACPI: Address of XSDT: " << hex_number((UIntPtr)xsdt) << endl;
+
+ const short cAcpiSignatureLength = 4;
+
+ for (Size index = 0; index < this->fEntries; ++index)
+ {
+ SDT* sdt = reinterpret_cast<SDT*>(xsdt->AddressArr[index]);
+
+ kcout << "ACPI: Checksum: " << number(sdt->Checksum) << endl;
+ kcout << "ACPI: Revision: " << number(sdt->Revision) << endl;
+
+ for (short signature_index = 0; signature_index < cAcpiSignatureLength; ++signature_index)
+ {
+ if (sdt->Signature[signature_index] != signature[signature_index])
+ break;
+
+ if (signature_index == (cAcpiSignatureLength - 1))
+ {
+ kcout << "ACPI: Found the SDT. " << endl;
+ return ErrorOr<voidPtr>(reinterpret_cast<voidPtr>(xsdt->AddressArr[index]));
+ }
+ }
+ }
+
+ return ErrorOr<voidPtr>{-1};
+ }
+
+ /***
+ @brief check SDT header
+ @param checksum the header to checksum
+ @param len the length of it.
+*/
+ bool ACPIFactoryInterface::Checksum(const Char* checksum, SSizeT len)
+ {
+ if (len == 0)
+ return -1;
+
+ char chr = 0;
+
+ for (int index = 0; index < len; ++index)
+ {
+ chr += checksum[index];
+ }
+
+ return chr == 0;
+ }
+} // namespace Kernel
diff --git a/dev/zka/HALKit/AMD64/HalAPICMgr.cxx b/dev/zka/HALKit/AMD64/HalAPICMgr.cxx
new file mode 100644
index 00000000..caa2ce0b
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalAPICMgr.cxx
@@ -0,0 +1,36 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <Modules/ACPI/ACPIFactoryInterface.hxx>
+#include <HALKit/AMD64/Processor.hxx>
+
+namespace Kernel::HAL
+{
+ /// @brief Read from APIC controller.
+ /// @param reg register.
+ UInt32 APICController::Read(UInt32 reg) noexcept
+ {
+ MUST_PASS(this->fApic);
+
+ UInt32 volatile* ioapic = (UInt32 volatile*)this->fApic;
+ ioapic[0] = (reg & 0xff);
+
+ return ioapic[4];
+ }
+
+ /// @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* ioapic = (UInt32 volatile*)this->fApic;
+
+ ioapic[0] = (reg & 0xFF);
+ ioapic[4] = value;
+ }
+} // namespace Kernel::HAL
diff --git a/dev/zka/HALKit/AMD64/HalBMPMgr.cxx b/dev/zka/HALKit/AMD64/HalBMPMgr.cxx
new file mode 100644
index 00000000..b788902a
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalBMPMgr.cxx
@@ -0,0 +1,182 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.hxx>
+
+#define cBitMpMagic ((Kernel::UIntPtr)0x10210)
+
+#ifdef __ZKA_AMD64__
+#include <HALKit/AMD64/Paging.hxx>
+#elif defined(__ZKA_ARM64__)
+#include <HALKit/ARM64/Paging.hxx>
+#endif
+
+#include <NewKit/Defines.hxx>
+#include <NewKit/KernelCheck.hxx>
+
+#define cBitMapMagIdx 0
+#define cBitMapSizeIdx 1
+#define cBitMapUsedIdx 2
+
+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[cBitMapMagIdx] ||
+ ptr_bit_set[cBitMapMagIdx] != cBitMpMagic)
+ 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[cBitMapMagIdx] = cBitMpMagic;
+ ptr_bit_set[cBitMapUsedIdx] = No;
+
+ this->GetBitMapStatus(ptr_bit_set);
+
+ mm_map_page(ptr_bit_set, ~eFlagsPresent);
+ mm_map_page(ptr_bit_set, ~eFlagsRw);
+ mm_map_page(ptr_bit_set, ~eFlagsUser);
+
+ return Yes;
+ }
+
+ /// @brief Iterate over availables pages for a free one.
+ /// @return The new address which was found.
+ auto FindBitMap(VoidPtr base_ptr, SizeT size, Bool rw, Bool user) -> VoidPtr
+ {
+ VoidPtr base = reinterpret_cast<VoidPtr>(((UIntPtr)base_ptr) + kPageSize);
+
+ while (base && size)
+ {
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(base);
+
+ if (ptr_bit_set[cBitMapMagIdx] == cBitMpMagic &&
+ ptr_bit_set[cBitMapSizeIdx] <= size)
+ {
+ if (ptr_bit_set[cBitMapUsedIdx] == No)
+ {
+ ptr_bit_set[cBitMapSizeIdx] = size;
+ ptr_bit_set[cBitMapUsedIdx] = Yes;
+
+ this->GetBitMapStatus(ptr_bit_set);
+
+ return (VoidPtr)ptr_bit_set;
+ }
+ }
+ else if (ptr_bit_set[cBitMapMagIdx] != cBitMpMagic)
+ {
+ UIntPtr* ptr_bit_set = reinterpret_cast<UIntPtr*>(base_ptr);
+
+ ptr_bit_set[cBitMapMagIdx] = cBitMpMagic;
+ ptr_bit_set[cBitMapSizeIdx] = size;
+ ptr_bit_set[cBitMapUsedIdx] = Yes;
+
+ this->GetBitMapStatus(ptr_bit_set);
+
+ return (VoidPtr)ptr_bit_set;
+ }
+
+ base = reinterpret_cast<VoidPtr>(reinterpret_cast<UIntPtr>(base_ptr) + (ptr_bit_set[0] != cBitMpMagic ? size : ptr_bit_set[1]));
+
+ if ((UIntPtr)base_ptr < (reinterpret_cast<UIntPtr>(base) + kHandoverHeader->f_BitMapSize))
+ return nullptr;
+ }
+
+ 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 BitMap Number: " << hex_number(ptr_bit_set[cBitMapMagIdx]) << endl;
+ kcout << "Allocated: " << (ptr_bit_set[cBitMapUsedIdx] ? "Yes" : "No") << endl;
+ kcout << "Size of BitMap (B): " << number(ptr_bit_set[cBitMapSizeIdx]) << endl;
+ kcout << "Size of BitMap (KIB): " << number(KIB(ptr_bit_set[cBitMapSizeIdx])) << endl;
+ kcout << "Size of BitMap (MIB): " << number(MIB(ptr_bit_set[cBitMapSizeIdx])) << endl;
+ kcout << "Size of BitMap (GIB): " << number(GIB(ptr_bit_set[cBitMapSizeIdx])) << endl;
+ kcout << "Size of BitMap (TIB): " << number(TIB(ptr_bit_set[cBitMapSizeIdx])) << endl;
+ kcout << "Address Of BitMap: " << hex_number((UIntPtr)ptr_bit_set) << endl;
+ }
+ };
+ } // namespace Detail
+
+ /// @brief Allocate a new page to be used by the OS.
+ /// @param rw read/write bit.
+ /// @param user user bit.
+ /// @return
+ auto mm_alloc_bitmap(Boolean rw, Boolean user, SizeT size) -> VoidPtr
+ {
+ VoidPtr ptr_new = nullptr;
+ Detail::IBitMapAllocator traits;
+
+ ptr_new = traits.FindBitMap(kKernelBitMpStart, size, rw, user);
+
+ if (!ptr_new)
+ {
+ ke_stop(RUNTIME_CHECK_PAGE);
+ }
+
+ if (rw)
+ mm_map_page(ptr_new, eFlagsRw | eFlagsPresent);
+ else if (user && rw)
+ mm_map_page(ptr_new, eFlagsUser | eFlagsRw | eFlagsPresent);
+ else if (user)
+ mm_map_page(ptr_new, eFlagsUser | eFlagsPresent);
+ else
+ mm_map_page(ptr_new, eFlagsPresent);
+
+ return (UIntPtr*)ptr_new;
+ }
+
+ auto mm_free_bitmap(VoidPtr page_ptr) -> Bool
+ {
+ if (!page_ptr)
+ return No;
+
+ Detail::IBitMapAllocator traits;
+ Bool ret = traits.FreeBitMap(page_ptr);
+
+ if (ret)
+ {
+ mm_map_page(page_ptr, ~eFlagsPresent);
+ }
+
+ return ret;
+ }
+ } // namespace HAL
+} // namespace Kernel
diff --git a/dev/zka/HALKit/AMD64/HalBoot.asm b/dev/zka/HALKit/AMD64/HalBoot.asm
new file mode 100644
index 00000000..21f99a49
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalBoot.asm
@@ -0,0 +1,22 @@
+;; /*
+;; * ========================================================
+;; *
+;; * ZKA
+;; * Copyright ZKA Technologies., 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
diff --git a/dev/zka/HALKit/AMD64/HalCommAPI.cxx b/dev/zka/HALKit/AMD64/HalCommAPI.cxx
new file mode 100644
index 00000000..11c442b4
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalCommAPI.cxx
@@ -0,0 +1,116 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ File: HalProcessor.cxx
+ Purpose: Platform processor routines.
+
+------------------------------------------- */
+
+#include <HALKit/AMD64/Paging.hxx>
+#include <HALKit/AMD64/Processor.hxx>
+
+/**
+ * @file HalCommAPI.cxx
+ * @brief CPU Common API.
+ */
+
+#define PhysShift36(ADDR) ((UInt64)ADDR >> 12)
+
+namespace Kernel::HAL
+{
+ /// @brief Maps or allocates a page from virt_addr.
+ /// @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)
+ {
+ ZKA_UNUSED(virt_addr);
+ ZKA_UNUSED(flags);
+
+ return 0;
+ }
+
+ Void Out8(UInt16 port, UInt8 value)
+ {
+ asm volatile("outb %%al, %1"
+ :
+ : "a"(value), "Nd"(port)
+ : "memory");
+ }
+
+ Void Out16(UInt16 port, UInt16 value)
+ {
+ asm volatile("outw %%ax, %1"
+ :
+ : "a"(value), "Nd"(port)
+ : "memory");
+ }
+
+ Void Out32(UInt16 port, UInt32 value)
+ {
+ asm volatile("outl %%eax, %1"
+ :
+ : "a"(value), "Nd"(port)
+ : "memory");
+ }
+
+ UInt8 In8(UInt16 port)
+ {
+ UInt8 value = 0UL;
+ asm volatile("inb %1, %%al"
+ : "=a"(value)
+ : "Nd"(port)
+ : "memory");
+
+ return value;
+ }
+
+ UInt16 In16(UInt16 port)
+ {
+ UInt16 value = 0UL;
+ asm volatile("inw %1, %%ax"
+ : "=a"(value)
+ : "Nd"(port)
+ : "memory");
+
+ return value;
+ }
+
+ UInt32 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/zka/HALKit/AMD64/HalControlRegister.s b/dev/zka/HALKit/AMD64/HalControlRegister.s
new file mode 100644
index 00000000..80b584ce
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalControlRegister.s
@@ -0,0 +1,45 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+.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/zka/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx b/dev/zka/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx
new file mode 100644
index 00000000..c6b8303d
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx
@@ -0,0 +1,129 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.hxx>
+#include <KernelKit/UserProcessScheduler.hxx>
+#include <NewKit/String.hxx>
+
+namespace Kernel
+{
+ EXTERN UserProcessScheduler* cProcessScheduler;
+}
+
+/// @brief Handle GPF fault.
+/// @param rsp
+EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp)
+{
+ if (Kernel::cProcessScheduler == nullptr)
+ {
+ Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED);
+ }
+
+ Kernel::UserProcessScheduler::The().CurrentProcess().Leak().Crash();
+
+ Kernel::UserProcessHelper::StartScheduling();
+ Kernel::ke_stop(RUNTIME_CHECK_PROCESS);
+}
+
+/// @brief Handle page fault.
+/// @param rsp
+EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp)
+{
+ if (Kernel::cProcessScheduler == nullptr)
+ {
+ Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED);
+ }
+
+ Kernel::UserProcessScheduler::The().CurrentProcess().Leak().Crash();
+
+ Kernel::UserProcessHelper::StartScheduling();
+ Kernel::ke_stop(RUNTIME_CHECK_PROCESS);
+}
+
+EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp)
+{
+ if (Kernel::cProcessScheduler == nullptr)
+ {
+ Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED);
+ }
+
+ Kernel::UserProcessHelper::StartScheduling();
+}
+
+/// @brief Handle math fault.
+/// @param rsp
+EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp)
+{
+ if (Kernel::cProcessScheduler == nullptr)
+ {
+ Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED);
+ }
+
+ Kernel::UserProcessScheduler::The().CurrentProcess().Leak().Crash();
+
+ Kernel::UserProcessHelper::StartScheduling();
+ Kernel::ke_stop(RUNTIME_CHECK_PROCESS);
+}
+
+/// @brief Handle any generic fault.
+/// @param rsp
+EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp)
+{
+ if (Kernel::cProcessScheduler == nullptr)
+ {
+ Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED);
+ }
+
+ Kernel::UserProcessScheduler::The().CurrentProcess().Leak().Crash();
+ Kernel::ke_stop(RUNTIME_CHECK_PROCESS);
+}
+
+/// @brief Handle #UD fault.
+/// @param rsp
+EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp)
+{
+ if (Kernel::cProcessScheduler == nullptr)
+ {
+ Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED);
+ }
+
+ Kernel::UserProcessScheduler::The().CurrentProcess().Leak().Crash();
+
+ Kernel::UserProcessHelper::StartScheduling();
+ Kernel::ke_stop(RUNTIME_CHECK_PROCESS);
+}
+
+/// @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, Kernel::UIntPtr rdx)
+{
+ if (rcx <= (kSyscalls.Count() - 1))
+ {
+ kcout << "syscall: Enter Fn.\r";
+
+ if (kSyscalls[rcx].fHooked)
+ (kSyscalls[rcx].fProc)((Kernel::VoidPtr)rdx);
+
+ kcout << "syscall: Exit Fn.\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, Kernel::UIntPtr rdx, Kernel::UIntPtr r8, Kernel::UIntPtr r9)
+{
+ if (rcx <= (kSyscalls.Count() - 1))
+ {
+ kcout << "kerncall: Enter Fn.\r";
+
+ if (kKerncalls[rcx].fHooked)
+ (kKerncalls[rcx].fProc)((Kernel::VoidPtr)rdx);
+
+ kcout << "kerncall: Exit Fn.\r";
+ }
+}
diff --git a/dev/zka/HALKit/AMD64/HalCoreMPScheduler.cxx b/dev/zka/HALKit/AMD64/HalCoreMPScheduler.cxx
new file mode 100644
index 00000000..18302f34
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalCoreMPScheduler.cxx
@@ -0,0 +1,241 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <Modules/ACPI/ACPIFactoryInterface.hxx>
+#include <KernelKit/UserProcessScheduler.hxx>
+#include <HALKit/AMD64/Processor.hxx>
+#include <NewKit/KernelCheck.hxx>
+#include <ArchKit/ArchKit.hxx>
+#include <KernelKit/Semaphore.hxx>
+#include <KernelKit/UserProcessScheduler.hxx>
+#include <KernelKit/Timer.hxx>
+#include <Modules/CoreCG/TextRenderer.hxx>
+
+// Needed for SMP. //
+#include <FirmwareKit/EFI.hxx>
+#include <KernelKit/HardwareThreadScheduler.hxx>
+
+#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
+
+#define cSMPMax (32U)
+
+/// @note: _hal_switch_context is internal
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+//! NOTE: fGSI stands 'Field Global System Interrupt'
+
+///////////////////////////////////////////////////////////////////////////////////////
+
+namespace Kernel::HAL
+{
+ struct MADT_TABLE;
+
+ EXTERN_C Void _hal_spin_core(Void);
+
+ STATIC struct MADT_TABLE* kMADTBlock = nullptr;
+ STATIC Bool kSMPAware = false;
+ STATIC Int64 kSMPCount = 0;
+
+ STATIC Int32 cSMPInterrupt = 0;
+ STATIC UInt64 cSMPCores[cSMPMax] = {0};
+ STATIC VoidPtr kRawMADT = nullptr;
+
+ /// @brief Multiple APIC Descriptor Table.
+ struct MADT_TABLE 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 start IPI for CPU.
+ /// @param apicId
+ /// @param vector
+ /// @param targetAddress
+ /// @return
+ /***********************************************************************************/
+
+ Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress)
+ {
+ Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, (apicId << 24));
+ Kernel::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_SIPI_Vector | vector);
+ }
+
+ /***********************************************************************************/
+ /// @brief Send end IPI for CPU.
+ /// @param apicId
+ /// @param vector
+ /// @param targetAddress
+ /// @return
+ /***********************************************************************************/
+ Void hal_send_end_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress)
+ {
+ Kernel::ke_dma_write(targetAddress, kAPIC_ICR_High, (apicId << 24));
+ Kernel::ke_dma_write(targetAddress, kAPIC_ICR_Low, kAPIC_EIPI_Vector | vector);
+ }
+
+ EXTERN_C Bool mp_register_process(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_frame);
+
+ /// @brief Called when the AP is ready.
+ /// @internal
+ EXTERN_C Void hal_on_ap_startup(Void)
+ {
+ while (Yes)
+ {
+ }
+ }
+
+ struct PROCESS_CONTROL_BLOCK final
+ {
+ HAL::StackFramePtr f_Frame;
+ UInt8* f_Stack;
+ VoidPtr f_Image;
+ } fBlocks[kSchedProcessLimitPerTeam] = {0};
+
+ EXTERN_C HAL::StackFramePtr mp_get_current_context(Void)
+ {
+ return fBlocks[UserProcessScheduler::The().CurrentProcess().Leak().ProcessId % kSchedProcessLimitPerTeam].f_Frame;
+ }
+
+ EXTERN_C Bool mp_register_process(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_frame)
+ {
+ if (kSMPAware)
+ {
+ fBlocks[UserProcessScheduler::The().CurrentProcess().Leak().ProcessId % kSchedProcessLimitPerTeam].f_Frame = stack_frame;
+ fBlocks[UserProcessScheduler::The().CurrentProcess().Leak().ProcessId % kSchedProcessLimitPerTeam].f_Stack = stack_ptr;
+ fBlocks[UserProcessScheduler::The().CurrentProcess().Leak().ProcessId % kSchedProcessLimitPerTeam].f_Image = image;
+
+ return Yes;
+ }
+
+ return No;
+ }
+
+ /***********************************************************************************/
+ /// @brief Fetch and enable cores inside main CPU.
+ /// @param vendor_ptr RSD PTR structure.
+ /***********************************************************************************/
+ Void mp_get_cores(VoidPtr vendor_ptr) noexcept
+ {
+ if (!vendor_ptr)
+ return;
+
+ auto hw_and_pow_int = PowerFactoryInterface(vendor_ptr);
+ kRawMADT = hw_and_pow_int.Find(kApicSignature).Leak().Leak();
+
+ kMADTBlock = reinterpret_cast<MADT_TABLE*>(kRawMADT);
+
+ kSMPAware = false;
+
+ if (kMADTBlock)
+ {
+ SizeT index = 0;
+
+ // reset values.
+
+ cSMPInterrupt = 0;
+ kSMPCount = 0;
+
+ kcout << "Probing MADT cores...\r";
+
+ UIntPtr madt_address = kMADTBlock->Address;
+
+ while (Yes)
+ {
+ if (kMADTBlock->List[index].Type > 9 ||
+ kSMPCount > cSMPMax)
+ break;
+
+ switch (kMADTBlock->List[index].Type)
+ {
+ case 0x00: {
+ cSMPCores[index] = kMADTBlock->List[index].LAPIC.ProcessorID;
+ kcout << "Core ID: " << number(cSMPCores[index]) << endl;
+ ++kSMPCount;
+ break;
+ }
+ case 0x05: {
+ madt_address = kMADTBlock->List[index].LAPIC_ADDRESS_OVERRIDE.Address;
+ kcout << "Address: " << number(madt_address) << endl;
+ break;
+ }
+ }
+
+ ++index;
+ }
+
+ kcout << "# of cores: " << number(kSMPCount) << endl;
+
+ // Kernel is now SMP aware.
+ // That means that the scheduler is now available (on MP Kernels)
+
+ kSMPAware = true;
+
+ const auto cStartIPI = 0x34;
+
+ /// TODO: Notify AP core that it must start.
+ }
+ }
+} // namespace Kernel::HAL
+
+///////////////////////////////////////////////////////////////////////////////////////
diff --git a/dev/zka/HALKit/AMD64/HalDebugOutput.cxx b/dev/zka/HALKit/AMD64/HalDebugOutput.cxx
new file mode 100644
index 00000000..296bbcec
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalDebugOutput.cxx
@@ -0,0 +1,145 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.hxx>
+#include <KernelKit/DebugOutput.hxx>
+#include <KernelKit/Framebuffer.hxx>
+#include <NewKit/Utils.hxx>
+#include <NewKit/New.hxx>
+
+namespace Kernel
+{
+ enum CommStatus
+ {
+ kStateInvalid,
+ kStateReady = 0xCF,
+ kStateTransmit = 0xFC,
+ kStateCnt = 3
+ };
+
+ namespace Detail
+ {
+ constexpr short PORT = 0x3F8;
+
+ static int kState = kStateInvalid;
+
+ /// @brief Init COM1.
+ /// @return
+ bool hal_serial_init() noexcept
+ {
+#ifdef __DEBUG__
+ if (kState == kStateReady || kState == kStateTransmit)
+ return true;
+
+ HAL::Out8(PORT + 1, 0x00); // Disable all interrupts
+ HAL::Out8(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor)
+ HAL::Out8(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud
+ HAL::Out8(PORT + 1, 0x00); // (hi byte)
+ HAL::Out8(PORT + 3, 0x03); // 8 bits, no parity, one stop bit
+ HAL::Out8(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold
+ HAL::Out8(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set
+ HAL::Out8(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip
+ HAL::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::In8(PORT) != 0xAE)
+ {
+ ke_stop(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::Out8(Detail::PORT + 4, 0x0F);
+#endif // __DEBUG__
+
+ return true;
+ }
+ } // namespace Detail
+
+ EXTERN_C void ke_io_write(const Char* bytes)
+ {
+#ifdef __DEBUG__
+ Detail::hal_serial_init();
+
+ 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::Out8(Detail::PORT, '\r');
+
+ HAL::Out8(Detail::PORT, 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();
+
+ 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::In8(Detail::PORT);
+
+ ///! 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/zka/HALKit/AMD64/HalDebugPort.cxx b/dev/zka/HALKit/AMD64/HalDebugPort.cxx
new file mode 100644
index 00000000..1ea52b8d
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalDebugPort.cxx
@@ -0,0 +1,40 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+//! @file DebuggerPort.cxx
+//! @brief UART debug via packets.
+
+#include <ArchKit/ArchKit.hxx>
+#include <KernelKit/DebugOutput.hxx>
+
+// 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::Out16(theHook->fPort[i], kDebugMag0);
+ HAL::rt_wait_400ns();
+
+ HAL::Out16(theHook->fPort[i], kDebugMag1);
+ HAL::rt_wait_400ns();
+
+ HAL::Out16(theHook->fPort[i], kDebugMag2);
+ HAL::rt_wait_400ns();
+
+ HAL::Out16(theHook->fPort[i], kDebugMag3);
+ HAL::rt_wait_400ns();
+
+ if (HAL::In16(theHook->fPort[i] != kDebugUnboundPort))
+ theHook->fBoundCnt++;
+ }
+ }
+} // namespace Kernel
diff --git a/dev/zka/HALKit/AMD64/HalDescriptorLoader.cxx b/dev/zka/HALKit/AMD64/HalDescriptorLoader.cxx
new file mode 100644
index 00000000..44263a1c
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalDescriptorLoader.cxx
@@ -0,0 +1,82 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.hxx>
+
+namespace Kernel::HAL
+{
+ namespace Detail
+ {
+ STATIC ::Kernel::Detail::AMD64::InterruptDescriptorAMD64
+ kInterruptVectorTable[kKernelIdtSize];
+
+ STATIC Void hal_remap_intel_pic_ctrl(Void) noexcept
+ {
+ auto a1 = HAL::In8(0xa1); // save masks
+ auto a2 = HAL::In8(0xa2);
+
+ HAL::Out8(0x20, 0x11);
+
+ HAL::Out8(0xA0, 0x11);
+
+ HAL::Out8(0x21, 32);
+ HAL::Out8(0xA1, 40);
+
+ HAL::Out8(0x21, 4);
+ HAL::Out8(0xA1, 2);
+
+ HAL::Out8(0x21, 0x01);
+ HAL::Out8(0xA1, 0x01);
+
+ HAL::Out8(0x21, a2);
+ HAL::Out8(0xA1, a1);
+ }
+ } // 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)
+ {
+ volatile ::Kernel::UIntPtr** ptr_ivt = (volatile ::Kernel::UIntPtr**)idt.Base;
+
+ for (UInt16 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 = 0x0;
+ }
+
+ idt.Base = (UIntPtr)&Detail::kInterruptVectorTable;
+ idt.Limit = sizeof(::Kernel::Detail::AMD64::InterruptDescriptorAMD64) *
+ (kKernelIdtSize)-1;
+
+ hal_load_idt(idt);
+
+ Detail::hal_remap_intel_pic_ctrl();
+ }
+
+ 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/zka/HALKit/AMD64/HalInterruptAPI.asm b/dev/zka/HALKit/AMD64/HalInterruptAPI.asm
new file mode 100644
index 00000000..cdbb2d1f
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalInterruptAPI.asm
@@ -0,0 +1,323 @@
+;; /*
+;; * ---------------------------------------------------
+;; *
+;; * Copyright ZKA Technologies., all rights reserved.
+;; *
+;; * File: HalInterruptAPI.asm
+;; * Purpose: Interrupt API, redirect raw interrupts into their handlers.
+;; *
+;; * ---------------------------------------------------
+;; */
+
+[bits 64]
+
+%define kInterruptId 0x21
+
+%macro IntExp 1
+global __ZKA_INT_%1
+__ZKA_INT_%1:
+ cld
+ o64 iret
+%endmacro
+
+%macro IntNormal 1
+global __ZKA_INT_%1
+__ZKA_INT_%1:
+ cld
+ 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
+
+section .text
+
+IntNormal 0
+IntNormal 1
+
+IntNormal 2
+
+IntNormal 3
+IntNormal 4
+IntNormal 5
+
+;; Invalid opcode interrupt
+__ZKA_INT_6:
+ cld
+
+ push rax
+
+ mov rcx, rsp
+ call idt_handle_ud
+
+ pop rax
+
+ std
+ o64 iret
+
+IntNormal 7
+
+;; Invalid opcode interrupt
+__ZKA_INT_8:
+ cld
+
+ push rax
+
+ mov rcx, rsp
+ call idt_handle_generic
+
+ pop rax
+
+ std
+ o64 iret
+
+IntNormal 9
+IntExp 10
+IntExp 11
+
+IntExp 12
+
+__ZKA_INT_13:
+ cld
+
+ push rax
+
+ mov rcx, rsp
+ call idt_handle_gpf
+
+ pop rax
+
+ std
+ o64 iret
+
+__ZKA_INT_14:
+ cld
+
+ push rax
+
+ mov rcx, rsp
+ call idt_handle_pf
+
+ pop rax
+
+ 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
+IntNormal 32
+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
+
+ push r8
+ push r9
+ push r10
+ push rsp
+
+ jmp hal_system_call_enter
+
+ add rsp, 16
+ pop rsp
+ pop r10
+ pop r9
+ pop r8
+
+ std
+ o64 iret
+
+__ZKA_INT_51:
+ cld
+
+ push rcx
+ push rdx
+ push r8
+ push r9
+ push rax
+
+ call hal_kernel_call_enter
+
+ pop rax
+ pop r9
+ pop r8
+ pop rdx
+ pop rcx
+
+ std
+ o64 iret
+
+[extern hal_on_ap_startup]
+
+PRESENT equ 1 << 7
+NOT_SYS equ 1 << 4
+EXEC equ 1 << 3
+DC equ 1 << 2
+RW equ 1 << 1
+ACCESSED equ 1 << 0
+
+; Flags bits
+GRAN_4K equ 1 << 7
+SZ_32 equ 1 << 6
+LONG_MODE equ 1 << 5
+
+__ZKA_INT_52:
+ cld
+ jmp hal_on_ap_startup
+ std
+ ret
+
+IntNormal 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
+ ;; Write address of syscall handler.
+
+ mov rdx, [mp_system_call_handler]
+ shr rdx, 32
+ mov rcx, 0xC0000082
+ wrmsr
+
+ ;; Set segments of syscall handler.
+
+ xor rax, rax
+ mov rdx, 0x230008
+ mov rcx, 0xC0000081
+ wrmsr
+
+ mov ecx, 0xC0000080
+ rdmsr
+ or eax, 1
+ wrmsr
+
+ jmp hal_real_init
+ ret
+
+global hal_load_idt
+global hal_user_code_start
+
+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
+
+hal_load_idt:
+ cld
+ lidt [rcx]
+ std
+ ret
+
+section .data
+
+kInterruptVectorTable:
+ %assign i 0
+ %rep 256
+ dq __ZKA_INT_%+i
+ %assign i i+1
+ %endrep
diff --git a/dev/zka/HALKit/AMD64/HalKernelMain.cxx b/dev/zka/HALKit/AMD64/HalKernelMain.cxx
new file mode 100644
index 00000000..767cc903
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalKernelMain.cxx
@@ -0,0 +1,95 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.hxx>
+#include <Modules/CoreCG/FbRenderer.hxx>
+#include <FirmwareKit/Handover.hxx>
+#include <KernelKit/FileMgr.hxx>
+#include <KernelKit/Framebuffer.hxx>
+#include <KernelKit/Heap.hxx>
+#include <KernelKit/PEFCodeMgr.hxx>
+#include <KernelKit/UserProcessScheduler.hxx>
+#include <NewKit/Json.hxx>
+#include <Modules/CoreCG/Accessibility.hxx>
+#include <KernelKit/CodeMgr.hxx>
+#include <Modules/ACPI/ACPIFactoryInterface.hxx>
+#include <NetworkKit/IPC.hxx>
+#include <CFKit/Property.hxx>
+#include <Modules/CoreCG/TextRenderer.hxx>
+#include <Modules/CoreCG/WindowRenderer.hxx>
+
+namespace Kernel::HAL
+{
+ /// @brief Gets the system cores using the MADT.
+ /// @param rsdPtr The 'RSD PTR' data structure.
+ EXTERN void mp_get_cores(Kernel::voidPtr rsdPtr) noexcept;
+} // namespace Kernel::HAL
+
+EXTERN_C Kernel::VoidPtr kInterruptVectorTable[];
+
+/// @brief Kernel init procedure.
+EXTERN_C void hal_init_platform(
+ Kernel::HEL::HANDOVER_INFO_HEADER* HandoverHeader)
+{
+ kHandoverHeader = HandoverHeader;
+
+ if (kHandoverHeader->f_Magic != kHandoverMagic &&
+ kHandoverHeader->f_Version != kHandoverVersion)
+ {
+ return;
+ }
+
+ CG::CGDrawBackground();
+
+ // get page size.
+ kKernelBitMpSize = kHandoverHeader->f_BitMapSize;
+
+ // get virtual address start (for the heap)
+ kKernelBitMpStart = reinterpret_cast<Kernel::VoidPtr>(
+ reinterpret_cast<Kernel::UIntPtr>(kHandoverHeader->f_BitMapStart));
+
+ STATIC CONST auto cEntriesCount = 6;
+
+ /* GDT, mostly descriptors for user and kernel segments. */
+ STATIC Kernel::HAL::Detail::ZKA_GDT_ENTRY ALIGN(0x08) cGdt[cEntriesCount] = {
+ {.fLimitLow = 0, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0x00, .fFlags = 0x00, .fBaseHigh = 0}, // Null entry
+ {.fLimitLow = 0xFFFF, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0x9A, .fFlags = 0xAF, .fBaseHigh = 0}, // Kernel code
+ {.fLimitLow = 0xFFFF, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0x92, .fFlags = 0xCF, .fBaseHigh = 0}, // Kernel data
+ {.fLimitLow = 0xFFFF, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0xF2, .fFlags = 0xCF, .fBaseHigh = 0}, // User data
+ {.fLimitLow = 0xFFFF, .fBaseLow = 0, .fBaseMid = 0, .fAccessByte = 0xFA, .fFlags = 0xAF, .fBaseHigh = 0}, // User code
+ };
+
+ // Load memory descriptors.
+ Kernel::HAL::RegisterGDT gdtBase;
+
+ gdtBase.Base = reinterpret_cast<Kernel::UIntPtr>(cGdt);
+ gdtBase.Limit = (sizeof(Kernel::HAL::Detail::ZKA_GDT_ENTRY) * cEntriesCount) - 1;
+
+ //! GDT will load hal_read_init after it successfully loads the segments.
+ Kernel::HAL::GDTLoader gdtLoader;
+ gdtLoader.Load(gdtBase);
+
+ Kernel::ke_stop(RUNTIME_CHECK_BOOTSTRAP);
+}
+
+EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept
+{
+ Kernel::HAL::Register64 idtBase;
+ idtBase.Base = (Kernel::UIntPtr)kInterruptVectorTable;
+
+ Kernel::HAL::IDTLoader idtLoader;
+ idtLoader.Load(idtBase);
+
+ if (kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled)
+ Kernel::HAL::mp_get_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr);
+
+ Kernel::NeFileSystemMgr* mgr = Kernel::mm_new_class<Kernel::NeFileSystemMgr>();
+ Kernel::NeFileSystemMgr::Mount(mgr);
+
+ mp_do_user_switch();
+
+ Kernel::ke_stop(RUNTIME_CHECK_BOOTSTRAP);
+}
diff --git a/dev/zka/HALKit/AMD64/HalMPContextSwitch.asm b/dev/zka/HALKit/AMD64/HalMPContextSwitch.asm
new file mode 100644
index 00000000..4251f232
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalMPContextSwitch.asm
@@ -0,0 +1,59 @@
+;; /*
+;; * ========================================================
+;; *
+;; * ZKA
+;; * Copyright ZKA Technologies., all rights reserved.
+;; *
+;; * ========================================================
+;; */
+
+[bits 64]
+
+[global mp_do_user_switch]
+[global mp_do_context_switch_pre]
+[global mp_user_switch_proc]
+[global mp_user_switch_proc_real]
+[global mp_user_switch_proc_stack_end]
+
+section .text
+
+;; @brief Switch to user mode.
+mp_do_user_switch:
+ mov rbp, rsp
+ mov rsp, mp_user_switch_proc_stack_end
+
+ mov rdx, mp_user_switch_proc
+ invlpg [rdx]
+
+ mov ax, 0x18 | 3
+ mov ds, ax
+ mov es, ax
+ mov gs, ax
+ mov fs, ax
+
+ push 0x18 | 3
+
+ mov rax, mp_user_switch_proc_stack_end
+ push rax
+
+ o64 pushf
+
+ push 0x20 | 3
+
+ mov rdx, mp_user_switch_proc
+ push rdx
+
+ o64 iret
+
+section .bss
+
+mp_user_switch_proc_stack_begin:
+ resb 4*4096
+mp_user_switch_proc_stack_end:
+
+section .text
+
+mp_user_switch_proc:
+ nop
+ jmp $
+mp_user_switch_proc_end:
diff --git a/dev/zka/HALKit/AMD64/HalRoutineWait.s b/dev/zka/HALKit/AMD64/HalRoutineWait.s
new file mode 100644
index 00000000..d794882d
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalRoutineWait.s
@@ -0,0 +1,9 @@
+.globl rt_wait_400ns
+
+.section .text
+rt_wait_400ns:
+ jmp .loop
+ .loop:
+ jmp .loop2
+ .loop2:
+ ret
diff --git a/dev/zka/HALKit/AMD64/HalSchedulerCore.cxx b/dev/zka/HALKit/AMD64/HalSchedulerCore.cxx
new file mode 100644
index 00000000..9dcce147
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalSchedulerCore.cxx
@@ -0,0 +1,56 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <HALKit/AMD64/Processor.hxx>
+#include <KernelKit/UserProcessScheduler.hxx>
+
+using namespace Kernel;
+
+Void UserProcess::SetImageStart(VoidPtr imageStart) noexcept
+{
+ if (imageStart == nullptr)
+ this->Crash();
+
+ this->Image = imageStart;
+}
+
+namespace Kernel
+{
+ /***********************************************************************************/
+ /// @brief Unimplemented function (crashes by default)
+ /// @param
+ /***********************************************************************************/
+
+ EXTERN_C Void __zka_pure_call(void)
+ {
+ asm volatile("mov %r8, 0; mov %r9, 1; syscall");
+ }
+
+ Bool hal_check_stack(HAL::StackFramePtr stack_ptr)
+ {
+ if (!stack_ptr)
+ return false;
+
+ return true;
+ }
+
+ /// @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/zka/HALKit/AMD64/HalTimer.cxx b/dev/zka/HALKit/AMD64/HalTimer.cxx
new file mode 100644
index 00000000..4a5d38cf
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalTimer.cxx
@@ -0,0 +1,86 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ File: HalTimer.cxx
+ Purpose: HAL timer
+
+ Revision History:
+
+ 07/07/24: Added file (amlel)
+
+------------------------------------------- */
+
+#include <Modules/ACPI/ACPIFactoryInterface.hxx>
+#include <ArchKit/ArchKit.hxx>
+#include <KernelKit/Timer.hxx>
+
+// timer slot 0
+
+#define cHPETCounterRegValue (0x00)
+#define cHPETConfigRegValue (0x20)
+#define cHPETCompRegValue (0x24)
+#define cHPETInterruptRegValue (0x2C)
+
+///! BUGS: 0
+///! @file HalTimer.cxx
+///! @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;
+}
+
+Int32 HardwareTimer::Wait() noexcept
+{
+ if (fWaitFor < 1)
+ return -1;
+
+ // 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 0;
+}
diff --git a/dev/zka/HALKit/AMD64/HalUtils.asm b/dev/zka/HALKit/AMD64/HalUtils.asm
new file mode 100644
index 00000000..0e4caf2b
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/HalUtils.asm
@@ -0,0 +1,33 @@
+;; /*
+;; * ========================================================
+;; *
+;; * ZKA
+;; * Copyright ZKA Technologies., 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 cBspDone]
+[extern kApicMadtAddressesCount]
+[extern hal_on_ap_startup]
+[global hal_ap_trampoline]
+
+hal_ap_trampoline:
+hal_ap_trampoline_1:
+ jmp hal_on_ap_startup
diff --git a/dev/zka/HALKit/AMD64/Hypervisor.hxx b/dev/zka/HALKit/AMD64/Hypervisor.hxx
new file mode 100644
index 00000000..7871288f
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/Hypervisor.hxx
@@ -0,0 +1,25 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.hxx>
+
+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/zka/HALKit/AMD64/MBCI/.gitkeep b/dev/zka/HALKit/AMD64/MBCI/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/MBCI/.gitkeep
diff --git a/dev/zka/HALKit/AMD64/PCI/Database.cxx b/dev/zka/HALKit/AMD64/PCI/Database.cxx
new file mode 100644
index 00000000..971d43f9
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/PCI/Database.cxx
@@ -0,0 +1,11 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <KernelKit/PCI/Database.hxx>
+
+namespace Kernel
+{
+}
diff --git a/dev/zka/HALKit/AMD64/PCI/Device.cxx b/dev/zka/HALKit/AMD64/PCI/Device.cxx
new file mode 100644
index 00000000..bc6ba2bb
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/PCI/Device.cxx
@@ -0,0 +1,141 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.hxx>
+#include <KernelKit/PCI/Device.hxx>
+
+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::Out32((Kernel::UShort)Kernel::PCI::PciConfigKind::ConfigAddress,
+ target);
+
+ return Kernel::HAL::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::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)
+ {
+ // get bar 0
+ auto bar_zero = 0x10 + bar * sizeof(UInt32);
+ fBar = this->Read(bar_zero, 4);
+ }
+
+ Device::~Device() = default;
+
+ UInt Device::Read(UInt bar, Size sz)
+ {
+ ZKA_PCISetCfgTarget(bar, fBus, fDevice, fFunction);
+
+ if (sz == 4)
+ return HAL::In32((UShort)PciConfigKind::ConfigData + (bar & 3));
+ if (sz == 2)
+ return HAL::In16((UShort)PciConfigKind::ConfigData + (bar & 3));
+ if (sz == 1)
+ return HAL::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::Out32((UShort)PciConfigKind::ConfigData + (fBar & 3), (UInt)data);
+ if (sz == 2)
+ HAL::Out16((UShort)PciConfigKind::ConfigData + (fBar & 3), (UShort)data);
+ if (sz == 1)
+ HAL::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()
+ {
+ bool enable = Read(0x04, sizeof(UChar)) | (1 << 1);
+ Write(0x04, enable, sizeof(UShort));
+ }
+
+ void Device::BecomeBusMaster()
+ {
+ bool enable = Read(0x04, sizeof(UShort)) | (1 << 2);
+ Write(0x04, enable, sizeof(UShort));
+ }
+
+ UInt32 Device::Bar()
+ {
+ return fBar;
+ }
+
+ 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/zka/HALKit/AMD64/PCI/Dma.cxx b/dev/zka/HALKit/AMD64/PCI/Dma.cxx
new file mode 100644
index 00000000..bf1730d8
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/PCI/Dma.cxx
@@ -0,0 +1,82 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <KernelKit/PCI/Dma.hxx>
+
+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/zka/HALKit/AMD64/PCI/Express.cxx b/dev/zka/HALKit/AMD64/PCI/Express.cxx
new file mode 100644
index 00000000..6a926827
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/PCI/Express.cxx
@@ -0,0 +1,11 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <KernelKit/PCI/Express.hxx>
+
+namespace Kernel
+{
+}
diff --git a/dev/zka/HALKit/AMD64/PCI/IO.cxx b/dev/zka/HALKit/AMD64/PCI/IO.cxx
new file mode 100644
index 00000000..ea91c7b7
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/PCI/IO.cxx
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <KernelKit/PCI/IO.hxx>
diff --git a/dev/zka/HALKit/AMD64/PCI/Iterator.cxx b/dev/zka/HALKit/AMD64/PCI/Iterator.cxx
new file mode 100644
index 00000000..ea38e717
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/PCI/Iterator.cxx
@@ -0,0 +1,39 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <KernelKit/PCI/Iterator.hxx>
+
+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)
+ {
+ Device dev(bus, device, function, type == Types::PciDeviceKind::MassStorageController ? 5 : 1);
+
+ 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/zka/HALKit/AMD64/PCI/PCI.cxx b/dev/zka/HALKit/AMD64/PCI/PCI.cxx
new file mode 100644
index 00000000..59e3b06e
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/PCI/PCI.cxx
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <KernelKit/PCI/PCI.hxx>
diff --git a/dev/zka/HALKit/AMD64/Paging.hxx b/dev/zka/HALKit/AMD64/Paging.hxx
new file mode 100644
index 00000000..f127d0e4
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/Paging.hxx
@@ -0,0 +1,99 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#pragma once
+
+/** ---------------------------------------------------
+
+ * THIS FILE CONTAINS CODE FOR X86_64 PAGING.
+
+------------------------------------------------------- */
+
+#include <NewKit/Defines.hxx>
+
+#ifndef kPageMax
+#define kPageMax (0x200)
+#endif //! kPageMax
+
+#ifndef kPageAlign
+#define kPageAlign (0x08)
+#endif //! kPageAlign
+
+#ifndef kPageSize
+#define kPageSize (0x100)
+#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 rw, Boolean user, SizeT size) -> 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/zka/HALKit/AMD64/Processor.hxx b/dev/zka/HALKit/AMD64/Processor.hxx
new file mode 100644
index 00000000..e39cac0a
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/Processor.hxx
@@ -0,0 +1,296 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ File: Prcoessor.hxx
+ Purpose: AMD64 processor abstraction.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Array.hxx>
+#include <NewKit/Defines.hxx>
+#include <NewKit/Utils.hxx>
+#include <FirmwareKit/Handover.hxx>
+#include <HALKit/AMD64/Paging.hxx>
+
+EXTERN_C
+{
+#include <cpuid.h>
+}
+
+#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 Virtual memory flags.
+ enum
+ {
+ eFlagsPresent = 0x1,
+ eFlagsRw = 0x2,
+ eFlagsUser = 0x4,
+ eFlagsCount = 3,
+ };
+
+ /// @brief Set a PTE from pd_base.
+ /// @param virt_addr a valid virtual address.
+ /// @param phys_addr point to physical address.
+ /// @param flags the flags to put on the page.
+ /// @return Status code of page manip.
+ EXTERN_C Int32 mm_map_page(VoidPtr virt_addr, UInt32 flags);
+
+ EXTERN_C UChar In8(UInt16 port);
+ EXTERN_C UShort In16(UInt16 port);
+ EXTERN_C UInt In32(UInt16 port);
+
+ EXTERN_C void Out16(UShort port, UShort byte);
+ EXTERN_C void Out8(UShort port, UChar byte);
+ EXTERN_C void 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();
+
+ 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};
+ };
+
+ 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);
+ };
+
+ Void mp_get_cores(VoidPtr rsdPtr) noexcept;
+ Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress);
+ Void hal_send_end_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress);
+
+ /// @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.
+ /// @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};
+ };
+} // 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 Kernel::Void hal_load_idt(Kernel::HAL::Register64 ptr);
+EXTERN_C Kernel::Void hal_load_gdt(Kernel::HAL::RegisterGDT ptr);
+
+/// @brief Maximum size of the IDT.
+#define kKernelIdtSize (0x100)
+#define kKernelInterruptId 0x32
+
+inline Kernel::VoidPtr kKernelBitMpStart = nullptr;
+inline Kernel::UIntPtr kKernelBitMpSize = 0UL;
diff --git a/dev/zka/HALKit/AMD64/ReadMe.md b/dev/zka/HALKit/AMD64/ReadMe.md
new file mode 100644
index 00000000..bb936737
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/ReadMe.md
@@ -0,0 +1,4 @@
+# AMD64 Hardware Abstraction Layer
+
+- Supported CPU: AMD64 CPU
+- Supported Firmware: EDK 2
diff --git a/dev/zka/HALKit/AMD64/Storage/AHCI.cxx b/dev/zka/HALKit/AMD64/Storage/AHCI.cxx
new file mode 100644
index 00000000..95d73c03
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/Storage/AHCI.cxx
@@ -0,0 +1,123 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+/**
+ * @file AHCI.cxx
+ * @author Amlal El Mahrouss (amlalelmahrouss@icloud.com)
+ * @brief AHCI driver.
+ * @version 0.1
+ * @date 2024-02-02
+ *
+ * @copyright ZKA Technologies.
+ *
+ */
+
+#include <Modules/AHCI/AHCI.hxx>
+#include <KernelKit/PCI/Iterator.hxx>
+
+#ifdef __AHCI__
+enum
+{
+ kSATAProgIfAHCI = 0x01,
+ kSATASubClass = 0x06
+};
+
+STATIC Kernel::PCI::Device kAhciDevice;
+STATIC HbaPort* kAhciPort = nullptr;
+
+/// @brief Initializes an AHCI disk.
+/// @param PortsImplemented the amount of port that have been detected.
+/// @return
+Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented)
+{
+ using namespace Kernel;
+
+ PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController);
+
+ for (SizeT devIndex = 0; devIndex < ZKA_BUS_COUNT; ++devIndex)
+ {
+ if (iterator[devIndex].Leak().Subclass() == kSATASubClass &&
+ iterator[devIndex].Leak().ProgIf() == kSATAProgIfAHCI)
+ {
+ iterator[devIndex].Leak().EnableMmio(); /// enable the memory i/o for this ahci device.
+ iterator[devIndex].Leak().BecomeBusMaster(); /// become bus master for this ahci device, so that we can control it.
+
+ kAhciDevice = iterator[devIndex].Leak(); /// and then leak the reference.
+
+ HbaMem* mem_ahci = (HbaMem*)kAhciDevice.Bar();
+
+ UInt32 ports_implemented = mem_ahci->Pi;
+ Int32 ahci_index = 0;
+
+ const auto cMaxAhciDevices = 32;
+ const auto cAhciSig = 0x00000101;
+ const auto cAhciPresent = 0x03;
+ const auto cAhciIPMActive = 0x01;
+
+ auto detected = false;
+
+ while (ahci_index < cMaxAhciDevices)
+ {
+ if (ports_implemented)
+ {
+ kcout << "Port is implemented by host.\r";
+
+ UInt8 ipm = (mem_ahci->Ports[ahci_index].Ssts >> 8) & 0x0F;
+ UInt8 det = mem_ahci->Ports[ahci_index].Ssts & 0x0F;
+
+ if (mem_ahci->Ports[ahci_index].Sig == cAhciSig &&
+ det == cAhciPresent &&
+ ipm == cAhciIPMActive)
+ {
+ kcout << "Found AHCI controller.\r";
+ kcout << "Device is of SATA type.\r";
+
+ detected = true;
+
+ kAhciPort = &mem_ahci->Ports[ahci_index];
+
+ // start command engine.
+ // drv_start_ahci_engine();
+ }
+ }
+
+ ports_implemented >>= 1;
+ ahci_index++;
+ }
+
+ return detected;
+ }
+ }
+
+ return false;
+}
+
+Kernel::Boolean drv_std_detected(Kernel::Void)
+{
+ return kAhciDevice.DeviceId() != 0xFFFF;
+}
+
+Kernel::Void drv_std_read(Kernel::UInt64 Lba, Kernel::Char* Buf, Kernel::SizeT SectorSz, Kernel::SizeT Size)
+{
+}
+
+Kernel::Void drv_std_write(Kernel::UInt64 Lba, Kernel::Char* Buf, Kernel::SizeT SectorSz, Kernel::SizeT Size)
+{
+}
+/***
+ @brief Getter, gets the number of sectors inside the drive.
+*/
+Kernel::SizeT drv_get_sector_count()
+{
+ return 0;
+}
+
+/// @brief Get the drive size.
+Kernel::SizeT drv_get_size()
+{
+ return 0;
+}
+#endif // __AHCI__
diff --git a/dev/zka/HALKit/AMD64/Storage/ATA-DMA.cxx b/dev/zka/HALKit/AMD64/Storage/ATA-DMA.cxx
new file mode 100644
index 00000000..49d10a7e
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/Storage/ATA-DMA.cxx
@@ -0,0 +1,38 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+/**
+ * @file ATA-DMA.cxx
+ * @author Amlal El Mahrouss (amlalelmahrouss@icloud.com)
+ * @brief ATA driver (DMA mode).
+ * @version 0.1
+ * @date 2024-02-02
+ *
+ * @copyright Copyright (c) ZKA Technologies
+ *
+ */
+
+#include <StorageKit/PRDT.hxx>
+
+#include <Modules/ATA/ATA.hxx>
+#include <ArchKit/ArchKit.hxx>
+
+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/zka/HALKit/AMD64/Storage/ATA-PIO.cxx b/dev/zka/HALKit/AMD64/Storage/ATA-PIO.cxx
new file mode 100644
index 00000000..e09a4277
--- /dev/null
+++ b/dev/zka/HALKit/AMD64/Storage/ATA-PIO.cxx
@@ -0,0 +1,199 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+/**
+ * @file ATA-PIO.cxx
+ * @author Amlal El Mahrouss (amlalelmahrouss@icloud.com)
+ * @brief ATA driver (PIO mode).
+ * @version 0.1
+ * @date 2024-02-02
+ *
+ * @copyright Copyright (c) ZKA Technologies
+ *
+ */
+
+#include <Modules/ATA/ATA.hxx>
+#include <ArchKit/ArchKit.hxx>
+
+#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++)
+ In8(IO + ATA_REG_STATUS);
+
+ATAWaitForIO_Retry:
+ auto statRdy = In8(IO + ATA_REG_STATUS);
+
+ if ((statRdy & ATA_SR_BSY))
+ goto ATAWaitForIO_Retry;
+
+ATAWaitForIO_Retry2:
+ statRdy = In8(IO + ATA_REG_STATUS);
+
+ if (statRdy & ATA_SR_ERR)
+ return false;
+
+ if (!(statRdy & ATA_SR_DRDY))
+ goto ATAWaitForIO_Retry2;
+
+ return true;
+}
+
+Void drv_std_select(UInt16 Bus)
+{
+ if (Bus == ATA_PRIMARY_IO)
+ Out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL);
+ else
+ 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);
+
+ kcout << "Initializing drive...\r";
+
+ATAInit_Retry:
+ // Bus init, NEIN bit.
+ Out8(IO + ATA_REG_NEIN, 1);
+
+ // identify until it's good
+
+ auto statRdy = In8(IO + ATA_REG_STATUS);
+
+ if (statRdy & ATA_SR_ERR)
+ {
+ kcout << "Failing drive...\r";
+
+ return false;
+ }
+
+ if ((statRdy & ATA_SR_BSY))
+ {
+ kcout << "Retrying...";
+ goto ATAInit_Retry;
+ }
+
+ 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] = 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;
+
+ kcout << "Created IDE module.\r";
+
+ return true;
+}
+
+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);
+
+ Out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F));
+
+ Out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz));
+
+ Out8(IO + ATA_REG_LBA0, (Lba) & 0xFF);
+ Out8(IO + ATA_REG_LBA1, (Lba) >> 8);
+ Out8(IO + ATA_REG_LBA2, (Lba) >> 16);
+ Out8(IO + ATA_REG_LBA3, (Lba) >> 24);
+
+ 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] = 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);
+
+ Out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F));
+
+ Out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz)) / SectorSz));
+
+ Out8(IO + ATA_REG_LBA0, (Lba) & 0xFF);
+ Out8(IO + ATA_REG_LBA1, (Lba) >> 8);
+ Out8(IO + ATA_REG_LBA2, (Lba) >> 16);
+ Out8(IO + ATA_REG_LBA3, (Lba) >> 24);
+
+ 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);
+ 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/zka/HALKit/ARM64/.gitkeep b/dev/zka/HALKit/ARM64/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/.gitkeep
diff --git a/dev/zka/HALKit/ARM64/APM/.gitkeep b/dev/zka/HALKit/ARM64/APM/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/APM/.gitkeep
diff --git a/dev/zka/HALKit/ARM64/HalKernelMain.cxx b/dev/zka/HALKit/ARM64/HalKernelMain.cxx
new file mode 100644
index 00000000..a1b75ccf
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/HalKernelMain.cxx
@@ -0,0 +1,68 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.hxx>
+#include <Modules/CoreCG/FbRenderer.hxx>
+#include <FirmwareKit/Handover.hxx>
+#include <KernelKit/FileMgr.hxx>
+#include <KernelKit/Framebuffer.hxx>
+#include <KernelKit/Heap.hxx>
+#include <KernelKit/PEFCodeMgr.hxx>
+#include <KernelKit/UserProcessScheduler.hxx>
+#include <NewKit/Json.hxx>
+#include <Modules/CoreCG/Accessibility.hxx>
+#include <KernelKit/CodeMgr.hxx>
+#include <Modules/ACPI/ACPIFactoryInterface.hxx>
+#include <NetworkKit/IPC.hxx>
+#include <CFKit/Property.hxx>
+#include <Modules/CoreCG/TextRenderer.hxx>
+
+namespace Kernel::HAL
+{
+ /// @brief Gets the system cores using the MADT.
+ /// @param rsdPtr The 'RSD PTR' data structure.
+ EXTERN void mp_get_cores(Kernel::voidPtr rsdPtr) noexcept;
+} // namespace Kernel::HAL
+
+Kernel::Void hal_real_init(Kernel::Void) noexcept;
+EXTERN_C Kernel::Void ke_dll_entrypoint(Kernel::Void);
+
+EXTERN_C void hal_init_platform(
+ Kernel::HEL::HANDOVER_INFO_HEADER* HandoverHeader)
+{
+ /* Setup globals. */
+
+ kHandoverHeader = HandoverHeader;
+
+ if (kHandoverHeader->f_Magic != kHandoverMagic &&
+ kHandoverHeader->f_Version != kHandoverVersion)
+ {
+ return;
+ }
+
+ CG::CGDrawBackground();
+
+ // get page size.
+ kKernelBitMpSize = kHandoverHeader->f_BitMapSize;
+
+ // get virtual address start (for the heap)
+ kKernelBitMpStart = reinterpret_cast<Kernel::VoidPtr>(
+ reinterpret_cast<Kernel::UIntPtr>(kHandoverHeader->f_BitMapStart));
+
+ if (kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled)
+ Kernel::HAL::mp_get_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr);
+
+ kcout << "Creating filesystem and such.\r";
+
+ if (kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled)
+ Kernel::HAL::mp_get_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr);
+
+ Kernel::NeFileSystemMgr::Mount(Kernel::mm_new_class<Kernel::NeFileSystemMgr>());
+
+ mp_do_user_switch();
+
+ Kernel::ke_stop(RUNTIME_CHECK_FAILED);
+}
diff --git a/dev/zka/HALKit/ARM64/HalPageInternal.S b/dev/zka/HALKit/ARM64/HalPageInternal.S
new file mode 100644
index 00000000..8fcf40ff
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/HalPageInternal.S
@@ -0,0 +1,5 @@
+.text
+
+hal_flush_tlb:
+ tlbi
+ ret
diff --git a/dev/zka/HALKit/ARM64/HalSchedulerCore.cxx b/dev/zka/HALKit/ARM64/HalSchedulerCore.cxx
new file mode 100644
index 00000000..7545b350
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/HalSchedulerCore.cxx
@@ -0,0 +1,48 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <KernelKit/UserProcessScheduler.hxx>
+
+using namespace Kernel;
+
+Void UserProcess::SetImageStart(UIntPtr& imageStart) noexcept
+{
+ if (imageStart == 0)
+ this->Crash();
+
+ this->StackFrame->BP = imageStart;
+ this->StackFrame->SP = this->StackFrame->BP;
+}
+
+namespace Kernel
+{
+ bool hal_check_stack(HAL::StackFramePtr stackPtr)
+ {
+ if (!stackPtr)
+ return false;
+ if (stackPtr->BP == 0 || stackPtr->SP == 0)
+ return false;
+
+ return true;
+ }
+
+ /// @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)
+ {
+ while (Yes)
+ {
+ /* Nothing to do, code is spinning */
+ }
+ }
+} // namespace Kernel
diff --git a/dev/zka/HALKit/ARM64/HalTimer.cxx b/dev/zka/HALKit/ARM64/HalTimer.cxx
new file mode 100644
index 00000000..4ef87227
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/HalTimer.cxx
@@ -0,0 +1,16 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ File: HalTimer.cxx
+ Purpose: HAL timer
+
+ Revision History:
+
+ 07/07/24: Added file (amlel)
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.hxx>
+
+struct TIMER_INFO;
diff --git a/dev/zka/HALKit/ARM64/MBCI/.keepme b/dev/zka/HALKit/ARM64/MBCI/.keepme
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/MBCI/.keepme
diff --git a/dev/zka/HALKit/ARM64/Paging.hxx b/dev/zka/HALKit/ARM64/Paging.hxx
new file mode 100644
index 00000000..7fe020ef
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/Paging.hxx
@@ -0,0 +1,120 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#pragma once
+
+/** ---------------------------------------------------
+
+ * THIS FILE CONTAINS CODE FOR ARMV8 PAGING.
+
+------------------------------------------------------- */
+
+#include <NewKit/Defines.hxx>
+
+#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 rw, Boolean user, SizeT size) -> 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/zka/HALKit/ARM64/Processor.hxx b/dev/zka/HALKit/ARM64/Processor.hxx
new file mode 100644
index 00000000..533457a9
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/Processor.hxx
@@ -0,0 +1,50 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Array.hxx>
+#include <NewKit/Defines.hxx>
+#include <NewKit/Utils.hxx>
+#include <FirmwareKit/Handover.hxx>
+
+#define kPageSize 512 /* 64-bit PT */
+
+#define kCPUBackendName "ARMv8"
+
+namespace Kernel::HAL
+{
+ struct PACKED Register64 final
+ {
+ UShort Limit;
+ UIntPtr Base;
+ };
+
+ 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};
+ };
+
+ typedef StackFrame* StackFramePtr;
+} // namespace Kernel::HAL
+
+inline Kernel::VoidPtr kKernelBitMpStart = nullptr;
+inline Kernel::UIntPtr kKernelBitMpSize = 0UL;
+
+inline Kernel::VoidPtr kKernelPhysicalStart = nullptr;
+
+#include <HALKit/ARM64/Paging.hxx>
diff --git a/dev/zka/HALKit/ARM64/ReadMe.md b/dev/zka/HALKit/ARM64/ReadMe.md
new file mode 100644
index 00000000..c51229f2
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/ReadMe.md
@@ -0,0 +1,3 @@
+# ARM64 Hardware Abstraction Layer
+
+- Supported Firmware: CoreBoot/EDK/OpenMobileBoot
diff --git a/dev/zka/HALKit/ARM64/Storage/.gitkeep b/dev/zka/HALKit/ARM64/Storage/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/Storage/.gitkeep
diff --git a/dev/zka/HALKit/ARM64/Storage/HalFlash.cxx b/dev/zka/HALKit/ARM64/Storage/HalFlash.cxx
new file mode 100644
index 00000000..a479da93
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/Storage/HalFlash.cxx
@@ -0,0 +1,66 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <NewKit/Defines.hxx>
+#include <ArchKit/ArchKit.hxx>
+
+/// @file Flash.cxx
+/// @brief Flash memory builtin.
+
+#ifdef __USE_MBCI_FLASH__
+
+#define cMaxFlash (4U)
+
+namespace Kernel
+{
+ /// /:\\BRIDGE\\FLSH\\1
+ constexpr auto cFlashBridgeMagic = "FLSH";
+ constexpr auto cFlashBridgeRevision = 1;
+
+ STATIC const Boolean kFlashEnabled = No;
+ STATIC SizeT kFlashSize[cMaxFlash] = {};
+ STATIC SizeT kFlashSectorSz[cMaxFlash] = {};
+
+ /// @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 sector count.
+ /// @return drive sector count.
+ SizeT drv_get_sector_count(Int32 slot)
+ {
+ if (slot > cMaxFlash)
+ return 0;
+
+ return kFlashSectorSz[slot];
+ }
+
+ /// @brief get device size.
+ /// @return drive size
+ SizeT drv_get_size(Int32 slot)
+ {
+ if (slot > cMaxFlash)
+ return 0;
+
+ return kFlashSize[slot];
+ }
+
+ /// @brief Enable flash memory at slot.
+ STATIC Void drv_enable_flash(Int32 arg)
+ {
+ kcout << "Enabled FLSH hardware.\r";
+ }
+
+ /// @brief Disable flash memory at slot.
+ STATIC Void drv_disable_flash(Int32 arg)
+ {
+ kcout << "Disabled FLSH hardware.\r";
+ }
+} // namespace Kernel
+
+#endif // if __USE_MBCI_FLASH__ (Bridge)
diff --git a/dev/zka/HALKit/AXP/CR.s b/dev/zka/HALKit/AXP/CR.s
new file mode 100644
index 00000000..4d68257d
--- /dev/null
+++ b/dev/zka/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/zka/HALKit/AXP/CoreInterruptHandlerDEC.cpp b/dev/zka/HALKit/AXP/CoreInterruptHandlerDEC.cpp
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/AXP/CoreInterruptHandlerDEC.cpp
diff --git a/dev/zka/HALKit/AXP/CoreSyscallHandlerDEC.cpp b/dev/zka/HALKit/AXP/CoreSyscallHandlerDEC.cpp
new file mode 100644
index 00000000..254e1ab6
--- /dev/null
+++ b/dev/zka/HALKit/AXP/CoreSyscallHandlerDEC.cpp
@@ -0,0 +1,24 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.hxx>
+#include <HALKit/AXP/Processor.hxx>
+
+/// @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/zka/HALKit/AXP/HAL.s b/dev/zka/HALKit/AXP/HAL.s
new file mode 100644
index 00000000..0178527f
--- /dev/null
+++ b/dev/zka/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/zka/HALKit/AXP/Processor.hxx b/dev/zka/HALKit/AXP/Processor.hxx
new file mode 100644
index 00000000..25a434a0
--- /dev/null
+++ b/dev/zka/HALKit/AXP/Processor.hxx
@@ -0,0 +1,7 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#pragma once \ No newline at end of file
diff --git a/dev/zka/HALKit/AXP/README b/dev/zka/HALKit/AXP/README
new file mode 100644
index 00000000..91e7b134
--- /dev/null
+++ b/dev/zka/HALKit/AXP/README
@@ -0,0 +1 @@
+This is for DEC Alpha.
diff --git a/dev/zka/HALKit/AXP/README.TXT b/dev/zka/HALKit/AXP/README.TXT
new file mode 100644
index 00000000..11e138f9
--- /dev/null
+++ b/dev/zka/HALKit/AXP/README.TXT
@@ -0,0 +1 @@
+An toy HAL to test the Kernel portability.
diff --git a/dev/zka/HALKit/AXP/SYSCALL.s b/dev/zka/HALKit/AXP/SYSCALL.s
new file mode 100644
index 00000000..19cab808
--- /dev/null
+++ b/dev/zka/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/zka/HALKit/AXP/VM.s b/dev/zka/HALKit/AXP/VM.s
new file mode 100644
index 00000000..7024086b
--- /dev/null
+++ b/dev/zka/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/zka/HALKit/POWER/.gitkeep b/dev/zka/HALKit/POWER/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/POWER/.gitkeep
diff --git a/dev/zka/HALKit/POWER/APM/.gitkeep b/dev/zka/HALKit/POWER/APM/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/POWER/APM/.gitkeep
diff --git a/dev/zka/HALKit/POWER/HalContextSwitchPowerPC.s b/dev/zka/HALKit/POWER/HalContextSwitchPowerPC.s
new file mode 100644
index 00000000..588de23a
--- /dev/null
+++ b/dev/zka/HALKit/POWER/HalContextSwitchPowerPC.s
@@ -0,0 +1,30 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+.align 4
+.type name, @function
+.text
+.globl mp_do_user_switch
+
+/* r3 (3) = assigner stack, r4 (4) = assignee stack */
+mp_do_user_switch:
+ lwz 0(%4), 0(%3)
+ lwz 4(%4), 4(%3)
+ lwz 8(%4), 8(%3)
+ lwz 12(%4), 12(%3)
+ lwz 14(%4), 14(%3)
+ lwz 18(%4), 18(%3)
+ lwz 22(%4), 22(%3)
+ lwz 24(%4), 24(%3)
+ lwz 28(%4), 28(%3)
+ lwz 32(%4), 32(%3)
+ lwz 34(%4), 34(%3)
+ lwz 38(%4), 38(%3)
+
+ /* also change exception level */
+
+ /* we are done here, the assignee should start executing code now. */
+ blr
diff --git a/dev/zka/HALKit/POWER/HalHart.cxx b/dev/zka/HALKit/POWER/HalHart.cxx
new file mode 100644
index 00000000..ce27ddad
--- /dev/null
+++ b/dev/zka/HALKit/POWER/HalHart.cxx
@@ -0,0 +1,25 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <HALKit/POWER/Processor.hxx>
+#include <KernelKit/DebugOutput.hxx>
+#include <HALKit/POWER/Hart.hxx>
+
+using namespace Kernel;
+
+/// @brief wakes up thread.
+/// wakes up thread from hang.
+void mp_wakeup_thread(HAL::StackFramePtr stack)
+{
+ ZKA_UNUSED(stack);
+}
+
+/// @brief makes thread sleep.
+/// hooks and hangs thread to prevent code from executing.
+void mp_hang_thread(HAL::StackFramePtr stack)
+{
+ ZKA_UNUSED(stack);
+}
diff --git a/dev/zka/HALKit/POWER/HalSerialPort.cxx b/dev/zka/HALKit/POWER/HalSerialPort.cxx
new file mode 100644
index 00000000..c8d49c0c
--- /dev/null
+++ b/dev/zka/HALKit/POWER/HalSerialPort.cxx
@@ -0,0 +1,27 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <HALKit/POWER/Processor.hxx>
+#include <KernelKit/DebugOutput.hxx>
+
+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/zka/HALKit/POWER/HalStartSequence.s b/dev/zka/HALKit/POWER/HalStartSequence.s
new file mode 100644
index 00000000..68110f8d
--- /dev/null
+++ b/dev/zka/HALKit/POWER/HalStartSequence.s
@@ -0,0 +1,14 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+.globl __ImageStart
+.extern hal_init_platform
+.align 4
+.text
+
+__ImageStart:
+ bl hal_init_platform
+ blr
diff --git a/dev/zka/HALKit/POWER/HalThread.cxx b/dev/zka/HALKit/POWER/HalThread.cxx
new file mode 100644
index 00000000..3e2f1703
--- /dev/null
+++ b/dev/zka/HALKit/POWER/HalThread.cxx
@@ -0,0 +1,8 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <HALKit/POWER/Processor.hxx>
+#include <KernelKit/DebugOutput.hxx>
diff --git a/dev/zka/HALKit/POWER/HalVirtualMemory.cxx b/dev/zka/HALKit/POWER/HalVirtualMemory.cxx
new file mode 100644
index 00000000..589c2cda
--- /dev/null
+++ b/dev/zka/HALKit/POWER/HalVirtualMemory.cxx
@@ -0,0 +1,51 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <HALKit/POWER/ppc-cpu.h>
+#include <HALKit/POWER/ppc-mmu.h>
+
+#include <HALKit/POWER/Processor.hxx>
+#include <KernelKit/DebugOutput.hxx>
+
+/// @note refer to the SoC documentation.
+
+using namespace Kernel;
+
+Void hal_write_tlb(UInt32 mas0, UInt32 mas1, UInt32 mas2, UInt32 mas3, UInt32 mas7)
+{
+ mtspr(MAS0, mas0);
+ mtspr(MAS1, mas1);
+ mtspr(MAS2, mas2);
+ mtspr(MAS3, mas3);
+ mtspr(MAS7, mas7);
+
+ hal_flush_tlb();
+}
+
+Bool hal_set_tlb(UInt8 tlb, UInt32 epn, UInt64 rpn, UInt8 perms, UInt8 wimge, UInt8 ts, UInt8 esel, UInt8 tsize, UInt8 iprot)
+{
+ if ((mfspr(SPRN_MMUCFG) & MMUCFG_MAVN) == MMUCFG_MAVN_V1 && (tsize & 1))
+ {
+ // this mmu-version 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/zka/HALKit/POWER/Hart.hxx b/dev/zka/HALKit/POWER/Hart.hxx
new file mode 100644
index 00000000..02020320
--- /dev/null
+++ b/dev/zka/HALKit/POWER/Hart.hxx
@@ -0,0 +1,36 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ File: Hart.hxx
+ Purpose: POWER hardware threads.
+
+ Revision History:
+
+ 14/04/24: Added file (amlel)
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.hxx>
+
+struct HAL_HARDWARE_THREAD;
+
+/// @brief hardware thread indentification type.
+typedef Kernel::Int32 PPCHartType;
+
+/// @brief Hardware thread information structure.
+typedef struct HAL_HARDWARE_THREAD
+{
+ Kernel::UIntPtr fStartAddress;
+ Kernel::UInt8 fPrivleged : 1;
+ Kernel::UInt32 fPageFlags;
+ PPCHartType 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);
diff --git a/dev/zka/HALKit/POWER/MBCI/.gitkeep b/dev/zka/HALKit/POWER/MBCI/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/POWER/MBCI/.gitkeep
diff --git a/dev/zka/HALKit/POWER/MBCI/HalMBCIHost.cxx b/dev/zka/HALKit/POWER/MBCI/HalMBCIHost.cxx
new file mode 100644
index 00000000..3e2f1703
--- /dev/null
+++ b/dev/zka/HALKit/POWER/MBCI/HalMBCIHost.cxx
@@ -0,0 +1,8 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <HALKit/POWER/Processor.hxx>
+#include <KernelKit/DebugOutput.hxx>
diff --git a/dev/zka/HALKit/POWER/Processor.hxx b/dev/zka/HALKit/POWER/Processor.hxx
new file mode 100644
index 00000000..75922d88
--- /dev/null
+++ b/dev/zka/HALKit/POWER/Processor.hxx
@@ -0,0 +1,60 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ Purpose: POWER processor header.
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.hxx>
+#include <NewKit/Utils.hxx>
+
+#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};
+ };
+
+ 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/zka/HALKit/POWER/ReadMe.md b/dev/zka/HALKit/POWER/ReadMe.md
new file mode 100644
index 00000000..a9751581
--- /dev/null
+++ b/dev/zka/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/zka/HALKit/RISCV/.keep b/dev/zka/HALKit/RISCV/.keep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/RISCV/.keep
diff --git a/dev/zka/HALKit/RISCV/APM/.gitkeep b/dev/zka/HALKit/RISCV/APM/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/RISCV/APM/.gitkeep
diff --git a/dev/zka/HALKit/RISCV/Hart.hxx b/dev/zka/HALKit/RISCV/Hart.hxx
new file mode 100644
index 00000000..0f5e021e
--- /dev/null
+++ b/dev/zka/HALKit/RISCV/Hart.hxx
@@ -0,0 +1,24 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ File: Hart.hxx
+ Purpose: RISC-V hardware threads.
+
+ Revision History:
+
+ 30/01/24: Added file (amlel)
+
+------------------------------------------- */
+
+#pragma once
+
+#include <NewKit/Defines.hxx>
+
+typedef Kernel::Int32 Rv64HartType;
+
+/// @brief Set PC to specific hart.
+/// @param hart the hart
+/// @param epc the pc.
+/// @return
+EXTERN_C Kernel::Void hal_set_pc_to_hart(Rv64HartType hart, Kernel::VoidPtr epc);
diff --git a/dev/zka/HALKit/RISCV/ReadMe.md b/dev/zka/HALKit/RISCV/ReadMe.md
new file mode 100644
index 00000000..b099aa31
--- /dev/null
+++ b/dev/zka/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/zka/HALKit/RISCV/Storage/.gitkeep b/dev/zka/HALKit/RISCV/Storage/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/RISCV/Storage/.gitkeep
diff --git a/dev/zka/HALKit/X86S/.gitkeep b/dev/zka/HALKit/X86S/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/X86S/.gitkeep
diff --git a/dev/zka/HALKit/X86S/ACPI/.gitkeep b/dev/zka/HALKit/X86S/ACPI/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/X86S/ACPI/.gitkeep
diff --git a/dev/zka/HALKit/X86S/Storage/.gitkeep b/dev/zka/HALKit/X86S/Storage/.gitkeep
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/dev/zka/HALKit/X86S/Storage/.gitkeep