https://git.reactos.org/?p=reactos.git;a=commitdiff;h=150f7212736bfb5da500cbafa58c0671d0cc8122

commit 150f7212736bfb5da500cbafa58c0671d0cc8122
Author:     Justin Miller <[email protected]>
AuthorDate: Sun Mar 19 12:13:16 2023 -0700
Commit:     GitHub <[email protected]>
CommitDate: Sun Mar 19 20:13:16 2023 +0100

    [FREELDR] Support compiling freeldr as a UEFI loader + Implement UI 
functions (#5171)
    
    First batch of changes to implement a UEFI version of freeldr:
    - Compile freeldr as EFI binary on top of the existing loader.
    - Stub out various functions so we can create a UEFI machine-type in 
freeldr.
    - Implement all of the video output functions so we can display a pretty 
freeldr BSoD :)
---
 boot/boot_images.cmake                            |  14 +-
 boot/freeldr/freeldr/CMakeLists.txt               |   3 +
 boot/freeldr/freeldr/arch/uefi/stubs.c            | 125 +++++++++++
 boot/freeldr/freeldr/arch/uefi/ueficon.c          |  61 ++++++
 boot/freeldr/freeldr/arch/uefi/uefildr.c          |  37 ++++
 boot/freeldr/freeldr/arch/uefi/uefisetup.c        |  60 ++++++
 boot/freeldr/freeldr/arch/uefi/uefiutil.c         |  38 ++++
 boot/freeldr/freeldr/arch/uefi/uefivid.c          | 240 ++++++++++++++++++++++
 boot/freeldr/freeldr/bootmgr.c                    |   6 +
 boot/freeldr/freeldr/freeldr.c                    |   2 +
 boot/freeldr/freeldr/include/arch/uefi/machuefi.h | 122 +++++++++++
 boot/freeldr/freeldr/include/arch/uefi/uefildr.h  |  36 ++++
 boot/freeldr/freeldr/lib/fs/fs.c                  |   4 +-
 boot/freeldr/freeldr/miscboot.c                   |   2 +
 boot/freeldr/freeldr/uefi.cmake                   | 122 +++++++++++
 15 files changed, 867 insertions(+), 5 deletions(-)

diff --git a/boot/boot_images.cmake b/boot/boot_images.cmake
index c0c9a957672..6ceb37fee73 100644
--- a/boot/boot_images.cmake
+++ b/boot/boot_images.cmake
@@ -15,11 +15,9 @@ else()
     message(FATAL_ERROR "Unknown ARCH '" ${ARCH} "', cannot generate a valid 
UEFI boot filename.")
 endif()
 
-# FIXME: this command creates a dummy EFI partition, add 
EFI/BOOT/boot${EFI_PLATFORM_ID}.efi file
-# once ReactOS supports UEFI
 add_custom_target(efisys
-    COMMAND native-fatten ${CMAKE_CURRENT_BINARY_DIR}/efisys.bin -format 2880 
EFIBOOT -boot ${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/fat.bin -mkdir EFI 
-mkdir EFI/BOOT
-    DEPENDS native-fatten fat
+    COMMAND native-fatten ${CMAKE_CURRENT_BINARY_DIR}/efisys.bin -format 2880 
EFIBOOT -boot ${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/fat.bin -mkdir EFI 
-mkdir EFI/BOOT -add $<TARGET_FILE:uefildr> EFI/BOOT/boot${EFI_PLATFORM_ID}.efi
+    DEPENDS native-fatten fat uefildr
     VERBATIM)
 
 
@@ -162,4 +160,12 @@ add_custom_target(hybridcd
     DEPENDS bootcd livecd
     VERBATIM)
 
+# For things like flashing USB drives, we also add the efi file into efi/boot.
 add_cd_file(TARGET efisys FILE ${CMAKE_CURRENT_BINARY_DIR}/efisys.bin 
DESTINATION loader NO_CAB NOT_IN_HYBRIDCD FOR bootcd regtest livecd hybridcd)
+
+add_cd_file(
+    TARGET uefildr
+    DESTINATION efi/boot
+    NO_CAB
+    NAME_ON_CD boot${EFI_PLATFORM_ID}.efi
+    FOR livecd hybridcd)
diff --git a/boot/freeldr/freeldr/CMakeLists.txt 
b/boot/freeldr/freeldr/CMakeLists.txt
index 740a0a5192c..22b58246ea8 100644
--- a/boot/freeldr/freeldr/CMakeLists.txt
+++ b/boot/freeldr/freeldr/CMakeLists.txt
@@ -135,3 +135,6 @@ if(ARCH STREQUAL "i386")
 endif()
 
 include(pcat.cmake)
+if(NOT ARCH STREQUAL "i386" OR NOT (SARCH STREQUAL "pc98" OR SARCH STREQUAL 
"xbox"))
+    include(uefi.cmake)
+endif()
diff --git a/boot/freeldr/freeldr/arch/uefi/stubs.c 
b/boot/freeldr/freeldr/arch/uefi/stubs.c
new file mode 100644
index 00000000000..b3d574fb00f
--- /dev/null
+++ b/boot/freeldr/freeldr/arch/uefi/stubs.c
@@ -0,0 +1,125 @@
+/*
+ * PROJECT:     Freeldr UEFI Extension
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     UEFI stubs
+ * COPYRIGHT:   Copyright 2022 Justin Miller <[email protected]>
+ */
+
+#include <uefildr.h>
+
+#include <debug.h>
+
+/* TODO: Handle this with custom Disk / partition setup */
+UCHAR
+DriveMapGetBiosDriveNumber(PCSTR DeviceName)
+{
+    return 0;
+}
+
+VOID
+StallExecutionProcessor(ULONG Microseconds)
+{
+
+}
+
+VOID
+NTAPI
+KeStallExecutionProcessor(ULONG Microseconds)
+{
+    StallExecutionProcessor(Microseconds);
+}
+
+VOID
+UefiVideoGetFontsFromFirmware(PULONG RomFontPointers)
+{
+
+}
+
+VOID
+UefiVideoSync(VOID)
+{
+
+}
+
+PFREELDR_MEMORY_DESCRIPTOR
+UefiMemGetMemoryMap(ULONG *MemoryMapSize)
+{
+    return 0;
+}
+
+VOID
+UefiGetExtendedBIOSData(PULONG ExtendedBIOSDataArea,
+                        PULONG ExtendedBIOSDataSize)
+{
+
+}
+
+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)
+{
+    return 0;
+}
+
+VOID
+UefiPrepareForReactOS(VOID)
+{
+
+}
+
+VOID
+UefiPcBeep(VOID)
+{
+    /* Not possible on UEFI, for now */
+}
+
+BOOLEAN
+UefiConsKbHit(VOID)
+{
+    return FALSE;
+}
+
+int
+UefiConsGetCh(void)
+{
+    return 0;
+}
+
+VOID
+UefiHwIdle(VOID)
+{
+
+}
diff --git a/boot/freeldr/freeldr/arch/uefi/ueficon.c 
b/boot/freeldr/freeldr/arch/uefi/ueficon.c
new file mode 100644
index 00000000000..78c67d9c6e8
--- /dev/null
+++ b/boot/freeldr/freeldr/arch/uefi/ueficon.c
@@ -0,0 +1,61 @@
+/*
+ * PROJECT:     Freeldr UEFI Extension
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     UEFI Console output
+ * COPYRIGHT:   Copyright 2022 Justin Miller <[email protected]>
+ */
+
+#include <uefildr.h>
+
+#define CHAR_WIDTH  8
+#define CHAR_HEIGHT 16
+
+/* GLOBALS 
********************************************************************/
+
+extern EFI_SYSTEM_TABLE* GlobalSystemTable;
+static unsigned CurrentCursorX = 0;
+static unsigned CurrentCursorY = 0;
+static unsigned CurrentAttr = 0x0f;
+
+/* FUNCTIONS 
******************************************************************/
+
+VOID
+UefiConsPutChar(int c)
+{
+    ULONG Width, Height, Unused;
+    BOOLEAN NeedScroll;
+
+    UefiVideoGetDisplaySize(&Width, &Height, &Unused);
+
+    NeedScroll = (CurrentCursorY >= Height);
+    if (NeedScroll)
+    {
+        UefiVideoScrollUp();
+        --CurrentCursorY;
+    }
+    if (c == '\r')
+    {
+        CurrentCursorX = 0;
+    }
+    else if (c == '\n')
+    {
+        CurrentCursorX = 0;
+
+        if (!NeedScroll)
+            ++CurrentCursorY;
+    }
+    else if (c == '\t')
+    {
+        CurrentCursorX = (CurrentCursorX + 8) & ~7;
+    }
+    else
+    {
+        UefiVideoPutChar(c, CurrentAttr, CurrentCursorX, CurrentCursorY);
+        CurrentCursorX++;
+    }
+    if (CurrentCursorX >= Width)
+    {
+        CurrentCursorX = 0;
+        CurrentCursorY++;
+    }
+}
diff --git a/boot/freeldr/freeldr/arch/uefi/uefildr.c 
b/boot/freeldr/freeldr/arch/uefi/uefildr.c
new file mode 100644
index 00000000000..e06ff9a1c5b
--- /dev/null
+++ b/boot/freeldr/freeldr/arch/uefi/uefildr.c
@@ -0,0 +1,37 @@
+/*
+ * PROJECT:     Freeldr UEFI Extension
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     UEFI Entry point and helpers
+ * COPYRIGHT:   Copyright 2022 Justin Miller <[email protected]>
+ */
+
+#include <uefildr.h>
+
+#include <debug.h>
+
+/* GLOBALS 
********************************************************************/
+
+EFI_HANDLE GlobalImageHandle;
+EFI_SYSTEM_TABLE *GlobalSystemTable;
+
+/* FUNCTIONS 
******************************************************************/
+
+EFI_STATUS
+EfiEntry(
+    _In_ EFI_HANDLE ImageHandle,
+    _In_ EFI_SYSTEM_TABLE *SystemTable)
+{
+    SystemTable->ConOut->OutputString(SystemTable->ConOut, L"UEFI EntryPoint: 
Starting freeldr from UEFI");
+    GlobalImageHandle = ImageHandle;
+    GlobalSystemTable = SystemTable;
+
+    BootMain(NULL);
+
+    UNREACHABLE;
+    return 0;
+}
+
+VOID __cdecl Reboot(VOID)
+{
+
+}
diff --git a/boot/freeldr/freeldr/arch/uefi/uefisetup.c 
b/boot/freeldr/freeldr/arch/uefi/uefisetup.c
new file mode 100644
index 00000000000..bd223da465f
--- /dev/null
+++ b/boot/freeldr/freeldr/arch/uefi/uefisetup.c
@@ -0,0 +1,60 @@
+/*
+ * PROJECT:     Freeldr UEFI Extension
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     UEFI Mach Setup
+ * COPYRIGHT:   Copyright 2022 Justin Miller <[email protected]>
+ */
+
+#include <uefildr.h>
+
+#include <debug.h>
+DBG_DEFAULT_CHANNEL(WARNING);
+
+/* GLOBALS 
********************************************************************/
+
+extern EFI_SYSTEM_TABLE* GlobalSystemTable;
+extern EFI_HANDLE GlobalImageHandle;
+BOOLEAN AcpiPresent = FALSE;
+
+/* FUNCTIONS 
******************************************************************/
+
+VOID
+MachInit(const char *CmdLine)
+{
+    RtlZeroMemory(&MachVtbl, sizeof(MachVtbl));
+
+    MachVtbl.ConsPutChar = UefiConsPutChar;
+    MachVtbl.ConsKbHit = UefiConsKbHit;
+    MachVtbl.ConsGetCh = UefiConsGetCh;
+    MachVtbl.VideoClearScreen = UefiVideoClearScreen;
+    MachVtbl.VideoSetDisplayMode = UefiVideoSetDisplayMode;
+    MachVtbl.VideoGetDisplaySize = UefiVideoGetDisplaySize;
+    MachVtbl.VideoGetBufferSize = UefiVideoGetBufferSize;
+    MachVtbl.VideoGetFontsFromFirmware = UefiVideoGetFontsFromFirmware;
+    MachVtbl.VideoSetTextCursorPosition = UefiVideoSetTextCursorPosition;
+    MachVtbl.VideoHideShowTextCursor = UefiVideoHideShowTextCursor;
+    MachVtbl.VideoPutChar = UefiVideoPutChar;
+    MachVtbl.VideoCopyOffScreenBufferToVRAM = 
UefiVideoCopyOffScreenBufferToVRAM;
+    MachVtbl.VideoIsPaletteFixed = UefiVideoIsPaletteFixed;
+    MachVtbl.VideoSetPaletteColor = UefiVideoSetPaletteColor;
+    MachVtbl.VideoGetPaletteColor = UefiVideoGetPaletteColor;
+    MachVtbl.VideoSync = UefiVideoSync;
+    MachVtbl.Beep = UefiPcBeep;
+    MachVtbl.PrepareForReactOS = UefiPrepareForReactOS;
+    MachVtbl.GetMemoryMap = UefiMemGetMemoryMap;
+    MachVtbl.GetExtendedBIOSData = UefiGetExtendedBIOSData;
+    MachVtbl.GetFloppyCount = UefiGetFloppyCount;
+    MachVtbl.DiskReadLogicalSectors = UefiDiskReadLogicalSectors;
+    MachVtbl.DiskGetDriveGeometry = UefiDiskGetDriveGeometry;
+    MachVtbl.DiskGetCacheableBlockCount = UefiDiskGetCacheableBlockCount;
+    MachVtbl.GetTime = UefiGetTime;
+    MachVtbl.InitializeBootDevices = UefiInitializeBootDevices;
+    MachVtbl.HwDetect = UefiHwDetect;
+    MachVtbl.HwIdle = UefiHwIdle;
+
+    /* Setup GOP */
+    if (UefiInitalizeVideo() != EFI_SUCCESS)
+    {
+        ERR("Failed to setup GOP\n");
+    }
+}
diff --git a/boot/freeldr/freeldr/arch/uefi/uefiutil.c 
b/boot/freeldr/freeldr/arch/uefi/uefiutil.c
new file mode 100644
index 00000000000..9dafea22b6c
--- /dev/null
+++ b/boot/freeldr/freeldr/arch/uefi/uefiutil.c
@@ -0,0 +1,38 @@
+/*
+ * PROJECT:     Freeldr UEFI Extension
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     UEFI Utils source
+ * COPYRIGHT:   Copyright 2022 Justin Miller <[email protected]>
+ */
+
+#include <uefildr.h>
+
+#include <debug.h>
+DBG_DEFAULT_CHANNEL(WARNING);
+
+/* GLOBALS 
********************************************************************/
+
+extern EFI_SYSTEM_TABLE *GlobalSystemTable;
+
+/* FUNCTIONS 
******************************************************************/
+
+TIMEINFO*
+UefiGetTime(VOID)
+{
+    static TIMEINFO TimeInfo;
+    EFI_STATUS Status;
+    EFI_TIME time = {0};
+
+    Status = GlobalSystemTable->RuntimeServices->GetTime(&time, NULL);
+    if (Status != EFI_SUCCESS)
+        ERR("UefiGetTime: cannot get time status %d\n", Status);
+
+    TimeInfo.Year = time.Year;
+    TimeInfo.Month = time.Month;
+    TimeInfo.Day = time.Day;
+    TimeInfo.Hour = time.Hour;
+    TimeInfo.Minute = time.Minute;
+    TimeInfo.Second = time.Second;
+    return &TimeInfo;
+}
+
diff --git a/boot/freeldr/freeldr/arch/uefi/uefivid.c 
b/boot/freeldr/freeldr/arch/uefi/uefivid.c
new file mode 100644
index 00000000000..5bd869fcfd4
--- /dev/null
+++ b/boot/freeldr/freeldr/arch/uefi/uefivid.c
@@ -0,0 +1,240 @@
+/*
+ * PROJECT:     Freeldr UEFI Extension
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     UEFI Video output
+ * COPYRIGHT:   Copyright 2022 Justin Miller <[email protected]>
+ */
+
+#include <uefildr.h>
+
+#include <debug.h>
+DBG_DEFAULT_CHANNEL(WARNING);
+
+#define CHAR_WIDTH  8
+#define CHAR_HEIGHT 16
+#define TOP_BOTTOM_LINES 0
+#define LOWEST_SUPPORTED_RES 1
+
+/* GLOBALS 
********************************************************************/
+
+extern EFI_SYSTEM_TABLE* GlobalSystemTable;
+extern EFI_HANDLE GlobalImageHandle;
+extern UCHAR BitmapFont8x16[256 * 16];
+
+UCHAR MachDefaultTextColor = COLOR_GRAY;
+REACTOS_INTERNAL_BGCONTEXT framebufferData;
+EFI_GUID EfiGraphicsOutputProtocol = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+
+/* FUNCTIONS 
******************************************************************/
+
+EFI_STATUS
+UefiInitalizeVideo(VOID)
+{
+    EFI_STATUS Status;
+    EFI_GRAPHICS_OUTPUT_PROTOCOL* gop = NULL;
+
+    RtlZeroMemory(&framebufferData, sizeof(framebufferData));
+    Status = 
GlobalSystemTable->BootServices->LocateProtocol(&EfiGraphicsOutputProtocol, 0, 
(void**)&gop);
+    if (Status != EFI_SUCCESS)
+    {
+        TRACE("Failed to find GOP with status %d\n", Status);
+        return Status;
+    }
+
+    /* We don't need high resolutions for freeldr */
+    gop->SetMode(gop, LOWEST_SUPPORTED_RES);
+
+    framebufferData.BaseAddress        = (ULONG_PTR)gop->Mode->FrameBufferBase;
+    framebufferData.BufferSize         = gop->Mode->FrameBufferSize;
+    framebufferData.ScreenWidth        = gop->Mode->Info->HorizontalResolution;
+    framebufferData.ScreenHeight       = gop->Mode->Info->VerticalResolution;
+    framebufferData.PixelsPerScanLine  = gop->Mode->Info->PixelsPerScanLine;
+    framebufferData.PixelFormat        = gop->Mode->Info->PixelFormat;
+
+    return Status;
+}
+
+VOID
+UefiPrintFramebufferData(VOID)
+{
+    TRACE("Framebuffer BaseAddress       : %X\n", framebufferData.BaseAddress);
+    TRACE("Framebuffer BufferSize        : %X\n", framebufferData.BufferSize);
+    TRACE("Framebuffer ScreenWidth       : %d\n", framebufferData.ScreenWidth);
+    TRACE("Framebuffer ScreenHeight      : %d\n", 
framebufferData.ScreenHeight);
+    TRACE("Framebuffer PixelsPerScanLine : %d\n", 
framebufferData.PixelsPerScanLine);
+    TRACE("Framebuffer PixelFormat       : %d\n", framebufferData.PixelFormat);
+}
+
+static ULONG
+UefiVideoAttrToSingleColor(UCHAR Attr)
+{
+    UCHAR Intensity;
+    Intensity = (0 == (Attr & 0x08) ? 127 : 255);
+
+    return 0xff000000 |
+           (0 == (Attr & 0x04) ? 0 : (Intensity << 16)) |
+           (0 == (Attr & 0x02) ? 0 : (Intensity << 8)) |
+           (0 == (Attr & 0x01) ? 0 : Intensity);
+}
+
+static VOID
+UefiVideoAttrToColors(UCHAR Attr, ULONG *FgColor, ULONG *BgColor)
+{
+    *FgColor = UefiVideoAttrToSingleColor(Attr & 0xf);
+    *BgColor = UefiVideoAttrToSingleColor((Attr >> 4) & 0xf);
+}
+
+
+static VOID
+UefiVideoClearScreenColor(ULONG Color, BOOLEAN FullScreen)
+{
+    ULONG Delta;
+    ULONG Line, Col;
+    PULONG p;
+
+    Delta = (framebufferData.PixelsPerScanLine * 4 + 3) & ~ 0x3;
+    for (Line = 0; Line < framebufferData.ScreenHeight - (FullScreen ? 0 : 2 * 
TOP_BOTTOM_LINES); Line++)
+    {
+        p = (PULONG) ((char *) framebufferData.BaseAddress + (Line + 
(FullScreen ? 0 : TOP_BOTTOM_LINES)) * Delta);
+        for (Col = 0; Col < framebufferData.ScreenWidth; Col++)
+        {
+            *p++ = Color;
+        }
+    }
+}
+
+VOID
+UefiVideoClearScreen(UCHAR Attr)
+{
+    ULONG FgColor, BgColor;
+
+    UefiVideoAttrToColors(Attr, &FgColor, &BgColor);
+    UefiVideoClearScreenColor(BgColor, FALSE);
+}
+
+VOID
+UefiVideoOutputChar(UCHAR Char, unsigned X, unsigned Y, ULONG FgColor, ULONG 
BgColor)
+{
+    PUCHAR FontPtr;
+    PULONG Pixel;
+    UCHAR Mask;
+    unsigned Line;
+    unsigned Col;
+    ULONG Delta;
+    Delta = (framebufferData.PixelsPerScanLine * 4 + 3) & ~ 0x3;
+    FontPtr = BitmapFont8x16 + Char * 16;
+    Pixel = (PULONG) ((char *) framebufferData.BaseAddress +
+            (Y * CHAR_HEIGHT + TOP_BOTTOM_LINES) *  Delta + X * CHAR_WIDTH * 
4);
+
+    for (Line = 0; Line < CHAR_HEIGHT; Line++)
+    {
+        Mask = 0x80;
+        for (Col = 0; Col < CHAR_WIDTH; Col++)
+        {
+            Pixel[Col] = (0 != (FontPtr[Line] & Mask) ? FgColor : BgColor);
+            Mask = Mask >> 1;
+        }
+        Pixel = (PULONG) ((char *) Pixel + Delta);
+    }
+}
+
+VOID
+UefiVideoPutChar(int Ch, UCHAR Attr, unsigned X, unsigned Y)
+{
+    ULONG FgColor = 0;
+    ULONG BgColor = 0;
+    if (Ch != 0)
+    {
+        UefiVideoAttrToColors(Attr, &FgColor, &BgColor);
+        UefiVideoOutputChar(Ch, X, Y, FgColor, BgColor);
+    }
+}
+
+VOID
+UefiVideoGetDisplaySize(PULONG Width, PULONG Height, PULONG Depth)
+{
+    *Width =  framebufferData.ScreenWidth / CHAR_WIDTH;
+    *Height = (framebufferData.ScreenHeight - 2 * TOP_BOTTOM_LINES) / 
CHAR_HEIGHT;
+    *Depth =  0;
+}
+
+VIDEODISPLAYMODE
+UefiVideoSetDisplayMode(char *DisplayMode, BOOLEAN Init)
+{
+    /* We only have one mode, semi-text */
+    return VideoTextMode;
+}
+
+ULONG
+UefiVideoGetBufferSize(VOID)
+{
+    return ((framebufferData.ScreenHeight - 2 * TOP_BOTTOM_LINES) / 
CHAR_HEIGHT * (framebufferData.ScreenWidth / CHAR_WIDTH) * 2);
+}
+
+VOID
+UefiVideoCopyOffScreenBufferToVRAM(PVOID Buffer)
+{
+    PUCHAR OffScreenBuffer = (PUCHAR)Buffer;
+
+    ULONG Col, Line;
+    for (Line = 0; Line < (framebufferData.ScreenHeight - 2 * 
TOP_BOTTOM_LINES) / CHAR_HEIGHT; Line++)
+    {
+        for (Col = 0; Col < framebufferData.ScreenWidth / CHAR_WIDTH; Col++)
+        {
+            UefiVideoPutChar(OffScreenBuffer[0], OffScreenBuffer[1], Col, 
Line);
+            OffScreenBuffer += 2;
+        }
+    }
+}
+
+VOID
+UefiVideoScrollUp(VOID)
+{
+    ULONG BgColor, Dummy;
+    ULONG Delta;
+    Delta = (framebufferData.PixelsPerScanLine * 4 + 3) & ~ 0x3;
+    ULONG PixelCount = framebufferData.ScreenWidth * CHAR_HEIGHT *
+                       (((framebufferData.ScreenHeight - 2 * TOP_BOTTOM_LINES) 
/ CHAR_HEIGHT) - 1);
+    PULONG Src = (PULONG)((PUCHAR)framebufferData.BaseAddress + (CHAR_HEIGHT + 
TOP_BOTTOM_LINES) * Delta);
+    PULONG Dst = (PULONG)((PUCHAR)framebufferData.BaseAddress + 
TOP_BOTTOM_LINES * Delta);
+
+    UefiVideoAttrToColors(ATTR(COLOR_WHITE, COLOR_BLACK), &Dummy, &BgColor);
+
+    while (PixelCount--)
+        *Dst++ = *Src++;
+
+    for (PixelCount = 0; PixelCount < framebufferData.ScreenWidth * 
CHAR_HEIGHT; PixelCount++)
+        *Dst++ = BgColor;
+}
+
+VOID
+UefiVideoSetTextCursorPosition(UCHAR X, UCHAR Y)
+{
+    /* We don't have a cursor yet */
+}
+
+VOID
+UefiVideoHideShowTextCursor(BOOLEAN Show)
+{
+    /* We don't have a cursor yet */
+}
+
+BOOLEAN
+UefiVideoIsPaletteFixed(VOID)
+{
+    return 0;
+}
+
+VOID
+UefiVideoSetPaletteColor(UCHAR Color, UCHAR Red,
+                         UCHAR Green, UCHAR Blue)
+{
+    /* Not supported */
+}
+
+VOID
+UefiVideoGetPaletteColor(UCHAR Color, UCHAR* Red,
+                         UCHAR* Green, UCHAR* Blue)
+{
+    /* Not supported */
+}
diff --git a/boot/freeldr/freeldr/bootmgr.c b/boot/freeldr/freeldr/bootmgr.c
index c866502a6aa..2c837951fec 100644
--- a/boot/freeldr/freeldr/bootmgr.c
+++ b/boot/freeldr/freeldr/bootmgr.c
@@ -55,11 +55,13 @@ static const struct
     {"ReactOSSetup", EditCustomBootReactOSSetup, LoadReactOSSetup},
 
 #if defined(_M_IX86) || defined(_M_AMD64)
+#ifndef UEFIBOOT
     {"Drive"       , EditCustomBootDisk      , LoadAndBootDevice},
     {"Partition"   , EditCustomBootPartition , LoadAndBootDevice},
     {"BootSector"  , EditCustomBootSectorFile, LoadAndBootDevice},
     {"Linux"       , EditCustomBootLinux, LoadAndBootLinux  },
 #endif
+#endif
 #ifdef _M_IX86
     {"WindowsNT40" , EditCustomBootNTOS , LoadAndBootWindows},
 #endif
@@ -194,8 +196,10 @@ VOID LoadOperatingSystem(IN OperatingSystemItem* 
OperatingSystem)
     ASSERT(*BootType);
 
 #ifdef _M_IX86
+#ifndef UEFIBOOT
     /* Install the drive mapper according to this section drive mappings */
     DriveMapMapDrivesInSection(SectionId);
+#endif
 #endif
 
     /* Find the suitable OS loader to start */
@@ -314,11 +318,13 @@ VOID RunLoader(VOID)
     }
 
 #ifdef _M_IX86
+#ifndef UEFIBOOT
     /* Load additional SCSI driver (if any) */
     if (LoadBootDeviceDriver() != ESUCCESS)
     {
         UiMessageBoxCritical("Unable to load additional boot device drivers.");
     }
+#endif
 #endif
 
     if (!IniFileInitialize())
diff --git a/boot/freeldr/freeldr/freeldr.c b/boot/freeldr/freeldr/freeldr.c
index 16af2375097..da9f8964fdb 100644
--- a/boot/freeldr/freeldr/freeldr.c
+++ b/boot/freeldr/freeldr/freeldr.c
@@ -51,8 +51,10 @@ VOID __cdecl BootMain(IN PCCH CmdLine)
 
     TRACE("BootMain() called.\n");
 
+#ifndef UEFIBOOT
     /* Check if the CPU is new enough */
     FrLdrCheckCpuCompatibility(); // FIXME: Should be done inside MachInit!
+#endif
 
     /* UI pre-initialization */
     if (!UiInitialize(FALSE))
diff --git a/boot/freeldr/freeldr/include/arch/uefi/machuefi.h 
b/boot/freeldr/freeldr/include/arch/uefi/machuefi.h
new file mode 100644
index 00000000000..ba878e30972
--- /dev/null
+++ b/boot/freeldr/freeldr/include/arch/uefi/machuefi.h
@@ -0,0 +1,122 @@
+/*
+ * PROJECT:     Freeldr UEFI Extension
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     UEFI "mach" header
+ * COPYRIGHT:   Copyright 2022 Justin Miller <[email protected]>
+ */
+
+#include <machine.h>
+
+EFI_STATUS
+UefiMachInit(_In_ EFI_HANDLE ImageHandle,
+             _In_ EFI_SYSTEM_TABLE *SystemTable);
+
+VOID
+UefiConsPutChar(int Ch);
+
+BOOLEAN
+UefiConsKbHit(VOID);
+
+VOID
+UefiConsSetCursor(UINT32 Col, UINT32 Row);
+
+int
+UefiConsGetCh(void);
+
+EFI_STATUS
+UefiInitalizeVideo(VOID);
+
+VOID
+UefiVideoClearScreen(UCHAR Attr);
+
+VIDEODISPLAYMODE
+UefiVideoSetDisplayMode(char *DisplayMode, BOOLEAN Init);
+
+VOID
+UefiVideoGetDisplaySize(PULONG Width, PULONG Height, PULONG Depth);
+
+ULONG
+UefiVideoGetBufferSize(VOID);
+
+VOID
+UefiVideoGetFontsFromFirmware(PULONG RomFontPointers);
+
+VOID
+UefiVideoSetTextCursorPosition(UCHAR X, UCHAR Y);
+
+VOID
+UefiVideoHideShowTextCursor(BOOLEAN Show);
+
+VOID
+UefiVideoOutputChar(UCHAR Char, unsigned X,
+                    unsigned Y, ULONG FgColor, ULONG BgColor);
+
+VOID
+UefiVideoPutChar(int Ch, UCHAR Attr,
+                 unsigned X, unsigned Y);
+
+
+VOID
+UefiVideoCopyOffScreenBufferToVRAM(PVOID Buffer);
+
+BOOLEAN
+UefiVideoIsPaletteFixed(VOID);
+
+VOID
+UefiVideoSetPaletteColor(UCHAR Color, UCHAR Red,
+                         UCHAR Green, UCHAR Blue);
+
+VOID
+UefiVideoGetPaletteColor(UCHAR Color, UCHAR* Red,
+                         UCHAR* Green, UCHAR* Blue);
+
+VOID
+UefiVideoSync(VOID);
+
+VOID
+UefiPcBeep(VOID);
+
+PFREELDR_MEMORY_DESCRIPTOR
+UefiMemGetMemoryMap(ULONG *MemoryMapSize);
+
+VOID
+UefiGetExtendedBIOSData(PULONG ExtendedBIOSDataArea,
+                        PULONG ExtendedBIOSDataSize);
+
+UCHAR
+UefiGetFloppyCount(VOID);
+
+BOOLEAN
+UefiDiskReadLogicalSectors(IN UCHAR DriveNumber,
+                           IN ULONGLONG SectorNumber,
+                           IN ULONG SectorCount,
+                           OUT PVOID Buffer);
+
+BOOLEAN
+UefiDiskGetDriveGeometry(UCHAR DriveNumber,
+                         PGEOMETRY Geometry);
+
+ULONG
+UefiDiskGetCacheableBlockCount(UCHAR DriveNumber);
+
+TIMEINFO*
+UefiGetTime(VOID);
+
+BOOLEAN
+UefiInitializeBootDevices(VOID);
+
+PCONFIGURATION_COMPONENT_DATA
+UefiHwDetect(VOID);
+
+VOID
+UefiPrepareForReactOS(VOID);
+
+VOID
+UefiHwIdle(VOID);
+
+VOID
+UefiInitializeFileSystemSupport(_In_ EFI_HANDLE ImageHandle,
+                                _In_ EFI_SYSTEM_TABLE *SystemTable);
+
+VOID
+UefiVideoScrollUp(VOID);
diff --git a/boot/freeldr/freeldr/include/arch/uefi/uefildr.h 
b/boot/freeldr/freeldr/include/arch/uefi/uefildr.h
new file mode 100644
index 00000000000..8074a615289
--- /dev/null
+++ b/boot/freeldr/freeldr/include/arch/uefi/uefildr.h
@@ -0,0 +1,36 @@
+/*
+ * PROJECT:     Freeldr UEFI Extension
+ * LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+ * PURPOSE:     Uefi freeldr core header
+ * COPYRIGHT:   Copyright 2022 Justin Miller <[email protected]>
+ */
+
+#pragma once
+
+/* INCLUDES ******************************************************************/
+#include <freeldr.h>
+
+/* UEFI Headers */
+#include <Uefi.h>
+#include <DevicePath.h>
+#include <LoadedImage.h>
+#include <GraphicsOutput.h>
+#include <UgaDraw.h>
+#include <BlockIo.h>
+#include <Acpi.h>
+#include <GlobalVariable.h>
+#include <debug.h>
+#include <machuefi.h>
+
+//TODO: this version of the struct is temporary
+typedef struct _REACTOS_INTERNAL_BGCONTEXT
+{
+    ULONG_PTR    BaseAddress;
+    ULONG        BufferSize;
+    UINT32       ScreenWidth;
+    UINT32       ScreenHeight;
+    UINT32       PixelsPerScanLine;
+    UINT32       PixelFormat;
+} REACTOS_INTERNAL_BGCONTEXT, *PREACTOS_INTERNAL_BGCONTEXT;
+
+VOID __cdecl BootMain(IN PCCH CmdLine);
diff --git a/boot/freeldr/freeldr/lib/fs/fs.c b/boot/freeldr/freeldr/lib/fs/fs.c
index 92cb3ef0362..3326b1951d6 100644
--- a/boot/freeldr/freeldr/lib/fs/fs.c
+++ b/boot/freeldr/freeldr/lib/fs/fs.c
@@ -1,7 +1,7 @@
 /*
  *  FreeLoader
  *  Copyright (C) 1998-2003  Brian Palmer  <[email protected]>
- *  Copyright (C) 2008-2009  Herv� Poussineau  <[email protected]>
+ *  Copyright (C) 2008-2009  Hervé Poussineau  <[email protected]>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -160,8 +160,10 @@ ARC_STATUS ArcOpen(CHAR* Path, OPENMODE OpenMode, ULONG* 
FileId)
                     FileData[DeviceId].FileFuncTable = Ext2Mount(DeviceId);
 #endif
 #if defined(_M_IX86) || defined(_M_AMD64)
+#ifndef UEFIBOOT
                 if (!FileData[DeviceId].FileFuncTable)
                     FileData[DeviceId].FileFuncTable = PxeMount(DeviceId);
+#endif
 #endif
                 if (!FileData[DeviceId].FileFuncTable)
                 {
diff --git a/boot/freeldr/freeldr/miscboot.c b/boot/freeldr/freeldr/miscboot.c
index 6aca738b773..445cecc9e3f 100644
--- a/boot/freeldr/freeldr/miscboot.c
+++ b/boot/freeldr/freeldr/miscboot.c
@@ -339,8 +339,10 @@ LoadAndBootDevice(
     UiUnInitialize("Booting...");
     IniCleanup();
 
+#ifndef UEFIBOOT
     /* Boot the loaded sector code */
     ChainLoadBiosBootSectorCode(DriveNumber, PartitionNumber);
+#endif
     /* Must not return! */
     return ESUCCESS;
 }
diff --git a/boot/freeldr/freeldr/uefi.cmake b/boot/freeldr/freeldr/uefi.cmake
new file mode 100644
index 00000000000..21710408dfc
--- /dev/null
+++ b/boot/freeldr/freeldr/uefi.cmake
@@ -0,0 +1,122 @@
+##
+## PROJECT:     FreeLoader
+## LICENSE:     GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
+## PURPOSE:     Build definitions for UEFI
+## COPYRIGHT:   Copyright 2023 Justin Miller <[email protected]>
+##
+
+include_directories(BEFORE
+    ${REACTOS_SOURCE_DIR}/boot/environ/include/efi
+    ${REACTOS_SOURCE_DIR}/boot/freeldr/freeldr
+    ${REACTOS_SOURCE_DIR}/boot/freeldr/freeldr/include
+    ${REACTOS_SOURCE_DIR}/boot/freeldr/freeldr/include/arch/uefi)
+
+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/vgafont.c)
+
+if(ARCH STREQUAL "i386")
+    list(APPEND UEFILDR_COMMON_ASM_SOURCE
+        arch/i386/i386trap.S)
+
+elseif(ARCH STREQUAL "amd64")
+    #TBD
+elseif(ARCH STREQUAL "arm")
+    #TBD
+elseif(ARCH STREQUAL "arm64")
+    #TBD
+else()
+    #TBD
+endif()
+
+add_asm_files(uefifreeldr_common_asm ${FREELDR_COMMON_ASM_SOURCE} 
${UEFILDR_COMMON_ASM_SOURCE})
+
+add_library(uefifreeldr_common
+    ${uefifreeldr_common_asm}
+    ${UEFILDR_ARC_SOURCE}
+    ${FREELDR_BOOTLIB_SOURCE}
+    ${FREELDR_BOOTMGR_SOURCE}
+    ${FREELDR_NTLDR_SOURCE})
+
+target_compile_definitions(uefifreeldr_common PRIVATE UEFIBOOT)
+
+if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
+    # Prevent using SSE (no support in freeldr)
+    target_compile_options(uefifreeldr_common PUBLIC -mno-sse)
+endif()
+
+set(PCH_SOURCE
+    ${UEFILDR_ARC_SOURCE}
+    ${FREELDR_BOOTLIB_SOURCE}
+    ${FREELDR_BOOTMGR_SOURCE}
+    ${FREELDR_NTLDR_SOURCE})
+
+add_pch(uefifreeldr_common include/arch/uefi/uefildr.h PCH_SOURCE)
+add_dependencies(uefifreeldr_common bugcodes asm xdk)
+
+## GCC builds need this extra thing for some reason...
+if(ARCH STREQUAL "i386" AND NOT MSVC)
+    target_link_libraries(uefifreeldr_common mini_hal)
+endif()
+
+
+spec2def(uefildr.exe freeldr.spec)
+
+list(APPEND UEFILDR_BASE_SOURCE
+    include/arch/uefi/uefildr.h
+    arch/uefi/uefildr.c
+    ${FREELDR_BASE_SOURCE})
+
+if(ARCH STREQUAL "i386")
+    # Must be included together with disk/scsiport.c
+    list(APPEND UEFILDR_BASE_SOURCE
+        ${CMAKE_CURRENT_BINARY_DIR}/uefildr.def)
+endif()
+
+add_executable(uefildr ${UEFILDR_BASE_SOURCE})
+set_target_properties(uefildr PROPERTIES SUFFIX ".efi")
+
+target_compile_definitions(uefildr PRIVATE UEFIBOOT)
+
+if(MSVC)
+    target_link_options(uefildr PRIVATE /DYNAMICBASE:NO /NXCOMPAT:NO 
/ignore:4078 /ignore:4254 /DRIVER)
+    # We don't need hotpatching
+    remove_target_compile_option(uefildr "/hotpatch")
+else()
+    target_link_options(uefildr PRIVATE 
-Wl,--exclude-all-symbols,--file-alignment,0x200,--section-alignment,0x200)
+    # Strip everything, including rossym data
+    add_custom_command(TARGET uefildr
+                    POST_BUILD
+                    COMMAND ${CMAKE_STRIP} --remove-section=.rossym 
$<TARGET_FILE:uefildr>
+                    COMMAND ${CMAKE_STRIP} --strip-all $<TARGET_FILE:uefildr>)
+endif()
+
+if(MSVC)
+    set_subsystem(uefildr EFI_APPLICATION)
+else()
+    set_subsystem(uefildr 10)
+endif()
+
+set_entrypoint(uefildr EfiEntry)
+
+if(ARCH STREQUAL "i386")
+    target_link_libraries(uefildr mini_hal)
+endif()
+
+target_link_libraries(uefildr uefifreeldr_common cportlib blcmlib blrtl 
libcntpr)
+
+# dynamic analysis switches
+if(STACK_PROTECTOR)
+    target_sources(uefildr PRIVATE $<TARGET_OBJECTS:gcc_ssp_nt>)
+endif()
+
+if(RUNTIME_CHECKS)
+    target_link_libraries(uefildr runtmchk)
+endif()
+
+add_dependencies(uefildr xdk)

Reply via email to