summaryrefslogtreecommitdiffhomepage
path: root/dev/zka/HALKit
diff options
context:
space:
mode:
authorAmlal El Mahrouss <zka-holder@mahrouss-logic.com>2024-10-14 05:58:38 +0000
committerAmlal El Mahrouss <zka-holder@mahrouss-logic.com>2024-10-14 05:58:38 +0000
commitd9d82713326069478e6dd212763d1fac15e65370 (patch)
tree37775f4299281598b0f5121df4c188392daebd04 /dev/zka/HALKit
parent7477a0f942c374b652da4f80cdb36d4661aac3c8 (diff)
IMP: Basic ARM64 port.
Diffstat (limited to 'dev/zka/HALKit')
-rw-r--r--dev/zka/HALKit/AMD64/HalACPIFactoryInterface.cxx86
-rw-r--r--dev/zka/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx13
-rw-r--r--dev/zka/HALKit/AMD64/HalCoreMPScheduler.cxx24
-rw-r--r--dev/zka/HALKit/AMD64/HalDescriptorLoader.cxx38
-rw-r--r--dev/zka/HALKit/AMD64/HalInterruptAPI.asm38
-rw-r--r--dev/zka/HALKit/AMD64/HalKernelMain.cxx41
-rw-r--r--dev/zka/HALKit/AMD64/HalMPContextSwitch.asm17
-rw-r--r--dev/zka/HALKit/AMD64/HalPagingMgr.cxx4
-rw-r--r--dev/zka/HALKit/AMD64/HalSchedulerCore.cxx2
-rw-r--r--dev/zka/HALKit/AMD64/HalUtils.asm6
-rw-r--r--dev/zka/HALKit/AMD64/Processor.hxx15
-rw-r--r--dev/zka/HALKit/ARM64/APM/APM.cxx37
-rw-r--r--dev/zka/HALKit/ARM64/HalACPIFactoryInterface.cxx31
-rw-r--r--dev/zka/HALKit/ARM64/HalCoreMPScheduler.cxx19
-rw-r--r--dev/zka/HALKit/ARM64/HalDebugOutput.cxx81
-rw-r--r--dev/zka/HALKit/ARM64/HalKernelMain.cxx28
-rw-r--r--dev/zka/HALKit/ARM64/HalPagingMgr.cxx87
-rw-r--r--dev/zka/HALKit/ARM64/HalSchedulerCore.cxx5
-rw-r--r--dev/zka/HALKit/ARM64/Processor.hxx30
-rw-r--r--dev/zka/HALKit/POWER/HalContextSwitchPowerPC.s4
20 files changed, 394 insertions, 212 deletions
diff --git a/dev/zka/HALKit/AMD64/HalACPIFactoryInterface.cxx b/dev/zka/HALKit/AMD64/HalACPIFactoryInterface.cxx
index 83f9993f..0d00b643 100644
--- a/dev/zka/HALKit/AMD64/HalACPIFactoryInterface.cxx
+++ b/dev/zka/HALKit/AMD64/HalACPIFactoryInterface.cxx
@@ -82,8 +82,8 @@ namespace Kernel
};
} // namespace Detail
- ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsdPtr)
- : fRsdp(rsdPtr), fEntries(0)
+ ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr)
+ : fRsdp(rsp_ptr), fEntries(0)
{
}
@@ -123,86 +123,4 @@ namespace Kernel
"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/HalCoreInterruptHandlerAMD64.cxx b/dev/zka/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx
index c6b8303d..1167e861 100644
--- a/dev/zka/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx
+++ b/dev/zka/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cxx
@@ -4,6 +4,7 @@
------------------------------------------- */
+#include "NewKit/Stop.hxx"
#include <ArchKit/ArchKit.hxx>
#include <KernelKit/UserProcessScheduler.hxx>
#include <NewKit/String.hxx>
@@ -43,13 +44,9 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp)
Kernel::ke_stop(RUNTIME_CHECK_PROCESS);
}
-EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp)
+/// @brief Handle scheduler interrupt.
+EXTERN_C void idt_handle_scheduler()
{
- if (Kernel::cProcessScheduler == nullptr)
- {
- Kernel::ke_stop(RUNTIME_CHECK_UNEXCPECTED);
- }
-
Kernel::UserProcessHelper::StartScheduling();
}
@@ -101,6 +98,8 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp)
/// @return nothing.
EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx, Kernel::UIntPtr rdx)
{
+ Kernel::HAL::Out8(0x20, 0x20); // Acknowledge interrupt to master PIC
+
if (rcx <= (kSyscalls.Count() - 1))
{
kcout << "syscall: Enter Fn.\r";
@@ -117,6 +116,8 @@ EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx, Kernel::UIntPtr
/// @return nothing.
EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx, Kernel::UIntPtr rdx, Kernel::UIntPtr r8, Kernel::UIntPtr r9)
{
+ Kernel::HAL::Out8(0x20, 0x20); // Acknowledge interrupt to master PIC
+
if (rcx <= (kSyscalls.Count() - 1))
{
kcout << "kerncall: Enter Fn.\r";
diff --git a/dev/zka/HALKit/AMD64/HalCoreMPScheduler.cxx b/dev/zka/HALKit/AMD64/HalCoreMPScheduler.cxx
index ae6dc905..44f1f60a 100644
--- a/dev/zka/HALKit/AMD64/HalCoreMPScheduler.cxx
+++ b/dev/zka/HALKit/AMD64/HalCoreMPScheduler.cxx
@@ -136,15 +136,6 @@ namespace Kernel::HAL
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;
@@ -157,18 +148,17 @@ namespace Kernel::HAL
return fBlocks[UserProcessScheduler::The().CurrentProcess().Leak().ProcessId % kSchedProcessLimitPerTeam].f_Frame;
}
+ EXTERN_C Void mp_do_task_switch(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_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;
+ 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;
- }
+ mp_do_task_switch(image, stack_ptr, stack_frame);
- return No;
+ return Yes;
}
/***********************************************************************************/
diff --git a/dev/zka/HALKit/AMD64/HalDescriptorLoader.cxx b/dev/zka/HALKit/AMD64/HalDescriptorLoader.cxx
index 44263a1c..bc06d01a 100644
--- a/dev/zka/HALKit/AMD64/HalDescriptorLoader.cxx
+++ b/dev/zka/HALKit/AMD64/HalDescriptorLoader.cxx
@@ -5,6 +5,7 @@
------------------------------------------- */
#include <ArchKit/ArchKit.hxx>
+#include <HALKit/AMD64/Processor.hxx>
namespace Kernel::HAL
{
@@ -15,24 +16,32 @@ namespace Kernel::HAL
STATIC Void hal_remap_intel_pic_ctrl(Void) noexcept
{
- auto a1 = HAL::In8(0xa1); // save masks
- auto a2 = HAL::In8(0xa2);
+ uint8_t a1_saved = In8(kPICData);
+ uint8_t a2_saved = In8(kPIC2Data);
- HAL::Out8(0x20, 0x11);
+ Out8(kPICCommand, 0x11); // Start initialization
+ Out8(kPICData, 0x20); // Master PIC offset
+ Out8(kPICData, 0x04); // Tell master PIC there is a slave
+ Out8(kPICData, 0x01); // 8086 mode
- HAL::Out8(0xA0, 0x11);
+ Out8(kPIC2Command, 0x11); // Start initialization
+ Out8(kPIC2Data, 0x28); // Slave PIC offset
+ Out8(kPIC2Data, 0x02); // Tell slave PIC its cascade
+ Out8(kPIC2Data, 0x01); // 8086 mode
- HAL::Out8(0x21, 32);
- HAL::Out8(0xA1, 40);
+ Out8(kPICData, a1_saved); // Restore saved masks
+ Out8(kPIC2Data, a2_saved);
+ }
- HAL::Out8(0x21, 4);
- HAL::Out8(0xA1, 2);
+ STATIC Void hal_enable_pit() noexcept
+ {
+ // Configure PIT to receieve scheduler interrupts.
- HAL::Out8(0x21, 0x01);
- HAL::Out8(0xA1, 0x01);
+ UInt32 cCommonDivisor = kPITFrequency / 100; // 100 Hz.
- HAL::Out8(0x21, a2);
- HAL::Out8(0xA1, a1);
+ HAL::Out8(kPITControlPort, 0x36); // Command to PIT
+ HAL::Out8(kPITChannel0Port, cCommonDivisor & 0xFF); // Send low byte
+ HAL::Out8(kPITControlPort, (cCommonDivisor >> 8) & 0xFF); // Send high byte
}
} // namespace Detail
@@ -46,6 +55,9 @@ namespace Kernel::HAL
Void IDTLoader::Load(Register64& idt)
{
+ Detail::hal_remap_intel_pic_ctrl();
+ Detail::hal_enable_pit();
+
volatile ::Kernel::UIntPtr** ptr_ivt = (volatile ::Kernel::UIntPtr**)idt.Base;
for (UInt16 idt_indx = 0; idt_indx < (kKernelIdtSize); ++idt_indx)
@@ -66,8 +78,6 @@ namespace Kernel::HAL
(kKernelIdtSize)-1;
hal_load_idt(idt);
-
- Detail::hal_remap_intel_pic_ctrl();
}
void GDTLoader::Load(Ref<RegisterGDT>& gdt)
diff --git a/dev/zka/HALKit/AMD64/HalInterruptAPI.asm b/dev/zka/HALKit/AMD64/HalInterruptAPI.asm
index cdbb2d1f..d9e16f6c 100644
--- a/dev/zka/HALKit/AMD64/HalInterruptAPI.asm
+++ b/dev/zka/HALKit/AMD64/HalInterruptAPI.asm
@@ -131,8 +131,24 @@ IntNormal 28
IntNormal 29
IntExp 30
IntNormal 31
-IntNormal 32
+
+[extern idt_handle_scheduler]
+
+__ZKA_INT_32:
+ cli
+
+ push rsp
+
+ jmp idt_handle_scheduler
+
+ add rsp, 16
+ pop rsp
+
+ sti
+ o64 iret
+
IntNormal 33
+
IntNormal 34
IntNormal 35
IntNormal 36
@@ -194,25 +210,7 @@ __ZKA_INT_51:
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 52
IntNormal 53
IntNormal 54
diff --git a/dev/zka/HALKit/AMD64/HalKernelMain.cxx b/dev/zka/HALKit/AMD64/HalKernelMain.cxx
index 30124932..ad32ada6 100644
--- a/dev/zka/HALKit/AMD64/HalKernelMain.cxx
+++ b/dev/zka/HALKit/AMD64/HalKernelMain.cxx
@@ -6,6 +6,7 @@
#include <ArchKit/ArchKit.hxx>
#include <KernelKit/UserProcessScheduler.hxx>
+#include <KernelKit/HardwareThreadScheduler.hxx>
#include <KernelKit/CodeMgr.hxx>
#include <modules/ACPI/ACPIFactoryInterface.hxx>
#include <NetworkKit/IPC.hxx>
@@ -15,13 +16,14 @@
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;
+ /// @param rsp_ptr The 'RSD PTR' data structure.
+ EXTERN void mp_get_cores(Kernel::voidPtr rsp_ptr) noexcept;
} // namespace Kernel::HAL
namespace Kernel
{
EXTERN UserProcessScheduler* cProcessScheduler;
+ EXTERN HardwareThreadScheduler* cHardwareThreadScheduler;
}
EXTERN_C Kernel::VoidPtr kInterruptVectorTable[];
@@ -35,6 +37,7 @@ EXTERN_C void hal_init_platform(
kHandoverHeader = HandoverHeader;
Kernel::cProcessScheduler = nullptr;
+ Kernel::cHardwareThreadScheduler = nullptr;
if (kHandoverHeader->f_Magic != kHandoverMagic &&
kHandoverHeader->f_Version != kHandoverVersion)
@@ -42,13 +45,18 @@ EXTERN_C void hal_init_platform(
return;
}
- // get page size.
- kKernelBitMpSize = kHandoverHeader->f_BitMapSize;
+ /************************************** */
+ /* INITIALIZE BIT MAP. */
+ /************************************** */
- // get virtual address start (for the heap)
+ kKernelBitMpSize = kHandoverHeader->f_BitMapSize;
kKernelBitMpStart = reinterpret_cast<Kernel::VoidPtr>(
reinterpret_cast<Kernel::UIntPtr>(kHandoverHeader->f_BitMapStart));
+ /************************************** */
+ /* INITIALIZE GDT AND SEGMENTS. */
+ /************************************** */
+
STATIC CONST auto cEntriesCount = 6;
/* GDT, mostly descriptors for user and kernel segments. */
@@ -61,25 +69,25 @@ EXTERN_C void hal_init_platform(
};
// Load memory descriptors.
- Kernel::HAL::RegisterGDT gdtBase;
+ Kernel::HAL::RegisterGDT gdt_reg;
- gdtBase.Base = reinterpret_cast<Kernel::UIntPtr>(cGdt);
- gdtBase.Limit = (sizeof(Kernel::HAL::Detail::ZKA_GDT_ENTRY) * cEntriesCount) - 1;
+ gdt_reg.Base = reinterpret_cast<Kernel::UIntPtr>(cGdt);
+ gdt_reg.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::HAL::GDTLoader gdt_loader;
+ gdt_loader.Load(gdt_reg);
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::Register64 idt_reg;
+ idt_reg.Base = (Kernel::UIntPtr)kInterruptVectorTable;
- Kernel::HAL::IDTLoader idtLoader;
- idtLoader.Load(idtBase);
+ Kernel::HAL::IDTLoader idt_loader;
+ idt_loader.Load(idt_reg);
if (kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled)
Kernel::HAL::mp_get_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr);
@@ -87,10 +95,7 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept
Kernel::NeFileSystemMgr* mgr = Kernel::mm_new_class<Kernel::NeFileSystemMgr>();
Kernel::NeFileSystemMgr::Mount(mgr);
- Kernel::HAL::mm_map_page(mp_user_switch_proc, Kernel::HAL::eFlagsUser | Kernel::HAL::eFlagsWr | Kernel::HAL::eFlagsPresent);
- Kernel::HAL::mm_map_page(mp_user_switch_proc_stack_begin, Kernel::HAL::eFlagsUser | Kernel::HAL::eFlagsWr | Kernel::HAL::eFlagsPresent);
-
- mp_do_user_switch();
+ Kernel::UserProcessHelper::InitializeScheduling();
Kernel::ke_stop(RUNTIME_CHECK_BOOTSTRAP);
}
diff --git a/dev/zka/HALKit/AMD64/HalMPContextSwitch.asm b/dev/zka/HALKit/AMD64/HalMPContextSwitch.asm
index c6480778..2ad38107 100644
--- a/dev/zka/HALKit/AMD64/HalMPContextSwitch.asm
+++ b/dev/zka/HALKit/AMD64/HalMPContextSwitch.asm
@@ -9,7 +9,7 @@
[bits 64]
-[global mp_do_user_switch]
+[global mp_do_task_switch]
[global mp_do_context_switch_pre]
[global mp_user_switch_proc]
[global mp_user_switch_proc_stack_begin]
@@ -17,12 +17,9 @@
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]
+mp_do_task_switch:
+ mov rbp, rdx
+ mov rsp, rdx
mov ax, 0x18 | 3
mov ds, ax
@@ -32,15 +29,15 @@ mp_do_user_switch:
push 0x18 | 3
- mov rax, mp_user_switch_proc_stack_end
+ mov rax, rdx
push rax
o64 pushf
push 0x20 | 3
- mov rdx, mp_user_switch_proc
- push rdx
+ mov rax, rcx
+ push rax
o64 iret
diff --git a/dev/zka/HALKit/AMD64/HalPagingMgr.cxx b/dev/zka/HALKit/AMD64/HalPagingMgr.cxx
index 06a8b7d2..78978bc7 100644
--- a/dev/zka/HALKit/AMD64/HalPagingMgr.cxx
+++ b/dev/zka/HALKit/AMD64/HalPagingMgr.cxx
@@ -57,7 +57,7 @@ namespace Kernel::HAL
kcout << (pte->User ? "User" : "Not User") << endl;
}
- STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, ZKA_PTE* pt_entry);
+ STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry);
/// @brief Maps or allocates a page from virtual_address.
/// @param virtual_address a valid virtual address.
@@ -121,7 +121,7 @@ namespace Kernel::HAL
/// @brief Maps flags for a specific pte.
/// @internal Internal function.
- STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, ZKA_PTE* pt_entry)
+ STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry)
{
if (flags & ~eFlagsPresent)
pt_entry->Present = false;
diff --git a/dev/zka/HALKit/AMD64/HalSchedulerCore.cxx b/dev/zka/HALKit/AMD64/HalSchedulerCore.cxx
index 9dcce147..d2f678e2 100644
--- a/dev/zka/HALKit/AMD64/HalSchedulerCore.cxx
+++ b/dev/zka/HALKit/AMD64/HalSchedulerCore.cxx
@@ -26,7 +26,7 @@ namespace Kernel
EXTERN_C Void __zka_pure_call(void)
{
- asm volatile("mov %r8, 0; mov %r9, 1; syscall");
+ UserProcessScheduler::The().CurrentProcess().Leak().Crash();
}
Bool hal_check_stack(HAL::StackFramePtr stack_ptr)
diff --git a/dev/zka/HALKit/AMD64/HalUtils.asm b/dev/zka/HALKit/AMD64/HalUtils.asm
index 0e4caf2b..715859e8 100644
--- a/dev/zka/HALKit/AMD64/HalUtils.asm
+++ b/dev/zka/HALKit/AMD64/HalUtils.asm
@@ -25,9 +25,3 @@ rt_install_tib:
[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/Processor.hxx b/dev/zka/HALKit/AMD64/Processor.hxx
index b0a8aa0a..f01c73ab 100644
--- a/dev/zka/HALKit/AMD64/Processor.hxx
+++ b/dev/zka/HALKit/AMD64/Processor.hxx
@@ -19,6 +19,15 @@
#include <FirmwareKit/Handover.hxx>
#include <HALKit/AMD64/Paging.hxx>
+#define kPITControlPort 0x43
+#define kPITChannel0Port 0x40
+#define kPITFrequency 1193180
+
+#define kPICCommand 0x20
+#define kPICData 0x21
+#define kPIC2Command 0xA0
+#define kPIC2Data 0xA1
+
EXTERN_C
{
#include <cpuid.h>
@@ -35,7 +44,7 @@ EXTERN_C
#define IsActiveLow(FLG) (FLG & 2)
#define IsLevelTriggered(FLG) (FLG & 8)
-#define kInterruptGate (0x8E)
+#define kInterruptGate (0x0E)
#define kTrapGate (0xEF)
#define kTaskGate (0b10001100)
#define kIDTSelector (0x08)
@@ -59,7 +68,7 @@ namespace Kernel
namespace Kernel::HAL
{
- /// @brief Virtual memory flags.
+ /// @brief Memory Manager mapping flags.
enum
{
eFlagsPresent = 1 << 0,
@@ -168,7 +177,7 @@ namespace Kernel::HAL
static Void Load(Ref<Register64>& idt);
};
- Void mp_get_cores(VoidPtr rsdPtr) noexcept;
+ Void mp_get_cores(VoidPtr rsp_ptr) noexcept;
Void hal_send_start_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress);
Void hal_send_end_ipi(UInt32 apicId, UInt8 vector, UInt32 targetAddress);
diff --git a/dev/zka/HALKit/ARM64/APM/APM.cxx b/dev/zka/HALKit/ARM64/APM/APM.cxx
new file mode 100644
index 00000000..7962aa16
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/APM/APM.cxx
@@ -0,0 +1,37 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <modules/APM/APM.hxx>
+#include <KernelKit/LPC.hxx>
+
+using namespace Kernel;
+
+/// @brief Send a APM command into it's own IO space.
+/// @param base_dma the IO base port.
+/// @param cmd the command.
+/// @return status code.
+EXTERN_C Int32 apm_send_io_command(UInt16 cmd, APMPowerCmd value)
+{
+ switch (cmd)
+ {
+ case kAPMPowerCommandReboot: {
+ asm volatile(
+ "ldr x0, =0x84000009\n"
+ "hvc #0\n");
+
+ return kErrorSuccess;
+ }
+ case kAPMPowerCommandShutdown: {
+ asm volatile(
+ "ldr x0, =0x84000008\n"
+ "hvc #0\n");
+
+ return kErrorSuccess;
+ }
+ default:
+ return kErrorInvalidData;
+ }
+}
diff --git a/dev/zka/HALKit/ARM64/HalACPIFactoryInterface.cxx b/dev/zka/HALKit/ARM64/HalACPIFactoryInterface.cxx
new file mode 100644
index 00000000..75ecefee
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/HalACPIFactoryInterface.cxx
@@ -0,0 +1,31 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <modules/ACPI/ACPIFactoryInterface.hxx>
+#include <NewKit/String.hxx>
+#include <ArchKit/ArchKit.hxx>
+#include <KernelKit/Heap.hxx>
+#include <modules/APM/APM.hxx>
+
+namespace Kernel
+{
+ ACPIFactoryInterface::ACPIFactoryInterface(VoidPtr rsp_ptr)
+ : fRsdp(rsp_ptr), fEntries(0)
+ {
+ }
+
+ Void ACPIFactoryInterface::Shutdown()
+ {
+ apm_send_io_command(kAPMPowerCommandShutdown, 0);
+ }
+
+ /// @brief Reboot machine in either ACPI or by triple faulting.
+ /// @return nothing it's a reboot.
+ Void ACPIFactoryInterface::Reboot()
+ {
+ apm_send_io_command(kAPMPowerCommandReboot, 0);
+ }
+} // namespace Kernel
diff --git a/dev/zka/HALKit/ARM64/HalCoreMPScheduler.cxx b/dev/zka/HALKit/ARM64/HalCoreMPScheduler.cxx
new file mode 100644
index 00000000..102ca194
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/HalCoreMPScheduler.cxx
@@ -0,0 +1,19 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <modules/ACPI/ACPIFactoryInterface.hxx>
+#include <KernelKit/UserProcessScheduler.hxx>
+
+using namespace Kernel;
+
+EXTERN_C Void mp_do_task_switch(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_frame);
+
+EXTERN_C Bool mp_register_process(VoidPtr image, UInt8* stack_ptr, HAL::StackFramePtr stack_frame)
+{
+ mp_do_task_switch(image, stack_ptr, stack_frame);
+
+ return Yes;
+}
diff --git a/dev/zka/HALKit/ARM64/HalDebugOutput.cxx b/dev/zka/HALKit/ARM64/HalDebugOutput.cxx
new file mode 100644
index 00000000..9dc7278c
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/HalDebugOutput.cxx
@@ -0,0 +1,81 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+------------------------------------------- */
+
+#include <ArchKit/ArchKit.hxx>
+#include <KernelKit/DebugOutput.hxx>
+#include <NewKit/Utils.hxx>
+#include <NewKit/New.hxx>
+
+namespace Kernel
+{
+ EXTERN_C void ke_io_write(const Char* bytes)
+ {
+#ifdef __DEBUG__
+ if (*bytes == 0)
+ return;
+
+ SizeT index = 0;
+ SizeT len = 0;
+
+ index = 0;
+ len = rt_string_len(bytes, 255);
+
+ volatile UInt8* uart_ptr = (UInt8*)0x09000000;
+
+ while (index < len)
+ {
+ if (bytes[index] == '\r')
+ *uart_ptr = '\r';
+
+ *uart_ptr = bytes[index] == '\r' ? '\n' : bytes[index];
+ ++index;
+ }
+#endif // __DEBUG__
+ }
+
+ EXTERN_C void ke_io_read(const Char* bytes)
+ {
+#ifdef __DEBUG__
+ SizeT index = 0;
+
+ volatile UInt8* uart_ptr = (UInt8*)0x09000000;
+
+ ///! TODO: Look on how to wait for the UART to complete.
+ while (Yes)
+ {
+ auto in = *uart_ptr;
+
+ ///! If enter pressed then break.
+ if (in == 0xD)
+ {
+ break;
+ }
+
+ if (in < '0' || in < 'A' || in < 'a')
+ {
+ if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' ||
+ in != ':')
+ {
+ continue;
+ }
+ }
+
+ ((char*)bytes)[index] = in;
+
+ ++index;
+ }
+
+ ((char*)bytes)[index] = 0;
+#endif // __DEBUG__
+ }
+
+ TerminalDevice TerminalDevice::The() noexcept
+ {
+ TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read);
+ return out;
+ }
+
+} // namespace Kernel
diff --git a/dev/zka/HALKit/ARM64/HalKernelMain.cxx b/dev/zka/HALKit/ARM64/HalKernelMain.cxx
index 56287733..4d0d0875 100644
--- a/dev/zka/HALKit/ARM64/HalKernelMain.cxx
+++ b/dev/zka/HALKit/ARM64/HalKernelMain.cxx
@@ -17,13 +17,6 @@
#include <NetworkKit/IPC.hxx>
#include <CFKit/Property.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);
@@ -38,24 +31,5 @@ EXTERN_C void hal_init_platform(
return;
}
- // 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);
+ while (Yes) {}
}
diff --git a/dev/zka/HALKit/ARM64/HalPagingMgr.cxx b/dev/zka/HALKit/ARM64/HalPagingMgr.cxx
new file mode 100644
index 00000000..7e686905
--- /dev/null
+++ b/dev/zka/HALKit/ARM64/HalPagingMgr.cxx
@@ -0,0 +1,87 @@
+/* -------------------------------------------
+
+ Copyright ZKA Technologies.
+
+ File: HalPagingMgr.cxx
+ Purpose: Platform Paging Manager..
+
+------------------------------------------- */
+
+#include <HALKit/ARM64/Paging.hxx>
+#include <HALKit/ARM64/Processor.hxx>
+
+namespace Kernel::HAL
+{
+ typedef UInt32 PageTableIndex;
+
+ /// \brief Page store type.
+ struct ZKA_PAGE_STORE final
+ {
+ struct
+ {
+ PDE* fPde{nullptr};
+ PTE* fPte{nullptr};
+ VoidPtr fVAddr{nullptr};
+ } fInternalStore;
+
+ Bool fStoreOp{No}; // Store operation in progress.
+
+ static ZKA_PAGE_STORE& The()
+ {
+ static ZKA_PAGE_STORE the;
+ return the;
+ }
+ };
+
+ /// \brief Retrieve the page status of a PTE.
+ STATIC Void mmi_page_status(PTE* pte)
+ {
+
+ }
+
+ STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry);
+
+ /// @brief Maps or allocates a page from virtual_address.
+ /// @param virtual_address a valid virtual address.
+ /// @param phys_addr point to physical address.
+ /// @param flags the flags to put on the page.
+ /// @return Status code of page manipulation process.
+ EXTERN_C Int32 mm_map_page(VoidPtr virtual_address, UInt32 flags)
+ {
+ if (!virtual_address ||
+ !flags)
+ return 0;
+
+ ZKA_PAGE_STORE& page_store = ZKA_PAGE_STORE::The();
+
+ while (page_store.fStoreOp)
+ ;
+
+ page_store.fStoreOp = Yes;
+
+ if (page_store.fInternalStore.fVAddr == virtual_address)
+ {
+ page_store.fStoreOp = No;
+ return mmi_map_page_table_entry(page_store.fInternalStore.fVAddr, flags, page_store.fInternalStore.fPte);
+ }
+
+ return -1;
+ }
+
+ /// @brief Maps flags for a specific pte.
+ /// @internal Internal function.
+ STATIC Int32 mmi_map_page_table_entry(VoidPtr virtual_address, UInt32 flags, PTE* pt_entry)
+ {
+ ZKA_PAGE_STORE& page_store = ZKA_PAGE_STORE::The();
+
+ // Update Internal store.
+
+ page_store.fInternalStore.fPde = nullptr;
+ page_store.fInternalStore.fPte = pt_entry;
+ page_store.fInternalStore.fVAddr = virtual_address;
+
+ page_store.fStoreOp = No;
+
+ return 0;
+ }
+} // namespace Kernel::HAL
diff --git a/dev/zka/HALKit/ARM64/HalSchedulerCore.cxx b/dev/zka/HALKit/ARM64/HalSchedulerCore.cxx
index 630df4fd..30e2f1b5 100644
--- a/dev/zka/HALKit/ARM64/HalSchedulerCore.cxx
+++ b/dev/zka/HALKit/ARM64/HalSchedulerCore.cxx
@@ -8,6 +8,11 @@
namespace Kernel
{
+ EXTERN_C Void __zka_pure_call(void)
+ {
+ UserProcessScheduler::The().CurrentProcess().Leak().Crash();
+ }
+
Void UserProcess::SetImageStart(VoidPtr image_start) noexcept
{
if (image_start == 0)
diff --git a/dev/zka/HALKit/ARM64/Processor.hxx b/dev/zka/HALKit/ARM64/Processor.hxx
index 533457a9..68c305f3 100644
--- a/dev/zka/HALKit/ARM64/Processor.hxx
+++ b/dev/zka/HALKit/ARM64/Processor.hxx
@@ -11,8 +11,6 @@
#include <NewKit/Utils.hxx>
#include <FirmwareKit/Handover.hxx>
-#define kPageSize 512 /* 64-bit PT */
-
#define kCPUBackendName "ARMv8"
namespace Kernel::HAL
@@ -23,6 +21,23 @@ namespace Kernel::HAL
UIntPtr Base;
};
+ /// @brief Memory Manager mapping flags.
+ enum
+ {
+ eFlagsPresent = 1 << 0,
+ eFlagsWr = 1 << 1,
+ eFlagsUser = 1 << 2,
+ eFlagsNX = 1 << 3,
+ 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);
+
typedef UIntPtr Reg;
typedef Register64 Register;
@@ -37,9 +52,20 @@ namespace Kernel::HAL
Reg R13{0};
Reg R14{0};
Reg R15{0};
+ Reg SP{0};
+ Reg BP{0};
};
typedef StackFrame* StackFramePtr;
+
+ inline Void rt_halt()
+ {
+ while (Yes)
+ {
+
+ }
+ }
+
} // namespace Kernel::HAL
inline Kernel::VoidPtr kKernelBitMpStart = nullptr;
diff --git a/dev/zka/HALKit/POWER/HalContextSwitchPowerPC.s b/dev/zka/HALKit/POWER/HalContextSwitchPowerPC.s
index 588de23a..d90c1fa0 100644
--- a/dev/zka/HALKit/POWER/HalContextSwitchPowerPC.s
+++ b/dev/zka/HALKit/POWER/HalContextSwitchPowerPC.s
@@ -7,10 +7,10 @@
.align 4
.type name, @function
.text
-.globl mp_do_user_switch
+.globl mp_do_task_switch
/* r3 (3) = assigner stack, r4 (4) = assignee stack */
-mp_do_user_switch:
+mp_do_task_switch:
lwz 0(%4), 0(%3)
lwz 4(%4), 4(%3)
lwz 8(%4), 8(%3)