diff options
| author | Amlal El Mahrouss <amlalelmahrouss@icloud.com> | 2024-02-01 22:29:30 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlalelmahrouss@icloud.com> | 2024-02-01 22:29:30 +0100 |
| commit | 025593a068bc83f64386325b826179cafd95a03f (patch) | |
| tree | d6724e71e4cb855dc747699cb380c01b3e7a10bf | |
| parent | 9700c31e4958856ea9e4fa755a43d196fcf50614 (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.hxx | 4 | ||||
| -rw-r--r-- | Private/NewBoot/BootKit/Arch/ATA.hxx | 15 | ||||
| -rw-r--r-- | Private/NewBoot/BootKit/BootKit.hxx | 39 | ||||
| -rw-r--r-- | Private/NewBoot/Source/HEL/AMD64/ATA.cxx | 124 | ||||
| -rw-r--r-- | Private/NewBoot/Source/HEL/AMD64/BootKit.cxx | 4 | ||||
| -rw-r--r-- | Private/NewBoot/Source/HEL/AMD64/Entrypoint.cxx | 6 | ||||
| -rw-r--r-- | Private/NewBoot/Source/HEL/AMD64/Platform.cxx | 3 | ||||
| -rw-r--r-- | Private/NewBoot/Source/makefile | 2 |
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: |
