diff --git a/src/boot/console.c b/src/boot/console.c index 2a8943f..86102e1 100644 --- a/src/boot/console.c +++ b/src/boot/console.c @@ -4,6 +4,7 @@ #include #include "console.h" +#include "guids.h" #include "utility.h" size_t ROWS = 0; @@ -22,9 +23,7 @@ con_initialize(EFI_SYSTEM_TABLE *system_table, const CHAR16 *version) con_out = system_table->ConOut; EFI_GRAPHICS_OUTPUT_PROTOCOL *gfx_out_proto; - EFI_GUID gfx_out_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; - - status = bootsvc->LocateProtocol(&gfx_out_guid, NULL, (void **)&gfx_out_proto); + status = bootsvc->LocateProtocol(&guid_gfx_out, NULL, (void **)&gfx_out_proto); CHECK_EFI_STATUS_OR_RETURN(status, "LocateProtocol gfx"); const uint32_t modes = gfx_out_proto->Mode->MaxMode; diff --git a/src/boot/guids.c b/src/boot/guids.c new file mode 100644 index 0000000..ec5d8ca --- /dev/null +++ b/src/boot/guids.c @@ -0,0 +1,13 @@ +#include "guids.h" + +#define GUID(dw, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, name) \ + EFI_GUID name __attribute__((section(".rodata"))) = {dw, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}} +#include "guids.inc" +#undef GUID + +int is_guid(EFI_GUID *a, EFI_GUID *b) +{ + uint64_t *ai = (uint64_t *)a; + uint64_t *bi = (uint64_t *)b; + return ai[0] == bi[0] && ai[1] == bi[1]; +} diff --git a/src/boot/guids.h b/src/boot/guids.h new file mode 100644 index 0000000..970d7a2 --- /dev/null +++ b/src/boot/guids.h @@ -0,0 +1,8 @@ +#pragma once +#include + +int is_guid(EFI_GUID *a, EFI_GUID *b); + +#define GUID(dw, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8, name) extern EFI_GUID name +#include "guids.inc" +#undef GUID diff --git a/src/boot/guids.inc b/src/boot/guids.inc new file mode 100644 index 0000000..8b87a99 --- /dev/null +++ b/src/boot/guids.inc @@ -0,0 +1,7 @@ +GUID(0xeb9d2d30,0x2d88,0x11d3,0x9a,0x16,0x00,0x90,0x27,0x3f,0xc1,0x4d, guid_acpi1); +GUID(0x8868e871,0xe4f1,0x11d3,0xbc,0x22,0x00,0x80,0xc7,0x3c,0x88,0x81, guid_acpi2); +GUID(0x09576e92,0x6d3f,0x11d2,0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b, guid_file_info); +GUID(0x9042a9de,0x23dc,0x4a38,0x96,0xfb,0x7a,0xde,0xd0,0x80,0x51,0x6a, guid_gfx_out); +GUID(0x964e5b22,0x6459,0x11d2,0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b, guid_simple_filesystem); + +// vim: ft=c diff --git a/src/boot/loader.c b/src/boot/loader.c index df55333..c8eed99 100644 --- a/src/boot/loader.c +++ b/src/boot/loader.c @@ -1,3 +1,4 @@ +#include "guids.h" #include "loader.h" #include "utility.h" @@ -18,17 +19,16 @@ loader_load_kernel( CHECK_EFI_STATUS_OR_RETURN(EFI_INVALID_PARAMETER, "NULL kernel_data or length pointer"); EFI_STATUS status; - EFI_GUID guid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID; EFI_HANDLE *handles = NULL; UINTN handleCount = 0; - status = bootsvc->LocateHandleBuffer(ByProtocol, &guid, NULL, &handleCount, &handles); + status = bootsvc->LocateHandleBuffer(ByProtocol, &guid_simple_filesystem, NULL, &handleCount, &handles); CHECK_EFI_STATUS_OR_RETURN(status, "LocateHandleBuffer"); for (unsigned i = 0; i < handleCount; ++i) { EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *fileSystem = NULL; - status = bootsvc->HandleProtocol(handles[i], &guid, (void **)&fileSystem); + status = bootsvc->HandleProtocol(handles[i], &guid_simple_filesystem, (void **)&fileSystem); CHECK_EFI_STATUS_OR_RETURN(status, "HandleProtocol"); EFI_FILE_PROTOCOL *root = NULL; @@ -41,13 +41,12 @@ loader_load_kernel( if (!EFI_ERROR(status)) { void *buffer = NULL; - EFI_GUID file_info_guid = EFI_FILE_INFO_ID; UINTN buffer_size = sizeof(EFI_FILE_INFO) + sizeof(kernel_name); status = bootsvc->AllocatePool(EfiLoaderCode, buffer_size, &buffer); CHECK_EFI_STATUS_OR_RETURN(status, "Allocating kernel file info memory"); - status = file->GetInfo(file, &file_info_guid, &buffer_size, buffer); + status = file->GetInfo(file, &guid_file_info, &buffer_size, buffer); CHECK_EFI_STATUS_OR_RETURN(status, "Getting kernel file info"); buffer_size = ((EFI_FILE_INFO *)buffer)->FileSize; diff --git a/src/boot/main.c b/src/boot/main.c index 108fa44..587190c 100644 --- a/src/boot/main.c +++ b/src/boot/main.c @@ -4,6 +4,7 @@ #include #include "console.h" +#include "guids.h" #include "loader.h" #include "memory.h" #include "utility.h" @@ -44,17 +45,11 @@ struct popcorn_data { EFI_MEMORY_DESCRIPTOR *memory_map; EFI_RUNTIME_SERVICES *runtime; + void *acpi_table; } __attribute__((aligned(_Alignof(EFI_MEMORY_DESCRIPTOR)))); #pragma pack(pop) -int is_guid(EFI_GUID *a, EFI_GUID *b) -{ - uint64_t *ai = (uint64_t *)a; - uint64_t *bi = (uint64_t *)b; - return ai[0] == bi[0] && ai[1] == bi[1]; -} - EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) { @@ -67,14 +62,17 @@ efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) CHECK_EFI_STATUS_OR_RETURN(status, "con_initialize"); // From here on out, we can use CHECK_EFI_STATUS_OR_FAIL instead - EFI_GUID acpi1_guid = ACPI_TABLE_GUID; - EFI_GUID acpi2_guid = {0x8868e871,0xe4f1,0x11d3,{0xbc,0x22,0x00,0x80,0xc7,0x3c,0x88,0x81}}; - - // Find ACPI tables. Ignore ACPI 1.0 if a 2.0 table is found. // + void *acpi_table = NULL; for (size_t i=0; iNumberOfTableEntries; ++i) { EFI_CONFIGURATION_TABLE *efi_table = &system_table->ConfigurationTable[i]; + if (is_guid(&efi_table->VendorGuid, &guid_acpi2)) { + acpi_table = efi_table->VendorTable; + break; + } else if (is_guid(&efi_table->VendorGuid, &guid_acpi1)) { + // Mark a v1 table with the LSB high + acpi_table = (void *)((intptr_t)efi_table->VendorTable | 0x1); } } @@ -126,6 +124,7 @@ efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) data_header->flags = 0; data_header->memory_map = (EFI_MEMORY_DESCRIPTOR *)(data_header + 1); data_header->runtime = system_table->RuntimeServices; + data_header->acpi_table = acpi_table; // Save the memory map and tell the firmware we're taking control. // diff --git a/src/boot/utility.c b/src/boot/utility.c index 9526eee..cadd973 100644 --- a/src/boot/utility.c +++ b/src/boot/utility.c @@ -1,57 +1,62 @@ #include -struct { +struct error_code_desc { EFI_STATUS code; - CHAR16 *desc; -} ErrorCodeTable[] = { - { 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"}, + CHAR16 *name; +}; - // warnings - { 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} -} ; +// 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 } +}; const CHAR16 * util_error_message(EFI_STATUS status) { int32_t i = -1; - while (ErrorCodeTable[++i].desc != NULL) { - if (ErrorCodeTable[i].code == status) return ErrorCodeTable[i].desc; + while (error_table[++i].name != NULL) { + if (error_table[i].code == status) return error_table[i].name; } - return L"Unknown"; + if (EFI_ERROR(status)) + return L"Unknown Error"; + else + return L"Unknown Warning"; }