Compare commits

...

10 Commits
tab2 ... loado

Author SHA1 Message Date
Simon Glass
6268c3c145 smbios: Add support for showing table types 16 and 19
In some cases it is useful to find out the location of physical memory,
e.g. so that the memory@ nodes can be correctly set up in the
devicetree. Add support for parsing this information from the SMBIOS
tables.

Series-to: concept
Series-cc: heinrich
Cover-letter:
smbios: Refactor the smbios command and parser
The 'smbios' command has its own code for parsing SMBIOS tables. There
in also lib/smbios-parser.c which parses tables, although only
version 2.

This series moved parsing to lib/ and rationalises the code a little. It
also adds support for a few more tables.

Finally, a hook is added so operation from coreboot can be tested on
ellesmere.
END

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:46 -06:00
Simon Glass
68aea48c74 smbios: coreboot: Update smbios_get_header() to use smbios_info
Use the smbios_info struct in this function, so it can deal with any
version of SMBIOS table.

Also update smbios_update_version_full() to work the same way.

Drop find_next_header() which is now unused.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:46 -06:00
Simon Glass
69f0425961 smbios: Pass smbios_info to smbios_next_table()
At present smbios_next_table() does not support SMBIOS v2 tables. Pass
in the info struct so that it can check for the end of the tables.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:45 -06:00
Simon Glass
31d89f2dac smbios: Create a function to locate the tables
The code in the smbios command is a nice implementation of finding the
tables. It supports both SMBIOS2 and SMBIOS3, which smbios-parser.c does
not.

Move this code over to the library, creating a struct to hold the
result.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:45 -06:00
Simon Glass
00b2d3ea4e smbios: Move some parsing code to smbios-parser.c
The 'smbios' command has some parsing code, as does the SMBIOS parser
in the lib/ directory. Start to unify these by moving over a few
functions.

Require CONFIG_SMBIOS_PARSER to be enabled when using the command.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:45 -06:00
Simon Glass
1ab7ea8419 smbios: Rename smbios_header()
This function has the same name as the struct, which is confusing.
Rename it to smbios_get_header() and update the function comment a
little.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:45 -06:00
Simon Glass
f5576bd01b smbios: x86: Enable command by default
If SMBIOS is enabled on x86, enable the 'smbios' command by default,
so that the tables can be examined.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:45 -06:00
Simon Glass
a63ecb45b7 coreboot: Increase the cyclic limit
This fails in CI sometimes, so increase the limit to 50ms:

 cyclic_run() cyclic function video_init took too long: 20725us vs 5000us max

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 14:48:10 -06:00
Simon Glass
8145d7ea4b hooks: Add ellesmere riscv64_spl board
Add a symlink for this board to the travis-ci board.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 13:06:46 -06:00
Simon Glass
e7408cafdd hooks: ellesmere: Add a coreboot board
Add a coreboot board which can run under QEMU on ellesmere.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-08-15 11:44:52 -06:00
12 changed files with 369 additions and 120 deletions

View File

@@ -55,15 +55,15 @@ static int cb_get_str(struct udevice *dev, int id, size_t size, char *val)
static int cb_detect(struct udevice *dev)
{
struct cb_sysinfo_priv *priv = dev_get_priv(dev);
const struct smbios_entry *smbios;
struct smbios_info info;
int ret;
smbios = smbios_entry(lib_sysinfo.smbios_start,
lib_sysinfo.smbios_size);
if (!smbios)
ret = smbios_locate(lib_sysinfo.smbios_start, &info);
if (ret)
return 0;
priv->bios = smbios_header(smbios, SMBIOS_BIOS_INFORMATION);
priv->system = smbios_header(smbios, SMBIOS_SYSTEM_INFORMATION);
priv->bios = smbios_get_header(&info, SMBIOS_BIOS_INFORMATION);
priv->system = smbios_get_header(&info, SMBIOS_SYSTEM_INFORMATION);
priv->t0 = (struct smbios_type0 *)priv->bios;
priv->t1 = (struct smbios_type1 *)priv->system;

View File

@@ -267,6 +267,7 @@ config CMD_SBI
config CMD_SMBIOS
bool "smbios"
depends on SMBIOS
select SMBIOS_PARSER
help
Display the SMBIOS information.

View File

@@ -6,6 +6,7 @@
*/
#include <command.h>
#include <errno.h>
#include <hexdump.h>
#include <mapmem.h>
#include <smbios.h>
@@ -116,45 +117,46 @@ static const struct str_lookup_table associativity_strings[] = {
{ SMBIOS_CACHE_ASSOC_48WAY, "48-way Set-Associative" },
{ SMBIOS_CACHE_ASSOC_64WAY, "64-way Set-Associative" },
{ SMBIOS_CACHE_ASSOC_20WAY, "20-way Set-Associative" },
};
/**
* smbios_get_string() - get SMBIOS string from table
*
* @table: SMBIOS table
* @index: index of the string
* Return: address of string, may point to empty string
*/
static const char *smbios_get_string(void *table, int index)
{
const char *str = (char *)table +
((struct smbios_header *)table)->length;
static const char fallback[] = "";
static const struct str_lookup_table mem_array_location_strings[] = {
{ 0x01, "Other" },
{ 0x02, "Unknown" },
{ 0x03, "System board or motherboard" },
{ 0x04, "ISA add-on card" },
{ 0x05, "EISA add-on card" },
{ 0x06, "PCI add-on card" },
{ 0x07, "MCA add-on card" },
{ 0x08, "PCMCIA add-on card" },
{ 0x09, "Proprietary add-on card" },
{ 0x0A, "NuBus" },
{ 0xA0, "PC-98/C20 add-on card" },
{ 0xA1, "PC-98/C24 add-on card" },
{ 0xA2, "PC-98/E add-on card" },
{ 0xA3, "PC-98/Local bus add-on card" },
};
if (!index)
return fallback;
static const struct str_lookup_table mem_array_use_strings[] = {
{ 0x01, "Other" },
{ 0x02, "Unknown" },
{ 0x03, "System memory" },
{ 0x04, "Video memory" },
{ 0x05, "Flash memory" },
{ 0x06, "Non-volatile RAM" },
{ 0x07, "Cache memory" },
};
if (!*str)
++str;
for (--index; *str && index; --index)
str += strlen(str) + 1;
static const struct str_lookup_table mem_err_corr_strings[] = {
{ 0x01, "Other" },
{ 0x02, "Unknown" },
{ 0x03, "None" },
{ 0x04, "Parity" },
{ 0x05, "Single-bit ECC" },
{ 0x06, "Multi-bit ECC" },
{ 0x07, "CRC" },
};
return str;
}
static struct smbios_header *next_table(struct smbios_header *table)
{
const char *str;
if (table->type == SMBIOS_END_OF_TABLE)
return NULL;
str = smbios_get_string(table, -1);
return (struct smbios_header *)(++str);
}
static void smbios_print_generic(struct smbios_header *table)
static void smbios_print_generic(const struct smbios_header *table)
{
char *str = (char *)table + table->length;
@@ -403,6 +405,62 @@ static void smbios_print_type7(struct smbios_type7 *table)
printf("\tInstalled Cache Size 2: 0x%08x\n", table->inst_size2.data);
}
static void smbios_print_type16(struct smbios_type16 *table)
{
u64 capacity;
printf("Physical Memory Array\n");
smbios_print_lookup_str(mem_array_location_strings, table->location,
ARRAY_SIZE(mem_array_location_strings),
"Location");
smbios_print_lookup_str(mem_array_use_strings, table->use,
ARRAY_SIZE(mem_array_use_strings), "Use");
smbios_print_lookup_str(mem_err_corr_strings, table->error_correction,
ARRAY_SIZE(mem_err_corr_strings),
"Error Correction");
capacity = table->maximum_capacity;
if (capacity == 0x7fffffff &&
table->hdr.length >= offsetof(struct smbios_type16,
extended_maximum_capacity)) {
capacity = table->extended_maximum_capacity;
printf("\tMaximum Capacity: %llu GB\n", capacity >> 30);
} else if (capacity > 0) {
printf("\tMaximum Capacity: %llu MB\n", capacity >> 10);
} else {
printf("\tMaximum Capacity: No limit\n");
}
printf("\tError Information Handle: 0x%04x\n",
table->error_information_handle);
printf("\tNumber Of Devices: %u\n", table->number_of_memory_devices);
}
static void smbios_print_type19(struct smbios_type19 *table)
{
u64 start_addr, end_addr;
printf("Memory Array Mapped Address\n");
/* Check if extended address fields are present (SMBIOS v2.7+) */
if (table->hdr.length >= 0x1f) {
start_addr = table->extended_starting_address;
end_addr = table->extended_ending_address;
} else {
start_addr = table->starting_address;
end_addr = table->ending_address;
}
/* The ending address is the address of the last 1KB block */
if (end_addr != 0xffffffff && end_addr != 0xffffffffffffffff)
end_addr = (end_addr + 1) * 1024 - 1;
printf("\tStarting Address: 0x%016llx\n", start_addr);
printf("\tEnding Address: 0x%016llx\n", end_addr);
printf("\tMemory Array Handle: 0x%04x\n", table->memory_array_handle);
printf("\tPartition Width: %u\n", table->partition_width);
}
static void smbios_print_type127(struct smbios_type127 *table)
{
printf("End Of Table\n");
@@ -411,55 +469,31 @@ static void smbios_print_type127(struct smbios_type127 *table)
static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc,
char *const argv[])
{
ulong addr;
void *entry;
u32 size;
char version[12];
struct smbios_header *table;
static const char smbios_sig[] = "_SM_";
static const char smbios3_sig[] = "_SM3_";
size_t count = 0;
u32 table_maximum_size;
struct smbios_info info;
int ret;
addr = gd_smbios_start();
if (!addr) {
ret = smbios_locate(gd_smbios_start(), &info);
if (ret == -ENOENT) {
log_warning("SMBIOS not available\n");
return CMD_RET_FAILURE;
}
entry = map_sysmem(addr, 0);
if (!memcmp(entry, smbios3_sig, sizeof(smbios3_sig) - 1)) {
struct smbios3_entry *entry3 = entry;
table = (void *)(uintptr_t)entry3->struct_table_address;
snprintf(version, sizeof(version), "%d.%d.%d",
entry3->major_ver, entry3->minor_ver, entry3->doc_rev);
table = (void *)(uintptr_t)entry3->struct_table_address;
size = entry3->length;
table_maximum_size = entry3->table_maximum_size;
} else if (!memcmp(entry, smbios_sig, sizeof(smbios_sig) - 1)) {
struct smbios_entry *entry2 = entry;
snprintf(version, sizeof(version), "%d.%d",
entry2->major_ver, entry2->minor_ver);
table = (void *)(uintptr_t)entry2->struct_table_address;
size = entry2->length;
table_maximum_size = entry2->struct_table_length;
} else {
if (ret == -EINVAL) {
log_err("Unknown SMBIOS anchor format\n");
return CMD_RET_FAILURE;
}
if (table_compute_checksum(entry, size)) {
if (ret == -EIO) {
log_err("Invalid anchor checksum\n");
return CMD_RET_FAILURE;
}
printf("SMBIOS %s present.\n", version);
printf("SMBIOS %d.%d.%d present.\n", info.version >> 16,
(info.version >> 8) & 0xff, info.version & 0xff);
for (struct smbios_header *pos = table; pos; pos = next_table(pos))
++count;
printf("%zd structures occupying %d bytes\n", count, table_maximum_size);
printf("Table at 0x%llx\n", (unsigned long long)map_to_sysmem(table));
printf("%d structures occupying %d bytes\n", info.count, info.max_size);
printf("Table at 0x%llx\n",
(unsigned long long)map_to_sysmem(info.table));
for (struct smbios_header *pos = table; pos; pos = next_table(pos)) {
for (struct smbios_header *pos = info.table; pos;
pos = smbios_next_table(&info, pos)) {
printf("\nHandle 0x%04x, DMI type %d, %d bytes at 0x%llx\n",
pos->handle, pos->type, pos->length,
(unsigned long long)map_to_sysmem(pos));
@@ -482,6 +516,12 @@ static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc,
case SMBIOS_CACHE_INFORMATION:
smbios_print_type7((struct smbios_type7 *)pos);
break;
case SMBIOS_PHYS_MEMORY_ARRAY:
smbios_print_type16((struct smbios_type16 *)pos);
break;
case SMBIOS_MEMORY_ARRAY_MAPPED_ADDRESS:
smbios_print_type19((struct smbios_type19 *)pos);
break;
case SMBIOS_END_OF_TABLE:
smbios_print_type127((struct smbios_type127 *)pos);
break;

View File

@@ -32,6 +32,7 @@ CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_MISC_INIT_R=y
CONFIG_HUSH_PARSER=y
CONFIG_CMD_CPU=y
# CONFIG_CMD_SMBIOS is not set
CONFIG_CMD_GPIO=y
CONFIG_CMD_PART=y
CONFIG_CMD_SPI=y

View File

@@ -23,6 +23,7 @@ CONFIG_LOG=y
CONFIG_LOGF_LINE=y
CONFIG_LOGF_FUNC=y
CONFIG_DISPLAY_BOARDINFO_LATE=y
CONFIG_CYCLIC_MAX_CPU_TIME_US=50000
CONFIG_PCI_INIT_R=y
CONFIG_CMD_IDE=y
CONFIG_CMD_MMC=y

View File

@@ -15,6 +15,23 @@
#define SMBIOS_MAJOR_VER 3
#define SMBIOS_MINOR_VER 7
/**
* struct smbios_info - Information about SMBIOS tables
*
* @table: Pointer to the first table
* @count: Number of tables
* @max_size: Maximum size of the tables pointed to by struct_table_address
* @version: table version in the form 0xMMmmrr, where MM is the major version
* number (2 or 3), mm is the minor version number and rr is * the revision
* (always 0 for major-version 2)
*/
struct smbios_info {
struct smbios_header *table;
int count;
int max_size;
int version;
};
enum {
SMBIOS_STR_MAX = 64, /* Maximum length allowed for a string */
};
@@ -264,6 +281,31 @@ struct __packed smbios_type7 {
char eos[SMBIOS_STRUCT_EOS_BYTES];
};
struct __packed smbios_type16 {
struct smbios_header hdr;
u8 location;
u8 use;
u8 error_correction;
u32 maximum_capacity;
u16 error_information_handle;
u16 number_of_memory_devices;
/* The following field is only present in SMBIOS v2.7+ */
u64 extended_maximum_capacity;
char eos[SMBIOS_STRUCT_EOS_BYTES];
};
struct __packed smbios_type19 {
struct smbios_header hdr;
u32 starting_address;
u32 ending_address;
u16 memory_array_handle;
u8 partition_width;
/* The following fields are only present in SMBIOS v2.7+ */
u64 extended_starting_address;
u64 extended_ending_address;
char eos[SMBIOS_STRUCT_EOS_BYTES];
};
struct __packed smbios_type32 {
u8 type;
u8 length;
@@ -325,13 +367,14 @@ ulong write_smbios_table(ulong addr);
const struct smbios_entry *smbios_entry(u64 address, u32 size);
/**
* smbios_header() - Search for SMBIOS header type
* smbios_get_header() - Search for an SMBIOS header type
*
* @entry: pointer to a struct smbios_entry
* @entry: pointer to the first entry
* @type: SMBIOS type
* @return: NULL or a valid pointer to a struct smbios_header
*/
const struct smbios_header *smbios_header(const struct smbios_entry *entry, int type);
const struct smbios_header *smbios_get_header(const struct smbios_info *info,
int type);
/**
* smbios_string() - Return string from SMBIOS
@@ -379,8 +422,39 @@ int smbios_update_version_full(void *smbios_tab, const char *version);
*
* @entry: pointer to a struct smbios3_entry
* @header: pointer to a struct smbios_header
* @table_maximum_size: number of bytes used by the tables at @header
*/
void smbios_prepare_measurement(const struct smbios3_entry *entry,
struct smbios_header *header);
struct smbios_header *smbios_copy,
int table_maximum_size);
/**
* smbios_get_string() - get SMBIOS string from table
*
* @table: SMBIOS table
* @index: index of the string
* Return: address of string, may point to empty string
*/
const char *smbios_get_string(void *table, int index);
/**
* smbios_next_table() - Find the next table
*
* @info: SMBIOS info
* @table: Table to start from
* Return: Pointer to the next table, or NULL if @table is the last
*/
struct smbios_header *smbios_next_table(const struct smbios_info *info,
struct smbios_header *table);
/**
* smbios_locate() - Locate the SMBIOS tables
*
* @addr: Address of SMBIOS table, typically gd_smbios_start()
* @info: Returns the SMBIOS info, on success
* Return: 0 if OK, -ENOENT if no table is present, -EINVAL if the header
* signature is not recognised, -EIO if the checksum is wrong
*/
int smbios_locate(ulong addr, struct smbios_info *info);
#endif /* _SMBIOS_H_ */

View File

@@ -191,4 +191,38 @@
#define SMBIOS_CACHE_ASSOC_64WAY 13
#define SMBIOS_CACHE_ASSOC_20WAY 14
/* Physical Memory Array */
#define SMBIOS_MEM_ARRAY_LOCATION_OTHER 0x01
#define SMBIOS_MEM_ARRAY_LOCATION_UNKNOWN 0x02
#define SMBIOS_MEM_ARRAY_LOCATION_SYSTEM_BOARD 0x03
#define SMBIOS_MEM_ARRAY_LOCATION_ISA_ADDON 0x04
#define SMBIOS_MEM_ARRAY_LOCATION_EISA_ADDON 0x05
#define SMBIOS_MEM_ARRAY_LOCATION_PCI_ADDON 0x06
#define SMBIOS_MEM_ARRAY_LOCATION_MCA_ADDON 0x07
#define SMBIOS_MEM_ARRAY_LOCATION_PCMCIA_ADDON 0x08
#define SMBIOS_MEM_ARRAY_LOCATION_PROPRIETARY_ADDON 0x09
#define SMBIOS_MEM_ARRAY_LOCATION_NUBUS 0x0a
#define SMBIOS_MEM_ARRAY_LOCATION_PC98_C20_ADDON 0xa0
#define SMBIOS_MEM_ARRAY_LOCATION_PC98_C24_ADDON 0xa1
#define SMBIOS_MEM_ARRAY_LOCATION_PC98_E_ADDON 0xa2
#define SMBIOS_MEM_ARRAY_LOCATION_PC98_LOCAL_BUS_ADDON 0xa3
#define SMBIOS_MEM_ARRAY_USE_OTHER 0x01
#define SMBIOS_MEM_ARRAY_USE_UNKNOWN 0x02
#define SMBIOS_MEM_ARRAY_USE_SYSTEM 0x03
#define SMBIOS_MEM_ARRAY_USE_VIDEO 0x04
#define SMBIOS_MEM_ARRAY_USE_FLASH 0x05
#define SMBIOS_MEM_ARRAY_USE_NON_VOLATILE_RAM 0x06
#define SMBIOS_MEM_ARRAY_USE_CACHE 0x07
#define SMBIOS_MEM_ERR_CORR_OTHER 0x01
#define SMBIOS_MEM_ERR_CORR_UNKNOWN 0x02
#define SMBIOS_MEM_ERR_CORR_NONE 0x03
#define SMBIOS_MEM_ERR_CORR_PARITY 0x04
#define SMBIOS_MEM_ERR_CORR_SINGLE_BIT_ECC 0x05
#define SMBIOS_MEM_ERR_CORR_MULTI_BIT_ECC 0x06
#define SMBIOS_MEM_ERR_CORR_CRC 0x07
#define SMBIOS_MEM_CAPACITY_EXTENDED 0x80000000
#endif /* _SMBIOS_DEF_H_ */

View File

@@ -1171,6 +1171,7 @@ config SMBIOS
depends on X86 || EFI_LOADER
default y
select LAST_STAGE_INIT
imply CMD_SMBIOS if X86
help
Indicates that this platform can support System Management BIOS
(SMBIOS) tables. These provide various pieces of information about

View File

@@ -1127,7 +1127,8 @@ tcg2_measure_smbios(struct udevice *dev,
(void *)((uintptr_t)entry->struct_table_address),
entry->table_maximum_size);
smbios_prepare_measurement(entry, smbios_copy);
smbios_prepare_measurement(entry, smbios_copy,
entry->table_maximum_size);
ret = measure_event(dev, 1, EV_EFI_HANDOFF_TABLES2, event_size,
(u8 *)event);

View File

@@ -6,11 +6,46 @@
#define LOG_CATEGORY LOGC_BOOT
#include <errno.h>
#include <mapmem.h>
#include <smbios.h>
#include <string.h>
#include <tables_csum.h>
#include <asm/global_data.h>
#include <linux/kernel.h>
DECLARE_GLOBAL_DATA_PTR;
const char *smbios_get_string(void *table, int index)
{
const char *str = (char *)table +
((struct smbios_header *)table)->length;
static const char fallback[] = "";
if (!index)
return fallback;
if (!*str)
++str;
for (--index; *str && index; --index)
str += strlen(str) + 1;
return str;
}
struct smbios_header *smbios_next_table(const struct smbios_info *info,
struct smbios_header *table)
{
const char *str;
if ((ulong)table - (ulong)info->table >= info->max_size)
return NULL;
if (table->type == SMBIOS_END_OF_TABLE)
return NULL;
str = smbios_get_string(table, -1);
return (struct smbios_header *)(++str);
}
const struct smbios_entry *smbios_entry(u64 address, u32 size)
{
const struct smbios_entry *entry = (struct smbios_entry *)(uintptr_t)address;
@@ -27,35 +62,17 @@ const struct smbios_entry *smbios_entry(u64 address, u32 size)
return entry;
}
static u8 *find_next_header(u8 *pos)
const struct smbios_header *smbios_get_header(const struct smbios_info *info,
int type)
{
/* search for _double_ NULL bytes */
while (!((*pos == 0) && (*(pos + 1) == 0)))
pos++;
struct smbios_header *header;
/* step behind the double NULL bytes */
pos += 2;
return pos;
}
static struct smbios_header *get_next_header(const struct smbios_header *curr)
{
u8 *pos = ((u8 *)curr) + curr->length;
return (struct smbios_header *)find_next_header(pos);
}
const struct smbios_header *smbios_header(const struct smbios_entry *entry, int type)
{
const unsigned int num_header = entry->struct_count;
const struct smbios_header *header = (struct smbios_header *)((uintptr_t)entry->struct_table_address);
for (unsigned int i = 0; i < num_header; i++) {
for (header = info->table; header;
header = smbios_next_table(info, header)) {
if (header->type == type)
return header;
header = get_next_header(header);
header = smbios_next_table(info, header);
}
return NULL;
@@ -90,15 +107,21 @@ char *smbios_string(const struct smbios_header *header, int index)
return string_from_smbios_table(header, index);
}
int smbios_update_version_full(void *smbios_tab, const char *version)
int smbios_update_version_full(void *smbios_tab, const char *new_version)
{
const struct smbios_header *hdr;
struct smbios_info info;
struct smbios_type0 *bios;
uint old_len, len;
char *ptr;
int ret;
ret = smbios_locate(map_to_sysmem(smbios_tab), &info);
if (ret)
return log_msg_ret("tab", -ENOENT);
log_info("Updating SMBIOS table at %p\n", smbios_tab);
hdr = smbios_header(smbios_tab, SMBIOS_BIOS_INFORMATION);
hdr = smbios_get_header(&info, SMBIOS_BIOS_INFORMATION);
if (!hdr)
return log_msg_ret("tab", -ENOENT);
bios = (struct smbios_type0 *)hdr;
@@ -113,12 +136,12 @@ int smbios_update_version_full(void *smbios_tab, const char *version)
* are not disturbed. See smbios_add_string()
*/
old_len = strnlen(ptr, SMBIOS_STR_MAX);
len = strnlen(version, SMBIOS_STR_MAX);
len = strnlen(new_version, SMBIOS_STR_MAX);
if (len > old_len)
return log_ret(-ENOSPC);
log_debug("Replacing SMBIOS type 0 version string '%s'\n", ptr);
memcpy(ptr, version, len);
memcpy(ptr, new_version, len);
#ifdef LOG_DEBUG
print_buffer((ulong)ptr, ptr, 1, old_len + 1, 0);
#endif
@@ -224,23 +247,26 @@ static void clear_smbios_table(struct smbios_header *header,
}
void smbios_prepare_measurement(const struct smbios3_entry *entry,
struct smbios_header *smbios_copy)
struct smbios_header *smbios_copy,
int table_maximum_size)
{
u32 i, j;
void *table_end;
struct smbios_header *header;
struct smbios_info info;
u32 i;
table_end = (void *)((u8 *)smbios_copy + entry->table_maximum_size);
info.table = smbios_copy;
info.count = 0; /* unknown */
info.max_size = table_maximum_size;
info.version = 3 << 16;
for (i = 0; i < ARRAY_SIZE(smbios_filter_tables); i++) {
header = smbios_copy;
for (j = 0; (void *)header < table_end; j++) {
struct smbios_header *header;
for (header = info.table; header;
header = smbios_next_table(&info, header)) {
if (header->type == smbios_filter_tables[i].type)
break;
header = get_next_header(header);
}
if ((void *)header >= table_end)
if (!header)
continue;
clear_smbios_table(header,
@@ -248,3 +274,44 @@ void smbios_prepare_measurement(const struct smbios3_entry *entry,
smbios_filter_tables[i].count);
}
}
int smbios_locate(ulong addr, struct smbios_info *info)
{
static const char smbios3_sig[] = "_SM3_";
static const char smbios_sig[] = "_SM_";
void *entry;
uint size;
if (!addr)
return -ENOENT;
entry = map_sysmem(addr, 0);
if (!memcmp(entry, smbios3_sig, sizeof(smbios3_sig) - 1)) {
struct smbios3_entry *entry3 = entry;
info->table = (void *)(uintptr_t)entry3->struct_table_address;
info->version = entry3->major_ver << 16 |
entry3->minor_ver << 8 | entry3->doc_rev;
size = entry3->length;
info->max_size = entry3->table_maximum_size;
} else if (!memcmp(entry, smbios_sig, sizeof(smbios_sig) - 1)) {
struct smbios_entry *entry2 = entry;
info->version = entry2->major_ver << 16 |
entry2->minor_ver << 8;
info->table = (void *)(uintptr_t)entry2->struct_table_address;
size = entry2->length;
info->max_size = entry2->struct_table_length;
} else {
return -EINVAL;
}
if (table_compute_checksum(entry, size))
return -EIO;
info->count = 0;
for (struct smbios_header *pos = info->table; pos;
pos = smbios_next_table(info, pos))
info->count++;
return 0;
}

View File

@@ -0,0 +1,28 @@
# Copyright (c) 2016 Konsulko Group. All rights reserved.
# Copyright 2021 Google LLC
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.
console_impl=qemu
qemu_machine="pc"
qemu_binary="qemu-system-i386"
qemu_extra_args="-nographic -cpu qemu32 -netdev user,id=net0,tftp=${UBOOT_TRAVIS_BUILD_DIR} -device e1000,netdev=net0"
qemu_kernel_args="-bios ${U_BOOT_BUILD_DIR}/coreboot.rom"
reset_impl=none
flash_impl=none

View File

@@ -0,0 +1 @@
../travis-ci/conf.qemu-riscv64_spl_na