summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/HALKit/AMD64
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlal@nekernel.org>2025-05-15 13:56:17 +0200
committerAmlal El Mahrouss <amlal@nekernel.org>2025-05-15 13:56:17 +0200
commit6a30f42d5dcd0f944262147b2806db6c14fe7ffc (patch)
tree86d86a66df2941e49d1d332aaa1671c11db594e5 /dev/kernel/HALKit/AMD64
parentf8aaa274535b6541f376090958eedbbba3ba00ba (diff)
feat(kernel): Finalizing the first version of the user scheduler.
other: - Removed DmaPool into its own Kit. - ApplicationProcessor unit has been cleaned up. - Rename functions of MemoryMgr. - Use KIB instead of MIBs of stack. - Cleanup parts of the scheduler, and hw scheduler. - Use UD handler for INT 6. Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/kernel/HALKit/AMD64')
-rw-r--r--dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc39
-rw-r--r--dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc37
-rw-r--r--dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc53
-rw-r--r--dev/kernel/HALKit/AMD64/HalInterruptAPI.asm18
-rw-r--r--dev/kernel/HALKit/AMD64/HalKernelMain.cc23
-rw-r--r--dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc4
-rw-r--r--dev/kernel/HALKit/AMD64/Paging.h23
-rw-r--r--dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc2
8 files changed, 74 insertions, 125 deletions
diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
index dd9a36ed..84c52768 100644
--- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
+++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc
@@ -152,10 +152,13 @@ EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid)
kHWThread[process_index].mCoreID = kAPICLocales[0];
- hal_send_sipi(kApicBaseAddress, kHWThread[process_index].mCoreID,
- (UInt8) (((UIntPtr) stack_frame->BP) >> 12));
+ if (mp_is_smp()) {
+ /// TODO:
- return YES;
+ return YES;
+ }
+
+ return NO;
}
/***********************************************************************************/
@@ -195,44 +198,36 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept {
kSMPAware = NO;
if (kMADTBlock) {
- SizeT index = 1;
+ SizeT index = 0;
kSMPInterrupt = 0;
kSMPCount = 0;
- kout << "SMP: Starting APs...\r";
-
kApicBaseAddress = kMADTBlock->Address;
+ constexpr const auto kSMPCountMax = kMaxAPInsideSched;
+
while (Yes) {
/// @note Anything bigger than x2APIC type doesn't exist.
- if (kMADTBlock->List[index].Type > 9 || kSMPCount > kSchedProcessLimitPerTeam) break;
+ if (kSMPCount > kSMPCountMax) break;
- switch (kMADTBlock->List[index].Type) {
- case 0x00: {
- if (kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID < 1) break;
+ if (kMADTBlock->List[index].Type > 9) {
+ ++index;
+ continue;
+ }
- kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID;
- (Void)(kout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << kendl);
+ kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID;
+ (Void)(kout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << kendl);
- ++kSMPCount;
- break;
- }
- default:
- break;
- }
+ ++kSMPCount;
++index;
}
- (Void)(kout << "SMP: Number of APs: " << number(kSMPCount) << kendl);
-
// Kernel is now SMP aware.
// That means that the scheduler is now available (on MP Kernels)
kSMPAware = true;
-
- /// TODO: Notify Boot AP that it must start.
}
}
} // namespace Kernel::HAL
diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
index 3a380a42..1e513e3f 100644
--- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
+++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc
@@ -16,10 +16,6 @@ STATIC BOOL kIsScheduling = NO;
EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) {
auto process = Kernel::UserProcessScheduler::The().CurrentProcess();
- if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) {
- MUST_PASS(NO);
- }
-
kIsScheduling = NO;
Kernel::kout << "Kernel: General Protection Fault.\r";
@@ -40,10 +36,6 @@ EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) {
EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) {
auto process = Kernel::UserProcessScheduler::The().CurrentProcess();
- if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) {
- MUST_PASS(NO);
- }
-
kIsScheduling = NO;
Kernel::kout << "Kernel: Page Fault.\r";
@@ -58,27 +50,14 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) {
process.Leak().Crash();
}
-namespace Kernel::Detail {
-constexpr static Int32 kTimeoutCount = 100000UL;
-}
-
/// @brief Handle scheduler interrupt.
EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) {
NE_UNUSED(rsp);
- static Kernel::Int64 try_count_before_brute = Kernel::Detail::kTimeoutCount;
-
- while (kIsScheduling) {
- --try_count_before_brute;
-
- if (try_count_before_brute < 1) break;
- }
-
- try_count_before_brute = Kernel::Detail::kTimeoutCount;
- kIsScheduling = YES;
+ Kernel::kout << "Kernel: Scheduler interrupt.\r";
+ kIsScheduling = YES;
Kernel::UserProcessHelper::StartScheduling();
-
kIsScheduling = NO;
}
@@ -87,10 +66,6 @@ EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) {
EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) {
auto process = Kernel::UserProcessScheduler::The().CurrentProcess();
- if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) {
- MUST_PASS(NO);
- }
-
kIsScheduling = NO;
Kernel::kout << "Kernel: Math error (division by zero?).\r";
@@ -111,10 +86,6 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) {
EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) {
auto process = Kernel::UserProcessScheduler::The().CurrentProcess();
- if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) {
- MUST_PASS(NO);
- }
-
kIsScheduling = NO;
Kernel::kout << "Kernel: Generic Process Fault.\r";
@@ -163,10 +134,6 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) {
EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) {
auto process = Kernel::UserProcessScheduler::The().CurrentProcess();
- if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) {
- MUST_PASS(NO);
- }
-
kIsScheduling = NO;
Kernel::kout << "Kernel: Undefined Opcode.\r";
diff --git a/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc b/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc
index 2fb6ad4c..b8eb8fe9 100644
--- a/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc
+++ b/dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc
@@ -8,56 +8,10 @@
#include <FSKit/NeFS.h>
#include <HALKit/AMD64/Processor.h>
-#define kPITDefaultTicks (1000U)
-
namespace Kernel::HAL {
namespace Detail {
STATIC ::Kernel::Detail::AMD64::InterruptDescriptorAMD64 kInterruptVectorTable[kKernelIdtSize] =
{};
-
- STATIC ATTRIBUTE(unused) void hal_set_irq_mask(UInt8 irql) [[maybe_unused]] {
- UInt16 port;
- UInt8 value;
-
- if (irql < 8) {
- port = kPICData;
- } else {
- port = kPIC2Data;
- irql -= 8;
- }
-
- value = rt_in8(port) | (1 << irql);
- rt_out8(port, value);
- }
-
- STATIC void hal_clear_irq_mask(UInt8 irql) [[maybe_unused]] {
- UInt16 port;
- UInt8 value;
-
- if (irql < 8) {
- port = kPICData;
- } else {
- port = kPIC2Data;
- irql -= 8;
- }
-
- value = rt_in8(port) & ~(1 << irql);
- rt_out8(port, value);
- }
-
- STATIC Void hal_enable_pit(UInt16 ticks) noexcept {
- if (ticks == 0) ticks = kPITDefaultTicks;
-
- // Configure PIT to receieve scheduler interrupts.
-
- UInt16 kPITCommDivisor = kPITFrequency / ticks; // 100 Hz.
-
- HAL::rt_out8(kPITControlPort, 0x36); // Command to PIT
- HAL::rt_out8(kPITChannel0Port, kPITCommDivisor & 0xFF); // Send low byte
- HAL::rt_out8(kPITChannel0Port, (kPITCommDivisor >> 8) & 0xFF); // Send high byte
-
- hal_clear_irq_mask(32);
- }
} // namespace Detail
/// @brief Loads the provided Global Descriptor Table.
@@ -72,8 +26,6 @@ Void GDTLoader::Load(Register64& gdt) {
Void IDTLoader::Load(Register64& idt) {
rt_cli();
- const Int16 kPITTickForScheduler = kPITDefaultTicks;
-
volatile ::Kernel::UIntPtr** ptr_ivt = (volatile ::Kernel::UIntPtr**) idt.Base;
for (SizeT idt_indx = 0; idt_indx < kKernelIdtSize; ++idt_indx) {
@@ -92,12 +44,7 @@ Void IDTLoader::Load(Register64& idt) {
idt.Base = (UIntPtr) &Detail::kInterruptVectorTable[0];
idt.Limit = sizeof(::Kernel::Detail::AMD64::InterruptDescriptorAMD64) * (kKernelIdtSize);
- Detail::hal_enable_pit(kPITTickForScheduler);
-
-#ifndef __NE_MODULAR_KERNEL_COMPONENTS__
hal_load_idt(idt);
-#endif // __NE_MODULAR_KERNEL_COMPONENTS__
-
rt_sti();
}
diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm
index a6c6bbb5..0634b0ea 100644
--- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm
+++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm
@@ -138,7 +138,7 @@ __NE_INT_6:
out 0x20, al
push rcx
- call idt_handle_generic
+ call idt_handle_ud
pop rcx
std
@@ -235,17 +235,14 @@ IntNormal 31
__NE_INT_32:
cld
-
- mov al, 0x20
- out 0xA0, al
- out 0x20, al
push rax
mov rcx, rsp
call idt_handle_scheduler
pop rax
- std
+ mov al, 0x20
+ out 0x20, al
o64 iret
@@ -416,3 +413,12 @@ kInterruptVectorTable:
dq __NE_INT_%+i
%assign i i+1
%endrep
+
+section .text
+
+global sched_jump_to_task
+
+;; Jump to the task from its stack frame.
+sched_jump_to_task:
+ mov rsp, rcx
+ ret \ No newline at end of file
diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc
index 2d213a9b..b0ac076d 100644
--- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc
+++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc
@@ -27,6 +27,8 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) {
return kEfiFail;
}
+ Kernel::HAL::rt_sti();
+
kHandoverHeader = handover_hdr;
FB::fb_clear_video();
@@ -54,7 +56,7 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) {
STATIC CONST auto kGDTEntriesCount = 6;
- /* GDT, mostly descriptors for user and kernel segments. */
+ /* The GDT, mostly descriptors for user and kernel segments. */
STATIC Kernel::HAL::Detail::NE_GDT_ENTRY ALIGN(0x08) kGDTArray[kGDTEntriesCount] = {
{.fLimitLow = 0,
.fBaseLow = 0,
@@ -101,6 +103,13 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) {
return kEfiFail;
}
+EXTERN_C Kernel::Void rtl_ne_task(Kernel::Void) {
+ kout << "Hello, world!\r";
+ dbg_break_point();
+}
+
+EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp);
+
EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept {
#ifdef __FSKIT_INCLUDES_HEFS__
if (!Kernel::HeFS::fs_init_hefs()) {
@@ -108,18 +117,24 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept {
Kernel::NeFS::fs_init_nefs();
}
#elif defined(__FSKIT_INCLUDES_NEFS__)
- Kernel::NeFS::fs_init_nefs();
+ if (!Kernel::NeFS::fs_init_nefs()) {
+ kout << "NeFS cannot be formated on the disk. Aborting\r";
+ dbg_break_point();
+ }
#endif
+ Kernel::rtl_create_user_process(rtl_ne_task, "NeTask");
+
Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr);
Kernel::HAL::Register64 idt_reg;
- idt_reg.Base = (Kernel::UIntPtr) kInterruptVectorTable;
+ idt_reg.Base = reinterpret_cast<Kernel::UIntPtr>(kInterruptVectorTable);
Kernel::HAL::IDTLoader idt_loader;
idt_loader.Load(idt_reg);
- dbg_break_point();
+ while (YES)
+ ;
}
#endif // ifndef __NE_MODULAR_KERNEL_COMPONENTS__
diff --git a/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc b/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc
index 06c18d8b..57f64712 100644
--- a/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc
+++ b/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc
@@ -4,8 +4,8 @@ Copyright (C) 2025, Amlal El Mahrouss, all rights reserved.
------------------------------------------- */
+#include <DmaKit/DmaPool.h>
#include <HALKit/AMD64/Processor.h>
-#include <StorageKit/DmaPool.h>
#include <modules/ACPI/ACPIFactoryInterface.h>
using namespace Kernel;
@@ -14,7 +14,7 @@ using namespace Kernel::HAL;
STATIC UInt16 kIOBase = 0xFFFF;
STATIC UInt32 kRXOffset = 0UL;
-STATIC constexpr const UInt32 kRxBufferSize = 8192 + 16 + 1500;
+STATIC constexpr CONST UInt32 kRxBufferSize = 8192 + 16 + 1500;
STATIC BOOL kTXEnabled = NO;
diff --git a/dev/kernel/HALKit/AMD64/Paging.h b/dev/kernel/HALKit/AMD64/Paging.h
index cfba232c..061bae45 100644
--- a/dev/kernel/HALKit/AMD64/Paging.h
+++ b/dev/kernel/HALKit/AMD64/Paging.h
@@ -63,6 +63,25 @@ auto mm_free_bitmap(VoidPtr page_ptr) -> Bool;
} // namespace Kernel::HAL
namespace Kernel {
-typedef VoidPtr PTE;
-typedef VoidPtr PDE;
+struct PTE {
+ UInt64 Present : 1;
+ UInt64 Wr : 1;
+ UInt64 User : 1;
+ UInt64 Pwt : 1; // Page-level Write-Through
+ UInt64 Pcd : 1; // Page-level Cache Disable
+ UInt64 Accessed : 1;
+ UInt64 Dirty : 1;
+ UInt64 Pat : 1; // Page Attribute Table (or PS for PDE)
+ UInt64 Global : 1;
+ UInt64 Ignored1 : 3; // Available to software
+ UInt64 PhysicalAddress : 40; // Physical page frame address (bits 12–51)
+ UInt64 Ignored2 : 7; // More software bits / reserved
+ UInt64 ProtectionKey : 4; // Optional (if PKU enabled)
+ UInt64 Reserved : 1; // Usually reserved
+ UInt64 Nx : 1; // No Execute
+};
+
+struct PDE {
+ ATTRIBUTE(aligned(kib_cast(4))) PTE fPTE[512];
+};
} // namespace Kernel
diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
index 21483560..57e77e77 100644
--- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
+++ b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc
@@ -15,6 +15,7 @@
*
*/
+#include <DmaKit/DmaPool.h>
#include <FirmwareKit/EPM.h>
#include <KernelKit/DeviceMgr.h>
#include <KernelKit/DriveMgr.h>
@@ -25,7 +26,6 @@
#include <KernelKit/Timer.h>
#include <NewKit/Utils.h>
#include <StorageKit/AHCI.h>
-#include <StorageKit/DmaPool.h>
#include <modules/AHCI/AHCI.h>
#include <modules/ATA/ATA.h>