
Add SMBIOS type 7 (cache information) write functions. Link cache handles from type 7 to type 4. Add SMBIOS command print functions for type 7.
Signed-off-by: Raymond Mao raymond.mao@linaro.org --- cmd/smbios.c | 82 +++++++++++++++++++++++++++++++++++++++ lib/smbios.c | 106 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 185 insertions(+), 3 deletions(-)
diff --git a/cmd/smbios.c b/cmd/smbios.c index 8e2bf46a09c..38651740451 100644 --- a/cmd/smbios.c +++ b/cmd/smbios.c @@ -91,6 +91,43 @@ static const char * const processor_upgrade_strings[] = { [7 ... 80] = "Other", /* skip these definitions from now */ };
+static const char * const err_corr_type_strings[] = { + "Reserved", /* 0x00 */ + "Other", /* 0x01 */ + "Unknown", /* 0x02 */ + "None", /* 0x03 */ + "Parity", /* 0x04 */ + "Single-bit ECC", /* 0x05 */ + "Multi-bit ECC", /* 0x06 */ +}; + +static const char * const sys_cache_type_strings[] = { + "Reserved", /* 0x00 */ + "Other", /* 0x01 */ + "Unknown", /* 0x02 */ + "Instruction", /* 0x03 */ + "Data", /* 0x04 */ + "Unified", /* 0x05 */ +}; + +static const char * const associativity_strings[] = { + "Reserved", /* 0x00 */ + "Other", /* 0x01 */ + "Unknown", /* 0x02 */ + "Direct Mapped", /* 0x03 */ + "2-way Set-Associative", /* 0x04 */ + "4-way Set-Associative", /* 0x05 */ + "Fully Associative", /* 0x06 */ + "8-way Set-Associative", /* 0x07 */ + "16-way Set-Associative", /* 0x08 */ + "12-way Set-Associative", /* 0x09 */ + "24-way Set-Associative", /* 0x0a */ + "32-way Set-Associative", /* 0x0b */ + "48-way Set-Associative", /* 0x0c */ + "64-way Set-Associative", /* 0x0d */ + "20-way Set-Associative", /* 0x0e */ +}; + /** * smbios_get_string() - get SMBIOS string from table * @@ -364,6 +401,48 @@ static void smbios_print_type4(struct smbios_type4 *table) printf("\tThread Enabled: 0x%04x\n", table->thread_enabled); }
+const char *smbios_cache_err_corr_type_str(u8 err_corr_type) +{ + if (err_corr_type >= ARRAY_SIZE(err_corr_type_strings)) + err_corr_type = 0; + return err_corr_type_strings[err_corr_type]; +} + +const char *smbios_cache_sys_cache_type_str(u8 sys_cache_type) +{ + if (sys_cache_type >= ARRAY_SIZE(sys_cache_type_strings)) + sys_cache_type = 0; + return sys_cache_type_strings[sys_cache_type]; +} + +const char *smbios_cache_associativity_str(u8 associativity) +{ + if (associativity >= ARRAY_SIZE(associativity_strings)) + associativity = 0; + return associativity_strings[associativity]; +} + +static void smbios_print_type7(struct smbios_type7 *table) +{ + printf("Cache Information:\n"); + smbios_print_str("Socket Designation", table, + table->socket_design); + printf("\tCache Configuration: 0x%04x\n", table->config.data); + printf("\tMaximum Cache Size: 0x%04x\n", table->max_size.data); + printf("\tInstalled Size: 0x%04x\n", table->inst_size.data); + printf("\tSupported SRAM Type: 0x%04x\n", table->supp_sram_type.data); + printf("\tCurrent SRAM Type: 0x%04x\n", table->curr_sram_type.data); + printf("\tCache Speed: 0x%02x\n", table->speed); + printf("\tError Correction Type: %s\n", + smbios_cache_err_corr_type_str(table->err_corr_type)); + printf("\tSystem Cache Type: %s\n", + smbios_cache_sys_cache_type_str(table->sys_cache_type)); + printf("\tAssociativity: %s\n", + smbios_cache_associativity_str(table->associativity)); + printf("\tMaximum Cache Size 2: 0x%08x\n", table->max_size2.data); + printf("\tInstalled Cache Size 2: 0x%08x\n", table->inst_size2.data); +} + static void smbios_print_type127(struct smbios_type127 *table) { printf("End Of Table\n"); @@ -440,6 +519,9 @@ static int do_smbios(struct cmd_tbl *cmdtp, int flag, int argc, case SMBIOS_PROCESSOR_INFORMATION: smbios_print_type4((struct smbios_type4 *)pos); break; + case SMBIOS_CACHE_INFORMATION: + smbios_print_type7((struct smbios_type7 *)pos); + break; case SMBIOS_END_OF_TABLE: smbios_print_type127((struct smbios_type127 *)pos); break; diff --git a/lib/smbios.c b/lib/smbios.c index 2f1759d419e..f5514661abe 100644 --- a/lib/smbios.c +++ b/lib/smbios.c @@ -703,6 +703,8 @@ static int smbios_write_type4(ulong *current, int handle, { struct smbios_type4 *t; int len = sizeof(*t); + u8 *hdl; + size_t hdl_size;
t = map_sysmem(*current, len); memset(t, 0, len); @@ -729,9 +731,25 @@ static int smbios_write_type4(ulong *current, int handle, t->processor_upgrade = smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_PROCESSOR_UPGRADE);
- t->l1_cache_handle = SMBIOS_CACHE_HANDLE_NONE; - t->l2_cache_handle = SMBIOS_CACHE_HANDLE_NONE; - t->l3_cache_handle = SMBIOS_CACHE_HANDLE_NONE; + /* Read the cache handles */ + if (!sysinfo_get_data(ctx->dev, SYSINFO_ID_SMBIOS_CACHE_HANDLE, + &hdl, &hdl_size) && + (hdl_size == SYSINFO_CACHE_LVL_MAX * sizeof(u16))) { + u16 *handle = (u16 *)hdl; + + t->l1_cache_handle = *handle ? *handle : + SMBIOS_CACHE_HANDLE_NONE; + handle++; + t->l2_cache_handle = *handle ? *handle : + SMBIOS_CACHE_HANDLE_NONE; + handle++; + t->l3_cache_handle = *handle ? *handle : + SMBIOS_CACHE_HANDLE_NONE; + } else { + t->l1_cache_handle = SMBIOS_CACHE_HANDLE_NONE; + t->l2_cache_handle = SMBIOS_CACHE_HANDLE_NONE; + t->l3_cache_handle = SMBIOS_CACHE_HANDLE_NONE; + }
t->serial_number = smbios_add_prop_si(ctx, NULL, SYSINFO_ID_SMBIOS_PROCESSOR_SN, @@ -766,6 +784,86 @@ static int smbios_write_type4(ulong *current, int handle, return len; }
+static int smbios_write_type7_1level(ulong *current, int handle, + struct smbios_ctx *ctx, int level) +{ + struct smbios_type7 *t; + int len = sizeof(*t); + u8 *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", + SYSINFO_ID_SMBIOS_CACHE_SOCKET + level, + NULL); + t->config.data = + smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_CACHE_CONFIG + level); + t->max_size.data = + smbios_get_val_si(ctx, + SYSINFO_ID_SMBIOS_CACHE_MAX_SIZE + level); + t->inst_size.data = + smbios_get_val_si(ctx, + SYSINFO_ID_SMBIOS_CACHE_INST_SIZE + level); + t->supp_sram_type.data = + smbios_get_val_si(ctx, + SYSINFO_ID_SMBIOS_CACHE_SUPSRAM_TYPE + level); + t->curr_sram_type.data = + smbios_get_val_si(ctx, + SYSINFO_ID_SMBIOS_CACHE_CURSRAM_TYPE + level); + t->speed = smbios_get_val_si(ctx, + SYSINFO_ID_SMBIOS_CACHE_SPEED + level); + t->err_corr_type = + smbios_get_val_si(ctx, + SYSINFO_ID_SMBIOS_CACHE_ERRCOR_TYPE + level); + t->sys_cache_type = + smbios_get_val_si(ctx, + SYSINFO_ID_SMBIOS_CACHE_SCACHE_TYPE + level); + t->associativity = + smbios_get_val_si(ctx, + SYSINFO_ID_SMBIOS_CACHE_ASSOC + level); + t->max_size2.data = + smbios_get_val_si(ctx, + SYSINFO_ID_SMBIOS_CACHE_MAX_SIZE2 + level); + t->inst_size2.data = + smbios_get_val_si(ctx, + SYSINFO_ID_SMBIOS_CACHE_INST_SIZE2 + level); + + /* Save the cache handles */ + if (!sysinfo_get_data(ctx->dev, SYSINFO_ID_SMBIOS_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; + + /* Get the number of level */ + level = smbios_get_val_si(ctx, SYSINFO_ID_SMBIOS_CACHE_LEVEL); + if (level >= SYSINFO_CACHE_LVL_MAX) /* Error, return 0-length */ + return 0; + + for (i = 0; i <= level; i++) + len += smbios_write_type7_1level(current, handle++, ctx, i); + + return len; +} + static int smbios_write_type32(ulong *current, int handle, struct smbios_ctx *ctx) { @@ -805,6 +903,8 @@ 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", }, + /* Type 7 must ahead of type 4 to get cache handles. */ + { smbios_write_type7, }, { smbios_write_type4, }, { smbios_write_type32, }, { smbios_write_type127 },