|
|
df7b7f |
From 8059dc9ef1cb92107370ff4e1e9a390210ec01b7 Mon Sep 17 00:00:00 2001
|
|
|
df7b7f |
From: Chandni Verma <chandni@linux.vnet.ibm.com>
|
|
|
df7b7f |
Date: Thu, 20 Oct 2016 14:55:43 +0530
|
|
|
df7b7f |
Subject: [PATCH 24/43] devtree: Add VPD info for FSP based Power System
|
|
|
df7b7f |
|
|
|
df7b7f |
Power Systems supports various service processor (IBM FSP, BMC, etc).
|
|
|
df7b7f |
|
|
|
df7b7f |
We have processor chip level VPD (part number, serial number etc) and
|
|
|
df7b7f |
all cores under chip shares this information.
|
|
|
df7b7f |
|
|
|
df7b7f |
On FSP based system, chip level vpd is available under '/vpd' node. This
|
|
|
df7b7f |
patch adds support to parse /vpd information and fill part, slot, serial
|
|
|
df7b7f |
number info for CPU nodes.
|
|
|
df7b7f |
|
|
|
df7b7f |
Sample output:
|
|
|
df7b7f |
*-cpu:0
|
|
|
df7b7f |
description: POWER8E (raw), altivec supported
|
|
|
df7b7f |
product: 00FY143 FRU #00FX519
|
|
|
df7b7f |
physical id: 32
|
|
|
df7b7f |
bus info: cpu@0
|
|
|
df7b7f |
version: 2.0 (pvr 004b 0200)
|
|
|
df7b7f |
serial: YA3932008163
|
|
|
df7b7f |
slot: U78C9.001.RST0027-P1-C32
|
|
|
df7b7f |
size: 2061MHz
|
|
|
df7b7f |
capacity: 4123MHz
|
|
|
df7b7f |
capabilities: performance-monitor cpufreq
|
|
|
df7b7f |
configuration: threads=8
|
|
|
df7b7f |
|
|
|
df7b7f |
Signed-off-by: Chandni Verma <chandni@linux.vnet.ibm.com>
|
|
|
df7b7f |
[Reorganized code, updated description - Vasant]
|
|
|
df7b7f |
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
|
|
|
df7b7f |
---
|
|
|
df7b7f |
src/core/device-tree.cc | 115 ++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
df7b7f |
1 file changed, 115 insertions(+)
|
|
|
df7b7f |
|
|
|
df7b7f |
diff --git a/src/core/device-tree.cc b/src/core/device-tree.cc
|
|
|
df7b7f |
index 9c74e5a..16406fd 100644
|
|
|
df7b7f |
--- a/src/core/device-tree.cc
|
|
|
df7b7f |
+++ b/src/core/device-tree.cc
|
|
|
df7b7f |
@@ -361,6 +361,107 @@ static void scan_devtree_cpu(hwNode & core)
|
|
|
df7b7f |
}
|
|
|
df7b7f |
}
|
|
|
df7b7f |
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+struct chip_vpd_data
|
|
|
df7b7f |
+{
|
|
|
df7b7f |
+ string product;
|
|
|
df7b7f |
+ string serial;
|
|
|
df7b7f |
+ string slot;
|
|
|
df7b7f |
+};
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+static void add_chip_vpd(string path, string name,
|
|
|
df7b7f |
+ map <uint32_t, chip_vpd_data *> & vpd)
|
|
|
df7b7f |
+{
|
|
|
df7b7f |
+ int n;
|
|
|
df7b7f |
+ struct dirent **dirlist;
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ pushd(path + name);
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ if (name.substr(0, 9) == "processor" && exists("ibm,chip-id"))
|
|
|
df7b7f |
+ {
|
|
|
df7b7f |
+ uint32_t chip_id = get_u32("ibm,chip-id");
|
|
|
df7b7f |
+ chip_vpd_data *data = new chip_vpd_data();
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ if (data)
|
|
|
df7b7f |
+ {
|
|
|
df7b7f |
+ if (exists("serial-number"))
|
|
|
df7b7f |
+ data->serial = hw::strip(get_string("serial-number"));
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ if (exists("ibm,loc-code"))
|
|
|
df7b7f |
+ data->slot = hw::strip(get_string("ibm,loc-code"));
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ if (exists("part-number"))
|
|
|
df7b7f |
+ data->product = hw::strip(get_string("part-number"));
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ if (exists("fru-number"))
|
|
|
df7b7f |
+ data->product += " FRU #" + hw::strip(get_string("fru-number"));
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ vpd.insert(std::pair<uint32_t, chip_vpd_data *>(chip_id, data));
|
|
|
df7b7f |
+ }
|
|
|
df7b7f |
+ }
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ n = scandir(".", &dirlist, selectdir, alphasort);
|
|
|
df7b7f |
+ popd();
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ if (n <= 0)
|
|
|
df7b7f |
+ return;
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ for (int i = 0; i < n; i++)
|
|
|
df7b7f |
+ {
|
|
|
df7b7f |
+ add_chip_vpd(path + name + "/", dirlist[i]->d_name, vpd);
|
|
|
df7b7f |
+ free(dirlist[i]);
|
|
|
df7b7f |
+ }
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ free(dirlist);
|
|
|
df7b7f |
+}
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+static void scan_chip_vpd(map <uint32_t, chip_vpd_data *> & vpd)
|
|
|
df7b7f |
+{
|
|
|
df7b7f |
+ int n;
|
|
|
df7b7f |
+ struct dirent **namelist;
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ if (!exists(DEVICETREEVPD))
|
|
|
df7b7f |
+ return;
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ pushd(DEVICETREEVPD);
|
|
|
df7b7f |
+ n = scandir(".", &namelist, selectdir, alphasort);
|
|
|
df7b7f |
+ popd();
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ if (n <= 0)
|
|
|
df7b7f |
+ return;
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ for (int i = 0; i < n; i++)
|
|
|
df7b7f |
+ {
|
|
|
df7b7f |
+ add_chip_vpd(DEVICETREEVPD, namelist[i]->d_name, vpd);
|
|
|
df7b7f |
+ free(namelist[i]);
|
|
|
df7b7f |
+ }
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ free(namelist);
|
|
|
df7b7f |
+}
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+static void fill_core_vpd(hwNode & cpu, string & basepath,
|
|
|
df7b7f |
+ map <uint32_t, chip_vpd_data *> & chip_vpd)
|
|
|
df7b7f |
+{
|
|
|
df7b7f |
+ uint32_t chip_id;
|
|
|
df7b7f |
+ chip_vpd_data *data;
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ if (!exists(basepath + "/ibm,chip-id"))
|
|
|
df7b7f |
+ return;
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ chip_id = get_u32(basepath + "/ibm,chip-id");
|
|
|
df7b7f |
+ data = chip_vpd[chip_id];
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ if (data)
|
|
|
df7b7f |
+ {
|
|
|
df7b7f |
+ cpu.setProduct(data->product);
|
|
|
df7b7f |
+ cpu.setSerial(data->serial);
|
|
|
df7b7f |
+ cpu.setSlot(data->slot);
|
|
|
df7b7f |
+ }
|
|
|
df7b7f |
+}
|
|
|
df7b7f |
+
|
|
|
df7b7f |
static void set_cpu_config_threads(hwNode & cpu, const string & basepath)
|
|
|
df7b7f |
{
|
|
|
df7b7f |
static int threads_per_cpu = 0;
|
|
|
df7b7f |
@@ -394,6 +495,7 @@ static void scan_devtree_cpu_power(hwNode & core)
|
|
|
df7b7f |
struct dirent **namelist;
|
|
|
df7b7f |
map <uint32_t, pair<uint32_t, vector <hwNode> > > l2_caches;
|
|
|
df7b7f |
map <uint32_t, vector <hwNode> > l3_caches;
|
|
|
df7b7f |
+ map <uint32_t, chip_vpd_data *> chip_vpd;
|
|
|
df7b7f |
|
|
|
df7b7f |
pushd(DEVICETREE "/cpus");
|
|
|
df7b7f |
n = scandir(".", &namelist, selectdir, alphasort);
|
|
|
df7b7f |
@@ -469,6 +571,13 @@ static void scan_devtree_cpu_power(hwNode & core)
|
|
|
df7b7f |
}
|
|
|
df7b7f |
} // first pass end
|
|
|
df7b7f |
|
|
|
df7b7f |
+ /*
|
|
|
df7b7f |
+ * We have chip level VPD information (like part number, slot, etc).
|
|
|
df7b7f |
+ * and this information is same for all cores under chip.
|
|
|
df7b7f |
+ * Fetch chip-level VPD from /vpd node.
|
|
|
df7b7f |
+ */
|
|
|
df7b7f |
+ scan_chip_vpd(chip_vpd);
|
|
|
df7b7f |
+
|
|
|
df7b7f |
for (int i = 0; i < n; i++) //second and final pass
|
|
|
df7b7f |
{
|
|
|
df7b7f |
uint32_t l2_key = 0;
|
|
|
df7b7f |
@@ -499,6 +608,8 @@ static void scan_devtree_cpu_power(hwNode & core)
|
|
|
df7b7f |
if (version != 0)
|
|
|
df7b7f |
cpu.setVersion(tostring(version));
|
|
|
df7b7f |
|
|
|
df7b7f |
+ fill_core_vpd(cpu, basepath, chip_vpd);
|
|
|
df7b7f |
+
|
|
|
df7b7f |
if (hw::strip(get_string(basepath + "/status")) != "okay")
|
|
|
df7b7f |
cpu.disable();
|
|
|
df7b7f |
|
|
|
df7b7f |
@@ -548,6 +659,10 @@ static void scan_devtree_cpu_power(hwNode & core)
|
|
|
df7b7f |
free(namelist[i]);
|
|
|
df7b7f |
}
|
|
|
df7b7f |
free(namelist);
|
|
|
df7b7f |
+
|
|
|
df7b7f |
+ map <uint32_t, chip_vpd_data *>::iterator it;
|
|
|
df7b7f |
+ for (it = chip_vpd.begin(); it != chip_vpd.end(); it++)
|
|
|
df7b7f |
+ delete it->second;
|
|
|
df7b7f |
}
|
|
|
df7b7f |
|
|
|
df7b7f |
void add_memory_bank(string name, string path, hwNode & core)
|
|
|
df7b7f |
--
|
|
|
df7b7f |
2.10.2
|
|
|
df7b7f |
|