summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlalelmahrouss@icloud.com>2024-02-01 20:05:58 +0100
committerAmlal El Mahrouss <amlalelmahrouss@icloud.com>2024-02-01 20:05:58 +0100
commit9700c31e4958856ea9e4fa755a43d196fcf50614 (patch)
tree262cb175fb3af842563436f5d92b084da27fd05f
parent5c59cd35a2fa3e620542b73e8c3f66f0dccd241c (diff)
NewBoot: Add ATA driver for NewFS/EPM.
Also added a ATAHelper class. Signed-off-by: Amlal El Mahrouss <amlalelmahrouss@icloud.com>
-rw-r--r--Private/EFIKit/EFI.hxx2
-rw-r--r--Private/KernelKit/ProcessManager.hpp2
-rw-r--r--Private/NewBoot/BootKit/Arch/ATA.hxx141
-rw-r--r--Private/NewBoot/BootKit/BootKit.hxx6
-rw-r--r--Private/NewBoot/Source/HEL/AMD64/ATA.cxx188
-rw-r--r--Private/NewBoot/Source/HEL/AMD64/BootKit.cxx4
-rw-r--r--Private/NewBoot/Source/HEL/AMD64/Entrypoint.cxx3
-rw-r--r--Private/NewBoot/Source/makefile4
8 files changed, 342 insertions, 8 deletions
diff --git a/Private/EFIKit/EFI.hxx b/Private/EFIKit/EFI.hxx
index af9c0de9..bf06c514 100644
--- a/Private/EFIKit/EFI.hxx
+++ b/Private/EFIKit/EFI.hxx
@@ -418,6 +418,6 @@ typedef struct EfiIPV6 {
UInt8 Addr[16];
} EfiIPV6;
-#define kEFIYellow 0x0E
+#define kEFIYellow (0x01 | 0x02 | 0x04 | 0x08)
#endif // __EFI__
diff --git a/Private/KernelKit/ProcessManager.hpp b/Private/KernelKit/ProcessManager.hpp
index dbcd08b2..5637dd6f 100644
--- a/Private/KernelKit/ProcessManager.hpp
+++ b/Private/KernelKit/ProcessManager.hpp
@@ -16,8 +16,6 @@
#include <NewKit/MutableArray.hpp>
#include <NewKit/UserHeap.hpp>
-#include "NewKit/Defines.hpp"
-
#define kMinMicroTime AffinityKind::kStandard
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/Private/NewBoot/BootKit/Arch/ATA.hxx b/Private/NewBoot/BootKit/Arch/ATA.hxx
new file mode 100644
index 00000000..8327f5c8
--- /dev/null
+++ b/Private/NewBoot/BootKit/Arch/ATA.hxx
@@ -0,0 +1,141 @@
+/*
+ * ========================================================
+ *
+ * NewBoot
+ * Copyright Mahrouss Logic, all rights reserved.
+ *
+ * ========================================================
+ */
+
+#pragma once
+
+#include <CompilerKit/CompilerKit.hpp>
+#include <NewKit/Defines.hpp>
+
+using namespace HCore;
+
+// Status register
+#define ATA_SR_BSY 0x80
+#define ATA_SR_DRDY 0x40
+#define ATA_SR_DF 0x20
+#define ATA_SR_DSC 0x10
+#define ATA_SR_DRQ 0x08
+#define ATA_SR_CORR 0x04
+#define ATA_SR_IDX 0x02
+#define ATA_SR_ERR 0x01
+
+// Error register
+#define ATA_ER_BBK 0x80
+#define ATA_ER_UNC 0x40
+#define ATA_ER_MC 0x20
+#define ATA_ER_IDNF 0x10
+#define ATA_ER_MCR 0x08
+#define ATA_ER_ABRT 0x04
+#define ATA_ER_TK0NF 0x02
+#define ATA_ER_AMNF 0x01
+
+#define ATA_CMD_READ_PIO 0x20
+#define ATA_CMD_READ_PIO_EXT 0x24
+#define ATA_CMD_READ_DMA 0xC8
+#define ATA_CMD_READ_DMA_EXT 0x25
+#define ATA_CMD_WRITE_PIO 0x30
+#define ATA_CMD_WRITE_PIO_EXT 0x34
+#define ATA_CMD_WRITE_DMA 0xCA
+#define ATA_CMD_WRITE_DMA_EXT 0x35
+#define ATA_CMD_CACHE_FLUSH 0xE7
+#define ATA_CMD_CACHE_FLUSH_EXT 0xEA
+#define ATA_CMD_PACKET 0xA0
+#define ATA_CMD_IDENTIFY_PACKET 0xA1
+#define ATA_CMD_IDENTIFY 0xEC
+
+#define ATA_IDENT_DEVICE_TYPE 0
+#define ATA_IDENT_CYLINDERS 2
+#define ATA_IDENT_HEADS 6
+#define ATA_IDENT_SECTORS 12
+#define ATA_IDENT_SERIAL 20
+#define ATA_IDENT_MODEL 54
+#define ATA_IDENT_CAPABILITIES 98
+#define ATA_IDENT_FIELDVALID 106
+#define ATA_IDENT_MAX_LBA 120
+#define ATA_IDENT_COMMANDSETS 164
+#define ATA_IDENT_MAX_LBA_EXT 200
+
+#define ATA_MASTER 0x00
+#define ATA_SLAVE 0x01
+
+// Register
+#define ATA_REG_DATA 0x00
+#define ATA_REG_ERROR 0x01
+#define ATA_REG_FEATURES 0x01
+#define ATA_REG_SEC_COUNT0 0x02
+#define ATA_REG_LBA0 0x03
+#define ATA_REG_LBA1 0x04
+#define ATA_REG_LBA2 0x05
+#define ATA_REG_HDDEVSEL 0x06
+#define ATA_REG_COMMAND 0x07
+#define ATA_REG_STATUS 0x07
+#define ATA_REG_SEC_COUNT1 0x08
+#define ATA_REG_LBA3 0x09
+#define ATA_REG_LBA4 0x0A
+#define ATA_REG_LBA5 0x0B
+#define ATA_REG_CONTROL 0x0C
+#define ATA_REG_ALT_STATUS 0x0C
+#define ATA_REG_DEV_ADDRESS 0x0D
+
+#define ATA_PRIMARY_IO 0x1F0
+#define ATA_SECONDARY_IO 0x170
+#define ATA_PRIMARY_DCR_AS 0x3F6
+#define ATA_SECONDARY_DCR_AS 0x376
+
+// Irq
+#define ATA_PRIMARY_IRQ 14
+#define ATA_SECONDARY_IRQ 15
+
+// Channels
+#define ATA_PRIMARY 0x00
+#define ATA_SECONDARY 0x01
+
+// IO Direction
+#define ATA_READ 0x00
+#define ATA_WRITE 0x013
+
+#define ATA_PRIMARY_SEL 0xA0
+#define ATA_SECONDARY_SEL 0xB0
+
+// ATA Helpers
+#define ATA_ADDRESS1(x) (x + 3)
+#define ATA_ADDRESS2(x) (x + 4)
+#define ATA_ADDRESS3(x) (x + 5)
+#define ATA_COMMAND(x) (x + 7)
+
+Boolean ATAInitDriver(UInt8 Bus, UInt8 Drv);
+Void ATAWait(UInt16 IO);
+UInt16 ATAReadLba(UInt32 Lba, UInt8 Bus, Boolean Master);
+Void ATAWriteLba(UInt16 Byte, UInt32 Lba, UInt8 Bus, Boolean Master);
+Boolean ATAIsDetected(Void);
+
+class ATAHelper final {
+ public:
+ enum {
+ kPrimary = ATA_PRIMARY,
+ kSecondary = ATA_SECONDARY,
+ };
+
+ explicit ATAHelper() noexcept;
+
+ HCORE_COPY_DEFAULT(ATAHelper);
+
+ struct ATATraits final {
+ SizeT mBase{1024};
+ UInt8 mBus{kPrimary};
+ Boolean mMaster{false};
+ };
+
+ ATAHelper& Read(WideChar*, const SizeT&);
+ ATAHelper& Write(WideChar*, const SizeT&);
+
+ ATATraits& Traits();
+
+ private:
+ ATATraits mTraits;
+};
diff --git a/Private/NewBoot/BootKit/BootKit.hxx b/Private/NewBoot/BootKit/BootKit.hxx
index cec3bdc2..73bbce37 100644
--- a/Private/NewBoot/BootKit/BootKit.hxx
+++ b/Private/NewBoot/BootKit/BootKit.hxx
@@ -14,6 +14,7 @@
#pragma once
+#include <BootKit/Arch/ATA.hxx>
#include <NewKit/Defines.hpp>
using namespace HCore;
@@ -27,7 +28,7 @@ enum {
kSegmentBss = 6,
};
-typedef wchar_t CharacterType;
+typedef WideChar CharacterType;
/**
* @brief BootKit Text Writer class
@@ -80,6 +81,9 @@ class BFileReader final {
private:
Int32 mErrorCode{kOperationOkay};
CharacterType mPath[255];
+
+ private:
+ ATAHelper mHelper;
};
/***********************************************************************************/
diff --git a/Private/NewBoot/Source/HEL/AMD64/ATA.cxx b/Private/NewBoot/Source/HEL/AMD64/ATA.cxx
new file mode 100644
index 00000000..6b45b4af
--- /dev/null
+++ b/Private/NewBoot/Source/HEL/AMD64/ATA.cxx
@@ -0,0 +1,188 @@
+/*
+ * ========================================================
+ *
+ * NewBoot
+ * Copyright Mahrouss Logic, all rights reserved.
+ *
+ * ========================================================
+ */
+
+#include <BootKit/Arch/ATA.hxx>
+#include <BootKit/BootKit.hxx>
+
+static Boolean kATADetected = false;
+
+extern "C" void out8(UInt16 port, UInt8 value) {
+ asm volatile("outb %%al, %1" : : "a"(value), "Nd"(port) : "memory");
+}
+
+extern "C" void out16(UInt16 port, UInt16 value) {
+ asm volatile("outw %%ax, %1" : : "a"(value), "Nd"(port) : "memory");
+}
+
+extern "C" void out32(UInt16 port, UInt32 value) {
+ asm volatile("outl %%eax, %1" : : "a"(value), "Nd"(port) : "memory");
+}
+
+extern "C" UInt8 in8(UInt16 port) {
+ UInt8 value = 0UL;
+ asm volatile("inb %1, %%al" : "=a"(value) : "Nd"(port) : "memory");
+
+ return value;
+}
+
+extern "C" UInt16 in16(UInt16 port) {
+ UInt16 value = 0UL;
+ asm volatile("inw %1, %%ax" : "=a"(value) : "Nd"(port) : "memory");
+
+ return value;
+}
+
+extern "C" UInt32 in32(UInt16 port) {
+ UInt32 value = 0UL;
+ asm volatile("inl %1, %%eax" : "=a"(value) : "Nd"(port) : "memory");
+
+ return value;
+}
+
+void ATASelect(UInt8 Bus, Boolean isMaster) {
+ if (Bus == ATA_PRIMARY)
+ out8(ATA_PRIMARY_IO + ATA_REG_HDDEVSEL,
+ isMaster ? ATA_PRIMARY_SEL : ATA_SECONDARY_SEL);
+ else
+ out8(ATA_SECONDARY_IO + ATA_REG_HDDEVSEL,
+ isMaster ? ATA_PRIMARY_SEL : ATA_SECONDARY_SEL);
+}
+
+Boolean ATAInitDriver(UInt8 Bus, UInt8 Drive) {
+ BTextWriter writer;
+
+ UInt16 IO = (Bus == ATA_PRIMARY) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO;
+
+ ATASelect(Bus, Drive);
+
+ out8(IO + ATA_REG_SEC_COUNT0, 0);
+ out8(IO + ATA_REG_LBA0, 0);
+ out8(IO + ATA_REG_LBA1, 0);
+ out8(IO + ATA_REG_LBA2, 0);
+
+ out8(IO + ATA_REG_COMMAND, ATA_CMD_IDENTIFY);
+
+ UInt8 status = in8(IO + ATA_REG_STATUS);
+ writer.WriteString(L"HCoreLdr: Init ATA: Checking status...\r\n");
+
+ if (status) {
+ while ((status = in8(IO + ATA_REG_STATUS) & ATA_SR_BSY))
+ ;
+
+ if (status & ATA_REG_ERROR) {
+#ifdef __DEBUG__
+ writer.WriteString(L"HCoreLdr: Init ATA: Bad Drive!\r\n");
+#endif // ifdef __DEBUG__
+ return false;
+ }
+
+#ifdef __DEBUG__
+ writer.WriteString(L"HCoreLdr: Init ATA: OnLine!\r\n");
+#endif // ifdef __DEBUG__
+
+ kATADetected = true;
+ return status;
+ }
+
+#ifdef __DEBUG__
+ writer.WriteString(L"HCoreLdr: Init ATA: Not detected!\r\n");
+#endif // ifdef __DEBUG__
+ return false;
+}
+
+void ATAWait(UInt16 IO) {
+ for (int i = 0; i < 4000; i++) in8(IO + ATA_REG_ALT_STATUS);
+}
+
+void ATAPoll(UInt16 IO) { ATAWait(IO); }
+
+UInt16 ATAReadLba(UInt32 Lba, UInt8 Bus, Boolean Master) {
+ UInt16 IO = Bus;
+ ATASelect(IO, Master ? ATA_MASTER : ATA_SLAVE);
+
+ out8(IO + ATA_REG_LBA5, (UInt8)(Lba >> 24) & 0xF);
+
+ out8(IO + ATA_REG_SEC_COUNT0, Lba / 512);
+
+ 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);
+
+ ATAPoll(IO);
+
+ UInt16 data = in16(IO + ATA_REG_DATA);
+
+ while ((in8(ATA_COMMAND(IO))) & 0x88) ATAWait(IO);
+
+ return data;
+}
+
+Void ATAWriteLba(UInt16 Byte, UInt32 Lba, UInt8 Bus, Boolean Master) {
+ UInt16 IO = Bus;
+ ATASelect(IO, Master ? ATA_MASTER : ATA_SLAVE);
+
+ out8(IO + ATA_REG_LBA5, (UInt8)(Lba >> 24) & 0xF);
+
+ out8(IO + ATA_REG_SEC_COUNT0, Lba / 512);
+
+ 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); // TODO: support DMA
+
+ ATAPoll(IO);
+
+ out32(IO + ATA_REG_DATA, Byte);
+
+ while ((in8(ATA_COMMAND(IO))) & 0x88) ATAWait(IO);
+}
+
+Boolean ATAIsDetected(Void) { return kATADetected; }
+
+/**
+ * @brief Init ATA driver.
+ * @param void none.
+ */
+ATAHelper::ATAHelper() noexcept {
+ if (ATAIsDetected()) return;
+
+ ATAInitDriver(ATA_PRIMARY, true);
+ ATAInitDriver(ATA_PRIMARY, false);
+
+ ATAInitDriver(ATA_SECONDARY, true);
+ ATAInitDriver(ATA_SECONDARY, false);
+
+ BTextWriter writer;
+ writer.WriteString(L"KeInitATA: Init: Done\r\n");
+}
+
+ATAHelper& ATAHelper::Read(CharacterType* Buf, const SizeT& Sz) {
+ if (!Buf || Sz < 1) return *this;
+
+ for (SizeT i = 0UL; i < Sz; ++i) {
+ Buf[i] = ATAReadLba(this->Traits().mBase + i, this->Traits().mBus,
+ this->Traits().mMaster);
+ }
+ return *this;
+}
+
+ATAHelper& ATAHelper::Write(CharacterType* Buf, const SizeT& Sz) {
+ if (!Buf || Sz < 1) return *this;
+
+ for (SizeT i = 0UL; i < Sz; ++i) {
+ ATAWriteLba(Buf[i], this->Traits().mBase + i, this->Traits().mBus,
+ this->Traits().mMaster);
+ }
+ return *this;
+}
+
+ATAHelper::ATATraits& ATAHelper::Traits() { return mTraits; }
diff --git a/Private/NewBoot/Source/HEL/AMD64/BootKit.cxx b/Private/NewBoot/Source/HEL/AMD64/BootKit.cxx
index 43a79b41..33e69d05 100644
--- a/Private/NewBoot/Source/HEL/AMD64/BootKit.cxx
+++ b/Private/NewBoot/Source/HEL/AMD64/BootKit.cxx
@@ -10,6 +10,8 @@
#include <BootKit/BootKit.hxx>
#include <EFIKit/EFILib.hxx>
+#include "BootKit/Arch/ATA.hxx"
+
/// bugs 0
HCore::SizeT BStrLen(const CharacterType *ptr) {
@@ -85,7 +87,7 @@ BFileReader::BFileReader(const CharacterType *path) {
*/
HCore::VoidPtr BFileReader::ReadAll() {
BTextWriter writer;
- writer.WriteString(L"*** PE/COFF: Reading ")
+ writer.WriteString(L"*** BFileReader::ReadAll: Reading ")
.WriteString(mPath)
.WriteString(L" *** \r\n");
diff --git a/Private/NewBoot/Source/HEL/AMD64/Entrypoint.cxx b/Private/NewBoot/Source/HEL/AMD64/Entrypoint.cxx
index d06338b5..e2c96d19 100644
--- a/Private/NewBoot/Source/HEL/AMD64/Entrypoint.cxx
+++ b/Private/NewBoot/Source/HEL/AMD64/Entrypoint.cxx
@@ -9,6 +9,7 @@
#define __BOOTLOADER__ 1
+#include <BootKit/Arch/ATA.hxx>
#include <BootKit/BootKit.hxx>
#include <EFIKit/EFILib.hxx>
@@ -19,9 +20,9 @@ EFI_EXTERN_C int EfiMain(EfiHandlePtr ImageHandle,
KeInitEFI(SystemTable);
BTextWriter writer;
+
writer.WriteString(L"HCoreLdr: Firmware: ")
.WriteString(SystemTable->FirmwareVendor)
- .WriteString(L"\r\nHCoreLdr: Booting on \\Volume0\\ (FAT32)")
.WriteString(L"\r\n");
UInt64 mapKey = 0;
diff --git a/Private/NewBoot/Source/makefile b/Private/NewBoot/Source/makefile
index f10a4194..acf5f201 100644
--- a/Private/NewBoot/Source/makefile
+++ b/Private/NewBoot/Source/makefile
@@ -6,7 +6,7 @@
CC_GNU=x86_64-w64-mingw32-g++
LD_GNU=x86_64-w64-mingw32-ld
-FLAG_GNU=-fshort-wchar -fPIC -D__DBG__ -DEFI_FUNCTION_WRAPPER -I../ -I../../ -I../../efiSDK/inc -I./ -c -ffreestanding -fno-rtti -fno-exceptions -std=c++20 -D__HAVE_HCORE_APIS__ -D__HCORE__ -I./ -I$(HOME)/
+FLAG_GNU=-fshort-wchar -fPIC -D__DEBUG__ -DEFI_FUNCTION_WRAPPER -I../ -I../../ -I../../efiSDK/inc -I./ -c -ffreestanding -fno-rtti -fno-exceptions -std=c++20 -D__HAVE_HCORE_APIS__ -D__HCORE__ -I./ -I$(HOME)/
.PHONY: invalid-recipe
invalid-recipe:
@@ -14,7 +14,7 @@ invalid-recipe:
.PHONY: bootloader-amd64
bootloader-amd64:
- $(CC_GNU) $(FLAG_GNU) HEL/AMD64/*.cxx *.cxx
+ $(CC_GNU) $(FLAG_GNU) HEL/AMD64/*.cxx
$(LD_GNU) *.o -e efi_main -filealign:16 -shared --subsystem=10 -ffreestanding -o HCoreLdr.exe
cp HCoreLdr.exe CDROM/EFI/BOOT/BOOTX64.EFI
cp ../../HCoreKrnl.exe CDROM/EFI/BOOT/HCoreKrnl.exe