Rework HELLO console module to use hulk.writef
This commit is contained in:
parent
e25d28ebc7
commit
0781962e9f
@ -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(CheckThreadLocal)
|
||||||
env.add_builder(HulkBinObj)
|
env.add_builder(HulkBinObj)
|
||||||
env["sources"] = glob("src/hello/**/*.d")
|
env["sources"] = glob("src/hello/**/*.d")
|
||||||
|
env["sources"] += ["src/hulk/writef.d"]
|
||||||
env["sources"] += glob("uefi-d/source/**/*.d")
|
env["sources"] += glob("uefi-d/source/**/*.d")
|
||||||
env.HulkBinObj("^/hulk_bin.S", hulk_env.expand("^/hulk.bin"))
|
env.HulkBinObj("^/hulk_bin.S", hulk_env.expand("^/hulk.bin"))
|
||||||
env.Object("^/hulk_bin.o", "^/hulk_bin.S")
|
env.Object("^/hulk_bin.o", "^/hulk_bin.S")
|
||||||
|
@ -6,155 +6,62 @@ module hello.console;
|
|||||||
import uefi;
|
import uefi;
|
||||||
import hello.hello;
|
import hello.hello;
|
||||||
import core.stdc.stdarg;
|
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 ch Character to write.
|
||||||
* @param v Value to format.
|
|
||||||
* @param ptr If true, always output all 16 digits, and separate the upper and
|
|
||||||
* lower halves with an underscore.
|
|
||||||
*/
|
*/
|
||||||
private static size_t format_hex(CHAR16 * s, ulong v, bool ptr)
|
public static void write(ubyte ch)
|
||||||
{
|
{
|
||||||
string hex_chars = "0123456789ABCDEF";
|
if (ch == '\n')
|
||||||
bool print = ptr;
|
|
||||||
size_t si = 0u;
|
|
||||||
for (size_t i = 0u; i < 16u; i++)
|
|
||||||
{
|
{
|
||||||
if (ptr && (i == 8u))
|
write('\r');
|
||||||
{
|
|
||||||
s[si++] = '_';
|
|
||||||
}
|
}
|
||||||
ulong n = (v >> (60u - 4u * i)) & 0xFu;
|
CHAR16[2] s16 = [ch, 0];
|
||||||
if (n != 0u)
|
|
||||||
{
|
|
||||||
print = true;
|
|
||||||
}
|
|
||||||
if (print || (i == 15u))
|
|
||||||
{
|
|
||||||
s[si++] = hex_chars[n];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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;
|
|
||||||
st.ConOut.OutputString(st.ConOut, &s16[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.
|
* @param s Format string.
|
||||||
*/
|
*/
|
||||||
public static extern (C) void write(string s, ...)
|
public static extern (C) void writef(string s, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, s);
|
va_start(args, s);
|
||||||
write(s, args);
|
writef(s, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Write a string to the console.
|
* Write a formatted string and newline to the console.
|
||||||
*
|
*
|
||||||
* @param s Format string.
|
* @param s Format string.
|
||||||
*/
|
*/
|
||||||
public static extern (C) void writeln(string s, ...)
|
public static extern (C) void writefln(string s, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, s);
|
va_start(args, s);
|
||||||
write(s, args);
|
writef(s, args);
|
||||||
write("\r\n", args);
|
writef("\n", args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,7 +70,7 @@ struct console
|
|||||||
*/
|
*/
|
||||||
public static void wait_key()
|
public static void wait_key()
|
||||||
{
|
{
|
||||||
writeln("Press any key...");
|
writefln("Press any key...");
|
||||||
st.ConIn.Reset(st.ConIn, FALSE);
|
st.ConIn.Reset(st.ConIn, FALSE);
|
||||||
EFI_INPUT_KEY key;
|
EFI_INPUT_KEY key;
|
||||||
while (st.ConIn.ReadKeyStroke(st.ConIn, &key) == EFI_NOT_READY)
|
while (st.ConIn.ReadKeyStroke(st.ConIn, &key) == EFI_NOT_READY)
|
||||||
|
@ -93,7 +93,7 @@ private bool set_graphics_mode()
|
|||||||
&gop_guid, null, &buffer_size, handles);
|
&gop_guid, null, &buffer_size, handles);
|
||||||
if (status != EFI_SUCCESS)
|
if (status != EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
console.writeln("LocateHandle: error %x", status);
|
Console.writefln("LocateHandle: error %x", status);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
EFI_HANDLE gop_handle = handles[0];
|
EFI_HANDLE gop_handle = handles[0];
|
||||||
@ -102,12 +102,12 @@ private bool set_graphics_mode()
|
|||||||
&gop_guid, &gop_interface);
|
&gop_guid, &gop_interface);
|
||||||
if (status != EFI_SUCCESS)
|
if (status != EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
console.writeln("HandleProtocol: error %x", status);
|
Console.writefln("HandleProtocol: error %x", status);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (gop_interface == null)
|
if (gop_interface == null)
|
||||||
{
|
{
|
||||||
console.writeln("null interface from HandleProtocol");
|
Console.writefln("null interface from HandleProtocol");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
EFI_GRAPHICS_OUTPUT_PROTOCOL * gop = cast(EFI_GRAPHICS_OUTPUT_PROTOCOL *)gop_interface;
|
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)
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
bootinfo().fb.buffer = cast(uint *)gop.Mode.FrameBufferBase;
|
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);
|
&descriptor_version);
|
||||||
if (status != EFI_SUCCESS)
|
if (status != EFI_SUCCESS)
|
||||||
{
|
{
|
||||||
console.writeln("GetMemoryMap: Error %x", status);
|
Console.writefln("GetMemoryMap: Error %x", status);
|
||||||
for (;;) {}
|
for (;;) {}
|
||||||
}
|
}
|
||||||
size_t n_entries = memory_map_size / descriptor_size;
|
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)
|
if (count > bootinfo().memory_map.length)
|
||||||
{
|
{
|
||||||
console.writeln("Memory map too large");
|
Console.writefln("Memory map too large");
|
||||||
for (;;) {}
|
for (;;) {}
|
||||||
}
|
}
|
||||||
EFI_MEMORY_DESCRIPTOR * descriptor = cast(EFI_MEMORY_DESCRIPTOR *)&scratch_base[count * descriptor_size];
|
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;
|
.st = st;
|
||||||
|
|
||||||
console.clear();
|
Console.clear();
|
||||||
|
|
||||||
console.writeln("Welcome to HELLO, HOS EFI Lightweight LOader, v0.1.0");
|
Console.writefln("Welcome to HELLO, HOS EFI Lightweight LOader, v0.1.0");
|
||||||
console.writeln("Firmware vendor: '%S', version: 0x%x", st.FirmwareVendor, st.FirmwareVendor);
|
Console.writefln("Firmware vendor: '%S', version: 0x%x", st.FirmwareVendor, st.FirmwareVendor);
|
||||||
|
|
||||||
if (!find_acpi_xsdt())
|
if (!find_acpi_xsdt())
|
||||||
{
|
{
|
||||||
console.writeln("Error: Could not locate ACPI XSDT");
|
Console.writefln("Error: Could not locate ACPI XSDT");
|
||||||
console.wait_key();
|
Console.wait_key();
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!set_graphics_mode())
|
if (!set_graphics_mode())
|
||||||
{
|
{
|
||||||
console.wait_key();
|
Console.wait_key();
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,8 +544,8 @@ extern (C) EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE * st)
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
console.writeln("ExitBootServices: Error %x", status);
|
Console.writefln("ExitBootServices: Error %x", status);
|
||||||
console.wait_key();
|
Console.wait_key();
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user