summaryrefslogtreecommitdiff
path: root/lib/smbios.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/smbios.c')
-rw-r--r--lib/smbios.c445
1 files changed, 379 insertions, 66 deletions
diff --git a/lib/smbios.c b/lib/smbios.c
index defb6b42f45..78cee8c0c26 100644
--- a/lib/smbios.c
+++ b/lib/smbios.c
@@ -208,6 +208,43 @@ void get_str_from_dt(const struct map_sysinfo *nprop, char *str, size_t size)
}
/**
+ * smbios_get_val_si() - Get value from the devicetree or sysinfo
+ *
+ * @ctx: context of SMBIOS
+ * @prop: property to read
+ * @sysinfo_id: unique identifier for the value to be read
+ * @val_def: Default value
+ * Return: Valid value from sysinfo or device tree, otherwise val_def.
+ */
+static int smbios_get_val_si(struct smbios_ctx * __maybe_unused ctx,
+ const char * __maybe_unused prop,
+ int __maybe_unused sysinfo_id, int val_def)
+{
+#if IS_ENABLED(CONFIG_GENERATE_SMBIOS_TABLE_VERBOSE)
+ int val;
+
+ if (!ctx->dev)
+ return val_def;
+
+ if (!sysinfo_get_int(ctx->dev, sysinfo_id, &val))
+ return val;
+
+ if (!IS_ENABLED(CONFIG_OF_CONTROL) || !prop)
+ return val_def;
+
+ if (ofnode_valid(ctx->node) && !ofnode_read_u32(ctx->node, prop, &val))
+ return val;
+
+ /*
+ * If the node or property is not valid fallback and try the root
+ */
+ if (!ofnode_read_u32(ofnode_root(), prop, &val))
+ return val;
+#endif
+ return val_def;
+}
+
+/**
* smbios_add_prop_si() - Add a property from the devicetree or sysinfo
*
* Sysinfo is used if available, with a fallback to devicetree
@@ -226,9 +263,6 @@ static int smbios_add_prop_si(struct smbios_ctx *ctx, const char *prop,
if (!dval || !*dval)
dval = NULL;
- if (!prop)
- return smbios_add_string(ctx, dval);
-
if (sysinfo_id && ctx->dev) {
char val[SMBIOS_STR_MAX];
@@ -236,6 +270,9 @@ static int smbios_add_prop_si(struct smbios_ctx *ctx, const char *prop,
if (!ret)
return smbios_add_string(ctx, val);
}
+ if (!prop)
+ return smbios_add_string(ctx, dval);
+
if (IS_ENABLED(CONFIG_OF_CONTROL)) {
const char *str = NULL;
char str_dt[128] = { 0 };
@@ -331,15 +368,17 @@ static int smbios_write_type0(ulong *current, int handle,
struct smbios_ctx *ctx)
{
struct smbios_type0 *t;
- int len = sizeof(struct smbios_type0);
+ int len = sizeof(*t);
t = map_sysmem(*current, len);
- memset(t, 0, sizeof(struct smbios_type0));
+ memset(t, 0, len);
fill_smbios_header(t, SMBIOS_BIOS_INFORMATION, len, handle);
smbios_set_eos(ctx, t->eos);
- t->vendor = smbios_add_prop(ctx, NULL, "U-Boot");
+ t->vendor = smbios_add_prop_si(ctx, NULL, SYSID_SM_BIOS_VENDOR,
+ "U-Boot");
- t->bios_ver = smbios_add_prop(ctx, "version", PLAIN_VERSION);
+ t->bios_ver = smbios_add_prop_si(ctx, "version", SYSID_SM_BIOS_VER,
+ PLAIN_VERSION);
if (t->bios_ver)
gd->smbios_version = ctx->last_str;
log_debug("smbios_version = %p: '%s'\n", gd->smbios_version,
@@ -348,7 +387,9 @@ static int smbios_write_type0(ulong *current, int handle,
print_buffer((ulong)gd->smbios_version, gd->smbios_version,
1, strlen(gd->smbios_version) + 1, 0);
#endif
- t->bios_release_date = smbios_add_prop(ctx, NULL, U_BOOT_DMI_DATE);
+ t->bios_release_date = smbios_add_prop_si(ctx, NULL,
+ SYSID_SM_BIOS_REL_DATE,
+ U_BOOT_DMI_DATE);
#ifdef CONFIG_ROM_SIZE
if (CONFIG_ROM_SIZE < SZ_16M) {
t->bios_rom_size = (CONFIG_ROM_SIZE / 65536) - 1;
@@ -375,7 +416,7 @@ static int smbios_write_type0(ulong *current, int handle,
t->ec_major_release = 0xff;
t->ec_minor_release = 0xff;
- len = t->length + smbios_string_table_len(ctx);
+ len = t->hdr.length + smbios_string_table_len(ctx);
*current += len;
unmap_sysmem(t);
@@ -386,37 +427,38 @@ static int smbios_write_type1(ulong *current, int handle,
struct smbios_ctx *ctx)
{
struct smbios_type1 *t;
- int len = sizeof(struct smbios_type1);
+ int len = sizeof(*t);
char *serial_str = env_get("serial#");
t = map_sysmem(*current, len);
- memset(t, 0, sizeof(struct smbios_type1));
+ memset(t, 0, len);
fill_smbios_header(t, SMBIOS_SYSTEM_INFORMATION, len, handle);
smbios_set_eos(ctx, t->eos);
+
t->manufacturer = smbios_add_prop_si(ctx, "manufacturer",
SYSID_SM_SYSTEM_MANUFACTURER,
NULL);
t->product_name = smbios_add_prop_si(ctx, "product",
- SYSID_SM_SYSTEM_PRODUCT,
- NULL);
- t->version = smbios_add_prop_si(ctx, "version",
- SYSID_SM_SYSTEM_VERSION,
+ SYSID_SM_SYSTEM_PRODUCT, NULL);
+ t->version = smbios_add_prop_si(ctx, "version", SYSID_SM_SYSTEM_VERSION,
NULL);
if (serial_str) {
t->serial_number = smbios_add_prop(ctx, NULL, serial_str);
- strncpy((char *)t->uuid, serial_str, sizeof(t->uuid));
+ strlcpy((char *)t->uuid, serial_str, sizeof(t->uuid));
} else {
t->serial_number = smbios_add_prop_si(ctx, "serial",
SYSID_SM_SYSTEM_SERIAL,
NULL);
}
- t->wakeup_type = SMBIOS_WAKEUP_TYPE_UNKNOWN;
- t->sku_number = smbios_add_prop_si(ctx, "sku",
- SYSID_SM_SYSTEM_SKU, NULL);
- t->family = smbios_add_prop_si(ctx, "family",
- SYSID_SM_SYSTEM_FAMILY, NULL);
-
- len = t->length + smbios_string_table_len(ctx);
+ t->wakeup_type = smbios_get_val_si(ctx, "wakeup-type",
+ SYSID_SM_SYSTEM_WAKEUP,
+ SMBIOS_WAKEUP_TYPE_UNKNOWN);
+ t->sku_number = smbios_add_prop_si(ctx, "sku", SYSID_SM_SYSTEM_SKU,
+ NULL);
+ t->family = smbios_add_prop_si(ctx, "family", SYSID_SM_SYSTEM_FAMILY,
+ NULL);
+
+ len = t->hdr.length + smbios_string_table_len(ctx);
*current += len;
unmap_sysmem(t);
@@ -427,33 +469,53 @@ static int smbios_write_type2(ulong *current, int handle,
struct smbios_ctx *ctx)
{
struct smbios_type2 *t;
- int len = sizeof(struct smbios_type2);
+ int len = sizeof(*t);
+ u8 *eos_addr;
+ /*
+ * reserve the space for the dynamic bytes of contained object handles.
+ * TODO: len += <obj_handle_num> * SMBIOS_TYPE2_CON_OBJ_HANDLE_SIZE
+ * obj_handle_num can be from DT node "baseboard" or sysinfo driver.
+ */
t = map_sysmem(*current, len);
- memset(t, 0, sizeof(struct smbios_type2));
+ memset(t, 0, len);
fill_smbios_header(t, SMBIOS_BOARD_INFORMATION, len, handle);
- smbios_set_eos(ctx, t->eos);
+
+ /* eos is at the end of the structure */
+ eos_addr = (u8 *)t + len - sizeof(t->eos);
+ smbios_set_eos(ctx, eos_addr);
+
t->manufacturer = smbios_add_prop_si(ctx, "manufacturer",
SYSID_SM_BASEBOARD_MANUFACTURER,
NULL);
t->product_name = smbios_add_prop_si(ctx, "product",
- SYSID_SM_BASEBOARD_PRODUCT,
- NULL);
+ SYSID_SM_BASEBOARD_PRODUCT, NULL);
t->version = smbios_add_prop_si(ctx, "version",
- SYSID_SM_BASEBOARD_VERSION,
- NULL);
-
+ SYSID_SM_BASEBOARD_VERSION, NULL);
t->serial_number = smbios_add_prop_si(ctx, "serial",
- SYSID_SM_BASEBOARD_SERIAL,
- NULL);
+ SYSID_SM_BASEBOARD_SERIAL, NULL);
t->asset_tag_number = smbios_add_prop_si(ctx, "asset-tag",
SYSID_SM_BASEBOARD_ASSET_TAG,
NULL);
- t->feature_flags = SMBIOS_BOARD_FEATURE_HOSTING;
- t->board_type = SMBIOS_BOARD_MOTHERBOARD;
+ t->feature_flags = smbios_get_val_si(ctx, "feature-flags",
+ SYSID_SM_BASEBOARD_FEATURE, 0);
+
+ t->chassis_location =
+ smbios_add_prop_si(ctx, "chassis-location",
+ SYSID_SM_BASEBOARD_CHASSIS_LOCAT, NULL);
+ t->board_type = smbios_get_val_si(ctx, "board-type",
+ SYSID_SM_BASEBOARD_TYPE,
+ SMBIOS_BOARD_TYPE_UNKNOWN);
+
+ /*
+ * TODO:
+ * Populate the Contained Object Handles if they exist
+ * t->number_contained_objects = <obj_handle_num>;
+ */
+
t->chassis_handle = handle + 1;
- len = t->length + smbios_string_table_len(ctx);
+ len = t->hdr.length + smbios_string_table_len(ctx);
*current += len;
unmap_sysmem(t);
@@ -464,20 +526,77 @@ static int smbios_write_type3(ulong *current, int handle,
struct smbios_ctx *ctx)
{
struct smbios_type3 *t;
- int len = sizeof(struct smbios_type3);
+ int len = sizeof(*t);
+ u8 *eos_addr;
+ 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.
+ * TODO: elem_size = <element_count> * <element_record_length>
+ * element_count and element_record_length can be from DT node
+ * "chassis" or sysinfo driver.
+ */
+ len += elem_size;
t = map_sysmem(*current, len);
- memset(t, 0, sizeof(struct smbios_type3));
+ memset(t, 0, len);
fill_smbios_header(t, SMBIOS_SYSTEM_ENCLOSURE, len, handle);
- smbios_set_eos(ctx, t->eos);
- t->manufacturer = smbios_add_prop(ctx, "manufacturer", NULL);
- t->chassis_type = SMBIOS_ENCLOSURE_DESKTOP;
- t->bootup_state = SMBIOS_STATE_SAFE;
- t->power_supply_state = SMBIOS_STATE_SAFE;
- t->thermal_state = SMBIOS_STATE_SAFE;
- t->security_status = SMBIOS_SECURITY_NONE;
-
- len = t->length + smbios_string_table_len(ctx);
+#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_addr = (u8 *)t + len - sizeof(t->eos);
+ smbios_set_eos(ctx, eos_addr);
+
+ t->manufacturer = smbios_add_prop_si(ctx, "manufacturer",
+ SYSID_SM_ENCLOSURE_MANUFACTURER,
+ NULL);
+ t->chassis_type = smbios_get_val_si(ctx, "chassis-type",
+ SYSID_SM_ENCLOSURE_TYPE,
+ SMBIOS_ENCLOSURE_UNKNOWN);
+ t->bootup_state = smbios_get_val_si(ctx, "bootup-state",
+ SYSID_SM_ENCLOSURE_BOOTUP,
+ SMBIOS_STATE_UNKNOWN);
+ t->power_supply_state = smbios_get_val_si(ctx, "power-supply-state",
+ SYSID_SM_ENCLOSURE_POW,
+ SMBIOS_STATE_UNKNOWN);
+ t->thermal_state = smbios_get_val_si(ctx, "thermal-state",
+ SYSID_SM_ENCLOSURE_THERMAL,
+ SMBIOS_STATE_UNKNOWN);
+ t->security_status = smbios_get_val_si(ctx, "security-status",
+ SYSID_SM_ENCLOSURE_SECURITY,
+ 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);
*current += len;
unmap_sysmem(t);
@@ -490,6 +609,8 @@ static void smbios_write_type4_dm(struct smbios_type4 *t,
u16 processor_family = SMBIOS_PROCESSOR_FAMILY_UNKNOWN;
const char *vendor = NULL;
const char *name = NULL;
+ __maybe_unused void *id_data = NULL;
+ __maybe_unused size_t id_size = 0;
#ifdef CONFIG_CPU
char processor_name[49];
@@ -511,46 +632,234 @@ static void smbios_write_type4_dm(struct smbios_type4 *t,
name = processor_name;
}
#endif
+ if (processor_family == SMBIOS_PROCESSOR_FAMILY_UNKNOWN)
+ processor_family =
+ smbios_get_val_si(ctx, "family",
+ SYSID_SM_PROCESSOR_FAMILY,
+ SMBIOS_PROCESSOR_FAMILY_UNKNOWN);
+
+ if (processor_family == SMBIOS_PROCESSOR_FAMILY_EXT)
+ t->processor_family2 =
+ smbios_get_val_si(ctx, "family2",
+ SYSID_SM_PROCESSOR_FAMILY2,
+ SMBIOS_PROCESSOR_FAMILY_UNKNOWN);
+
+ t->processor_family = processor_family;
+ t->processor_manufacturer =
+ smbios_add_prop_si(ctx, "manufacturer",
+ SYSID_SM_PROCESSOR_MANUFACT, vendor);
+ t->processor_version = smbios_add_prop_si(ctx, "version",
+ SYSID_SM_PROCESSOR_VERSION,
+ 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;
- t->processor_family = 0xfe;
- t->processor_family2 = processor_family;
- t->processor_manufacturer = smbios_add_prop(ctx, NULL, vendor);
- t->processor_version = smbios_add_prop(ctx, NULL, name);
+ 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,
struct smbios_ctx *ctx)
{
struct smbios_type4 *t;
- int len = sizeof(struct smbios_type4);
+ int len = sizeof(*t);
+ __maybe_unused void *hdl;
+ __maybe_unused size_t hdl_size;
t = map_sysmem(*current, len);
- memset(t, 0, sizeof(struct smbios_type4));
+ memset(t, 0, len);
fill_smbios_header(t, SMBIOS_PROCESSOR_INFORMATION, len, handle);
smbios_set_eos(ctx, t->eos);
- t->processor_type = SMBIOS_PROCESSOR_TYPE_CENTRAL;
+ t->socket_design = smbios_add_prop_si(ctx, "socket-design",
+ SYSID_SM_PROCESSOR_SOCKET, NULL);
+ t->processor_type = smbios_get_val_si(ctx, "processor-type",
+ SYSID_SM_PROCESSOR_TYPE,
+ SMBIOS_PROCESSOR_TYPE_UNKNOWN);
smbios_write_type4_dm(t, ctx);
- t->status = SMBIOS_PROCESSOR_STATUS_ENABLED;
- t->processor_upgrade = SMBIOS_PROCESSOR_UPGRADE_NONE;
- t->l1_cache_handle = 0xffff;
- t->l2_cache_handle = 0xffff;
- t->l3_cache_handle = 0xffff;
- len = t->length + smbios_string_table_len(ctx);
+ t->status = smbios_get_val_si(ctx, "processor-status",
+ SYSID_SM_PROCESSOR_STATUS,
+ SMBIOS_PROCESSOR_STATUS_UNKNOWN);
+ t->processor_upgrade =
+ smbios_get_val_si(ctx, "upgrade", SYSID_SM_PROCESSOR_UPGRADE,
+ SMBIOS_PROCESSOR_UPGRADE_UNKNOWN);
+
+ t->l1_cache_handle = SMBIOS_CACHE_HANDLE_NONE;
+ t->l2_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);
+ *current += len;
+ unmap_sysmem(t);
+
+ 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,
struct smbios_ctx *ctx)
{
struct smbios_type32 *t;
- int len = sizeof(struct smbios_type32);
+ int len = sizeof(*t);
t = map_sysmem(*current, len);
- memset(t, 0, sizeof(struct smbios_type32));
+ memset(t, 0, len);
fill_smbios_header(t, SMBIOS_SYSTEM_BOOT_INFORMATION, len, handle);
smbios_set_eos(ctx, t->eos);
@@ -564,10 +873,10 @@ static int smbios_write_type127(ulong *current, int handle,
struct smbios_ctx *ctx)
{
struct smbios_type127 *t;
- int len = sizeof(struct smbios_type127);
+ int len = sizeof(*t);
t = map_sysmem(*current, len);
- memset(t, 0, sizeof(struct smbios_type127));
+ memset(t, 0, len);
fill_smbios_header(t, SMBIOS_END_OF_TABLE, len, handle);
*current += len;
@@ -582,7 +891,11 @@ static struct smbios_write_method smbios_write_funcs[] = {
{ smbios_write_type2, "baseboard", },
/* Type 3 must immediately follow type 2 due to chassis handle. */
{ smbios_write_type3, "chassis", },
- { smbios_write_type4, },
+#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_type32, },
{ smbios_write_type127 },
};
@@ -599,7 +912,7 @@ ulong write_smbios_table(ulong addr)
int i;
ctx.node = ofnode_null();
- if (IS_ENABLED(CONFIG_OF_CONTROL) && CONFIG_IS_ENABLED(SYSINFO)) {
+ if (CONFIG_IS_ENABLED(SYSINFO)) {
uclass_first_device(UCLASS_SYSINFO, &ctx.dev);
if (ctx.dev) {
int ret;