From 7a260f76e9c05d84e59ffd7270ed8a65d08a4790 Mon Sep 17 00:00:00 2001 From: Amlal El Mahrouss Date: Sat, 8 Feb 2025 08:43:57 +0100 Subject: ADD: Tweaks and improvements on the Operating System. Signed-off-by: Amlal El Mahrouss --- dev/Kernel/HALKit/AMD64/Storage/ATA.cc | 261 -------------------------------- dev/Kernel/HALKit/AMD64/Storage/DMA.cc | 244 +++++++++++++++++++++++++++++ dev/Kernel/HALKit/AMD64/Storage/PIO.cc | 189 +++++++++++++++++++++++ dev/Kernel/HALKit/AMD64/Storage/SATA.cc | 13 +- dev/Kernel/src/DriveMgr.cc | 2 + 5 files changed, 444 insertions(+), 265 deletions(-) delete mode 100644 dev/Kernel/HALKit/AMD64/Storage/ATA.cc create mode 100644 dev/Kernel/HALKit/AMD64/Storage/DMA.cc create mode 100644 dev/Kernel/HALKit/AMD64/Storage/PIO.cc (limited to 'dev/Kernel') diff --git a/dev/Kernel/HALKit/AMD64/Storage/ATA.cc b/dev/Kernel/HALKit/AMD64/Storage/ATA.cc deleted file mode 100644 index 25143a6d..00000000 --- a/dev/Kernel/HALKit/AMD64/Storage/ATA.cc +++ /dev/null @@ -1,261 +0,0 @@ -/* ------------------------------------------- - - Copyright (C) 2024-2025, 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__) - -#define kATADataLen 256 - -using namespace Kernel; -using namespace Kernel::HAL; - -/// BUGS: 0 - -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); - - rt_out8(IO + ATA_REG_NEIN, 1); - - // Step 1: Wait until drive is not busy - int timeout = 100000; - while ((rt_in8(IO + ATA_REG_STATUS) & ATA_SR_BSY) && --timeout) - ; - if (!timeout) - { - kout << "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) - { - kout << "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)) - { - kout << "No DMA support...\r"; - ke_panic(RUNTIME_CHECK_BOOTSTRAP, "No DMA support on necessary disk driver."); - - return false; - } - - // 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) - { - kout << "DMA Initialization Timeout...\r"; - return false; - } -#endif // __ATA_DMA__ - - kout << "ATA is enabled now.\r"; - - 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); - - 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); - - 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); - - 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); - - 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/DMA.cc b/dev/Kernel/HALKit/AMD64/Storage/DMA.cc new file mode 100644 index 00000000..6fa98a24 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/Storage/DMA.cc @@ -0,0 +1,244 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, 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_DMA__) + +#define kATADataLen 256 + +using namespace Kernel; +using namespace Kernel::HAL; + +/// BUGS: 0 + +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 statRdy = rt_in8(IO + ATA_REG_STATUS); + + if ((statRdy & ATA_SR_BSY)) + goto ATAWaitForIO_Retry; + +ATAWaitForIO_Retry2: + statRdy = rt_in8(IO + ATA_REG_STATUS); + + if (statRdy & ATA_SR_ERR) + return false; + + if (!(statRdy & ATA_SR_DRDY)) + goto ATAWaitForIO_Retry2; + + return true; +} + +Void drv_std_select(UInt16 Bus) +{ + if (Bus == ATA_PRIMARY_IO) + 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) +{ + if (drv_std_detected()) + return true; + + UInt16 IO = Bus; + + drv_std_select(IO); + + // Bus init, NEIN bit. + rt_out8(IO + ATA_REG_NEIN, 1); + + // identify until it's good. +ATAInit_Retry: + auto statRdy = rt_in8(IO + ATA_REG_STATUS); + + if (statRdy & ATA_SR_ERR) + { + return false; + } + + if ((statRdy & ATA_SR_BSY)) + 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] = Kernel::HAL::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 true; +#ifdef __ATA_DMA__ + // Step 7: Check if the drive supports DMA + if (!(kATAData[63] & (1 << 8)) || !(kATAData[88] & 0xFF)) + { + kout << "No DMA support...\r"; + ke_panic(RUNTIME_CHECK_BOOTSTRAP, "No DMA support on necessary disk driver."); + + return false; + } + + // 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) + { + kout << "DMA Initialization Timeout...\r"; + return false; + } +#endif // __ATA_DMA__ + + kout << "ATA is enabled now.\r"; + + 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); + + 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); + + if (Size > kib_cast(64)) + ke_panic(RUNTIME_CHECK_FAILED, "ATA-DMA only supports < 64kb DMA transfers."); + + Details::PRD* prd = new Details::PRD(); + 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); // Stop DMA engine + + delete prd; + prd = nullptr; +} + +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_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); + + if (Size > kib_cast(64)) + ke_panic(RUNTIME_CHECK_FAILED, "ATA-DMA only supports < 64kb DMA transfers."); + + Details::PRD* prd = new Details::PRD(); + 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); // Stop DMA engine + + delete prd; + prd = nullptr; +} + +/// @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_DMA__ */ diff --git a/dev/Kernel/HALKit/AMD64/Storage/PIO.cc b/dev/Kernel/HALKit/AMD64/Storage/PIO.cc new file mode 100644 index 00000000..3f1286b6 --- /dev/null +++ b/dev/Kernel/HALKit/AMD64/Storage/PIO.cc @@ -0,0 +1,189 @@ +/* ------------------------------------------- + + Copyright (C) 2024-2025, 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 statRdy = rt_in8(IO + ATA_REG_STATUS); + + if ((statRdy & ATA_SR_BSY)) + goto ATAWaitForIO_Retry; + +ATAWaitForIO_Retry2: + statRdy = rt_in8(IO + ATA_REG_STATUS); + + if (statRdy & ATA_SR_ERR) + return false; + + if (!(statRdy & ATA_SR_DRDY)) + goto ATAWaitForIO_Retry2; + + return true; +} + +Void drv_std_select(UInt16 Bus) +{ + if (Bus == ATA_PRIMARY_IO) + 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) +{ + if (drv_std_detected()) + return true; + + UInt16 IO = Bus; + + drv_std_select(IO); + + // Bus init, NEIN bit. + rt_out8(IO + ATA_REG_NEIN, 1); + + // identify until it's good. +ATAInit_Retry: + auto statRdy = rt_in8(IO + ATA_REG_STATUS); + + if (statRdy & ATA_SR_ERR) + { + return false; + } + + if ((statRdy & ATA_SR_BSY)) + 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] = Kernel::HAL::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 true; +} + +Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) +{ + Lba /= SectorSz; + + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + + drv_std_wait_io(IO); + drv_std_select(IO); + + 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] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA); + 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/SATA.cc b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc index 26391340..00ef8767 100644 --- a/dev/Kernel/HALKit/AMD64/Storage/SATA.cc +++ b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc @@ -184,8 +184,13 @@ static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buff if (slot == -1) return; + if (size_buffer > mib_cast(4)) + Kernel::ke_panic(RUNTIME_CHECK_FAILED, "AHCI only supports < 4mb DMA transfers."); + HbaCmdHeader* command_header = ((HbaCmdHeader*)((Kernel::UInt64)kSATAPort->Ports[kSATAPortIdx].Clb + kSATAPort->Ports[kSATAPortIdx].Clbu)); + command_header += slot; + Kernel::rt_set_memory(reinterpret_cast(command_header), 0, sizeof(HbaCmdHeader)); MUST_PASS(command_header); @@ -200,10 +205,10 @@ static Kernel::Void drv_std_input_output(Kernel::UInt64 lba, Kernel::UInt8* buff MUST_PASS(command_table); - command_table->Prdt[0].Dba = ((Kernel::UInt32)(Kernel::UInt64)Kernel::HAL::hal_get_phys_address(buffer)); - command_table->Prdt[0].Dbau = (((Kernel::UInt64)Kernel::HAL::hal_get_phys_address(buffer) >> 32)); - command_table->Prdt[0].Dbc = ((size_buffer)-1); - command_table->Prdt[0].InterruptBit = 1; + command_table->Prdt[0].Dba = ((Kernel::UInt32)(Kernel::UInt64)Kernel::HAL::hal_get_phys_address(buffer)); + command_table->Prdt[0].Dbau = (((Kernel::UInt64)Kernel::HAL::hal_get_phys_address(buffer) >> 32)); + command_table->Prdt[0].Dbc = ((size_buffer)-1); + command_table->Prdt[0].IE = 1; command_header->Ctba = ((Kernel::UInt32)(Kernel::UInt64)command_table); command_header->Ctbau = ((Kernel::UInt32)((Kernel::UInt64)command_table >> 32)); diff --git a/dev/Kernel/src/DriveMgr.cc b/dev/Kernel/src/DriveMgr.cc index 7230f112..f7215346 100644 --- a/dev/Kernel/src/DriveMgr.cc +++ b/dev/Kernel/src/DriveMgr.cc @@ -162,6 +162,8 @@ namespace Kernel trait.fInit(trait.fPacket); + kout << "Reading EPM block...\r"; + trait.fInput(trait.fPacket); if (rt_string_cmp(((BOOT_BLOCK_STRUCT*)trait.fPacket.fPacketContent)->Magic, kEPMMagic, kEPMMagicLength) == 0) -- cgit v1.2.3