From a38f95a7b8f24d8b98575614df48bd5594823e1a Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 14 Mar 2022 22:26:55 -0400 Subject: [PATCH] Set graphics mode --- Rsconscript | 4 +-- src/hel/hel.d | 67 ++++++++++++++++++++++++++++++++------- src/hel/output.d | 2 +- src/kernel/hos/bootinfo.d | 19 +++++++++++ 4 files changed, 77 insertions(+), 15 deletions(-) create mode 100644 src/kernel/hos/bootinfo.d diff --git a/Rsconscript b/Rsconscript index 78b76b2..a24adbf 100644 --- a/Rsconscript +++ b/Rsconscript @@ -73,10 +73,10 @@ end hel_env = env "hel", use: %w[ldc2 x86_64-w64-mingw32-gcc] do |env| env.add_builder(Image) - env["sources"] = glob("src/hel/**/*.d") + env["sources"] = glob("src/hel/**/*.d", "src/kernel/hos/bootinfo.d") env["sources"] += glob("uefi-d/source/**/*.d") env["DFLAGS"] += %w[-mtriple=x86_64-unknown-windows-coff --betterC -release -O3 --wi] - env["D_IMPORT_PATH"] += %w[src/hel uefi-d/source] + env["D_IMPORT_PATH"] += %w[src/hel src/kernel uefi-d/source] env["LD"] = "x86_64-w64-mingw32-gcc" env["LDFLAGS"] += %w[-nostdlib -Wl,-dll -shared -Wl,--subsystem,10 -e efi_main -Wl,-Map,${_TARGET}.map] env["LDCMD"] = %w[${LD} -o ${_TARGET} ${LDFLAGS} ${_SOURCES} ${LIBDIRPREFIX}${LIBPATH} ${LIBLINKPREFIX}${LIBS}] diff --git a/src/hel/hel.d b/src/hel/hel.d index e24e1ad..467d1a7 100644 --- a/src/hel/hel.d +++ b/src/hel/hel.d @@ -1,28 +1,23 @@ import uefi; import output; import heap; +import hos.bootinfo; -__gshared EFI_SYSTEM_TABLE * g_st; +__gshared EFI_SYSTEM_TABLE * st; +__gshared BootInfo * bootinfo; private void wait_key() { writeln("Press any key..."); - g_st.ConIn.Reset(g_st.ConIn, FALSE); + st.ConIn.Reset(st.ConIn, FALSE); EFI_INPUT_KEY key; - while (g_st.ConIn.ReadKeyStroke(g_st.ConIn, &key) == EFI_NOT_READY) + while (st.ConIn.ReadKeyStroke(st.ConIn, &key) == EFI_NOT_READY) { } } -extern (C) EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * st) +private bool set_graphics_mode() { - g_st = st; - - st.ConOut.ClearScreen(st.ConOut); - - writeln("HOS EFI loader"); - writeln("Firmware vendor: '%S', version: 0x%x", st.FirmwareVendor, st.FirmwareVendor); - UINTN buffer_size = heap_free(); EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; EFI_HANDLE * handles = cast(EFI_HANDLE *)heap_base(); @@ -31,10 +26,58 @@ extern (C) EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * st) if (status != EFI_SUCCESS) { writeln("LocateHandle: error %u", status); + return false; + } + EFI_HANDLE gop_handle = handles[0]; + EFI_HANDLE gop_interface; + status = st.BootServices.HandleProtocol(gop_handle, + &gop_guid, &gop_interface); + if (status != EFI_SUCCESS) + { + writeln("HandleProtocol: error %u", status); + return false; + } + if (gop_interface == null) + { + writeln("null interface from HandleProtocol"); + return false; + } + EFI_GRAPHICS_OUTPUT_PROTOCOL * gop = cast(EFI_GRAPHICS_OUTPUT_PROTOCOL *)gop_interface; + UINTN info_size; + EFI_GRAPHICS_OUTPUT_MODE_INFORMATION * info; + uint best_width; + uint best_mode_number; + for (uint mode_number = 0u; + (status = gop.QueryMode(gop, mode_number, &info_size, &info)) == EFI_SUCCESS; + mode_number++) + { + if (info.HorizontalResolution > best_width) + { + best_width = info.HorizontalResolution; + best_mode_number = mode_number; + } + st.BootServices.FreePool(info); + } + gop.SetMode(gop, best_mode_number); + return true; +} + +extern (C) EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * st) +{ + .st = st; + + st.ConOut.ClearScreen(st.ConOut); + + writeln("HOS EFI loader"); + writeln("Firmware vendor: '%S', version: 0x%x", st.FirmwareVendor, st.FirmwareVendor); + + bootinfo = cast(BootInfo *)heap_consume(BootInfo.sizeof); + + if (!set_graphics_mode()) + { wait_key(); return EFI_SUCCESS; } - EFI_HANDLE gop_handle = handles[0]; wait_key(); diff --git a/src/hel/output.d b/src/hel/output.d index 96506f4..537c761 100644 --- a/src/hel/output.d +++ b/src/hel/output.d @@ -101,7 +101,7 @@ void write(string s, va_list args) } } s16[i++] = 0u; - g_st.ConOut.OutputString(g_st.ConOut, &s16[0]); + st.ConOut.OutputString(st.ConOut, &s16[0]); } extern (C) void write(string s, ...) diff --git a/src/kernel/hos/bootinfo.d b/src/kernel/hos/bootinfo.d new file mode 100644 index 0000000..68cda2d --- /dev/null +++ b/src/kernel/hos/bootinfo.d @@ -0,0 +1,19 @@ +struct BootInfo +{ + struct MemoryRegion + { + void * base; + size_t size; + } + struct Framebuffer + { + uint * buffer; + uint width; + uint height; + uint stride; + uint format; + } + Framebuffer fb; + MemoryRegion * memory_map; + uint memory_map_size; +}