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