summaryrefslogtreecommitdiffhomepage
path: root/Private
diff options
context:
space:
mode:
authoramlal <amlal@el-mahrouss-logic.com>2024-03-22 10:09:51 +0100
committeramlal <amlal@el-mahrouss-logic.com>2024-03-22 10:09:51 +0100
commit71ead709ab3e30a1b137a5b9215bf74c7bed9d04 (patch)
tree55ded35496cc7054c0975fd9364f8b2513ac0531 /Private
parent5df4daf0619b95131ea99110ee2e8913012b6134 (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.hxx29
-rw-r--r--Private/HALKit/AMD64/Storage/ATA.cxx175
-rw-r--r--Private/NewBoot/BootKit/Arch/ATA.hxx11
-rw-r--r--Private/NewBoot/Source/HEL/AMD64/BootMain.cxx5
-rw-r--r--Private/Source/Storage/ATA-Wrapper.cxx102
-rw-r--r--Private/Source/Storage/ATAWrapper.cxx64
-rw-r--r--Private/StorageKit/ATA.hpp18
-rw-r--r--Private/makefile2
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