diff options
| author | Burt P <pburt0@gmail.com> | 2019-06-28 12:16:56 -0500 | 
|---|---|---|
| committer | Leandro A. F. Pereira <leandro@hardinfo.org> | 2019-06-29 17:58:52 -0700 | 
| commit | 80e82c190e52d6d5d5814bef08a083bef7af52f4 (patch) | |
| tree | c728e1cc9411eb057b901ea030575407b11c9b79 /modules | |
| parent | 079440fd7219bb4864420f4ea6a16f2e7bef546e (diff) | |
Memory Devices improvements
* note if ddr3 is installed but ee1004 is used
* create an SPD "array" if no DMI arrays exist
* show mem types in array info
* include any SPD-detected modules even if they are
  types that can't be decoded currently
Signed-off-by: Burt P <pburt0@gmail.com>
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/devices/dmi_memory.c | 88 | ||||
| -rw-r--r-- | modules/devices/spd-decode2.c | 51 | 
2 files changed, 108 insertions, 31 deletions
| diff --git a/modules/devices/dmi_memory.c b/modules/devices/dmi_memory.c index 937b5e80..7280d328 100644 --- a/modules/devices/dmi_memory.c +++ b/modules/devices/dmi_memory.c @@ -29,6 +29,8 @@  gboolean no_handles = FALSE;  gboolean sketchy_info = FALSE; +int dmi_ram_types = 0; /* bits using enum RamType */ +  /* strings from dmidecode */  static const char empty_mem_str[] = "No Module Installed";  static const char unknown_mfgr_str[] = "<BAD INDEX>"; @@ -59,6 +61,7 @@ typedef struct {      int devs_populated;      long int size_MiB_max;      long int size_MiB_present; +    int ram_types; /* bits using enum RamType */  } dmi_mem_array;  dmi_mem_array *dmi_mem_array_new(unsigned long h) { @@ -109,6 +112,7 @@ typedef struct {      gchar *type;      gchar *type_detail; +    int ram_type; /* using enum RamType */      gchar *array_locator;      gchar *bank_locator;      gchar *form_factor; @@ -131,6 +135,8 @@ typedef struct {      GSList *arrays;      GSList *sockets;      GSList *spd; +    long int spd_size_MiB; +    int spd_ram_types; /* bits using enum RamType */  } dmi_mem;  gboolean null_if_empty(gchar **str) { @@ -189,6 +195,12 @@ dmi_mem_socket *dmi_mem_socket_new(unsigned long h) {          s->form_factor = dmidecode_match("Form Factor", &dtm, &h);          s->type = dmidecode_match("Type", &dtm, &h);          STR_IGNORE(s->type, "Unknown"); +        if (SEQ(s->type, "DDR")) s->ram_type = DDR_SDRAM; +        if (SEQ(s->type, "DDR2")) s->ram_type = DDR2_SDRAM; +        if (SEQ(s->type, "DDR3")) s->ram_type = DDR3_SDRAM; +        if (SEQ(s->type, "DDR4")) s->ram_type = DDR4_SDRAM; +        if (s->ram_type) +            dmi_ram_types |= (1 << s->ram_type-1);          s->type_detail = dmidecode_match("Type Detail", &dtm, &h);          STR_IGNORE(s->type_detail, "None"); @@ -288,6 +300,15 @@ dmi_mem *dmi_mem_new() {      }      GSList *l = NULL, *l2 = NULL; + +    /* totals for SPD */ +    for(l2 = m->spd; l2; l2 = l2->next) { +        spd_data *e = (spd_data*)l2->data; +        m->spd_size_MiB += e->size_MiB; +        if (e->type) +            m->spd_ram_types |= (1 << e->type-1); +    } +      for(l = m->sockets; l; l = l->next) {          dmi_mem_socket *s = (dmi_mem_socket*)l->data; @@ -297,6 +318,8 @@ dmi_mem *dmi_mem_new() {              a->size_MiB_present += s->size_MiB;              if (s->populated)                  a->devs_populated++; +            if (s->ram_type) +                a->ram_types |= (1 << s->ram_type-1);          }          if (!s->populated) continue; @@ -307,6 +330,7 @@ dmi_mem *dmi_mem_new() {          int best_score = 0;          for(l2 = m->spd; l2; l2 = l2->next) {              spd_data *e = (spd_data*)l2->data; +              int score = 0;              if (!e->claimed_by_dmi) {                  if (SEQ(s->partno, e->partno)) @@ -453,28 +477,39 @@ gchar *dmi_mem_socket_info() {              size_str = h_strdup_cprintf(" %s", size_str, problem_marker());          } +        gchar *types_str = NULL; +        int i; +        for(i = 1; i < N_RAM_TYPES; i++) { +            int bit = 1 << (i-1); +            if (a->ram_types & bit) +                types_str = appf(types_str, "%s", GET_RAM_TYPE_STR(i)); +        } +          gchar *details = g_strdup_printf("[%s]\n"                          "%s=0x%lx\n"                          "%s=%s\n"                          "%s=%s\n"                          "%s=%s\n"                          "%s=%s\n" -                        "%s=%d / %d\n", +                        "%s=%d / %d\n" +                        "%s=[0x%x] %s\n",                          _("Memory Array"),                          _("DMI Handle"), a->array_handle,                          _("Locator"), a->locator ? a->locator : ".",                          _("Use"), UNKIFNULL2(a->use),                          _("Error Correction Type"), UNKIFNULL2(a->ecc),                          _("Size (Present / Max)"), size_str, -                        _("Devices (Populated / Sockets)"), a->devs_populated, a->devs +                        _("Devices (Populated / Sockets)"), a->devs_populated, a->devs, +                        _("Types Present"), a->ram_types, types_str                          );          moreinfo_add_with_prefix(key_prefix, key, details); /* moreinfo now owns *details */ -        ret = h_strdup_cprintf("$!%s$%s=|%s\n", +        ret = h_strdup_cprintf("$!%s$%s=%s|%s\n",                  ret, -                key, a->locator, size_str +                key, a->locator, UNKIFNULL2(types_str), size_str                  ); -        g_free(size_str);          g_free(key); +        g_free(size_str); +        g_free(types_str);      }      /* Sockets */ @@ -562,6 +597,43 @@ gchar *dmi_mem_socket_info() {          g_free(key);      } +    /* No DMI Array, show SPD totals */ +    if (!mem->arrays && mem->spd) { +        gchar *key = g_strdup("SPD:*"); +        gchar *types_str = NULL; +        gchar *size_str = NULL; + +        if (mem->spd_size_MiB > 1024 && (mem->spd_size_MiB % 1024 == 0) ) +            size_str = g_strdup_printf("%"PRId64" %s", mem->spd_size_MiB / 1024, _("GiB")); +        else +            size_str = g_strdup_printf("%"PRId64" %s", mem->spd_size_MiB, _("MiB")); + +        int i; +        for(i = 1; i < N_RAM_TYPES; i++) { +            int bit = 1 << (i-1); +            if (mem->spd_ram_types & bit) +                types_str = appf(types_str, "%s", GET_RAM_TYPE_STR(i)); +        } + +        gchar *details = g_strdup_printf("[%s]\n" +                        "%s=%s\n" +                        "%s=%d\n" +                        "%s=[0x%x] %s\n", +                        _("Serial Presence Detect (SPD) Summary"), +                        _("Size"), size_str, +                        _("Devices"), g_slist_length(mem->spd), +                        _("Types Present"), mem->spd_ram_types, types_str +                        ); +        moreinfo_add_with_prefix(key_prefix, key, details); /* moreinfo now owns *details */ +        ret = h_strdup_cprintf("$!%s$%s=%s|%s\n", +                ret, +                key, key, UNKIFNULL2(types_str), size_str +                ); +        g_free(key); +        g_free(size_str); +        g_free(types_str); +    } +      /* Unmatched SPD */      for(l = mem->spd; l; l = l->next) {          spd_data *s = (spd_data*)l->data; @@ -585,7 +657,7 @@ gchar *dmi_mem_socket_info() {          const gchar *mfgr = s->vendor_str ? vendor_get_shortest_name(s->vendor_str) : NULL;          ret = h_strdup_cprintf("$!%s$%s%s=%s|%s|%s\n",                  ret, -                key, key, problem_marker(), UNKIFNULL2(s->partno), size_str, UNKIFNULL2(mfgr) +                key, key, problem_marker(), UNKIFEMPTY2(s->partno), size_str, UNKIFNULL2(mfgr)                  );          g_free(vendor_str);          g_free(size_str); @@ -630,10 +702,12 @@ gboolean dmi_mem_show_hinote(const char **msg) {      note_state = appf(note_state, "<tt>2. </tt>%s%s", has_eeprom ? bullet_yes : bullet_no, want_eeprom);      note_state = appf(note_state, "<tt>   </tt>%s%s", has_ee1004 ? bullet_yes : bullet_no, want_ee1004); +    gboolean ddr3_ee1004 = ((dmi_ram_types & (1<<DDR3_SDRAM)) && has_ee1004); +      gboolean best_state = FALSE;      if (has_dmi && has_root &&          ((has_eeprom && !spd_ddr4_partial_data) -        || has_ee1004) ) +        || has_ee1004 && !ddr3_ee1004) )          best_state = TRUE;      if (!best_state) { diff --git a/modules/devices/spd-decode2.c b/modules/devices/spd-decode2.c index 57ceeb9a..bc9fc911 100644 --- a/modules/devices/spd-decode2.c +++ b/modules/devices/spd-decode2.c @@ -34,27 +34,31 @@  gboolean spd_no_driver = FALSE;  gboolean spd_no_support = FALSE;  gboolean spd_ddr4_partial_data = FALSE; +int spd_ram_types = 0; /* bits using enum RamType */  typedef enum { -    UNKNOWN, -    DIRECT_RAMBUS, -    RAMBUS, -    FPM_DRAM, -    EDO, -    PIPELINED_NIBBLE, -    SDR_SDRAM, -    MULTIPLEXED_ROM, -    DDR_SGRAM, -    DDR_SDRAM, -    DDR2_SDRAM, -    DDR3_SDRAM, -    DDR4_SDRAM +    UNKNOWN           = 0, +    DIRECT_RAMBUS     = 1, +    RAMBUS            = 2, +    FPM_DRAM          = 3, +    EDO               = 4, +    PIPELINED_NIBBLE  = 5, +    SDR_SDRAM         = 6, +    MULTIPLEXED_ROM   = 7, +    DDR_SGRAM         = 8, +    DDR_SDRAM         = 9, +    DDR2_SDRAM        = 10, +    DDR3_SDRAM        = 11, +    DDR4_SDRAM        = 12, +    N_RAM_TYPES       = 13  } RamType;  static const char *ram_types[] = {"Unknown",   "Direct Rambus",    "Rambus",     "FPM DRAM",                                    "EDO",       "Pipelined Nibble", "SDR SDRAM",  "Multiplexed ROM",                                    "DDR SGRAM", "DDR SDRAM",        "DDR2 SDRAM", "DDR3 SDRAM",                                    "DDR4 SDRAM"}; +#define GET_RAM_TYPE_STR(rt) (ram_types[(rt < N_RAM_TYPES) ? rt : 0]) +  static const char *vendors1[] = {"AMD",                                   "AMI", @@ -882,16 +886,8 @@ typedef struct {      gboolean claimed_by_dmi;  } spd_data; -spd_data *spd_data_new() { -    spd_data *s = g_new0(spd_data, 1); -    return s; -} - -void spd_data_free(spd_data *s) { -    if (s) { -        g_free(s); -    } -} +#define spd_data_new() g_new0(spd_data, 1) +void spd_data_free(spd_data *s) { g_free(s); }  /*   * We consider that no data was written to this area of the SPD EEPROM if @@ -1812,7 +1808,13 @@ static GSList *decode_dimms2(GSList *eeprom_list, gboolean use_sysfs, int max_si              s->ddr4_no_ee1004 = s->ddr4_no_ee1004 || (spd_size < 512);              spd_ddr4_partial_data = spd_ddr4_partial_data || s->ddr4_no_ee1004;              break; -        default: DEBUG("Unsupported EEPROM type: %s for %s\n", ram_types[ram_type], spd_path); continue; +        default: +            DEBUG("Unsupported EEPROM type: %s for %s\n", GET_RAM_TYPE_STR(ram_type), spd_path); continue; +            if (ram_type) { +                /* some kind of RAM that we can't decode, but exists */ +                s = spd_data_new(); +                memcpy(s->bytes, bytes, 512); +            }          }          if (s) { @@ -1821,6 +1823,7 @@ static GSList *decode_dimms2(GSList *eeprom_list, gboolean use_sysfs, int max_si                  s->spd_driver = 1;              s->spd_size = spd_size;              s->type = ram_type; +            spd_ram_types |= (1 << ram_type-1);              if (ram_type == SDR_SDRAM) {                  /* SDR */                  s->spd_rev_major = 0; | 
