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....@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 },
-- 
2.25.1

Reply via email to