mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-13 15:03:58 +03:00
smbios: add detailed smbios information
Add detailed SMBIOS information as following: 1. Missing fields in Type #3 and #4 2. Type #7 Add support to dynamic length of contained object handles and elements. As SMBIOS is a fundamental feature which is enabled for all boards, in order to avoid increasing rom size, all detailed SMBIOS information is under kconfig GENERATE_SMBIOS_TABLE_VERBOSE. Board maintainers can determine whether to select this feature. Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
This commit is contained in:
203
lib/smbios.c
203
lib/smbios.c
@@ -528,6 +528,8 @@ static int smbios_write_type3(ulong *current, int handle,
|
|||||||
int len = sizeof(*t);
|
int len = sizeof(*t);
|
||||||
u8 *eos_addr;
|
u8 *eos_addr;
|
||||||
size_t elem_size = 0;
|
size_t elem_size = 0;
|
||||||
|
__maybe_unused u8 *elem_addr;
|
||||||
|
__maybe_unused u8 *sku_num_addr;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* reserve the space for the dynamic bytes of contained elements.
|
* reserve the space for the dynamic bytes of contained elements.
|
||||||
@@ -540,7 +542,10 @@ static int smbios_write_type3(ulong *current, int handle,
|
|||||||
t = map_sysmem(*current, len);
|
t = map_sysmem(*current, len);
|
||||||
memset(t, 0, len);
|
memset(t, 0, len);
|
||||||
fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle);
|
fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle);
|
||||||
|
#if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE_VERBOSE)
|
||||||
|
elem_addr = (u8 *)t + offsetof(struct smbios_type3, sku_number);
|
||||||
|
sku_num_addr = elem_addr + elem_size;
|
||||||
|
#endif
|
||||||
/* eos is at the end of the structure */
|
/* eos is at the end of the structure */
|
||||||
eos_addr = (u8 *)t + len - sizeof(t->eos);
|
eos_addr = (u8 *)t + len - sizeof(t->eos);
|
||||||
smbios_set_eos(ctx, eos_addr);
|
smbios_set_eos(ctx, eos_addr);
|
||||||
@@ -564,6 +569,32 @@ static int smbios_write_type3(ulong *current, int handle,
|
|||||||
SYSID_SM_ENCLOSURE_SECURITY,
|
SYSID_SM_ENCLOSURE_SECURITY,
|
||||||
SMBIOS_SECURITY_UNKNOWN);
|
SMBIOS_SECURITY_UNKNOWN);
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE_VERBOSE)
|
||||||
|
t->version = smbios_add_prop_si(ctx, "version",
|
||||||
|
SYSID_SM_ENCLOSURE_VERSION, NULL);
|
||||||
|
t->serial_number = smbios_add_prop_si(ctx, "serial",
|
||||||
|
SYSID_SM_ENCLOSURE_SERIAL, NULL);
|
||||||
|
t->asset_tag_number = smbios_add_prop_si(ctx, "asset-tag",
|
||||||
|
SYSID_SM_BASEBOARD_ASSET_TAG,
|
||||||
|
NULL);
|
||||||
|
t->oem_defined = smbios_get_val_si(ctx, "oem-defined",
|
||||||
|
SYSID_SM_ENCLOSURE_OEM, 0);
|
||||||
|
t->height = smbios_get_val_si(ctx, "height",
|
||||||
|
SYSID_SM_ENCLOSURE_HEIGHT, 0);
|
||||||
|
t->number_of_power_cords =
|
||||||
|
smbios_get_val_si(ctx, "number-of-power-cords",
|
||||||
|
SYSID_SM_ENCLOSURE_POWCORE_NUM, 0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Populate the Contained Element Record if they exist
|
||||||
|
* t->element_count = <element_num>;
|
||||||
|
* t->element_record_length = <element_len>;
|
||||||
|
*/
|
||||||
|
|
||||||
|
*sku_num_addr = smbios_add_prop_si(ctx, "sku", SYSID_SM_ENCLOSURE_SKU,
|
||||||
|
NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
len = t->hdr.length + smbios_string_table_len(ctx);
|
len = t->hdr.length + smbios_string_table_len(ctx);
|
||||||
*current += len;
|
*current += len;
|
||||||
unmap_sysmem(t);
|
unmap_sysmem(t);
|
||||||
@@ -577,6 +608,8 @@ static void smbios_write_type4_dm(struct smbios_type4 *t,
|
|||||||
u16 processor_family = SMBIOS_PROCESSOR_FAMILY_UNKNOWN;
|
u16 processor_family = SMBIOS_PROCESSOR_FAMILY_UNKNOWN;
|
||||||
const char *vendor = NULL;
|
const char *vendor = NULL;
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
|
__maybe_unused void *id_data = NULL;
|
||||||
|
__maybe_unused size_t id_size = 0;
|
||||||
|
|
||||||
#ifdef CONFIG_CPU
|
#ifdef CONFIG_CPU
|
||||||
char processor_name[49];
|
char processor_name[49];
|
||||||
@@ -617,6 +650,16 @@ static void smbios_write_type4_dm(struct smbios_type4 *t,
|
|||||||
t->processor_version = smbios_add_prop_si(ctx, "version",
|
t->processor_version = smbios_add_prop_si(ctx, "version",
|
||||||
SYSID_SM_PROCESSOR_VERSION,
|
SYSID_SM_PROCESSOR_VERSION,
|
||||||
name);
|
name);
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE_VERBOSE)
|
||||||
|
if (t->processor_id[0] || t->processor_id[1] ||
|
||||||
|
sysinfo_get_data(ctx->dev, SYSID_SM_PROCESSOR_ID, &id_data,
|
||||||
|
&id_size))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (id_data && id_size == sizeof(t->processor_id))
|
||||||
|
memcpy((u8 *)t->processor_id, id_data, id_size);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int smbios_write_type4(ulong *current, int handle,
|
static int smbios_write_type4(ulong *current, int handle,
|
||||||
@@ -624,6 +667,8 @@ static int smbios_write_type4(ulong *current, int handle,
|
|||||||
{
|
{
|
||||||
struct smbios_type4 *t;
|
struct smbios_type4 *t;
|
||||||
int len = sizeof(*t);
|
int len = sizeof(*t);
|
||||||
|
__maybe_unused void *hdl;
|
||||||
|
__maybe_unused size_t hdl_size;
|
||||||
|
|
||||||
t = map_sysmem(*current, len);
|
t = map_sysmem(*current, len);
|
||||||
memset(t, 0, len);
|
memset(t, 0, len);
|
||||||
@@ -647,6 +692,60 @@ static int smbios_write_type4(ulong *current, int handle,
|
|||||||
t->l2_cache_handle = SMBIOS_CACHE_HANDLE_NONE;
|
t->l2_cache_handle = SMBIOS_CACHE_HANDLE_NONE;
|
||||||
t->l3_cache_handle = SMBIOS_CACHE_HANDLE_NONE;
|
t->l3_cache_handle = SMBIOS_CACHE_HANDLE_NONE;
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE_VERBOSE)
|
||||||
|
t->voltage = smbios_get_val_si(ctx, "voltage",
|
||||||
|
SYSID_SM_PROCESSOR_VOLTAGE, 0);
|
||||||
|
t->external_clock = smbios_get_val_si(ctx, "external-clock",
|
||||||
|
SYSID_SM_PROCESSOR_EXT_CLOCK, 0);
|
||||||
|
t->max_speed = smbios_get_val_si(ctx, "max-speed",
|
||||||
|
SYSID_SM_PROCESSOR_MAX_SPEED, 0);
|
||||||
|
t->current_speed = smbios_get_val_si(ctx, "current-speed",
|
||||||
|
SYSID_SM_PROCESSOR_CUR_SPEED, 0);
|
||||||
|
|
||||||
|
/* Read the cache handles */
|
||||||
|
if (!sysinfo_get_data(ctx->dev, SYSID_SM_CACHE_HANDLE, &hdl,
|
||||||
|
&hdl_size) &&
|
||||||
|
(hdl_size == SYSINFO_CACHE_LVL_MAX * sizeof(u16))) {
|
||||||
|
u16 *handle = (u16 *)hdl;
|
||||||
|
|
||||||
|
if (*handle)
|
||||||
|
t->l1_cache_handle = *handle;
|
||||||
|
|
||||||
|
handle++;
|
||||||
|
if (*handle)
|
||||||
|
t->l2_cache_handle = *handle;
|
||||||
|
|
||||||
|
handle++;
|
||||||
|
if (*handle)
|
||||||
|
t->l3_cache_handle = *handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
t->serial_number = smbios_add_prop_si(ctx, "serial",
|
||||||
|
SYSID_SM_PROCESSOR_SN, NULL);
|
||||||
|
t->asset_tag = smbios_add_prop_si(ctx, "asset-tag",
|
||||||
|
SYSID_SM_PROCESSOR_ASSET_TAG, NULL);
|
||||||
|
t->part_number = smbios_add_prop_si(ctx, "part-number",
|
||||||
|
SYSID_SM_PROCESSOR_PN, NULL);
|
||||||
|
t->core_count = smbios_get_val_si(ctx, "core-count",
|
||||||
|
SYSID_SM_PROCESSOR_CORE_CNT, 0);
|
||||||
|
t->core_enabled = smbios_get_val_si(ctx, "core-enabled",
|
||||||
|
SYSID_SM_PROCESSOR_CORE_EN, 0);
|
||||||
|
t->thread_count = smbios_get_val_si(ctx, "thread-count",
|
||||||
|
SYSID_SM_PROCESSOR_THREAD_CNT, 0);
|
||||||
|
t->processor_characteristics =
|
||||||
|
smbios_get_val_si(ctx, "characteristics",
|
||||||
|
SYSID_SM_PROCESSOR_CHARA,
|
||||||
|
SMBIOS_PROCESSOR_UND);
|
||||||
|
t->core_count2 = smbios_get_val_si(ctx, "core-count2",
|
||||||
|
SYSID_SM_PROCESSOR_CORE_CNT2, 0);
|
||||||
|
t->core_enabled2 = smbios_get_val_si(ctx, "core-enabled2",
|
||||||
|
SYSID_SM_PROCESSOR_CORE_EN2, 0);
|
||||||
|
t->thread_count2 = smbios_get_val_si(ctx, "thread-count2",
|
||||||
|
SYSID_SM_PROCESSOR_THREAD_CNT2, 0);
|
||||||
|
t->thread_enabled = smbios_get_val_si(ctx, "thread-enabled",
|
||||||
|
SYSID_SM_PROCESSOR_THREAD_EN, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
len = t->hdr.length + smbios_string_table_len(ctx);
|
len = t->hdr.length + smbios_string_table_len(ctx);
|
||||||
*current += len;
|
*current += len;
|
||||||
unmap_sysmem(t);
|
unmap_sysmem(t);
|
||||||
@@ -654,6 +753,104 @@ static int smbios_write_type4(ulong *current, int handle,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE_VERBOSE)
|
||||||
|
|
||||||
|
static int smbios_write_type7_1level(ulong *current, int handle,
|
||||||
|
struct smbios_ctx *ctx, int level)
|
||||||
|
{
|
||||||
|
struct smbios_type7 *t;
|
||||||
|
int len = sizeof(*t);
|
||||||
|
void *hdl;
|
||||||
|
size_t hdl_size;
|
||||||
|
|
||||||
|
t = map_sysmem(*current, len);
|
||||||
|
memset(t, 0, len);
|
||||||
|
fill_smbios_header(t, SMBIOS_CACHE_INFORMATION, len, handle);
|
||||||
|
smbios_set_eos(ctx, t->eos);
|
||||||
|
|
||||||
|
t->socket_design = smbios_add_prop_si(ctx, "socket-design",
|
||||||
|
SYSID_SM_CACHE_SOCKET + level,
|
||||||
|
NULL);
|
||||||
|
t->config.data = smbios_get_val_si(ctx, "config",
|
||||||
|
SYSID_SM_CACHE_CONFIG + level,
|
||||||
|
(level - 1) | SMBIOS_CACHE_OP_UND);
|
||||||
|
t->max_size.data = smbios_get_val_si(ctx, "max-size",
|
||||||
|
SYSID_SM_CACHE_MAX_SIZE + level,
|
||||||
|
0);
|
||||||
|
t->inst_size.data = smbios_get_val_si(ctx, "installed-size",
|
||||||
|
SYSID_SM_CACHE_INST_SIZE + level,
|
||||||
|
0);
|
||||||
|
t->supp_sram_type.data =
|
||||||
|
smbios_get_val_si(ctx, "supported-sram-type",
|
||||||
|
SYSID_SM_CACHE_SUPSRAM_TYPE + level,
|
||||||
|
SMBIOS_CACHE_SRAM_TYPE_UNKNOWN);
|
||||||
|
t->curr_sram_type.data =
|
||||||
|
smbios_get_val_si(ctx, "current-sram-type",
|
||||||
|
SYSID_SM_CACHE_CURSRAM_TYPE + level,
|
||||||
|
SMBIOS_CACHE_SRAM_TYPE_UNKNOWN);
|
||||||
|
t->speed = smbios_get_val_si(ctx, "speed", SYSID_SM_CACHE_SPEED + level,
|
||||||
|
0);
|
||||||
|
t->err_corr_type = smbios_get_val_si(ctx, "error-correction-type",
|
||||||
|
SYSID_SM_CACHE_ERRCOR_TYPE + level,
|
||||||
|
SMBIOS_CACHE_ERRCORR_UNKNOWN);
|
||||||
|
t->sys_cache_type =
|
||||||
|
smbios_get_val_si(ctx, "system-cache-type",
|
||||||
|
SYSID_SM_CACHE_SCACHE_TYPE + level,
|
||||||
|
SMBIOS_CACHE_SYSCACHE_TYPE_UNKNOWN);
|
||||||
|
t->associativity = smbios_get_val_si(ctx, "associativity",
|
||||||
|
SYSID_SM_CACHE_ASSOC + level,
|
||||||
|
SMBIOS_CACHE_ASSOC_UNKNOWN);
|
||||||
|
t->max_size2.data = smbios_get_val_si(ctx, "max-size2",
|
||||||
|
SYSID_SM_CACHE_MAX_SIZE2 + level,
|
||||||
|
0);
|
||||||
|
t->inst_size2.data =
|
||||||
|
smbios_get_val_si(ctx, "installed-size2",
|
||||||
|
SYSID_SM_CACHE_INST_SIZE2 + level, 0);
|
||||||
|
|
||||||
|
/* Save the cache handles */
|
||||||
|
if (!sysinfo_get_data(ctx->dev, SYSID_SM_CACHE_HANDLE, &hdl,
|
||||||
|
&hdl_size)) {
|
||||||
|
if (hdl_size == SYSINFO_CACHE_LVL_MAX * sizeof(u16))
|
||||||
|
*((u16 *)hdl + level) = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = t->hdr.length + smbios_string_table_len(ctx);
|
||||||
|
*current += len;
|
||||||
|
unmap_sysmem(t);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int smbios_write_type7(ulong *current, int handle,
|
||||||
|
struct smbios_ctx *ctx)
|
||||||
|
{
|
||||||
|
int len = 0;
|
||||||
|
int i, level;
|
||||||
|
ofnode parent = ctx->node;
|
||||||
|
struct smbios_ctx ctx_bak;
|
||||||
|
|
||||||
|
memcpy(&ctx_bak, ctx, sizeof(ctx_bak));
|
||||||
|
|
||||||
|
/* Get the number of level */
|
||||||
|
level = smbios_get_val_si(ctx, NULL, SYSID_SM_CACHE_LEVEL, 0);
|
||||||
|
if (level >= SYSINFO_CACHE_LVL_MAX) /* Error, return 0-length */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
for (i = 0; i <= level; i++) {
|
||||||
|
char buf[9] = "";
|
||||||
|
|
||||||
|
if (!snprintf(buf, sizeof(buf), "l%d-cache", i + 1))
|
||||||
|
return 0;
|
||||||
|
ctx->subnode_name = buf;
|
||||||
|
ctx->node = ofnode_find_subnode(parent, ctx->subnode_name);
|
||||||
|
len += smbios_write_type7_1level(current, handle++, ctx, i);
|
||||||
|
memcpy(ctx, &ctx_bak, sizeof(*ctx));
|
||||||
|
}
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* #if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE_VERBOSE) */
|
||||||
|
|
||||||
static int smbios_write_type32(ulong *current, int handle,
|
static int smbios_write_type32(ulong *current, int handle,
|
||||||
struct smbios_ctx *ctx)
|
struct smbios_ctx *ctx)
|
||||||
{
|
{
|
||||||
@@ -693,6 +890,10 @@ static struct smbios_write_method smbios_write_funcs[] = {
|
|||||||
{ smbios_write_type2, "baseboard", },
|
{ smbios_write_type2, "baseboard", },
|
||||||
/* Type 3 must immediately follow type 2 due to chassis handle. */
|
/* Type 3 must immediately follow type 2 due to chassis handle. */
|
||||||
{ smbios_write_type3, "chassis", },
|
{ smbios_write_type3, "chassis", },
|
||||||
|
#if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE_VERBOSE)
|
||||||
|
/* Type 7 must ahead of type 4 to get cache handles. */
|
||||||
|
{ smbios_write_type7, "cache", },
|
||||||
|
#endif
|
||||||
{ smbios_write_type4, "processor"},
|
{ smbios_write_type4, "processor"},
|
||||||
{ smbios_write_type32, },
|
{ smbios_write_type32, },
|
||||||
{ smbios_write_type127 },
|
{ smbios_write_type127 },
|
||||||
|
|||||||
Reference in New Issue
Block a user