From f1cd42c0c6f434e15ba322970cfa4519ee1f523d Mon Sep 17 00:00:00 2001
From: Jack Miller <jack@codezen.org>
Date: Tue, 16 Aug 2016 15:08:51 -0500
Subject: [PATCH 38/43] devtree: Report memory info for BMC based Power System
Some variants of Power System (BMC service processor system) device tree
contains SPD information. Also it has memory-buffer representation in
device tree.
This patch adds support to display memory information on this system.
Sample output;
*-bank:1
description: RDIMM DDR3 1600 MHz (0.6ns)
product: HMT42GR7BFR4A-PB
vendor: Hynix Semiconductor (Hyundai Electronics)
physical id: 1
version: 5438,15 33,01
serial: 0x10c0af2c
slot: Physical:/Sys0/Node0/DIMM11
size: 16GiB
clock: 1333MHz (0.8ns)
capabilities: ecc spd-1.3
configuration: errordetection=ecc
Signed-off-by: Jack Miller <jack@codezen.org>
[Updated description, fixed minor issues - Vasant]
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
---
src/core/device-tree.cc | 71 +++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 66 insertions(+), 5 deletions(-)
diff --git a/src/core/device-tree.cc b/src/core/device-tree.cc
index 41034e5..b7d0d57 100644
--- a/src/core/device-tree.cc
+++ b/src/core/device-tree.cc
@@ -753,6 +753,57 @@ static void scan_devtree_cpu_power(hwNode & core)
delete it->second;
}
+static bool add_memory_bank_mba_dimm(string path,
+ unsigned long serial, hwNode & bank)
+{
+ bool found = false;
+ int n;
+ struct dirent **namelist;
+
+ pushd(path);
+ n = scandir(".", &namelist, selectdir, alphasort);
+ popd();
+
+ if (n < 0)
+ return found;
+
+ for (int i = 0; i < n; i++)
+ {
+ string sname = string(namelist[i]->d_name);
+ string fullpath = path + "/" + sname;
+
+ if (found)
+ {
+ free(namelist[i]);
+ continue;
+ }
+
+ if (sname.substr(0, 13) == "memory-buffer")
+ {
+ if (exists(fullpath + "/frequency-mhz"))
+ {
+ int hz = get_u32(fullpath + "/frequency-mhz") * 1000000;
+ bank.setClock(hz);
+ }
+ found = add_memory_bank_mba_dimm(fullpath, serial, bank);
+ } else if (sname.substr(0, 3) == "mba") {
+ found = add_memory_bank_mba_dimm(fullpath, serial, bank);
+ } else if ((sname.substr(0, 4) == "dimm") &&
+ (get_u32(fullpath + "/serial-number") == serial)) {
+ vector < reg_entry > regs = get_reg_property(fullpath);
+ bank.setSize(regs[0].size);
+
+ bank.setSlot(hw::strip(get_string(fullpath + "/ibm,slot-location-code")));
+ found = true;
+ }
+ free(namelist[i]);
+ }
+
+ free(namelist);
+ return found;
+}
+
+
static void add_memory_bank_spd(string path, hwNode & bank)
{
char dimmversion[20];
@@ -885,6 +936,8 @@ static void add_memory_bank_spd(string path, hwNode & bank)
snprintf(buff, sizeof(buff), "0x%lx", serial);
bank.setSerial(buff);
+ add_memory_bank_mba_dimm(DEVICETREE, serial, bank);
+
snprintf(buff, sizeof(buff), "spd-%d.%d", (version & 0xF0) >> 4, version & 0x0F);
bank.addCapability(buff);
}
@@ -895,18 +948,17 @@ static void add_memory_bank(string name, string path, hwNode & core)
string product;
int n;
+ hwNode *memory = core.getChild("memory");
+ if(!memory)
+ memory = core.addChild(hwNode("memory", hw::memory));
+
pushd(path + name);
if(name.substr(0, 7) == "ms-dimm")
{
- hwNode *memory = core.getChild("memory");
-
hwNode bank("bank", hw::memory);
bank.claim(true);
bank.addHint("icon", string("memory"));
- if(!memory)
- memory = core.addChild(hwNode("memory", hw::memory));
-
if(exists("serial-number"))
bank.setSerial(hw::strip(get_string("serial-number")));
@@ -926,6 +978,15 @@ static void add_memory_bank(string name, string path, hwNode & core)
bank.setSize(size*1024*1024);
memory->addChild(bank);
+ } else if(name.substr(0, 4) == "dimm") {
+ hwNode bank("bank", hw::memory);
+ bank.claim(true);
+ bank.addHint("icon", string("memory"));
+
+ // Parse Memory SPD data
+ add_memory_bank_spd(path + name + "/spd", bank);
+
+ memory->addChild(bank);
}
n = scandir(".", &dirlist, selectdir, alphasort);
--
2.10.2