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

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