|
|
99c779 |
From 20872dd40742dc7f59c338e1575765cb2c88e6c6 Mon Sep 17 00:00:00 2001
|
|
|
99c779 |
From: Jack Miller <jack@codezen.org>
|
|
|
99c779 |
Date: Tue, 16 Aug 2016 14:03:47 -0500
|
|
|
99c779 |
Subject: [PATCH 34/43] devtree: Refactor SPD handling code
|
|
|
99c779 |
|
|
|
99c779 |
Some variants of IBM Power Systems has SPD property in device tree.
|
|
|
99c779 |
Hence move SPD reading code to separate function. Following patch
|
|
|
99c779 |
makes use of this changes.
|
|
|
99c779 |
|
|
|
99c779 |
Also minor cleanup included, mostly trying to reduce nested scopes.
|
|
|
99c779 |
|
|
|
99c779 |
No functionality changes.
|
|
|
99c779 |
|
|
|
99c779 |
Signed-off-by: Jack Miller <jack@codezen.org>
|
|
|
99c779 |
[Fixed minor issues, updated description - Vasant]
|
|
|
99c779 |
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
|
|
|
99c779 |
---
|
|
|
99c779 |
src/core/device-tree.cc | 227 ++++++++++++++++++++++++------------------------
|
|
|
99c779 |
1 file changed, 114 insertions(+), 113 deletions(-)
|
|
|
99c779 |
|
|
|
99c779 |
diff --git a/src/core/device-tree.cc b/src/core/device-tree.cc
|
|
|
99c779 |
index 05db9f3..2d908d2 100644
|
|
|
99c779 |
--- a/src/core/device-tree.cc
|
|
|
99c779 |
+++ b/src/core/device-tree.cc
|
|
|
99c779 |
@@ -752,6 +752,98 @@ static void scan_devtree_cpu_power(hwNode & core)
|
|
|
99c779 |
delete it->second;
|
|
|
99c779 |
}
|
|
|
99c779 |
|
|
|
99c779 |
+static void add_memory_bank_spd(string path, hwNode & bank)
|
|
|
99c779 |
+{
|
|
|
99c779 |
+ char dimmversion[20];
|
|
|
99c779 |
+ unsigned char mfg_loc_offset;
|
|
|
99c779 |
+ unsigned char rev_offset1;
|
|
|
99c779 |
+ unsigned char rev_offset2;
|
|
|
99c779 |
+ unsigned char year_offset;
|
|
|
99c779 |
+ unsigned char week_offset;
|
|
|
99c779 |
+ unsigned char partno_offset;
|
|
|
99c779 |
+ unsigned char ver_offset;
|
|
|
99c779 |
+ int fd;
|
|
|
99c779 |
+ dimminfo_buf dimminfo;
|
|
|
99c779 |
+
|
|
|
99c779 |
+ fd = open(path.c_str(), O_RDONLY);
|
|
|
99c779 |
+ if (fd < 0)
|
|
|
99c779 |
+ return;
|
|
|
99c779 |
+
|
|
|
99c779 |
+ if (read(fd, &dimminfo, 0x80) != 0x80)
|
|
|
99c779 |
+ {
|
|
|
99c779 |
+ close(fd);
|
|
|
99c779 |
+ return;
|
|
|
99c779 |
+ }
|
|
|
99c779 |
+
|
|
|
99c779 |
+ /* Read entire SPD eeprom */
|
|
|
99c779 |
+ if (dimminfo[2] >= 9) /* DDR3 */
|
|
|
99c779 |
+ {
|
|
|
99c779 |
+ read(fd, &dimminfo[0x80], (64 << ((dimminfo[0] & 0x70) >> 4)));
|
|
|
99c779 |
+ } else if (dimminfo[0] < 15) { /* DDR 2 */
|
|
|
99c779 |
+ read(fd, &dimminfo[0x80], (1 << (dimminfo[1])));
|
|
|
99c779 |
+ }
|
|
|
99c779 |
+
|
|
|
99c779 |
+ close(fd);
|
|
|
99c779 |
+
|
|
|
99c779 |
+ if (dimminfo[2] >= 9) {
|
|
|
99c779 |
+ mfg_loc_offset = 0x77;
|
|
|
99c779 |
+ rev_offset1 = 0x92;
|
|
|
99c779 |
+ rev_offset2 = 0x93;
|
|
|
99c779 |
+ year_offset = 0x78;
|
|
|
99c779 |
+ week_offset = 0x79;
|
|
|
99c779 |
+ partno_offset = 0x80;
|
|
|
99c779 |
+ ver_offset = 0x01;
|
|
|
99c779 |
+
|
|
|
99c779 |
+ switch ((dimminfo[0x8] >> 3) & 0x3) // DDR3 error detection and correction scheme
|
|
|
99c779 |
+ {
|
|
|
99c779 |
+ case 0x00:
|
|
|
99c779 |
+ bank.setConfig("errordetection", "none");
|
|
|
99c779 |
+ break;
|
|
|
99c779 |
+ case 0x01:
|
|
|
99c779 |
+ bank.addCapability("ecc");
|
|
|
99c779 |
+ bank.setConfig("errordetection", "ecc");
|
|
|
99c779 |
+ break;
|
|
|
99c779 |
+ }
|
|
|
99c779 |
+ } else {
|
|
|
99c779 |
+ mfg_loc_offset = 0x48;
|
|
|
99c779 |
+ rev_offset1 = 0x5b;
|
|
|
99c779 |
+ rev_offset2 = 0x5c;
|
|
|
99c779 |
+ year_offset = 0x5d;
|
|
|
99c779 |
+ week_offset = 0x5e;
|
|
|
99c779 |
+ partno_offset = 0x49;
|
|
|
99c779 |
+ ver_offset = 0x3e;
|
|
|
99c779 |
+
|
|
|
99c779 |
+ switch (dimminfo[0xb] & 0x3) // DDR2 error detection and correction scheme
|
|
|
99c779 |
+ {
|
|
|
99c779 |
+ case 0x00:
|
|
|
99c779 |
+ bank.setConfig("errordetection", "none");
|
|
|
99c779 |
+ break;
|
|
|
99c779 |
+ case 0x01:
|
|
|
99c779 |
+ bank.addCapability("parity");
|
|
|
99c779 |
+ bank.setConfig("errordetection", "parity");
|
|
|
99c779 |
+ break;
|
|
|
99c779 |
+ case 0x02:
|
|
|
99c779 |
+ case 0x03:
|
|
|
99c779 |
+ bank.addCapability("ecc");
|
|
|
99c779 |
+ bank.setConfig("errordetection", "ecc");
|
|
|
99c779 |
+ break;
|
|
|
99c779 |
+ }
|
|
|
99c779 |
+ }
|
|
|
99c779 |
+
|
|
|
99c779 |
+ snprintf(dimmversion, sizeof(dimmversion),
|
|
|
99c779 |
+ "%02X%02X,%02X %02X,%02X", dimminfo[rev_offset1],
|
|
|
99c779 |
+ dimminfo[rev_offset2], dimminfo[year_offset], dimminfo[week_offset],
|
|
|
99c779 |
+ dimminfo[mfg_loc_offset]);
|
|
|
99c779 |
+ bank.setSerial(string((char *) &dimminfo[partno_offset], 18));
|
|
|
99c779 |
+ bank.setVersion(dimmversion);
|
|
|
99c779 |
+
|
|
|
99c779 |
+ int version = dimminfo[ver_offset];
|
|
|
99c779 |
+ char buff[32];
|
|
|
99c779 |
+
|
|
|
99c779 |
+ snprintf(buff, sizeof(buff), "spd-%d.%d", (version & 0xF0) >> 4, version & 0x0F);
|
|
|
99c779 |
+ bank.addCapability(buff);
|
|
|
99c779 |
+}
|
|
|
99c779 |
+
|
|
|
99c779 |
static void add_memory_bank(string name, string path, hwNode & core)
|
|
|
99c779 |
{
|
|
|
99c779 |
struct dirent **dirlist;
|
|
|
99c779 |
@@ -872,123 +964,32 @@ static void scan_devtree_memory(hwNode & core)
|
|
|
99c779 |
memory = core.addChild(hwNode("memory", hw::memory));
|
|
|
99c779 |
}
|
|
|
99c779 |
|
|
|
99c779 |
- if (memory)
|
|
|
99c779 |
- {
|
|
|
99c779 |
- int fd = open(dimminfo.c_str(), O_RDONLY);
|
|
|
99c779 |
+ if (!memory)
|
|
|
99c779 |
+ break;
|
|
|
99c779 |
|
|
|
99c779 |
- if (regs.size() == slotnames.size())
|
|
|
99c779 |
+ if (regs.size() == slotnames.size())
|
|
|
99c779 |
+ {
|
|
|
99c779 |
+ for (unsigned int i = 0; i < slotnames.size(); i++)
|
|
|
99c779 |
{
|
|
|
99c779 |
- for (unsigned int i = 0; i < slotnames.size(); i++)
|
|
|
99c779 |
- {
|
|
|
99c779 |
- uint64_t size = regs[i].size;
|
|
|
99c779 |
- hwNode bank("bank",
|
|
|
99c779 |
- hw::memory);
|
|
|
99c779 |
-
|
|
|
99c779 |
- if (fd >= 0)
|
|
|
99c779 |
- {
|
|
|
99c779 |
- dimminfo_buf dimminfo;
|
|
|
99c779 |
-
|
|
|
99c779 |
- if (read(fd, &dimminfo, 0x80) == 0x80)
|
|
|
99c779 |
- {
|
|
|
99c779 |
-
|
|
|
99c779 |
- /* Read entire SPD eeprom */
|
|
|
99c779 |
- if (dimminfo[2] >= 9) /* DDR3 */
|
|
|
99c779 |
- {
|
|
|
99c779 |
- read(fd, &dimminfo[0x80], (64 << ((dimminfo[0] & 0x70) >> 4)));
|
|
|
99c779 |
- } else if (dimminfo[0] < 15) { /* DDR 2 */
|
|
|
99c779 |
- read(fd, &dimminfo[0x80], (1 << (dimminfo[1]) ));
|
|
|
99c779 |
- }
|
|
|
99c779 |
-
|
|
|
99c779 |
- if (size > 0)
|
|
|
99c779 |
- {
|
|
|
99c779 |
- char dimmversion[20];
|
|
|
99c779 |
- unsigned char mfg_loc_offset;
|
|
|
99c779 |
- unsigned char rev_offset1;
|
|
|
99c779 |
- unsigned char rev_offset2;
|
|
|
99c779 |
- unsigned char year_offset;
|
|
|
99c779 |
- unsigned char week_offset;
|
|
|
99c779 |
- unsigned char partno_offset;
|
|
|
99c779 |
- unsigned char ver_offset;
|
|
|
99c779 |
-
|
|
|
99c779 |
- if (dimminfo[2] >= 9) {
|
|
|
99c779 |
- mfg_loc_offset = 0x77;
|
|
|
99c779 |
- rev_offset1 = 0x92;
|
|
|
99c779 |
- rev_offset2 = 0x93;
|
|
|
99c779 |
- year_offset = 0x78;
|
|
|
99c779 |
- week_offset = 0x79;
|
|
|
99c779 |
- partno_offset = 0x80;
|
|
|
99c779 |
- ver_offset = 0x01;
|
|
|
99c779 |
-
|
|
|
99c779 |
- switch ((dimminfo[0x8] >> 3) & 0x3) // DDR3 error detection and correction scheme
|
|
|
99c779 |
- {
|
|
|
99c779 |
- case 0x00:
|
|
|
99c779 |
- bank.setConfig("errordetection", "none");
|
|
|
99c779 |
- break;
|
|
|
99c779 |
- case 0x01:
|
|
|
99c779 |
- bank.addCapability("ecc");
|
|
|
99c779 |
- bank.setConfig("errordetection", "ecc");
|
|
|
99c779 |
- break;
|
|
|
99c779 |
- }
|
|
|
99c779 |
- } else {
|
|
|
99c779 |
- mfg_loc_offset = 0x48;
|
|
|
99c779 |
- rev_offset1 = 0x5b;
|
|
|
99c779 |
- rev_offset2 = 0x5c;
|
|
|
99c779 |
- year_offset = 0x5d;
|
|
|
99c779 |
- week_offset = 0x5e;
|
|
|
99c779 |
- partno_offset = 0x49;
|
|
|
99c779 |
- ver_offset = 0x3e;
|
|
|
99c779 |
-
|
|
|
99c779 |
- switch (dimminfo[0xb] & 0x3) // DDR2 error detection and correction scheme
|
|
|
99c779 |
- {
|
|
|
99c779 |
- case 0x00:
|
|
|
99c779 |
- bank.setConfig("errordetection", "none");
|
|
|
99c779 |
- break;
|
|
|
99c779 |
- case 0x01:
|
|
|
99c779 |
- bank.addCapability("parity");
|
|
|
99c779 |
- bank.setConfig("errordetection", "parity");
|
|
|
99c779 |
- break;
|
|
|
99c779 |
- case 0x02:
|
|
|
99c779 |
- case 0x03:
|
|
|
99c779 |
- bank.addCapability("ecc");
|
|
|
99c779 |
- bank.setConfig("errordetection", "ecc");
|
|
|
99c779 |
- break;
|
|
|
99c779 |
- }
|
|
|
99c779 |
- }
|
|
|
99c779 |
- snprintf(dimmversion, sizeof(dimmversion),
|
|
|
99c779 |
- "%02X%02X,%02X %02X,%02X", dimminfo[rev_offset1],
|
|
|
99c779 |
- dimminfo[rev_offset2], dimminfo[year_offset], dimminfo[week_offset],
|
|
|
99c779 |
- dimminfo[mfg_loc_offset]);
|
|
|
99c779 |
- bank.setSerial(string((char *) &dimminfo[partno_offset], 18));
|
|
|
99c779 |
- bank.setVersion(dimmversion);
|
|
|
99c779 |
-
|
|
|
99c779 |
- int version = dimminfo[ver_offset];
|
|
|
99c779 |
- char buff[32];
|
|
|
99c779 |
-
|
|
|
99c779 |
- snprintf(buff, sizeof(buff), "spd-%d.%d", (version & 0xF0) >> 4, version & 0x0F);
|
|
|
99c779 |
- bank.addCapability(buff);
|
|
|
99c779 |
- }
|
|
|
99c779 |
- }
|
|
|
99c779 |
- }
|
|
|
99c779 |
-
|
|
|
99c779 |
- if(size>0)
|
|
|
99c779 |
- bank.addHint("icon", string("memory"));
|
|
|
99c779 |
- bank.setDescription("Memory bank");
|
|
|
99c779 |
- bank.setSlot(slotnames[i]);
|
|
|
99c779 |
- if (i < dimmtypes.size())
|
|
|
99c779 |
- bank.setDescription(dimmtypes[i]);
|
|
|
99c779 |
- if (i < dimmspeeds.size())
|
|
|
99c779 |
- bank.setProduct(hw::strip(dimmspeeds[i]));
|
|
|
99c779 |
- bank.setSize(size);
|
|
|
99c779 |
- memory->addChild(bank);
|
|
|
99c779 |
- }
|
|
|
99c779 |
+ uint64_t size = regs[i].size;
|
|
|
99c779 |
+ hwNode bank("bank", hw::memory);
|
|
|
99c779 |
+
|
|
|
99c779 |
+ // Parse Memory SPD data
|
|
|
99c779 |
+ add_memory_bank_spd(dimminfo, bank);
|
|
|
99c779 |
+
|
|
|
99c779 |
+ if (size > 0)
|
|
|
99c779 |
+ bank.addHint("icon", string("memory"));
|
|
|
99c779 |
+ bank.setDescription("Memory bank");
|
|
|
99c779 |
+ bank.setSlot(slotnames[i]);
|
|
|
99c779 |
+ if (i < dimmtypes.size())
|
|
|
99c779 |
+ bank.setDescription(dimmtypes[i]);
|
|
|
99c779 |
+ if (i < dimmspeeds.size())
|
|
|
99c779 |
+ bank.setProduct(hw::strip(dimmspeeds[i]));
|
|
|
99c779 |
+ bank.setSize(size);
|
|
|
99c779 |
+ memory->addChild(bank);
|
|
|
99c779 |
}
|
|
|
99c779 |
-
|
|
|
99c779 |
- if (fd >= 0)
|
|
|
99c779 |
- close(fd);
|
|
|
99c779 |
- currentmc++;
|
|
|
99c779 |
}
|
|
|
99c779 |
- else
|
|
|
99c779 |
- break;
|
|
|
99c779 |
+ currentmc++;
|
|
|
99c779 |
|
|
|
99c779 |
memory = NULL;
|
|
|
99c779 |
}
|
|
|
99c779 |
--
|
|
|
99c779 |
2.10.2
|
|
|
99c779 |
|