Blame SOURCES/0024-devtree-Add-VPD-info-for-FSP-based-Power-System.patch

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