@@ -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;
@@ -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 },
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(-)