From a4d64ddc1375f40a4c72bd2ba9326df04058c9bb Mon Sep 17 00:00:00 2001 From: Amlal Date: Mon, 27 Jan 2025 15:09:24 +0100 Subject: Bump and fixes. Signed-off-by: Amlal --- dev/Boot/amd64-desktop.make | 11 +- dev/Boot/src/HEL/AMD64/EFIBootStartup.cc | 4 +- dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc | 4 +- dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cc | 38 --- dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc | 195 ------------ dev/Kernel/HALKit/AMD64/Storage/ATA.cc | 266 ++++++++++++++++ dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc | 336 --------------------- dev/Kernel/HALKit/AMD64/Storage/SATA.cc | 313 +++++++++++++++++++ dev/Kernel/src/Semaphore.cc | 4 +- dev/Kernel/src/UserProcessScheduler.cc | 27 +- dev/Mod/ACPI/ACPI.h | 2 + dev/Mod/AHCI/AHCI.h | 17 +- dev/Mod/ATA/ATA.h | 2 + 13 files changed, 624 insertions(+), 595 deletions(-) delete mode 100644 dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cc delete mode 100644 dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc create mode 100644 dev/Kernel/HALKit/AMD64/Storage/ATA.cc delete mode 100644 dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc create mode 100644 dev/Kernel/HALKit/AMD64/Storage/SATA.cc (limited to 'dev') diff --git a/dev/Boot/amd64-desktop.make b/dev/Boot/amd64-desktop.make index 4e817a43..14ed07cd 100644 --- a/dev/Boot/amd64-desktop.make +++ b/dev/Boot/amd64-desktop.make @@ -28,7 +28,7 @@ BIOS=OVMF.fd IMG=epm-master-1.img IMG_2=epm-master-2.img -EMU_FLAGS=-net none -smp 4 -m 8G -M q35 \ +EMU_FLAGS=-net none -smp 4 -m 8G \ -bios $(BIOS) -drive \ file=fat:rw:src/Root/,index=2,format=raw \ -d int @@ -82,14 +82,15 @@ compile-amd64: .PHONY: run-efi-amd64-ahci run-efi-amd64-ahci: - $(EMU) $(EMU_FLAGS) -device ahci,id=ahci0 \ - -drive id=disk,file=$(IMG),if=none,format=raw \ - -device ide-hd,drive=disk \ + $(EMU) $(EMU_FLAGS) -M q35 -drive file=$(IMG),format=raw,if=none,id=disk \ + -device ich9-ahci,id=ahci \ + -device ide-hd,drive=disk,bus=ahci.0 \ + -enable-kvm \ -s -S .PHONY: run-efi-amd64-ata run-efi-amd64-ata: - $(EMU) $(EMU_FLAGS) -device piix3-ide,id=ide -drive id=disk,file=$(IMG),format=raw,if=none -device ide-hd,drive=disk,bus=ide.0 -s -S + $(EMU) $(EMU_FLAGS) -enable-kvm -device piix4-ide,id=ide -drive id=disk,file=$(IMG),format=raw,if=none -device ide-hd,drive=disk,bus=ide.0 -s -S # img_2 is the rescue disk. img is the bootable disk, as provided by the Zeta specs. .PHONY: epm-img diff --git a/dev/Boot/src/HEL/AMD64/EFIBootStartup.cc b/dev/Boot/src/HEL/AMD64/EFIBootStartup.cc index d742b098..f653de52 100644 --- a/dev/Boot/src/HEL/AMD64/EFIBootStartup.cc +++ b/dev/Boot/src/HEL/AMD64/EFIBootStartup.cc @@ -221,6 +221,7 @@ EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr image_handle, syschk_thread->SetName("BootZ: System Recovery Check"); } +#if 0 Boot::BDiskFormatFactory partition_factory; if (syschk_thread->Start(handover_hdr, NO) != kEfiOk) @@ -236,7 +237,7 @@ EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr image_handle, const auto kFSName = "SSD"; - // partition_factory.Format(kFSName, &root, 1); + partition_factory.Format(kFSName, &root, 1); fb_init(); @@ -247,6 +248,7 @@ EFI_EXTERN_C EFI_API Int32 Main(EfiHandlePtr image_handle, fb_clear(); } } +#endif // ------------------------------------------ // // null these fields, to avoid being reused later. diff --git a/dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc b/dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc index 81479fc8..7f666012 100644 --- a/dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc +++ b/dev/Kernel/HALKit/AMD64/HalApplicationProcessor.cc @@ -57,7 +57,7 @@ namespace Kernel::HAL STATIC VoidPtr kRawMADT = nullptr; /// @brief Multiple APIC Descriptor Table. - struct PROCESS_APIC_MADT final : public SDT + struct PROCESS_APIC_MADT final SDT_OBJECT { UInt32 Address; // Madt address UInt8 Flags; // Madt flags @@ -246,7 +246,7 @@ namespace Kernel::HAL /// TODO: HAL helper to create an address. - hal_send_sipi(kApicBaseAddress, kAPICLocales[kSMPCount], (UInt8)(((UIntPtr)0x7c00) >> 12)); + hal_send_sipi(kApicBaseAddress, kAPICLocales[kSMPCount], (UInt8)(((UIntPtr)hal_ap_blob_start) >> 12)); ++kSMPCount; break; diff --git a/dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cc b/dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cc deleted file mode 100644 index 5f765d03..00000000 --- a/dev/Kernel/HALKit/AMD64/Storage/ATA-DMA.cc +++ /dev/null @@ -1,38 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. - -------------------------------------------- */ - -/** - * @file ATA-DMA.cc - * @author Amlal EL Mahrouss (amlalelmahrouss@icloud.com) - * @brief ATA driver (DMA mode). - * @version 0.1 - * @date 2024-02-02 - * - * @copyright Copyright (c) Amlal EL Mahrouss - * - */ - -#include - -#include -#include - -using namespace Kernel; - -EXTERN_C Int32 kPRDTTransferStatus; -STATIC PRDT kPRDT; - -#ifdef __ATA_DMA__ - -#ifdef __ATA_PIO__ -#error !!! You cant have both PIO and DMA enabled! !!! -#endif /* ifdef __ATA_PIO__ */ - -#ifdef __AHCI__ -#error !!! You cant have both ATA and AHCI enabled! !!! -#endif /* ifdef __AHCI__ */ - -#endif /* ifdef __ATA_DMA__ */ diff --git a/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc b/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc deleted file mode 100644 index 6e523cb7..00000000 --- a/dev/Kernel/HALKit/AMD64/Storage/ATA-PIO.cc +++ /dev/null @@ -1,195 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. - -------------------------------------------- */ - -/** - * @file ATA-PIO.cc - * @author Amlal EL Mahrouss (amlalelmahrouss@icloud.com) - * @brief ATA driver (PIO mode). - * @version 0.1 - * @date 2024-02-02 - * - * @copyright Copyright (c) Amlal EL Mahrouss - * - */ - -#include -#include - -#ifdef __ATA_PIO__ - -using namespace Kernel; -using namespace Kernel::HAL; - -/// bugs: 0 - -#define kATADataLen 256 - -STATIC Boolean kATADetected = false; -STATIC Int32 kATADeviceType = kATADeviceCount; -STATIC Char kATAData[kATADataLen] = {0}; - -Boolean drv_std_wait_io(UInt16 IO) -{ - for (int i = 0; i < 400; i++) - rt_in8(IO + ATA_REG_STATUS); - -ATAWaitForIO_Retry: - auto rdy = rt_in8(IO + ATA_REG_STATUS); - - if ((rdy & ATA_SR_BSY)) - goto ATAWaitForIO_Retry; - -ATAWaitForIO_Retry2: - rdy = rt_in8(IO + ATA_REG_STATUS); - - if (rdy & ATA_SR_ERR) - return false; - - if (!(rdy & ATA_SR_DRDY)) - goto ATAWaitForIO_Retry2; - - return true; -} - -Void drv_std_select(UInt16 Bus) -{ - if (Bus == ATA_PRIMARY_IO) - rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); - else - rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL); -} - -Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) -{ - UInt16 IO = Bus; - - drv_std_select(IO); - -ATAInit_Retry: - // Bus init, NEIN bit. - rt_out8(IO + ATA_REG_NEIN, 1); - - // identify until it's good - - auto rdy = rt_in8(IO + ATA_REG_STATUS); - - if (rdy & ATA_SR_ERR) - { - kcout << "ATA Error, aborting...\r"; - - return false; - } - - if ((rdy & ATA_SR_BSY)) - { - kcout << "Retrying as controller is busy...\r"; - goto ATAInit_Retry; - } - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - - /// fetch serial info - /// model, speed, number of sectors... - - drv_std_wait_io(IO); - - for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) - { - kATAData[indexData] = rt_in16(IO + ATA_REG_DATA); - } - - OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO; - - OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; - - return YES; -} - -Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) -{ - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - drv_std_wait_io(IO); - drv_std_select(IO); - - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz) / SectorSz)); - - rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF); - rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); - rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); - rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); - - drv_std_wait_io(IO); - - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) - { - drv_std_wait_io(IO); - Buf[IndexOff] = rt_in16(IO + ATA_REG_DATA); - drv_std_wait_io(IO); - } - - drv_std_wait_io(IO); -} - -Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) -{ - Lba /= SectorSz; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - drv_std_wait_io(IO); - drv_std_select(IO); - - rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); - - rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz)) / SectorSz)); - - rt_out8(IO + ATA_REG_LBA0, (Lba) & 0xFF); - rt_out8(IO + ATA_REG_LBA1, (Lba) >> 8); - rt_out8(IO + ATA_REG_LBA2, (Lba) >> 16); - rt_out8(IO + ATA_REG_LBA3, (Lba) >> 24); - - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); - - drv_std_wait_io(IO); - - for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) - { - drv_std_wait_io(IO); - rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]); - drv_std_wait_io(IO); - } - - drv_std_wait_io(IO); -} - -/// @brief is ATA detected? -Boolean drv_std_detected(Void) -{ - return kATADetected; -} - -/*** - @brief Getter, gets the number of sectors inside the drive. -*/ -Kernel::SizeT drv_get_sector_count() -{ - return (kATAData[61] << 16) | kATAData[60]; -} - -/// @brief Get the drive size. -Kernel::SizeT drv_get_size() -{ - return (drv_get_sector_count()) * kATASectorSize; -} - -#endif /* ifdef __ATA_PIO__ */ diff --git a/dev/Kernel/HALKit/AMD64/Storage/ATA.cc b/dev/Kernel/HALKit/AMD64/Storage/ATA.cc new file mode 100644 index 00000000..a3e8f4ab --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/Storage/ATA.cc @@ -0,0 +1,266 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +/** + * @file ATA-PIO.cc + * @author Amlal EL Mahrouss (amlalelmahrouss@icloud.com) + * @brief ATA driver (PIO mode). + * @version 0.1 + * @date 2024-02-02 + * + * @copyright Copyright (c) Amlal EL Mahrouss + * + */ + +#include +#include + +#if defined(__ATA_PIO__) || defined(__ATA_DMA__) + +using namespace Kernel; +using namespace Kernel::HAL; + +/// bugs: 0 + +#define kATADataLen 256 + +STATIC Boolean kATADetected = false; +STATIC Int32 kATADeviceType = kATADeviceCount; +STATIC Char kATAData[kATADataLen] = {0}; + +Boolean drv_std_wait_io(UInt16 IO) +{ + for (int i = 0; i < 400; i++) + rt_in8(IO + ATA_REG_STATUS); + +ATAWaitForIO_Retry: + auto rdy = rt_in8(IO + ATA_REG_STATUS); + + if ((rdy & ATA_SR_BSY)) + goto ATAWaitForIO_Retry; + +ATAWaitForIO_Retry2: + rdy = rt_in8(IO + ATA_REG_STATUS); + + if (rdy & ATA_SR_ERR) + return false; + + if (!(rdy & ATA_SR_DRDY)) + goto ATAWaitForIO_Retry2; + + return true; +} + +Void drv_std_select(UInt16 Bus) +{ + if (Bus == ATA_PRIMARY_IO) + rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); + else + rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL); +} + +Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) +{ + UInt16 IO = Bus; + drv_std_select(IO); + + // Step 1: Wait until drive is not busy + int timeout = 100000; + while ((rt_in8(IO + ATA_REG_STATUS) & ATA_SR_BSY) && --timeout) + ; + if (!timeout) + { + kcout << "Timeout waiting for drive to become ready...\r"; + return false; + } + + // Step 2: Send IDENTIFY command + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); + + // Step 3: Wait for the drive to be ready (not busy) + drv_std_wait_io(IO); + + // Step 4: Check for errors + UInt8 status = rt_in8(IO + ATA_REG_STATUS); + if (status & ATA_SR_ERR) + { + kcout << "ATA Error, aborting...\r"; + return false; + } + + // Step 5: Read IDENTIFY DEVICE response + for (SizeT indexData = 0UL; indexData < kATADataLen; ++indexData) + { + kATAData[indexData] = rt_in16(IO + ATA_REG_DATA); + } + + // Step 6: Set OutBus & OutMaster correctly + OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO; + OutMaster = (Drive == ATA_MASTER) ? ATA_MASTER : ATA_SLAVE; + +#ifdef __ATA_DMA__ + // Step 7: Check if the drive supports DMA + if (!(kATAData[63] & (1 << 8)) || !(kATAData[88] & 0xFF)) + { + kcout << "No DMA support, falling back to PIO...\r"; + return false; // Or switch to PIO mode if needed + } + + // Step 8: Enable DMA Mode + rt_out8(IO + ATA_REG_FEATURES, 0x03); // Enable DMA mode + rt_out8(IO + ATA_REG_COMMAND, ATA_REG_SET_FEATURES); // Send set features command + + // Step 9: Wait for drive to acknowledge DMA setting + timeout = 100000; + while (!(rt_in8(IO + ATA_REG_STATUS) & ATA_SR_DRDY) && --timeout) + ; + if (!timeout) + { + kcout << "DMA Initialization Timeout...\r"; + return false; + } +#endif // __ATA_DMA__ + + return YES; +} + +namespace Details +{ + using namespace Kernel; + + struct __attribute__((packed, aligned(4))) PRD final + { + UInt32 mAddress; + UInt16 mByteCount; + UInt16 mFlags; + }; +} // namespace Details + +Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) +{ + Lba /= SectorSz; + + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + +#ifdef __ATA_PIO__ + drv_std_wait_io(IO); +#endif + + drv_std_select(IO); + + rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); + + rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + SectorSz - 1) / 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); + +#ifdef __ATA_PIO__ + rt_out8(ATA_REG_COMMAND, ATA_CMD_READ_PIO); + + drv_std_wait_io(IO); + + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) + { + drv_std_wait_io(IO); + rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]); + drv_std_wait_io(IO); + } +#else + if (Size > kib_cast(64)) + ke_panic(RUNTIME_CHECK_FAILED, "ATA-DMA only supports < 64kb DMA transfers."); + + Details::PRD* prd = (Details::PRD*)mib_cast(4); + prd->mAddress = (UInt32)(UIntPtr)Buf; + prd->mByteCount = Size; + prd->mFlags = 0x8000; + + rt_out32(IO + 0x04, (UInt32)(UIntPtr)prd); + + rt_out8(IO + 0x00, 0x09); // Start DMA engine + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_DMA); + + while (rt_in8(ATA_REG_STATUS) & 0x01) + ; + rt_out8(IO + 0x00, 0x00); // Start DMA engine +#endif // __ATA_PIO__ +} + +Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) +{ + Lba /= SectorSz; + + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + +#ifdef __ATA_PIO__ + drv_std_wait_io(IO); +#endif + + drv_std_select(IO); + + rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); + + rt_out8(IO + ATA_REG_SEC_COUNT0, ((Size + (SectorSz - 1)) / 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); + +#ifdef __ATA_PIO__ + rt_out8(ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); + + drv_std_wait_io(IO); + + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) + { + drv_std_wait_io(IO); + rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]); + drv_std_wait_io(IO); + } +#else + if (Size > kib_cast(64)) + ke_panic(RUNTIME_CHECK_FAILED, "ATA-DMA only supports < 64kb DMA transfers."); + + Details::PRD* prd = (Details::PRD*)mib_cast(4); + prd->mAddress = (UInt32)(UIntPtr)Buf; + prd->mByteCount = Size; + prd->mFlags = 0x8000; + + rt_out32(IO + 0x04, (UInt32)(UIntPtr)prd); + + rt_out8(IO + 0x00, 0x09); // Start DMA engine + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_DMA); + + while (rt_in8(ATA_REG_STATUS) & 0x01) + ; + rt_out8(IO + 0x00, 0x00); // Start DMA engine +#endif // __ATA_PIO__ +} + +/// @brief is ATA detected? +Boolean drv_std_detected(Void) +{ + return kATADetected; +} + +/*** + @brief Getter, gets the number of sectors inside the drive. +*/ +Kernel::SizeT drv_get_sector_count() +{ + return (kATAData[61] << 16) | kATAData[60]; +} + +/// @brief Get the drive size. +Kernel::SizeT drv_get_size() +{ + return (drv_get_sector_count()) * kATASectorSize; +} + +#endif /* ifdef __ATA_PIO__ */ diff --git a/dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc b/dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc deleted file mode 100644 index 767f83e5..00000000 --- a/dev/Kernel/HALKit/AMD64/Storage/SATA-DMA.cc +++ /dev/null @@ -1,336 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. - -------------------------------------------- */ - -/** - * @file AHCI.cc - * @author Amlal EL Mahrouss (amlalelmahrouss@icloud.com) - * @brief AHCI driver. - * @version 0.1 - * @date 2024-02-02 - * - * @Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. - * - */ - -#include "HALKit/AMD64/Processor.h" -#include "KernelKit/DebugOutput.h" -#include "KernelKit/MemoryMgr.h" -#include "NewKit/Defines.h" -#include -#include - -#include -#include -#include -#include -#include - -#ifdef __AHCI__ - -#define kHBAErrTaskFile (1 << 30) -#define kHBAPxCmdST 0x0001 -#define kHBAPxCmdFre 0x0010 -#define kHBAPxCmdFR 0x4000 -#define kHBAPxCmdCR 0x8000 - -#define kSataLBAMode (1 << 6) - -#define kAhciSRBsy (0x80) -#define kAhciSRDrq (0x08) - -#define kAhciPortCnt 32 - -enum -{ - kSATAProgIfAHCI = 0x01, - kSATASubClass = 0x06, - kSATABar5 = 0x24, -}; - -STATIC Kernel::PCI::Device kPCIDevice; -STATIC HbaMem* kSATAPort = nullptr; -STATIC Kernel::SizeT kSATAPortIdx = 0UL; -STATIC Kernel::Lba kCurrentDiskSectorCount = 0UL; -STATIC Kernel::Char kModel[41] = {0}; - -template -static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) noexcept; - -static Kernel::Int32 drv_find_cmd_slot(HbaPort* port) noexcept; - -static Kernel::Void drv_calculate_disk_geometry() noexcept; - -static Kernel::Void drv_calculate_disk_geometry() noexcept -{ - kCurrentDiskSectorCount = 0UL; - - Kernel::UInt8 __attribute__((aligned(4096))) identify_data[kib_cast(4)] = {}; - - drv_std_input_output(0, identify_data, 0, kib_cast(8)); - - if (!(identify_data[83] & (1 << 10))) - { - kCurrentDiskSectorCount = identify_data[61] << 16; - kCurrentDiskSectorCount |= identify_data[60]; - } - else - { - kCurrentDiskSectorCount = (identify_data[103] << 48) | (identify_data[102] << 32) | (identify_data[101] << 16) | (identify_data[100]); - } - - for (Kernel::Int32 i = 0; i < 40; i += 2) - { - Kernel::Char temp = identify_data[54 + i]; - identify_data[54 + i] = identify_data[54 + i + 1]; - identify_data[54 + i + 1] = temp; - } - - Kernel::rt_copy_memory((Kernel::Char*)(identify_data + 54), kModel, 40); - kModel[40] = '\0'; - - kcout << "Disk Model: " << kModel << endl; - kcout << "Disk Size: " << Kernel::number(drv_get_size()) << endl; - kcout << "Disk Highest LBA: " << Kernel::number(kCurrentDiskSectorCount) << endl; -} - -/// @brief Initializes an AHCI disk. -/// @param PortsImplemented the amount of kSATAPort that have been detected. -/// @return if the disk was successfully initialized or not. -Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) -{ - using namespace Kernel; - - PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController); - - for (SizeT device_index = 0; device_index < ZKA_BUS_COUNT; ++device_index) - { - kPCIDevice = iterator[device_index].Leak(); // And then leak the reference. - - // if SATA and then interface is AHCI... - if (kPCIDevice.Subclass() == kSATASubClass && - kPCIDevice.ProgIf() == kSATAProgIfAHCI) - { - HbaMem* mem_ahci = (HbaMem*)kPCIDevice.Bar(kSATABar5); - - kPCIDevice.EnableMmio(kSATABar5); // Enable the memory index_byte/o for this ahci device. - kPCIDevice.BecomeBusMaster(kSATABar5); // Become bus master for this ahci device, so that we can control it. - - Kernel::UInt32 ports_implemented = mem_ahci->Pi; - Kernel::UInt16 ahci_index = 0; - - const Kernel::UInt16 kMaxPortsImplemented = kAhciPortCnt; - const Kernel::UInt32 kSATASignature = 0x00000101; - const Kernel::UInt8 kAhciPresent = 0x03; - const Kernel::UInt8 kAhciIPMActive = 0x01; - - Kernel::Boolean detected = false; - - while (ahci_index < kMaxPortsImplemented) - { - if (ports_implemented) - { - kcout << "Port is implemented.\r"; - - Kernel::UInt8 ipm = (mem_ahci->Ports[ahci_index].Ssts >> 8) & 0x0F; - Kernel::UInt8 det = mem_ahci->Ports[ahci_index].Ssts & 0x0F; - - if (mem_ahci->Ports[ahci_index].Sig == kSATASignature && det == 3 && ipm == 1) - { - kcout << "Port is SATA.\r"; - - kSATAPortIdx = ahci_index; - kSATAPort = mem_ahci; - - kSATAPort->Ports[kSATAPortIdx].Cmd &= ~kHBAPxCmdST; - kSATAPort->Ports[kSATAPortIdx].Cmd &= ~kHBAPxCmdFre; - - while (YES) - { - if (kSATAPort->Ports[kSATAPortIdx].Cmd & kHBAPxCmdFR) - continue; - if (kSATAPort->Ports[kSATAPortIdx].Cmd & kHBAPxCmdCR) - continue; - - break; - } - - const auto kAHCIBaseAddress = mib_cast(4); - - kSATAPort->Ports[kSATAPortIdx].Clb = kAHCIBaseAddress + (kSATAPortIdx << 10); - - rt_set_memory((VoidPtr)((UIntPtr)kSATAPort->Ports[kSATAPortIdx].Clb), 0, 1024); - - kSATAPort->Ports[kSATAPortIdx].Fb = kAHCIBaseAddress + (32 << 10) + (kSATAPortIdx << 8); - kSATAPort->Ports[kSATAPortIdx].Fbu = 0; - - rt_set_memory((VoidPtr)((UIntPtr)kSATAPort->Ports[kSATAPortIdx].Fb), 0, 256); - - HbaCmdHeader* cmd_header = (HbaCmdHeader*)((UIntPtr)kSATAPort->Ports[kSATAPortIdx].Clb); - - for (Int32 i = 0; i < kMaxPortsImplemented; i++) - { - cmd_header[i].Prdtl = 1; - cmd_header[i].Ctba = kAHCIBaseAddress + (40 << 10) + (kSATAPortIdx << 13) + (i << 8); - - rt_set_memory((VoidPtr)(UIntPtr)cmd_header[i].Ctba, 0, 256); - } - - while (kSATAPort->Ports[kSATAPortIdx].Cmd & kHBAPxCmdCR) - ; - - kSATAPort->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdFre; - kSATAPort->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdST; - - // Enable AHCI Mode FIRST - kSATAPort->Ghc |= (1 >> 31); - - drv_calculate_disk_geometry(); - - return YES; - } - } - - ports_implemented >>= 1; - ++ahci_index; - } - } - } - - return NO; -} - -Kernel::Boolean drv_std_detected(Kernel::Void) -{ - return kPCIDevice.DeviceId() != 0xFFFF; -} - -Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) -{ - drv_std_input_output(lba, (Kernel::UInt8*)buffer, sector_sz, size_buffer / sector_sz); -} - -Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) -{ - drv_std_input_output(lba, (Kernel::UInt8*)buffer, sector_sz, size_buffer / sector_sz); -} - -static Kernel::Int32 drv_find_cmd_slot(HbaPort* port) noexcept -{ - if (port == nullptr) - return -1; - - Kernel::UInt32 slots = (kSATAPort->Ports[kSATAPortIdx].Sact | kSATAPort->Ports[kSATAPortIdx].Ci); - - for (Kernel::Int32 i = 0; i < ((kSATAPort->Cap & 0x1F) + 1); i++) - { - if ((slots & 1) == 0) - return i; - - slots >>= 1; - } - - return -1; -} - -template -static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) noexcept -{ - if (!CommandOrCTRL) - return; - - auto slot = 0L; - - slot = drv_find_cmd_slot(&kSATAPort->Ports[kSATAPortIdx]); - - if (slot == -1) - return; - - kcout << "Reading AHCI disk...\r"; - - volatile HbaCmdHeader* command_header = ((volatile HbaCmdHeader*)((Kernel::UInt64)kSATAPort->Ports[kSATAPortIdx].Clb + slot * sizeof(HbaCmdHeader))); - - Kernel::rt_set_memory((void*)command_header, 0, sizeof(HbaCmdTbl)); - - MUST_PASS(command_header); - - command_header->Cfl = sizeof(FisRegH2D) / sizeof(Kernel::UInt32); - command_header->Write = Write; - command_header->Prdtl = 1; - command_header->Ctba = (Kernel::UIntPtr)Kernel::mm_new_heap(sizeof(HbaCmdTbl), YES, NO); - - volatile HbaCmdTbl* command_table = (volatile HbaCmdTbl*)((Kernel::UInt64)command_header->Ctba); - - Kernel::rt_set_memory((void*)command_table, 0, sizeof(HbaCmdTbl)); - - MUST_PASS(command_table); - - command_table->PrdtEntries->Dba = (Kernel::UInt64)buffer; - command_table->PrdtEntries->Dbc = (size_buffer * sector_sz) - 1; - command_table->PrdtEntries->InterruptBit = YES; - kcout << "PRDT Entry 0 - Dba: " << Kernel::hex_number(command_table->PrdtEntries->Dba) << endl; - kcout << "PRDT Entry 0 - Dbc: " << Kernel::hex_number(command_table->PrdtEntries->Dbc) << endl; - - volatile FisRegH2D* h2d_fis = (volatile FisRegH2D*)(command_table->Cfis); - - Kernel::rt_set_memory((void*)h2d_fis, 0, sizeof(FisRegH2D)); - - h2d_fis->FisType = kFISTypeRegH2D; - - h2d_fis->CmdOrCtrl = CommandOrCTRL; - - h2d_fis->Command = Write ? kAHCICmdWriteDmaEx : kAHCICmdReadDmaEx; - - if (Identify) - h2d_fis->Command = kAHCICmdIdentify; - - h2d_fis->Lba0 = (Kernel::UInt32)(lba) & 0xFF; - h2d_fis->Lba1 = (Kernel::UInt8)(lba >> 8) & 0xFF; - h2d_fis->Lba2 = (Kernel::UInt8)(lba >> 16) & 0xFF; - - h2d_fis->Lba3 = (Kernel::UInt8)(lba >> 24) & 0xFF; - h2d_fis->Lba4 = (Kernel::UInt8)(lba >> 32) & 0xFF; - h2d_fis->Lba5 = (Kernel::UInt8)(lba >> 40) & 0xFF; - - h2d_fis->Device = kSataLBAMode; - - h2d_fis->CountLow = sector_sz & 0xFF; - h2d_fis->CountHigh = (sector_sz >> 8) & 0xFF; - - while ((kSATAPort->Ports[kSATAPortIdx].Tfd & (kAhciSRBsy | kAhciSRDrq))) - { - kcout << "waiting for slot to be ready\r\n"; - } - - kSATAPort->Ports[kSATAPortIdx].Ci = 1 << slot; - - while (kSATAPort->Ports[kSATAPortIdx].Ci & (1 << slot)) - { - Kernel::UInt32 tfd = kSATAPort->Ports[kSATAPortIdx].Tfd; - kcout << "AHCI TFD: " << Kernel::number(tfd) << endl; - } - - kcout << "Last Command Sent: " << (int)Kernel::number(h2d_fis->Command) << endl; - - Kernel::mm_delete_heap((Kernel::VoidPtr)command_header->Ctba); -} - -/*** - @brief Gets the number of sectors inside the drive. - @return Sector size in bytes. - */ -Kernel::SizeT drv_get_sector_count() -{ - return kCurrentDiskSectorCount; -} - -/// @brief Get the drive size. -/// @return Disk size in bytes. -Kernel::SizeT drv_get_size() -{ - return (drv_get_sector_count()) * kAHCISectorSize; -} - -#endif // ifdef __AHCI__ diff --git a/dev/Kernel/HALKit/AMD64/Storage/SATA.cc b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc new file mode 100644 index 00000000..d2c0ee5b --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc @@ -0,0 +1,313 @@ +/* ------------------------------------------- + + Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + +------------------------------------------- */ + +/** + * @file AHCI.cc + * @author Amlal EL Mahrouss (amlalelmahrouss@icloud.com) + * @brief AHCI driver. + * @version 0.1 + * @date 2024-02-02 + * + * @Copyright (C) 2024, Amlal EL Mahrouss, all rights reserved. + * + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef __AHCI__ + +#define kHBAErrTaskFile (1 << 30) +#define kHBAPxCmdST 0x0001 +#define kHBAPxCmdFre 0x0010 +#define kHBAPxCmdFR 0x4000 +#define kHBAPxCmdCR 0x8000 + +#define kSataLBAMode (1 << 6) + +#define kAhciSRBsy (0x80) +#define kAhciSRDrq (0x08) + +#define kAhciPortCnt 32 + +enum +{ + kSATAProgIfAHCI = 0x01, + kSATASubClass = 0x06, + kSATABar5 = 0x24, +}; + +STATIC Kernel::PCI::Device kPCIDevice; +STATIC HbaMem* kSATAPort = nullptr; +STATIC Kernel::SizeT kSATAPortIdx = 0UL; +STATIC Kernel::Lba kCurrentDiskSectorCount = 0UL; +STATIC Kernel::Char kModel[41] = {0}; + +template +static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) noexcept; + +static Kernel::Int32 drv_find_cmd_slot(HbaPort* port) noexcept; + +static Kernel::Void drv_calculate_disk_geometry() noexcept; + +static Kernel::Void drv_calculate_disk_geometry() noexcept +{ + kCurrentDiskSectorCount = 0UL; + + Kernel::UInt8 __attribute__((aligned(4096))) identify_data[kib_cast(4)] = {}; + + drv_std_input_output(0, identify_data, 0, kib_cast(4)); + + uint32_t lba28_sectors = (identify_data[61] << 16) | identify_data[60]; + + uint64_t lba48_sectors = ((uint64_t)identify_data[103] << 48) | + ((uint64_t)identify_data[102] << 32) | + ((uint64_t)identify_data[101] << 16) | + ((uint64_t)identify_data[100]); + + kCurrentDiskSectorCount = (lba48_sectors) ? lba48_sectors : lba28_sectors; + + for (Kernel::Int32 i = 0; i < 40; i += 2) + { + Kernel::Char temp = identify_data[54 + i]; + identify_data[54 + i] = identify_data[54 + i + 1]; + identify_data[54 + i + 1] = temp; + } + + Kernel::rt_copy_memory((Kernel::Char*)(identify_data + 54), kModel, 40); + kModel[40] = '\0'; + + kcout << "Disk Model: " << kModel << endl; + kcout << "Disk Size: " << Kernel::number(drv_get_size()) << endl; + kcout << "Disk Highest LBA: " << Kernel::number(kCurrentDiskSectorCount) << endl; +} + +/// @brief Initializes an AHCI disk. +/// @param PortsImplemented the amount of kSATAPort that have been detected. +/// @return if the disk was successfully initialized or not. +Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) +{ + using namespace Kernel; + + PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController); + + for (SizeT device_index = 0; device_index < ZKA_BUS_COUNT; ++device_index) + { + kPCIDevice = iterator[device_index].Leak(); // And then leak the reference. + + // if SATA and then interface is AHCI... + if (kPCIDevice.Subclass() == kSATASubClass && + kPCIDevice.ProgIf() == kSATAProgIfAHCI) + { + HbaMem* mem_ahci = (HbaMem*)kPCIDevice.Bar(kSATABar5); + + kPCIDevice.EnableMmio(kSATABar5); // Enable the memory index_byte/o for this ahci device. + kPCIDevice.BecomeBusMaster(kSATABar5); // Become bus master for this ahci device, so that we can control it. + + Kernel::UInt32 ports_implemented = mem_ahci->Pi; + Kernel::UInt16 ahci_index = 0; + + const Kernel::UInt16 kMaxPortsImplemented = kAhciPortCnt; + const Kernel::UInt32 kSATASignature = 0x00000101; + const Kernel::UInt8 kAhciPresent = 0x03; + const Kernel::UInt8 kAhciIPMActive = 0x01; + + Kernel::Boolean detected = false; + + while (ahci_index < kMaxPortsImplemented) + { + if (ports_implemented) + { + kcout << "Port is implemented.\r"; + + Kernel::UInt8 ipm = (mem_ahci->Ports[ahci_index].Ssts >> 8) & 0x0F; + Kernel::UInt8 det = mem_ahci->Ports[ahci_index].Ssts & 0x0F; + + if (mem_ahci->Ports[ahci_index].Sig == kSATASignature && det == 3 && ipm == 1) + { + kcout << "Port is SATA.\r"; + + kSATAPortIdx = ahci_index; + kSATAPort = mem_ahci; + + // Enable AHCI Mode FIRST + kSATAPort->Ghc |= (1 << 31); + + const int timeout = 1000000; + int attempts = 0; + while ((kSATAPort->Ports[kSATAPortIdx].Tfd & 0x80) && (attempts < timeout)) + { + attempts++; + } + if (attempts == timeout) + { + kcout << "Error: Drive is still busy after waiting.\r"; + return NO; + } + + kSATAPort->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdST; + kSATAPort->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdFre; + + drv_calculate_disk_geometry(); + + return YES; + } + } + + ports_implemented >>= 1; + ++ahci_index; + } + } + } + + return NO; +} + +Kernel::Boolean drv_std_detected(Kernel::Void) +{ + return kPCIDevice.DeviceId() != 0xFFFF; +} + +Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) +{ + drv_std_input_output(lba, (Kernel::UInt8*)buffer, sector_sz, size_buffer); +} + +Kernel::Void drv_std_read(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) +{ + drv_std_input_output(lba, (Kernel::UInt8*)buffer, sector_sz, size_buffer); +} + +static Kernel::Int32 drv_find_cmd_slot(HbaPort* port) noexcept +{ + if (port == nullptr) + return -1; + + kcout << "Finding a slot..."; + + Kernel::UInt32 slots = (kSATAPort->Ports[kSATAPortIdx].Sact | kSATAPort->Ports[kSATAPortIdx].Ci); + + for (Kernel::Int32 i = 0; i < ((kSATAPort->Cap & 0x1F) + 1); i++) + { + if ((slots & (1 << i)) == 0) + return i; + } + + return -1; +} + +template +static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) noexcept +{ + if (!CommandOrCTRL) + return; + + auto slot = 0L; + + slot = drv_find_cmd_slot(&kSATAPort->Ports[kSATAPortIdx]); + + if (slot == -1) + return; + + kcout << "Reading AHCI disk...\r"; + + volatile HbaCmdHeader* command_header = ((volatile HbaCmdHeader*)((Kernel::UInt64)kSATAPort->Ports[kSATAPortIdx].Clb)); + command_header += slot; + + MUST_PASS(command_header); + + command_header->Cfl = sizeof(FisRegH2D) / sizeof(Kernel::UInt32); + command_header->Write = Write; + command_header->Prdtl = mib_cast(32) / mib_cast(4); + command_header->Prdbc = (1 << slot); + + volatile HbaCmdTbl* command_table = (volatile HbaCmdTbl*)((Kernel::UInt64)command_header->Ctba); + + Kernel::rt_set_memory((void*)command_table, 0, sizeof(HbaCmdTbl)); + + MUST_PASS(command_table); + + command_table->Prdt[0].Dba = (Kernel::UInt32)((Kernel::UInt64)buffer); + command_table->Prdt[0].Dbau = (Kernel::UInt32)(((Kernel::UInt64)buffer >> 32)); + command_table->Prdt[0].Dbc = size_buffer; + command_table->Prdt[0].InterruptBit = YES; // Ensure Interrupt-On-Completion is set + + // Debug PRDT entry + kcout << "PRDT Entry - Dba (Low): " << Kernel::hex_number(command_table->Prdt[0].Dba) << endl; + kcout << "PRDT Entry - DbaU (High): " << Kernel::hex_number(command_table->Prdt[0].Dbau) << endl; + kcout << "PRDT Entry - Dbc: " << Kernel::hex_number(command_table->Prdt[0].Dbc) << endl; + + volatile FisRegH2D* h2d_fis = (volatile FisRegH2D*)(&command_table->Cfis); + + Kernel::rt_set_memory((void*)h2d_fis, 0, sizeof(FisRegH2D)); + + h2d_fis->FisType = 0x27; + h2d_fis->CmdOrCtrl = 1; + + h2d_fis->Command = Write ? kAHCICmdWriteDmaEx : kAHCICmdReadDmaEx; + + if (Identify) + h2d_fis->Command = kAHCICmdIdentify; + + h2d_fis->Lba0 = (Kernel::UInt32)(lba) & 0xFF; + h2d_fis->Lba1 = (Kernel::UInt8)(lba >> 8) & 0xFF; + h2d_fis->Lba2 = (Kernel::UInt8)(lba >> 16) & 0xFF; + + h2d_fis->Lba3 = (Kernel::UInt8)(lba >> 24) & 0xFF; + h2d_fis->Lba4 = (Kernel::UInt8)(lba >> 32) & 0xFF; + h2d_fis->Lba5 = (Kernel::UInt8)(lba >> 40) & 0xFF; + + h2d_fis->Device = kSataLBAMode; + + h2d_fis->CountLow = sector_sz & 0xFF; + h2d_fis->CountHigh = (sector_sz >> 8) & 0xFF; + + while ((kSATAPort->Ports[kSATAPortIdx].Tfd & (kAhciSRBsy | kAhciSRDrq))) + { + kcout << "waiting for slot to be ready\r\n"; + } + + Kernel::UInt32 ahci_status = kSATAPort->Ports[kSATAPortIdx].Tfd; + kcout << "AHCI Status Before Write: " << Kernel::hex_number(ahci_status) << endl; + + kSATAPort->Ports[kSATAPortIdx].Ci = 1 << slot; + + while (kSATAPort->Ports[kSATAPortIdx].Ci & (1 << slot)) + { + Kernel::UInt32 tfd = kSATAPort->Ports[kSATAPortIdx].Tfd; + kcout << "AHCI TFD: " << Kernel::number(tfd) << endl; + } + + kcout << "Last Command Sent: " << (int)Kernel::number(h2d_fis->Command) << endl; + + ahci_status = kSATAPort->Ports[kSATAPortIdx].Tfd; + kcout << "AHCI Status Before Write: " << Kernel::hex_number(ahci_status) << endl; +} + +/*** + @brief Gets the number of sectors inside the drive. + @return Sector size in bytes. + */ +Kernel::SizeT drv_get_sector_count() +{ + return kCurrentDiskSectorCount; +} + +/// @brief Get the drive size. +/// @return Disk size in bytes. +Kernel::SizeT drv_get_size() +{ + return (drv_get_sector_count()) * kAHCISectorSize; +} + +#endif // ifdef __AHCI__ diff --git a/dev/Kernel/src/Semaphore.cc b/dev/Kernel/src/Semaphore.cc index 07434e75..d0498b28 100644 --- a/dev/Kernel/src/Semaphore.cc +++ b/dev/Kernel/src/Semaphore.cc @@ -16,7 +16,7 @@ namespace Kernel { if (fLockingProcess) { - fLockingProcess = UserProcess(); + fLockingProcess = UserProcess(); fLockingProcess.Status = ProcessStatusKind::kFrozen; return Yes; } @@ -42,7 +42,7 @@ namespace Kernel /***********************************************************************************/ Bool Semaphore::IsLocked() const { - return fLockingProcess->Status == ProcessStatusKind::kRunning; + return fLockingProcess.Status == ProcessStatusKind::kRunning; } /***********************************************************************************/ diff --git a/dev/Kernel/src/UserProcessScheduler.cc b/dev/Kernel/src/UserProcessScheduler.cc index a0b160ad..dbe0471b 100644 --- a/dev/Kernel/src/UserProcessScheduler.cc +++ b/dev/Kernel/src/UserProcessScheduler.cc @@ -400,20 +400,25 @@ namespace Kernel return Yes; } + /// @brief Is it a user scheduler? + const Bool UserProcessScheduler::IsUser() { return Yes; } + /// @brief Is it a kernel scheduler? + const Bool UserProcessScheduler::IsKernel() { return No; } + /// @brief Is it a SMP scheduler? + const Bool UserProcessScheduler::HasMP() { - MUST_PASS(kHandoverHeader); - return kHandoverHeader->f_HardwareTables.f_MultiProcessingEnabled; + return Yes; } /***********************************************************************************/ @@ -423,13 +428,13 @@ namespace Kernel const SizeT UserProcessScheduler::Run() noexcept { - SizeT process_index = 0; //! we store this guy to tell the scheduler how many - //! things we have scheduled. + SizeT process_index = 0UL; //! we store this guy to tell the scheduler how many + //! things we have scheduled. if (mTeam.mProcessCount < 1) { kcout << "UserProcessScheduler::Run(): This team doesn't have any process!\r"; - return 0; + return 0UL; } kcout << "UserProcessScheduler::Run(): This team has a process capacity of: " << number(mTeam.mProcessList.Capacity()) << endl; @@ -449,10 +454,16 @@ namespace Kernel kcout << "Switch to: '" << process.Name << "'.\r"; // tell helper to find a core to schedule on. - if (!UserProcessHelper::Switch(process.Image.fCode, &process.StackReserve[process.StackSize - 1], process.StackFrame, - process.ProcessId)) + BOOL ret = UserProcessHelper::Switch(process.Image.fCode, &process.StackReserve[process.StackSize - 1], process.StackFrame, + process.ProcessId); + + if (!ret) { - kcout << "Invalid process (UH OH)\r"; + if (process.Affinity == AffinityKind::kRealTime) + continue; + + kcout << "The process: " << process.Name << ", is not valid! Crashing it...\r"; + process.Crash(); } } diff --git a/dev/Mod/ACPI/ACPI.h b/dev/Mod/ACPI/ACPI.h index 3a895430..a07f4b60 100644 --- a/dev/Mod/ACPI/ACPI.h +++ b/dev/Mod/ACPI/ACPI.h @@ -13,6 +13,8 @@ #include +#define SDT_OBJECT : public Kernel::SDT + namespace Kernel { class PACKED SDT diff --git a/dev/Mod/AHCI/AHCI.h b/dev/Mod/AHCI/AHCI.h index 7b50d461..937be6d2 100644 --- a/dev/Mod/AHCI/AHCI.h +++ b/dev/Mod/AHCI/AHCI.h @@ -284,10 +284,10 @@ typedef struct HbaCmdHeader final Kernel::UInt8 Reserved0 : 1; // Reserved Kernel::UInt8 Pmp : 4; // Port multiplier port - Kernel::UInt16 Prdtl; // Physical region descriptor table length in entries - volatile Kernel::UInt32 Prdbc; // Physical region descriptor byte count transferred + Kernel::UInt16 Prdtl; // Physical region descriptor table length in entries + Kernel::UInt32 Prdbc; // Physical region descriptor byte count transferred - Kernel::UInt64 Ctba; // Command table descriptor base address + Kernel::UInt32 Ctba; // Command table descriptor base address Kernel::UInt32 Reserved1[4]; // Reserved } HbaCmdHeader; @@ -313,7 +313,8 @@ typedef struct HbaFis final typedef struct HbaPrdtEntry final { - Kernel::UInt64 Dba; // Data base address + Kernel::UInt32 Dba; // Data base address + Kernel::UInt32 Dbau; Kernel::UInt32 Reserved0; // Reserved // DW3 Kernel::UInt32 Dbc : 22; // Byte count, 4M max @@ -323,10 +324,10 @@ typedef struct HbaPrdtEntry final typedef struct HbaCmdTbl final { - Kernel::UInt8 Cfis[64]; // Command FIS - Kernel::UInt8 Acmd[16]; // ATAPI command, 12 or 16 bytes - Kernel::UInt8 Rsv[48]; // Reserved - struct HbaPrdtEntry PrdtEntries[1]; // Physical region descriptor table entries, 0 ~ 65535 + Kernel::UInt8 Cfis[64]; // Command FIS + Kernel::UInt8 Acmd[16]; // ATAPI command, 12 or 16 bytes + Kernel::UInt8 Rsv[48]; // Reserved + struct HbaPrdtEntry Prdt[1]; // Physical region descriptor table entries, 0 ~ 65535 } HbaCmdTbl; /// @brief Initializes an AHCI disk. diff --git a/dev/Mod/ATA/ATA.h b/dev/Mod/ATA/ATA.h index 07226a97..c3c65ec0 100644 --- a/dev/Mod/ATA/ATA.h +++ b/dev/Mod/ATA/ATA.h @@ -65,6 +65,8 @@ #define ATA_IDENT_COMMANDSETS 164 #define ATA_IDENT_MAX_LBA_EXT 200 +#define ATA_REG_SET_FEATURES 0xEF + #define ATA_MASTER 0x00 #define ATA_SLAVE 0x01 -- cgit v1.2.3