https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1fd9d11f160c10e70311b…
commit 1fd9d11f160c10e70311b4176d0fad950b6cfe54
Author: Justin Miller <justinmiller100(a)gmail.com>
AuthorDate: Sun Apr 30 05:57:10 2023 -0700
Commit: GitHub <noreply(a)github.com>
CommitDate: Sun Apr 30 14:57:10 2023 +0200
[FREELDR] Add disk access handlers for UEFI (#5219)
CORE-11953
---
boot/freeldr/freeldr/arch/uefi/stubs.c | 34 --
boot/freeldr/freeldr/arch/uefi/uefidisk.c | 596 ++++++++++++++++++++++++++++++
boot/freeldr/freeldr/uefi.cmake | 7 +-
3 files changed, 600 insertions(+), 37 deletions(-)
diff --git a/boot/freeldr/freeldr/arch/uefi/stubs.c
b/boot/freeldr/freeldr/arch/uefi/stubs.c
index 75f7ee0fc8b..28f11b7795b 100644
--- a/boot/freeldr/freeldr/arch/uefi/stubs.c
+++ b/boot/freeldr/freeldr/arch/uefi/stubs.c
@@ -48,40 +48,6 @@ UefiGetExtendedBIOSData(PULONG ExtendedBIOSDataArea,
}
-UCHAR
-UefiGetFloppyCount(VOID)
-{
- return 0;
-}
-
-BOOLEAN
-UefiDiskReadLogicalSectors(IN UCHAR DriveNumber,
- IN ULONGLONG SectorNumber,
- IN ULONG SectorCount,
- OUT PVOID Buffer)
-{
- return 0;
-}
-
-BOOLEAN
-UefiDiskGetDriveGeometry(UCHAR DriveNumber,
- PGEOMETRY Geometry)
-{
- return 0;
-}
-
-ULONG
-UefiDiskGetCacheableBlockCount(UCHAR DriveNumber)
-{
- return 0;
-}
-
-BOOLEAN
-UefiInitializeBootDevices(VOID)
-{
- return 0;
-}
-
PCONFIGURATION_COMPONENT_DATA
UefiHwDetect(VOID)
{
diff --git a/boot/freeldr/freeldr/arch/uefi/uefidisk.c
b/boot/freeldr/freeldr/arch/uefi/uefidisk.c
new file mode 100644
index 00000000000..772cdece7ce
--- /dev/null
+++ b/boot/freeldr/freeldr/arch/uefi/uefidisk.c
@@ -0,0 +1,596 @@
+/*
+ * PROJECT: FreeLoader UEFI Support
+ * LICENSE: GPL-2.0-or-later (
https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE: Disk Access Functions
+ * COPYRIGHT: Copyright 2022 Justin Miller <justinmiller100(a)gmail.com>
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <uefildr.h>
+
+#include <debug.h>
+DBG_DEFAULT_CHANNEL(WARNING);
+
+#define TAG_HW_RESOURCE_LIST 'lRwH'
+#define TAG_HW_DISK_CONTEXT 'cDwH'
+#define FIRST_BIOS_DISK 0x80
+#define FIRST_PARTITION 1
+
+typedef struct tagDISKCONTEXT
+{
+ UCHAR DriveNumber;
+ ULONG SectorSize;
+ ULONGLONG SectorOffset;
+ ULONGLONG SectorCount;
+ ULONGLONG SectorNumber;
+} DISKCONTEXT;
+
+typedef struct _INTERNAL_UEFI_DISK
+{
+ UCHAR ArcDriveNumber;
+ UCHAR NumOfPartitions;
+ UCHAR UefiRootNumber;
+ BOOLEAN IsThisTheBootDrive;
+} INTERNAL_UEFI_DISK, *PINTERNAL_UEFI_DISK;
+
+/* GLOBALS *******************************************************************/
+
+extern EFI_SYSTEM_TABLE* GlobalSystemTable;
+extern EFI_HANDLE GlobalImageHandle;
+extern EFI_HANDLE PublicBootHandle; /* Freeldr itself */
+
+/* Made to match BIOS */
+PVOID DiskReadBuffer;
+UCHAR PcBiosDiskCount;
+
+UCHAR FrldrBootDrive;
+ULONG FrldrBootPartition;
+SIZE_T DiskReadBufferSize;
+PVOID Buffer;
+
+static const CHAR Hex[] = "0123456789abcdef";
+static CHAR PcDiskIdentifier[32][20];
+
+/* UEFI-specific */
+static ULONG UefiBootRootIdentifier;
+static ULONG OffsetToBoot;
+static ULONG PublicBootArcDisk;
+static INTERNAL_UEFI_DISK* InternalUefiDisk = NULL;
+static EFI_GUID bioGuid = BLOCK_IO_PROTOCOL;
+static EFI_BLOCK_IO* bio;
+static EFI_HANDLE* handles = NULL;
+
+/* FUNCTIONS *****************************************************************/
+
+PCHAR
+GetHarddiskIdentifier(UCHAR DriveNumber)
+{
+ TRACE("GetHarddiskIdentifier: DriveNumber: %d\n", DriveNumber);
+ return PcDiskIdentifier[DriveNumber - FIRST_BIOS_DISK];
+}
+
+static LONG lReportError = 0; // >= 0: display errors; < 0: hide errors.
+
+LONG
+DiskReportError(BOOLEAN bShowError)
+{
+ /* Set the reference count */
+ if (bShowError) ++lReportError;
+ else --lReportError;
+ return lReportError;
+}
+
+static
+BOOLEAN
+UefiGetBootPartitionEntry(
+ IN UCHAR DriveNumber,
+ OUT PPARTITION_TABLE_ENTRY PartitionTableEntry,
+ OUT PULONG BootPartition)
+{
+ ULONG PartitionNum;
+
+ TRACE("UefiGetBootPartitionEntry: DriveNumber: %d\n", DriveNumber -
FIRST_BIOS_DISK);
+ /* UefiBootRoot is the offset into the array of handles where the raw disk of the
boot drive is.
+ * Partitions start with 1 in ARC, but UEFI root drive identitfier is also first
partition. */
+ PartitionNum = (OffsetToBoot - UefiBootRootIdentifier);
+ if (PartitionNum == 0)
+ {
+ TRACE("Boot PartitionNumber is 0\n");
+ /* The OffsetToBoot is equal to the RootIdentifier */
+ PartitionNum = 1;
+ }
+
+ *BootPartition = PartitionNum;
+ TRACE("UefiGetBootPartitionEntry: Boot Partition is: %d\n", PartitionNum);
+ return TRUE;
+}
+
+static
+ARC_STATUS
+UefiDiskClose(ULONG FileId)
+{
+ DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
+ FrLdrTempFree(Context, TAG_HW_DISK_CONTEXT);
+ return ESUCCESS;
+}
+
+static
+ARC_STATUS
+UefiDiskGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
+{
+ DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
+ RtlZeroMemory(Information, sizeof(*Information));
+
+ /*
+ * The ARC specification mentions that for partitions, StartingAddress and
+ * EndingAddress are the start and end positions of the partition in terms
+ * of byte offsets from the start of the disk.
+ * CurrentAddress is the current offset into (i.e. relative to) the partition.
+ */
+ Information->StartingAddress.QuadPart = Context->SectorOffset *
Context->SectorSize;
+ Information->EndingAddress.QuadPart = (Context->SectorOffset +
Context->SectorCount) * Context->SectorSize;
+ Information->CurrentAddress.QuadPart = Context->SectorNumber *
Context->SectorSize;
+
+ return ESUCCESS;
+}
+
+static
+ARC_STATUS
+UefiDiskOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
+{
+ DISKCONTEXT* Context;
+ UCHAR DriveNumber;
+ ULONG DrivePartition, SectorSize;
+ ULONGLONG SectorOffset = 0;
+ ULONGLONG SectorCount = 0;
+ ULONG UefiDriveNumber = 0;
+ PARTITION_TABLE_ENTRY PartitionTableEntry;
+
+ TRACE("UefiDiskOpen: File ID: %d, Path: %s\n", FileId, Path);
+
+ if (DiskReadBufferSize == 0)
+ {
+ ERR("DiskOpen(): DiskReadBufferSize is 0, something is wrong.\n");
+ ASSERT(FALSE);
+ return ENOMEM;
+ }
+
+ if (!DissectArcPath(Path, NULL, &DriveNumber, &DrivePartition))
+ return EINVAL;
+
+ TRACE("Opening disk: DriveNumber: %d, DrivePartition: %d\n", DriveNumber,
DrivePartition);
+ UefiDriveNumber = DriveNumber - FIRST_BIOS_DISK;
+ GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber],
&bioGuid, (void**)&bio);
+ SectorSize = bio->Media->BlockSize;
+
+ if (DrivePartition != 0xff && DrivePartition != 0)
+ {
+ if (!DiskGetPartitionEntry(DriveNumber, DrivePartition,
&PartitionTableEntry))
+ return EINVAL;
+
+ SectorOffset = PartitionTableEntry.SectorCountBeforePartition;
+ SectorCount = PartitionTableEntry.PartitionSectorCount;
+ }
+ else
+ {
+ GEOMETRY Geometry;
+ if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
+ return EINVAL;
+
+ if (SectorSize != Geometry.BytesPerSector)
+ {
+ ERR("SectorSize (%lu) != Geometry.BytesPerSector (%lu), expect
problems!\n",
+ SectorSize, Geometry.BytesPerSector);
+ }
+
+ SectorOffset = 0;
+ SectorCount = (ULONGLONG)Geometry.Cylinders * Geometry.Heads * Geometry.Sectors;
+ }
+
+ Context = FrLdrTempAlloc(sizeof(DISKCONTEXT), TAG_HW_DISK_CONTEXT);
+ if (!Context)
+ return ENOMEM;
+
+ Context->DriveNumber = DriveNumber;
+ Context->SectorSize = SectorSize;
+ Context->SectorOffset = SectorOffset;
+ Context->SectorCount = SectorCount;
+ Context->SectorNumber = 0;
+ FsSetDeviceSpecific(*FileId, Context);
+ return ESUCCESS;
+}
+
+static
+ARC_STATUS
+UefiDiskRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
+{
+ DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
+ UCHAR* Ptr = (UCHAR*)Buffer;
+ ULONG Length, TotalSectors, MaxSectors, ReadSectors;
+ ULONGLONG SectorOffset;
+ BOOLEAN ret;
+
+ ASSERT(DiskReadBufferSize > 0);
+
+ TotalSectors = (N + Context->SectorSize - 1) / Context->SectorSize;
+ MaxSectors = DiskReadBufferSize / Context->SectorSize;
+ SectorOffset = Context->SectorOffset + Context->SectorNumber;
+
+ // If MaxSectors is 0, this will lead to infinite loop.
+ // In release builds assertions are disabled, however we also have sanity checks in
DiskOpen()
+ ASSERT(MaxSectors > 0);
+
+ ret = TRUE;
+
+ while (TotalSectors)
+ {
+ ReadSectors = min(TotalSectors, MaxSectors);
+
+ ret = MachDiskReadLogicalSectors(Context->DriveNumber,
+ SectorOffset,
+ ReadSectors,
+ DiskReadBuffer);
+ if (!ret)
+ break;
+
+ Length = ReadSectors * Context->SectorSize;
+ Length = min(Length, N);
+
+ RtlCopyMemory(Ptr, DiskReadBuffer, Length);
+
+ Ptr += Length;
+ N -= Length;
+ SectorOffset += ReadSectors;
+ TotalSectors -= ReadSectors;
+ }
+
+ *Count = (ULONG)((ULONG_PTR)Ptr - (ULONG_PTR)Buffer);
+ Context->SectorNumber = SectorOffset - Context->SectorOffset;
+
+ return (ret ? ESUCCESS : EIO);
+}
+
+static
+ARC_STATUS
+UefiDiskSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
+{
+ DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
+ LARGE_INTEGER NewPosition = *Position;
+
+ switch (SeekMode)
+ {
+ case SeekAbsolute:
+ break;
+ case SeekRelative:
+ NewPosition.QuadPart += (Context->SectorNumber * Context->SectorSize);
+ break;
+ default:
+ ASSERT(FALSE);
+ return EINVAL;
+ }
+
+ if (NewPosition.QuadPart & (Context->SectorSize - 1))
+ return EINVAL;
+
+ /* Convert in number of sectors */
+ NewPosition.QuadPart /= Context->SectorSize;
+
+ /* HACK: CDROMs may have a SectorCount of 0 */
+ if (Context->SectorCount != 0 && NewPosition.QuadPart >=
Context->SectorCount)
+ return EINVAL;
+
+ Context->SectorNumber = NewPosition.QuadPart;
+ return ESUCCESS;
+}
+
+static const DEVVTBL UefiDiskVtbl =
+{
+ UefiDiskClose,
+ UefiDiskGetFileInformation,
+ UefiDiskOpen,
+ UefiDiskRead,
+ UefiDiskSeek,
+};
+
+static
+VOID
+GetHarddiskInformation(UCHAR DriveNumber)
+{
+ PMASTER_BOOT_RECORD Mbr;
+ PULONG Buffer;
+ ULONG i;
+ ULONG Checksum;
+ ULONG Signature;
+ BOOLEAN ValidPartitionTable;
+ CHAR ArcName[MAX_PATH];
+ PARTITION_TABLE_ENTRY PartitionTableEntry;
+ PCHAR Identifier = PcDiskIdentifier[DriveNumber - FIRST_BIOS_DISK];
+
+ /* Detect disk partition type */
+ DiskDetectPartitionType(DriveNumber);
+
+ /* Read the MBR */
+ if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, DiskReadBuffer))
+ {
+ ERR("Reading MBR failed\n");
+ /* We failed, use a default identifier */
+ sprintf(Identifier, "BIOSDISK%d", DriveNumber - FIRST_BIOS_DISK);
+ return;
+ }
+
+ Buffer = (ULONG*)DiskReadBuffer;
+ Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
+
+ Signature = Mbr->Signature;
+ TRACE("Signature: %x\n", Signature);
+
+ /* Calculate the MBR checksum */
+ Checksum = 0;
+ for (i = 0; i < 512 / sizeof(ULONG); i++)
+ {
+ Checksum += Buffer[i];
+ }
+ Checksum = ~Checksum + 1;
+ TRACE("Checksum: %x\n", Checksum);
+
+ ValidPartitionTable = (Mbr->MasterBootRecordMagic == 0xAA55);
+
+ /* Fill out the ARC disk block */
+ sprintf(ArcName, "multi(0)disk(0)rdisk(%u)", DriveNumber -
FIRST_BIOS_DISK);
+ AddReactOSArcDiskInfo(ArcName, Signature, Checksum, ValidPartitionTable);
+
+ sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(0)", DriveNumber -
FIRST_BIOS_DISK);
+ FsRegisterDevice(ArcName, &UefiDiskVtbl);
+
+ /* Add partitions */
+ i = FIRST_PARTITION;
+ DiskReportError(FALSE);
+ while (DiskGetPartitionEntry(DriveNumber, i, &PartitionTableEntry))
+ {
+ if (PartitionTableEntry.SystemIndicator != PARTITION_ENTRY_UNUSED)
+ {
+ sprintf(ArcName, "multi(0)disk(0)rdisk(%u)partition(%lu)",
DriveNumber - FIRST_BIOS_DISK, i);
+ FsRegisterDevice(ArcName, &UefiDiskVtbl);
+ }
+ i++;
+ }
+ DiskReportError(TRUE);
+
+ InternalUefiDisk[DriveNumber].NumOfPartitions = i;
+ /* Convert checksum and signature to identifier string */
+ Identifier[0] = Hex[(Checksum >> 28) & 0x0F];
+ Identifier[1] = Hex[(Checksum >> 24) & 0x0F];
+ Identifier[2] = Hex[(Checksum >> 20) & 0x0F];
+ Identifier[3] = Hex[(Checksum >> 16) & 0x0F];
+ Identifier[4] = Hex[(Checksum >> 12) & 0x0F];
+ Identifier[5] = Hex[(Checksum >> 8) & 0x0F];
+ Identifier[6] = Hex[(Checksum >> 4) & 0x0F];
+ Identifier[7] = Hex[Checksum & 0x0F];
+ Identifier[8] = '-';
+ Identifier[9] = Hex[(Signature >> 28) & 0x0F];
+ Identifier[10] = Hex[(Signature >> 24) & 0x0F];
+ Identifier[11] = Hex[(Signature >> 20) & 0x0F];
+ Identifier[12] = Hex[(Signature >> 16) & 0x0F];
+ Identifier[13] = Hex[(Signature >> 12) & 0x0F];
+ Identifier[14] = Hex[(Signature >> 8) & 0x0F];
+ Identifier[15] = Hex[(Signature >> 4) & 0x0F];
+ Identifier[16] = Hex[Signature & 0x0F];
+ Identifier[17] = '-';
+ Identifier[18] = (ValidPartitionTable ? 'A' : 'X');
+ Identifier[19] = 0;
+ TRACE("Identifier: %s\n", Identifier);
+}
+
+static
+VOID
+UefiSetupBlockDevices(VOID)
+{
+ ULONG BlockDeviceIndex;
+ ULONG SystemHandleCount;
+ EFI_STATUS Status;
+ ULONG i;
+
+ UINTN handle_size = 0;
+ PcBiosDiskCount = 0;
+ UefiBootRootIdentifier = 0;
+
+ /* 1) Setup a list of boothandles by using the LocateHandle protocol */
+ Status = GlobalSystemTable->BootServices->LocateHandle(ByProtocol,
&bioGuid, NULL, &handle_size, handles);
+ handles = MmAllocateMemoryWithType(handle_size, LoaderFirmwareTemporary);
+ Status = GlobalSystemTable->BootServices->LocateHandle(ByProtocol,
&bioGuid, NULL, &handle_size, handles);
+ SystemHandleCount = handle_size / sizeof(EFI_HANDLE);
+ InternalUefiDisk = MmAllocateMemoryWithType(sizeof(INTERNAL_UEFI_DISK) *
SystemHandleCount, LoaderFirmwareTemporary);
+
+ BlockDeviceIndex = 0;
+ /* 2) Parse the handle list */
+ for (i = 0; i < SystemHandleCount; ++i)
+ {
+ Status = GlobalSystemTable->BootServices->HandleProtocol(handles[i],
&bioGuid, (void**)&bio);
+ if (handles[i] == PublicBootHandle)
+ {
+ OffsetToBoot = i; /* Drive offset in the handles list */
+ }
+
+ if (EFI_ERROR(Status) ||
+ bio == NULL ||
+ bio->Media->BlockSize == 0 ||
+ bio->Media->BlockSize > 2048)
+ {
+ TRACE("UefiSetupBlockDevices: UEFI has found a block device that failed,
skipping\n");
+ continue;
+ }
+ if (bio->Media->LogicalPartition == FALSE)
+ {
+ TRACE("Found root of a HDD\n");
+ PcBiosDiskCount++;
+ InternalUefiDisk[BlockDeviceIndex].ArcDriveNumber = BlockDeviceIndex;
+ InternalUefiDisk[BlockDeviceIndex].UefiRootNumber = i;
+ GetHarddiskInformation(BlockDeviceIndex + FIRST_BIOS_DISK);
+ BlockDeviceIndex++;
+ }
+ else if (handles[i] == PublicBootHandle)
+ {
+ ULONG increment = 0;
+ ULONG i;
+
+ /* 3) Grab the offset into the array of handles and decrement per volume
(valid partition) */
+ for (increment = OffsetToBoot; increment > 0; increment--)
+ {
+ GlobalSystemTable->BootServices->HandleProtocol(handles[increment],
&bioGuid, (void**)&bio);
+ if (bio->Media->LogicalPartition == FALSE)
+ {
+ TRACE("Found root at increment %u\n", increment);
+ UefiBootRootIdentifier = increment;
+
+ for (i = 0; i <= PcBiosDiskCount; ++i)
+ {
+ /* Now only of the root drive number is equal to this drive we
found above */
+ if (InternalUefiDisk[i].UefiRootNumber ==
UefiBootRootIdentifier)
+ {
+ InternalUefiDisk[i].IsThisTheBootDrive == TRUE;
+ PublicBootArcDisk = i;
+ TRACE("Found Boot drive\n");
+ }
+ }
+
+ break;
+ }
+ }
+ }
+ }
+}
+
+static
+BOOLEAN
+UefiSetBootpath(VOID)
+{
+ TRACE("UefiSetBootpath: Setting up boot path\n");
+ GlobalSystemTable->BootServices->HandleProtocol(handles[UefiBootRootIdentifier],
&bioGuid, (void**)&bio);
+ FrldrBootDrive = (FIRST_BIOS_DISK + PublicBootArcDisk);
+ if (bio->Media->RemovableMedia == TRUE && bio->Media->BlockSize ==
2048)
+ {
+ /* Boot Partition 0xFF is the magic value that indicates booting from CD-ROM (see
isoboot.S) */
+ FrldrBootPartition == 0xFF;
+ RtlStringCbPrintfA(FrLdrBootPath, sizeof(FrLdrBootPath),
+ "multi(0)disk(0)cdrom(%u)", PublicBootArcDisk);
+ }
+ else
+ {
+ ULONG BootPartition;
+ PARTITION_TABLE_ENTRY PartitionEntry;
+
+ /* This is a hard disk */
+ if (!UefiGetBootPartitionEntry(FrldrBootDrive, &PartitionEntry,
&BootPartition))
+ {
+ ERR("Failed to get boot partition entry\n");
+ return FALSE;
+ }
+
+ RtlStringCbPrintfA(FrLdrBootPath, sizeof(FrLdrBootPath),
+ "multi(0)disk(0)rdisk(%u)partition(%lu)",
+ PublicBootArcDisk, BootPartition);
+ }
+
+ return TRUE;
+}
+
+BOOLEAN
+UefiInitializeBootDevices(VOID)
+{
+ ULONG i = 0;
+
+ DiskReadBufferSize = EFI_PAGE_SIZE;
+ DiskReadBuffer = MmAllocateMemoryWithType(DiskReadBufferSize,
LoaderFirmwareTemporary);
+ UefiSetupBlockDevices();
+ UefiSetBootpath();
+
+ /* Add it, if it's a cdrom */
+
GlobalSystemTable->BootServices->HandleProtocol(handles[UefiBootRootIdentifier],
&bioGuid, (void**)&bio);
+ if (bio->Media->RemovableMedia == TRUE && bio->Media->BlockSize
== 2048)
+ {
+ PMASTER_BOOT_RECORD Mbr;
+ PULONG Buffer;
+ ULONG Checksum = 0;
+ ULONG Signature;
+
+ /* Read the MBR */
+ if (!MachDiskReadLogicalSectors(FrldrBootDrive, 16ULL, 1, DiskReadBuffer))
+ {
+ ERR("Reading MBR failed\n");
+ return FALSE;
+ }
+
+ Buffer = (ULONG*)DiskReadBuffer;
+ Mbr = (PMASTER_BOOT_RECORD)DiskReadBuffer;
+
+ Signature = Mbr->Signature;
+ TRACE("Signature: %x\n", Signature);
+
+ /* Calculate the MBR checksum */
+ for (i = 0; i < 2048 / sizeof(ULONG); i++)
+ {
+ Checksum += Buffer[i];
+ }
+ Checksum = ~Checksum + 1;
+ TRACE("Checksum: %x\n", Checksum);
+
+ /* Fill out the ARC disk block */
+ AddReactOSArcDiskInfo(FrLdrBootPath, Signature, Checksum, TRUE);
+
+ FsRegisterDevice(FrLdrBootPath, &UefiDiskVtbl);
+ PcBiosDiskCount++; // This is not accounted for in the number of pre-enumerated
BIOS drives!
+ TRACE("Additional boot drive detected: 0x%02X\n",
(int)FrldrBootDrive);
+ }
+ return TRUE;
+}
+
+UCHAR
+UefiGetFloppyCount(VOID)
+{
+ /* No floppy for you for now... */
+ return 0;
+}
+
+BOOLEAN
+UefiDiskReadLogicalSectors(
+ IN UCHAR DriveNumber,
+ IN ULONGLONG SectorNumber,
+ IN ULONG SectorCount,
+ OUT PVOID Buffer)
+{
+ ULONG UefiDriveNumber;
+
+ UefiDriveNumber = InternalUefiDisk[DriveNumber - FIRST_BIOS_DISK].UefiRootNumber;
+ TRACE("UefiDiskReadLogicalSectors: DriveNumber: %d\n", UefiDriveNumber);
+ GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber],
&bioGuid, (void**)&bio);
+
+ /* Devices setup */
+ bio->ReadBlocks(bio, bio->Media->MediaId, SectorNumber, SectorCount *
bio->Media->BlockSize, Buffer);
+ return TRUE;
+}
+
+BOOLEAN
+UefiDiskGetDriveGeometry(UCHAR DriveNumber, PGEOMETRY Geometry)
+{
+ ULONG UefiDriveNumber;
+
+ UefiDriveNumber = InternalUefiDisk[DriveNumber - FIRST_BIOS_DISK].UefiRootNumber;
+ GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber],
&bioGuid, (void**)&bio);
+ Geometry->Cylinders = 1; // Not relevant for the UEFI BIO protocol
+ Geometry->Heads = 1; // Not relevant for the UEFI BIO protocol
+ Geometry->Sectors = bio->Media->LastBlock; // Number of sectors per
track
+ Geometry->BytesPerSector = bio->Media->BlockSize; // Number of bytes per
sector
+
+ return TRUE;
+}
+
+ULONG
+UefiDiskGetCacheableBlockCount(UCHAR DriveNumber)
+{
+ ULONG UefiDriveNumber = InternalUefiDisk[DriveNumber -
FIRST_BIOS_DISK].UefiRootNumber;
+ TRACE("UefiDiskGetCacheableBlockCount: DriveNumber: %d\n",
UefiDriveNumber);
+
+ GlobalSystemTable->BootServices->HandleProtocol(handles[UefiDriveNumber],
&bioGuid, (void**)&bio);
+ return bio->Media->LastBlock;
+}
diff --git a/boot/freeldr/freeldr/uefi.cmake b/boot/freeldr/freeldr/uefi.cmake
index 94b5baa7630..0adb0a25f4b 100644
--- a/boot/freeldr/freeldr/uefi.cmake
+++ b/boot/freeldr/freeldr/uefi.cmake
@@ -14,11 +14,12 @@ include_directories(BEFORE
list(APPEND UEFILDR_ARC_SOURCE
${FREELDR_ARC_SOURCE}
arch/uefi/stubs.c
- arch/uefi/uefisetup.c
- arch/uefi/uefivid.c
- arch/uefi/uefiutil.c
arch/uefi/ueficon.c
+ arch/uefi/uefidisk.c
arch/uefi/uefimem.c
+ arch/uefi/uefisetup.c
+ arch/uefi/uefiutil.c
+ arch/uefi/uefivid.c
arch/vgafont.c)
if(ARCH STREQUAL "i386")