diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-04-01 09:44:20 +0200 |
|---|---|---|
| committer | Amlal El Mahrouss <amlal@nekernel.org> | 2025-04-01 09:44:20 +0200 |
| commit | 6965e19b184358431dd9832187e541da3af3968f (patch) | |
| tree | 6c7e782ad9d66c6d1c5d55cc1031e5ef54488d9f /dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc | |
| parent | 2a7a9825fd275d6d999b94614fe87c1d705c7f8f (diff) | |
kernel/storage, pio, ahci, dma: a lot of patches and fixes according to StorageKit specs and
cleaned up DMA driver for a future more robust implementation.
Signed-off-by: Amlal El Mahrouss <amlal@nekernel.org>
Diffstat (limited to 'dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc')
| -rw-r--r-- | dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc | 142 |
1 files changed, 122 insertions, 20 deletions
diff --git a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc index 201cdf30..c6eee7f7 100644 --- a/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc +++ b/dev/kernel/HALKit/AMD64/Storage/PIO+Generic.cc @@ -15,10 +15,11 @@ * */ +#include "NewKit/Defines.h" #include <modules/ATA/ATA.h> #include <ArchKit/ArchKit.h> - -#ifdef __ATA_PIO__ +#include <KernelKit/DriveMgr.h> +#include <StorageKit/ATA.h> using namespace Kernel; using namespace Kernel::HAL; @@ -30,9 +31,9 @@ using namespace Kernel::HAL; STATIC Boolean kATADetected = false; STATIC Int32 kATADeviceType = kATADeviceCount; STATIC Char kATAData[kATADataLen] = {0}; -STATIC Char kCurrentDiskModel[50] = {"UNKNOWN PIO DRIVE"}; +STATIC Char kCurrentDiskModel[50] = {"GENERIC PIO"}; -Boolean drv_std_wait_io(UInt16 IO) +static Boolean drv_pio_std_wait_io(UInt16 IO) { for (int i = 0; i < 400; i++) rt_in8(IO + ATA_REG_STATUS); @@ -55,7 +56,7 @@ ATAWaitForIO_Retry2: return true; } -Void drv_std_select(UInt16 Bus) +static Void drv_pio_std_select(UInt16 Bus) { if (Bus == ATA_PRIMARY_IO) rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); @@ -63,11 +64,11 @@ Void drv_std_select(UInt16 Bus) rt_out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL); } -Boolean drv_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) +Boolean drv_pio_std_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, UInt8& OutMaster) { UInt16 IO = Bus; - drv_std_select(IO); + drv_pio_std_select(IO); // Bus init, NEIN bit. rt_out8(IO + ATA_REG_NEIN, 1); @@ -89,7 +90,7 @@ ATAInit_Retry: rt_out8(OutBus + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); - drv_std_wait_io(IO); + drv_pio_std_wait_io(IO); /// fetch serial info /// model, speed, number of sectors... @@ -114,14 +115,14 @@ ATAInit_Retry: return true; } -Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) +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_std_wait_io(IO); - drv_std_select(IO); + drv_pio_std_wait_io(IO); + drv_pio_std_select(IO); rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); @@ -136,19 +137,19 @@ Void drv_std_read(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { - drv_std_wait_io(IO); + drv_pio_std_wait_io(IO); Buf[IndexOff] = HAL::rt_in16(IO + ATA_REG_DATA); } } -Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorSz, SizeT Size) +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_std_wait_io(IO); - drv_std_select(IO); + drv_pio_std_wait_io(IO); + drv_pio_std_select(IO); rt_out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0x0F)); @@ -163,13 +164,13 @@ Void drv_std_write(UInt64 Lba, UInt16 IO, UInt8 Master, Char* Buf, SizeT SectorS for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { - drv_std_wait_io(IO); + drv_pio_std_wait_io(IO); rt_out16(IO + ATA_REG_DATA, Buf[IndexOff]); } } /// @brief is ATA detected? -Boolean drv_std_detected(Void) +Boolean drv_pio_std_detected(Void) { return kATADetected; } @@ -177,15 +178,116 @@ Boolean drv_std_detected(Void) /*** @brief Getter, gets the number of sectors inside the drive. */ -SizeT drv_get_sector_count() +SizeT drv_pio_get_sector_count() { return (kATAData[61] << 16) | kATAData[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_pio_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(IDeviceObject<MountpointInterface*>* self, MountpointInterface* 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(IDeviceObject<MountpointInterface*>* self, MountpointInterface* 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_pio_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, + nullptr); + + 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_get_size() { - return (drv_get_sector_count()) * kATASectorSize; + return drv_pio_get_size(); +} + +SizeT drv_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 /* ifdef __ATA_PIO__ */
\ No newline at end of file +#endif
\ No newline at end of file |
