From 60c75a2a41264e5e07bb4d6b4dedaaf2cf44021e Mon Sep 17 00:00:00 2001 From: anonymix007 <48598263+anonymix007@users.noreply.github.com> Date: Thu, 10 Oct 2024 17:54:13 +0300 Subject: [PATCH 1/8] boot: Add be32toh --- src/boot/efi/util.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h index 50025a34a8..e17402540c 100644 --- a/src/boot/efi/util.h +++ b/src/boot/efi/util.h @@ -188,3 +188,9 @@ static inline bool efi_guid_equal(const EFI_GUID *a, const EFI_GUID *b) { void *find_configuration_table(const EFI_GUID *guid); char16_t *get_extra_dir(const EFI_DEVICE_PATH *file_path); + +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define be32toh(x) __builtin_bswap32(x) +#else +# error "Unexpected byte order in EFI mode?" +#endif From 53443e81763bc495efb40e9a632645d8dfb5ac3d Mon Sep 17 00:00:00 2001 From: anonymix007 <48598263+anonymix007@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:23:42 +0300 Subject: [PATCH 2/8] boot: Add bswap_{16,32} --- src/boot/efi/util.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h index e17402540c..e5f88ec5f0 100644 --- a/src/boot/efi/util.h +++ b/src/boot/efi/util.h @@ -194,3 +194,6 @@ char16_t *get_extra_dir(const EFI_DEVICE_PATH *file_path); #else # error "Unexpected byte order in EFI mode?" #endif + +#define bswap_16(x) __builtin_bswap16(x) +#define bswap_32(x) __builtin_bswap32(x) From 5faaac27fdf2ea4f08b754fcedec4b335ffeb69b Mon Sep 17 00:00:00 2001 From: anonymix007 <48598263+anonymix007@users.noreply.github.com> Date: Sat, 31 Aug 2024 21:31:49 +0300 Subject: [PATCH 3/8] boot: Add EFI_STATUS_IS_ERROR macro --- src/boot/efi/efi.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/boot/efi/efi.h b/src/boot/efi/efi.h index e8217c1836..e1042635b9 100644 --- a/src/boot/efi/efi.h +++ b/src/boot/efi/efi.h @@ -68,6 +68,8 @@ typedef uint64_t EFI_PHYSICAL_ADDRESS; # error Unsupported pointer size #endif +#define EFI_STATUS_IS_ERROR(s) (((s) & EFI_ERROR_MASK) != 0) + #define EFIWARN(s) ((EFI_STATUS) s) #define EFIERR(s) ((EFI_STATUS) (s | EFI_ERROR_MASK)) From 1fcdf22573a7348a121f51e826ce9c6547b11116 Mon Sep 17 00:00:00 2001 From: anonymix007 <48598263+anonymix007@users.noreply.github.com> Date: Sat, 31 Aug 2024 21:34:56 +0300 Subject: [PATCH 4/8] boot: Add xcalloc and xcalloc_multiply --- src/boot/efi/util.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/boot/efi/util.h b/src/boot/efi/util.h index e5f88ec5f0..35f6c80a02 100644 --- a/src/boot/efi/util.h +++ b/src/boot/efi/util.h @@ -2,8 +2,10 @@ #pragma once #include "efi.h" +#include "efi-string.h" #include "log.h" #include "proto/file-io.h" +#include "memory-util-fundamental.h" #include "string-util-fundamental.h" /* This is provided by the linker. */ @@ -31,6 +33,19 @@ static inline void freep(void *p) { _malloc_ _alloc_(1) _returns_nonnull_ _warn_unused_result_ void *xmalloc(size_t size); +_malloc_ _alloc_(1) _returns_nonnull_ _warn_unused_result_ +static inline void *xcalloc(size_t size) { + void *t = xmalloc(size); + memzero(t, size); + return t; +} + +_malloc_ _alloc_(1, 2) _returns_nonnull_ _warn_unused_result_ +static inline void *xcalloc_multiply(size_t n, size_t size) { + assert_se(MUL_ASSIGN_SAFE(&size, n)); + return xcalloc(size); +} + _malloc_ _alloc_(1, 2) _returns_nonnull_ _warn_unused_result_ static inline void *xmalloc_multiply(size_t n, size_t size) { assert_se(MUL_ASSIGN_SAFE(&size, n)); From dd6a37e3353955acd911fe1a225bccf3005a5268 Mon Sep 17 00:00:00 2001 From: anonymix007 <48598263+anonymix007@users.noreply.github.com> Date: Wed, 11 Sep 2024 15:18:05 +0300 Subject: [PATCH 5/8] boot: Move smbios-related functions to a separate file --- src/boot/efi/boot.c | 1 + src/boot/efi/meson.build | 1 + src/boot/efi/smbios.c | 188 +++++++++++++++++++++++++++++++++++++++ src/boot/efi/smbios.h | 8 ++ src/boot/efi/stub.c | 1 + src/boot/efi/vmm.c | 181 +------------------------------------ src/boot/efi/vmm.h | 2 - 7 files changed, 200 insertions(+), 182 deletions(-) create mode 100644 src/boot/efi/smbios.c create mode 100644 src/boot/efi/smbios.h diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index a362f7a93f..a8c7b6881f 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -23,6 +23,7 @@ #include "sbat.h" #include "secure-boot.h" #include "shim.h" +#include "smbios.h" #include "ticks.h" #include "tpm2-pcr.h" #include "uki.h" diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index ce2e798daf..0109793b7a 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -270,6 +270,7 @@ libefi_sources = files( 'random-seed.c', 'secure-boot.c', 'shim.c', + 'smbios.c', 'ticks.c', 'util.c', 'vmm.c', diff --git a/src/boot/efi/smbios.c b/src/boot/efi/smbios.c new file mode 100644 index 0000000000..bea6577635 --- /dev/null +++ b/src/boot/efi/smbios.c @@ -0,0 +1,188 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "efi-string.h" +#include "efivars.h" +#include "proto/device-path.h" +#include "smbios.h" +#include "string-util-fundamental.h" +#include "util.h" + +#define SMBIOS_TABLE_GUID \ + GUID_DEF(0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) +#define SMBIOS3_TABLE_GUID \ + GUID_DEF(0xf2fd1544, 0x9794, 0x4a2c, 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94) + +typedef struct { + uint8_t anchor_string[4]; + uint8_t entry_point_structure_checksum; + uint8_t entry_point_length; + uint8_t major_version; + uint8_t minor_version; + uint16_t max_structure_size; + uint8_t entry_point_revision; + uint8_t formatted_area[5]; + uint8_t intermediate_anchor_string[5]; + uint8_t intermediate_checksum; + uint16_t table_length; + uint32_t table_address; + uint16_t number_of_smbios_structures; + uint8_t smbios_bcd_revision; +} _packed_ SmbiosEntryPoint; + +typedef struct { + uint8_t anchor_string[5]; + uint8_t entry_point_structure_checksum; + uint8_t entry_point_length; + uint8_t major_version; + uint8_t minor_version; + uint8_t docrev; + uint8_t entry_point_revision; + uint8_t reserved; + uint32_t table_maximum_size; + uint64_t table_address; +} _packed_ Smbios3EntryPoint; + +typedef struct { + uint8_t type; + uint8_t length; + uint8_t handle[2]; +} _packed_ SmbiosHeader; + +typedef struct { + SmbiosHeader header; + uint8_t vendor; + uint8_t bios_version; + uint16_t bios_segment; + uint8_t bios_release_date; + uint8_t bios_size; + uint64_t bios_characteristics; + uint8_t bios_characteristics_ext[2]; +} _packed_ SmbiosTableType0; + +typedef struct { + SmbiosHeader header; + uint8_t count; + char contents[]; +} _packed_ SmbiosTableType11; + +static const void *find_smbios_configuration_table(uint64_t *ret_size) { + assert(ret_size); + + const Smbios3EntryPoint *entry3 = find_configuration_table(MAKE_GUID_PTR(SMBIOS3_TABLE)); + if (entry3 && memcmp(entry3->anchor_string, "_SM3_", 5) == 0 && + entry3->entry_point_length <= sizeof(*entry3)) { + *ret_size = entry3->table_maximum_size; + return PHYSICAL_ADDRESS_TO_POINTER(entry3->table_address); + } + + const SmbiosEntryPoint *entry = find_configuration_table(MAKE_GUID_PTR(SMBIOS_TABLE)); + if (entry && memcmp(entry->anchor_string, "_SM_", 4) == 0 && + entry->entry_point_length <= sizeof(*entry)) { + *ret_size = entry->table_length; + return PHYSICAL_ADDRESS_TO_POINTER(entry->table_address); + } + + return NULL; +} + +static const SmbiosHeader *get_smbios_table(uint8_t type, size_t min_size, uint64_t *ret_size_left) { + uint64_t size = 0; + const uint8_t *p = find_smbios_configuration_table(&size); + if (!p) + return NULL; + + for (;;) { + if (size < sizeof(SmbiosHeader)) + return NULL; + + const SmbiosHeader *header = (const SmbiosHeader *) p; + + /* End of table. */ + if (header->type == 127) + return NULL; + + if (size < header->length) + return NULL; + + if (header->type == type) { + /* Table is smaller than the minimum expected size? Refuse */ + if (header->length < min_size) + return NULL; + + if (ret_size_left) + *ret_size_left = size; + return header; /* Yay! */ + } + + /* Skip over formatted area. */ + size -= header->length; + p += header->length; + + /* Special case: if there are no strings appended, we'll see two NUL bytes, skip over them */ + if (size >= 2 && p[0] == 0 && p[1] == 0) { + size -= 2; + p += 2; + continue; + } + + /* Skip over a populated string table. */ + bool first = true; + for (;;) { + const uint8_t *e = memchr(p, 0, size); + if (!e) + return NULL; + + if (!first && e == p) {/* Double NUL byte means we've reached the end of the string table. */ + p++; + size--; + break; + } + + size -= e + 1 - p; + p = e + 1; + first = false; + } + } + + return NULL; +} + +bool smbios_in_hypervisor(void) { + /* Look up BIOS Information (Type 0). */ + const SmbiosTableType0 *type0 = (const SmbiosTableType0 *) get_smbios_table(0, sizeof(SmbiosTableType0), /* left= */ NULL); + if (!type0) + return false; + + /* Bit 4 of 2nd BIOS characteristics extension bytes indicates virtualization. */ + return FLAGS_SET(type0->bios_characteristics_ext[1], 1 << 4); +} + +const char* smbios_find_oem_string(const char *name) { + uint64_t left; + + assert(name); + + const SmbiosTableType11 *type11 = (const SmbiosTableType11 *) get_smbios_table(11, sizeof(SmbiosTableType11), &left); + if (!type11) + return NULL; + + const char *s = type11->contents; + + assert(left >= type11->header.length); /* get_smbios_table() already validated this */ + left -= type11->header.length; + const char *limit = s + left; + + for (const char *p = s; p < limit; ) { + const char *e = memchr(p, 0, limit - p); + if (!e || e == p) /* Double NUL byte means we've reached the end of the OEM strings. */ + break; + + const char *eq = startswith8(p, name); + if (eq && *eq == '=') + return eq + 1; + + p = e + 1; + } + + return NULL; +} diff --git a/src/boot/efi/smbios.h b/src/boot/efi/smbios.h new file mode 100644 index 0000000000..5a05bfff00 --- /dev/null +++ b/src/boot/efi/smbios.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "efi.h" + +bool smbios_in_hypervisor(void); + +const char* smbios_find_oem_string(const char *name); diff --git a/src/boot/efi/stub.c b/src/boot/efi/stub.c index 4df993c5d0..9664c95d57 100644 --- a/src/boot/efi/stub.c +++ b/src/boot/efi/stub.c @@ -17,6 +17,7 @@ #include "sbat.h" #include "secure-boot.h" #include "shim.h" +#include "smbios.h" #include "splash.h" #include "tpm2-pcr.h" #include "uki.h" diff --git a/src/boot/efi/vmm.c b/src/boot/efi/vmm.c index 1d04509a1e..fea4c446c0 100644 --- a/src/boot/efi/vmm.c +++ b/src/boot/efi/vmm.c @@ -10,6 +10,7 @@ #include "efi-string.h" #include "efivars.h" #include "proto/device-path.h" +#include "smbios.h" #include "string-util-fundamental.h" #include "util.h" #include "vmm.h" @@ -135,156 +136,6 @@ static bool cpuid_in_hypervisor(void) { return false; } -#define SMBIOS_TABLE_GUID \ - GUID_DEF(0xeb9d2d31, 0x2d88, 0x11d3, 0x9a, 0x16, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d) -#define SMBIOS3_TABLE_GUID \ - GUID_DEF(0xf2fd1544, 0x9794, 0x4a2c, 0x99, 0x2e, 0xe5, 0xbb, 0xcf, 0x20, 0xe3, 0x94) - -typedef struct { - uint8_t anchor_string[4]; - uint8_t entry_point_structure_checksum; - uint8_t entry_point_length; - uint8_t major_version; - uint8_t minor_version; - uint16_t max_structure_size; - uint8_t entry_point_revision; - uint8_t formatted_area[5]; - uint8_t intermediate_anchor_string[5]; - uint8_t intermediate_checksum; - uint16_t table_length; - uint32_t table_address; - uint16_t number_of_smbios_structures; - uint8_t smbios_bcd_revision; -} _packed_ SmbiosEntryPoint; - -typedef struct { - uint8_t anchor_string[5]; - uint8_t entry_point_structure_checksum; - uint8_t entry_point_length; - uint8_t major_version; - uint8_t minor_version; - uint8_t docrev; - uint8_t entry_point_revision; - uint8_t reserved; - uint32_t table_maximum_size; - uint64_t table_address; -} _packed_ Smbios3EntryPoint; - -typedef struct { - uint8_t type; - uint8_t length; - uint8_t handle[2]; -} _packed_ SmbiosHeader; - -typedef struct { - SmbiosHeader header; - uint8_t vendor; - uint8_t bios_version; - uint16_t bios_segment; - uint8_t bios_release_date; - uint8_t bios_size; - uint64_t bios_characteristics; - uint8_t bios_characteristics_ext[2]; -} _packed_ SmbiosTableType0; - -typedef struct { - SmbiosHeader header; - uint8_t count; - char contents[]; -} _packed_ SmbiosTableType11; - -static const void *find_smbios_configuration_table(uint64_t *ret_size) { - assert(ret_size); - - const Smbios3EntryPoint *entry3 = find_configuration_table(MAKE_GUID_PTR(SMBIOS3_TABLE)); - if (entry3 && memcmp(entry3->anchor_string, "_SM3_", 5) == 0 && - entry3->entry_point_length <= sizeof(*entry3)) { - *ret_size = entry3->table_maximum_size; - return PHYSICAL_ADDRESS_TO_POINTER(entry3->table_address); - } - - const SmbiosEntryPoint *entry = find_configuration_table(MAKE_GUID_PTR(SMBIOS_TABLE)); - if (entry && memcmp(entry->anchor_string, "_SM_", 4) == 0 && - entry->entry_point_length <= sizeof(*entry)) { - *ret_size = entry->table_length; - return PHYSICAL_ADDRESS_TO_POINTER(entry->table_address); - } - - return NULL; -} - -static const SmbiosHeader *get_smbios_table(uint8_t type, size_t min_size, uint64_t *ret_size_left) { - uint64_t size = 0; - const uint8_t *p = find_smbios_configuration_table(&size); - if (!p) - return NULL; - - for (;;) { - if (size < sizeof(SmbiosHeader)) - return NULL; - - const SmbiosHeader *header = (const SmbiosHeader *) p; - - /* End of table. */ - if (header->type == 127) - return NULL; - - if (size < header->length) - return NULL; - - if (header->type == type) { - /* Table is smaller than the minimum expected size? Refuse */ - if (header->length < min_size) - return NULL; - - if (ret_size_left) - *ret_size_left = size; - return header; /* Yay! */ - } - - /* Skip over formatted area. */ - size -= header->length; - p += header->length; - - /* Special case: if there are no strings appended, we'll see two NUL bytes, skip over them */ - if (size >= 2 && p[0] == 0 && p[1] == 0) { - size -= 2; - p += 2; - continue; - } - - /* Skip over a populated string table. */ - bool first = true; - for (;;) { - const uint8_t *e = memchr(p, 0, size); - if (!e) - return NULL; - - if (!first && e == p) {/* Double NUL byte means we've reached the end of the string table. */ - p++; - size--; - break; - } - - size -= e + 1 - p; - p = e + 1; - first = false; - } - } - - return NULL; -} - -static bool smbios_in_hypervisor(void) { - /* Look up BIOS Information (Type 0). */ - const SmbiosTableType0 *type0 = (const SmbiosTableType0 *) get_smbios_table(0, sizeof(SmbiosTableType0), /* left= */ NULL); - if (!type0) - return false; - - /* Bit 4 of 2nd BIOS characteristics extension bytes indicates virtualization. */ - return FLAGS_SET(type0->bios_characteristics_ext[1], 1 << 4); -} - bool in_hypervisor(void) { static int cache = -1; if (cache >= 0) @@ -294,36 +145,6 @@ bool in_hypervisor(void) { return cache; } -const char* smbios_find_oem_string(const char *name) { - uint64_t left; - - assert(name); - - const SmbiosTableType11 *type11 = (const SmbiosTableType11 *) get_smbios_table(11, sizeof(SmbiosTableType11), &left); - if (!type11) - return NULL; - - const char *s = type11->contents; - - assert(left >= type11->header.length); /* get_smbios_table() already validated this */ - left -= type11->header.length; - const char *limit = s + left; - - for (const char *p = s; p < limit; ) { - const char *e = memchr(p, 0, limit - p); - if (!e || e == p) /* Double NUL byte means we've reached the end of the OEM strings. */ - break; - - const char *eq = startswith8(p, name); - if (eq && *eq == '=') - return eq + 1; - - p = e + 1; - } - - return NULL; -} - #if defined(__i386__) || defined(__x86_64__) static uint32_t cpuid_leaf(uint32_t eax, char ret_sig[static 13], bool swapped) { /* zero-init as some queries explicitly require subleaf == 0 */ diff --git a/src/boot/efi/vmm.h b/src/boot/efi/vmm.h index 1d1037b32a..ae9b532767 100644 --- a/src/boot/efi/vmm.h +++ b/src/boot/efi/vmm.h @@ -9,5 +9,3 @@ EFI_STATUS vmm_open(EFI_HANDLE *ret_vmm_dev, EFI_FILE **ret_vmm_dir); bool in_hypervisor(void); bool is_confidential_vm(void); - -const char* smbios_find_oem_string(const char *name); From 4ef4781ff87822a4cfefef10577c6945ab55b2be Mon Sep 17 00:00:00 2001 From: anonymix007 <48598263+anonymix007@users.noreply.github.com> Date: Sat, 31 Aug 2024 21:38:21 +0300 Subject: [PATCH 6/8] boot: Add smbios_populate_raw_info This function will be used to gather information for DeviceTree matching --- src/boot/efi/smbios.c | 62 +++++++++++++++++++++++++++++++++++++++++++ src/boot/efi/smbios.h | 11 ++++++++ 2 files changed, 73 insertions(+) diff --git a/src/boot/efi/smbios.c b/src/boot/efi/smbios.c index bea6577635..997428a9c4 100644 --- a/src/boot/efi/smbios.c +++ b/src/boot/efi/smbios.c @@ -59,6 +59,26 @@ typedef struct { uint8_t bios_characteristics_ext[2]; } _packed_ SmbiosTableType0; +typedef struct { + SmbiosHeader header; + uint8_t manufacturer; + uint8_t product_name; + uint8_t version; + uint8_t serial_number; + EFI_GUID uuid; + uint8_t wake_up_type; + uint8_t sku_number; + uint8_t family; +} _packed_ SmbiosTableType1; + +typedef struct { + SmbiosHeader header; + uint8_t manufacturer; + uint8_t product_name; + uint8_t version; + uint8_t serial_number; +} _packed_ SmbiosTableType2; + typedef struct { SmbiosHeader header; uint8_t count; @@ -186,3 +206,45 @@ const char* smbios_find_oem_string(const char *name) { return NULL; } + +static const char* smbios_get_string(const SmbiosHeader *header, size_t nr, uint64_t left) { + assert(header); + const char *s = (const char *) header; + + /* We assume that get_smbios_table() already validated the header size making some superficial sense */ + assert(left >= header->length); + s += header->length; + left -= header->length; + + size_t index = 1; + for (const char *p = s, *limit = s + left; index <= nr && p < limit; index++) { + const char *e = memchr(p, 0, limit - p); + if (!e || e == p) /* Double NUL byte means we've reached the end of the strings. */ + break; + + if (index == nr) + return p; + + p = e + 1; + } + return NULL; +} + +void smbios_raw_info_populate(RawSmbiosInfo *ret_info) { + assert(ret_info); + uint64_t left; + + const SmbiosTableType1 *type1 = (const SmbiosTableType1 *) get_smbios_table(1, sizeof(SmbiosTableType1), &left); + if (type1) { + ret_info->manufacturer = smbios_get_string(&type1->header, type1->manufacturer, left); + ret_info->product_name = smbios_get_string(&type1->header, type1->product_name, left); + ret_info->product_sku = smbios_get_string(&type1->header, type1->sku_number, left); + ret_info->family = smbios_get_string(&type1->header, type1->family, left); + } + + const SmbiosTableType2 *type2 = (const SmbiosTableType2 *) get_smbios_table(2, sizeof(SmbiosTableType2), &left); + if (type2) { + ret_info->baseboard_manufacturer = smbios_get_string(&type2->header, type2->manufacturer, left); + ret_info->baseboard_product = smbios_get_string(&type2->header, type2->product_name, left); + } +} diff --git a/src/boot/efi/smbios.h b/src/boot/efi/smbios.h index 5a05bfff00..34625c8572 100644 --- a/src/boot/efi/smbios.h +++ b/src/boot/efi/smbios.h @@ -6,3 +6,14 @@ bool smbios_in_hypervisor(void); const char* smbios_find_oem_string(const char *name); + +typedef struct RawSmbiosInfo { + const char *manufacturer; + const char *product_name; + const char *product_sku; + const char *family; + const char *baseboard_product; + const char *baseboard_manufacturer; +} RawSmbiosInfo; + +void smbios_raw_info_populate(RawSmbiosInfo *ret_info); From beb41e3948a4a48535dba728ad1dfdc1e1677bd1 Mon Sep 17 00:00:00 2001 From: anonymix007 <48598263+anonymix007@users.noreply.github.com> Date: Thu, 12 Sep 2024 00:26:34 +0300 Subject: [PATCH 7/8] boot: Add log_info and log_debug --- src/boot/efi/log.c | 7 +++---- src/boot/efi/log.h | 13 ++++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/boot/efi/log.c b/src/boot/efi/log.c index 364471e6a2..8ada8e9d8c 100644 --- a/src/boot/efi/log.c +++ b/src/boot/efi/log.c @@ -2,7 +2,6 @@ #include "log.h" #include "proto/rng.h" -#include "proto/simple-text-io.h" #include "util.h" static unsigned log_count = 0; @@ -32,14 +31,14 @@ void efi_assert(const char *expr, const char *file, unsigned line, const char *f freeze(); } -EFI_STATUS log_internal(EFI_STATUS status, const char *format, ...) { +EFI_STATUS log_internal(EFI_STATUS status, uint8_t text_color, const char *format, ...) { assert(format); int32_t attr = ST->ConOut->Mode->Attribute; if (ST->ConOut->Mode->CursorColumn > 0) ST->ConOut->OutputString(ST->ConOut, (char16_t *) u"\r\n"); - ST->ConOut->SetAttribute(ST->ConOut, EFI_TEXT_ATTR(EFI_LIGHTRED, EFI_BLACK)); + ST->ConOut->SetAttribute(ST->ConOut, EFI_TEXT_ATTR(text_color, EFI_BLACK)); va_list ap; va_start(ap, format); @@ -58,7 +57,7 @@ void log_hexdump(const char16_t *prefix, const void *data, size_t size) { /* Debugging helper — please keep this around, even if not used */ _cleanup_free_ char16_t *hex = hexdump(data, size); - log_internal(EFI_SUCCESS, "%ls[%zu]: %ls", prefix, size, hex); + log_internal(EFI_SUCCESS, EFI_LIGHTRED, "%ls[%zu]: %ls", prefix, size, hex); } #endif diff --git a/src/boot/efi/log.h b/src/boot/efi/log.h index 13f3887b8a..9ea8e1891f 100644 --- a/src/boot/efi/log.h +++ b/src/boot/efi/log.h @@ -2,6 +2,7 @@ #pragma once #include "efi-string.h" +#include "proto/simple-text-io.h" #if defined __has_attribute # if __has_attribute(no_stack_protector) @@ -21,11 +22,13 @@ __attribute__((no_stack_protector, noinline)) void __stack_chk_guard_init(void); _noreturn_ void freeze(void); void log_wait(void); -_gnu_printf_(2, 3) EFI_STATUS log_internal(EFI_STATUS status, const char *format, ...); -#define log_error_status(status, ...) log_internal(status, __VA_ARGS__) -#define log_error(...) log_internal(EFI_INVALID_PARAMETER, __VA_ARGS__) -#define log_oom() log_internal(EFI_OUT_OF_RESOURCES, "Out of memory.") -#define log_trace() log_internal(EFI_SUCCESS, "%s:%i@%s", __FILE__, __LINE__, __func__) +_gnu_printf_(3, 4) EFI_STATUS log_internal(EFI_STATUS status, uint8_t text_color, const char *format, ...); +#define log_debug(...) log_internal(EFI_SUCCESS, EFI_LIGHTGRAY, __VA_ARGS__) +#define log_info(...) log_internal(EFI_SUCCESS, EFI_WHITE, __VA_ARGS__) +#define log_error_status(status, ...) log_internal(status, EFI_LIGHTRED, __VA_ARGS__) +#define log_error(...) log_internal(EFI_INVALID_PARAMETER, EFI_LIGHTRED, __VA_ARGS__) +#define log_oom() log_internal(EFI_OUT_OF_RESOURCES, EFI_LIGHTRED, "Out of memory.") +#define log_trace() log_internal(EFI_SUCCESS, EFI_LIGHTRED, "%s:%i@%s", __FILE__, __LINE__, __func__) #ifdef EFI_DEBUG void log_hexdump(const char16_t *prefix, const void *data, size_t size); From 33af0441781d73325a6e1e8c2ad9ec2743283ac1 Mon Sep 17 00:00:00 2001 From: anonymix007 <48598263+anonymix007@users.noreply.github.com> Date: Thu, 10 Oct 2024 18:35:30 +0300 Subject: [PATCH 8/8] fundamental: Add EFI_GUID userspace definition --- src/fundamental/efi-fundamental.h | 13 +++++++++++ src/shared/efi-api.c | 38 +++++++++++++------------------ 2 files changed, 29 insertions(+), 22 deletions(-) create mode 100644 src/fundamental/efi-fundamental.h diff --git a/src/fundamental/efi-fundamental.h b/src/fundamental/efi-fundamental.h new file mode 100644 index 0000000000..2862932ec9 --- /dev/null +++ b/src/fundamental/efi-fundamental.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#if !SD_BOOT +# include +/* Matches EFI API definition of the same structure for userspace */ +typedef struct { + uint32_t Data1; + uint16_t Data2; + uint16_t Data3; + uint8_t Data4[8]; +} EFI_GUID; +#endif diff --git a/src/shared/efi-api.c b/src/shared/efi-api.c index 3ca33efafb..3b9954be9b 100644 --- a/src/shared/efi-api.c +++ b/src/shared/efi-api.c @@ -5,6 +5,7 @@ #include "alloc-util.h" #include "dirent-util.h" #include "efi-api.h" +#include "efi-fundamental.h" #include "efivars.h" #include "fd-util.h" #include "fileio.h" @@ -523,29 +524,22 @@ bool efi_has_tpm2(void) { #endif -struct efi_guid { - uint32_t u1; - uint16_t u2; - uint16_t u3; - uint8_t u4[8]; -} _packed_; - sd_id128_t efi_guid_to_id128(const void *guid) { - const struct efi_guid *uuid = ASSERT_PTR(guid); /* cast is safe, because struct efi_guid is packed */ + const EFI_GUID *uuid = ASSERT_PTR(guid); /* cast is safe, because struct efi_guid is packed */ sd_id128_t id128; - id128.bytes[0] = (uuid->u1 >> 24) & 0xff; - id128.bytes[1] = (uuid->u1 >> 16) & 0xff; - id128.bytes[2] = (uuid->u1 >> 8) & 0xff; - id128.bytes[3] = uuid->u1 & 0xff; + id128.bytes[0] = (uuid->Data1 >> 24) & 0xff; + id128.bytes[1] = (uuid->Data1 >> 16) & 0xff; + id128.bytes[2] = (uuid->Data1 >> 8) & 0xff; + id128.bytes[3] = uuid->Data1 & 0xff; - id128.bytes[4] = (uuid->u2 >> 8) & 0xff; - id128.bytes[5] = uuid->u2 & 0xff; + id128.bytes[4] = (uuid->Data2 >> 8) & 0xff; + id128.bytes[5] = uuid->Data2 & 0xff; - id128.bytes[6] = (uuid->u3 >> 8) & 0xff; - id128.bytes[7] = uuid->u3 & 0xff; + id128.bytes[6] = (uuid->Data3 >> 8) & 0xff; + id128.bytes[7] = uuid->Data3 & 0xff; - memcpy(&id128.bytes[8], uuid->u4, sizeof(uuid->u4)); + memcpy(&id128.bytes[8], uuid->Data4, sizeof(uuid->Data4)); return id128; } @@ -553,11 +547,11 @@ sd_id128_t efi_guid_to_id128(const void *guid) { void efi_id128_to_guid(sd_id128_t id, void *ret_guid) { assert(ret_guid); - struct efi_guid uuid = { - .u1 = id.bytes[0] << 24 | id.bytes[1] << 16 | id.bytes[2] << 8 | id.bytes[3], - .u2 = id.bytes[4] << 8 | id.bytes[5], - .u3 = id.bytes[6] << 8 | id.bytes[7], + EFI_GUID uuid = { + .Data1 = id.bytes[0] << 24 | id.bytes[1] << 16 | id.bytes[2] << 8 | id.bytes[3], + .Data2 = id.bytes[4] << 8 | id.bytes[5], + .Data3 = id.bytes[6] << 8 | id.bytes[7], }; - memcpy(uuid.u4, id.bytes+8, sizeof(uuid.u4)); + memcpy(uuid.Data4, id.bytes+8, sizeof(uuid.Data4)); memcpy(ret_guid, &uuid, sizeof(uuid)); }