diff options
| author | Amlal El Mahrouss <amlalelmahrouss@icloud.com> | 2024-02-01 20:05:58 +0100 |
|---|---|---|
| committer | Amlal El Mahrouss <amlalelmahrouss@icloud.com> | 2024-02-01 20:05:58 +0100 |
| commit | 9700c31e4958856ea9e4fa755a43d196fcf50614 (patch) | |
| tree | 262cb175fb3af842563436f5d92b084da27fd05f | |
| parent | 5c59cd35a2fa3e620542b73e8c3f66f0dccd241c (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.hxx | 2 | ||||
| -rw-r--r-- | Private/KernelKit/ProcessManager.hpp | 2 | ||||
| -rw-r--r-- | Private/NewBoot/BootKit/Arch/ATA.hxx | 141 | ||||
| -rw-r--r-- | Private/NewBoot/BootKit/BootKit.hxx | 6 | ||||
| -rw-r--r-- | Private/NewBoot/Source/HEL/AMD64/ATA.cxx | 188 | ||||
| -rw-r--r-- | Private/NewBoot/Source/HEL/AMD64/BootKit.cxx | 4 | ||||
| -rw-r--r-- | Private/NewBoot/Source/HEL/AMD64/Entrypoint.cxx | 3 | ||||
| -rw-r--r-- | Private/NewBoot/Source/makefile | 4 |
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 |
