summaryrefslogtreecommitdiffhomepage
path: root/dev/kernel/HALKit/AMD64/Storage
diff options
context:
space:
mode:
Diffstat (limited to 'dev/kernel/HALKit/AMD64/Storage')
-rw-r--r--dev/kernel/HALKit/AMD64/Storage/AHCI+Generic.cc600
-rw-r--r--dev/kernel/HALKit/AMD64/Storage/DMA+Generic.cc199
-rw-r--r--dev/kernel/HALKit/AMD64/Storage/NVME+Generic.cc9
-rw-r--r--dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc278
-rw-r--r--dev/kernel/HALKit/AMD64/Storage/SCSI+Generic.cc13
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};