From f1cd42c0c6f434e15ba322970cfa4519ee1f523d Mon Sep 17 00:00:00 2001 From: Jack Miller 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 [Updated description, fixed minor issues - Vasant] Signed-off-by: Vasant Hegde --- 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