From 0781962e9fa9f5f186463276c7321178dd400ea0 Mon Sep 17 00:00:00 2001 From: Josh Holtrop Date: Mon, 4 Sep 2023 16:17:47 -0400 Subject: [PATCH] Rework HELLO console module to use hulk.writef --- Rsconscript | 1 + src/hello/console.d | 151 +++++++++----------------------------------- src/hello/hello.d | 28 ++++---- 3 files changed, 44 insertions(+), 136 deletions(-) diff --git a/Rsconscript b/Rsconscript index ebd44b2..9b175a5 100644 --- a/Rsconscript +++ b/Rsconscript @@ -162,6 +162,7 @@ hello_env = env "hello", use: %w[ldc2 x86_64-w64-mingw32-gcc] do |env| env.add_builder(CheckThreadLocal) env.add_builder(HulkBinObj) env["sources"] = glob("src/hello/**/*.d") + env["sources"] += ["src/hulk/writef.d"] env["sources"] += glob("uefi-d/source/**/*.d") env.HulkBinObj("^/hulk_bin.S", hulk_env.expand("^/hulk.bin")) env.Object("^/hulk_bin.o", "^/hulk_bin.S") diff --git a/src/hello/console.d b/src/hello/console.d index 21e5c12..e811aed 100644 --- a/src/hello/console.d +++ b/src/hello/console.d @@ -6,155 +6,62 @@ module hello.console; import uefi; import hello.hello; import core.stdc.stdarg; +import hulk.writef; -struct console +struct Console { /** - * Format a hexadecimal value to a string. + * Write a character to the console. * - * @param s String buffer. - * @param v Value to format. - * @param ptr If true, always output all 16 digits, and separate the upper and - * lower halves with an underscore. + * @param ch Character to write. */ - private static size_t format_hex(CHAR16 * s, ulong v, bool ptr) + public static void write(ubyte ch) { - string hex_chars = "0123456789ABCDEF"; - bool print = ptr; - size_t si = 0u; - for (size_t i = 0u; i < 16u; i++) + if (ch == '\n') { - if (ptr && (i == 8u)) - { - s[si++] = '_'; - } - ulong n = (v >> (60u - 4u * i)) & 0xFu; - if (n != 0u) - { - print = true; - } - if (print || (i == 15u)) - { - s[si++] = hex_chars[n]; - } + write('\r'); } - return si; - } - - /** - * Format a decimal value to a string. - * - * @param s String buffer. - * @param v Value to format. - */ - private static size_t format_dec(CHAR16 * s, ulong v) - { - string dec_chars = "0123456789"; - bool print; - char[20] buf; - size_t buf_i; - while ((buf_i == 0u) || (v != 0u)) - { - ulong n = v % 10u; - buf[buf_i++] = dec_chars[n]; - v /= 10u; - } - for (size_t si = 0u; si < buf_i; si++) - { - s[si] = buf[buf_i - si - 1u]; - } - return buf_i; - } - - /** - * Write a string to the console. - * - * @param s Format string. - * @param args Variable arguments structure. - */ - public static void write(string s, va_list args) - { - __gshared static CHAR16[256] s16; - size_t i = 0u; - bool escape = false; - foreach (char c; s) - { - if (escape) - { - if (c == '%') - { - s16[i++] = '%'; - } - else if (c == 'x') - { - ulong v; - va_arg(args, v); - i += format_hex(&s16[i], v, false); - } - else if (c == 'p') - { - ulong v; - va_arg(args, v); - i += format_hex(&s16[i], v, true); - } - else if (c == 'S') - { - const(CHAR16) * s2; - va_arg(args, s2); - for (size_t s2_i = 0u; s2[s2_i] != 0; s2_i++) - { - s16[i++] = s2[s2_i]; - } - } - else if (c == 'u') - { - ulong v; - va_arg(args, v); - i += format_dec(&s16[i], v); - } - else - { - s16[i++] = c; - } - escape = false; - } - else if (c == '%') - { - escape = true; - } - else - { - s16[i++] = c; - } - } - s16[i++] = 0u; + CHAR16[2] s16 = [ch, 0]; st.ConOut.OutputString(st.ConOut, &s16[0]); } /** - * Write a string to the console. + * Write a formatted string to the console. + * + * @param s Format string. + * @param args Variable arguments structure. + */ + public static void writef(string s, va_list args) + { + hulk.writef.writef(s, args, function void(ubyte ch) { + Console.write(ch); + }); + } + + /** + * Write a formatted string to the console. * * @param s Format string. */ - public static extern (C) void write(string s, ...) + public static extern (C) void writef(string s, ...) { va_list args; va_start(args, s); - write(s, args); + writef(s, args); va_end(args); } /** - * Write a string to the console. + * Write a formatted string and newline to the console. * * @param s Format string. */ - public static extern (C) void writeln(string s, ...) + public static extern (C) void writefln(string s, ...) { va_list args; va_start(args, s); - write(s, args); - write("\r\n", args); + writef(s, args); + writef("\n", args); va_end(args); } @@ -163,7 +70,7 @@ struct console */ public static void wait_key() { - writeln("Press any key..."); + writefln("Press any key..."); st.ConIn.Reset(st.ConIn, FALSE); EFI_INPUT_KEY key; while (st.ConIn.ReadKeyStroke(st.ConIn, &key) == EFI_NOT_READY) diff --git a/src/hello/hello.d b/src/hello/hello.d index e6a01c4..1109b9a 100644 --- a/src/hello/hello.d +++ b/src/hello/hello.d @@ -93,7 +93,7 @@ private bool set_graphics_mode() &gop_guid, null, &buffer_size, handles); if (status != EFI_SUCCESS) { - console.writeln("LocateHandle: error %x", status); + Console.writefln("LocateHandle: error %x", status); return false; } EFI_HANDLE gop_handle = handles[0]; @@ -102,12 +102,12 @@ private bool set_graphics_mode() &gop_guid, &gop_interface); if (status != EFI_SUCCESS) { - console.writeln("HandleProtocol: error %x", status); + Console.writefln("HandleProtocol: error %x", status); return false; } if (gop_interface == null) { - console.writeln("null interface from HandleProtocol"); + Console.writefln("null interface from HandleProtocol"); return false; } EFI_GRAPHICS_OUTPUT_PROTOCOL * gop = cast(EFI_GRAPHICS_OUTPUT_PROTOCOL *)gop_interface; @@ -129,7 +129,7 @@ private bool set_graphics_mode() } if ((status = gop.SetMode(gop, best_mode_number)) != EFI_SUCCESS) { - console.writeln("SetMode: Error %x\n", status); + Console.writefln("SetMode: Error %x\n", status); return false; } bootinfo().fb.buffer = cast(uint *)gop.Mode.FrameBufferBase; @@ -174,7 +174,7 @@ private void get_memory_map(ulong * physical_address_limit, UINTN * memory_map_k &descriptor_version); if (status != EFI_SUCCESS) { - console.writeln("GetMemoryMap: Error %x", status); + Console.writefln("GetMemoryMap: Error %x", status); for (;;) {} } size_t n_entries = memory_map_size / descriptor_size; @@ -187,7 +187,7 @@ private void get_memory_map(ulong * physical_address_limit, UINTN * memory_map_k { if (count > bootinfo().memory_map.length) { - console.writeln("Memory map too large"); + Console.writefln("Memory map too large"); for (;;) {} } EFI_MEMORY_DESCRIPTOR * descriptor = cast(EFI_MEMORY_DESCRIPTOR *)&scratch_base[count * descriptor_size]; @@ -511,21 +511,21 @@ extern (C) EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * st) { .st = st; - console.clear(); + Console.clear(); - console.writeln("Welcome to HELLO, HOS EFI Lightweight LOader, v0.1.0"); - console.writeln("Firmware vendor: '%S', version: 0x%x", st.FirmwareVendor, st.FirmwareVendor); + Console.writefln("Welcome to HELLO, HOS EFI Lightweight LOader, v0.1.0"); + Console.writefln("Firmware vendor: '%S', version: 0x%x", st.FirmwareVendor, st.FirmwareVendor); if (!find_acpi_xsdt()) { - console.writeln("Error: Could not locate ACPI XSDT"); - console.wait_key(); + Console.writefln("Error: Could not locate ACPI XSDT"); + Console.wait_key(); return EFI_SUCCESS; } if (!set_graphics_mode()) { - console.wait_key(); + Console.wait_key(); return EFI_SUCCESS; } @@ -544,8 +544,8 @@ extern (C) EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * st) { break; } - console.writeln("ExitBootServices: Error %x", status); - console.wait_key(); + Console.writefln("ExitBootServices: Error %x", status); + Console.wait_key(); return EFI_SUCCESS; }