diff options
| author | amlal <amlal@el-mahrouss-logic.com> | 2024-03-22 10:09:51 +0100 |
|---|---|---|
| committer | amlal <amlal@el-mahrouss-logic.com> | 2024-03-22 10:09:51 +0100 |
| commit | 71ead709ab3e30a1b137a5b9215bf74c7bed9d04 (patch) | |
| tree | 55ded35496cc7054c0975fd9364f8b2513ac0531 /Private | |
| parent | 5df4daf0619b95131ea99110ee2e8913012b6134 (diff) | |
HCR-14: Implement ATA for HCoreKrnl.exe.
[TODO]: Need to also implement a
ATADeviceInterface class.
Signed-off-by: amlal <amlal@el-mahrouss-logic.com>
Diffstat (limited to 'Private')
| -rw-r--r-- | Private/Builtins/ATA/Defines.hxx | 29 | ||||
| -rw-r--r-- | Private/HALKit/AMD64/Storage/ATA.cxx | 175 | ||||
| -rw-r--r-- | Private/NewBoot/BootKit/Arch/ATA.hxx | 11 | ||||
| -rw-r--r-- | Private/NewBoot/Source/HEL/AMD64/BootMain.cxx | 5 | ||||
| -rw-r--r-- | Private/Source/Storage/ATA-Wrapper.cxx | 102 | ||||
| -rw-r--r-- | Private/Source/Storage/ATAWrapper.cxx | 64 | ||||
| -rw-r--r-- | Private/StorageKit/ATA.hpp | 18 | ||||
| -rw-r--r-- | Private/makefile | 2 |
8 files changed, 280 insertions, 126 deletions
diff --git a/Private/Builtins/ATA/Defines.hxx b/Private/Builtins/ATA/Defines.hxx index 4ea49dc9..f0f019e8 100644 --- a/Private/Builtins/ATA/Defines.hxx +++ b/Private/Builtins/ATA/Defines.hxx @@ -16,8 +16,6 @@ #include <CompilerKit/CompilerKit.hxx> #include <NewKit/Defines.hpp> -using namespace HCore; - // Status register #define ATA_SR_BSY 0x80 #define ATA_SR_DRDY 0x40 @@ -118,3 +116,30 @@ using namespace HCore; #define ATA_COMMAND(x) (x + 7) #define kATASectorSize 512 + +enum { + kATADevicePATA, + kATADeviceSATA, + kATADevicePATA_PI, + kATADeviceSATA_PI, + kATADeviceCount, +}; + +#ifdef __KERNEL__ + +HCore::Boolean drv_ata_init(HCore::UInt16 Bus, HCore::UInt8 Drive, HCore::UInt16& OutBus, + HCore::UInt8& OutMaster); + +HCore::Boolean drv_ata_detected(HCore::Void); + +HCore::Void drv_ata_select(HCore::UInt16 Bus); + +HCore::Boolean drv_ata_wait_io(HCore::UInt16 IO); + +HCore::Void drv_ata_read(HCore::UInt32 Lba, HCore::UInt16 IO, HCore::UInt8 Master, HCore::Char* Buf, + HCore::SizeT SectorSz, HCore::SizeT Size); + +HCore::Void drv_ata_write(HCore::UInt32 Lba, HCore::UInt16 IO, HCore::UInt8 Master, HCore::Char* Buf, + HCore::SizeT SectorSz, HCore::SizeT Size); + +#endif // ifdef __KERNEL__
\ No newline at end of file diff --git a/Private/HALKit/AMD64/Storage/ATA.cxx b/Private/HALKit/AMD64/Storage/ATA.cxx new file mode 100644 index 00000000..cd68af23 --- /dev/null +++ b/Private/HALKit/AMD64/Storage/ATA.cxx @@ -0,0 +1,175 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + +------------------------------------------- */ + +/** + * @file ATA.cxx + * @author Amlal El Mahrouss (amlalelmahrouss@icloud.com) + * @brief ATA driver. + * @version 0.1 + * @date 2024-02-02 + * + * @copyright Copyright (c) Mahrouss Logic + * + */ + +#include <Builtins/ATA/Defines.hxx> +#include <ArchKit/ArchKit.hpp> + +using namespace HCore; +using namespace HCore::HAL; + +/// bugs: 0 + +#define kATADataLen 256 + +static Boolean kATADetected = false; +static Int32 kATADeviceType = kATADeviceCount; +static Char kATAData[kATADataLen] = {0}; + +Boolean drv_ata_wait_io(UInt16 IO) { + for (int i = 0; i < 4; i++) In8(IO + ATA_REG_STATUS); + +ATAWaitForIO_Retry: + auto statRdy = In8(IO + ATA_REG_STATUS); + + if ((statRdy & ATA_SR_BSY)) goto ATAWaitForIO_Retry; + +ATAWaitForIO_Retry2: + statRdy = In8(IO + ATA_REG_STATUS); + + if (statRdy & ATA_SR_ERR) return false; + + if (!(statRdy & ATA_SR_DRDY)) goto ATAWaitForIO_Retry2; + + return true; +} + +Void drv_ata_select(UInt16 Bus) { + if (Bus == ATA_PRIMARY_IO) + Out8(Bus + ATA_REG_HDDEVSEL, ATA_PRIMARY_SEL); + else + Out8(Bus + ATA_REG_HDDEVSEL, ATA_SECONDARY_SEL); +} + +Boolean drv_ata_init(UInt16 Bus, UInt8 Drive, UInt16& OutBus, + UInt8& OutMaster) { + if (drv_ata_detected()) return false; + + UInt16 IO = Bus; + + drv_ata_select(IO); + + // Bus init, NEIN bit. + Out8(IO + ATA_REG_NEIN, 1); + + // identify until it's good. +ATAInit_Retry: + auto statRdy = In8(IO + ATA_REG_STATUS); + + if (statRdy & ATA_SR_ERR) { + kcout << "HCoreKrnl.exe: ATA: Select error, not an IDE based hard-drive.\r\n"; + + return false; + } + + if ((statRdy & ATA_SR_BSY)) goto ATAInit_Retry; + + Out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY); + + rt_set_memory(kATAData, 0, kATADataLen); + + /// fetch serial info + /// model, speed, number of sectors... + + drv_ata_wait_io(IO); + + for (SizeT indexData = 0ul; indexData < kATADataLen; ++indexData) { + kATAData[indexData] = In16(IO + ATA_REG_DATA); + } + + OutBus = Bus; + OutMaster = (OutBus == ATA_PRIMARY_IO) ? ATA_MASTER : ATA_SLAVE; + + Out8(Bus + ATA_REG_HDDEVSEL, 0xA0 | ATA_MASTER << 4); + + In8(Bus + ATA_REG_CONTROL); + In8(Bus + ATA_REG_CONTROL); + In8(Bus + ATA_REG_CONTROL); + In8(Bus + ATA_REG_CONTROL); + + unsigned cl = In8(Bus + ATA_CYL_LOW); /* get the "signature bytes" */ + unsigned ch = In8(Bus + ATA_CYL_HIGH); + + /* differentiate ATA, ATAPI, SATA and SATAPI */ + if (cl == 0x14 && ch == 0xEB) { + kcout << "HCoreKrnl.exe: PATAPI drive detected.\r\n"; + kATADeviceType = kATADevicePATA_PI; + } + if (cl == 0x69 && ch == 0x96) { + kcout << "HCoreKrnl.exe: SATAPI drive detected.\r\n"; + kATADeviceType = kATADeviceSATA_PI; + } + + if (cl == 0x0 && ch == 0x0) { + kcout << "HCoreKrnl.exe: PATA drive detected.\r\n"; + kATADeviceType = kATADevicePATA; + } + + if (cl == 0x3c && ch == 0xc3) { + kcout << "HCoreKrnl.exe: SATA drive detected.\r\n"; + kATADeviceType = kATADeviceSATA; + } + + Out8(IO + ATA_REG_CONTROL, 0x02); + + return true; +} + +Void drv_ata_read(UInt32 Lba, UInt16 IO, UInt8 Master, Char* Buf, + SizeT SectorSz, SizeT Size) { + UInt8 Command = (!Master ? 0xE0 : 0xF0); + + Out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0xF)); + Out8(IO + ATA_REG_SEC_COUNT0, SectorSz); + + Out8(IO + ATA_REG_LBA0, (UInt8)(Lba)); + Out8(IO + ATA_REG_LBA1, (UInt8)(Lba) >> 8); + Out8(IO + ATA_REG_LBA2, (UInt8)(Lba) >> 16); + + Out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO); + + drv_ata_wait_io(IO); + + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { + WideChar chr = In16(IO + ATA_REG_DATA); + + Buf[IndexOff] = chr; + } +} + +Void drv_ata_write(UInt32 Lba, UInt16 IO, UInt8 Master, Char* Buf, + SizeT SectorSz, SizeT Size) { + UInt8 Command = (!Master ? 0xE0 : 0xF0); + + Out8(IO + ATA_REG_HDDEVSEL, (Command) | (((Lba) >> 24) & 0xF)); + Out8(IO + ATA_REG_SEC_COUNT0, SectorSz); + + Out8(IO + ATA_REG_LBA0, (UInt8)(Lba)); + Out8(IO + ATA_REG_LBA1, (UInt8)(Lba) >> 8); + Out8(IO + ATA_REG_LBA2, (UInt8)(Lba) >> 16); + + Out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); + + drv_ata_wait_io(IO); + + for (SizeT IndexOff = 0; IndexOff < Size; ++IndexOff) { + Out16(IO + ATA_REG_DATA, Buf[IndexOff]); + + } +} + +/// @check is ATA detected? +Boolean drv_ata_detected(Void) { return kATADetected; }
\ No newline at end of file diff --git a/Private/NewBoot/BootKit/Arch/ATA.hxx b/Private/NewBoot/BootKit/Arch/ATA.hxx index 8cd948a3..8e0a15eb 100644 --- a/Private/NewBoot/BootKit/Arch/ATA.hxx +++ b/Private/NewBoot/BootKit/Arch/ATA.hxx @@ -8,6 +8,8 @@ #include <Builtins/ATA/Defines.hxx> +using namespace HCore; + class BDeviceATA final { public: enum { @@ -40,12 +42,3 @@ class BDeviceATA final { private: ATATrait mTrait; }; - -enum { - kATADevicePATA, - kATADeviceSATA, - kATADevicePATA_PI, - kATADeviceSATA_PI, - kATADeviceCount, -}; - diff --git a/Private/NewBoot/Source/HEL/AMD64/BootMain.cxx b/Private/NewBoot/Source/HEL/AMD64/BootMain.cxx index 5bff5929..a3f82275 100644 --- a/Private/NewBoot/Source/HEL/AMD64/BootMain.cxx +++ b/Private/NewBoot/Source/HEL/AMD64/BootMain.cxx @@ -31,8 +31,7 @@ EFI_EXTERN_C EFI_API Int EfiMain(EfiHandlePtr ImageHandle, /// Splash screen stuff writer.Write(L"MahroussLogic (R) NewBoot: ") - .Write(BVersionString::Shared()) - .Write(L"\r\n"); + .Write(BVersionString::Shared()); writer.Write(L"\r\nNewBoot: Firmware Vendor: ") .Write(SystemTable->FirmwareVendor) @@ -46,7 +45,7 @@ EFI_EXTERN_C EFI_API Int EfiMain(EfiHandlePtr ImageHandle, kernelImg.ReadAll(); if (kernelImg.Error() == BFileReader::kOperationOkay) { - // First check for a kernel.cfg inside the ESP. + // First check for a .MANIFEST inside the ESP. // This will tell us about the current kernel. BFileReader systemManifest(L".MANIFEST", ImageHandle); diff --git a/Private/Source/Storage/ATA-Wrapper.cxx b/Private/Source/Storage/ATA-Wrapper.cxx deleted file mode 100644 index 407cd30f..00000000 --- a/Private/Source/Storage/ATA-Wrapper.cxx +++ /dev/null @@ -1,102 +0,0 @@ -/* ------------------------------------------- - - Copyright Mahrouss Logic - -------------------------------------------- */ - -#include <ArchKit/ArchKit.hpp> -#include <StorageKit/ATA.hpp> - -#define kBufferLen 512 - -//! @brief ATA DMA Driver -//! The idea is to let a driver do the transfer. - -/// bugs 0 - -#define kATAError 2 - -namespace HCore { -Ref<PRDT*> kPrdt = nullptr; - -bool set_prdt_struct(Ref<PRDT*>& refCtrl) { - if (!kPrdt) { - kPrdt = refCtrl; - kcout << "[set_prdt_struct] PRDT is set."; - - return true; - } - - kcout << "[set_prdt_struct] [WARNING] Trying to change PRDT.\n"; - return false; -} - -enum { - k28BitRead = 0xC8, - k48BitRead = 0x25, - k28BitWrite = 0xCA, - k48BitWrite = 0x35, -}; - -const char* ata_read_28(ULong lba) { - if (!kPrdt) return nullptr; - - char* buffer = reinterpret_cast<char*>(Alloca(sizeof(char) * kBufferLen)); - rt_set_memory(buffer, 0, kBufferLen); - - UIntPtr* packet = reinterpret_cast<UIntPtr*>(kPrdt.Leak()->PhysicalAddress()); - - packet[0] = k28BitRead; - packet[1] = (UIntPtr)&buffer; - packet[4] = lba; - - rt_wait_400ns(); - - return buffer; -} - -const char* ata_read_48(ULong lba) { - if (!kPrdt) return nullptr; - - char* buffer = reinterpret_cast<char*>(Alloca(sizeof(char) * kBufferLen)); - rt_set_memory(buffer, 0, kBufferLen); - - UIntPtr* packet = reinterpret_cast<UIntPtr*>(kPrdt.Leak()->PhysicalAddress()); - - packet[0] = k48BitRead; - packet[1] = (UIntPtr)buffer; - packet[4] = lba; - - rt_wait_400ns(); - - return buffer; -} - -Int32 ata_write_48(ULong lba, const char* buffer) { - if (!kPrdt) return kATAError; - - UIntPtr* packet = reinterpret_cast<UIntPtr*>(kPrdt.Leak()->PhysicalAddress()); - - packet[0] = k48BitWrite; - packet[1] = (UIntPtr)buffer; - packet[2] = lba; - - rt_wait_400ns(); - - return packet[1] == 2 ? kATAError : 0; -} - -Int32 ata_write_28(ULong lba, const char* buffer) { - if (!kPrdt) return kATAError; - - UIntPtr* packet = (UIntPtr*)kPrdt.Leak()->PhysicalAddress(); - - packet[0] = k28BitWrite; - packet[1] = (UIntPtr)buffer; - packet[2] = lba; - - rt_wait_400ns(); - - return packet[1] == 2 ? kATAError : 0; -} -} // namespace HCore diff --git a/Private/Source/Storage/ATAWrapper.cxx b/Private/Source/Storage/ATAWrapper.cxx new file mode 100644 index 00000000..22996d12 --- /dev/null +++ b/Private/Source/Storage/ATAWrapper.cxx @@ -0,0 +1,64 @@ +/* ------------------------------------------- + + Copyright Mahrouss Logic + +------------------------------------------- */ + +#include <ArchKit/ArchKit.hpp> +#include <Builtins/ATA/Defines.hxx> +#include <StorageKit/ATA.hpp> + +#define kBufferLen 512 +#define kSectorCount 512 + +//! @brief ATA DMA Driver +//! The idea is to let a driver do the transfer. +/// @author Amlal EL Mahrouss +/// BUGS: 0 + +#define kATAError 2 + +namespace HCore { +Ref<PRDT*> kPrdt = nullptr; + +bool set_prdt_struct(Ref<PRDT*>& refCtrl) { + if (!kPrdt) { + kPrdt = refCtrl; + kcout << "[set_prdt_struct] PRDT is set."; + + return true; + } + + kcout << "[set_prdt_struct] [WARNING] Trying to change PRDT.\n"; + return false; +} + +enum { + k28BitRead = 0xC8, + k48BitRead = 0x25, + k28BitWrite = 0xCA, + k48BitWrite = 0x35, +}; + +const char* ata_read_28(ULong lba) { + if (!kPrdt) return nullptr; + + Char* packet = reinterpret_cast<Char*>(kPrdt.Leak()->PhysicalAddress()); + + drv_ata_read(lba, ATA_PRIMARY_IO, ATA_MASTER, packet, kSectorCount, + kBufferLen); + + return packet; +} + +const char* ata_read_48(ULong lba) { return nullptr; } + +Int32 ata_write_48(ULong lba, char* buffer) { return kATAError; } + +Int32 ata_write_28(ULong lba, char* buffer) { + drv_ata_write(lba, ATA_PRIMARY_IO, ATA_MASTER, buffer, kSectorCount, + kBufferLen); + + return kATAError; +} +} // namespace HCore diff --git a/Private/StorageKit/ATA.hpp b/Private/StorageKit/ATA.hpp index 4cdf06a2..30c325d5 100644 --- a/Private/StorageKit/ATA.hpp +++ b/Private/StorageKit/ATA.hpp @@ -18,20 +18,20 @@ enum class PATAType { kRead28, kRead48, kWrite28, kWrite48, kATAUnknown }; const char *ata_read_28(ULong lba); const char *ata_read_48(ULong lba); -Int32 ata_write_48(ULong lba, const char *text = nullptr); -Int32 ata_write_28(ULong lba, const char *text = nullptr); +Int32 ata_write_48(ULong lba, char *text = nullptr); +Int32 ata_write_28(ULong lba, char *text = nullptr); -class PATACommandManager final { +class PATACommandFactory final { public: - explicit PATACommandManager() = default; - ~PATACommandManager() = default; + explicit PATACommandFactory() = default; + ~PATACommandFactory() = default; - PATACommandManager &operator=(const PATACommandManager &) = default; - PATACommandManager(const PATACommandManager &) = default; + PATACommandFactory &operator=(const PATACommandFactory &) = default; + PATACommandFactory(const PATACommandFactory &) = default; public: - static Ref<PATACommandManager> Shared() { - static Ref<PATACommandManager> manager; + static Ref<PATACommandFactory> Shared() { + static Ref<PATACommandFactory> manager; return manager; } diff --git a/Private/makefile b/Private/makefile index b7424bad..262bba0f 100644 --- a/Private/makefile +++ b/Private/makefile @@ -27,7 +27,7 @@ MOVEALL=./MoveAll.sh .PHONY: h-core-amd64-pc h-core-amd64-pc: clean - $(CC) $(CCFLAGS) $(DEBUG) Source/*.cxx HALKit/AMD64/PCI/*.cxx Source/Network/*.cxx\ + $(CC) $(CCFLAGS) $(DEBUG) Source/*.cxx HALKit/AMD64/Storage/*.cxx HALKit/AMD64/PCI/*.cxx Source/Network/*.cxx\ Source/Storage/*.cxx HALKit/AMD64/*.cxx HALKit/AMD64/*.cpp HALKit/AMD64/*.s $(ASM) $(ASMFLAGS) HALKit/AMD64/HalInterruptRouting.asm $(ASM) $(ASMFLAGS) HALKit/AMD64/HalSMPCoreManager.asm |
