From: anonymix007 <48598263+anonymix007@users.noreply.github.com> Date: Sat, 31 Aug 2024 18:38:21 +0000 (+0300) Subject: boot: Add smbios_populate_raw_info X-Git-Tag: v257-rc1~254^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4ef4781ff87822a4cfefef10577c6945ab55b2be;p=thirdparty%2Fsystemd.git boot: Add smbios_populate_raw_info This function will be used to gather information for DeviceTree matching --- diff --git a/src/boot/efi/smbios.c b/src/boot/efi/smbios.c index bea6577635f..997428a9c48 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 5a05bfff00e..34625c85726 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);