diff options
| author | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2025-02-13 06:43:02 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal.elmahrouss@icloud.com> | 2025-02-13 06:43:02 +0100 |
| commit | 79ad2556be55a61a41d5d849e396ad4b3a72a23e (patch) | |
| tree | f98fc03644e8233186b8b43bac7e125b3bda2de1 /dev/Kernel/HALKit | |
| parent | e83cfb3dbdd121f6d76e70ff50155c16d6f90c46 (diff) | |
ADD: Much needed tweaks for Driver Manager, DMA, PIO ATA, and SATA.
Signed-off-by: Amlal El Mahrouss <amlal.elmahrouss@icloud.com>
Diffstat (limited to 'dev/Kernel/HALKit')
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalAPICController.cc | 5 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc | 5 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/HalKernelPanic.cc | 4 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/Processor.h | 40 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/Storage/DMA.cc | 152 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/Storage/PIO.cc | 26 | ||||
| -rw-r--r-- | dev/Kernel/HALKit/AMD64/Storage/SATA.cc | 26 |
7 files changed, 140 insertions, 118 deletions
diff --git a/dev/Kernel/HALKit/AMD64/HalAPICController.cc b/dev/Kernel/HALKit/AMD64/HalAPICController.cc index 3e2e267a..c3ce5c1a 100644 --- a/dev/Kernel/HALKit/AMD64/HalAPICController.cc +++ b/dev/Kernel/HALKit/AMD64/HalAPICController.cc @@ -12,6 +12,11 @@ namespace Kernel::HAL { + APICController::APICController(VoidPtr base) + : fApic(base) + { + } + /// @brief Read from APIC controller. /// @param reg register. UInt32 APICController::Read(UInt32 reg) noexcept diff --git a/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc index c64a3e41..63ed2a21 100644 --- a/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc +++ b/dev/Kernel/HALKit/AMD64/HalCoreInterruptHandlerAMD64.cc @@ -133,7 +133,10 @@ EXTERN_C Kernel::Void idt_handle_breakpoint(Kernel::UIntPtr rip) auto process = Kernel::UserProcessScheduler::The().CurrentProcess(); if (process.Leak().Status != Kernel::ProcessStatusKind::kRunning) - return; + { + while (YES) + ; + } kIsScheduling = NO; diff --git a/dev/Kernel/HALKit/AMD64/HalKernelPanic.cc b/dev/Kernel/HALKit/AMD64/HalKernelPanic.cc index 6a4284ec..11ed4c04 100644 --- a/dev/Kernel/HALKit/AMD64/HalKernelPanic.cc +++ b/dev/Kernel/HALKit/AMD64/HalKernelPanic.cc @@ -40,9 +40,9 @@ namespace Kernel auto y = 10; auto x = 10; - kout << "Kernel_Panic: " << message << endl; + kout << "Kernel_Panic_MSG: " << message << endl; kout << "Kernel_Panic_ID: " << hex_number(id) << endl; - kout << "Kernel_Panic_CR2:" << hex_number((UIntPtr)hal_read_cr2()) << endl; + kout << "Kernel_Panic_CR2: " << hex_number((UIntPtr)hal_read_cr2()) << endl; RecoveryFactory::Recover(); } diff --git a/dev/Kernel/HALKit/AMD64/Processor.h b/dev/Kernel/HALKit/AMD64/Processor.h index b95fff74..24e84b79 100644 --- a/dev/Kernel/HALKit/AMD64/Processor.h +++ b/dev/Kernel/HALKit/AMD64/Processor.h @@ -19,14 +19,14 @@ #include <FirmwareKit/Handover.h> #include <HALKit/AMD64/Paging.h> -#define kPITControlPort 0x43 -#define kPITChannel0Port 0x40 -#define kPITFrequency 1193180 +#define kPITControlPort (0x43) +#define kPITChannel0Port (0x40) +#define kPITFrequency (1193180) -#define kPICCommand 0x20 -#define kPICData 0x21 -#define kPIC2Command 0xA0 -#define kPIC2Data 0xA1 +#define kPICCommand (0x20) +#define kPICData (0x21) +#define kPIC2Command (0xA0) +#define kPIC2Data (0xA1) EXTERN_C { @@ -294,14 +294,10 @@ namespace Kernel::HAL }; } // namespace Detail - class APICController + class APICController final { public: - explicit APICController(VoidPtr base) - : fApic(base) - { - } - + explicit APICController(VoidPtr base); ~APICController() = default; NE_COPY_DEFAULT(APICController); @@ -325,16 +321,16 @@ namespace Kernel::HAL EXTERN_C UInt16 rt_in16(UInt16 port); EXTERN_C UInt32 rt_in32(UInt16 port); - EXTERN_C void rt_out16(UShort port, UShort byte); - EXTERN_C void rt_out8(UShort port, UChar byte); - EXTERN_C void rt_out32(UShort port, UInt byte); + EXTERN_C Void rt_out16(UShort port, UShort byte); + EXTERN_C Void rt_out8(UShort port, UChar byte); + EXTERN_C Void rt_out32(UShort port, UInt byte); - EXTERN_C void rt_wait_400ns(); - EXTERN_C void rt_halt(); - EXTERN_C void rt_cli(); - EXTERN_C void rt_sti(); - EXTERN_C void rt_cld(); - EXTERN_C void rt_std(); + EXTERN_C Void rt_wait_400ns(); + EXTERN_C Void rt_halt(); + EXTERN_C Void rt_cli(); + EXTERN_C Void rt_sti(); + EXTERN_C Void rt_cld(); + EXTERN_C Void rt_std(); } // namespace Kernel::HAL EXTERN_C Kernel::Void idt_handle_generic(Kernel::UIntPtr rsp); diff --git a/dev/Kernel/HALKit/AMD64/Storage/DMA.cc b/dev/Kernel/HALKit/AMD64/Storage/DMA.cc index 6fa98a24..c592277d 100644 --- a/dev/Kernel/HALKit/AMD64/Storage/DMA.cc +++ b/dev/Kernel/HALKit/AMD64/Storage/DMA.cc @@ -15,8 +15,11 @@ * */ +#include "KernelKit/DebugOutput.h" +#include "NewKit/KernelPanic.h" #include <Mod/ATA/ATA.h> #include <ArchKit/ArchKit.h> +#include <KernelKit/PCI/Iterator.h> #if defined(__ATA_DMA__) @@ -30,6 +33,8 @@ using namespace Kernel::HAL; STATIC Boolean kATADetected = false; STATIC Int32 kATADeviceType = kATADeviceCount; STATIC Char kATAData[kATADataLen] = {0}; +STATIC Kernel::PCI::Device kATADevice; +STATIC Char kCurrentDiskModel[50] = {"UNKNOWN ATA DRIVE"}; Boolean drv_std_wait_io(UInt16 IO) { @@ -64,79 +69,75 @@ Void drv_std_select(UInt16 Bus) Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) { - if (drv_std_detected()) - return true; + PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController); - UInt16 IO = Bus; + for (SizeT device_index = 0; device_index < NE_BUS_COUNT; ++device_index) + { + kATADevice = iterator[device_index].Leak(); // And then leak the reference. - drv_std_select(IO); + // if SATA and then interface is AHCI... + if (kATADevice.Subclass() == 0x01) + { + UInt16 IO = Bus; - // Bus init, NEIN bit. - rt_out8(IO + ATA_REG_NEIN, 1); + drv_std_select(IO); - // identify until it's good. -ATAInit_Retry: - auto statRdy = rt_in8(IO + ATA_REG_STATUS); + // Bus init, NEIN bit. + rt_out8(IO + ATA_REG_NEIN, 1); - if (statRdy & ATA_SR_ERR) - { - return false; - } + // identify until it's good. + ATAInit_Retry: + auto statRdy = rt_in8(IO + ATA_REG_STATUS); - if ((statRdy & ATA_SR_BSY)) - goto ATAInit_Retry; + if (statRdy & ATA_SR_ERR) + { + return false; + } - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); + if ((statRdy & ATA_SR_BSY)) + goto ATAInit_Retry; - /// fetch serial info - /// model, speed, number of sectors... + rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - drv_std_wait_io(IO); + /// fetch serial info + /// model, speed, number of sectors... - for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) - { - kATAData[indexData] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA); - } + drv_std_wait_io(IO); - OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO; - OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; + for (SizeT i = 0ul; i < kATADataLen; ++i) + { + drv_std_wait_io(IO); + kATAData[i] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA); + drv_std_wait_io(IO); + } - 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."); + for (SizeT i = 0; i < 40; i += 2) + { + kCurrentDiskModel[i] = kATAData[54 + i] >> 8; + kCurrentDiskModel[i + 1] = kATAData[54 + i] & 0xFF; + } - return false; - } + kCurrentDiskModel[40] = '\0'; - // 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 + kout << "Drive Model: " << kCurrentDiskModel << endl; - // 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; + OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO; + OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; + + return YES; + } } -#endif // __ATA_DMA__ - kout << "ATA is enabled now.\r"; + ke_panic(RUNTIME_CHECK_BOOTSTRAP, "Invalid ATA DMA driver, not detected"); - return YES; + return NO; } namespace Details { using namespace Kernel; - struct __attribute__((packed, aligned(4))) PRD final + struct PRD final { UInt32 mAddress; UInt16 mByteCount; @@ -144,12 +145,20 @@ namespace Details }; } // namespace Details +static UIntPtr kReadAddr = mib_cast(2); +static UIntPtr kWriteAddr = mib_cast(4); + Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { Lba /= SectorSz; + if (Size > kib_cast(64)) + ke_panic(RUNTIME_CHECK_FAILED, "ATA-DMA only supports < 64kb DMA transfers."); + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); + rt_copy_memory((VoidPtr)Buf, (VoidPtr)kReadAddr, Size); + drv_std_select(IO); rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); @@ -161,22 +170,23 @@ Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz 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; + Details::PRD* prd = (Details::PRD*)(kATADevice.Bar(0x20) + 4); + prd->mAddress = (UInt32)(UIntPtr)kReadAddr; + prd->mByteCount = Size - 1; prd->mFlags = 0x8000; - rt_out32(IO + 0x04, (UInt32)(UIntPtr)prd); + rt_out32(kATADevice.Bar(0x20) + 0x04, (UInt32)(UIntPtr)prd); - rt_out8(IO + 0x00, 0x09); // Start DMA engine - rt_out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_DMA); + rt_out8(kATADevice.Bar(0x20) + ATA_REG_COMMAND, ATA_CMD_READ_DMA); + + rt_out8(kATADevice.Bar(0x20) + 0x00, 0x09); // Start DMA engine - while (rt_in8(ATA_REG_STATUS) & 0x01) + while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01) ; - rt_out8(IO + 0x00, 0x00); // Stop DMA engine + + rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine + + rt_copy_memory((VoidPtr)kReadAddr, (VoidPtr)Buf, Size); delete prd; prd = nullptr; @@ -186,9 +196,12 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS { Lba /= SectorSz; + if (Size > kib_cast(64)) + ke_panic(RUNTIME_CHECK_FAILED, "ATA-DMA only supports < 64kb DMA transfers."); + UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - drv_std_select(IO); + rt_copy_memory((VoidPtr)Buf, (VoidPtr)kWriteAddr, Size); rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); @@ -199,23 +212,20 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS 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; + Details::PRD* prd = (Details::PRD*)(kATADevice.Bar(0x20) + 4); + prd->mAddress = (UInt32)(UIntPtr)kWriteAddr; + prd->mByteCount = Size - 1; prd->mFlags = 0x8000; - rt_out32(IO + 0x04, (UInt32)(UIntPtr)prd); + rt_out32(kATADevice.Bar(0x20) + 0x04, (UInt32)(UIntPtr)prd); + rt_out8(kATADevice.Bar(0x20) + ATA_REG_COMMAND, ATA_CMD_WRITE_DMA); 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) + while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01) ; - rt_out8(IO + 0x00, 0x00); // Stop DMA engine + rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine delete prd; prd = nullptr; diff --git a/dev/Kernel/HALKit/AMD64/Storage/PIO.cc b/dev/Kernel/HALKit/AMD64/Storage/PIO.cc index 3f1286b6..3ca1e403 100644 --- a/dev/Kernel/HALKit/AMD64/Storage/PIO.cc +++ b/dev/Kernel/HALKit/AMD64/Storage/PIO.cc @@ -5,7 +5,7 @@ ------------------------------------------- */ /** - * @file ATA-PIO.cc + * @file PIO.cc * @author Amlal EL Mahrouss (amlalelmahrouss@icloud.com) * @brief ATA driver (PIO mode). * @version 0.1 @@ -30,6 +30,7 @@ using namespace Kernel::HAL; STATIC Boolean kATADetected = false; STATIC Int32 kATADeviceType = kATADeviceCount; STATIC Char kATAData[kATADataLen] = {0}; +STATIC Char kCurrentDiskModel[50] = {"UNKNOWN ATA DRIVE"}; Boolean drv_std_wait_io(UInt16 IO) { @@ -64,9 +65,6 @@ Void drv_std_select(UInt16 Bus) 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); @@ -93,11 +91,23 @@ ATAInit_Retry: drv_std_wait_io(IO); - for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) + for (SizeT i = 0ul; i < kATADataLen; ++i) + { + drv_std_wait_io(IO); + kATAData[i] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA); + drv_std_wait_io(IO); + } + + for (SizeT i = 0; i < 40; i += 2) { - kATAData[indexData] = Kernel::HAL::rt_in16(IO + ATA_REG_DATA); + kCurrentDiskModel[i] = kATAData[54 + i] >> 8; + kCurrentDiskModel[i + 1] = kATAData[54 + i] & 0xFF; } + kCurrentDiskModel[40] = '\0'; + + kout << "Drive Model: " << kCurrentDiskModel << endl; + OutBus = (Bus == ATA_PRIMARY_IO) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO; OutMaster = (Bus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; @@ -173,7 +183,7 @@ Boolean drv_std_detected(Void) } /*** - @brief Getter, gets the number of sectors inside the drive. + @brief Getter, gets the number of sectors inside the drive. */ Kernel::SizeT drv_get_sector_count() { @@ -186,4 +196,4 @@ Kernel::SizeT drv_get_size() return (drv_get_sector_count()) * kATASectorSize; } -#endif /* ifdef __ATA_PIO__ */ +#endif /* ifdef __ATA_PIO__ */
\ No newline at end of file diff --git a/dev/Kernel/HALKit/AMD64/Storage/SATA.cc b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc index b37de7e5..8f68b734 100644 --- a/dev/Kernel/HALKit/AMD64/Storage/SATA.cc +++ b/dev/Kernel/HALKit/AMD64/Storage/SATA.cc @@ -15,7 +15,6 @@ * */ -#include "KernelKit/DebugOutput.h" #include <KernelKit/UserProcessScheduler.h> #include <KernelKit/LPC.h> @@ -46,7 +45,7 @@ #define kSATASubClass (0x06) #define kSATABar5 (0x24) -STATIC Kernel::PCI::Device kPCIDevice; +STATIC Kernel::PCI::Device kDevice; STATIC HbaMem* kSATA = nullptr; STATIC Kernel::SizeT kSATAPortIdx = 0UL; STATIC Kernel::Lba kCurrentDiskSectorCount = 0UL; @@ -94,16 +93,16 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) for (SizeT device_index = 0; device_index < NE_BUS_COUNT; ++device_index) { - kPCIDevice = iterator[device_index].Leak(); // And then leak the reference. + kDevice = iterator[device_index].Leak(); // And then leak the reference. // if SATA and then interface is AHCI... - if (kPCIDevice.Subclass() == kSATASubClass && - kPCIDevice.ProgIf() == kSATAProgIfAHCI) + if (kDevice.Subclass() == kSATASubClass && + kDevice.ProgIf() == kSATAProgIfAHCI) { - 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. + kDevice.EnableMmio(kSATABar5); // Enable the memory index_byte/o for this ahci device. + kDevice.BecomeBusMaster(kSATABar5); // Become bus master for this ahci device, so that we can control it. - HbaMem* mem_ahci = (HbaMem*)kPCIDevice.Bar(kSATABar5); + HbaMem* mem_ahci = (HbaMem*)kDevice.Bar(kSATABar5); kout << hex_number((UIntPtr)mem_ahci) << endl; @@ -124,9 +123,6 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) HAL::mm_map_page(mem_ahci, mem_ahci, HAL::kMMFlagsWr); - kout << "Virtddr: " << hex_number((UIntPtr)mem_ahci) << endl; - kout << "PhysAddr: " << hex_number((UIntPtr)HAL::hal_get_phys_address(mem_ahci)) << endl; - if (mem_ahci->Ports[ahci_index].Sig == kSATASignature && det == 3 && ipm == 1 && (mem_ahci->Ports[ahci_index].Ssts & 0xF)) { @@ -135,6 +131,8 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) kSATAPortIdx = ahci_index; kSATA = mem_ahci; + // Restart the HBA. + kSATA->Ports[kSATAPortIdx].Cmd &= ~(kHBAPxCmdST | kHBAPxCmdFre); // Disable command and FIS reception while (kSATA->Ports[kSATAPortIdx].Cmd & kHBAPxCmdCR) @@ -145,8 +143,8 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) kSATA->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdFre; // Re-enable FIS reception kSATA->Ports[kSATAPortIdx].Cmd |= kHBAPxCmdST; // Start command engine - - kSATA->Ghc |= kHBACmdAE; // Enable AHCI mode + + kSATA->Ghc |= kHBACmdAE; // Enable AHCI mode HAL::rt_wait_400ns(); @@ -167,7 +165,7 @@ Kernel::Boolean drv_std_init(Kernel::UInt16& PortsImplemented) Kernel::Boolean drv_std_detected(Kernel::Void) { - return kPCIDevice.DeviceId() != 0xFFFF && kCurrentDiskSectorCount > 0; + return kDevice.DeviceId() != 0xFFFF && kCurrentDiskSectorCount > 0; } Kernel::Void drv_std_write(Kernel::UInt64 lba, Kernel::Char* buffer, Kernel::SizeT sector_sz, Kernel::SizeT size_buffer) |
