summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAmlal El Mahrouss <amlalelmahrouss@icloud.com>2024-02-01 22:29:30 +0100
committerAmlal El Mahrouss <amlalelmahrouss@icloud.com>2024-02-01 22:29:30 +0100
commit025593a068bc83f64386325b826179cafd95a03f (patch)
treed6724e71e4cb855dc747699cb380c01b3e7a10bf
parent9700c31e4958856ea9e4fa755a43d196fcf50614 (diff)
Bootloader: Improve PATA support, but will use UEFI SimpleFile to get
the kernel image. Signed-off-by: Amlal El Mahrouss <amlalelmahrouss@icloud.com>
-rw-r--r--Private/EFIKit/Api.hxx (renamed from Private/EFIKit/EFILib.hxx)0
-rw-r--r--Private/EFIKit/EFI.hxx4
-rw-r--r--Private/NewBoot/BootKit/Arch/ATA.hxx15
-rw-r--r--Private/NewBoot/BootKit/BootKit.hxx39
-rw-r--r--Private/NewBoot/Source/HEL/AMD64/ATA.cxx124
-rw-r--r--Private/NewBoot/Source/HEL/AMD64/BootKit.cxx4
-rw-r--r--Private/NewBoot/Source/HEL/AMD64/Entrypoint.cxx6
-rw-r--r--Private/NewBoot/Source/HEL/AMD64/Platform.cxx3
-rw-r--r--Private/NewBoot/Source/makefile2
9 files changed, 109 insertions, 88 deletions
diff --git a/Private/EFIKit/EFILib.hxx b/Private/EFIKit/Api.hxx
index b08c2866..b08c2866 100644
--- a/Private/EFIKit/EFILib.hxx
+++ b/Private/EFIKit/Api.hxx
diff --git a/Private/EFIKit/EFI.hxx b/Private/EFIKit/EFI.hxx
index bf06c514..529efe65 100644
--- a/Private/EFIKit/EFI.hxx
+++ b/Private/EFIKit/EFI.hxx
@@ -420,4 +420,8 @@ typedef struct EfiIPV6 {
#define kEFIYellow (0x01 | 0x02 | 0x04 | 0x08)
+#ifdef __x86_64
+#define __EFI_x86_64__ 1
+#endif // __x86_64
+
#endif // __EFI__
diff --git a/Private/NewBoot/BootKit/Arch/ATA.hxx b/Private/NewBoot/BootKit/Arch/ATA.hxx
index 8327f5c8..6e692c3d 100644
--- a/Private/NewBoot/BootKit/Arch/ATA.hxx
+++ b/Private/NewBoot/BootKit/Arch/ATA.hxx
@@ -95,6 +95,9 @@ using namespace HCore;
#define ATA_PRIMARY 0x00
#define ATA_SECONDARY 0x01
+#define ATA_CYL_LOW 4
+#define ATA_CYL_HIGH 5
+
// IO Direction
#define ATA_READ 0x00
#define ATA_WRITE 0x013
@@ -114,25 +117,25 @@ UInt16 ATAReadLba(UInt32 Lba, UInt8 Bus, Boolean Master);
Void ATAWriteLba(UInt16 Byte, UInt32 Lba, UInt8 Bus, Boolean Master);
Boolean ATAIsDetected(Void);
-class ATAHelper final {
+class BATADevice final {
public:
enum {
kPrimary = ATA_PRIMARY,
kSecondary = ATA_SECONDARY,
};
- explicit ATAHelper() noexcept;
+ explicit BATADevice() noexcept;
- HCORE_COPY_DEFAULT(ATAHelper);
+ HCORE_COPY_DEFAULT(BATADevice);
struct ATATraits final {
SizeT mBase{1024};
- UInt8 mBus{kPrimary};
+ UInt16 mBus{kPrimary};
Boolean mMaster{false};
};
- ATAHelper& Read(WideChar*, const SizeT&);
- ATAHelper& Write(WideChar*, const SizeT&);
+ BATADevice& Read(WideChar*, const SizeT&);
+ BATADevice& Write(WideChar*, const SizeT&);
ATATraits& Traits();
diff --git a/Private/NewBoot/BootKit/BootKit.hxx b/Private/NewBoot/BootKit/BootKit.hxx
index 73bbce37..edd8015b 100644
--- a/Private/NewBoot/BootKit/BootKit.hxx
+++ b/Private/NewBoot/BootKit/BootKit.hxx
@@ -83,7 +83,7 @@ class BFileReader final {
CharacterType mPath[255];
private:
- ATAHelper mHelper;
+ BATADevice mDevice;
};
/***********************************************************************************/
@@ -92,3 +92,40 @@ class BFileReader final {
#include <BootKit/Platform.hxx>
#include <BootKit/Protocol.hxx>
+
+#ifdef __EFI_x86_64__
+
+inline void out8(UInt16 port, UInt8 value) {
+ asm volatile("outb %%al, %1" : : "a"(value), "Nd"(port) : "memory");
+}
+
+inline void out16(UInt16 port, UInt16 value) {
+ asm volatile("outw %%ax, %1" : : "a"(value), "Nd"(port) : "memory");
+}
+
+inline void out32(UInt16 port, UInt32 value) {
+ asm volatile("outl %%eax, %1" : : "a"(value), "Nd"(port) : "memory");
+}
+
+inline UInt8 in8(UInt16 port) {
+ UInt8 value = 0UL;
+ asm volatile("inb %1, %%al" : "=a"(value) : "Nd"(port) : "memory");
+
+ return value;
+}
+
+inline UInt16 in16(UInt16 port) {
+ UInt16 value = 0UL;
+ asm volatile("inw %1, %%ax" : "=a"(value) : "Nd"(port) : "memory");
+
+ return value;
+}
+
+inline UInt32 in32(UInt16 port) {
+ UInt32 value = 0UL;
+ asm volatile("inl %1, %%eax" : "=a"(value) : "Nd"(port) : "memory");
+
+ return value;
+}
+
+#endif // __EFI_x86_64__ \ No newline at end of file
diff --git a/Private/NewBoot/Source/HEL/AMD64/ATA.cxx b/Private/NewBoot/Source/HEL/AMD64/ATA.cxx
index 6b45b4af..6d3635bc 100644
--- a/Private/NewBoot/Source/HEL/AMD64/ATA.cxx
+++ b/Private/NewBoot/Source/HEL/AMD64/ATA.cxx
@@ -10,40 +10,11 @@
#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;
-}
+/***********************************************************************************/
+/// Provide some useful processor features.
+/***********************************************************************************/
-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;
-}
+static Boolean kATADetected = false;
void ATASelect(UInt8 Bus, Boolean isMaster) {
if (Bus == ATA_PRIMARY)
@@ -54,7 +25,8 @@ void ATASelect(UInt8 Bus, Boolean isMaster) {
isMaster ? ATA_PRIMARY_SEL : ATA_SECONDARY_SEL);
}
-Boolean ATAInitDriver(UInt8 Bus, UInt8 Drive) {
+Boolean ATAInitDriver(UInt8 Bus, UInt8 Drive, UInt16& OutBus,
+ Boolean& OutMaster) {
BTextWriter writer;
UInt16 IO = (Bus == ATA_PRIMARY) ? ATA_PRIMARY_IO : ATA_SECONDARY_IO;
@@ -69,33 +41,35 @@ Boolean ATAInitDriver(UInt8 Bus, UInt8 Drive) {
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) {
+ if (status & ATA_SR_ERR) {
#ifdef __DEBUG__
- writer.WriteString(L"HCoreLdr: Init ATA: Bad Drive!\r\n");
+ writer.WriteString(L"HCoreLdr: Init ATA: Bad Drive!\r\n");
#endif // ifdef __DEBUG__
- return false;
- }
+ return false;
+ }
-#ifdef __DEBUG__
- writer.WriteString(L"HCoreLdr: Init ATA: OnLine!\r\n");
-#endif // ifdef __DEBUG__
+ OutBus = (Bus == ATA_PRIMARY) ? BATADevice::kPrimary : BATADevice::kSecondary;
+ OutMaster = (Bus == ATA_PRIMARY);
- kATADetected = true;
- return status;
- }
+ char cl = in8(Bus + ATA_CYL_LOW); /* get the "signature bytes" */
+ char ch = in8(Bus + ATA_CYL_HIGH);
-#ifdef __DEBUG__
- writer.WriteString(L"HCoreLdr: Init ATA: Not detected!\r\n");
-#endif // ifdef __DEBUG__
- return false;
+ /* differentiate ATA, ATAPI, SATA and SATAPI */
+ if (cl == 0x14 && ch == 0xEB)
+ writer.WriteString(L"HCoreLdr: PATAPI detected.\r\n");
+ if (cl == 0x69 && ch == 0x96)
+ writer.WriteString(L"HCoreLdr: SATAPI detected.\r\n");
+ if (cl == 0 && ch == 0) writer.WriteString(L"HCoreLdr: PATA detected.\r\n");
+ if (cl == 0x3c && ch == 0xc3)
+ writer.WriteString(L"HCoreLdr: SATA detected.\r\n");
+
+ return true;
}
+/*** @brief
+ * This polls the ATA drive.
+ */
void ATAWait(UInt16 IO) {
for (int i = 0; i < 4000; i++) in8(IO + ATA_REG_ALT_STATUS);
}
@@ -106,8 +80,6 @@ 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);
@@ -116,21 +88,18 @@ UInt16 ATAReadLba(UInt32 Lba, UInt8 Bus, Boolean Master) {
out8(IO + ATA_REG_COMMAND, ATA_CMD_READ_PIO);
- ATAPoll(IO);
+ while ((in8(ATA_COMMAND(IO))) & 0x88) ATAWait(IO);
- UInt16 data = in16(IO + ATA_REG_DATA);
+ auto chr = in8(IO + ATA_REG_DATA);
while ((in8(ATA_COMMAND(IO))) & 0x88) ATAWait(IO);
-
- return data;
+ return chr;
}
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);
@@ -139,7 +108,7 @@ Void ATAWriteLba(UInt16 Byte, UInt32 Lba, UInt8 Bus, Boolean Master) {
out8(IO + ATA_REG_COMMAND, ATA_CMD_WRITE_PIO); // TODO: support DMA
- ATAPoll(IO);
+ while ((in8(ATA_COMMAND(IO))) & 0x88) ATAWait(IO);
out32(IO + ATA_REG_DATA, Byte);
@@ -152,20 +121,27 @@ Boolean ATAIsDetected(Void) { return kATADetected; }
* @brief Init ATA driver.
* @param void none.
*/
-ATAHelper::ATAHelper() noexcept {
+BATADevice::BATADevice() noexcept {
if (ATAIsDetected()) return;
- ATAInitDriver(ATA_PRIMARY, true);
- ATAInitDriver(ATA_PRIMARY, false);
-
- ATAInitDriver(ATA_SECONDARY, true);
- ATAInitDriver(ATA_SECONDARY, false);
+ if (ATAInitDriver(ATA_PRIMARY, true, this->Traits().mBus,
+ this->Traits().mMaster) ||
+ ATAInitDriver(ATA_PRIMARY, false, this->Traits().mBus,
+ this->Traits().mMaster) ||
+ ATAInitDriver(ATA_SECONDARY, true, this->Traits().mBus,
+ this->Traits().mMaster) ||
+ ATAInitDriver(ATA_SECONDARY, false, this->Traits().mBus,
+ this->Traits().mMaster)) {
+ kATADetected = true;
- BTextWriter writer;
- writer.WriteString(L"KeInitATA: Init: Done\r\n");
+ BTextWriter writer;
+ writer.WriteString(L"BATADevice::BATADevice: OnLine\r\n");
+ }
}
-ATAHelper& ATAHelper::Read(CharacterType* Buf, const SizeT& Sz) {
+BATADevice& BATADevice::Read(CharacterType* Buf, const SizeT& Sz) {
+ if (!ATAIsDetected()) return *this;
+
if (!Buf || Sz < 1) return *this;
for (SizeT i = 0UL; i < Sz; ++i) {
@@ -175,7 +151,9 @@ ATAHelper& ATAHelper::Read(CharacterType* Buf, const SizeT& Sz) {
return *this;
}
-ATAHelper& ATAHelper::Write(CharacterType* Buf, const SizeT& Sz) {
+BATADevice& BATADevice::Write(CharacterType* Buf, const SizeT& Sz) {
+ if (!ATAIsDetected()) return *this;
+
if (!Buf || Sz < 1) return *this;
for (SizeT i = 0UL; i < Sz; ++i) {
@@ -185,4 +163,4 @@ ATAHelper& ATAHelper::Write(CharacterType* Buf, const SizeT& Sz) {
return *this;
}
-ATAHelper::ATATraits& ATAHelper::Traits() { return mTraits; }
+BATADevice::ATATraits& BATADevice::Traits() { return mTraits; }
diff --git a/Private/NewBoot/Source/HEL/AMD64/BootKit.cxx b/Private/NewBoot/Source/HEL/AMD64/BootKit.cxx
index 33e69d05..99f8d41b 100644
--- a/Private/NewBoot/Source/HEL/AMD64/BootKit.cxx
+++ b/Private/NewBoot/Source/HEL/AMD64/BootKit.cxx
@@ -8,9 +8,7 @@
*/
#include <BootKit/BootKit.hxx>
-#include <EFIKit/EFILib.hxx>
-
-#include "BootKit/Arch/ATA.hxx"
+#include <EFIKit/Api.hxx>
/// bugs 0
diff --git a/Private/NewBoot/Source/HEL/AMD64/Entrypoint.cxx b/Private/NewBoot/Source/HEL/AMD64/Entrypoint.cxx
index e2c96d19..31ec449f 100644
--- a/Private/NewBoot/Source/HEL/AMD64/Entrypoint.cxx
+++ b/Private/NewBoot/Source/HEL/AMD64/Entrypoint.cxx
@@ -11,7 +11,7 @@
#include <BootKit/Arch/ATA.hxx>
#include <BootKit/BootKit.hxx>
-#include <EFIKit/EFILib.hxx>
+#include <EFIKit/Api.hxx>
// don't remove EfiGUID, it will call initializer_list!
@@ -27,7 +27,9 @@ EFI_EXTERN_C int EfiMain(EfiHandlePtr ImageHandle,
UInt64 mapKey = 0;
- BFileReader reader(L"\\MAHROUSS\\Root\\System\\HCoreKrnl.exe\0");
+ CharacterType bytes[1024];
+
+ BFileReader reader(L"\\Root\\System\\HCoreKrnl.exe\0");
auto blob = reader.ReadAll();
if (!blob)
diff --git a/Private/NewBoot/Source/HEL/AMD64/Platform.cxx b/Private/NewBoot/Source/HEL/AMD64/Platform.cxx
index dbd2b900..f92de33b 100644
--- a/Private/NewBoot/Source/HEL/AMD64/Platform.cxx
+++ b/Private/NewBoot/Source/HEL/AMD64/Platform.cxx
@@ -15,8 +15,7 @@
*/
#include <BootKit/Platform.hxx>
-
-#include "EFIKit/EFILib.hxx"
+#include <EFIKit/Api.hxx>
extern "C" void rt_halt() { asm volatile("hlt"); }
diff --git a/Private/NewBoot/Source/makefile b/Private/NewBoot/Source/makefile
index acf5f201..0f679772 100644
--- a/Private/NewBoot/Source/makefile
+++ b/Private/NewBoot/Source/makefile
@@ -22,7 +22,7 @@ bootloader-amd64:
.PHONY: run-efi-debug
run-efi-debug:
wget https://retrage.github.io/edk2-nightly/bin/DEBUGX64_OVMF.fd -O OVMF.fd
- qemu-system-x86_64 -bios OVMF.fd -net none -drive file=fat:rw:CDROM,format=raw -d int
+ qemu-system-x86_64 -bios OVMF.fd -drive file=fat:rw:CDROM,format=raw -d int
.PHONY: clean
clean: