diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-11-24 03:02:43 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal@nekernel.org> | 2025-11-24 03:02:43 +0100 |
| commit | 83d870e58457a1d335a1d9b9966a6a1887cc297b (patch) | |
| tree | 72888f88c7728c82f3f6df1f4f70591de15eab36 /dev/kernel/HALKit/AMD64/Storage | |
| parent | ab37adbacf0f33845804c788b39680cd754752a8 (diff) | |
feat! breaking changes on kernel sources.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/kernel/HALKit/AMD64/Storage')
| -rw-r--r-- | dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc | 600 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc | 199 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/Storage/NVME+Generic.cc | 9 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc | 278 | ||||
| -rw-r--r-- | dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc | 13 |
5 files changed, 0 insertions, 1099 deletions
diff --git a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc deleted file mode 100644 index 14b40b98..00000000 --- a/dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc +++ /dev/null @@ -1,600 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -/** - * @file AHCI+Generic.cc - * @author Amlal El Mahrouss (amlal@nekernel.org) - * @brief AHCI Generic driver. - * @version 0.1 - * @date 2024-02-02 - * - * @copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - * - */ - -#include <DmaKit/DmaPool.h> -#include <FirmwareKit/EPM.h> -#include <KernelKit/DeviceMgr.h> -#include <KernelKit/DriveMgr.h> -#include <KernelKit/KPC.h> -#include <KernelKit/LockDelegate.h> -#include <KernelKit/PCI/Iterator.h> -#include <KernelKit/ProcessScheduler.h> -#include <KernelKit/Timer.h> -#include <NeKit/Utils.h> -#include <StorageKit/AHCI.h> -#include <modules/AHCI/AHCI.h> -#include <modules/ATA/ATA.h> - -#define kSATAErrTaskFile (1 << 30) -#define kSATAPxCmdST (0x0001) -#define kSATAPxCmdFre (0x0010) -#define kSATAPxCmdFR (0x4000) -#define kSATAPxCmdCR (0x8000) - -#define kSATALBAMode (1 << 6) - -#define kSATASRBsy (0x80) -#define kSATASRDrq (0x08) - -#define kSATABohcBiosOwned (1 << 0) -#define kSATABohcOSOwned (1 << 1) - -#define kSATAPortCnt (0x20) - -#define kSATASig (0x00000101) -#define kSATAPISig (0xEB140101) - -#define kSATAProgIfAHCI (0x01) -#define kSATASubClass (0x06) -#define kSATABar5 (0x24) - -using namespace Kernel; - -STATIC PCI::Device kSATADev; -STATIC HbaMemRef kSATAHba; -STATIC Lba kSATASectorCount = 0UL; -STATIC UInt16 kSATAIndex = 0U; -STATIC Char kCurrentDiskModel[50] = {"GENERIC SATA"}; -STATIC UInt16 kSATAPortsImplemented = 0U; -STATIC ALIGN(kib_cast(4)) UInt8 kIdentifyData[kAHCISectorSize] = {0}; - -template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify> -STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, - SizeT size_buffer) noexcept; - -STATIC Int32 drv_find_cmd_slot_ahci(HbaPort* port) noexcept; - -STATIC Void drv_compute_disk_ahci() noexcept; - -STATIC SizeT drv_get_size_ahci(); - -STATIC SizeT drv_get_sector_count_ahci(); - -/***********************************************************************************/ -/// @brief Identify device and read LBA info, Disk OEM vendor. -/***********************************************************************************/ -STATIC Void drv_compute_disk_ahci() noexcept { - kSATASectorCount = 0UL; - - rt_set_memory(kIdentifyData, 0, kAHCISectorSize); - - drv_std_input_output_ahci<NO, YES, YES>(0, kIdentifyData, kAHCISectorSize, kAHCISectorSize); - - // --> Reinterpret the 512-byte buffer as an array of 256 UInt16 words - UInt16* identify_words = reinterpret_cast<UInt16*>(kIdentifyData); - - /// Extract 48-bit LBA. - UInt64 lba48_sectors = 0UL; - lba48_sectors |= (UInt64) identify_words[100]; - lba48_sectors |= (UInt64) identify_words[101] << 16; - lba48_sectors |= (UInt64) identify_words[102] << 32; - - if (lba48_sectors == 0) - kSATASectorCount = (identify_words[61] << 16) | identify_words[60]; - else - kSATASectorCount = lba48_sectors; - - for (Int32 i = 0; i < 20; i++) { - kCurrentDiskModel[i * 2] = (identify_words[27 + i] >> 8) & 0xFF; - kCurrentDiskModel[i * 2 + 1] = identify_words[27 + i] & 0xFF; - } - - kCurrentDiskModel[40] = '\0'; - - (Void)(kout << "SATA Sector Count: " << hex_number(kSATASectorCount) << kendl); - (Void)(kout << "SATA Disk Model: " << kCurrentDiskModel << kendl); -} - -/***********************************************************************************/ -/// @brief Finds a command slot for a HBA port. -/// @param port The port to search on. -/// @return The slot, or -1. -/***********************************************************************************/ -STATIC Int32 drv_find_cmd_slot_ahci(HbaPort* port) noexcept { - UInt32 slots = port->Sact | port->Ci; - - for (Int32 i = 0; i < kSATAPortCnt; ++i) // AHCI supports up to 32 slots - { - if ((slots & (1U << i)) == 0) return i; - } - - return -1; // no free slot found -} - -/***********************************************************************************/ -/// @brief Send an AHCI command, according to the template parameters. -/// @param lba Logical Block Address to look for. -/// @param buffer The data buffer to transfer. -/// @param sector_sz The disk's sector size (unused) -/// @param size_buffer The size of the **buffer** parameter. -/***********************************************************************************/ -template <BOOL Write, BOOL CommandOrCTRL, BOOL Identify> -STATIC Void drv_std_input_output_ahci(UInt64 lba, UInt8* buffer, SizeT sector_sz, - SizeT size_buffer) noexcept { - if (sector_sz == 0) { - kout << "ahci: Invalid sector size.\r"; - err_global_get() = kErrorDisk; - return; - } - - lba /= sector_sz; - - if (!buffer || size_buffer == 0) { - kout << "ahci: Invalid buffer for AHCI I/O.\r"; - err_global_get() = kErrorDisk; - return; - } - - UIntPtr slot = drv_find_cmd_slot_ahci(&kSATAHba->Ports[kSATAIndex]); - - UInt16 timeout = 0; - - constexpr static UInt16 kTimeout = 0x8000; - - while (slot == ~0UL) { - if (timeout > kTimeout) { - kout << "ahci: No free command slot found, AHCI disk is busy!\r"; - - err_global_get() = kErrorDisk; - return; - } - - slot = drv_find_cmd_slot_ahci(&kSATAHba->Ports[kSATAIndex]); - ++timeout; - } - - volatile HbaCmdHeader* command_header = - (volatile HbaCmdHeader*) ((UInt64) kSATAHba->Ports[kSATAIndex].Clb); - - command_header += slot; - - MUST_PASS(command_header); - - // Clear old command table memory - volatile HbaCmdTbl* command_table = - (volatile HbaCmdTbl*) (((UInt64) command_header->Ctbau << 32) | command_header->Ctba); - - MUST_PASS(command_table); - - rt_set_memory((VoidPtr) command_table, 0, sizeof(HbaCmdTbl)); - - VoidPtr ptr = rtl_dma_alloc(size_buffer, kib_cast(4)); - - rtl_dma_flush(ptr, size_buffer); - - if (Write) { - rt_copy_memory(buffer, ptr, size_buffer); - } - - rtl_dma_flush(ptr, size_buffer); - - // Build the PRD table. - SizeT bytes_remaining = size_buffer; - SizeT prdt_index = 0; - UIntPtr buffer_phys = (UIntPtr) ptr; - - while (bytes_remaining > 0) { - SizeT chunk_size = bytes_remaining; - - if (chunk_size > kib_cast(32)) chunk_size = kib_cast(32); - - command_table->Prdt[prdt_index].Dba = (UInt32) (buffer_phys & 0xFFFFFFFF); - command_table->Prdt[prdt_index].Dbau = (UInt32) (buffer_phys >> 32); - command_table->Prdt[prdt_index].Dbc = (UInt32) (chunk_size - 1); - command_table->Prdt[prdt_index].Ie = NO; - - buffer_phys += chunk_size; - bytes_remaining -= chunk_size; - - ++prdt_index; - } - - // Mark the last PRD entry, for the FIS to process the table. - command_table->Prdt[prdt_index - 1].Ie = YES; - - if (bytes_remaining > 0) { - kout << "ahci: AHCI PRDT overflow, cannot map full buffer.\r"; - err_global_get() = kErrorDisk; - rtl_dma_free(size_buffer); - - return; - } - - command_header->Prdtl = prdt_index; - command_header->HbaFlags.Struct.Cfl = sizeof(FisRegH2D) / sizeof(UInt32); - command_header->HbaFlags.Struct.Write = Write; - - volatile FisRegH2D* h2d_fis = (volatile FisRegH2D*) (&command_table->Cfis[0]); - - h2d_fis->FisType = kFISTypeRegH2D; - h2d_fis->CmdOrCtrl = CommandOrCTRL; - h2d_fis->Command = - (Identify ? kAHCICmdIdentify : (Write ? kAHCICmdWriteDmaEx : kAHCICmdReadDmaEx)); - - h2d_fis->Lba0 = (lba >> 0) & 0xFF; - h2d_fis->Lba1 = (lba >> 8) & 0xFF; - h2d_fis->Lba2 = (lba >> 16) & 0xFF; - h2d_fis->Lba3 = (lba >> 24) & 0xFF; - h2d_fis->Lba4 = (lba >> 32) & 0xFF; - h2d_fis->Lba5 = (lba >> 40) & 0xFF; - - h2d_fis->Device = 0; - - if (Identify) { - h2d_fis->CountLow = 1; - h2d_fis->CountHigh = 0; - } else { - h2d_fis->Device = kSATALBAMode; - h2d_fis->CountLow = (size_buffer / kAHCISectorSize) & 0xFF; - h2d_fis->CountHigh = ((size_buffer / kAHCISectorSize) >> 8) & 0xFF; - } - - rtl_dma_flush(ptr, size_buffer); - - // Issue command - kSATAHba->Ports[kSATAIndex].Ci = (1 << slot); - - timeout = 0UL; - - while (YES) { - if (timeout > kTimeout) { - kout << "ahci: disk-hangup, corrupted-disk.\r"; - err_global_get() = kErrorDiskIsCorrupted; - rtl_dma_free(size_buffer); - - return; - } - - ++timeout; - - if (!(kSATAHba->Ports[kSATAIndex].Ci & (1 << slot))) break; - } - - rtl_dma_flush(ptr, size_buffer); - - if (kSATAHba->Is & kSATAErrTaskFile) { - kout << "ahci: Task File Error during I/O.\r"; - - rtl_dma_free(size_buffer); - err_global_get() = kErrorDiskIsCorrupted; - - return; - } else { - if (!Write) { - rtl_dma_flush(ptr, size_buffer); - rt_copy_memory(ptr, buffer, size_buffer); - rtl_dma_flush(ptr, size_buffer); - } - - if ((kSATAHba->Ports[kSATAIndex].Tfd & (kSATASRBsy | kSATASRDrq)) == 0) { - goto ahci_io_end; - } else { - kout << "ahci: Disk still busy after command completion!\r"; - while (kSATAHba->Ports[kSATAIndex].Tfd & (kSATASRBsy | kSATASRDrq)) - ; - } - - ahci_io_end: - rtl_dma_free(size_buffer); - err_global_get() = kErrorSuccess; - } -} - -/*** - @brief Gets the number of sectors inside the drive. - @return Sector size in bytes. - */ -STATIC ATTRIBUTE(unused) SizeT drv_get_sector_count_ahci() { - return kSATASectorCount; -} - -/// @brief Get the drive size. -/// @return Disk size in bytes. -STATIC ATTRIBUTE(unused) SizeT drv_get_size_ahci() { - return drv_std_get_sector_count() * kAHCISectorSize; -} - -/// @brief Enable Host and probe using the IDENTIFY command. -STATIC BOOL ahci_enable_and_probe() { - if (kSATAHba->Cap == 0x0) return NO; - - kSATAHba->Ports[kSATAIndex].Cmd &= ~kSATAPxCmdFre; - kSATAHba->Ports[kSATAIndex].Cmd &= ~kSATAPxCmdST; - - while (YES) { - if (kSATAHba->Ports[kSATAIndex].Cmd & kSATAPxCmdCR) continue; - - if (kSATAHba->Ports[kSATAIndex].Cmd & kSATAPxCmdFR) continue; - - break; - } - - // Now we are ready. - - kSATAHba->Ports[kSATAIndex].Cmd |= kSATAPxCmdFre; - kSATAHba->Ports[kSATAIndex].Cmd |= kSATAPxCmdST; - - if (kSATAHba->Bohc & kSATABohcBiosOwned) { - kSATAHba->Bohc |= kSATABohcOSOwned; - - while (kSATAHba->Bohc & kSATABohcBiosOwned) { - ; - } - } - - drv_compute_disk_ahci(); - - return YES; -} - -STATIC Bool drv_init_command_structures_ahci() { - // Allocate 4KiB for Command List (32 headers) - VoidPtr clb_mem = rtl_dma_alloc(4096, 1024); - if (!clb_mem) { - kout << "Failed to allocate CLB memory!\r"; - return NO; - } - - UIntPtr clb_phys = HAL::mm_get_page_addr(clb_mem); - - kSATAHba->Ports[kSATAIndex].Clb = (UInt32) (clb_phys & 0xFFFFFFFF); - kSATAHba->Ports[kSATAIndex].Clbu = (UInt32) (clb_phys >> 32); - - // Clear it - rt_set_memory(clb_mem, 0, kib_cast(4)); - - // For each command slot (up to 32) - volatile HbaCmdHeader* header = (volatile HbaCmdHeader*) clb_mem; - - for (Int32 i = 0; i < 32; ++i) { - // Allocate 4KiB for Command Table - VoidPtr ct_mem = rtl_dma_alloc(4096, 128); - if (!ct_mem) { - (Void)(kout << "Failed to allocate CTB memory for slot " << hex_number(i)); - kout << "!\r"; - return NO; - } - - UIntPtr ct_phys = HAL::mm_get_page_addr(ct_mem); - - header[i].Ctba = (UInt32) (ct_phys & 0xFFFFFFFF); - header[i].Ctbau = (UInt32) (ct_phys >> 32); - - // Clear the command table - rt_set_memory((VoidPtr) ct_mem, 0, 4096); - } - - return YES; -} - -/// @brief Initializes an AHCI disk. -/// @param pi the amount of ports that have been detected. -/// @param atapi reference value, tells whether we should detect ATAPI instead of SATA. -/// @return if the disk was successfully initialized or not. -STATIC Bool drv_std_init_ahci(UInt16& pi, BOOL& atapi) { - /// AMLALE: TODO: Iterator is good enough, but we need to expand it. - PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController, 0x00); - - for (SizeT device_index = 0; device_index < NE_BUS_COUNT; ++device_index) { - kSATADev = iterator[device_index].Leak(); // Leak device. - - if (kSATADev.Subclass() == kSATASubClass && kSATADev.ProgIf() == kSATAProgIfAHCI) { - kSATADev.EnableMmio(); - kSATADev.BecomeBusMaster(); - - HbaMem* mem_ahci = (HbaMem*) kSATADev.Bar(kSATABar5); - - HAL::mm_map_page( - (VoidPtr) mem_ahci, (VoidPtr) mem_ahci, - HAL::kMMFlagsPresent | HAL::kMMFlagsWr | HAL::kMMFlagsPCD | HAL::kMMFlagsPwt); - - UInt32 ports_implemented = mem_ahci->Pi; - UInt16 ahci_index = 0; - - pi = ports_implemented; - - const UInt16 kSATAMaxPortsImplemented = ports_implemented; - const UInt32 kSATASignature = kSATASig; - const UInt32 kSATAPISignature = kSATAPISig; - const UInt8 kSATAPresent = 0x03; - const UInt8 kSATAIPMActive = 0x01; - - if (kSATAMaxPortsImplemented < 1) continue; - - while (ports_implemented) { - UInt8 ipm = (mem_ahci->Ports[ahci_index].Ssts >> 8) & 0x0F; - UInt8 det = (mem_ahci->Ports[ahci_index].Ssts & 0x0F); - - if (det != kSATAPresent || ipm != kSATAIPMActive) continue; - - if ((mem_ahci->Ports[ahci_index].Sig == kSATASignature) || - (atapi && kSATAPISignature == mem_ahci->Ports[ahci_index].Sig)) { - kSATAIndex = ahci_index; - kSATAHba = mem_ahci; - - if (!drv_init_command_structures_ahci()) { - err_global_get() = kErrorDisk; - } - - goto success_hba_fetch; - } - - ports_implemented >>= 1; - ++ahci_index; - } - } - } - - err_global_get() = kErrorDisk; - - return NO; - -success_hba_fetch: - if (ahci_enable_and_probe()) { - err_global_get() = kErrorSuccess; - } - - return err_global_get() == kErrorSuccess; -} - -/// @brief Checks if an AHCI device is detected. -/// @return Either if detected, or not found. -Bool drv_std_detected_ahci() { - return kSATADev.DeviceId() != (UShort) PCI::PciConfigKind::Invalid && - kSATADev.Bar(kSATABar5) != 0; -} - -// ================================================================================================ - -// -/// @note This applies only if we compile with AHCI as a default disk driver. -// - -// ================================================================================================ - -#ifdef __AHCI__ - -//////////////////////////////////////////////////// -/// -//////////////////////////////////////////////////// -Void drv_std_write(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer) { - drv_std_input_output_ahci<YES, YES, NO>(lba, reinterpret_cast<UInt8*>(buffer), sector_sz, - size_buffer); -} - -//////////////////////////////////////////////////// -/// -//////////////////////////////////////////////////// -Void drv_std_read(UInt64 lba, Char* buffer, SizeT sector_sz, SizeT size_buffer) { - drv_std_input_output_ahci<NO, YES, NO>(lba, reinterpret_cast<UInt8*>(buffer), sector_sz, - size_buffer); -} - -//////////////////////////////////////////////////// -/// -//////////////////////////////////////////////////// -Bool drv_std_init(UInt16& pi) { - BOOL atapi = NO; - return drv_std_init_ahci(pi, atapi); -} - -//////////////////////////////////////////////////// -/// -//////////////////////////////////////////////////// -Bool drv_std_detected(Void) { - return drv_std_detected_ahci(); -} - -//////////////////////////////////////////////////// -/** - @brief Gets the number of sectors inside the drive. - @return Sector size in bytes. - */ -//////////////////////////////////////////////////// -SizeT drv_std_get_sector_count() { - return drv_get_sector_count_ahci(); -} - -//////////////////////////////////////////////////// -/// @brief Get the drive size. -/// @return Disk size in bytes. -//////////////////////////////////////////////////// -SizeT drv_std_get_size() { - return drv_get_size_ahci(); -} - -#endif // ifdef __AHCI__ - -namespace Kernel { -/// @brief Initialize an AHCI device (StorageKit) -UInt16 sk_init_ahci_device(BOOL atapi) { - UInt16 pi = 0; - - if (drv_std_init_ahci(pi, atapi)) kSATAPortsImplemented = pi; - - return pi; -} - -/// @brief Implementation details namespace. -namespace Detail { - /// @brief Read AHCI device. - /// @param self device - /// @param mnt mounted disk. - STATIC Void sk_io_read_ahci(DeviceInterface<IMountpoint*>* self, IMountpoint* mnt) { - AHCIDeviceInterface* dev = (AHCIDeviceInterface*) self; - - err_global_get() = kErrorDisk; - - if (!dev) return; - - auto disk = mnt->GetAddressOf(dev->GetIndex()); - - if (!disk) return; - - err_global_get() = kErrorSuccess; - - drv_std_input_output_ahci<NO, YES, NO>(disk->fPacket.fPacketLba / kAHCISectorSize, - (UInt8*) disk->fPacket.fPacketContent, kAHCISectorSize, - disk->fPacket.fPacketSize); - } - - /// @brief Write AHCI device. - /// @param self device - /// @param mnt mounted disk. - STATIC Void sk_io_write_ahci(DeviceInterface<IMountpoint*>* self, IMountpoint* mnt) { - AHCIDeviceInterface* dev = (AHCIDeviceInterface*) self; - - err_global_get() = kErrorDisk; - - if (!dev) return; - - auto disk = mnt->GetAddressOf(dev->GetIndex()); - - if (!disk) return; - - err_global_get() = kErrorSuccess; - - drv_std_input_output_ahci<YES, YES, NO>(disk->fPacket.fPacketLba / kAHCISectorSize, - (UInt8*) disk->fPacket.fPacketContent, kAHCISectorSize, - disk->fPacket.fPacketSize); - } -} // namespace Detail - -/// @brief Acquires a new AHCI 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<AHCIDeviceInterface> sk_acquire_ahci_device(UInt32 drv_index) { - if (!drv_std_detected_ahci()) return ErrorOr<AHCIDeviceInterface>(kErrorDisk); - - AHCIDeviceInterface device(Detail::sk_io_read_ahci, Detail::sk_io_write_ahci); - - device.SetPortsImplemented(kSATAPortsImplemented); - device.SetIndex(drv_index); - - return ErrorOr<AHCIDeviceInterface>(device); -} -} // namespace Kernel diff --git a/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc deleted file mode 100644 index cf6147d9..00000000 --- a/dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc +++ /dev/null @@ -1,199 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -/** - * @file DMA+Generic.cc - * @author Amlal El Mahrouss (amlal@nekernel.org) - * @brief ATA driver (DMA mode). - * @version 0.1 - * @date 2024-02-02 - * - * @copyright Copyright (c) Amlal El Mahrouss - * - */ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/PCI/Iterator.h> -#include <modules/ATA/ATA.h> - -#if defined(__ATA_DMA__) - -#define kATADataLen (256) - -using namespace Kernel; -using namespace Kernel::HAL; - -/// BUGS: 0 - -STATIC Boolean kATADetected = false; -STATIC Int32 kATADeviceType ATTRIBUTE(unused) = kATADeviceCount; -STATIC UInt16 kATAIdentifyData[kATADataLen] = {0}; -STATIC Kernel::PCI::Device kATADevice; -STATIC Char kATADiskModel[50] ATTRIBUTE(unused) = {"GENERIC DMA"}; - -Boolean drv_std_wait_io(UInt16 IO) { - for (int i = 0; i < 400; i++) rt_in8(IO + ATA_REG_STATUS); - -ATAWaitForIO_Retry: - auto status_rdy = rt_in8(IO + ATA_REG_STATUS); - - if ((status_rdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry; - -ATAWaitForIO_Retry2: - status_rdy = rt_in8(IO + ATA_REG_STATUS); - - if (status_rdy & ATA_SR_ERR) return false; - - if (!(status_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) { - NE_UNUSED(Bus); - NE_UNUSED(Drive); - NE_UNUSED(OutBus); - NE_UNUSED(OutMaster); - - PCI::Iterator iterator(Types::PciDeviceKind::MassStorageController); - - for (SizeT device_index = 0; device_index < NE_BUS_COUNT; ++device_index) { - kATADevice = iterator[device_index].Leak(); // And then leak the reference. - - /// IDE interface - if (kATADevice.Subclass() == 0x01) { - break; - } - } - - return NO; -} - -namespace Kernel::Detail { -struct PRDEntry final { - UInt32 mAddress; - UInt16 mByteCount; - UInt16 mFlags; /// @param PRD flags, set to 0x8000 to indicate end of prd. -}; -} // namespace Kernel::Detail - -static UIntPtr kReadAddr = mib_cast(2); -static UIntPtr kWriteAddr = mib_cast(2) + kib_cast(64); - -Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - Lba /= SectorSz; - - if (Size > kib_cast(64)) return; - - 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)); - - 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); - - Kernel::Detail::PRDEntry* prd = - (Kernel::Detail::PRDEntry*) (kATADevice.Bar(0x20) + 4); // The PRDEntry is not correct. - - prd->mAddress = (UInt32) (UIntPtr) kReadAddr; - prd->mByteCount = Size - 1; - prd->mFlags = 0x8000; // indicate the end of prd. - - rt_out32(kATADevice.Bar(0x20) + 0x04, (UInt32) (UIntPtr) prd); - - 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(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01) - ; - - rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine - - rt_copy_memory((VoidPtr) kReadAddr, (VoidPtr) Buf, Size); - - delete prd; - prd = nullptr; -} - -Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) { - Lba /= SectorSz; - - if (Size > kib_cast(64)) return; - - UInt8 Command = ((!Master) ? 0xE0 : 0xF0); - - rt_copy_memory((VoidPtr) Buf, (VoidPtr) kWriteAddr, Size); - - 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); - - Kernel::Detail::PRDEntry* prd = (Kernel::Detail::PRDEntry*) (kATADevice.Bar(0x20) + 4); - - prd->mAddress = (UInt32) (UIntPtr) kWriteAddr; - prd->mByteCount = Size - 1; - prd->mFlags = 0x8000; - - 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 - - while (rt_in8(kATADevice.Bar(0x20) + ATA_REG_STATUS) & 0x01) - ; - - rt_out8(kATADevice.Bar(0x20) + 0x00, 0x00); // Stop DMA engine - - delete prd; - prd = nullptr; -} - -/***********************************************************************************/ -/// @brief Is ATA detected? -/***********************************************************************************/ -Boolean drv_std_detected(Void) { - return kATADetected; -} - -/***********************************************************************************/ -/*** - @brief Gets the number of sectors inside the drive. - @return Number of sectors, or zero. -*/ -/***********************************************************************************/ -Kernel::SizeT drv_std_get_sector_count() { - return (kATAIdentifyData[61] << 16) | kATAIdentifyData[60]; -} - -/***********************************************************************************/ -/// @brief Get the size of the current drive. -/***********************************************************************************/ -Kernel::SizeT drv_std_get_size() { - return (drv_std_get_sector_count()) * kATASectorSize; -} - -#endif /* ifdef __ATA_DMA__ */ diff --git a/dev/kernel/HALKit/AMD64/Storage/NVME+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/NVME+Generic.cc deleted file mode 100644 index 88f95a86..00000000 --- a/dev/kernel/HALKit/AMD64/Storage/NVME+Generic.cc +++ /dev/null @@ -1,9 +0,0 @@ -/* ======================================== - - Copyright (C) 2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <modules/NVME/NVME.h> - -using namespace Kernel; diff --git a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc deleted file mode 100644 index 0516be39..00000000 --- a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc +++ /dev/null @@ -1,278 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -/** - * @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 - * - */ - -#include <ArchKit/ArchKit.h> -#include <KernelKit/DriveMgr.h> -#include <StorageKit/ATA.h> -#include <modules/ATA/ATA.h> - -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(DeviceInterface<IMountpoint*>* self, IMountpoint* 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(DeviceInterface<IMountpoint*>* self, IMountpoint* 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<ATADeviceInterface> 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<ATADeviceInterface>(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
\ No newline at end of file diff --git a/dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc deleted file mode 100644 index 0200ec5a..00000000 --- a/dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc +++ /dev/null @@ -1,13 +0,0 @@ -/* ======================================== - - Copyright (C) 2024-2025, Amlal El Mahrouss, licensed under the Apache 2.0 license. - -======================================== */ - -#include <modules/SCSI/SCSI.h> - -using namespace Kernel; - -///! @brief ATAPI SCSI packet. -const ATTRIBUTE(unused) scsi_packet_type_12 kCDRomPacketTemplate = {0x43, 0, 1, 0, 0, 0, - 0, 12, 0x40, 0, 0}; |
