From 521c13280133f04e0dc746586537ebd41ffec9bb Mon Sep 17 00:00:00 2001 From: "Justin C. Miller" Date: Sat, 22 Feb 2020 01:54:00 -0800 Subject: [PATCH] Back to a basic UEFI stub --- modules.yaml | 10 +- scripts/templates/exe.boot.j2 | 18 +--- scripts/templates/target.boot.j2 | 25 ++--- src/boot/console.cpp | 178 ++++++++++++++++++++----------- src/boot/console.h | 24 +++-- src/boot/error.cpp | 66 ++++++++++++ src/boot/error.h | 53 +++++++++ src/boot/main.cpp | 52 +++++++-- src/boot/utility.cpp | 53 ++------- src/boot/utility.h | 12 +-- 10 files changed, 323 insertions(+), 168 deletions(-) create mode 100644 src/boot/error.cpp create mode 100644 src/boot/error.h diff --git a/modules.yaml b/modules.yaml index df3d73f..82aad4d 100644 --- a/modules.yaml +++ b/modules.yaml @@ -53,15 +53,11 @@ modules: boot: kind: exe target: boot - output: boot.elf + output: boot.efi source: - - src/boot/crt0.s - - src/boot/console.cpp - - src/boot/guids.cpp - - src/boot/loader.cpp - src/boot/main.cpp - - src/boot/memory.cpp - - src/boot/reloc.cpp + - src/boot/console.cpp + - src/boot/error.cpp - src/boot/utility.cpp nulldrv: diff --git a/scripts/templates/exe.boot.j2 b/scripts/templates/exe.boot.j2 index bb1e9b5..700f82e 100644 --- a/scripts/templates/exe.boot.j2 +++ b/scripts/templates/exe.boot.j2 @@ -4,22 +4,8 @@ ccflags = $ccflags $ -DKERNEL_FILENAME=L\"jsix.elf\" $ - -DGNU_EFI_USE_MS_ABI $ - -DHAVE_USE_MS_ABI $ - -DEFI_DEBUG=0 $ - -DEFI_DEBUG_CLEAR_MEMORY=0 $ - -DBOOTLOADER_DEBUG - -ldflags = $ldflags $ - -T ${srcroot}/src/arch/x86_64/boot.ld $ - -shared - -{% endblock %} - -{% block extra %} - -build $builddir/boot.efi : makeefi ${builddir}/{{ module.output }} - name = boot.efi + -I${srcroot}/external/include $ + -I${srcroot}/external/include/X64 {% endblock %} diff --git a/scripts/templates/target.boot.j2 b/scripts/templates/target.boot.j2 index 5c6da7b..6358003 100644 --- a/scripts/templates/target.boot.j2 +++ b/scripts/templates/target.boot.j2 @@ -3,7 +3,7 @@ {% block binaries %} cc = clang cxx = clang++ -ld = ld +ld = clang++ ar = ar nasm = nasm objcopy = objcopy @@ -12,27 +12,24 @@ objcopy = objcopy {% block variables %} ccflags = $ccflags $ - -ggdb $ - -nostdlib $ + --target=x86_64-unknown-windows $ -ffreestanding $ - -nodefaultlibs $ - -fno-builtin $ - -mno-sse $ - -fno-omit-frame-pointer $ -mno-red-zone $ -fshort-wchar $ - -D__ELF__ $ - -fPIC + -fno-omit-frame-pointer $ + -ggdb cxxflags = $cxxflags $ - -fno-exceptions $ - -fno-rtti $ + -fno-rtti $ + -fno-exceptions ldflags = $ldflags $ - -g $ + --target=x86_64-unknown-windows $ -nostdlib $ - -Bsymbolic $ - -nostartfiles + -Wl,-entry:efi_main $ + -Wl,-subsystem:efi_application $ + -fuse-ld=lld-link $ + -g {% endblock %} diff --git a/src/boot/console.cpp b/src/boot/console.cpp index 84add27..35a7d4d 100644 --- a/src/boot/console.cpp +++ b/src/boot/console.cpp @@ -1,84 +1,94 @@ #include #include +#include +#include +#include +#include +#include + #include "console.h" -#include "guids.h" +//#include "guids.h" #include "utility.h" +namespace boot { + size_t ROWS = 0; size_t COLS = 0; -static EFI_SIMPLE_TEXT_OUT_PROTOCOL *m_out = 0; +console *console::s_console = nullptr; static const wchar_t digits[] = {u'0', u'1', u'2', u'3', u'4', u'5', u'6', u'7', u'8', u'9', u'a', u'b', u'c', u'd', u'e', u'f'}; -console::console(EFI_SYSTEM_TABLE *system_table) : +console::console(uefi::system_table *system_table) : m_rows(0), m_cols(0), + m_current_status_line(0), m_out(nullptr) { s_console = this; - m_boot = system_table->BootServices; - m_out = system_table->ConOut; + m_boot = system_table->boot_services; + m_out = system_table->con_out; } -EFI_STATUS +uefi::status console::initialize(const wchar_t *version) { - EFI_STATUS status; + uefi::status status; // Might not find a video device at all, so ignore not found errors status = pick_mode(); - if (status != EFI_NOT_FOUND) + if (status != uefi::status::not_found) CHECK_EFI_STATUS_OR_FAIL(status); - status = m_out->QueryMode(m_out, m_out->Mode->Mode, &m_cols, &m_rows); + status = m_out->query_mode(m_out->mode->mode, &m_cols, &m_rows); CHECK_EFI_STATUS_OR_RETURN(status, "QueryMode"); - status = m_out->ClearScreen(m_out); + status = m_out->clear_screen(); CHECK_EFI_STATUS_OR_RETURN(status, "ClearScreen"); - m_out->SetAttribute(m_out, EFI_LIGHTCYAN); - m_out->OutputString(m_out, (wchar_t *)L"jsix loader "); + m_out->set_attribute(uefi::attribute::light_cyan); + m_out->output_string((wchar_t *)L"jsix loader "); - m_out->SetAttribute(m_out, EFI_LIGHTMAGENTA); - m_out->OutputString(m_out, (wchar_t *)version); + m_out->set_attribute(uefi::attribute::light_magenta); + m_out->output_string((wchar_t *)version); - m_out->SetAttribute(m_out, EFI_LIGHTGRAY); - m_out->OutputString(m_out, (wchar_t *)L" booting...\r\n\n"); + m_out->set_attribute(uefi::attribute::light_gray); + m_out->output_string((wchar_t *)L" booting...\r\n\n"); return status; } -EFI_STATUS +uefi::status console::pick_mode() { - EFI_STATUS status; - EFI_GRAPHICS_OUTPUT_PROTOCOL *gfx_out_proto; - status = m_boot->LocateProtocol(&guid_gfx_out, NULL, (void **)&gfx_out_proto); + uefi::status status; + uefi::protos::graphics_output *gfx_out_proto; + uefi::guid guid = uefi::protos::graphics_output::guid; + status = m_boot->locate_protocol(&guid, nullptr, (void **)&gfx_out_proto); CHECK_EFI_STATUS_OR_RETURN(status, "LocateProtocol gfx"); - const uint32_t modes = gfx_out_proto->Mode->MaxMode; - uint32_t best = gfx_out_proto->Mode->Mode; + const uint32_t modes = gfx_out_proto->mode->max_mode; + uint32_t best = gfx_out_proto->mode->mode; - EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info = - (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *)gfx_out_proto->Mode; + uefi::graphics_output_mode_info *info = + (uefi::graphics_output_mode_info *)gfx_out_proto->mode; - uint32_t res = info->HorizontalResolution * info->VerticalResolution; - int is_fb = info->PixelFormat != PixelBltOnly; + uint32_t res = info->horizontal_resolution * info->vertical_resolution; + int is_fb = info->pixel_format != uefi::pixel_format::blt_only; for (uint32_t i = 0; i < modes; ++i) { size_t size = 0; - status = gfx_out_proto->QueryMode(gfx_out_proto, i, &size, &info); + status = gfx_out_proto->query_mode(i, &size, &info); CHECK_EFI_STATUS_OR_RETURN(status, "QueryMode"); #ifdef MAX_HRES - if (info->HorizontalResolution > MAX_HRES) continue; + if (info->horizontal_resolution > MAX_HRES) continue; #endif - const uint32_t new_res = info->HorizontalResolution * info->VerticalResolution; - const int new_is_fb = info->PixelFormat == PixelBltOnly; + const uint32_t new_res = info->horizontal_resolution * info->vertical_resolution; + const int new_is_fb = info->pixel_format != uefi::pixel_format::blt_only; if (new_is_fb > is_fb && new_res >= res) { best = i; @@ -86,9 +96,9 @@ console::pick_mode() } } - status = gfx_out_proto->SetMode(gfx_out_proto, best); + status = gfx_out_proto->set_mode(best); CHECK_EFI_STATUS_OR_RETURN(status, "SetMode %d/%d", best, modes); - return EFI_SUCCESS; + return uefi::status::success; } size_t @@ -101,7 +111,7 @@ console::print_hex(uint32_t n) const *p++ = digits[nibble]; } *p = 0; - m_out->OutputString(m_out, buffer); + m_out->output_string(buffer); return 8; } @@ -115,7 +125,7 @@ console::print_long_hex(uint64_t n) const *p++ = digits[nibble]; } *p = 0; - m_out->OutputString(m_out, buffer); + m_out->output_string(buffer); return 16; } @@ -130,7 +140,7 @@ console::print_dec(uint32_t n) const n /= 10; } while (n != 0); - m_out->OutputString(m_out, ++p); + m_out->output_string(++p); return 10 - (p - buffer); } @@ -145,7 +155,7 @@ console::print_long_dec(uint64_t n) const n /= 10; } while (n != 0); - m_out->OutputString(m_out, ++p); + m_out->output_string(++p); return 20 - (p - buffer); } @@ -165,14 +175,14 @@ console::vprintf(const wchar_t *fmt, va_list args) const } *w = 0; - m_out->OutputString(m_out, buffer); + m_out->output_string(buffer); w = buffer; r++; // chomp the % switch (*r++) { case L'%': - m_out->OutputString(m_out, const_cast(L"%")); + m_out->output_string(const_cast(L"%")); count++; break; @@ -189,7 +199,7 @@ console::vprintf(const wchar_t *fmt, va_list args) const { wchar_t *s = va_arg(args, wchar_t*); count += wstrlen(s); - m_out->OutputString(m_out, s); + m_out->output_string(s); } break; @@ -215,7 +225,7 @@ console::vprintf(const wchar_t *fmt, va_list args) const } *w = 0; - m_out->OutputString(m_out, buffer); + m_out->output_string(buffer); return count; } @@ -244,40 +254,77 @@ console::print(const wchar_t *fmt, ...) } void -console::status_begin(const wchar_t *message) const +console::status_begin(const wchar_t *message) { - m_out->SetAttribute(m_out, EFI_LIGHTGRAY); - m_out->OutputString(m_out, (wchar_t *)message); + m_current_status_line = m_out->mode->cursor_row; + m_out->set_cursor_position(0, m_current_status_line); + m_out->set_attribute(uefi::attribute::light_gray); + m_out->output_string((wchar_t *)message); + m_out->output_string((wchar_t *)L"\r\n"); } void console::status_ok() const { - m_out->SetAttribute(m_out, EFI_LIGHTGRAY); - m_out->OutputString(m_out, (wchar_t *)L"["); - m_out->SetAttribute(m_out, EFI_GREEN); - m_out->OutputString(m_out, (wchar_t *)L" ok "); - m_out->SetAttribute(m_out, EFI_LIGHTGRAY); - m_out->OutputString(m_out, (wchar_t *)L"]\r\n"); + int row = m_out->mode->cursor_row; + int col = m_out->mode->cursor_column; + + m_out->set_cursor_position(50, m_current_status_line); + + m_out->set_attribute(uefi::attribute::light_gray); + m_out->output_string((wchar_t *)L"["); + m_out->set_attribute(uefi::attribute::green); + m_out->output_string((wchar_t *)L" ok "); + m_out->set_attribute(uefi::attribute::light_gray); + m_out->output_string((wchar_t *)L"]\r\n"); + + m_out->set_cursor_position(col, row); } void console::status_fail(const wchar_t *error) const { - m_out->SetAttribute(m_out, EFI_LIGHTGRAY); - m_out->OutputString(m_out, (wchar_t *)L"["); - m_out->SetAttribute(m_out, EFI_LIGHTRED); - m_out->OutputString(m_out, (wchar_t *)L"failed"); - m_out->SetAttribute(m_out, EFI_LIGHTGRAY); - m_out->OutputString(m_out, (wchar_t *)L"]\r\n"); + int row = m_out->mode->cursor_row; + m_out->set_cursor_position(50, m_current_status_line); - m_out->SetAttribute(m_out, EFI_RED); - m_out->OutputString(m_out, (wchar_t *)error); - m_out->SetAttribute(m_out, EFI_LIGHTGRAY); - m_out->OutputString(m_out, (wchar_t *)L"\r\n"); + m_out->set_attribute(uefi::attribute::light_gray); + m_out->output_string((wchar_t *)L"["); + m_out->set_attribute(uefi::attribute::light_red); + m_out->output_string((wchar_t *)L"failed"); + m_out->set_attribute(uefi::attribute::light_gray); + m_out->output_string((wchar_t *)L"]"); + + m_out->set_cursor_position(4, row); + + m_out->set_attribute(uefi::attribute::red); + m_out->output_string((wchar_t *)error); + m_out->set_attribute(uefi::attribute::light_gray); + m_out->output_string((wchar_t *)L"\r\n"); } -EFI_STATUS +void +console::status_warn(const wchar_t *error) const +{ + int row = m_out->mode->cursor_row; + m_out->set_cursor_position(50, m_current_status_line); + + m_out->set_attribute(uefi::attribute::light_gray); + m_out->output_string((wchar_t *)L"["); + m_out->set_attribute(uefi::attribute::brown); + m_out->output_string((wchar_t *)L" warn "); + m_out->set_attribute(uefi::attribute::light_gray); + m_out->output_string((wchar_t *)L"]"); + + m_out->set_cursor_position(4, row); + + m_out->set_attribute(uefi::attribute::yellow); + m_out->output_string((wchar_t *)error); + m_out->set_attribute(uefi::attribute::light_gray); + m_out->output_string((wchar_t *)L"\r\n"); +} + +/* +uefi::status con_get_framebuffer( EFI_BOOT_SERVICES *bootsvc, void **buffer, @@ -288,17 +335,17 @@ con_get_framebuffer( uint32_t *gmask, uint32_t *bmask) { - EFI_STATUS status; + uefi::status status; - EFI_GRAPHICS_OUTPUT_PROTOCOL *gop; + uefi::protos::graphics_output *gop; status = bootsvc->LocateProtocol(&guid_gfx_out, NULL, (void **)&gop); if (status != EFI_NOT_FOUND) { CHECK_EFI_STATUS_OR_RETURN(status, "LocateProtocol gfx"); *buffer = (void *)gop->Mode->FrameBufferBase; *buffer_size = gop->Mode->FrameBufferSize; - *hres = gop->Mode->Info->HorizontalResolution; - *vres = gop->Mode->Info->VerticalResolution; + *hres = gop->Mode->Info->horizontal_resolution; + *vres = gop->Mode->Info->vertical_resolution; switch (gop->Mode->Info->PixelFormat) { case PixelRedGreenBlueReserved8BitPerColor: @@ -331,3 +378,6 @@ con_get_framebuffer( *rmask = *gmask = *bmask = 0; return EFI_SUCCESS; } +*/ + +} // namespace boot diff --git a/src/boot/console.h b/src/boot/console.h index c9fded0..7e43d6f 100644 --- a/src/boot/console.h +++ b/src/boot/console.h @@ -1,17 +1,20 @@ #pragma once #include #include -#include +#include + +namespace boot { class console { public: - console(EFI_SYSTEM_TABLE *system_table); + console(uefi::system_table *system_table); - EFI_STATUS initialize(const wchar_t *version); + uefi::status initialize(const wchar_t *version); - void status_begin(const wchar_t *message) const; + void status_begin(const wchar_t *message); void status_fail(const wchar_t *error) const; + void status_warn(const wchar_t *error) const; void status_ok() const; size_t print_hex(uint32_t n) const; @@ -24,19 +27,20 @@ public: static size_t print(const wchar_t *fmt, ...); private: - EFI_STATUS pick_mode(); + uefi::status pick_mode(); size_t vprintf(const wchar_t *fmt, va_list args) const; size_t m_rows, m_cols; - EFI_BOOT_SERVICES *m_boot; - EFI_SIMPLE_TEXT_OUT_PROTOCOL *m_out; + int m_current_status_line; + uefi::boot_services *m_boot; + uefi::protos::simple_text_output *m_out; static console *s_console; }; -EFI_STATUS +uefi::status con_get_framebuffer( - EFI_BOOT_SERVICES *bootsvc, + uefi::boot_services *bs, void **buffer, size_t *buffer_size, uint32_t *hres, @@ -44,3 +48,5 @@ con_get_framebuffer( uint32_t *rmask, uint32_t *gmask, uint32_t *bmask); + +} // namespace boot diff --git a/src/boot/error.cpp b/src/boot/error.cpp new file mode 100644 index 0000000..97d7ff2 --- /dev/null +++ b/src/boot/error.cpp @@ -0,0 +1,66 @@ +#include "error.h" +#include "console.h" + +namespace boot { +namespace error { + +handler *handler::s_current = nullptr; + +[[ noreturn ]] void +raise(uefi::status status, const wchar_t *message) +{ + if (handler::s_current) { + handler::s_current->handle(status, message); + } + while (1) asm("hlt"); +} + +handler::handler() : + m_next(s_current) +{ + s_current = this; +} + +handler::~handler() +{ + if (s_current != this) + raise(uefi::status::warn_stale_data, + L"Non-current error handler destructing"); + s_current = m_next; +} + +uefi_handler::uefi_handler(console &con) : + handler(), + m_con(con) +{ +} + +[[ noreturn ]] void +uefi_handler::handle(uefi::status s, const wchar_t *message) +{ + m_con.status_fail(message); + while (1) asm("hlt"); +} + +cpu_assert_handler::cpu_assert_handler() : handler() {} + +[[ noreturn ]] void +cpu_assert_handler::handle(uefi::status s, const wchar_t *message) +{ + asm volatile ( + "movq $0xeeeeeeebadbadbad, %%r8;" + "movq %0, %%r9;" + "movq $0, %%rdx;" + "divq %%rdx;" + : + : "r"((uint64_t)s) + : "rax", "rdx", "r8", "r9"); + while (1) asm("hlt"); +} + +} // namespace error +} // namespace boot + +extern "C" int _purecall() { ::boot::error::raise(uefi::status::unsupported, L"Pure virtual call"); } +void operator delete (void *) {} + diff --git a/src/boot/error.h b/src/boot/error.h new file mode 100644 index 0000000..24c562f --- /dev/null +++ b/src/boot/error.h @@ -0,0 +1,53 @@ +#pragma once + +#include +#include + +namespace boot { + +class console; + +namespace error { + +/// Halt or exit the program with the given error status/message +[[ noreturn ]] void raise(uefi::status status, const wchar_t *message); + +/// Interface for error-handling functors +class handler +{ +public: + /// Constructor must be called by implementing classes. + handler(); + virtual ~handler(); + + /// Interface for implementations of error handling. + virtual void handle(uefi::status, const wchar_t*) = 0; + +private: + friend void raise(uefi::status, const wchar_t *); + + handler *m_next; + static handler *s_current; +}; + +class uefi_handler : + public handler +{ +public: + uefi_handler(console &con); + [[ noreturn ]] void handle(uefi::status, const wchar_t*) override; + +private: + console &m_con; +}; + +class cpu_assert_handler : + public handler +{ +public: + cpu_assert_handler(); + [[ noreturn ]] void handle(uefi::status, const wchar_t*) override; +}; + +} // namespace error +} // namespace boot diff --git a/src/boot/main.cpp b/src/boot/main.cpp index af1a5cb..3fb7b5e 100644 --- a/src/boot/main.cpp +++ b/src/boot/main.cpp @@ -1,9 +1,15 @@ +#include +#include +#include +#include + #include #include - -#include +#include #include "console.h" +#include "error.h" +/* #include "guids.h" #include "kernel_args.h" #include "loader.h" @@ -13,11 +19,15 @@ #ifndef SCRATCH_PAGES #define SCRATCH_PAGES 64 #endif +*/ #ifndef GIT_VERSION_WIDE #define GIT_VERSION_WIDE L"no version" #endif +using namespace boot; + +/* #define KERNEL_HEADER_MAGIC 0x600db007 #define KERNEL_HEADER_VERSION 1 @@ -45,7 +55,7 @@ type_to_wchar(wchar_t *into, uint32_t type) EFI_STATUS detect_debug_mode(EFI_RUNTIME_SERVICES *run, kernel_args *header) { - wchar_t var_name[] = L"debug"; + CHAR16 var_name[] = L"debug"; EFI_STATUS status; uint8_t debug = 0; @@ -79,15 +89,38 @@ detect_debug_mode(EFI_RUNTIME_SERVICES *run, kernel_args *header) { return EFI_SUCCESS; } +*/ -extern "C" EFI_STATUS -efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) +extern "C" uefi::status +efi_main(uefi::handle image_handle, uefi::system_table *st) { - EFI_STATUS status; - EFI_BOOT_SERVICES *bootsvc = system_table->BootServices; - EFI_RUNTIME_SERVICES *runsvc = system_table->RuntimeServices; + error::cpu_assert_handler handler; - console con(system_table); + uefi::boot_services *bs = st->boot_services; + uefi::runtime_services *rs = st->runtime_services; + + console con(st); + con.initialize(GIT_VERSION_WIDE); + + { + error::uefi_handler handler(con); + con.status_begin(L"Trying to do an easy thing..."); + con.status_ok(); + + con.status_begin(L"Trying to do a harder thing..."); + con.status_warn(L"First warning"); + con.status_warn(L"Second warning"); + + con.status_begin(L"Trying to do the impossible..."); + con.status_warn(L"we're not going to make it"); + + error::raise(uefi::status::unsupported, L"OH NO"); + } + + while(1); + return uefi::status::success; +} + /* // When checking console initialization, use CHECK_EFI_STATUS_OR_RETURN // because we can't be sure if the console was fully set up @@ -225,3 +258,4 @@ efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) kernel_main(data_header); return EFI_LOAD_ERROR; } +*/ diff --git a/src/boot/utility.cpp b/src/boot/utility.cpp index f11e770..417402d 100644 --- a/src/boot/utility.cpp +++ b/src/boot/utility.cpp @@ -1,61 +1,28 @@ #include "utility.h" struct error_code_desc { - EFI_STATUS code; + uefi::status code; const wchar_t *name; }; -// Based off the gnu-efi table struct error_code_desc error_table[] = { - { EFI_SUCCESS, L"Success" }, - { EFI_LOAD_ERROR, L"Load Error" }, - { EFI_INVALID_PARAMETER, L"Invalid Parameter" }, - { EFI_UNSUPPORTED, L"Unsupported" }, - { EFI_BAD_BUFFER_SIZE, L"Bad Buffer Size" }, - { EFI_BUFFER_TOO_SMALL, L"Buffer Too Small" }, - { EFI_NOT_READY, L"Not Ready" }, - { EFI_DEVICE_ERROR, L"Device Error" }, - { EFI_WRITE_PROTECTED, L"Write Protected" }, - { EFI_OUT_OF_RESOURCES, L"Out of Resources" }, - { EFI_VOLUME_CORRUPTED, L"Volume Corrupt" }, - { EFI_VOLUME_FULL, L"Volume Full" }, - { EFI_NO_MEDIA, L"No Media" }, - { EFI_MEDIA_CHANGED, L"Media changed" }, - { EFI_NOT_FOUND, L"Not Found" }, - { EFI_ACCESS_DENIED, L"Access Denied" }, - { EFI_NO_RESPONSE, L"No Response" }, - { EFI_NO_MAPPING, L"No mapping" }, - { EFI_TIMEOUT, L"Time out" }, - { EFI_NOT_STARTED, L"Not started" }, - { EFI_ALREADY_STARTED, L"Already started" }, - { EFI_ABORTED, L"Aborted" }, - { EFI_ICMP_ERROR, L"ICMP Error" }, - { EFI_TFTP_ERROR, L"TFTP Error" }, - { EFI_PROTOCOL_ERROR, L"Protocol Error" }, - { EFI_INCOMPATIBLE_VERSION, L"Incompatible Version" }, - { EFI_SECURITY_VIOLATION, L"Security Policy Violation" }, - { EFI_CRC_ERROR, L"CRC Error" }, - { EFI_END_OF_MEDIA, L"End of Media" }, - { EFI_END_OF_FILE, L"End of File" }, - { EFI_INVALID_LANGUAGE, L"Invalid Languages" }, - { EFI_COMPROMISED_DATA, L"Compromised Data" }, - - { EFI_WARN_UNKOWN_GLYPH, L"Warning Unknown Glyph" }, - { EFI_WARN_DELETE_FAILURE, L"Warning Delete Failure" }, - { EFI_WARN_WRITE_FAILURE, L"Warning Write Failure" }, - { EFI_WARN_BUFFER_TOO_SMALL, L"Warning Buffer Too Small" }, - { 0, NULL } +#define STATUS_ERROR(name, num) { uefi::status::name, L#name }, +#define STATUS_WARNING(name, num) { uefi::status::name, L#name }, +#include "uefi/errors.inc" +#undef STATUS_ERROR +#undef STATUS_WARNING + { uefi::status::success, nullptr } }; const wchar_t * -util_error_message(EFI_STATUS status) +util_error_message(uefi::status status) { int32_t i = -1; - while (error_table[++i].name != NULL) { + while (error_table[++i].name != nullptr) { if (error_table[i].code == status) return error_table[i].name; } - if (EFI_ERROR(status)) + if (uefi::is_error(status)) return L"Unknown Error"; else return L"Unknown Warning"; diff --git a/src/boot/utility.h b/src/boot/utility.h index 885a1ef..4bd6ffe 100644 --- a/src/boot/utility.h +++ b/src/boot/utility.h @@ -1,27 +1,27 @@ -#include -#include +#include +#include #include "console.h" #define UNUSED __attribute__((unused)) size_t wstrlen(const wchar_t *s); -const wchar_t *util_error_message(EFI_STATUS status); +const wchar_t *util_error_message(uefi::status status); #define CHECK_EFI_STATUS_OR_RETURN(s, msg, ...) \ - if (EFI_ERROR((s))) { \ + if (uefi::is_error((s))) { \ console::print(L"ERROR: " msg L": %s\r\n", ##__VA_ARGS__, util_error_message(s)); \ return (s); \ } #define CHECK_EFI_STATUS_OR_FAIL(s) \ - if (EFI_ERROR((s))) { \ + if (uefi::is_error((s))) { \ console::get().status_fail(util_error_message(s)); \ while (1) __asm__("hlt"); \ } #define CHECK_EFI_STATUS_OR_ASSERT(s, d) \ - if (EFI_ERROR((s))) { \ + if (uefi::is_error((s))) { \ __asm__ __volatile__( \ "movq %0, %%r8;" \ "movq %1, %%r9;" \