summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
Diffstat (limited to 'modules')
-rw-r--r--modules/devices/dmi_memory.c88
-rw-r--r--modules/devices/spd-decode2.c51
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;