From f5f62b145d472a2a2c388c385be9d1c4e5b5d84c Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Tue, 13 May 2025 08:46:49 +0200 Subject: feat(kernel): see below for the commit's details. what? - UserProcessScheduler and CoreProcessScheduler have been extended for FILE_TREE and also HEAP_TREE structures. - DDK device's API will use dk_ calls instead of sk_ calls. - SIGTRAP and Interrupt handlers have been fixed to handle when no process is being run, and the kernel is instead raising the interrupt. - Add file for HeFS formating in DiskImage.fwrk - Replace generic handler with breakpoint handler in int 3. why? - These changes are bug fixes and improvements. Signed-off-by: Amlal El Mahrouss --- dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'dev/kernel/HALKit/AMD64/HalInterruptAPI.asm') diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index cc34b99f..cf2870c8 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -98,7 +98,7 @@ __NE_INT_3: out 0x20, al push rcx - call idt_handle_generic + call idt_handle_breakpoint pop rcx std -- cgit v1.2.3 From f8aaa274535b6541f376090958eedbbba3ba00ba Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 14 May 2025 18:35:05 +0200 Subject: feat(kernel): Filesystem fixes, and others. what? - Add simple generic RTL8139 NIC driver, to be used within a NK device. - Update IVT accordingly. - Comment ARM's AP GIC init function, to tell what it's actually doing. - Cleanup Kernel Main, removed the useless pre_init_scheduler function. - Prepare new FileMgr with HeFileSystemMgr. - Fallback to NeFS when trying to format a fileysstem. Signed-off-by: Amlal El Mahrouss --- dev/kernel/FSKit/HeFS.h | 13 +- dev/kernel/HALKit/AMD64/HalAPICController.cc | 12 +- dev/kernel/HALKit/AMD64/HalDebugPort.cc | 3 +- dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 19 +- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 14 +- .../HALKit/AMD64/Network/Generic+Basic+RTL8139.cc | 81 ++++++ .../HALKit/AMD64/Storage/PIO+Generic+Next.cc | 280 --------------------- dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc | 42 +++- dev/kernel/HALKit/ARM64/ApplicationProcessor.h | 3 +- dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc | 2 + dev/kernel/KernelKit/FileMgr.h | 48 +++- dev/kernel/KernelKit/PCI/DMA.h | 5 +- dev/kernel/NetworkKit/NetworkDevice.inl | 11 +- dev/kernel/amd64-desktop.make | 2 +- dev/kernel/src/FS/HeFS+FileSystemParser.cc | 10 +- dev/kernel/src/FS/NeFS+FileSystemParser.cc | 23 +- 16 files changed, 216 insertions(+), 352 deletions(-) create mode 100644 dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc delete mode 100644 dev/kernel/HALKit/AMD64/Storage/PIO+Generic+Next.cc (limited to 'dev/kernel/HALKit/AMD64/HalInterruptAPI.asm') diff --git a/dev/kernel/FSKit/HeFS.h b/dev/kernel/FSKit/HeFS.h index 04a265f5..5f0dcddf 100644 --- a/dev/kernel/FSKit/HeFS.h +++ b/dev/kernel/FSKit/HeFS.h @@ -370,7 +370,7 @@ inline const Char* hefs_file_flags_to_string(UInt32 flags) noexcept { } } // namespace Kernel::Detail -namespace Kernel::HeFS { +namespace Kernel { /// @brief HeFS filesystem parser class. /// @details This class is used to parse the HeFS filesystem. class HeFileSystemParser final { @@ -417,7 +417,10 @@ class HeFileSystemParser final { const Utf8Char* dir, const BOOL delete_or_create); }; -/// @brief Initialize HeFS inside the main disk. -/// @return Whether it successfuly formated it or not. -Boolean fs_init_hefs(Void); -} // namespace Kernel::HeFS +namespace HeFS { + + /// @brief Initialize HeFS inside the main disk. + /// @return Whether it successfuly formated it or not. + Boolean fs_init_hefs(Void) noexcept; +} // namespace HeFS +} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/HalAPICController.cc b/dev/kernel/HALKit/AMD64/HalAPICController.cc index 758e2f52..e547d982 100644 --- a/dev/kernel/HALKit/AMD64/HalAPICController.cc +++ b/dev/kernel/HALKit/AMD64/HalAPICController.cc @@ -7,8 +7,8 @@ #include #include -#define cIOAPICRegVal (4) -#define cIOAPICRegReg (0) +#define kIOAPICRegVal (4) +#define kIOAPICRegReg (0) namespace Kernel::HAL { APICController::APICController(VoidPtr base) : fApic(base) {} @@ -19,9 +19,9 @@ UInt32 APICController::Read(UInt32 reg) noexcept { MUST_PASS(this->fApic); UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic; - io_apic[cIOAPICRegReg] = (reg & 0xFF); + io_apic[kIOAPICRegReg] = (reg & 0xFF); - return io_apic[cIOAPICRegVal]; + return io_apic[kIOAPICRegVal]; } /// @brief Write to APIC controller. @@ -32,7 +32,7 @@ Void APICController::Write(UInt32 reg, UInt32 value) noexcept { UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic; - io_apic[cIOAPICRegReg] = (reg & 0xFF); - io_apic[cIOAPICRegVal] = value; + io_apic[kIOAPICRegReg] = (reg & 0xFF); + io_apic[kIOAPICRegVal] = value; } } // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/HalDebugPort.cc b/dev/kernel/HALKit/AMD64/HalDebugPort.cc index 105fcf47..4e0e2b7f 100644 --- a/dev/kernel/HALKit/AMD64/HalDebugPort.cc +++ b/dev/kernel/HALKit/AMD64/HalDebugPort.cc @@ -9,11 +9,12 @@ #include #include +#include // after that we have start of additional data. namespace Kernel { -void rt_debug_listen(KernelDebugHeader* the_hdr) noexcept { +Void rt_debug_listen(KernelDebugHeader* the_hdr) noexcept { NE_UNUSED(the_hdr); } } // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index cf2870c8..a6c6bbb5 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -257,7 +257,24 @@ IntNormal 36 IntNormal 37 IntNormal 38 IntNormal 39 -IntNormal 40 + +[extern rtl_rtl8139_interrupt_handler] + +__NE_INT_40: + cld + + mov al, 0x20 + out 0xA0, al + out 0x20, al + + push rax + mov rcx, rsp + call rtl_rtl8139_interrupt_handler + pop rax + + std + + o64 iret IntNormal 41 diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 70b07193..2d213a9b 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -20,13 +20,6 @@ #ifndef __NE_MODULAR_KERNEL_COMPONENTS__ EXTERN_C Kernel::VoidPtr kInterruptVectorTable[]; -STATIC Kernel::Void hal_pre_init_scheduler() noexcept { - for (Kernel::SizeT i = 0U; - i < Kernel::UserProcessScheduler::The().CurrentTeam().AsArray().Count(); ++i) { - Kernel::UserProcessScheduler::The().CurrentTeam().AsArray()[i] = Kernel::USER_PROCESS(); - } -} - /// @brief Kernel init function. /// @param handover_hdr Handover boot header. EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { @@ -109,10 +102,11 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { } EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { - hal_pre_init_scheduler(); - #ifdef __FSKIT_INCLUDES_HEFS__ - Kernel::HeFS::fs_init_hefs(); + if (!Kernel::HeFS::fs_init_hefs()) { + // Fallback to NeFS, if HeFS doesn't work here. + Kernel::NeFS::fs_init_nefs(); + } #elif defined(__FSKIT_INCLUDES_NEFS__) Kernel::NeFS::fs_init_nefs(); #endif diff --git a/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc b/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc new file mode 100644 index 00000000..06c18d8b --- /dev/null +++ b/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc @@ -0,0 +1,81 @@ +/* ------------------------------------------- + +Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include +#include +#include + +using namespace Kernel; +using namespace Kernel::HAL; + +STATIC UInt16 kIOBase = 0xFFFF; + +STATIC UInt32 kRXOffset = 0UL; +STATIC constexpr const UInt32 kRxBufferSize = 8192 + 16 + 1500; + +STATIC BOOL kTXEnabled = NO; + +STATIC UInt8* kRXUpperLayer = nullptr; +STATIC UInt8* kRxBuffer = nullptr; + +EXTERN_C Void rtl_init_nic_rtl8139(UInt16 io_base) noexcept { + if (kTXEnabled) return; + + kIOBase = io_base; + MUST_PASS(io_base); + + kRxBuffer = (UInt8*) rtl_dma_alloc(sizeof(UInt8) * kRxBufferSize, 0); + + MUST_PASS(kRxBuffer); + + /// Reset first. + + rt_out8(io_base + 0x37, 0x10); + + UInt16 timeout = 0U; + + while (rt_in8(io_base + 0x37) & 0x10) { + ++timeout; + if (timeout > 0x1000) break; + } + + MUST_PASS(timeout <= 0x1000); + + rt_out32(io_base + 0x30, (UInt32) (UIntPtr) kRxBuffer); + + rt_out8(io_base + 0x37, 0x0C); + + rt_out32(io_base + 0x44, 0xf | (1 << 7)); + + // Enable IRQ. + rt_out16(io_base + 0x3C, 0x0005); + + kTXEnabled = YES; +} + +EXTERN_C void rtl_rtl8139_interrupt_handler() { + if (kIOBase == 0xFFFF) return; + + UInt16 status = rt_in16(kIOBase + 0x3E); + rt_out16(kIOBase + 0x3E, status); + + if (status & 0x01) { + while ((rt_in8(kIOBase + 0x37) & 0x01) == 0) { + UInt32 offset = kRXOffset % kRxBufferSize; + volatile UInt8* packet = kRxBuffer + offset + 4; + UInt16 len = *(UInt16*) (kRxBuffer + offset + 2); + + kRXUpperLayer[offset + 4] = *packet; + + kRXOffset += len + 4; + rt_out16(kIOBase + 0x38, (UInt16) (kRXOffset - 16)); + } + } + + if (!(status & 0x04)) { + err_global_get() = kErrorNoNetwork; + } +} \ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic+Next.cc b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic+Next.cc deleted file mode 100644 index dd6b9aea..00000000 --- a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic+Next.cc +++ /dev/null @@ -1,280 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -/** - * @file PIO+Generic.cc - * @author Amlal El Mahrouss (amlal@nekernel.org) - * @brief ATA driver (PIO mode). - * @version 0.1 - * @date 2024-02-02 - * - * @copyright Copyright (c) Amlal El Mahrouss - * - */ - -#if 0 - -#include -#include -#include -#include - -using namespace Kernel; -using namespace Kernel::HAL; - -/// BUGS: 0 - -#define kATADataLen 256 - -STATIC Boolean kATADetected = false; -STATIC UInt16 kATAIdentifyData[kATADataLen] = {0}; -STATIC Char kATADiskModel[50] = {"GENERIC PIO"}; - -static Boolean drv_pio_std_wait_io(UInt16 IO) { - for (int i = 0; i < 400; i++) rt_in8(IO + ATA_REG_STATUS); - -ATAWaitForIO_Retry: - auto stat_rdy = rt_in8(IO + ATA_REG_STATUS); - - if ((stat_rdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry; - -ATAWaitForIO_Retry2: - stat_rdy = rt_in8(IO + ATA_REG_STATUS); - - if (stat_rdy & ATA_SR_ERR) return false; - - if (!(stat_rdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2; - - return true; -} - -STATIC Void drv_pio_std_select(UInt16 Bus) { - if (Bus == ATA_PRIMARY_IO) - rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); - else - rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL); -} - -Boolean drv_pio_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) { - UInt16 IO = Bus; - - NE_UNUSED(Drive); - - drv_pio_std_select(IO); - - // Bus init, NEIN bit. - rt_out8(IO + ATA_REG_NEIN, 1); - - // identify until it's good. -ATAInit_Retry: - auto stat_rdy = rt_in8(IO + ATA_REG_STATUS); - - if (stat_rdy & ATA_SR_ERR) { - return false; - } - - if ((stat_rdy & ATA_SR_BSY)) goto ATAInit_Retry; - - OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO; - OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; - - drv_pio_std_select(IO); - - rt_out8(OutBus + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); - - - /// fetch serial info - /// model, speed, number of sectors... - - for (SizeT i = 0ul; i < kATADataLen; ++i) { - kATAIdentifyData[i] = rt_in16(OutBus + ATA_REG_DATA); - } - - for (Int32 i = 0; i < 20; i++) { - kATADiskModel[i * 2] = (kATAIdentifyData[27 + i] >> 8) & 0xFF; - kATADiskModel[i * 2 + 1] = kATAIdentifyData[27 + i] & 0xFF; - } - - kATADiskModel[40] = '\0'; - - (Void)(kout << "Drive Model: " << kATADiskModel << kendl); - - return true; -} - -Void drv_pio_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - drv_pio_std_wait_io(IO); - drv_pio_std_select(IO); - - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); - - rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF); - rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); - rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); - rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); - - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); - - for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { - drv_pio_std_wait_io(IO); - - auto in = rt_in16(IO + ATA_REG_DATA); - - Buf[IndexOff] = in & 0xFF; - Buf[IndexOff + 1] = (in >> 8) & 0xFF; - } -} - -Void drv_pio_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - drv_pio_std_wait_io(IO); - drv_pio_std_select(IO); - - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); - - rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF); - rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); - rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); - rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); - - while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); - - for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { - drv_pio_std_wait_io(IO); - - UInt8 low = (UInt8)Buf[IndexOff]; - UInt8 high = (IndexOff + 1 < Size) ? (UInt8)Buf[IndexOff + 1] : 0; - UInt16 packed = (high << 8) | low; - - rt_out16(IO + ATA_REG_DATA, packed); - } -} - -/// @brief is ATA detected? -Boolean drv_pio_std_detected(Void) { - return kATADetected; -} - -/*** - @brief Getter, gets the number of sectors inside the drive. - */ -SizeT drv_pio_get_sector_count() { - return (kATAIdentifyData[61] << 16) | kATAIdentifyData[60]; -} - -/// @brief Get the drive size. -SizeT drv_pio_get_size() { - return (drv_pio_get_sector_count()) * kATASectorSize; -} - -namespace Kernel { -/// @brief Initialize an PIO device (StorageKit function) -/// @param is_master is the current PIO master? -/// @return [io:master] for PIO device. -BOOL sk_init_ata_device(BOOL is_master, UInt16& io, UInt8& master) { - return drv_pio_std_init(ATA_SECONDARY_IO, is_master, io, master); -} - -/// @brief Implementation details namespace. -namespace Detail { - /// @brief Read PIO device. - /// @param self device - /// @param mnt mounted disk. - STATIC Void sk_io_read_pio(IDeviceObject* self, MountpointInterface* mnt) { - ATADeviceInterface* dev = (ATADeviceInterface*) self; - - err_global_get() = kErrorDisk; - - if (!dev) return; - - auto disk = mnt->GetAddressOf(dev->GetIndex()); - - if (!disk) return; - - err_global_get() = kErrorSuccess; - - drv_pio_std_read(disk->fPacket.fPacketLba, dev->GetIO(), dev->GetMaster(), - (Char*) disk->fPacket.fPacketContent, kATASectorSize, - disk->fPacket.fPacketSize); - } - - /// @brief Write PIO device. - /// @param self device - /// @param mnt mounted disk. - STATIC Void sk_io_write_pio(IDeviceObject* self, MountpointInterface* mnt) { - ATADeviceInterface* dev = (ATADeviceInterface*) self; - - err_global_get() = kErrorDisk; - - if (!dev) return; - - auto disk = mnt->GetAddressOf(dev->GetIndex()); - - if (!disk) return; - - err_global_get() = kErrorSuccess; - - drv_pio_std_write(disk->fPacket.fPacketLba, dev->GetIO(), dev->GetMaster(), - (Char*) disk->fPacket.fPacketContent, kATASectorSize, - disk->fPacket.fPacketSize); - } -} // namespace Detail - -/// @brief Acquires a new PIO device with drv_index in mind. -/// @param drv_index The drive index to assign. -/// @return A wrapped device interface if successful, or error code. -ErrorOr sk_acquire_ata_device(Int32 drv_index) { - /// here we don't check if we probed ATA, since we'd need to grab IO after that. - ATADeviceInterface device(Detail::sk_io_read_pio, Detail::sk_io_write_pio); - - device.SetIndex(drv_index); - - return ErrorOr(device); -} -} // namespace Kernel - -#ifdef __ATA_PIO__ - -Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - drv_pio_std_read(Lba, IO, Master, Buf, SectorSz, Size); -} - -Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - drv_pio_std_write(Lba, IO, Master, Buf, SectorSz, Size); -} - -SizeT drv_std_get_size() { - return drv_pio_get_size(); -} - -SizeT drv_std_get_sector_count() { - return drv_pio_get_sector_count(); -} - -Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) { - return drv_pio_std_init(Bus, Drive, OutBus, OutMaster); -} - -#endif - -#endif \ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc index aec21ee4..dd6b9aea 100644 --- a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc @@ -15,6 +15,8 @@ * */ +#if 0 + #include #include #include @@ -49,7 +51,7 @@ ATAWaitForIO_Retry2: return true; } -static Void drv_pio_std_select(UInt16 Bus) { +STATIC Void drv_pio_std_select(UInt16 Bus) { if (Bus == ATA_PRIMARY_IO) rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); else @@ -79,15 +81,18 @@ ATAInit_Retry: OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO; OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; + drv_pio_std_select(IO); + rt_out8(OutBus + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - drv_pio_std_wait_io(IO); + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); + /// fetch serial info /// model, speed, number of sectors... for (SizeT i = 0ul; i < kATADataLen; ++i) { - kATAIdentifyData[i] = HAL::rt_in16(OutBus + ATA_REG_DATA); + kATAIdentifyData[i] = rt_in16(OutBus + ATA_REG_DATA); } for (Int32 i = 0; i < 20; i++) { @@ -99,10 +104,6 @@ ATAInit_Retry: (Void)(kout << "Drive Model: " << kATADiskModel << kendl); - // Why? the current disk driver writes whole word instead of a single byte (expected btw) so i'm - // planning to finish +Next drivers for 0.0.3 - ke_panic(RUNTIME_CHECK_INVALID, "PIO driver is currently being reworked."); - return true; } @@ -118,16 +119,22 @@ Void drv_pio_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT Sect rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); - rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF); + rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF); rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); + + for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { drv_pio_std_wait_io(IO); - Buf[IndexOff] = HAL::rt_in16(IO + ATA_REG_DATA); + + auto in = rt_in16(IO + ATA_REG_DATA); + + Buf[IndexOff] = in & 0xFF; + Buf[IndexOff + 1] = (in >> 8) & 0xFF; } } @@ -143,16 +150,23 @@ Void drv_pio_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT Sec rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); - rt_out8(IO + ATA_REG_LBA0, (Lba) &0xFF); + rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF); rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRQ)); + + for (SizeT IndexOff = 0; IndexOff < Size; IndexOff += 2) { drv_pio_std_wait_io(IO); - rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]); + + UInt8 low = (UInt8)Buf[IndexOff]; + UInt8 high = (IndexOff + 1 < Size) ? (UInt8)Buf[IndexOff + 1] : 0; + UInt16 packed = (high << 8) | low; + + rt_out16(IO + ATA_REG_DATA, packed); } } @@ -261,4 +275,6 @@ Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) return drv_pio_std_init(Bus, Drive, OutBus, OutMaster); } +#endif + #endif \ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/ApplicationProcessor.h b/dev/kernel/HALKit/ARM64/ApplicationProcessor.h index f48c1483..75f4eb07 100644 --- a/dev/kernel/HALKit/ARM64/ApplicationProcessor.h +++ b/dev/kernel/HALKit/ARM64/ApplicationProcessor.h @@ -10,7 +10,8 @@ #include /************************************************** */ -/* INITIALIZE THE GIC ON CPU. */ +/* INITIALIZE THE GIC ON THE CURRENT CORE. */ +/* WITH AN EXECUTION LEVEL IN MIND. */ /************************************************** */ namespace Kernel { diff --git a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc index 7e55aa07..a89702ea 100644 --- a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc @@ -122,6 +122,8 @@ EXTERN_C Bool mp_register_process(HAL::StackFramePtr stack_frame, ProcessID pid) return YES; } +/// @internal +/// @brief Initialize the Global Interrupt Controller. BOOL mp_initialize_gic(Void) { if (!Detail::kGICEnabled) { Detail::kGICEnabled = YES; diff --git a/dev/kernel/KernelKit/FileMgr.h b/dev/kernel/KernelKit/FileMgr.h index 2c4b2055..6751b0a8 100644 --- a/dev/kernel/KernelKit/FileMgr.h +++ b/dev/kernel/KernelKit/FileMgr.h @@ -36,7 +36,7 @@ #include /// @brief Filesystem manager, abstraction over mounted filesystem. -/// Works like the VFS or IFS subsystem. +/// Works like an VFS (Virtual File System) or IFS subsystem on NT/OS 2. #define kRestrictR "r" #define kRestrictRB "rb" @@ -176,6 +176,52 @@ class NeFileSystemMgr final : public IFilesystemMgr { #endif // ifdef __FSKIT_INCLUDES_NEFS__ +#ifdef __FSKIT_INCLUDES_HEFS__ +/** + * @brief Based of IFilesystemMgr, takes care of managing NeFS + * disks. + */ +class HeFileSystemMgr final : public IFilesystemMgr { + public: + explicit HeFileSystemMgr(); + ~HeFileSystemMgr() override; + + public: + NE_COPY_DEFAULT(HeFileSystemMgr) + + public: + NodePtr Create(const Char* path) override; + NodePtr CreateAlias(const Char* path) override; + NodePtr CreateDirectory(const Char* path) override; + NodePtr CreateSwapFile(const Char* path) override; + + public: + bool Remove(_Input const Char* path) override; + NodePtr Open(_Input const Char* path, _Input const Char* r) override; + Void Write(_Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, + _Input SizeT sz) override; + VoidPtr Read(_Input NodePtr node, _Input Int32 flags, _Input SizeT sz) override; + bool Seek(_Input NodePtr node, _Input SizeT off) override; + SizeT Tell(_Input NodePtr node) override; + bool Rewind(_Input NodePtr node) override; + + Void Write(_Input const Char* name, _Input NodePtr node, _Input VoidPtr data, _Input Int32 flags, + _Input SizeT size) override; + + _Output VoidPtr Read(_Input const Char* name, _Input NodePtr node, _Input Int32 flags, + _Input SizeT sz) override; + + public: + /// @brief Get NeFS parser class. + /// @return The filesystem parser class. + HeFileSystemParser* GetParser() noexcept; + + private: + HeFileSystemParser* mParser{nullptr}; +}; + +#endif // ifdef __FSKIT_INCLUDES_HEFS__ + /** * FileStream class. * @tparam Encoding file encoding (char, wchar_t...) diff --git a/dev/kernel/KernelKit/PCI/DMA.h b/dev/kernel/KernelKit/PCI/DMA.h index 66d64f61..cad27a7a 100644 --- a/dev/kernel/KernelKit/PCI/DMA.h +++ b/dev/kernel/KernelKit/PCI/DMA.h @@ -14,11 +14,12 @@ namespace Kernel { enum class DmaKind { - PCI, // Bus mastering is required to be turned on. Basiaclly a request + PCI = 10, // Bus mastering is required to be turned on. Basiaclly a request // control system. 64-Bit access depends on the PAE bit and the device // (if Double Address Cycle is available) ISA, // Four DMA channels 0-3; 8 bit transfers and only a megabyte of RAM. - Invalid, + Count = 2, + Invalid = 0, }; class DMAWrapper final { diff --git a/dev/kernel/NetworkKit/NetworkDevice.inl b/dev/kernel/NetworkKit/NetworkDevice.inl index 797b8adc..812c0248 100644 --- a/dev/kernel/NetworkKit/NetworkDevice.inl +++ b/dev/kernel/NetworkKit/NetworkDevice.inl @@ -9,17 +9,18 @@ */ namespace Kernel { -NetworkDevice::NetworkDevice(void (*out)(IDeviceObject*, - NetworkDeviceCommand), - void (*in)(IDeviceObject*, NetworkDeviceCommand), - void (*on_cleanup)(void)) +inline NetworkDevice::NetworkDevice(void (*out)(IDeviceObject*, + NetworkDeviceCommand), + void (*in)(IDeviceObject*, + NetworkDeviceCommand), + void (*on_cleanup)(void)) : IDeviceObject(out, in), fCleanup(on_cleanup) { kout << "NetworkDevice initialized.\r"; MUST_PASS(out && in && on_cleanup); } -NetworkDevice::~NetworkDevice() { +inline NetworkDevice::~NetworkDevice() { MUST_PASS(fCleanup); kout << "NetworkDevice cleanup.\r"; diff --git a/dev/kernel/amd64-desktop.make b/dev/kernel/amd64-desktop.make index f13bc63a..0358bd0a 100644 --- a/dev/kernel/amd64-desktop.make +++ b/dev/kernel/amd64-desktop.make @@ -50,7 +50,7 @@ WINDRES=x86_64-w64-mingw32-windres .PHONY: nekernel-amd64-epm nekernel-amd64-epm: clean $(WINDRES) kernel_rsrc.rsrc -O coff -o kernel_rsrc.obj - $(CXX) $(CCFLAGS) $(DISK_DRV) $(DEBUG_MACRO) $(wildcard src/*.cc) $(wildcard src/Gfx/*.cc) $(wildcard HALKit/AMD64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) $(wildcard src/FS/*.cc) $(wildcard HALKit/AMD64/Storage/*.cc) $(wildcard HALKit/AMD64/*.cc) $(wildcard src/Swap/*.cc) $(wildcard HALKit/AMD64/*.s) + $(CXX) $(CCFLAGS) $(DISK_DRV) $(DEBUG_MACRO) $(wildcard src/*.cc) $(wildcard src/Gfx/*.cc) $(wildcard HALKit/AMD64/Network/*.cc) $(wildcard HALKit/AMD64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) $(wildcard src/FS/*.cc) $(wildcard HALKit/AMD64/Storage/*.cc) $(wildcard HALKit/AMD64/*.cc) $(wildcard src/Swap/*.cc) $(wildcard HALKit/AMD64/*.s) $(ASM) $(ASMFLAGS) HALKit/AMD64/HalInterruptAPI.asm $(ASM) $(ASMFLAGS) HALKit/AMD64/HalCommonAPI.asm $(ASM) $(ASMFLAGS) HALKit/AMD64/HalBootHeader.asm diff --git a/dev/kernel/src/FS/HeFS+FileSystemParser.cc b/dev/kernel/src/FS/HeFS+FileSystemParser.cc index 70a31154..d4aa1ee3 100644 --- a/dev/kernel/src/FS/HeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/HeFS+FileSystemParser.cc @@ -742,7 +742,7 @@ namespace Detail { /// real-time. /// @note This is certainly take longer to format a disk with it, but worth-it in the long run. -namespace Kernel::HeFS { +namespace Kernel { /// @brief Make a EPM+HeFS mnt out of the disk. /// @param mnt The mnt to write on. /// @return If it was sucessful, see err_local_get(). @@ -1142,7 +1142,7 @@ STATIC DriveTrait kMountPoint; /// @brief Initialize the HeFS filesystem. /// @return To check its status, see err_local_get(). -Boolean fs_init_hefs(Void) { +Boolean HeFS::fs_init_hefs(Void) noexcept { kout << "Creating HeFS disk...\r"; kMountPoint = io_construct_main_drive(); @@ -1152,10 +1152,8 @@ Boolean fs_init_hefs(Void) { HeFileSystemParser parser; - parser.Format(&kMountPoint, kHeFSEncodingFlagsUTF8, kHeFSDefaultVolumeName); - - return YES; + return parser.Format(&kMountPoint, kHeFSEncodingFlagsUTF8, kHeFSDefaultVolumeName); } -} // namespace Kernel::HeFS +} // namespace Kernel #endif // ifdef __FSKIT_INCLUDES_HEFS__ diff --git a/dev/kernel/src/FS/NeFS+FileSystemParser.cc b/dev/kernel/src/FS/NeFS+FileSystemParser.cc index 0b818bbb..49673b59 100644 --- a/dev/kernel/src/FS/NeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/NeFS+FileSystemParser.cc @@ -444,6 +444,8 @@ bool NeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const I NEFS_ROOT_PARTITION_BLOCK* part_block = (NEFS_ROOT_PARTITION_BLOCK*) fs_buf; + if (rt_string_cmp(kNeFSIdent, part_block->Ident, kNeFSIdentLen) == 0) return true; + const auto kNeFSUntitledHD = part_name; rt_copy_memory((VoidPtr) kNeFSIdent, (VoidPtr) part_block->Ident, kNeFSIdentLen); @@ -463,6 +465,7 @@ bool NeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const I part_block->FreeSectors = sectorCount / sizeof(NEFS_CATALOG_STRUCT) - 1; part_block->SectorCount = sectorCount; part_block->DiskSize = diskSize; + part_block->SectorSize = drive->fSectorSz; part_block->FreeCatalog = sectorCount / sizeof(NEFS_CATALOG_STRUCT) - 1; drive->fPacket.fPacketContent = fs_buf; @@ -479,26 +482,6 @@ bool NeFileSystemParser::Format(_Input _Output DriveTrait* drive, _Input const I (Void)(kout << "Free sectors: " << hex_number(part_block->FreeSectors) << kendl); (Void)(kout << "Sector size: " << hex_number(part_block->SectorSize) << kendl); - NEFS_CATALOG_STRUCT root{}; - - rt_set_memory(&root, 0, sizeof(NEFS_CATALOG_STRUCT)); - - root.PrevSibling = part_block->StartCatalog; - root.NextSibling = 0UL; - - root.Kind = kNeFSCatalogKindDir; - root.Flags |= kNeFSFlagCreated; - root.CatalogFlags |= kNeFSStatusUnlocked; - - root.Name[0] = '/'; - root.Name[1] = 0; - - drive->fPacket.fPacketLba = part_block->StartCatalog; - drive->fPacket.fPacketSize = sizeof(NEFS_CATALOG_STRUCT); - drive->fPacket.fPacketContent = &root; - - drive->fOutput(drive->fPacket); - return true; } -- cgit v1.2.3 From 6a30f42d5dcd0f944262147b2806db6c14fe7ffc Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 15 May 2025 13:56:17 +0200 Subject: 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 --- dev/boot/amd64-desktop.make | 4 +- dev/boot/modules/SysChk/amd64-ahci-epm.json | 1 + dev/boot/src/HEL/AMD64/BootAPI.S | 10 ++ dev/ddk/src/ddk_alloc.c | 4 +- dev/kernel/DmaKit/DmaPool.h | 91 ++++++++++ dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 39 ++-- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 37 +--- dev/kernel/HALKit/AMD64/HalDescriptorLoader.cc | 53 ------ dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 18 +- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 23 ++- .../HALKit/AMD64/Network/Generic+Basic+RTL8139.cc | 4 +- dev/kernel/HALKit/AMD64/Paging.h | 23 ++- dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc | 2 +- dev/kernel/KernelKit/CodeMgr.h | 2 +- dev/kernel/KernelKit/CoreProcessScheduler.h | 2 +- dev/kernel/KernelKit/FileMgr.h | 4 +- dev/kernel/KernelKit/HardwareThreadScheduler.h | 10 +- dev/kernel/KernelKit/MemoryMgr.h | 14 +- dev/kernel/KernelKit/UserProcessScheduler.h | 7 +- dev/kernel/KernelKit/UserProcessScheduler.inl | 4 +- dev/kernel/NewKit/Array.h | 5 +- dev/kernel/NewKit/Ref.h | 2 +- dev/kernel/StorageKit/DmaPool.h | 92 ---------- dev/kernel/src/BitMapMgr.cc | 2 +- dev/kernel/src/CxxAbi-AMD64.cc | 6 +- dev/kernel/src/DriveMgr.cc | 10 +- dev/kernel/src/FS/HeFS+FileSystemParser.cc | 42 ++--- dev/kernel/src/FS/NeFS+FileSystemParser.cc | 4 +- dev/kernel/src/HardwareThreadScheduler.cc | 12 +- dev/kernel/src/KPC.cc | 2 +- dev/kernel/src/MemoryMgr.cc | 59 +++--- dev/kernel/src/New+Delete.cc | 12 +- dev/kernel/src/PEFCodeMgr.cc | 16 +- dev/kernel/src/UserProcessScheduler.cc | 198 ++++++++------------- 34 files changed, 359 insertions(+), 455 deletions(-) create mode 100644 dev/kernel/DmaKit/DmaPool.h delete mode 100644 dev/kernel/StorageKit/DmaPool.h (limited to 'dev/kernel/HALKit/AMD64/HalInterruptAPI.asm') diff --git a/dev/boot/amd64-desktop.make b/dev/boot/amd64-desktop.make index b5e49cb0..7687e3c6 100644 --- a/dev/boot/amd64-desktop.make +++ b/dev/boot/amd64-desktop.make @@ -49,7 +49,7 @@ DEBUG_MACRO = -D__DEBUG__ endif ifeq ($(shell uname), Darwin) -EMU_FLAGS=-M q35 -smp 4 -m 8G \ +EMU_FLAGS=-M q35 -smp 4 -m 8G \ -bios $(BIOS) -cdrom $(BOOT) -boot d endif @@ -117,7 +117,7 @@ compile-amd64: .PHONY: run-efi-amd64-ahci run-efi-amd64-ahci: - $(EMU) $(EMU_FLAGS) -d int -hda $(IMG) -s -S -trace ahci_* -boot menu=on + $(EMU) $(EMU_FLAGS) -serial stdio -hda $(IMG) -s -S -boot menu=on .PHONY: run-efi-amd64-ata-pio run-efi-amd64-ata-pio: diff --git a/dev/boot/modules/SysChk/amd64-ahci-epm.json b/dev/boot/modules/SysChk/amd64-ahci-epm.json index 91c95941..8ce9bfd8 100644 --- a/dev/boot/modules/SysChk/amd64-ahci-epm.json +++ b/dev/boot/modules/SysChk/amd64-ahci-epm.json @@ -14,6 +14,7 @@ "../../../kernel/HALKit/AMD64/PCI/*.cc", "../../../kernel/HALKit/AMD64/Storage/*.cc", "../../../kernel/src/Storage/*.cc", + "../../../kernel/src/Network/*.cc", "../../../kernel/HALKit/AMD64/*.cc", "../../../kernel/HALKit/AMD64/*.s", "../../../kernel/src/*.cc" diff --git a/dev/boot/src/HEL/AMD64/BootAPI.S b/dev/boot/src/HEL/AMD64/BootAPI.S index 43775fc2..2c0005ac 100644 --- a/dev/boot/src/HEL/AMD64/BootAPI.S +++ b/dev/boot/src/HEL/AMD64/BootAPI.S @@ -5,6 +5,16 @@ .intel_syntax noprefix +.global hal_load_idt + +hal_load_idt: + ret + +.global sched_jump_to_task + +sched_jump_to_task: + ret + /** @brief this function setups a stack and then jumps to a function */ diff --git a/dev/ddk/src/ddk_alloc.c b/dev/ddk/src/ddk_alloc.c index 6daafb7e..1354bce4 100644 --- a/dev/ddk/src/ddk_alloc.c +++ b/dev/ddk/src/ddk_alloc.c @@ -16,7 +16,7 @@ DDK_EXTERN void* kalloc(size_t sz) { if (!sz) ++sz; - void* ptr = ke_call("mm_new_heap", 1, &sz, sizeof(size_t)); + void* ptr = ke_call("mm_new_ptr", 1, &sz, sizeof(size_t)); return ptr; } @@ -28,5 +28,5 @@ DDK_EXTERN void* kalloc(size_t sz) { DDK_EXTERN void kfree(void* ptr) { if (!ptr) return; - ke_call("mm_delete_heap", 1, ptr, 0); + ke_call("mm_delete_ptr", 1, ptr, 0); } diff --git a/dev/kernel/DmaKit/DmaPool.h b/dev/kernel/DmaKit/DmaPool.h new file mode 100644 index 00000000..5acff623 --- /dev/null +++ b/dev/kernel/DmaKit/DmaPool.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2025 Amlal El Mahrouss. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#pragma once + +#include +#include + +#ifdef __NE_AMD64__ +#define kNeDMAPoolStart (0x1000000) +#define kNeDMAPoolSize (0x1000000) + +namespace Kernel { +/// @brief DMA pool base pointer, here we're sure that AHCI or whatever tricky standard sees it. +inline UInt8* kDmaPoolPtr = (UInt8*) kNeDMAPoolStart; +inline const UInt8* kDmaPoolEnd = (UInt8*) (kNeDMAPoolStart + kNeDMAPoolSize); + +/***********************************************************************************/ +/// @brief allocate from the rtl_dma_alloc system. +/// @param size the size of the chunk to allocate. +/// @param align alignement of pointer. +/***********************************************************************************/ +inline VoidPtr rtl_dma_alloc(SizeT size, SizeT align) { + if (!size) { + return nullptr; + } + + UIntPtr addr = (UIntPtr) kDmaPoolPtr; + + /// here we just align the address according to a `align` variable, i'd rather be a power of two + /// really. + addr = (addr + (align - 1)) & ~(align - 1); + + if ((addr + size) >= reinterpret_cast(kDmaPoolEnd)) { + kout << "DMA Pool is exhausted!\r"; + + err_global_get() = kErrorDmaExhausted; + + return nullptr; + } + + kDmaPoolPtr = (UInt8*) (addr + size); + return (VoidPtr) addr; +} + +/***********************************************************************************/ +/// @brief Free DMA pointer. +/***********************************************************************************/ +inline Void rtl_dma_free(SizeT size) { + if (!size) return; + + kDmaPoolPtr = (UInt8*) (kDmaPoolPtr - size); +} + +/***********************************************************************************/ +/// @brief Flush DMA pointer. +/***********************************************************************************/ +inline Void rtl_dma_flush(VoidPtr ptr, SizeT size_buffer) { + if (ptr > kDmaPoolEnd) { + return; + } + + if (!ptr || ptr < (UInt8*) kNeDMAPoolStart) { + return; + } + + for (SizeT buf_idx = 0UL; buf_idx < size_buffer; ++buf_idx) { + HAL::mm_memory_fence((VoidPtr) ((UInt8*) ptr + buf_idx)); + } +} +} // namespace Kernel +#endif \ No newline at end of file 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 #include -#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(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 #include -#include #include 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 #include #include #include @@ -25,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/dev/kernel/KernelKit/CodeMgr.h b/dev/kernel/KernelKit/CodeMgr.h index ff70707b..f4d46b4b 100644 --- a/dev/kernel/KernelKit/CodeMgr.h +++ b/dev/kernel/KernelKit/CodeMgr.h @@ -20,7 +20,7 @@ namespace Kernel { /// @brief Main process entrypoint. -typedef void (*rtl_main_kind)(SizeT argc, Char** argv, Char** envp, SizeT envp_len); +typedef void (*rtl_main_kind)(void); /// @brief C++ Constructor entrypoint. typedef void (*rtl_ctor_kind)(void); diff --git a/dev/kernel/KernelKit/CoreProcessScheduler.h b/dev/kernel/KernelKit/CoreProcessScheduler.h index 3f55c099..f9d11459 100644 --- a/dev/kernel/KernelKit/CoreProcessScheduler.h +++ b/dev/kernel/KernelKit/CoreProcessScheduler.h @@ -15,7 +15,7 @@ #define kSchedTeamCount (256U) #define kSchedMaxMemoryLimit gib_cast(128) /* max physical memory limit */ -#define kSchedMaxStackSz mib_cast(8) /* maximum stack size */ +#define kSchedMaxStackSz (kib_cast(8)) /* maximum stack size */ #define kSchedNameLen (128U) diff --git a/dev/kernel/KernelKit/FileMgr.h b/dev/kernel/KernelKit/FileMgr.h index 6751b0a8..32c30b70 100644 --- a/dev/kernel/KernelKit/FileMgr.h +++ b/dev/kernel/KernelKit/FileMgr.h @@ -385,13 +385,13 @@ inline FileStream::FileStream(const Encoding* path, const Encod } } - kout << "new file: " << path << ".\r"; + kout << "FileMgr: New file at: " << path << ".\r"; } /// @brief destructor of the file stream. template inline FileStream::~FileStream() { - mm_delete_heap(fFile); + mm_delete_ptr(fFile); } } // namespace Kernel diff --git a/dev/kernel/KernelKit/HardwareThreadScheduler.h b/dev/kernel/KernelKit/HardwareThreadScheduler.h index d47b2994..dd8271eb 100644 --- a/dev/kernel/KernelKit/HardwareThreadScheduler.h +++ b/dev/kernel/KernelKit/HardwareThreadScheduler.h @@ -14,7 +14,7 @@ /// @note Last Rev Sun 28 Jul CET 2024 /// @note Last Rev Thu, Aug 1, 2024 9:07:38 AM -#define kMaxAPInsideSched (8U) +#define kMaxAPInsideSched (4U) namespace Kernel { class HardwareThread; @@ -58,14 +58,14 @@ class HardwareThread final { void Busy(const BOOL busy = false) noexcept; public: - BOOL Switch(VoidPtr image, Ptr8 stack_ptr, HAL::StackFramePtr frame, const ThreadID& pid); + BOOL Switch(HAL::StackFramePtr frame, const ThreadID& pid); BOOL IsWakeup() noexcept; public: HAL::StackFramePtr StackFrame() noexcept; - const ThreadKind& Kind() noexcept; - bool IsBusy() noexcept; - const ThreadID& ID() noexcept; + ThreadKind& Kind() noexcept; + BOOL IsBusy() noexcept; + ThreadID& ID() noexcept; private: HAL::StackFramePtr fStack{nullptr}; diff --git a/dev/kernel/KernelKit/MemoryMgr.h b/dev/kernel/KernelKit/MemoryMgr.h index 2274e24e..d84dc9a4 100644 --- a/dev/kernel/KernelKit/MemoryMgr.h +++ b/dev/kernel/KernelKit/MemoryMgr.h @@ -19,29 +19,29 @@ namespace Kernel { /// @brief Declare pointer as free. /// @param heap_ptr the pointer. /// @return a status code regarding the deallocation. -Int32 mm_delete_heap(VoidPtr heap_ptr); +Int32 mm_delete_ptr(VoidPtr heap_ptr); /// @brief Declare a new size for heap_ptr. /// @param heap_ptr the pointer. /// @return unsupported always returns nullptr. -VoidPtr mm_realloc_heap(VoidPtr heap_ptr, SizeT new_sz); +VoidPtr mm_realloc_ptr(VoidPtr heap_ptr, SizeT new_sz); /// @brief Check if pointer is a valid Kernel pointer. /// @param heap_ptr the pointer /// @return if it exists it returns true. -Boolean mm_is_valid_heap(VoidPtr heap_ptr); +Boolean mm_is_valid_ptr(VoidPtr heap_ptr); /// @brief Allocate chunk of memory. /// @param sz Size of pointer /// @param wr Read Write bit. /// @param user User enable bit. /// @return The newly allocated pointer, or nullptr. -VoidPtr mm_new_heap(SizeT sz, Bool wr, Bool user, SizeT pad_amount = 0); +VoidPtr mm_new_ptr(SizeT sz, Bool wr, Bool user, SizeT pad_amount = 0); /// @brief Protect the heap with a CRC value. /// @param heap_ptr pointer. /// @return if it valid: point has crc now., otherwise fail. -Boolean mm_protect_heap(VoidPtr heap_ptr); +Boolean mm_protect_ptr(VoidPtr heap_ptr); /// @brief Makes a Kernel page. /// @param heap_ptr the page pointer. @@ -51,11 +51,11 @@ Int32 mm_make_page(VoidPtr heap_ptr); /// @brief Overwrites and set the flags of a heap header. /// @param heap_ptr the pointer to update. /// @param flags the flags to set. -Int32 mm_make_flags(VoidPtr heap_ptr, UInt64 flags); +Int32 mm_make_ptr_flags(VoidPtr heap_ptr, UInt64 flags); /// @brief Gets the flags of a heap header. /// @param heap_ptr the pointer to get. -UInt64 mm_get_flags(VoidPtr heap_ptr); +UInt64 mm_get_ptr_flags(VoidPtr heap_ptr); /// @brief Allocate C++ class. /// @param cls The class to allocate. diff --git a/dev/kernel/KernelKit/UserProcessScheduler.h b/dev/kernel/KernelKit/UserProcessScheduler.h index a638f0dc..717788e9 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.h +++ b/dev/kernel/KernelKit/UserProcessScheduler.h @@ -47,7 +47,7 @@ class USER_PROCESS final { HAL::StackFramePtr StackFrame{nullptr}; AffinityKind Affinity{AffinityKind::kStandard}; ProcessStatusKind Status{ProcessStatusKind::kKilled}; - UInt8* StackReserve{nullptr}; + UInt8 StackReserve[kSchedMaxStackSz]; PROCESS_IMAGE Image{}; SizeT StackSize{kSchedMaxStackSz}; IDylibObject* DylibDelegate{nullptr}; @@ -92,6 +92,8 @@ class USER_PROCESS final { /***********************************************************************************/ Void Crash(); + Bool SpawnDylib(); + /***********************************************************************************/ ///! @brief Exits the app. /***********************************************************************************/ @@ -219,8 +221,7 @@ class UserProcessScheduler final : public ISchedulable { class UserProcessHelper final { public: - STATIC Bool Switch(VoidPtr image_ptr, UInt8* stack_ptr, HAL::StackFramePtr frame_ptr, - PID new_pid); + STATIC Bool Switch(HAL::StackFramePtr frame_ptr, PID new_pid); STATIC Bool CanBeScheduled(const USER_PROCESS& process); STATIC ErrorOr TheCurrentPID(); STATIC SizeT StartScheduling(); diff --git a/dev/kernel/KernelKit/UserProcessScheduler.inl b/dev/kernel/KernelKit/UserProcessScheduler.inl index 7bf98d78..236262e1 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.inl +++ b/dev/kernel/KernelKit/UserProcessScheduler.inl @@ -36,13 +36,13 @@ Boolean USER_PROCESS::Delete(ErrorOr ptr) { hal_write_cr3(this->VMRegister); - auto ret = mm_delete_heap(entry->Entry); + auto ret = mm_delete_ptr(entry->Entry); hal_write_cr3(pd); return ret == kErrorSuccess; #else - Bool ret = mm_delete_heap(ptr.Leak().Leak()); + Bool ret = mm_delete_ptr(ptr.Leak().Leak()); return ret == kErrorSuccess; #endif diff --git a/dev/kernel/NewKit/Array.h b/dev/kernel/NewKit/Array.h index af73d002..767d8678 100644 --- a/dev/kernel/NewKit/Array.h +++ b/dev/kernel/NewKit/Array.h @@ -20,10 +20,7 @@ class Array final { Array& operator=(const Array&) = default; Array(const Array&) = default; - T& operator[](SizeT at) { - MUST_PASS(at < this->Count()); - return fArray[at]; - } + T& operator[](SizeT at) { return fArray[at]; } Boolean Empty() { return this->Count() > 0; } diff --git a/dev/kernel/NewKit/Ref.h b/dev/kernel/NewKit/Ref.h index 6737ce09..31ad16f8 100644 --- a/dev/kernel/NewKit/Ref.h +++ b/dev/kernel/NewKit/Ref.h @@ -19,7 +19,7 @@ class Ref final { Ref() = default; ~Ref() { - if (mm_is_valid_heap(fClass)) delete fClass; + if (mm_is_valid_ptr(fClass)) delete fClass; } public: diff --git a/dev/kernel/StorageKit/DmaPool.h b/dev/kernel/StorageKit/DmaPool.h deleted file mode 100644 index a5d8c880..00000000 --- a/dev/kernel/StorageKit/DmaPool.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2025 Amlal El Mahrouss. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#pragma once - -#include - -#ifdef __NE_AMD64__ -#define NE_DMA_POOL_START (0x1000000) -#define NE_DMA_POOL_SIZE (0x1000000) - -namespace Kernel { -/// @brief DMA pool base pointer, here we're sure that AHCI or whatever tricky standard sees it. -inline UInt8* kDmaPoolPtr = (UInt8*) NE_DMA_POOL_START; -inline const UInt8* kDmaPoolEnd = (UInt8*) (NE_DMA_POOL_START + NE_DMA_POOL_SIZE); - -/***********************************************************************************/ -/// @brief allocate from the rtl_dma_alloc system. -/// @param size the size of the chunk to allocate. -/// @param align alignement of pointer. -/***********************************************************************************/ -inline VoidPtr rtl_dma_alloc(SizeT size, SizeT align) { - if (!size) { - return nullptr; - } - - UIntPtr addr = (UIntPtr) kDmaPoolPtr; - - /// here we just align the address according to a `align` variable, i'd rather be a power of two - /// really. - addr = (addr + (align - 1)) & ~(align - 1); - - if ((addr + size) >= reinterpret_cast(kDmaPoolEnd)) { - kout << "DMA Pool is exhausted!\r"; - - err_global_get() = kErrorDmaExhausted; - - return nullptr; - } - - kDmaPoolPtr = (UInt8*) (addr + size); - return (VoidPtr) addr; -} - -/***********************************************************************************/ -/// @brief Free DMA pointer. -/***********************************************************************************/ -inline Void rtl_dma_free(SizeT size) { - if (!size) return; - - kDmaPoolPtr = (UInt8*) (kDmaPoolPtr - size); -} - -/***********************************************************************************/ -/// @brief Flush DMA pointer. -/***********************************************************************************/ -inline Void rtl_dma_flush(VoidPtr ptr, SizeT size_buffer) { - if (ptr > (Void*) (NE_DMA_POOL_START + NE_DMA_POOL_SIZE)) { - return; - } - - if (!ptr) { - return; - } - - for (SizeT i = 0; i < size_buffer; ++i) { - asm volatile("clflush (%0)" : : "r"((UInt8*) ptr + i) : "memory"); - } - - asm volatile("mfence" ::: "memory"); -} -} // namespace Kernel -#endif \ No newline at end of file diff --git a/dev/kernel/src/BitMapMgr.cc b/dev/kernel/src/BitMapMgr.cc index 7cbcf376..dfd29770 100644 --- a/dev/kernel/src/BitMapMgr.cc +++ b/dev/kernel/src/BitMapMgr.cc @@ -169,7 +169,7 @@ namespace HAL { VoidPtr ptr_new = nullptr; Detail::IBitMapProxy bitmp; - NE_UNUSED(is_page); + if (is_page) return nullptr; ptr_new = bitmp.FindBitMap(kKernelBitMpStart, size, wr, user, pad); return (UIntPtr*) ptr_new; diff --git a/dev/kernel/src/CxxAbi-AMD64.cc b/dev/kernel/src/CxxAbi-AMD64.cc index 452f23cd..c97b99f9 100644 --- a/dev/kernel/src/CxxAbi-AMD64.cc +++ b/dev/kernel/src/CxxAbi-AMD64.cc @@ -8,6 +8,7 @@ #include #include +#include #include atexit_func_entry_t __atexit_funcs[kAtExitMacDestructors]; @@ -23,10 +24,7 @@ EXTERN_C Kernel::Void __cxa_pure_virtual(void* self) { (Kernel::Void)(Kernel::kout << ", has unimplemented virtual functions.\r"); } -EXTERN_C void ___chkstk_ms(void) { - (Kernel::Void)(Kernel::kout << "Stack smashing detected!\r"); - dbg_break_point(); -} +EXTERN_C void ___chkstk_ms(void) {} EXTERN_C int atexit(void (*f)()) { if (__atexit_func_count >= kAtExitMacDestructors) return 1; diff --git a/dev/kernel/src/DriveMgr.cc b/dev/kernel/src/DriveMgr.cc index 449640f9..8bb1c930 100644 --- a/dev/kernel/src/DriveMgr.cc +++ b/dev/kernel/src/DriveMgr.cc @@ -146,7 +146,7 @@ DriveTrait io_construct_blank_drive() noexcept { trait.fInit = io_drv_unimplemented; trait.fProtocol = io_drv_kind; - kout << "Construct: " << trait.fName << "\r"; + kout << "DriveMgr: Construct: " << trait.fName << "\r"; return trait; } @@ -170,7 +170,7 @@ namespace Detail { trait.fPacket.fPacketReadOnly = NO; trait.fKind = kMassStorageDrive | kEPMDrive; - kout << "Disk is EPM formatted.\r"; + kout << "DriveMgr: Disk is EPM formatted.\r"; trait.fSectorSz = block_struct.SectorSz; trait.fLbaEnd = block_struct.LbaEnd; @@ -191,13 +191,13 @@ namespace Detail { trait.fPacket.fPacketReadOnly = NO; trait.fKind = kMassStorageDrive | kGPTDrive; - kout << "Disk is GPT formatted.\r"; + kout << "DriveMgr: Disk is GPT formatted.\r"; trait.fSectorSz = gpt_struct.SizeOfEntries; trait.fLbaEnd = gpt_struct.LastGPTEntry; trait.fLbaStart = gpt_struct.FirstGPTEntry; } else { - kout << "Disk is unformatted.\r"; + kout << "DriveMgr: Disk is unformatted.\r"; trait.fPacket.fPacketReadOnly = YES; trait.fKind = kMassStorageDrive | kUnformattedDrive | kReadOnlyDrive; @@ -233,7 +233,7 @@ DriveTrait io_construct_main_drive() noexcept { trait.fInit = io_drv_init; trait.fProtocol = io_drv_kind; - kout << "Detecting partition scheme of: " << trait.fName << ".\r"; + kout << "DriveMgr: Detecting partition scheme of: " << trait.fName << ".\r"; Detail::io_detect_drive(trait); diff --git a/dev/kernel/src/FS/HeFS+FileSystemParser.cc b/dev/kernel/src/FS/HeFS+FileSystemParser.cc index d4aa1ee3..519707d7 100644 --- a/dev/kernel/src/FS/HeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/HeFS+FileSystemParser.cc @@ -262,7 +262,7 @@ namespace Detail { const BOOL delete_or_create) { if (mnt) { HEFS_INDEX_NODE_DIRECTORY* tmpdir = - (HEFS_INDEX_NODE_DIRECTORY*) mm_new_heap(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); + (HEFS_INDEX_NODE_DIRECTORY*) mm_new_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); auto start = root->fStartIND; auto prev_location = start; @@ -294,7 +294,7 @@ namespace Detail { if (expr) { HEFS_INDEX_NODE_DIRECTORY* dirent = - (HEFS_INDEX_NODE_DIRECTORY*) mm_new_heap(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); + (HEFS_INDEX_NODE_DIRECTORY*) mm_new_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); rt_set_memory(dirent, 0, sizeof(HEFS_INDEX_NODE_DIRECTORY)); @@ -412,8 +412,8 @@ namespace Detail { err_global_get() = kErrorSuccess; - mm_delete_heap(dirent); - mm_delete_heap(tmpdir); + mm_delete_ptr(dirent); + mm_delete_ptr(tmpdir); if (!delete_or_create) ++root->fINDCount; @@ -438,7 +438,7 @@ namespace Detail { } err_global_get() = kErrorDisk; - mm_delete_heap(tmpdir); + mm_delete_ptr(tmpdir); return NO; } @@ -467,7 +467,7 @@ namespace Detail { HEFS_INDEX_NODE* node = new HEFS_INDEX_NODE(); HEFS_INDEX_NODE_DIRECTORY* dir = - (HEFS_INDEX_NODE_DIRECTORY*) mm_new_heap(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); + (HEFS_INDEX_NODE_DIRECTORY*) mm_new_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); while (YES) { if (err_global_get() == kErrorDiskIsCorrupted) { @@ -543,7 +543,7 @@ namespace Detail { if (mnt) { HEFS_INDEX_NODE_DIRECTORY* dir = - (HEFS_INDEX_NODE_DIRECTORY*) mm_new_heap(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); + (HEFS_INDEX_NODE_DIRECTORY*) mm_new_ptr(sizeof(HEFS_INDEX_NODE_DIRECTORY), Yes, No); auto hash_file = node->fHashPath; @@ -596,7 +596,7 @@ namespace Detail { mnt->fOutput(mnt->fPacket); - mm_delete_heap(dir); + mm_delete_ptr(dir); return YES; } else if (dir->fINSlices[inode_index] != 0 && delete_or_create) { @@ -646,7 +646,7 @@ namespace Detail { mnt->fOutput(mnt->fPacket); - mm_delete_heap(dir); + mm_delete_ptr(dir); return YES; } @@ -657,7 +657,7 @@ namespace Detail { if (start > root->fEndIND || start == 0) break; } - mm_delete_heap(dir); + mm_delete_ptr(dir); err_global_get() = kErrorFileNotFound; return NO; } @@ -902,7 +902,7 @@ _Output Bool HeFileSystemParser::INodeDirectoryCtlManip(_Input DriveTrait* mnt, return NO; } - HEFS_BOOT_NODE* root = (HEFS_BOOT_NODE*) mm_new_heap(sizeof(HEFS_BOOT_NODE), Yes, No); + HEFS_BOOT_NODE* root = (HEFS_BOOT_NODE*) mm_new_ptr(sizeof(HEFS_BOOT_NODE), Yes, No); rt_copy_memory((VoidPtr) "fs/hefs-packet", mnt->fPacket.fPacketMime, rt_string_len("fs/hefs-packet")); @@ -938,11 +938,11 @@ _Output Bool HeFileSystemParser::INodeDirectoryCtlManip(_Input DriveTrait* mnt, // todo: make it smarter for high-throughput. Detail::hefsi_balance_ind(root, mnt); - mm_delete_heap((VoidPtr) root); + mm_delete_ptr((VoidPtr) root); return YES; } - mm_delete_heap((VoidPtr) root); + mm_delete_ptr((VoidPtr) root); return NO; } @@ -983,7 +983,7 @@ _Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr bloc return NO; } - HEFS_BOOT_NODE* root = (HEFS_BOOT_NODE*) mm_new_heap(sizeof(HEFS_BOOT_NODE), Yes, No); + HEFS_BOOT_NODE* root = (HEFS_BOOT_NODE*) mm_new_ptr(sizeof(HEFS_BOOT_NODE), Yes, No); if (!root) { err_global_get() = kErrorInvalidData; @@ -1001,7 +1001,7 @@ _Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr bloc if (!KStringBuilder::Equals(root->fMagic, kHeFSMagic) || root->fVersion != kHeFSVersion) { (Void)(kout << "Invalid Boot Node, HeFS partition is invalid." << kendl); - mm_delete_heap((VoidPtr) root); + mm_delete_ptr((VoidPtr) root); err_global_get() = kErrorDisk; return NO; } @@ -1021,7 +1021,7 @@ _Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr bloc mnt->fInput(mnt->fPacket); } else { if (start->fFlags & kHeFSFlagsReadOnly) { - mm_delete_heap((VoidPtr) root); + mm_delete_ptr((VoidPtr) root); delete start; kout << "Error: File is read-only\r"; @@ -1034,7 +1034,7 @@ _Output Bool HeFileSystemParser::INodeManip(_Input DriveTrait* mnt, VoidPtr bloc } } - mm_delete_heap((VoidPtr) root); + mm_delete_ptr((VoidPtr) root); delete start; return YES; } @@ -1058,7 +1058,7 @@ _Output Bool HeFileSystemParser::INodeCtlManip(_Input DriveTrait* mnt, _Input co return NO; } - HEFS_INDEX_NODE* node = (HEFS_INDEX_NODE*) mm_new_heap(sizeof(HEFS_INDEX_NODE), Yes, No); + HEFS_INDEX_NODE* node = (HEFS_INDEX_NODE*) mm_new_ptr(sizeof(HEFS_INDEX_NODE), Yes, No); if (!node) { err_global_get() = kErrorInvalidData; @@ -1070,7 +1070,7 @@ _Output Bool HeFileSystemParser::INodeCtlManip(_Input DriveTrait* mnt, _Input co HEFS_BOOT_NODE* root = (HEFS_BOOT_NODE*) RTL_ALLOCA(sizeof(HEFS_BOOT_NODE)); if (!root) { - mm_delete_heap((VoidPtr) node); + mm_delete_ptr((VoidPtr) node); err_global_get() = kErrorInvalidData; return NO; @@ -1124,7 +1124,7 @@ _Output Bool HeFileSystemParser::INodeCtlManip(_Input DriveTrait* mnt, _Input co node->fHashPath = Detail::hefsi_hash_64(name); if (Detail::hefsi_update_in_status(root, mnt, dir, node, delete_or_create)) { - mm_delete_heap((VoidPtr) node); + mm_delete_ptr((VoidPtr) node); Detail::hefsi_balance_ind(root, mnt); @@ -1132,7 +1132,7 @@ _Output Bool HeFileSystemParser::INodeCtlManip(_Input DriveTrait* mnt, _Input co return YES; } - mm_delete_heap((VoidPtr) node); + mm_delete_ptr((VoidPtr) node); err_global_get() = kErrorDirectoryNotFound; return NO; diff --git a/dev/kernel/src/FS/NeFS+FileSystemParser.cc b/dev/kernel/src/FS/NeFS+FileSystemParser.cc index 49673b59..dae69a21 100644 --- a/dev/kernel/src/FS/NeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/NeFS+FileSystemParser.cc @@ -240,7 +240,7 @@ _Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char return nullptr; } - Char* parent_name = (Char*) mm_new_heap(sizeof(Char) * rt_string_len(name), Yes, No); + Char* parent_name = (Char*) mm_new_ptr(sizeof(Char) * rt_string_len(name), Yes, No); /// Locate parent catalog, to then allocate right after it. @@ -269,7 +269,7 @@ _Output NEFS_CATALOG_STRUCT* NeFileSystemParser::CreateCatalog(_Input const Char NEFS_CATALOG_STRUCT* catalog = this->FindCatalog(parent_name, out_lba); - mm_delete_heap(parent_name); + mm_delete_ptr(parent_name); auto& drive = kMountpoint.A(); diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc index c49c3081..1df5ad7a 100644 --- a/dev/kernel/src/HardwareThreadScheduler.cc +++ b/dev/kernel/src/HardwareThreadScheduler.cc @@ -41,14 +41,14 @@ HardwareThread::~HardwareThread() = default; /***********************************************************************************/ //! @brief returns the id of the thread. /***********************************************************************************/ -const ThreadID& HardwareThread::ID() noexcept { +ThreadID& HardwareThread::ID() noexcept { return fID; } /***********************************************************************************/ //! @brief returns the kind of thread we have. /***********************************************************************************/ -const ThreadKind& HardwareThread::Kind() noexcept { +ThreadKind& HardwareThread::Kind() noexcept { return fKind; } @@ -104,16 +104,10 @@ Void HardwareThread::Wake(const bool wakeup) noexcept { /// @retval true stack was changed, code is running. /// @retval false stack is invalid, previous code is running. /***********************************************************************************/ -Bool HardwareThread::Switch(VoidPtr image_ptr, Ptr8 stack_ptr, HAL::StackFramePtr frame, - const ThreadID& pid) { - if (this->IsBusy()) return NO; - +Bool HardwareThread::Switch(HAL::StackFramePtr frame, const ThreadID& pid) { this->fStack = frame; this->fPID = pid; - this->fStack->BP = reinterpret_cast(image_ptr); - this->fStack->SP = reinterpret_cast(stack_ptr); - Bool ret = mp_register_process(fStack, this->fPID); if (ret) this->Busy(YES); diff --git a/dev/kernel/src/KPC.cc b/dev/kernel/src/KPC.cc index 8937d19a..9a76c110 100644 --- a/dev/kernel/src/KPC.cc +++ b/dev/kernel/src/KPC.cc @@ -19,7 +19,7 @@ Boolean err_bug_check_raise(Void) noexcept { if (ptr == nullptr) goto bug_check_fail; - if (!mm_is_valid_heap(ptr)) goto bug_check_fail; + if (!mm_is_valid_ptr(ptr)) goto bug_check_fail; delete[] ptr; diff --git a/dev/kernel/src/MemoryMgr.cc b/dev/kernel/src/MemoryMgr.cc index 9b7bea43..f8aa14cf 100644 --- a/dev/kernel/src/MemoryMgr.cc +++ b/dev/kernel/src/MemoryMgr.cc @@ -74,14 +74,14 @@ namespace Detail { /// @brief Check for heap address validity. /// @param heap_ptr The address_ptr to check. /// @return Bool if the pointer is valid or not. - _Output auto mm_check_heap_address(VoidPtr heap_ptr) -> Bool { + _Output auto mm_check_ptr_address(VoidPtr heap_ptr) -> Bool { if (!heap_ptr) return false; - IntPtr base_heap = ((IntPtr) heap_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK); + IntPtr base_ptr = ((IntPtr) heap_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK); /// Add that check in case we're having an integer underflow. /// - if (base_heap < 0) { + if (base_ptr < 0) { return false; } @@ -91,15 +91,17 @@ namespace Detail { typedef MM_INFORMATION_BLOCK* MM_INFORMATION_BLOCK_PTR; } // namespace Detail -/// @brief Declare a new size for ptr_heap. -/// @param ptr_heap the pointer. +STATIC PageMgr kPageMgr; + +/// @brief Declare a new size for ptr_ptr. +/// @param ptr_ptr the pointer. /// @return Newly allocated heap header. -_Output auto mm_realloc_heap(VoidPtr ptr_heap, SizeT new_sz) -> VoidPtr { - if (Detail::mm_check_heap_address(ptr_heap) == No) return nullptr; +_Output auto mm_realloc_ptr(VoidPtr ptr_ptr, SizeT new_sz) -> VoidPtr { + if (Detail::mm_check_ptr_address(ptr_ptr) == No) return nullptr; - if (!ptr_heap || new_sz < 1) return nullptr; + if (!ptr_ptr || new_sz < 1) return nullptr; - kout << "This function is not implemented by the kernel yet.\r"; + kout << "MemoryMgr: This function is not implemented by the kernel yet.\r"; ke_panic(RUNTIME_CHECK_INVALID); @@ -111,15 +113,14 @@ _Output auto mm_realloc_heap(VoidPtr ptr_heap, SizeT new_sz) -> VoidPtr { /// @param wr Read Write bit. /// @param user User enable bit. /// @return The newly allocated pointer. -_Output VoidPtr mm_new_heap(SizeT sz, Bool wr, Bool user, SizeT pad_amount) { +_Output VoidPtr mm_new_ptr(SizeT sz, Bool wr, Bool user, SizeT pad_amount) { auto sz_fix = sz; if (sz_fix == 0) return nullptr; sz_fix += sizeof(Detail::MM_INFORMATION_BLOCK); - PageMgr page_mgr; - auto wrapper = page_mgr.Request(wr, user, No, sz_fix, pad_amount); + auto wrapper = kPageMgr.Request(wr, user, No, sz_fix, pad_amount); Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = reinterpret_cast(wrapper.VirtualAddress() + @@ -127,7 +128,7 @@ _Output VoidPtr mm_new_heap(SizeT sz, Bool wr, Bool user, SizeT pad_amount) { heap_info_ptr->fSize = sz_fix; heap_info_ptr->fMagic = kMemoryMgrMagic; - heap_info_ptr->fCRC32 = 0; // dont fill it for now. + heap_info_ptr->fCRC32 = 0U; // dont fill it for now. heap_info_ptr->fOffset = reinterpret_cast(heap_info_ptr) + sizeof(Detail::MM_INFORMATION_BLOCK); heap_info_ptr->fPage = No; @@ -140,8 +141,8 @@ _Output VoidPtr mm_new_heap(SizeT sz, Bool wr, Bool user, SizeT pad_amount) { auto result = reinterpret_cast(heap_info_ptr->fOffset); - (Void)(kout << "Registered heap address: " << hex_number(reinterpret_cast(heap_info_ptr)) - << kendl); + (Void)(kout << "MemoryMgr: Registered heap address: " + << hex_number(reinterpret_cast(heap_info_ptr)) << kendl); return result; } @@ -150,7 +151,7 @@ _Output VoidPtr mm_new_heap(SizeT sz, Bool wr, Bool user, SizeT pad_amount) { /// @param heap_ptr the pointer to make a page heap. /// @return kErrorSuccess if successful, otherwise an error code. _Output Int32 mm_make_page(VoidPtr heap_ptr) { - if (Detail::mm_check_heap_address(heap_ptr) == No) return kErrorHeapNotPresent; + if (Detail::mm_check_ptr_address(heap_ptr) == No) return kErrorHeapNotPresent; Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = reinterpret_cast((UIntPtr) heap_ptr - @@ -160,8 +161,8 @@ _Output Int32 mm_make_page(VoidPtr heap_ptr) { heap_info_ptr->fPage = true; - (Void)(kout << "Registered page address: " << hex_number(reinterpret_cast(heap_info_ptr)) - << kendl); + (Void)(kout << "MemoryMgr: Registered page from heap address: " + << hex_number(reinterpret_cast(heap_info_ptr)) << kendl); return kErrorSuccess; } @@ -169,8 +170,8 @@ _Output Int32 mm_make_page(VoidPtr heap_ptr) { /// @brief Overwrites and set the flags of a heap header. /// @param heap_ptr the pointer to update. /// @param flags the flags to set. -_Output Int32 mm_make_flags(VoidPtr heap_ptr, UInt64 flags) { - if (Detail::mm_check_heap_address(heap_ptr) == No) return kErrorHeapNotPresent; +_Output Int32 mm_make_ptr_flags(VoidPtr heap_ptr, UInt64 flags) { + if (Detail::mm_check_ptr_address(heap_ptr) == No) return kErrorHeapNotPresent; Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = reinterpret_cast((UIntPtr) heap_ptr - @@ -185,7 +186,7 @@ _Output Int32 mm_make_flags(VoidPtr heap_ptr, UInt64 flags) { /// @brief Gets the flags of a heap header. /// @param heap_ptr the pointer to get. -_Output UInt64 mm_get_flags(VoidPtr heap_ptr) { +_Output UInt64 mm_get_ptr_flags(VoidPtr heap_ptr) { Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = reinterpret_cast((UIntPtr) heap_ptr - sizeof(Detail::MM_INFORMATION_BLOCK)); @@ -198,8 +199,8 @@ _Output UInt64 mm_get_flags(VoidPtr heap_ptr) { /// @brief Declare pointer as free. /// @param heap_ptr the pointer. /// @return -_Output Int32 mm_delete_heap(VoidPtr heap_ptr) { - if (Detail::mm_check_heap_address(heap_ptr) == No) return kErrorHeapNotPresent; +_Output Int32 mm_delete_ptr(VoidPtr heap_ptr) { + if (Detail::mm_check_ptr_address(heap_ptr) == No) return kErrorHeapNotPresent; Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = reinterpret_cast((UIntPtr) (heap_ptr) - @@ -219,16 +220,16 @@ _Output Int32 mm_delete_heap(VoidPtr heap_ptr) { heap_info_ptr->fMagic = 0; heap_info_ptr->fPad = 0; - (Void)(kout << "Freed heap address: " << hex_number(reinterpret_cast(heap_info_ptr)) - << kendl); + (Void)(kout << "MemoryMgr: Freed heap address: " + << hex_number(reinterpret_cast(heap_info_ptr)) << kendl); PTEWrapper page_wrapper( No, No, No, reinterpret_cast(heap_info_ptr) - sizeof(Detail::MM_INFORMATION_BLOCK)); + Ref pte_address{page_wrapper}; - PageMgr page_mgr; - page_mgr.Free(pte_address); + kPageMgr.Free(pte_address); return kErrorSuccess; } @@ -239,7 +240,7 @@ _Output Int32 mm_delete_heap(VoidPtr heap_ptr) { /// @brief Check if pointer is a valid Kernel pointer. /// @param heap_ptr the pointer /// @return if it exists. -_Output Boolean mm_is_valid_heap(VoidPtr heap_ptr) { +_Output Boolean mm_is_valid_ptr(VoidPtr heap_ptr) { if (heap_ptr && HAL::mm_is_bitmap(heap_ptr)) { Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = reinterpret_cast((UIntPtr) (heap_ptr) - @@ -254,7 +255,7 @@ _Output Boolean mm_is_valid_heap(VoidPtr heap_ptr) { /// @brief Protect the heap with a CRC value. /// @param heap_ptr HIB pointer. /// @return if it valid: point has crc now., otherwise fail. -_Output Boolean mm_protect_heap(VoidPtr heap_ptr) { +_Output Boolean mm_protect_ptr(VoidPtr heap_ptr) { if (heap_ptr) { Detail::MM_INFORMATION_BLOCK_PTR heap_info_ptr = reinterpret_cast((UIntPtr) heap_ptr - diff --git a/dev/kernel/src/New+Delete.cc b/dev/kernel/src/New+Delete.cc index 96e7ab64..a6bde691 100644 --- a/dev/kernel/src/New+Delete.cc +++ b/dev/kernel/src/New+Delete.cc @@ -10,25 +10,25 @@ void* operator new[](size_t sz) { if (sz == 0) ++sz; - return Kernel::mm_new_heap(sz, true, false); + return Kernel::mm_new_ptr(sz, true, false); } void* operator new(size_t sz) { if (sz == 0) ++sz; - return Kernel::mm_new_heap(sz, true, false); + return Kernel::mm_new_ptr(sz, true, false); } void operator delete[](void* ptr) { if (ptr == nullptr) return; - Kernel::mm_delete_heap(ptr); + Kernel::mm_delete_ptr(ptr); } void operator delete(void* ptr) { if (ptr == nullptr) return; - Kernel::mm_delete_heap(ptr); + Kernel::mm_delete_ptr(ptr); } void operator delete(void* ptr, size_t sz) { @@ -36,7 +36,7 @@ void operator delete(void* ptr, size_t sz) { NE_UNUSED(sz); - Kernel::mm_delete_heap(ptr); + Kernel::mm_delete_ptr(ptr); } void operator delete[](void* ptr, size_t sz) { @@ -44,5 +44,5 @@ void operator delete[](void* ptr, size_t sz) { NE_UNUSED(sz); - Kernel::mm_delete_heap(ptr); + Kernel::mm_delete_ptr(ptr); } diff --git a/dev/kernel/src/PEFCodeMgr.cc b/dev/kernel/src/PEFCodeMgr.cc index 09a262d4..5ff54098 100644 --- a/dev/kernel/src/PEFCodeMgr.cc +++ b/dev/kernel/src/PEFCodeMgr.cc @@ -78,7 +78,7 @@ PEFLoader::PEFLoader(const Char* path) : fCachedBlob(nullptr), fFatBinary(false) fBad = true; - if (fCachedBlob) mm_delete_heap(fCachedBlob); + if (fCachedBlob) mm_delete_ptr(fCachedBlob); kout << "PEFLoader: Warning: Executable format error!\r"; @@ -89,7 +89,7 @@ PEFLoader::PEFLoader(const Char* path) : fCachedBlob(nullptr), fFatBinary(false) /// @brief PEF destructor. /***********************************************************************************/ PEFLoader::~PEFLoader() { - if (fCachedBlob) mm_delete_heap(fCachedBlob); + if (fCachedBlob) mm_delete_ptr(fCachedBlob); fFile.Delete(); } @@ -147,7 +147,7 @@ ErrorOr PEFLoader::FindSymbol(const Char* name, Int32 kind) { if (container_header->Kind == kind) { if (container_header->Cpu != Detail::ldr_get_platform()) { if (!this->fFatBinary) { - mm_delete_heap(blob); + mm_delete_ptr(blob); return ErrorOr{kErrorInvalidData}; } } @@ -156,7 +156,7 @@ ErrorOr PEFLoader::FindSymbol(const Char* name, Int32 kind) { rt_copy_memory((VoidPtr) ((Char*) blob + sizeof(PEFCommandHeader)), container_blob_value, container_header->Size); - mm_delete_heap(blob); + mm_delete_ptr(blob); kout << "PEFLoader: Information: Loaded stub: " << container_header->Name << "!\r"; @@ -165,7 +165,7 @@ ErrorOr PEFLoader::FindSymbol(const Char* name, Int32 kind) { HAL::kMMFlagsPresent | HAL::kMMFlagsUser); if (ret != kErrorSuccess) { - mm_delete_heap(container_blob_value); + mm_delete_ptr(container_blob_value); return ErrorOr{kErrorInvalidData}; } @@ -174,7 +174,7 @@ ErrorOr PEFLoader::FindSymbol(const Char* name, Int32 kind) { } } - mm_delete_heap(blob); + mm_delete_ptr(blob); return ErrorOr{kErrorInvalidData}; } @@ -236,7 +236,7 @@ namespace Utils { UserProcessScheduler::The().Spawn(reinterpret_cast(symname.Leak().Leak()), errOrStart.Leak().Leak(), exec.GetBlob().Leak().Leak()); - mm_delete_heap(symname.Leak().Leak()); + mm_delete_ptr(symname.Leak().Leak()); if (id != kSchedInvalidPID) { auto stacksym = exec.FindSymbol(kPefStackSizeSymbol, kPefData); @@ -253,7 +253,7 @@ namespace Utils { UserProcessScheduler::The().CurrentTeam().AsArray()[id].StackSize = *(UIntPtr*) stacksym.Leak().Leak(); - mm_delete_heap(stacksym.Leak().Leak()); + mm_delete_ptr(stacksym.Leak().Leak()); } return id; diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index f868a810..e44cbed4 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -25,14 +25,14 @@ ///! BUGS: 0 namespace Kernel { +EXTERN_C Void sched_jump_to_task(HAL::StackFramePtr stack_frame); + /***********************************************************************************/ /// @brief Exit Code global variable. /***********************************************************************************/ STATIC UInt32 kLastExitCode = 0U; -STATIC BOOL kCurrentlySwitching = No; - /***********************************************************************************/ /// @brief Scheduler itself. /***********************************************************************************/ @@ -101,7 +101,7 @@ Void USER_PROCESS::Wake(Bool should_wakeup) { /** @param tree The tree to calibrate */ /***********************************************************************************/ -STATIC PROCESS_HEAP_TREE* sched_try_go_upper_heap_tree(PROCESS_HEAP_TREE* tree) { +STATIC PROCESS_HEAP_TREE* sched_try_go_upper_ptr_tree(PROCESS_HEAP_TREE* tree) { if (!tree) { return nullptr; } @@ -132,11 +132,11 @@ ErrorOr USER_PROCESS::New(SizeT sz, SizeT pad_amount) { auto vm_register = kKernelCR3; hal_write_cr3(this->VMRegister); - auto ptr = mm_new_heap(sz, Yes, Yes, pad_amount); + auto ptr = mm_new_ptr(sz, Yes, Yes, pad_amount); hal_write_cr3(vm_register); #else - auto ptr = mm_new_heap(sz, Yes, Yes, pad_amount); + auto ptr = mm_new_ptr(sz, Yes, Yes, pad_amount); #endif if (!this->HeapTree) { @@ -173,7 +173,7 @@ ErrorOr USER_PROCESS::New(SizeT sz, SizeT pad_amount) { is_parent = NO; entry = entry->Next; } else { - entry = sched_try_go_upper_heap_tree(entry); + entry = sched_try_go_upper_ptr_tree(entry); if (entry && entry->Color == kBlackTreeKind) break; } } @@ -240,20 +240,20 @@ const AffinityKind& USER_PROCESS::GetAffinity() noexcept { /** @brief Free heap tree. */ /***********************************************************************************/ -STATIC Void sched_free_heap_tree(PROCESS_HEAP_TREE* memory_heap_list) { +STATIC Void sched_free_ptr_tree(PROCESS_HEAP_TREE* memory_ptr_list) { // Deleting memory lists. Make sure to free all of them. - while (memory_heap_list) { - if (memory_heap_list->Entry) { - MUST_PASS(mm_delete_heap(memory_heap_list->Entry)); + while (memory_ptr_list) { + if (memory_ptr_list->Entry) { + MUST_PASS(mm_delete_ptr(memory_ptr_list->Entry)); } - auto next = memory_heap_list->Next; + auto next = memory_ptr_list->Next; - mm_delete_heap(memory_heap_list); + mm_delete_ptr(memory_ptr_list); - if (memory_heap_list->Child) sched_free_heap_tree(memory_heap_list->Child); + if (memory_ptr_list->Child) sched_free_ptr_tree(memory_ptr_list->Child); - memory_heap_list = next; + memory_ptr_list = next; } } @@ -270,14 +270,14 @@ Void USER_PROCESS::Exit(const Int32& exit_code) { kLastExitCode = exit_code; - auto memory_heap_list = this->HeapTree; + auto memory_ptr_list = this->HeapTree; #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ auto pd = kKernelCR3; hal_write_cr3(this->VMRegister); #endif - sched_free_heap_tree(memory_heap_list); + sched_free_ptr_tree(memory_ptr_list); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ hal_write_cr3(pd); @@ -289,24 +289,19 @@ Void USER_PROCESS::Exit(const Int32& exit_code) { #endif //! Delete image if not done already. - if (this->Image.fCode && mm_is_valid_heap(this->Image.fCode)) mm_delete_heap(this->Image.fCode); + if (this->Image.fCode && mm_is_valid_ptr(this->Image.fCode)) mm_delete_ptr(this->Image.fCode); //! Delete blob too. - if (this->Image.fBlob && mm_is_valid_heap(this->Image.fBlob)) mm_delete_heap(this->Image.fBlob); + if (this->Image.fBlob && mm_is_valid_ptr(this->Image.fBlob)) mm_delete_ptr(this->Image.fBlob); //! Delete stack frame. - if (this->StackFrame && mm_is_valid_heap(this->StackFrame)) - mm_delete_heap((VoidPtr) this->StackFrame); - - //! Delete stack reserve. - if (this->StackReserve && mm_is_valid_heap(this->StackReserve)) - mm_delete_heap(reinterpret_cast(this->StackReserve)); + if (this->StackFrame && mm_is_valid_ptr(this->StackFrame)) + mm_delete_ptr((VoidPtr) this->StackFrame); //! Avoid use after free. - this->Image.fBlob = nullptr; - this->Image.fCode = nullptr; - this->StackFrame = nullptr; - this->StackReserve = nullptr; + this->Image.fBlob = nullptr; + this->Image.fCode = nullptr; + this->StackFrame = nullptr; if (this->Kind == kExecutableDylibKind) { Bool success = false; @@ -326,6 +321,34 @@ Void USER_PROCESS::Exit(const Int32& exit_code) { --this->ParentTeam->mProcessCount; } +/***********************************************************************************/ +/// @brief Add dylib to process. +/***********************************************************************************/ + +Bool USER_PROCESS::SpawnDylib() { + // React according to process kind. + switch (this->Kind) { + case USER_PROCESS::kExecutableDylibKind: { + this->DylibDelegate = rtl_init_dylib_pef(*this); + + if (!this->DylibDelegate) { + this->Crash(); + return NO; + } + + return YES; + } + case USER_PROCESS::kExecutableKind: { + return NO; + } + default: { + (Void)(kout << "Unknown process kind: " << hex_number(this->Kind) << kendl); + this->Crash(); + return NO; + } + } +} + /***********************************************************************************/ /// @brief Add process to team. /// @param process the process *Ref* class. @@ -363,18 +386,9 @@ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr im rt_copy_memory(reinterpret_cast(const_cast(name)), process.Name, len); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - process.VMRegister = new PDE(); - - if (!process.VMRegister) { - process.Crash(); - return -kErrorProcessFault; - } - - UInt32 flags = HAL::kMMFlagsPresent; - flags |= HAL::kMMFlagsWr; - flags |= HAL::kMMFlagsUser; - - HAL::mm_map_page((VoidPtr) process.VMRegister, process.VMRegister, flags); + process.VMRegister = kKernelCR3; +#else + process.VMRegister = 0UL; #endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ process.StackFrame = new HAL::StackFrame(); @@ -386,52 +400,17 @@ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr im rt_set_memory(process.StackFrame, 0, sizeof(HAL::StackFrame)); -#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - flags = HAL::kMMFlagsPresent; - flags |= HAL::kMMFlagsWr; - flags |= HAL::kMMFlagsUser; + process.StackFrame->BP = reinterpret_cast(code); - HAL::mm_map_page((VoidPtr) process.StackFrame, process.StackFrame, flags); -#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - - // React according to process kind. - switch (process.Kind) { - case USER_PROCESS::kExecutableDylibKind: { - process.DylibDelegate = rtl_init_dylib_pef(process); - MUST_PASS(process.DylibDelegate); - break; - } - case USER_PROCESS::kExecutableKind: { - break; - } - default: { - (Void)(kout << "Unknown process kind: " << hex_number(process.Kind) << kendl); - break; - } - } - - process.StackReserve = new UInt8[process.StackSize]; - - if (!process.StackReserve) { - process.Crash(); - return -kErrorProcessFault; - } + process.StackSize = kSchedMaxStackSz; rt_set_memory(process.StackReserve, 0, process.StackSize); -#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - flags = HAL::kMMFlagsPresent; - flags |= HAL::kMMFlagsWr; - flags |= HAL::kMMFlagsUser; - - HAL::mm_map_page((VoidPtr) process.StackReserve, process.StackReserve, flags); -#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - process.ParentTeam = &mTeam; process.ProcessId = pid; - process.Status = ProcessStatusKind::kStarting; - process.PTime = (UIntPtr) AffinityKind::kStandard; + process.Status = ProcessStatusKind::kRunning; + process.PTime = 0; process.RTime = 0; (Void)(kout << "PID: " << number(process.ProcessId) << kendl); @@ -498,10 +477,6 @@ SizeT UserProcessScheduler::Run() noexcept { return 0UL; } - if (kCurrentlySwitching) return 0UL; - - kCurrentlySwitching = Yes; - SizeT process_index = 0UL; //! we store this guy to tell the scheduler how many //! things we have scheduled. @@ -516,53 +491,38 @@ SizeT UserProcessScheduler::Run() noexcept { continue; } - // Set current process header. + kout << "The process: " << process.Name << " is being scheduled to run...\r"; + this->CurrentProcess() = process; process.PTime = static_cast(process.Affinity); + process.RTime = 0UL; - // tell helper to find a core to schedule on. - BOOL ret = UserProcessHelper::Switch(process.Image.Leak().Leak().Leak(), - &process.StackReserve[process.StackSize - 1], - process.StackFrame, process.ProcessId); - - if (!ret) { - kout << "The process: " << process.Name << ", is not valid! Crashing it...\r"; - process.Crash(); + // tell helper to find a core to schedule on, otherwise run on this core directly. + if (!UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { + sched_jump_to_task(process.StackFrame); } - } else { - if (process.ProcessId == this->CurrentProcess().Leak().ProcessId) { + + if (process.ProcessId == this->CurrentProcess().Leak().ProcessId && + process.PTime > (Int32) AffinityKind::kStandard) { if (process.PTime < process.RTime) { - if (process.RTime < (Int32) AffinityKind::kRealTime) - process.PTime = (Int32) AffinityKind::kVeryLowUsage; - else if (process.RTime < (Int32) AffinityKind::kVeryHigh) + if (process.RTime < (Int32) AffinityKind::kVeryHigh) process.PTime = (Int32) AffinityKind::kLowUsage; else if (process.RTime < (Int32) AffinityKind::kHigh) process.PTime = (Int32) AffinityKind::kStandard; else if (process.RTime < (Int32) AffinityKind::kStandard) process.PTime = (Int32) AffinityKind::kHigh; - process.RTime = static_cast(process.Affinity); - - BOOL ret = UserProcessHelper::Switch(process.Image.Leak().Leak().Leak(), - &process.StackReserve[process.StackSize - 1], - process.StackFrame, process.ProcessId); - - if (!ret) { - kout << "The process: " << process.Name << ", is not valid! Crashing it...\r"; - process.Crash(); - } + process.RTime = 0UL; } else { ++process.RTime; } } - + } else { --process.PTime; } } - kCurrentlySwitching = No; - return process_index; } @@ -582,8 +542,6 @@ UserProcessTeam& UserProcessScheduler::CurrentTeam() { BOOL UserProcessScheduler::SwitchTeam(UserProcessTeam& team) { if (team.AsArray().Count() < 1) return No; - if (kCurrentlySwitching) return No; - kScheduler.mTeam = team; return Yes; @@ -617,8 +575,6 @@ Bool UserProcessHelper::CanBeScheduled(const USER_PROCESS& process) { if (process.Status == ProcessStatusKind::kInvalid) return No; - if (!process.Image.HasCode()) return No; - if (!process.Name[0]) return No; // real time processes shouldn't wait that much. @@ -645,8 +601,7 @@ SizeT UserProcessHelper::StartScheduling() { */ /***********************************************************************************/ -Bool UserProcessHelper::Switch(VoidPtr image, UInt8* stack, HAL::StackFramePtr frame_ptr, - PID new_pid) { +Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { for (SizeT index = 0UL; index < HardwareThreadScheduler::The().Capacity(); ++index) { if (HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPInvalid || HardwareThreadScheduler::The()[index].Leak()->Kind() == kAPBoot) @@ -658,13 +613,13 @@ Bool UserProcessHelper::Switch(VoidPtr image, UInt8* stack, HAL::StackFramePtr f AffinityKind::kRealTime) continue; - if (HardwareThreadScheduler::The()[index].Leak()->Switch(image, stack, frame_ptr, new_pid)) { + if (HardwareThreadScheduler::The()[index].Leak()->Switch(frame_ptr, new_pid)) { HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].PTime; UserProcessHelper::TheCurrentPID().Leak().Leak() = UserProcessHelper::TheCurrentPID(); - return YES; + break; } continue; @@ -678,8 +633,7 @@ Bool UserProcessHelper::Switch(VoidPtr image, UInt8* stack, HAL::StackFramePtr f /// Prepare task switch. /// //////////////////////////////////////////////////////////// - Bool ret = - HardwareThreadScheduler::The()[index].Leak()->Switch(image, stack, frame_ptr, new_pid); + Bool ret = HardwareThreadScheduler::The()[index].Leak()->Switch(frame_ptr, new_pid); //////////////////////////////////////////////////////////// /// Rollback on fail. /// @@ -693,10 +647,10 @@ Bool UserProcessHelper::Switch(VoidPtr image, UInt8* stack, HAL::StackFramePtr f UserProcessScheduler::The().CurrentTeam().AsArray()[new_pid].PTime; HardwareThreadScheduler::The()[index].Leak()->Wake(YES); - return Yes; + return YES; } - return No; + return NO; } //////////////////////////////////////////////////////////// -- cgit v1.2.3 From d126ebf73370fbc64913aa6ff19db56a39f625b2 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 15 May 2025 18:42:59 +0200 Subject: feat(kernel): pushing the fixes regarding the scheduler, and working on making the LAPIC work correctly. Signed-off-by: Amlal El Mahrouss --- dev/boot/amd64-desktop.make | 2 +- dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 69 +++++++++++++++------- dev/kernel/HALKit/AMD64/HalCommonAPI.asm | 30 +++++++++- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 12 +--- dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 15 +---- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 31 +++++----- dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc | 5 ++ .../AMD64/HalSchedulerCorePrimitivesAMD64.cc | 2 +- dev/kernel/HALKit/AMD64/Processor.h | 31 ++++------ .../ARM64/HalSchedulerCorePrimitivesARM64.cc | 2 +- dev/kernel/HALKit/ARM64/Processor.h | 22 +++---- dev/kernel/HALKit/POWER/HalApplicationProcessor.cc | 2 +- dev/kernel/HALKit/POWER/Processor.h | 2 +- dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc | 2 +- dev/kernel/src/UserProcessScheduler.cc | 47 ++++++++------- 15 files changed, 151 insertions(+), 123 deletions(-) (limited to 'dev/kernel/HALKit/AMD64/HalInterruptAPI.asm') diff --git a/dev/boot/amd64-desktop.make b/dev/boot/amd64-desktop.make index 7687e3c6..8c227ebf 100644 --- a/dev/boot/amd64-desktop.make +++ b/dev/boot/amd64-desktop.make @@ -117,7 +117,7 @@ compile-amd64: .PHONY: run-efi-amd64-ahci run-efi-amd64-ahci: - $(EMU) $(EMU_FLAGS) -serial stdio -hda $(IMG) -s -S -boot menu=on + $(EMU) $(EMU_FLAGS) -monitor stdio -hda $(IMG) -s -S -boot menu=on .PHONY: run-efi-amd64-ata-pio run-efi-amd64-ata-pio: diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index 84c52768..d049a74d 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -14,16 +14,21 @@ #include #include -#define kAPIC_Signature "APIC" +#define APIC_Signature "APIC" -#define kAPIC_ICR_Low 0x300 -#define kAPIC_ICR_High 0x310 -#define kAPIC_SIPI_Vector 0x00500 -#define kAPIC_EIPI_Vector 0x00400 +#define APIC_ICR_Low 0x300 +#define APIC_ICR_High 0x310 +#define APIC_SIPI_Vector 0x00500 +#define APIC_EIPI_Vector 0x00400 -#define kAPIC_BASE_MSR 0x1B -#define kAPIC_BASE_MSR_BSP 0x100 -#define kAPIC_BASE_MSR_ENABLE 0x800 +#define LAPIC_REG_TIMER_LVT 0x320 +#define LAPIC_REG_TIMER_INITCNT 0x380 +#define LAPIC_REG_TIMER_CURRCNT 0x390 +#define LAPIC_REG_TIMER_DIV 0x3E0 + +#define APIC_BASE_MSR 0x1B +#define APIC_BASE_MSR_BSP 0x100 +#define APIC_BASE_MSR_ENABLE 0x800 /// @note: _hal_switch_context is internal @@ -47,7 +52,7 @@ STATIC HAL_APIC_MADT* kMADTBlock = nullptr; STATIC Bool kSMPAware = false; STATIC Int64 kSMPCount = 0; -STATIC UIntPtr kApicBaseAddress = 0UL; +EXTERN_C UIntPtr kApicBaseAddress = 0UL; STATIC Int32 kSMPInterrupt = 0; STATIC UInt64 kAPICLocales[kSchedProcessLimitPerTeam] = {0}; @@ -109,10 +114,10 @@ struct HAL_APIC_MADT final SDT_OBJECT { /***********************************************************************************/ Void hal_send_start_ipi(UInt32 target, UInt32 apic_id) { - Kernel::ke_dma_write(target, kAPIC_ICR_High, apic_id << 24); - Kernel::ke_dma_write(target, kAPIC_ICR_Low, 0x00000500 | 0x00004000 | 0x00000000); + Kernel::ke_dma_write(target, APIC_ICR_High, apic_id << 24); + Kernel::ke_dma_write(target, APIC_ICR_Low, 0x00000500 | 0x00004000 | 0x00000000); - while (Kernel::ke_dma_read(target, kAPIC_ICR_Low) & 0x1000) { + while (Kernel::ke_dma_read(target, APIC_ICR_Low) & 0x1000) { ; } } @@ -125,11 +130,10 @@ Void hal_send_start_ipi(UInt32 target, UInt32 apic_id) { /// @return /***********************************************************************************/ Void hal_send_sipi(UInt32 target, UInt32 apic_id, UInt8 vector) { - Kernel::ke_dma_write(target, kAPIC_ICR_High, apic_id << 24); - Kernel::ke_dma_write(target, kAPIC_ICR_Low, - 0x00000600 | 0x00004000 | 0x00000000 | vector); + Kernel::ke_dma_write(target, APIC_ICR_High, apic_id << 24); + Kernel::ke_dma_write(target, APIC_ICR_Low, 0x00000600 | 0x00004000 | 0x00000000 | vector); - while (Kernel::ke_dma_read(target, kAPIC_ICR_Low) & 0x1000) { + while (Kernel::ke_dma_read(target, APIC_ICR_Low) & 0x1000) { NE_UNUSED(0); } } @@ -192,7 +196,7 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { } auto hw_and_pow_int = PowerFactoryInterface(vendor_ptr); - kRawMADT = hw_and_pow_int.Find(kAPIC_Signature).Leak().Leak(); + kRawMADT = hw_and_pow_int.Find(APIC_Signature).Leak().Leak(); kMADTBlock = reinterpret_cast(kRawMADT); kSMPAware = NO; @@ -203,7 +207,31 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { kSMPInterrupt = 0; kSMPCount = 0; - kApicBaseAddress = kMADTBlock->Address; + UInt32 lo = 0, hi = 0; + hal_get_msr(0x1B, &lo, &hi); + UInt64 apic_base = ((UInt64) hi << 32) | lo; + + apic_base |= 0x800; // enable bit + + lo = apic_base & 0xFFFFFFFF; + hi = apic_base >> 32; + + hal_set_msr(0x1B, lo, hi); + + kApicBaseAddress = apic_base & 0xFFFFF000; + + // Allow LAPIC to forward interrupts (TPR = 0) + *(volatile UInt32*) (kApicBaseAddress + 0x80) = 0; + + // Set Spurious Interrupt Vector and enable LAPIC (bit 8) + *(volatile UInt32*) (kApicBaseAddress + 0xF0) = 0x1FF; // vector = 0xFF, enable bit = 1 << 8 + + // LAPIC timer setup + *(volatile UInt32*) (kApicBaseAddress + LAPIC_REG_TIMER_DIV) = 0b0011; // Divide by 16 + *(volatile UInt32*) (kApicBaseAddress + LAPIC_REG_TIMER_LVT) = + 32 | (1 << 17); // Vector 32, periodic + *(volatile UInt32*) (kApicBaseAddress + LAPIC_REG_TIMER_INITCNT) = + 1000000; // Init count (e.g., ~100Hz) constexpr const auto kSMPCountMax = kMaxAPInsideSched; @@ -224,10 +252,7 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { ++index; } - // Kernel is now SMP aware. - // That means that the scheduler is now available (on MP Kernels) - - kSMPAware = true; + kSMPAware = kSMPCount > 1; } } } // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/HalCommonAPI.asm b/dev/kernel/HALKit/AMD64/HalCommonAPI.asm index c1dfc66a..432f79d3 100644 --- a/dev/kernel/HALKit/AMD64/HalCommonAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalCommonAPI.asm @@ -79,4 +79,32 @@ mp_system_call_handler: o64 sysret -[bits 16] + +section .text + +global sched_jump_to_task + +;; Jump to the task from its stack frame. +sched_jump_to_task: + push rbp + mov rbp, rsp + + mov r8, [rcx + 0x10] + mov r9, [rcx + 0x18] + mov r10, [rcx + 0x20] + mov r11, [rcx + 0x28] + mov r12, [rcx + 0x30] + mov r13, [rcx + 0x38] + mov r14, [rcx + 0x40] + mov r15, [rcx + 0x48] + + mov rax, [rcx + 0x00] + mov rsp, [rcx + 0x08] ; SP + + jmp rax + +global rtl_ne_task + +rtl_ne_task: + jmp $ + ret \ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 1e513e3f..2c2bf5ff 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -11,6 +11,8 @@ STATIC BOOL kIsScheduling = NO; +EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip); + /// @brief Handle GPF fault. /// @param rsp EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) { @@ -104,16 +106,6 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) { - (Void)(Kernel::kout << "Kernel: Kernel RIP: " << Kernel::hex_number(rip) << Kernel::kendl); - Kernel::kout << "Kernel: SIGTRAP\r"; - - kIsScheduling = NO; - - while (YES) - ; - } - kIsScheduling = NO; (Void)(Kernel::kout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << Kernel::kendl); diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index 0634b0ea..60a20b77 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -232,17 +232,15 @@ IntExp 30 IntNormal 31 [extern idt_handle_scheduler] +[extern kApicBaseAddress] __NE_INT_32: - cld - push rax mov rcx, rsp call idt_handle_scheduler pop rax - mov al, 0x20 - out 0x20, al + mov dword [kApicBaseAddress+0xB0], 0 o64 iret @@ -413,12 +411,3 @@ 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 b0ac076d..a535b4ac 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -103,14 +103,22 @@ 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 void rtl_ne_task(void); EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { + Kernel::rtl_create_user_process(rtl_ne_task, "NeTask"); + Kernel::rtl_create_user_process(rtl_ne_task, "NeTask#2"); + Kernel::rtl_create_user_process(rtl_ne_task, "NeTask#3"); + + Kernel::HAL::Register64 idt_reg; + idt_reg.Base = reinterpret_cast(kInterruptVectorTable); + + Kernel::HAL::IDTLoader idt_loader; + + idt_loader.Load(idt_reg); + + Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); + #ifdef __FSKIT_INCLUDES_HEFS__ if (!Kernel::HeFS::fs_init_hefs()) { // Fallback to NeFS, if HeFS doesn't work here. @@ -123,17 +131,6 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { } #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 = reinterpret_cast(kInterruptVectorTable); - - Kernel::HAL::IDTLoader idt_loader; - - idt_loader.Load(idt_reg); - while (YES) ; } diff --git a/dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc b/dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc index 66f27c24..2fc18e2f 100644 --- a/dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalProcessorAMD64.cc @@ -16,6 +16,11 @@ */ namespace Kernel::HAL { +Void hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept { + if (!lo || !hi) return; + asm volatile("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr)); +} + Void hal_set_msr(UInt32 msr, UInt32 lo, UInt32 hi) noexcept { asm volatile("wrmsr" : : "a"(lo), "d"(hi), "c"(msr)); } diff --git a/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc b/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc index 8f7ffdaf..0c468e14 100644 --- a/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalSchedulerCorePrimitivesAMD64.cc @@ -25,7 +25,7 @@ EXTERN_C Void __zka_pure_call(USER_PROCESS* process) { EXTERN_C Bool hal_check_stack(HAL::StackFramePtr stack_ptr) { if (!stack_ptr) return No; - return stack_ptr->SP != 0 && stack_ptr->BP != 0; + return stack_ptr->SP != 0 && stack_ptr->IP != 0; } /// @brief Wakes up thread. diff --git a/dev/kernel/HALKit/AMD64/Processor.h b/dev/kernel/HALKit/AMD64/Processor.h index e1ce8718..1b2e35f7 100644 --- a/dev/kernel/HALKit/AMD64/Processor.h +++ b/dev/kernel/HALKit/AMD64/Processor.h @@ -83,18 +83,17 @@ using Reg = RawRegister; using InterruptId = UInt16; /* For each element in the IVT */ /// @brief Stack frame (as retrieved from assembly.) -struct PACKED StackFrame final { - RawRegister R8{0}; - RawRegister R9{0}; - RawRegister R10{0}; - RawRegister FS{0}; - RawRegister R12{0}; - RawRegister R13{0}; - RawRegister R14{0}; - RawRegister R15{0}; - RawRegister GS{0}; - RawRegister SP{0}; - RawRegister BP{0}; +struct PACKED StackFrame { + Reg IP; + Reg SP; + Reg R8; + Reg R9; + Reg R10; + Reg R11; + Reg R12; + Reg R13; + Reg R14; + Reg R15; }; typedef StackFrame* StackFramePtr; @@ -187,13 +186,7 @@ UIntPtr mm_get_phys_address(VoidPtr virtual_address); /// @param lo low byte /// @param hi high byte /***********************************************************************************/ -inline UInt32 hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept { - if (!lo || !hi) return 0; - - asm volatile("rdmsr" : "=a"(*lo), "=d"(*hi) : "c"(msr)); - - return *lo + *hi; -} +Void hal_get_msr(UInt32 msr, UInt32* lo, UInt32* hi) noexcept; /// @brief Set Model-specific register. /// @param msr MSR diff --git a/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc b/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc index a8f0b1e1..ee286639 100644 --- a/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc +++ b/dev/kernel/HALKit/ARM64/HalSchedulerCorePrimitivesARM64.cc @@ -25,6 +25,6 @@ EXTERN_C Void __zka_pure_call(USER_PROCESS* process) { EXTERN_C Bool hal_check_stack(HAL::StackFramePtr stack_ptr) { if (!stack_ptr) return No; - return stack_ptr->SP != 0 && stack_ptr->BP != 0; + return stack_ptr->SP != 0 && stack_ptr->IP != 0; } } // namespace Kernel diff --git a/dev/kernel/HALKit/ARM64/Processor.h b/dev/kernel/HALKit/ARM64/Processor.h index 1d9d2af2..9f16d8f5 100644 --- a/dev/kernel/HALKit/ARM64/Processor.h +++ b/dev/kernel/HALKit/ARM64/Processor.h @@ -42,17 +42,17 @@ typedef UIntPtr Reg; typedef Register64 Register; /// @note let's keep the same name as AMD64 HAL. -struct PACKED StackFrame final { - Reg R8{0}; - Reg R9{0}; - Reg R10{0}; - Reg R11{0}; - Reg R12{0}; - Reg R13{0}; - Reg R14{0}; - Reg R15{0}; - Reg SP{0}; - Reg BP{0}; +struct PACKED StackFrame { + Reg IP; + Reg SP; + Reg R8; + Reg R9; + Reg R10; + Reg R11; + Reg R12; + Reg R13; + Reg R14; + Reg R15; }; typedef StackFrame* StackFramePtr; diff --git a/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc b/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc index 617b3dda..daa26e53 100644 --- a/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/POWER/HalApplicationProcessor.cc @@ -22,7 +22,7 @@ void mp_wakeup_thread(HAL::StackFramePtr stack) { if (!stack) return; hal_set_pc_to_hart(reinterpret_cast(stack->R15), - reinterpret_cast(stack->BP)); + reinterpret_cast(stack->IP)); } /// @brief makes thread sleep. diff --git a/dev/kernel/HALKit/POWER/Processor.h b/dev/kernel/HALKit/POWER/Processor.h index 850b636d..d50c4ff2 100644 --- a/dev/kernel/HALKit/POWER/Processor.h +++ b/dev/kernel/HALKit/POWER/Processor.h @@ -28,7 +28,7 @@ struct PACKED StackFrame final { Reg R14{0}; Reg R15{0}; Reg SP{0}; - Reg BP{0}; + Reg IP{0}; }; typedef StackFrame* StackFramePtr; diff --git a/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc b/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc index 80162b81..31d4a62e 100644 --- a/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/RISCV/HalApplicationProcessor.cc @@ -25,7 +25,7 @@ void mp_wakeup_thread(HAL::StackFramePtr stack) { if (!stack) return; hal_set_pc_to_hart(reinterpret_cast(stack->R15), - reinterpret_cast(stack->BP)); + reinterpret_cast(stack->IP)); } /// @brief makes thread sleep. diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index e44cbed4..54f8ca77 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -37,8 +37,6 @@ STATIC UInt32 kLastExitCode = 0U; /// @brief Scheduler itself. /***********************************************************************************/ -STATIC UserProcessScheduler kScheduler; - USER_PROCESS::USER_PROCESS() = default; USER_PROCESS::~USER_PROCESS() = default; @@ -400,7 +398,8 @@ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr im rt_set_memory(process.StackFrame, 0, sizeof(HAL::StackFrame)); - process.StackFrame->BP = reinterpret_cast(code); + process.StackFrame->IP = reinterpret_cast(code); + process.StackFrame->SP = reinterpret_cast(&process.StackReserve[0] + process.StackSize); process.StackSize = kSchedMaxStackSz; @@ -424,6 +423,7 @@ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr im /***********************************************************************************/ UserProcessScheduler& UserProcessScheduler::The() { + STATIC UserProcessScheduler kScheduler; return kScheduler; } @@ -491,7 +491,7 @@ SizeT UserProcessScheduler::Run() noexcept { continue; } - kout << "The process: " << process.Name << " is being scheduled to run...\r"; + kout << process.Name << " is being scheduled to run...\r"; this->CurrentProcess() = process; @@ -500,25 +500,24 @@ SizeT UserProcessScheduler::Run() noexcept { // tell helper to find a core to schedule on, otherwise run on this core directly. if (!UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { - sched_jump_to_task(process.StackFrame); - } - - if (process.ProcessId == this->CurrentProcess().Leak().ProcessId && - process.PTime > (Int32) AffinityKind::kStandard) { - if (process.PTime < process.RTime) { - if (process.RTime < (Int32) AffinityKind::kVeryHigh) - process.PTime = (Int32) AffinityKind::kLowUsage; - else if (process.RTime < (Int32) AffinityKind::kHigh) - process.PTime = (Int32) AffinityKind::kStandard; - else if (process.RTime < (Int32) AffinityKind::kStandard) - process.PTime = (Int32) AffinityKind::kHigh; - - process.RTime = 0UL; - } else { - ++process.RTime; + if (process.ProcessId == this->CurrentProcess().Leak().ProcessId && + process.PTime > (Int32) AffinityKind::kStandard) { + if (process.PTime < process.RTime) { + if (process.RTime < (Int32) AffinityKind::kVeryHigh) + process.PTime = (Int32) AffinityKind::kLowUsage; + else if (process.RTime < (Int32) AffinityKind::kHigh) + process.PTime = (Int32) AffinityKind::kStandard; + else if (process.RTime < (Int32) AffinityKind::kStandard) + process.PTime = (Int32) AffinityKind::kHigh; + + process.RTime = 0UL; + } else { + ++process.RTime; + } } } } else { + kout << process.Name << " won't be scheduled to run...\r"; --process.PTime; } } @@ -542,7 +541,7 @@ UserProcessTeam& UserProcessScheduler::CurrentTeam() { BOOL UserProcessScheduler::SwitchTeam(UserProcessTeam& team) { if (team.AsArray().Count() < 1) return No; - kScheduler.mTeam = team; + UserProcessScheduler::The().mTeam = team; return Yes; } @@ -556,10 +555,10 @@ Ref& UserProcessScheduler::CurrentProcess() { /// @brief Current proccess id getter. /// @return USER_PROCESS ID integer. ErrorOr UserProcessHelper::TheCurrentPID() { - if (!kScheduler.CurrentProcess()) return ErrorOr{-kErrorProcessFault}; + if (!UserProcessScheduler::The().CurrentProcess()) return ErrorOr{-kErrorProcessFault}; kout << "UserProcessHelper::TheCurrentPID: Leaking ProcessId...\r"; - return ErrorOr{kScheduler.CurrentProcess().Leak().ProcessId}; + return ErrorOr{UserProcessScheduler::The().CurrentProcess().Leak().ProcessId}; } /// @brief Check if process can be schedulded. @@ -590,7 +589,7 @@ Bool UserProcessHelper::CanBeScheduled(const USER_PROCESS& process) { /***********************************************************************************/ SizeT UserProcessHelper::StartScheduling() { - return kScheduler.Run(); + return UserProcessScheduler::The().Run(); } /***********************************************************************************/ -- cgit v1.2.3 From b55f22d6a4f85751e0054dbf17eefe438a21b048 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Thu, 15 May 2025 23:50:06 +0200 Subject: feat(kernel/sched): fixes and improvements on the scheduler's implementation. why? - The previous one wasn't entierly correct on some parts. Signed-off-by: Amlal El Mahrouss --- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 35 +++++++--------------- dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 10 +++---- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 6 ++-- dev/kernel/KernelKit/CoreProcessScheduler.h | 4 +-- dev/kernel/src/HardwareThreadScheduler.cc | 2 ++ dev/kernel/src/UserProcessScheduler.cc | 18 ++++++----- 6 files changed, 33 insertions(+), 42 deletions(-) (limited to 'dev/kernel/HALKit/AMD64/HalInterruptAPI.asm') diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 2c2bf5ff..ff283141 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -9,16 +9,12 @@ #include #include -STATIC BOOL kIsScheduling = NO; - EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip); /// @brief Handle GPF fault. /// @param rsp EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) { - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - - kIsScheduling = NO; + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); Kernel::kout << "Kernel: General Protection Fault.\r"; @@ -36,9 +32,7 @@ EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) { /// @brief Handle page fault. /// @param rsp EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - - kIsScheduling = NO; + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); Kernel::kout << "Kernel: Page Fault.\r"; Kernel::kout << "Kernel: SIGKILL\r"; @@ -55,20 +49,13 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { /// @brief Handle scheduler interrupt. EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) { NE_UNUSED(rsp); - - Kernel::kout << "Kernel: Scheduler interrupt.\r"; - - kIsScheduling = YES; Kernel::UserProcessHelper::StartScheduling(); - kIsScheduling = NO; } /// @brief Handle math fault. /// @param rsp EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - - kIsScheduling = NO; + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); Kernel::kout << "Kernel: Math error (division by zero?).\r"; @@ -86,11 +73,10 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { /// @brief Handle any generic fault. /// @param rsp EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - - kIsScheduling = NO; + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); - Kernel::kout << "Kernel: Generic Process Fault.\r"; + (Void)(Kernel::kout << "Kernel: Process RSP: " << Kernel::hex_number(rsp) << Kernel::kendl); + Kernel::kout << "Kernel: Access Process Fault.\r"; process.Leak().Signal.SignalArg = rsp; process.Leak().Signal.SignalID = SIGKILL; @@ -104,11 +90,10 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { } EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); - - kIsScheduling = NO; + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); (Void)(Kernel::kout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << Kernel::kendl); + Kernel::kout << "Kernel: SIGTRAP\r"; process.Leak().Signal.SignalArg = rip; @@ -124,9 +109,9 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { /// @brief Handle #UD fault. /// @param rsp EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { - auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); + NE_UNUSED(rsp); - kIsScheduling = NO; + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); Kernel::kout << "Kernel: Undefined Opcode.\r"; diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index 60a20b77..189b2976 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -164,7 +164,6 @@ __NE_INT_8: cld mov al, 0x20 - out 0xA0, al out 0x20, al push rcx @@ -185,7 +184,6 @@ __NE_INT_13: cld mov al, 0x20 - out 0xA0, al out 0x20, al push rcx @@ -200,7 +198,6 @@ __NE_INT_14: cld mov al, 0x20 - out 0xA0, al out 0x20, al push rcx @@ -235,13 +232,16 @@ IntNormal 31 [extern kApicBaseAddress] __NE_INT_32: + mov al, 0x20 + out 0x20, al + + mov dword [kApicBaseAddress+0xB0], 0 + push rax mov rcx, rsp call idt_handle_scheduler pop rax - mov dword [kApicBaseAddress+0xB0], 0 - o64 iret IntNormal 33 diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 722c9cb5..b7ff3038 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -106,9 +106,9 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { EXTERN_C void rtl_ne_task(void); EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { - Kernel::rtl_create_user_process(rtl_ne_task, "NeTask"); - Kernel::rtl_create_user_process(rtl_ne_task, "NeTask#2"); - Kernel::rtl_create_user_process(rtl_ne_task, "NeTask#3"); + Kernel::rtl_create_user_process(rtl_ne_task, "MGMTCTL"); + Kernel::rtl_create_user_process(rtl_ne_task, "LAUNCHCTL"); + Kernel::rtl_create_user_process(rtl_ne_task, "SECURITYCTL"); Kernel::HAL::Register64 idt_reg; idt_reg.Base = reinterpret_cast(kInterruptVectorTable); diff --git a/dev/kernel/KernelKit/CoreProcessScheduler.h b/dev/kernel/KernelKit/CoreProcessScheduler.h index f9d11459..6cb17261 100644 --- a/dev/kernel/KernelKit/CoreProcessScheduler.h +++ b/dev/kernel/KernelKit/CoreProcessScheduler.h @@ -128,8 +128,8 @@ enum class ProcessStatusKind : Int32 { //! @brief Affinity is the amount of nano-seconds this process is going to run. /***********************************************************************************/ enum class AffinityKind : Int32 { - kRealTime = 500, - kVeryHigh = 250, + kRealTime = 50, + kVeryHigh = 150, kHigh = 200, kStandard = 1000, kLowUsage = 1500, diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc index 1df5ad7a..6cb83b3d 100644 --- a/dev/kernel/src/HardwareThreadScheduler.cc +++ b/dev/kernel/src/HardwareThreadScheduler.cc @@ -105,6 +105,8 @@ Void HardwareThread::Wake(const bool wakeup) noexcept { /// @retval false stack is invalid, previous code is running. /***********************************************************************************/ Bool HardwareThread::Switch(HAL::StackFramePtr frame, const ThreadID& pid) { + if (this->IsBusy()) return NO; + this->fStack = frame; this->fPID = pid; diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 24869d63..fe1a95ae 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -491,7 +491,7 @@ SizeT UserProcessScheduler::Run() noexcept { continue; } - kout << process.Name << " is being scheduled to run...\r"; + kout << ((*process.Name) ? process.Name : "USER_PROCESS") << " will be scheduled...\r"; this->CurrentProcess() = process; @@ -499,17 +499,21 @@ SizeT UserProcessScheduler::Run() noexcept { if (process.PTime < process.RTime) { if (process.RTime < (Int32) AffinityKind::kVeryHigh) - process.PTime = (Int32) AffinityKind::kLowUsage; + process.RTime = (Int32) AffinityKind::kLowUsage; else if (process.RTime < (Int32) AffinityKind::kHigh) - process.PTime = (Int32) AffinityKind::kStandard; + process.RTime = (Int32) AffinityKind::kStandard; else if (process.RTime < (Int32) AffinityKind::kStandard) - process.PTime = (Int32) AffinityKind::kHigh; + process.RTime = (Int32) AffinityKind::kHigh; + + process.PTime += process.RTime; process.RTime = 0UL; - } else { - ++process.RTime; + } + + if (!UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { + continue; } } else { - kout << process.Name << " won't be scheduled to run...\r"; + ++process.RTime; --process.PTime; } } -- cgit v1.2.3 From 5b2ec031ab578caec8fbbdbe5350b9c0df493fd3 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Fri, 16 May 2025 09:51:24 +0200 Subject: feat(kernel/ap): Improved and fixed the AP boot flow, also made sure that the segment loading for the long mode stub works. TODO: - Stack pointer shall be set when jumping to AP routine. Signed-off-by: Amlal El Mahrouss --- dev/kernel/HALKit/AMD64/HalAPICController.cc | 38 ------ dev/kernel/HALKit/AMD64/HalAPICDmaWrapper.cc | 39 ++++++ dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 138 +++++++++------------ .../AMD64/HalApplicationProcessorStartup.asm | 14 +-- dev/kernel/HALKit/AMD64/HalBootHeader.asm | 32 ----- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 20 ++- dev/kernel/HALKit/AMD64/HalHandoverStub.asm | 30 +++++ dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 8 +- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 10 +- dev/kernel/HALKit/AMD64/Processor.h | 17 +-- dev/kernel/amd64-ci.make | 2 +- dev/kernel/amd64-desktop.make | 2 +- dev/kernel/src/UserProcessTeam.cc | 1 + 13 files changed, 176 insertions(+), 175 deletions(-) delete mode 100644 dev/kernel/HALKit/AMD64/HalAPICController.cc create mode 100644 dev/kernel/HALKit/AMD64/HalAPICDmaWrapper.cc delete mode 100644 dev/kernel/HALKit/AMD64/HalBootHeader.asm create mode 100644 dev/kernel/HALKit/AMD64/HalHandoverStub.asm (limited to 'dev/kernel/HALKit/AMD64/HalInterruptAPI.asm') diff --git a/dev/kernel/HALKit/AMD64/HalAPICController.cc b/dev/kernel/HALKit/AMD64/HalAPICController.cc deleted file mode 100644 index e547d982..00000000 --- a/dev/kernel/HALKit/AMD64/HalAPICController.cc +++ /dev/null @@ -1,38 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -#include -#include - -#define kIOAPICRegVal (4) -#define kIOAPICRegReg (0) - -namespace Kernel::HAL { -APICController::APICController(VoidPtr base) : fApic(base) {} - -/// @brief Read from APIC controller. -/// @param reg register. -UInt32 APICController::Read(UInt32 reg) noexcept { - MUST_PASS(this->fApic); - - UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic; - io_apic[kIOAPICRegReg] = (reg & 0xFF); - - return io_apic[kIOAPICRegVal]; -} - -/// @brief Write to APIC controller. -/// @param reg register. -/// @param value value. -Void APICController::Write(UInt32 reg, UInt32 value) noexcept { - MUST_PASS(this->fApic); - - UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic; - - io_apic[kIOAPICRegReg] = (reg & 0xFF); - io_apic[kIOAPICRegVal] = value; -} -} // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/HalAPICDmaWrapper.cc b/dev/kernel/HALKit/AMD64/HalAPICDmaWrapper.cc new file mode 100644 index 00000000..6aba5b0e --- /dev/null +++ b/dev/kernel/HALKit/AMD64/HalAPICDmaWrapper.cc @@ -0,0 +1,39 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#include +#include + +namespace Kernel::HAL { +/***********************************************************************************/ +/// Constructors. +/***********************************************************************************/ +LAPICDmaWrapper::LAPICDmaWrapper(VoidPtr base) : fApic(base) {} +LAPICDmaWrapper::~LAPICDmaWrapper() = default; + +/***********************************************************************************/ +/// @brief Read from APIC controller. +/// @param reg register. +/***********************************************************************************/ +UInt32 LAPICDmaWrapper::Read(UInt16 reg) noexcept { + MUST_PASS(this->fApic); + + UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic; + return io_apic[reg]; +} + +/***********************************************************************************/ +/// @brief Write to APIC controller. +/// @param reg register. +/// @param value value. +/***********************************************************************************/ +Void LAPICDmaWrapper::Write(UInt16 reg, UInt32 value) noexcept { + MUST_PASS(this->fApic); + + UInt32 volatile* io_apic = (UInt32 volatile*) this->fApic; + io_apic[reg] = value; +} +} // namespace Kernel::HAL diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index 46b376c0..98e96687 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -13,18 +13,23 @@ #include #include #include +#include "NewKit/Defines.h" #define APIC_Signature "APIC" -#define APIC_ICR_Low 0x300 -#define APIC_ICR_High 0x310 -#define APIC_SIPI_Vector 0x00500 -#define APIC_EIPI_Vector 0x00400 +#define AP_BLOB_SIZE 126 + +#define APIC_ICR_LOW 0x300 +#define APIC_ICR_HIGH 0x310 +#define APIC_SIPI_VEC 0x00500 +#define APIC_EIPI_VEC 0x00400 #define LAPIC_REG_TIMER_LVT 0x320 #define LAPIC_REG_TIMER_INITCNT 0x380 #define LAPIC_REG_TIMER_CURRCNT 0x390 #define LAPIC_REG_TIMER_DIV 0x3E0 +#define LAPIC_REG_ENABLE 0x80 +#define LAPIC_REG_SPURIOUS 0xF0 #define APIC_BASE_MSR 0x1B #define APIC_BASE_MSR_BSP 0x100 @@ -52,7 +57,7 @@ STATIC HAL_APIC_MADT* kMADTBlock = nullptr; STATIC Bool kSMPAware = false; STATIC Int64 kSMPCount = 0; -EXTERN_C UIntPtr kApicBaseAddress = 0UL; +EXTERN_C UIntPtr kApicBaseAddress; STATIC Int32 kSMPInterrupt = 0; STATIC UInt64 kAPICLocales[kSchedProcessLimitPerTeam] = {0}; @@ -61,46 +66,16 @@ STATIC VoidPtr kRawMADT = nullptr; /// @brief Multiple APIC Descriptor Table. struct HAL_APIC_MADT final SDT_OBJECT { UInt32 Address; // Madt address - UInt8 Flags; // Madt flags - - struct { - UInt8 Type; - UInt8 Len; - - union APIC { - struct IOAPIC { - UInt8 IoID; - UInt8 Zero; - UInt32 IoAddress; - UInt32 GISBase; - } IOAPIC; - - struct LAPIC_NMI { - UInt8 Source; - UInt8 IRQSource; - UInt32 GSI; - UInt16 Flags; - } LApicNMI; - - struct LAPIC { - UInt8 ProcessorID; - UInt16 Flags; - UInt8 LINT; - } LAPIC; - - struct LAPIC_OVERRIDE { - UInt16 Reserved; - UInt64 Address; - } LApicOverride; - - struct LAPIC_X2 { - UInt16 Reserved; - UInt32 x2APICID; - UInt32 Flags; - UInt32 AcpiID; - } LocalApicX2; - } Apic; - } List[1]; // Records List + UInt32 Flags; // Madt flags + UInt8 List[1]; // Records List +}; + +struct LAPIC final { + UInt8 Type; + UInt8 Length; + UInt8 ProcessorID; + UInt8 APICID; + UInt32 Flags; }; /////////////////////////////////////////////////////////////////////////////////////// @@ -114,10 +89,10 @@ struct HAL_APIC_MADT final SDT_OBJECT { /***********************************************************************************/ Void hal_send_start_ipi(UInt32 target, UInt32 apic_id) { - Kernel::ke_dma_write(target, APIC_ICR_High, apic_id << 24); - Kernel::ke_dma_write(target, APIC_ICR_Low, 0x00000500 | 0x00004000 | 0x00000000); + Kernel::ke_dma_write(target, APIC_ICR_HIGH, apic_id << 24); + Kernel::ke_dma_write(target, APIC_ICR_LOW, 0x00000500 | 0x00004000 | 0x00000000); - while (Kernel::ke_dma_read(target, APIC_ICR_Low) & 0x1000) { + while (Kernel::ke_dma_read(target, APIC_ICR_LOW) & 0x1000) { ; } } @@ -130,10 +105,10 @@ Void hal_send_start_ipi(UInt32 target, UInt32 apic_id) { /// @return /***********************************************************************************/ Void hal_send_sipi(UInt32 target, UInt32 apic_id, UInt8 vector) { - Kernel::ke_dma_write(target, APIC_ICR_High, apic_id << 24); - Kernel::ke_dma_write(target, APIC_ICR_Low, 0x00000600 | 0x00004000 | 0x00000000 | vector); + Kernel::ke_dma_write(target, APIC_ICR_HIGH, apic_id << 24); + Kernel::ke_dma_write(target, APIC_ICR_LOW, 0x00000600 | 0x00004000 | 0x00000000 | vector); - while (Kernel::ke_dma_read(target, APIC_ICR_Low) & 0x1000) { + while (Kernel::ke_dma_read(target, APIC_ICR_LOW) & 0x1000) { NE_UNUSED(0); } } @@ -202,8 +177,6 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { kSMPAware = NO; if (kMADTBlock) { - SizeT index = 0; - kSMPInterrupt = 0; kSMPCount = 0; @@ -221,39 +194,52 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { kApicBaseAddress = apic_base & 0xFFFFF000; - // Allow LAPIC to forward interrupts (TPR = 0) - *(volatile UInt32*) (kApicBaseAddress + 0x80) = 0; + LAPICDmaWrapper controller{(VoidPtr) kApicBaseAddress}; - // Set Spurious Interrupt Vector and enable LAPIC (bit 8) - *(volatile UInt32*) (kApicBaseAddress + 0xF0) = 0x1FF; // vector = 0xFF, enable bit = 1 << 8 + controller.Write(LAPIC_REG_ENABLE, 0); + controller.Write(LAPIC_REG_SPURIOUS, 0x1FF); // Enable bit, spurious interrupt vector register. + controller.Write(LAPIC_REG_TIMER_DIV, 0b0011); + controller.Write(LAPIC_REG_TIMER_LVT, 32 | (1 << 17)); + controller.Write(LAPIC_REG_TIMER_INITCNT, 1000000); - // LAPIC timer setup - *(volatile UInt32*) (kApicBaseAddress + LAPIC_REG_TIMER_DIV) = 0b0011; // Divide by 16 + const UIntPtr trampoline_phys = 0x8000; - *(volatile UInt32*) (kApicBaseAddress + LAPIC_REG_TIMER_LVT) = - 32 | (1 << 17); // Vector 32, periodic + HAL::mm_map_page((VoidPtr)trampoline_phys, (VoidPtr)trampoline_phys, HAL::kMMFlagsWr | HAL::kMMFlagsPresent); - *(volatile UInt32*) (kApicBaseAddress + LAPIC_REG_TIMER_INITCNT) = - 1000000; // Init count (e.g., ~100Hz) + const SizeT len = AP_BLOB_SIZE; /// AP blob size. - constexpr const auto kSMPCountMax = kMaxAPInsideSched; + rt_copy_memory(hal_ap_blob_start, reinterpret_cast(trampoline_phys), len); - while (Yes) { - // @note Don't probe greater than what the APMgr expects. - if (kSMPCount > kSMPCountMax) break; + volatile UInt8* entry_ptr = reinterpret_cast(kMADTBlock->List); + volatile UInt8* end_ptr = ((UInt8*) kMADTBlock) + kMADTBlock->Length; - /// @note Anything bigger than x2APIC type doesn't exist. - if (kMADTBlock->List[index].Type > 9) { - ++index; - continue; - } + while (entry_ptr < end_ptr) { + UInt8 type = *entry_ptr; + UInt8 length = *(entry_ptr + 1); - kAPICLocales[kSMPCount] = kMADTBlock->List[kSMPCount].Apic.LAPIC.ProcessorID; - (Void)(kout << "SMP: APIC ID: " << number(kAPICLocales[kSMPCount]) << kendl); + // Avoid infinite loop on bad APIC tables. + if (length < 2) break; - ++kSMPCount; + if (type == 0) { + volatile LAPIC* entry_struct = (volatile LAPIC*) entry_ptr; + + if (entry_struct->Flags & 0x1) { + kAPICLocales[kSMPCount] = entry_struct->ProcessorID; + ++kSMPCount; + + kout << "LAPIC type, also is on...\r"; + + hal_send_start_ipi(kApicBaseAddress, entry_struct->ProcessorID); + hal_send_sipi(kApicBaseAddress, entry_struct->ProcessorID, trampoline_phys >> 12); + + } else { + kout << "LAPIC type, also is not on...\r"; + } + } else { + kout << "Unknown APIC type...\r"; + } - ++index; + entry_ptr += length; } kSMPAware = kSMPCount > 1; diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm b/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm index 09a59e4f..181937ab 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessorStartup.asm @@ -10,7 +10,7 @@ ;; */ [bits 16] -[org 0x7c000] +[org 0x8000] hal_ap_start: mov ax, 0x0 @@ -61,19 +61,15 @@ hal_ap_64bit_entry: mov fs, ax mov gs, ax mov ss, ax - mov rsp, [hal_ap_64bit_entry_stack_end] + + mov rsp, rbx push 0x33 - push qword [hal_ap_64bit_entry_loop] + lea rax, [hal_ap_64bit_entry_loop] + push rax o64 pushf - push rsp - push 0x33 o64 iret hal_ap_64bit_entry_loop: jmp $ - -hal_ap_64bit_entry_stack: - times 8196*2 nop -hal_ap_64bit_entry_stack_end: \ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/HalBootHeader.asm b/dev/kernel/HALKit/AMD64/HalBootHeader.asm deleted file mode 100644 index 21f8621b..00000000 --- a/dev/kernel/HALKit/AMD64/HalBootHeader.asm +++ /dev/null @@ -1,32 +0,0 @@ -;; /* -;; * ======================================================== -;; * -;; * NeKernel -;; * Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. -;; * -;; * 25/03/25: Rename HalBootHeader.asm to HalBootHeader.asm, expose struct symbols; remove unused external symbol. -;; * -;; * ======================================================== -;; */ - -[bits 64] - -%define kTypeKernel 100 -%define kArchAmd64 122 -%define kHandoverMagic 0xBADCC - -global _HandoverMagic -global _HandoverType -global _HandoverPad -global _HandoverArch - -section .ldr - -_HandoverMagic: - dq kHandoverMagic -_HandoverType: - dw kTypeKernel -_HandoverPad: - dw 0 -_HandoverArch: - dw kArchAmd64 diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index ff283141..d5a40390 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -11,9 +11,11 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip); +EXTERN_C Kernel::UIntPtr kApicBaseAddress; + /// @brief Handle GPF fault. /// @param rsp -EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) { +EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); Kernel::kout << "Kernel: General Protection Fault.\r"; @@ -27,6 +29,8 @@ EXTERN_C void idt_handle_gpf(Kernel::UIntPtr rsp) { process.Leak().Status = Kernel::ProcessStatusKind::kKilled; process.Leak().Crash(); + + dbg_break_point(); } /// @brief Handle page fault. @@ -44,10 +48,16 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { process.Leak().Status = Kernel::ProcessStatusKind::kKilled; process.Leak().Crash(); + + dbg_break_point(); } /// @brief Handle scheduler interrupt. EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) { + ((volatile UInt32*) kApicBaseAddress)[0xB0] = 0; + + Kernel::HAL::rt_out8(0x20, 0x20); + NE_UNUSED(rsp); Kernel::UserProcessHelper::StartScheduling(); } @@ -68,6 +78,8 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { process.Leak().Status = Kernel::ProcessStatusKind::kKilled; process.Leak().Crash(); + + dbg_break_point(); } /// @brief Handle any generic fault. @@ -87,6 +99,8 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { process.Leak().Status = Kernel::ProcessStatusKind::kKilled; process.Leak().Crash(); + + dbg_break_point(); } EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { @@ -104,6 +118,8 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { Kernel::kout << "Kernel: SIGTRAP status.\r"; process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; + + idt_handle_scheduler(rip); } /// @brief Handle #UD fault. @@ -124,6 +140,8 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { process.Leak().Status = Kernel::ProcessStatusKind::kKilled; process.Leak().Crash(); + + dbg_break_point(); } /// @brief Enter syscall from assembly. diff --git a/dev/kernel/HALKit/AMD64/HalHandoverStub.asm b/dev/kernel/HALKit/AMD64/HalHandoverStub.asm new file mode 100644 index 00000000..a337a223 --- /dev/null +++ b/dev/kernel/HALKit/AMD64/HalHandoverStub.asm @@ -0,0 +1,30 @@ +;; /* +;; * ======================================================== +;; * +;; * NeKernel +;; * Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. +;; * +;; * ======================================================== +;; */ + +[bits 64] + +%define kTypeKernel 100 +%define kArchAmd64 122 +%define kHandoverMagic 0xBADCC + +global _HandoverMagic +global _HandoverType +global _HandoverPad +global _HandoverArch + +section .ldr + +_HandoverMagic: + dq kHandoverMagic +_HandoverType: + dw kTypeKernel +_HandoverPad: + dw 0 +_HandoverArch: + dw kArchAmd64 diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index 189b2976..fdd62e57 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -232,11 +232,6 @@ IntNormal 31 [extern kApicBaseAddress] __NE_INT_32: - mov al, 0x20 - out 0x20, al - - mov dword [kApicBaseAddress+0xB0], 0 - push rax mov rcx, rsp call idt_handle_scheduler @@ -411,3 +406,6 @@ kInterruptVectorTable: dq __NE_INT_%+i %assign i i+1 %endrep + +kApicBaseAddress: + dq 0 \ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index b7ff3038..158eaa85 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -106,10 +106,12 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { EXTERN_C void rtl_ne_task(void); EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { - Kernel::rtl_create_user_process(rtl_ne_task, "MGMTCTL"); - Kernel::rtl_create_user_process(rtl_ne_task, "LAUNCHCTL"); - Kernel::rtl_create_user_process(rtl_ne_task, "SECURITYCTL"); + Kernel::rtl_create_user_process(rtl_ne_task, "MgmtSrv"); + Kernel::rtl_create_user_process(rtl_ne_task, "LaunchSrv"); + Kernel::rtl_create_user_process(rtl_ne_task, "SecSrv"); + Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); + Kernel::HAL::Register64 idt_reg; idt_reg.Base = reinterpret_cast(kInterruptVectorTable); @@ -117,8 +119,6 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { idt_loader.Load(idt_reg); - Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); - #ifdef __FSKIT_INCLUDES_HEFS__ if (Kernel::HeFS::fs_init_hefs()) { goto hal_spin_kernel; diff --git a/dev/kernel/HALKit/AMD64/Processor.h b/dev/kernel/HALKit/AMD64/Processor.h index 1b2e35f7..8fb69c0c 100644 --- a/dev/kernel/HALKit/AMD64/Processor.h +++ b/dev/kernel/HALKit/AMD64/Processor.h @@ -19,6 +19,8 @@ #include #include +#include + #define kPITControlPort (0x43) #define kPITChannel0Port (0x40) #define kPITFrequency (1193180) @@ -28,7 +30,8 @@ #define kPIC2Command (0xA0) #define kPIC2Data (0xA1) -#include +#define kIOAPICRegVal (4) +#define kIOAPICRegReg (0) #define rtl_nop_op() asm volatile("nop") @@ -229,16 +232,16 @@ namespace Detail { }; } // namespace Detail -class APICController final { +class LAPICDmaWrapper final { public: - explicit APICController(VoidPtr base); - ~APICController() = default; + explicit LAPICDmaWrapper(VoidPtr base); + ~LAPICDmaWrapper(); - NE_COPY_DEFAULT(APICController) + NE_COPY_DEFAULT(LAPICDmaWrapper) public: - UInt32 Read(UInt32 reg) noexcept; - Void Write(UInt32 reg, UInt32 value) noexcept; + UInt32 Read(UInt16 reg) noexcept; + Void Write(UInt16 reg, UInt32 value) noexcept; private: VoidPtr fApic{nullptr}; diff --git a/dev/kernel/amd64-ci.make b/dev/kernel/amd64-ci.make index d431342a..38021901 100644 --- a/dev/kernel/amd64-ci.make +++ b/dev/kernel/amd64-ci.make @@ -51,7 +51,7 @@ nekernel-amd64-epm: clean $(CXX) $(CCFLAGS) $(DISK_DRV) $(DEBUG_MACRO) $(wildcard src/*.cc) $(wildcard src/Gfx/*.cc) $(wildcard HALKit/AMD64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) $(wildcard src/FS/*.cc) $(wildcard HALKit/AMD64/Storage/*.cc) $(wildcard HALKit/AMD64/*.cc) $(wildcard src/Swap/*.cc) $(wildcard HALKit/AMD64/*.s) $(ASM) $(ASMFLAGS) HALKit/AMD64/HalInterruptAPI.asm $(ASM) $(ASMFLAGS) HALKit/AMD64/HalCommonAPI.asm - $(ASM) $(ASMFLAGS) HALKit/AMD64/HalBootHeader.asm + $(ASM) $(ASMFLAGS) HALKit/AMD64/HalHandoverStub.asm $(ASM) $(ASMFLAGS) HALKit/AMD64/HalUtilsAPI.asm $(MOVEALL) diff --git a/dev/kernel/amd64-desktop.make b/dev/kernel/amd64-desktop.make index 0358bd0a..ae2307fd 100644 --- a/dev/kernel/amd64-desktop.make +++ b/dev/kernel/amd64-desktop.make @@ -53,7 +53,7 @@ nekernel-amd64-epm: clean $(CXX) $(CCFLAGS) $(DISK_DRV) $(DEBUG_MACRO) $(wildcard src/*.cc) $(wildcard src/Gfx/*.cc) $(wildcard HALKit/AMD64/Network/*.cc) $(wildcard HALKit/AMD64/PCI/*.cc) $(wildcard src/Network/*.cc) $(wildcard src/Storage/*.cc) $(wildcard src/FS/*.cc) $(wildcard HALKit/AMD64/Storage/*.cc) $(wildcard HALKit/AMD64/*.cc) $(wildcard src/Swap/*.cc) $(wildcard HALKit/AMD64/*.s) $(ASM) $(ASMFLAGS) HALKit/AMD64/HalInterruptAPI.asm $(ASM) $(ASMFLAGS) HALKit/AMD64/HalCommonAPI.asm - $(ASM) $(ASMFLAGS) HALKit/AMD64/HalBootHeader.asm + $(ASM) $(ASMFLAGS) HALKit/AMD64/HalHandoverStub.asm $(ASM) $(ASMFLAGS) HALKit/AMD64/HalUtilsAPI.asm $(MOVEALL) diff --git a/dev/kernel/src/UserProcessTeam.cc b/dev/kernel/src/UserProcessTeam.cc index 7acbcf8d..987fbf0b 100644 --- a/dev/kernel/src/UserProcessTeam.cc +++ b/dev/kernel/src/UserProcessTeam.cc @@ -16,6 +16,7 @@ UserProcessTeam::UserProcessTeam() { for (SizeT i = 0U; i < this->mProcessList.Count(); ++i) { this->mProcessList[i] = USER_PROCESS(); this->mProcessList[i].PTime = 0; + this->mProcessList[i].RTime = 0; this->mProcessList[i].Status = ProcessStatusKind::kKilled; } -- cgit v1.2.3 From 65a97e32ef586e073988186f1f4932c0193b3409 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Fri, 16 May 2025 16:51:06 +0200 Subject: feat(kernel): Better UPS and interrupt system too. Signed-off-by: Amlal El Mahrouss --- dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 32 ++------ .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 54 +++++++++---- dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 89 +++++++++------------- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 2 +- dev/kernel/src/FS/NeFS+FileSystemParser.cc | 2 +- dev/kernel/src/UserProcessScheduler.cc | 22 +++--- dev/kernel/src/UserProcessTeam.cc | 9 ++- 7 files changed, 98 insertions(+), 112 deletions(-) (limited to 'dev/kernel/HALKit/AMD64/HalInterruptAPI.asm') diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index f7aa2a70..89fe00b5 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -80,23 +80,6 @@ struct LAPIC final { /////////////////////////////////////////////////////////////////////////////////////// -/***********************************************************************************/ -/// @brief Send IPI command to APIC. -/// @param apic_id programmable interrupt controller id. -/// @param vector vector interrupt. -/// @param target target APIC adress. -/// @return -/***********************************************************************************/ - -Void hal_send_start_ipi(UInt32 target, UInt32 apic_id) { - Kernel::ke_dma_write(target, APIC_ICR_HIGH, apic_id << 24); - Kernel::ke_dma_write(target, APIC_ICR_LOW, 0x00000500 | 0x00004000 | 0x00000000); - - while (Kernel::ke_dma_read(target, APIC_ICR_LOW) & 0x1000) { - ; - } -} - /***********************************************************************************/ /// @brief Send end IPI for CPU. /// @param apic_id @@ -104,7 +87,7 @@ Void hal_send_start_ipi(UInt32 target, UInt32 apic_id) { /// @param target /// @return /***********************************************************************************/ -Void hal_send_sipi(UInt32 target, UInt32 apic_id, UInt8 vector) { +Void hal_send_ipi_msg(UInt32 target, UInt32 apic_id, UInt8 vector) { Kernel::ke_dma_write(target, APIC_ICR_HIGH, apic_id << 24); Kernel::ke_dma_write(target, APIC_ICR_LOW, 0x00000600 | 0x00004000 | 0x00000000 | vector); @@ -202,13 +185,10 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { controller.Write(LAPIC_REG_TIMER_LVT, 32 | (1 << 17)); controller.Write(LAPIC_REG_TIMER_INITCNT, 1000000); - const UIntPtr trampoline_phys = 0x7c00; + UInt8* trampoline_phys = (UInt8*) 0x7c00; - HAL::mm_map_page((VoidPtr)trampoline_phys, (VoidPtr)trampoline_phys, HAL::kMMFlagsWr | HAL::kMMFlagsPresent); - - const SizeT len = AP_BLOB_SIZE; /// AP blob size. - - rt_copy_memory(hal_ap_blob_start, reinterpret_cast(trampoline_phys), len); + *trampoline_phys = 0xcd; + *(trampoline_phys + 1) = 0x00; volatile UInt8* entry_ptr = reinterpret_cast(kMADTBlock->List); volatile UInt8* end_ptr = ((UInt8*) kMADTBlock) + kMADTBlock->Length; @@ -229,9 +209,7 @@ Void mp_init_cores(VoidPtr vendor_ptr) noexcept { kout << "LAPIC type, also is on...\r"; - hal_send_start_ipi(kApicBaseAddress, entry_struct->ProcessorID); - hal_send_sipi(kApicBaseAddress, entry_struct->ProcessorID, trampoline_phys >> 12); - + hal_send_ipi_msg(kApicBaseAddress, entry_struct->ProcessorID, 0x7c); } else { kout << "LAPIC type, also is not on...\r"; } diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index d5a40390..f52a7167 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -13,12 +13,31 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip); EXTERN_C Kernel::UIntPtr kApicBaseAddress; +STATIC BOOL kIsRunning = NO; + +/// @brief Notify APIC and PIC that we're done with the interrupt. +/// @note +STATIC void hal_idt_send_eoi(UInt8 vector) { + ((volatile UInt32*) kApicBaseAddress)[0xB0 / 4] = 0; + + if (vector >= 0x20 && vector <= 0x2F) { + if (vector >= 0x28) { + Kernel::HAL::rt_out8(0xA0, 0x20); + } + Kernel::HAL::rt_out8(0x20, 0x20); + } + + kIsRunning = NO; +} + /// @brief Handle GPF fault. /// @param rsp EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) { + hal_idt_send_eoi(13); + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); - Kernel::kout << "Kernel: General Protection Fault.\r"; + Kernel::kout << "Kernel: General Access Fault.\r"; process.Leak().Signal.SignalArg = rsp; process.Leak().Signal.SignalID = SIGKILL; @@ -26,8 +45,6 @@ EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) { Kernel::kout << "Kernel: SIGKILL status.\r"; - process.Leak().Status = Kernel::ProcessStatusKind::kKilled; - process.Leak().Crash(); dbg_break_point(); @@ -36,6 +53,8 @@ EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) { /// @brief Handle page fault. /// @param rsp EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { + hal_idt_send_eoi(14); + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); Kernel::kout << "Kernel: Page Fault.\r"; @@ -45,8 +64,6 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { process.Leak().Signal.SignalID = SIGKILL; process.Leak().Signal.Status = process.Leak().Status; - process.Leak().Status = Kernel::ProcessStatusKind::kKilled; - process.Leak().Crash(); dbg_break_point(); @@ -54,17 +71,24 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { /// @brief Handle scheduler interrupt. EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) { - ((volatile UInt32*) kApicBaseAddress)[0xB0] = 0; + hal_idt_send_eoi(32); - Kernel::HAL::rt_out8(0x20, 0x20); + while (kIsRunning) + ; + + kIsRunning = YES; NE_UNUSED(rsp); Kernel::UserProcessHelper::StartScheduling(); + + kIsRunning = NO; } /// @brief Handle math fault. /// @param rsp EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { + hal_idt_send_eoi(8); + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); Kernel::kout << "Kernel: Math error (division by zero?).\r"; @@ -75,8 +99,6 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { Kernel::kout << "Kernel: SIGKILL status.\r"; - process.Leak().Status = Kernel::ProcessStatusKind::kKilled; - process.Leak().Crash(); dbg_break_point(); @@ -85,6 +107,8 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { /// @brief Handle any generic fault. /// @param rsp EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { + hal_idt_send_eoi(30); + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); (Void)(Kernel::kout << "Kernel: Process RSP: " << Kernel::hex_number(rsp) << Kernel::kendl); @@ -96,14 +120,14 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { Kernel::kout << "Kernel: SIGKILL status.\r"; - process.Leak().Status = Kernel::ProcessStatusKind::kKilled; - process.Leak().Crash(); dbg_break_point(); } EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { + hal_idt_send_eoi(3); + auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); (Void)(Kernel::kout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << Kernel::kendl); @@ -125,6 +149,8 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { /// @brief Handle #UD fault. /// @param rsp EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { + hal_idt_send_eoi(6); + NE_UNUSED(rsp); auto& process = Kernel::UserProcessScheduler::The().CurrentProcess(); @@ -137,8 +163,6 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { Kernel::kout << "Kernel: SIGKILL status.\r"; - process.Leak().Status = Kernel::ProcessStatusKind::kKilled; - process.Leak().Crash(); dbg_break_point(); @@ -149,6 +173,8 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { /// @return nothing. EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_syscall_index, Kernel::UIntPtr rdx_syscall_struct) { + hal_idt_send_eoi(50); + if (rcx_syscall_index < kSysCalls.Count()) { Kernel::kout << "syscall: Enter Syscall.\r"; @@ -171,6 +197,8 @@ EXTERN_C Kernel::Void hal_system_call_enter(Kernel::UIntPtr rcx_syscall_index, /// @return nothing. EXTERN_C Kernel::Void hal_kernel_call_enter(Kernel::UIntPtr rcx_kerncall_index, Kernel::UIntPtr rdx_kerncall_struct) { + hal_idt_send_eoi(51); + if (rcx_kerncall_index < kKernCalls.Count()) { Kernel::kout << "kerncall: Enter Kernel Call List.\r"; diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index fdd62e57..667d3c5b 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -20,6 +20,8 @@ __NE_INT_%1: std + add rsp, 8 + o64 iret %endmacro @@ -30,6 +32,8 @@ __NE_INT_%1: std + add rsp, 8 + o64 iret %endmacro @@ -45,29 +49,24 @@ extern ke_io_write extern idt_handle_ud extern idt_handle_generic extern idt_handle_breakpoint +extern idt_handle_math section .text __NE_INT_0: cld - - mov al, 0x20 - out 0x20, al - push rcx call idt_handle_generic pop rcx std + add rsp, 8 + o64 iret __NE_INT_1: cld - - mov al, 0x20 - out 0x20, al - push rcx call idt_handle_generic pop rcx @@ -78,100 +77,87 @@ __NE_INT_1: __NE_INT_2: cld - - mov al, 0x20 - out 0x20, al - push rcx call idt_handle_generic pop rcx std + add rsp, 8 + o64 iret ;; @brief Triggers a breakpoint and freeze the process. RIP is also fetched. __NE_INT_3: cld - - mov al, 0x20 - out 0x20, al - push rcx call idt_handle_breakpoint pop rcx std + add rsp, 8 + o64 iret __NE_INT_4: cld - mov al, 0x20 - out 0x20, al - - push rcx call idt_handle_generic pop rcx std + add rsp, 8 + o64 iret __NE_INT_5: cld - - mov al, 0x20 - out 0x20, al - std + add rsp, 8 + o64 iret ;; Invalid opcode interrupt __NE_INT_6: cld - - mov al, 0x20 - out 0x20, al - push rcx call idt_handle_ud pop rcx std + add rsp, 8 + o64 iret __NE_INT_7: cld - - mov al, 0x20 - out 0x20, al - push rcx call idt_handle_generic pop rcx std + add rsp, 8 + o64 iret ;; Invalid opcode interrupt __NE_INT_8: cld - mov al, 0x20 - out 0x20, al - push rcx - call idt_handle_generic + call idt_handle_math pop rcx std + add rsp, 8 + o64 iret IntNormal 9 @@ -183,29 +169,26 @@ IntExp 12 __NE_INT_13: cld - mov al, 0x20 - out 0x20, al - push rcx call idt_handle_gpf pop rcx std + add rsp, 8 + o64 iret __NE_INT_14: cld - - mov al, 0x20 - out 0x20, al - push rcx call idt_handle_pf pop rcx std + add rsp, 8 + o64 iret IntNormal 15 @@ -232,11 +215,17 @@ IntNormal 31 [extern kApicBaseAddress] __NE_INT_32: + cld + push rax mov rcx, rsp call idt_handle_scheduler pop rax + std + + add rsp, 8 + o64 iret IntNormal 33 @@ -253,10 +242,6 @@ IntNormal 39 __NE_INT_40: cld - mov al, 0x20 - out 0xA0, al - out 0x20, al - push rax mov rcx, rsp call rtl_rtl8139_interrupt_handler @@ -264,6 +249,8 @@ __NE_INT_40: std + add rsp, 8 + o64 iret IntNormal 41 @@ -283,10 +270,6 @@ IntNormal 49 __NE_INT_50: cld - mov al, 0x20 - out 0xA0, al - out 0x20, al - push rax mov rax, hal_system_call_enter @@ -303,10 +286,6 @@ __NE_INT_50: __NE_INT_51: cld - mov al, 0x20 - out 0xA0, al - out 0x20, al - push rax mov rax, hal_kernel_call_enter diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 158eaa85..00dafc7b 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -111,7 +111,7 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { Kernel::rtl_create_user_process(rtl_ne_task, "SecSrv"); Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); - + Kernel::HAL::Register64 idt_reg; idt_reg.Base = reinterpret_cast(kInterruptVectorTable); diff --git a/dev/kernel/src/FS/NeFS+FileSystemParser.cc b/dev/kernel/src/FS/NeFS+FileSystemParser.cc index 3622e711..84317ad4 100644 --- a/dev/kernel/src/FS/NeFS+FileSystemParser.cc +++ b/dev/kernel/src/FS/NeFS+FileSystemParser.cc @@ -886,7 +886,7 @@ Boolean fs_init_nefs(Void) noexcept { ke_panic(RUNTIME_CHECK_FILESYSTEM, "Main disk cannot be mounted."); NeFileSystemParser parser; - + return parser.Format(&kMountpoint.A(), 0, kNeFSVolumeName); } } // namespace Kernel::NeFS diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index fe1a95ae..4f6e859e 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -268,6 +268,8 @@ Void USER_PROCESS::Exit(const Int32& exit_code) { kLastExitCode = exit_code; + --this->ParentTeam->mProcessCount; + auto memory_ptr_list = this->HeapTree; #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ @@ -483,6 +485,8 @@ SizeT UserProcessScheduler::Run() noexcept { for (; process_index < mTeam.AsArray().Capacity(); ++process_index) { auto& process = mTeam.AsArray()[process_index]; + if (this->CurrentProcess() == process) continue; + //! Check if the process needs to be run. if (UserProcessHelper::CanBeScheduled(process)) { if (process.StackSize > kSchedMaxStackSz) { @@ -493,8 +497,6 @@ SizeT UserProcessScheduler::Run() noexcept { kout << ((*process.Name) ? process.Name : "USER_PROCESS") << " will be scheduled...\r"; - this->CurrentProcess() = process; - process.PTime = static_cast(process.Affinity); if (process.PTime < process.RTime) { @@ -509,9 +511,13 @@ SizeT UserProcessScheduler::Run() noexcept { process.RTime = 0UL; } + this->CurrentProcess() = process; + if (!UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { - continue; + break; } + + break; } else { ++process.RTime; --process.PTime; @@ -537,7 +543,7 @@ UserProcessTeam& UserProcessScheduler::CurrentTeam() { BOOL UserProcessScheduler::SwitchTeam(UserProcessTeam& team) { if (team.AsArray().Count() < 1) return No; - UserProcessScheduler::The().mTeam = team; + this->mTeam = team; return Yes; } @@ -562,13 +568,7 @@ ErrorOr UserProcessHelper::TheCurrentPID() { /// @retval true can be schedulded. /// @retval false cannot be schedulded. Bool UserProcessHelper::CanBeScheduled(const USER_PROCESS& process) { - if (process.Status == ProcessStatusKind::kKilled || - process.Status == ProcessStatusKind::kFinished || - process.Status == ProcessStatusKind::kStarting || - process.Status == ProcessStatusKind::kFrozen) - return No; - - if (process.Status == ProcessStatusKind::kInvalid) return No; + if (process.Status != ProcessStatusKind::kRunning) return No; if (!process.Name[0]) return No; diff --git a/dev/kernel/src/UserProcessTeam.cc b/dev/kernel/src/UserProcessTeam.cc index 987fbf0b..8ef9a013 100644 --- a/dev/kernel/src/UserProcessTeam.cc +++ b/dev/kernel/src/UserProcessTeam.cc @@ -14,10 +14,11 @@ namespace Kernel { UserProcessTeam::UserProcessTeam() { for (SizeT i = 0U; i < this->mProcessList.Count(); ++i) { - this->mProcessList[i] = USER_PROCESS(); - this->mProcessList[i].PTime = 0; - this->mProcessList[i].RTime = 0; - this->mProcessList[i].Status = ProcessStatusKind::kKilled; + this->mProcessList[i] = USER_PROCESS(); + this->mProcessList[i].PTime = 0; + this->mProcessList[i].RTime = 0; + this->mProcessList[i].Status = ProcessStatusKind::kKilled; + this->mProcessList[i].ParentTeam = this; } this->mProcessCount = 0UL; -- cgit v1.2.3 From 0266d8058990a496b935abd76417abcfe4e9cffd Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sun, 18 May 2025 15:15:52 +0200 Subject: dev(sched): Improvements and work in progress fixes. what? - The main algorithm got improved for real time tasks, and SMP usage. - The SMP usage was present before, I just reintroduced it after realizing that it won't scale well from what I have right now. - Also removed weird implementations quirks from previous sketch. - Such as the core 0 being reserved for the boot core. - Also moved FS init code after IDT initalization. - To avoid weird FS format behavior. - Wrap HPET signature in a macro. next? - Work on the HAL's userspace transition mechanism. Signed-off-by: Amlal El Mahrouss --- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 30 ++++++++++++++--- dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 2 -- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 15 +++++---- dev/kernel/HALKit/AMD64/HalTimerAMD64.cc | 4 ++- dev/kernel/KernelKit/HardwareThreadScheduler.h | 10 +++--- dev/kernel/src/ACPIFactoryInterface.cc | 7 ++-- dev/kernel/src/HardwareThreadScheduler.cc | 8 ++--- dev/kernel/src/UserProcessScheduler.cc | 38 ++++++++++------------ 8 files changed, 64 insertions(+), 50 deletions(-) (limited to 'dev/kernel/HALKit/AMD64/HalInterruptAPI.asm') diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 7e2b8957..eac6c389 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -37,6 +37,9 @@ EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "General Access Fault."); + } if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); @@ -62,6 +65,10 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Access Fault."); + } + if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); @@ -101,6 +108,9 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Math Fault."); + } if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); @@ -126,6 +136,10 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Generic Fault."); + } + if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); @@ -146,10 +160,15 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { } EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { - hal_idt_send_eoi(3); - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + while (YES) + ; + } + + hal_idt_send_eoi(3); + if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); @@ -167,8 +186,6 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { Kernel::kout << "Kernel: SIGTRAP status.\r"; process.Leak().Status = Kernel::ProcessStatusKind::kFrozen; - - idt_handle_scheduler(rip); } /// @brief Handle #UD fault. @@ -180,6 +197,11 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); + if (!process) { + while (YES) + ; + } + if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index 667d3c5b..a6b194d3 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -224,8 +224,6 @@ __NE_INT_32: std - add rsp, 8 - o64 iret IntNormal 33 diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 581af60a..f4585835 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -110,24 +110,25 @@ EXTERN_C Kernel::Void hal_real_init(Kernel::Void) noexcept { Kernel::HAL::mp_init_cores(kHandoverHeader->f_HardwareTables.f_VendorPtr); - Kernel::HAL::Register64 idt_reg; - idt_reg.Base = reinterpret_cast(kInterruptVectorTable); - - Kernel::HAL::IDTLoader idt_loader; - - idt_loader.Load(idt_reg); - #ifdef __FSKIT_INCLUDES_HEFS__ if (Kernel::HeFS::fs_init_hefs()) { goto hal_spin_kernel; } #endif + if (!Kernel::NeFS::fs_init_nefs()) { kout << "NeFS cannot be formated on the disk. Aborting\r"; dbg_break_point(); } hal_spin_kernel: + Kernel::HAL::Register64 idt_reg; + idt_reg.Base = reinterpret_cast(kInterruptVectorTable); + + Kernel::HAL::IDTLoader idt_loader; + + idt_loader.Load(idt_reg); + while (YES) ; } diff --git a/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc b/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc index 79165289..13573880 100644 --- a/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalTimerAMD64.cc @@ -17,6 +17,8 @@ // timer slot 0 +#define kHPETSignature ("HPET") + #define kHPETCounterRegValue (0x00) #define kHPETConfigRegValue (0x20) #define kHPETCompRegValue (0x24) @@ -46,7 +48,7 @@ using namespace Kernel; HardwareTimer::HardwareTimer(UInt64 ms) : fWaitFor(ms) { auto power = PowerFactoryInterface(kHandoverHeader->f_HardwareTables.f_VendorPtr); - auto hpet = (Detail::HPET_BLOCK*) power.Find("HPET").Leak().Leak(); + auto hpet = (Detail::HPET_BLOCK*) power.Find(kHPETSignature).Leak().Leak(); MUST_PASS(hpet); fDigitalTimer = (UInt8*) hpet->address.Address; diff --git a/dev/kernel/KernelKit/HardwareThreadScheduler.h b/dev/kernel/KernelKit/HardwareThreadScheduler.h index dd8271eb..4a3220bd 100644 --- a/dev/kernel/KernelKit/HardwareThreadScheduler.h +++ b/dev/kernel/KernelKit/HardwareThreadScheduler.h @@ -24,11 +24,11 @@ using ThreadID = UInt32; enum ThreadKind { kAPInvalid, - kAPSystemReserved, // System reserved thread, well user can't use it - kAPStandard, // user thread, cannot be used by Kernel - kAPRealTime, // fallback thread, cannot be used by user if not clear or - // used by Kernel. - kAPBoot, // The core we booted from, the mama. + kAPSystemReserved = 100, // System reserved thread, well user can't use it + kAPStandard, // user thread, cannot be used by Kernel + kAPRealTime, // fallback thread, cannot be used by user if not clear or + // used by Kernel. + kAPBoot, // The core we booted from, the mama. kAPCount, }; diff --git a/dev/kernel/src/ACPIFactoryInterface.cc b/dev/kernel/src/ACPIFactoryInterface.cc index a76caff2..ded49587 100644 --- a/dev/kernel/src/ACPIFactoryInterface.cc +++ b/dev/kernel/src/ACPIFactoryInterface.cc @@ -14,13 +14,12 @@ namespace Kernel { ErrorOr ACPIFactoryInterface::Find(const Char* signature) { MUST_PASS(this->fRsdp); - if (!signature) return ErrorOr{-1}; - - if (*signature == 0) return ErrorOr{-1}; + if (!signature) return ErrorOr{nullptr}; + if (*signature == 0) return ErrorOr{nullptr}; RSDP* rsp_ptr = reinterpret_cast(this->fRsdp); - if (rsp_ptr->Revision <= 1) return ErrorOr{-1}; + if (rsp_ptr->Revision < 1) return ErrorOr{nullptr}; RSDT* xsdt = reinterpret_cast(rsp_ptr->RsdtAddress); diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc index 6cb83b3d..eda68104 100644 --- a/dev/kernel/src/HardwareThreadScheduler.cc +++ b/dev/kernel/src/HardwareThreadScheduler.cc @@ -158,12 +158,8 @@ HAL::StackFramePtr HardwareThreadScheduler::Leak() noexcept { */ /***********************************************************************************/ Ref HardwareThreadScheduler::operator[](SizeT idx) { - if (idx == 0) { - if (fThreadList[idx].Kind() != kAPSystemReserved) { - fThreadList[idx].fKind = kAPBoot; - } - } else if (idx >= kMaxAPInsideSched) { - static HardwareThread* kFakeThread = nullptr; + if (idx >= kMaxAPInsideSched) { + STATIC HardwareThread* kFakeThread = nullptr; return {kFakeThread}; } diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index b0d56c5d..165cfb5d 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -494,37 +494,28 @@ SizeT UserProcessScheduler::Run() noexcept { //! Check if the process needs to be run. if (UserProcessHelper::CanBeScheduled(process)) { - if (process.StackSize > kSchedMaxStackSz) { - kout << "Process: " << process.Name << ", has not a valid stack size! Crashing it...\r"; - process.Crash(); - continue; - } - kout << ((*process.Name) ? process.Name : "USER_PROCESS") << " will be scheduled...\r"; process.PTime = static_cast(process.Affinity); - if (process.PTime < process.RTime) { + if (process.PTime < process.RTime && AffinityKind::kRealTime != process.Affinity) { if (process.RTime < (Int32) AffinityKind::kVeryHigh) - process.RTime = (Int32) AffinityKind::kLowUsage; + process.RTime = (Int32) AffinityKind::kLowUsage / 2; else if (process.RTime < (Int32) AffinityKind::kHigh) - process.RTime = (Int32) AffinityKind::kStandard; + process.RTime = (Int32) AffinityKind::kStandard / 3; else if (process.RTime < (Int32) AffinityKind::kStandard) - process.RTime = (Int32) AffinityKind::kHigh; + process.RTime = (Int32) AffinityKind::kHigh / 4; - process.PTime += process.RTime; + process.PTime -= process.RTime; process.RTime = 0UL; } if (!UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { - break; + continue; } - - mTeam.AsArray()[this->TheCurrentProcess().Leak().ProcessId] = - this->TheCurrentProcess().Leak(); - - this->TheCurrentProcess() = process; } else { + kout << ((*process.Name) ? process.Name : "USER_PROCESS") << " will be scheduled later...\r"; + ++process.RTime; --process.PTime; } @@ -575,14 +566,13 @@ ErrorOr UserProcessHelper::TheCurrentPID() { /// @retval false cannot be schedulded. Bool UserProcessHelper::CanBeScheduled(const USER_PROCESS& process) { if (process.Status != ProcessStatusKind::kRunning) return No; - + if (process.StackSize > kSchedMaxStackSz) return No; if (!process.Name[0]) return No; // real time processes shouldn't wait that much. if (process.Affinity == AffinityKind::kRealTime) return Yes; - if (process.Signal.SignalID == SIGKILL || process.Signal.SignalID == SIGABRT || - process.Signal.SignalID == SIGTRAP) { + if (process.Signal.SignalID == SIGTRAP) { return No; } @@ -625,7 +615,10 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { UserProcessHelper::TheCurrentPID().Leak().Leak() = UserProcessHelper::TheCurrentPID(); - break; + UserProcessScheduler::The().TheCurrentProcess() = + UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid]; + + return YES; } continue; @@ -653,6 +646,9 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid].PTime; HardwareThreadScheduler::The()[index].Leak()->Wake(YES); + UserProcessScheduler::The().TheCurrentProcess() = + UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid]; + return YES; } -- cgit v1.2.3 From 58d2af14429be02b580cde5b3e23978530d8ab74 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Wed, 21 May 2025 10:19:07 +0200 Subject: feat(kernel): Architectural changes, and introducing a kKernelVM. see code for more details. Signed-off-by: Amlal El Mahrouss --- dev/boot/src/BootThread.cc | 3 ++ dev/boot/src/HEL/AMD64/BootEFI.cc | 2 +- dev/kernel/ArchKit/ArchKit.h | 8 +++- dev/kernel/FirmwareKit/Handover.h | 2 + dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc | 22 +++------- dev/kernel/HALKit/AMD64/HalCommonAPI.asm | 48 +++++++++++++++----- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 51 +--------------------- dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 22 ---------- dev/kernel/HALKit/AMD64/HalKernelMain.cc | 27 ++++++++++-- dev/kernel/HALKit/AMD64/Processor.h | 2 - dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc | 2 +- dev/kernel/HALKit/ARM64/Processor.h | 2 - dev/kernel/KernelKit/KernelTaskScheduler.h | 2 +- dev/kernel/src/HardwareThreadScheduler.cc | 4 +- dev/kernel/src/UserProcessScheduler.cc | 23 +++++++--- 15 files changed, 100 insertions(+), 120 deletions(-) (limited to 'dev/kernel/HALKit/AMD64/HalInterruptAPI.asm') diff --git a/dev/boot/src/BootThread.cc b/dev/boot/src/BootThread.cc index ada864bb..b502b52e 100644 --- a/dev/boot/src/BootThread.cc +++ b/dev/boot/src/BootThread.cc @@ -175,6 +175,9 @@ Int32 BootThread::Start(HEL::BootInfoHeader* handover, Bool own_stack) { writer.Write("BootZ: Stack address: ").Write((UIntPtr) &fStack[mib_cast(16) - 1]).Write("\r"); writer.Write("BootZ: Stack size: ").Write(mib_cast(16)).Write("\r"); + fHandover->f_StackTop = &fStack[mib_cast(16) - 1]; + fHandover->f_StackSz = mib_cast(16); + auto ret = rt_jump_to_address(fStartAddress, fHandover, &fStack[mib_cast(16) - 1]); // we don't need the stack anymore. diff --git a/dev/boot/src/HEL/AMD64/BootEFI.cc b/dev/boot/src/HEL/AMD64/BootEFI.cc index 45566d6c..33dfd3ca 100644 --- a/dev/boot/src/HEL/AMD64/BootEFI.cc +++ b/dev/boot/src/HEL/AMD64/BootEFI.cc @@ -243,7 +243,7 @@ EFI_EXTERN_C EFI_API Int32 BootloaderMain(EfiHandlePtr image_handle, EfiSystemTa handover_hdr->f_KernelImage = reader_kernel.Blob(); handover_hdr->f_KernelSz = reader_kernel.Size(); - kernel_thread.Start(handover_hdr, NO); + kernel_thread.Start(handover_hdr, YES); } Boot::BootFileReader reader_netboot(L"net.efi", image_handle); diff --git a/dev/kernel/ArchKit/ArchKit.h b/dev/kernel/ArchKit/ArchKit.h index 41a36e69..d511658f 100644 --- a/dev/kernel/ArchKit/ArchKit.h +++ b/dev/kernel/ArchKit/ArchKit.h @@ -77,8 +77,14 @@ struct HalSyscallEntry final { operator bool() { return fHooked; } }; +EXTERN_C Kernel::HAL::StackFramePtr mp_get_current_context(Kernel::Int64 pid); + inline Kernel::Array kSysCalls; inline Kernel::Array kKernCalls; -EXTERN_C Kernel::HAL::StackFramePtr mp_get_current_context(Kernel::Int64 pid); +#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ + +inline Kernel::VoidPtr kKernelVM = nullptr; + +#endif // __NE_VIRTUAL_MEMORY_SUPPORT__ \ No newline at end of file diff --git a/dev/kernel/FirmwareKit/Handover.h b/dev/kernel/FirmwareKit/Handover.h index d3ccc724..cda27e52 100644 --- a/dev/kernel/FirmwareKit/Handover.h +++ b/dev/kernel/FirmwareKit/Handover.h @@ -63,6 +63,8 @@ struct BootInfoHeader final { SizeT f_KernelSz; VoidPtr f_StartupImage; SizeT f_StartupSz; + VoidPtr f_StackTop; + SizeT f_StackSz; WideChar f_FirmwareVendorName[32]; SizeT f_FirmwareVendorLen; diff --git a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc index e4ad1024..ada2ee3f 100644 --- a/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -113,27 +113,17 @@ EXTERN_C HAL::StackFramePtr mp_get_current_context(Int64 thrdid) { /// @param thrdid The thread ID. /***********************************************************************************/ -EXTERN_C BOOL mp_register_process(HAL::StackFramePtr stack_frame, ProcessID thrdid) { +EXTERN_C BOOL mp_register_task(HAL::StackFramePtr stack_frame, ProcessID thrdid) { if (thrdid > kSMPCount) return NO; - if (!mp_is_smp()) { - if (stack_frame) { - kHWThread[thrdid].mFramePtr = stack_frame; - kHWThread[thrdid].mThreadID = thrdid; - HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO); + kHWThread[thrdid].mFramePtr = stack_frame; + kHWThread[thrdid].mThreadID = thrdid; - sched_jump_to_task(stack_frame); + HardwareThreadScheduler::The()[thrdid].Leak()->Busy(NO); - return YES; - } - } else { - kHWThread[thrdid].mFramePtr = stack_frame; - kHWThread[thrdid].mThreadID = thrdid; - - return YES; - } + sched_jump_to_task(stack_frame); - return NO; + return YES; } /***********************************************************************************/ diff --git a/dev/kernel/HALKit/AMD64/HalCommonAPI.asm b/dev/kernel/HALKit/AMD64/HalCommonAPI.asm index 230f50ed..d0ce2418 100644 --- a/dev/kernel/HALKit/AMD64/HalCommonAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalCommonAPI.asm @@ -56,6 +56,8 @@ extern hal_system_call_enter global mp_system_call_handler mp_system_call_handler: + push rbp + mov rbp, rsp push r8 push r9 @@ -77,7 +79,9 @@ mp_system_call_handler: pop r9 pop r8 - o64 sysret + pop rbp + + o64 iret section .text @@ -88,12 +92,40 @@ sched_jump_to_task: push rbp mov rbp, rsp - mov ax, 0x20 + mov ax, 0x30 mov ds, ax mov es, ax mov fs, ax mov gs, ax + mov ax, 0x18 + ltr ax + + push 0x30 + mov rdx, [rcx + 0x08] + push rdx + o64 pushf + push 0x28 + mov rdx, [rcx + 0x00] + push rdx + + call sched_recover_registers + + o64 iret + +global sched_idle_task + +sched_idle_task: + mov ax, cs + and ax, 3 + + jmp $ + ret + +sched_recover_registers: + push rbp + mov rbp, rsp + mov r8, [rcx + 0x10] mov r9, [rcx + 0x18] mov r10, [rcx + 0x20] @@ -103,14 +135,6 @@ sched_jump_to_task: mov r14, [rcx + 0x40] mov r15, [rcx + 0x48] - mov rax, [rcx + 0x00] - mov rsp, [rcx + 0x08] - - o64 sysret - int 3 ;; Never continue here. + pop rbp -global sched_idle_task - -sched_idle_task: - jmp $ - ret + ret \ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 51fc4f0e..633adccb 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -37,14 +37,6 @@ EXTERN_C Kernel::Void idt_handle_gpf(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (!process) { - ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "General Access Fault."); - } - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || - process.Leak().Signal.SignalID == SIGTRAP) { - dbg_break_point(); - } - Kernel::kout << "Kernel: General Access Fault.\r"; process.Leak().Signal.SignalArg = rsp; @@ -63,15 +55,6 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (!process) { - ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Access Fault."); - } - - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || - process.Leak().Signal.SignalID == SIGTRAP) { - dbg_break_point(); - } - Kernel::kout << "Kernel: Page Fault.\r"; Kernel::kout << "Kernel: SIGKILL\r"; @@ -104,14 +87,6 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (!process) { - ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Math Fault."); - } - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || - process.Leak().Signal.SignalID == SIGTRAP) { - dbg_break_point(); - } - Kernel::kout << "Kernel: Math error (division by zero?).\r"; process.Leak().Signal.SignalArg = rsp; @@ -130,15 +105,6 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (!process) { - ke_panic(RUNTIME_CHECK_BAD_BEHAVIOR, "Generic Fault."); - } - - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || - process.Leak().Signal.SignalID == SIGTRAP) { - dbg_break_point(); - } - (Void)(Kernel::kout << "Kernel: Process RSP: " << Kernel::hex_number(rsp) << Kernel::kendl); Kernel::kout << "Kernel: Access Process Fault.\r"; @@ -152,19 +118,9 @@ EXTERN_C void idt_handle_generic(Kernel::UIntPtr rsp) { } EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) { - auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - - if (!process) { - while (YES) - ; - } - hal_idt_send_eoi(3); - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || - process.Leak().Signal.SignalID == SIGTRAP) { - dbg_break_point(); - } + auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); (Void)(Kernel::kout << "Kernel: Process RIP: " << Kernel::hex_number(rip) << Kernel::kendl); @@ -189,11 +145,6 @@ EXTERN_C void idt_handle_ud(Kernel::UIntPtr rsp) { auto& process = Kernel::UserProcessScheduler::The().TheCurrentProcess(); - if (!process) { - while (YES) - ; - } - if (process.Leak().Signal.SignalID == SIGKILL || process.Leak().Signal.SignalID == SIGABRT || process.Leak().Signal.SignalID == SIGTRAP) { dbg_break_point(); diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index a6b194d3..5e82f969 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -20,8 +20,6 @@ __NE_INT_%1: std - add rsp, 8 - o64 iret %endmacro @@ -61,8 +59,6 @@ __NE_INT_0: std - add rsp, 8 - o64 iret __NE_INT_1: @@ -83,8 +79,6 @@ __NE_INT_2: std - add rsp, 8 - o64 iret ;; @brief Triggers a breakpoint and freeze the process. RIP is also fetched. @@ -96,8 +90,6 @@ __NE_INT_3: std - add rsp, 8 - o64 iret __NE_INT_4: @@ -109,16 +101,12 @@ __NE_INT_4: std - add rsp, 8 - o64 iret __NE_INT_5: cld std - add rsp, 8 - o64 iret ;; Invalid opcode interrupt @@ -130,8 +118,6 @@ __NE_INT_6: std - add rsp, 8 - o64 iret __NE_INT_7: @@ -142,8 +128,6 @@ __NE_INT_7: std - add rsp, 8 - o64 iret ;; Invalid opcode interrupt @@ -156,8 +140,6 @@ __NE_INT_8: std - add rsp, 8 - o64 iret IntNormal 9 @@ -187,8 +169,6 @@ __NE_INT_14: std - add rsp, 8 - o64 iret IntNormal 15 @@ -247,8 +227,6 @@ __NE_INT_40: std - add rsp, 8 - o64 iret IntNormal 41 diff --git a/dev/kernel/HALKit/AMD64/HalKernelMain.cc b/dev/kernel/HALKit/AMD64/HalKernelMain.cc index 4de43f27..5394645a 100644 --- a/dev/kernel/HALKit/AMD64/HalKernelMain.cc +++ b/dev/kernel/HALKit/AMD64/HalKernelMain.cc @@ -38,9 +38,9 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { Boot::ExitBootServices(handover_hdr->f_HardwareTables.f_ImageKey, handover_hdr->f_HardwareTables.f_ImageHandle); - kKernelCR3 = kHandoverHeader->f_PageStart; + kKernelVM = kHandoverHeader->f_PageStart; - hal_write_cr3(kKernelCR3); + hal_write_cr3(kKernelVM); /************************************** */ /* INITIALIZE BIT MAP. */ @@ -54,7 +54,12 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { /* INITIALIZE GDT AND SEGMENTS. */ /************************************** */ - STATIC CONST auto kGDTEntriesCount = 6; + STATIC CONST auto kGDTEntriesCount = 8; + + STATIC HAL::Detail::NE_TSS kKernelTSS{}; + + kKernelTSS.fRsp0 = (UInt64) kHandoverHeader->f_StackTop; + kKernelTSS.fIopb = sizeof(HAL::Detail::NE_TSS); /* The GDT, mostly descriptors for user and kernel segments. */ STATIC Kernel::HAL::Detail::NE_GDT_ENTRY ALIGN(0x08) kGDTArray[kGDTEntriesCount] = { @@ -76,6 +81,8 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { .fAccessByte = 0x92, .fFlags = 0xCF, .fBaseHigh = 0}, // Kernel data + {}, // TSS data low + {}, // TSS data high {.fLimitLow = 0x0, .fBaseLow = 0, .fBaseMid = 0, @@ -90,6 +97,20 @@ EXTERN_C Int32 hal_init_platform(Kernel::HEL::BootInfoHeader* handover_hdr) { .fBaseHigh = 0}, // User data }; + kGDTArray[3].fLimitLow = sizeof(HAL::Detail::NE_TSS) - 1; + kGDTArray[3].fBaseLow = ((UIntPtr) &kKernelTSS) & 0xFFFF; + kGDTArray[3].fBaseMid = (((UIntPtr) &kKernelTSS) >> 16) & 0xFF; + kGDTArray[3].fAccessByte = 0x89; // Present, type 9 = 64-bit available TSS + kGDTArray[3].fFlags = 0x20 | ((((UIntPtr) &kKernelTSS) >> 24) & 0x0F); + kGDTArray[3].fBaseHigh = (((UIntPtr) &kKernelTSS) >> 24) & 0xFF; + + kGDTArray[4].fLimitLow = ((UIntPtr) &kKernelTSS >> 32) & 0xFFFF; + kGDTArray[4].fBaseLow = 0; + kGDTArray[4].fBaseMid = 0; + kGDTArray[4].fAccessByte = 0; + kGDTArray[4].fFlags = 0; + kGDTArray[4].fBaseHigh = 0; + // Load memory descriptors. Kernel::HAL::Register64 gdt_reg; diff --git a/dev/kernel/HALKit/AMD64/Processor.h b/dev/kernel/HALKit/AMD64/Processor.h index c574f8d5..3bf0ad3e 100644 --- a/dev/kernel/HALKit/AMD64/Processor.h +++ b/dev/kernel/HALKit/AMD64/Processor.h @@ -285,6 +285,4 @@ EXTERN_C ATTRIBUTE(naked) Kernel::Void hal_load_gdt(Kernel::HAL::Register64 ptr) inline Kernel::VoidPtr kKernelBitMpStart = nullptr; inline Kernel::UIntPtr kKernelBitMpSize = 0UL; -inline Kernel::VoidPtr kKernelCR3 = nullptr; - #endif // __NE_AMD64__ */ \ No newline at end of file diff --git a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc index 5be41e4e..70a5e2d9 100644 --- a/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc +++ b/dev/kernel/HALKit/ARM64/HalApplicationProcessor.cc @@ -113,7 +113,7 @@ EXTERN_C HAL::StackFramePtr mp_get_current_context(ProcessID thrdid) { /// @param thrdid The thread ID. /***********************************************************************************/ -EXTERN_C Bool mp_register_process(HAL::StackFramePtr stack_frame, ProcessID thrdid) { +EXTERN_C Bool mp_register_task(HAL::StackFramePtr stack_frame, ProcessID thrdid) { MUST_PASS(Detail::kGICEnabled); if (!stack_frame) return NO; diff --git a/dev/kernel/HALKit/ARM64/Processor.h b/dev/kernel/HALKit/ARM64/Processor.h index f52b854f..ba1ed11e 100644 --- a/dev/kernel/HALKit/ARM64/Processor.h +++ b/dev/kernel/HALKit/ARM64/Processor.h @@ -72,8 +72,6 @@ inline Void hal_wfi(Void) { inline Kernel::VoidPtr kKernelBitMpStart = nullptr; inline Kernel::UIntPtr kKernelBitMpSize = 0UL; -inline Kernel::VoidPtr kKernelPDE = nullptr; - #include #endif // __NE_ARM64__ \ No newline at end of file diff --git a/dev/kernel/KernelKit/KernelTaskScheduler.h b/dev/kernel/KernelKit/KernelTaskScheduler.h index f4ff4125..57b83ccb 100644 --- a/dev/kernel/KernelKit/KernelTaskScheduler.h +++ b/dev/kernel/KernelKit/KernelTaskScheduler.h @@ -16,7 +16,7 @@ namespace Kernel { class KERNEL_TASK final { -public: + public: Char Name[kSchedNameLen] = {"KERNEL_TASK"}; ProcessSubsystem SubSystem{ProcessSubsystem::kProcessSubsystemDriver}; HAL::StackFramePtr StackFrame{nullptr}; diff --git a/dev/kernel/src/HardwareThreadScheduler.cc b/dev/kernel/src/HardwareThreadScheduler.cc index b801632c..23365af5 100644 --- a/dev/kernel/src/HardwareThreadScheduler.cc +++ b/dev/kernel/src/HardwareThreadScheduler.cc @@ -21,7 +21,7 @@ namespace Kernel { /***********************************************************************************/ EXTERN_C Bool hal_check_stack(HAL::StackFramePtr frame); -EXTERN_C Bool mp_register_process(HAL::StackFramePtr frame, ProcessID pid); +EXTERN_C Bool mp_register_task(HAL::StackFramePtr frame, ProcessID pid); STATIC HardwareThreadScheduler kHardwareThreadScheduler; @@ -94,7 +94,7 @@ Void HardwareThread::Wake(const bool wakeup) noexcept { Bool HardwareThread::Switch(HAL::StackFramePtr frame) { this->fStack = frame; - Bool ret = mp_register_process(fStack, this->fPID); + Bool ret = mp_register_task(fStack, this->fPID); return ret; } diff --git a/dev/kernel/src/UserProcessScheduler.cc b/dev/kernel/src/UserProcessScheduler.cc index 0de38532..a901e6d0 100644 --- a/dev/kernel/src/UserProcessScheduler.cc +++ b/dev/kernel/src/UserProcessScheduler.cc @@ -21,6 +21,7 @@ #include #include #include +#include "NewKit/Macros.h" ///! BUGS: 0 @@ -125,7 +126,7 @@ ErrorOr USER_PROCESS::New(SizeT sz, SizeT pad_amount) { if (this->UsedMemory > kSchedMaxMemoryLimit) return ErrorOr(-kErrorHeapOutOfMemory); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - auto vm_register = kKernelCR3; + auto vm_register = kKernelVM; hal_write_cr3(this->VMRegister); auto ptr = mm_new_ptr(sz, Yes, Yes, pad_amount); @@ -271,7 +272,7 @@ Void USER_PROCESS::Exit(const Int32& exit_code) { auto memory_ptr_list = this->HeapTree; #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - auto pd = kKernelCR3; + auto pd = kKernelVM; hal_write_cr3(this->VMRegister); #endif @@ -384,7 +385,7 @@ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr im rt_copy_memory(reinterpret_cast(const_cast(name)), process.Name, len); #ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ - process.VMRegister = kKernelCR3; + process.VMRegister = kKernelVM; #else process.VMRegister = 0UL; #endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ @@ -401,6 +402,15 @@ ProcessID UserProcessScheduler::Spawn(const Char* name, VoidPtr code, VoidPtr im process.StackFrame->IP = reinterpret_cast(code); process.StackFrame->SP = reinterpret_cast(&process.StackReserve[0] + process.StackSize); +#ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ + HAL::mm_map_page((VoidPtr) process.StackFrame->IP, + (VoidPtr) HAL::mm_get_phys_address((VoidPtr) process.StackFrame->IP), + HAL::kMMFlagsUser | HAL::kMMFlagsPresent); + HAL::mm_map_page((VoidPtr) process.StackFrame->SP, + (VoidPtr) HAL::mm_get_phys_address((VoidPtr) process.StackFrame->SP), + HAL::kMMFlagsUser | HAL::kMMFlagsPresent); +#endif // ifdef __NE_VIRTUAL_MEMORY_SUPPORT__ + process.StackSize = kSchedMaxStackSz; rt_set_memory(process.StackReserve, 0, process.StackSize); @@ -494,6 +504,8 @@ SizeT UserProcessScheduler::Run() noexcept { if (UserProcessHelper::CanBeScheduled(process)) { kout << process.Name << " will be scheduled...\r"; + this->TheCurrentProcess() = process; + if (UserProcessHelper::Switch(process.StackFrame, process.ProcessId)) { process.PTime = static_cast(process.Affinity); @@ -606,6 +618,7 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { if (HardwareThreadScheduler::The()[index].Leak()->IsBusy()) { (Void)(kout << "AP_" << hex_number(index)); kout << " is busy\r"; + continue; } @@ -627,10 +640,6 @@ Bool UserProcessHelper::Switch(HAL::StackFramePtr frame_ptr, PID new_pid) { HardwareThreadScheduler::The()[index].Leak()->fPTime = UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid].PTime; - HardwareThreadScheduler::The()[index].Leak()->Wake(YES); - - UserProcessScheduler::The().TheCurrentProcess() = - UserProcessScheduler::The().TheCurrentTeam().AsArray()[new_pid]; return YES; } -- cgit v1.2.3 From 386d9a5bffcd66633e4c3c72eb6cb25722796c92 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sat, 24 May 2025 10:59:49 +0200 Subject: feat(kernel): Better syscall routing, also added new tools. what: - ping, manual have been added. - Rework RtlCurrentPID to SchedGetCurrentProcessID. - Cleanup codebase overall. Signed-off-by: Amlal El Mahrouss --- .../HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 8 ++-- dev/kernel/HALKit/AMD64/HalInterruptAPI.asm | 4 ++ .../HALKit/AMD64/Network/Generic+Basic+RTL8139.cc | 53 +++++++++++++--------- dev/kernel/KernelKit/UserProcessScheduler.inl | 6 ++- dev/kernel/KernelKit/ZXD.h | 37 +++++++++++++++ dev/kernel/KernelKit/Zxd.h | 37 --------------- dev/user/SystemCalls.h | 14 +++--- dev/user/src/SystemCalls+IO.asm | 9 +--- public/tools/manual/.keep | 0 public/tools/manual/manual.json | 19 ++++++++ public/tools/manual/src/.keep | 0 public/tools/manual/src/CommandLine.cc | 13 ++++++ public/tools/manual/vendor/.keep | 0 public/tools/ping/.keep | 0 public/tools/ping/ping.json | 19 ++++++++ public/tools/ping/src/.keep | 0 public/tools/ping/src/CommandLine.cc | 29 ++++++++++++ public/tools/ping/vendor/.keep | 0 tooling/mk_app.py | 4 +- tooling/mk_fwrk.py | 4 +- tooling/mk_img.py | 4 +- 21 files changed, 174 insertions(+), 86 deletions(-) create mode 100644 dev/kernel/KernelKit/ZXD.h delete mode 100644 dev/kernel/KernelKit/Zxd.h create mode 100644 public/tools/manual/.keep create mode 100644 public/tools/manual/manual.json create mode 100644 public/tools/manual/src/.keep create mode 100644 public/tools/manual/src/CommandLine.cc create mode 100644 public/tools/manual/vendor/.keep create mode 100644 public/tools/ping/.keep create mode 100644 public/tools/ping/ping.json create mode 100644 public/tools/ping/src/.keep create mode 100644 public/tools/ping/src/CommandLine.cc create mode 100644 public/tools/ping/vendor/.keep (limited to 'dev/kernel/HALKit/AMD64/HalInterruptAPI.asm') diff --git a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index 54a79571..b70cd51f 100644 --- a/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -19,15 +19,13 @@ STATIC BOOL kIsRunning = NO; /// @note STATIC void hal_idt_send_eoi(UInt8 vector) { ((volatile UInt32*) kApicBaseAddress)[0xB0 / 4] = 0; - + if (vector >= kPICCommand && vector <= 0x2F) { if (vector >= 0x28) { Kernel::HAL::rt_out8(kPIC2Command, kPICCommand); } Kernel::HAL::rt_out8(kPICCommand, kPICCommand); } - - kIsRunning = NO; } /// @brief Handle GPF fault. @@ -58,6 +56,8 @@ EXTERN_C void idt_handle_pf(Kernel::UIntPtr rsp) { /// @brief Handle scheduler interrupt. EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) { + NE_UNUSED(rsp); + hal_idt_send_eoi(32); while (kIsRunning) @@ -65,7 +65,6 @@ EXTERN_C void idt_handle_scheduler(Kernel::UIntPtr rsp) { kIsRunning = YES; - NE_UNUSED(rsp); Kernel::UserProcessHelper::StartScheduling(); kIsRunning = NO; @@ -82,7 +81,6 @@ EXTERN_C void idt_handle_math(Kernel::UIntPtr rsp) { process.Leak().Signal.SignalArg = rsp; process.Leak().Signal.SignalID = SIGKILL; process.Leak().Signal.Status = process.Leak().Status; - } /// @brief Handle any generic fault. diff --git a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm index 5e82f969..a0ff40dc 100644 --- a/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm +++ b/dev/kernel/HALKit/AMD64/HalInterruptAPI.asm @@ -251,6 +251,8 @@ __NE_INT_50: mov rcx, r8 mov rdx, r9 + mov r8, r10 + mov r9, r11 call rax pop rax @@ -267,6 +269,8 @@ __NE_INT_51: mov rcx, r8 mov rdx, r9 + mov r8, r10 + mov r9, r11 call rax pop rax diff --git a/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc b/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc index 38c12fee..7c611c26 100644 --- a/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc +++ b/dev/kernel/HALKit/AMD64/Network/Generic+Basic+RTL8139.cc @@ -11,15 +11,16 @@ Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. using namespace Kernel; using namespace Kernel::HAL; -STATIC UInt16 kIOBase = 0xFFFF; - -STATIC UInt32 kRXOffset = 0UL; -STATIC constexpr CONST UInt32 kRxBufferSize = 8192 + 16 + 1500; +STATIC UInt16 kRTLIOBase = 0xFFFF; STATIC BOOL kTXEnabled = NO; +STATIC UInt32 kRXOffset = 0UL; + +STATIC constexpr CONST UInt32 kRXBufferSize = 8192 + 16 + 1500; + STATIC UInt8* kRXUpperLayer = nullptr; -STATIC UInt8* kRxBuffer = nullptr; +STATIC UInt8* kRXBuffer = nullptr; /***********************************************************************************/ ///@brief RTL8139 Init routine. @@ -28,12 +29,13 @@ STATIC UInt8* kRxBuffer = nullptr; EXTERN_C Void rtl_init_nic_rtl8139(UInt16 io_base) noexcept { if (kTXEnabled) return; - kIOBase = io_base; - MUST_PASS(io_base); + kRTLIOBase = io_base; - kRxBuffer = (UInt8*) rtl_dma_alloc(sizeof(UInt8) * kRxBufferSize, 0); + MUST_PASS(io_base != 0xFFFF); - MUST_PASS(kRxBuffer); + kRXBuffer = reinterpret_cast(rtl_dma_alloc(sizeof(UInt8) * kRXBufferSize, 0)); + + MUST_PASS(kRXBuffer); /// Reset first. @@ -51,11 +53,11 @@ EXTERN_C Void rtl_init_nic_rtl8139(UInt16 io_base) noexcept { return; } - rt_out32(io_base + 0x30, (UInt32) (UIntPtr) kRxBuffer); + rt_out32(io_base + 0x30, (UInt32) (UIntPtr) kRXBuffer); rt_out8(io_base + 0x37, 0x0C); - rt_out32(io_base + 0x44, 0xf | (1 << 7)); + rt_out32(io_base + 0x44, 0xF | (1 << 7)); rt_out16(io_base + 0x3C, 0x0005); @@ -68,21 +70,30 @@ EXTERN_C Void rtl_init_nic_rtl8139(UInt16 io_base) noexcept { /***********************************************************************************/ EXTERN_C void rtl_rtl8139_interrupt_handler() { - if (kIOBase == 0xFFFF) return; + if (kRTLIOBase == 0xFFFF) return; - UInt16 status = rt_in16(kIOBase + 0x3E); - rt_out16(kIOBase + 0x3E, status); + UInt16 status = rt_in16(kRTLIOBase + 0x3E); + rt_out16(kRTLIOBase + 0x3E, status); if (status & 0x01) { - while ((rt_in8(kIOBase + 0x37) & 0x01) == 0) { - UInt32 offset = kRXOffset % kRxBufferSize; - volatile UInt8* packet = kRxBuffer + offset + 4; - UInt16 len = *(UInt16*) (kRxBuffer + offset + 2); + // While we receive data. + while ((rt_in8(kRTLIOBase + 0x37) & 0x01) == 0) { + // We grab an offset from the RX buffer. + UInt32 offset = kRXOffset % kRXBufferSize; + + // If the offset is too high, we reset it. + if (offset >= (kRXBufferSize - 16)) { + kRXOffset = 0UL; + offset = 0UL; + } + + volatile UInt8* packet = kRXBuffer + offset + 4; + UInt16 len = *(UInt16*) (kRXBuffer + offset + 2); - kRXUpperLayer[offset + 4] = *packet; + kRXUpperLayer[(offset + 4)] = *packet; + kRXOffset += (len + 4); - kRXOffset += len + 4; - rt_out16(kIOBase + 0x38, (UInt16) (kRXOffset - 16)); + rt_out16(kRTLIOBase + 0x38, (UInt16) (kRXOffset - 16)); } } diff --git a/dev/kernel/KernelKit/UserProcessScheduler.inl b/dev/kernel/KernelKit/UserProcessScheduler.inl index 156aa0b5..df35e037 100644 --- a/dev/kernel/KernelKit/UserProcessScheduler.inl +++ b/dev/kernel/KernelKit/UserProcessScheduler.inl @@ -11,13 +11,17 @@ /// @author Amlal El Mahrouss (amlal@nekernel.org) /// @date Tue Apr 22 22:01:07 CEST 2025 +#ifndef INC_PROCESS_SCHEDULER_H +#include +#endif // INC_PROCESS_SCHEDULER_H + namespace Kernel { /***********************************************************************************/ /** @brief Free pointer from usage. */ /***********************************************************************************/ template -Boolean USER_PROCESS::Delete(ErrorOr ptr) { +BOOL USER_PROCESS::Delete(ErrorOr ptr) { if (!ptr) return No; if (!this->HeapTree) { diff --git a/dev/kernel/KernelKit/ZXD.h b/dev/kernel/KernelKit/ZXD.h new file mode 100644 index 00000000..d2456f51 --- /dev/null +++ b/dev/kernel/KernelKit/ZXD.h @@ -0,0 +1,37 @@ +/* ------------------------------------------- + + Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. + +------------------------------------------- */ + +#pragma once + +#include + +namespace ZXD { +using namespace Kernel; + +struct ZXD_EXEC_HEADER; +struct ZXD_STUB_HEADER; + +/// @brief ZXD executable header +/// @details This header is used to identify ZXD executable files. +struct ZXD_EXEC_HEADER { + UInt32 fMagic; + UInt32 fVersion; + UInt32 fFlags; + UInt32 fHdrSize; + UInt32 fCRC32; + UInt32 fAssigneeSignature; + UInt32 fIssuerSingature; +}; + +/// @brief ZXD stub header +/// @details This header is used to identify ZXD stub files. It contains the size of the stub, the +/// offset of the stub, and the CRC32 checksum of the stub. +struct ZXD_STUB_HEADER : public ZXD_EXEC_HEADER { + UInt32 fStubSize; + UInt32 fStubOffset; + UInt32 fStubCRC32; +}; +} // namespace ZXD \ No newline at end of file diff --git a/dev/kernel/KernelKit/Zxd.h b/dev/kernel/KernelKit/Zxd.h deleted file mode 100644 index d2456f51..00000000 --- a/dev/kernel/KernelKit/Zxd.h +++ /dev/null @@ -1,37 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2025, Amlal El Mahrouss, all rights reserved. - -------------------------------------------- */ - -#pragma once - -#include - -namespace ZXD { -using namespace Kernel; - -struct ZXD_EXEC_HEADER; -struct ZXD_STUB_HEADER; - -/// @brief ZXD executable header -/// @details This header is used to identify ZXD executable files. -struct ZXD_EXEC_HEADER { - UInt32 fMagic; - UInt32 fVersion; - UInt32 fFlags; - UInt32 fHdrSize; - UInt32 fCRC32; - UInt32 fAssigneeSignature; - UInt32 fIssuerSingature; -}; - -/// @brief ZXD stub header -/// @details This header is used to identify ZXD stub files. It contains the size of the stub, the -/// offset of the stub, and the CRC32 checksum of the stub. -struct ZXD_STUB_HEADER : public ZXD_EXEC_HEADER { - UInt32 fStubSize; - UInt32 fStubOffset; - UInt32 fStubCRC32; -}; -} // namespace ZXD \ No newline at end of file diff --git a/dev/user/SystemCalls.h b/dev/user/SystemCalls.h index d40dc127..e8b4e59c 100644 --- a/dev/user/SystemCalls.h +++ b/dev/user/SystemCalls.h @@ -331,19 +331,17 @@ IMPORT_C IORef PrintGet(const Char* path); typedef SInt32 AffinityRef; typedef UInt64 ProcessRef; -IMPORT_C SInt32 SchedSetAffinity(ProcessRef, SInt32 req, AffinityRef* local); +IMPORT_C SInt32 SchedSetAffinity(_Input ProcessRef, SInt32 req, _Input AffinityRef*); -IMPORT_C SInt32 SchedGetAffinity(ProcessRef, AffinityRef* local); +IMPORT_C SInt32 SchedGetAffinity(_Input ProcessRef, _InOut AffinityRef*); -IMPORT_C SInt32 SchedFireSignal(ProcessRef, SInt32 req); +IMPORT_C SInt32 SchedFireSignal(_Input ProcessRef, SInt32); -IMPORT_C SInt32 SchedReadMemory(ProcessRef, SInt32 address, SInt32 data); +IMPORT_C SInt32 SchedReadMemory(_Input ProcessRef, SInt32, SInt32); -IMPORT_C SInt32 SchedWriteMemory(ProcessRef, SInt32 address, SInt32 data); +IMPORT_C SInt32 SchedWriteMemory(_Input ProcessRef, SInt32, SInt32); -/// @brief Get current ProcessRef of process. -/// @return Current process ID. -IMPORT_C UIntPtr RtlCurrentPID(Void); +IMPORT_C UIntPtr SchedGetCurrentProcessID(Void); // ------------------------------------------------------------------------------------------ // // @brief Filesystem API. diff --git a/dev/user/src/SystemCalls+IO.asm b/dev/user/src/SystemCalls+IO.asm index 9126b7de..097046af 100644 --- a/dev/user/src/SystemCalls+IO.asm +++ b/dev/user/src/SystemCalls+IO.asm @@ -1,7 +1,7 @@ ;; /* ;; * ======================================================== ;; * -;; * user/src/SystemCalls+IO.asm +;; * libSystem/src/SystemCalls+IO.asm ;; * Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ;; * ;; * ======================================================== @@ -9,8 +9,6 @@ [bits 64] -;; @brief Syscall dispatch, also taking note the Microsoft's calling convention to translate it to NeKernel's ABI. - section .text global sci_syscall_arg_1 @@ -44,8 +42,6 @@ sci_syscall_arg_3: push rbp mov rbp, rsp - mov rbx, r8 - mov r8, rcx mov r9, rdx mov r10, rbx @@ -59,9 +55,6 @@ sci_syscall_arg_4: push rbp mov rbp, rsp - mov rbx, r8 - mov rax, r9 - mov r8, rcx mov r9, rdx mov r10, rbx diff --git a/public/tools/manual/.keep b/public/tools/manual/.keep new file mode 100644 index 00000000..e69de29b diff --git a/public/tools/manual/manual.json b/public/tools/manual/manual.json new file mode 100644 index 00000000..04626145 --- /dev/null +++ b/public/tools/manual/manual.json @@ -0,0 +1,19 @@ +{ + "compiler_path": "clang++", + "compiler_std": "c++20", + "headers_path": [ + "./", + "../../../dev/kernel", + "../../../public/frameworks/", + "../../../dev/", + "./" + ], + "sources_path": [], + "output_name": "./dist/manual", + "cpp_macros": [ + "kSampleFWVersion=0x0100", + "kSampleFWVersionHighest=0x0100", + "kSampleFWVersionLowest=0x0100", + "__NE_SDK__" + ] +} \ No newline at end of file diff --git a/public/tools/manual/src/.keep b/public/tools/manual/src/.keep new file mode 100644 index 00000000..e69de29b diff --git a/public/tools/manual/src/CommandLine.cc b/public/tools/manual/src/CommandLine.cc new file mode 100644 index 00000000..0d9c4136 --- /dev/null +++ b/public/tools/manual/src/CommandLine.cc @@ -0,0 +1,13 @@ +#include + +SInt32 _NeMain(SInt32 argc, Char* argv[]) { + SCI_UNUSED(argc); + SCI_UNUSED(argv); + + if (argc < 2) { + PrintOut(nullptr, "HELP: manual \n"); + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/public/tools/manual/vendor/.keep b/public/tools/manual/vendor/.keep new file mode 100644 index 00000000..e69de29b diff --git a/public/tools/ping/.keep b/public/tools/ping/.keep new file mode 100644 index 00000000..e69de29b diff --git a/public/tools/ping/ping.json b/public/tools/ping/ping.json new file mode 100644 index 00000000..d8d4133a --- /dev/null +++ b/public/tools/ping/ping.json @@ -0,0 +1,19 @@ +{ + "compiler_path": "clang++", + "compiler_std": "c++20", + "headers_path": [ + "./", + "../../../dev/kernel", + "../../../public/frameworks/", + "../../../dev/", + "./" + ], + "sources_path": [], + "output_name": "./dist/ping", + "cpp_macros": [ + "kSampleFWVersion=0x0100", + "kSampleFWVersionHighest=0x0100", + "kSampleFWVersionLowest=0x0100", + "__NE_SDK__" + ] +} \ No newline at end of file diff --git a/public/tools/ping/src/.keep b/public/tools/ping/src/.keep new file mode 100644 index 00000000..e69de29b diff --git a/public/tools/ping/src/CommandLine.cc b/public/tools/ping/src/CommandLine.cc new file mode 100644 index 00000000..9aae0ea9 --- /dev/null +++ b/public/tools/ping/src/CommandLine.cc @@ -0,0 +1,29 @@ +#include + +SInt32 _NeMain(SInt32 argc, Char* argv[]) { + SCI_UNUSED(argc); + + if (argc < 2) { + PrintOut(nullptr, "HELP: ping \n"); + return EXIT_FAILURE; + } + + PrintOut(nullptr, "Pinging %s...\n", argv[1]); + + for (SizeT i = 0U; i < 4; ++i) { + SInt32 result = 0; + + if (result != 0) { + PrintOut(nullptr, "Request timed out.\n"); + return EXIT_FAILURE; + } + + SInt32 bytes = 64; // Simulated response size + SInt32 time = 100 + (i * 10); // Simulated response time + SInt32 ttl = 64; + + PrintOut(nullptr, "Reply from %s: bytes=%i time=%ims TTL=%i\n", argv[1], bytes, time, ttl); + } + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/public/tools/ping/vendor/.keep b/public/tools/ping/vendor/.keep new file mode 100644 index 00000000..e69de29b diff --git a/tooling/mk_app.py b/tooling/mk_app.py index 9418cf05..a40c6dee 100755 --- a/tooling/mk_app.py +++ b/tooling/mk_app.py @@ -71,10 +71,10 @@ def create_directory_structure(base_path, project_name): if __name__ == "__main__": if len(sys.argv) != 2: - print("Usage: mk_app.py ") + print("HELP: mk_app.py ") sys.exit(os.EX_CONFIG) base_path = os.getcwd() # Use the current working directory as the base path create_directory_structure(base_path, sys.argv[1]) - print("Info: Application created successfully.") + print("INFO: Application created successfully.") diff --git a/tooling/mk_fwrk.py b/tooling/mk_fwrk.py index 3c73e88e..78659686 100755 --- a/tooling/mk_fwrk.py +++ b/tooling/mk_fwrk.py @@ -83,10 +83,10 @@ def create_directory_structure(base_path_fwrk, project_file_name, project_name): if __name__ == "__main__": if len(sys.argv) != 2: - print("Usage: mk_fwrk.py ") + print("HELP: mk_fwrk.py ") sys.exit(os.EX_CONFIG) base_path = os.getcwd() # Use the current working directory as the base path create_directory_structure(base_path, sys.argv[1], sys.argv[1] + '.fwrk') - print("Info: Framework created successfully.") + print("INFO: Framework created successfully.") diff --git a/tooling/mk_img.py b/tooling/mk_img.py index 539353fc..28af22e3 100755 --- a/tooling/mk_img.py +++ b/tooling/mk_img.py @@ -30,7 +30,7 @@ def copy_to_fat(image_path, source_dir): if __name__ == "__main__": if len(sys.argv) != 3: - print("Usage: mk_img.py ") + print("HELP: mk_img.py ") sys.exit(1) image_path = sys.argv[1] @@ -38,4 +38,4 @@ if __name__ == "__main__": copy_to_fat(image_path, source_dir) - print("Info: image created successfully.") + print("INFO: Image created successfully.") -- cgit v1.2.3