PASS 2 Planar support for vpd parser
The system has two planar passes - Pass1 & Pass2 Planars.
Pass1 Planar a buffer connects all pcie cards, Whereas
Pass2 Planar has mux connection established for pcie card selection.
ibm-read-vpd picks up the right deviceTree and json
(either 2UPass1/2UPass2/4UPass1/4UPass2)
based on the HW and IM kw of the planar.
Test-
tested on Rainier 2U simics
root@rainier:/tmp# ./ibm-read-vpd -f /tmp/systemVpd
imKeyword- 50001001, HW - 0001
Processing with this JSON - /usr/share/vpd/50001001_v1.json
root@rainier:/tmp# ./ibm-read-vpd -f /tmp/systemVpd
imKeyword- 50001001, HW - 0011
Processing with this JSON - /usr/share/vpd/50001001_v2.json
root@rainier:/tmp# ./ibm-read-vpd -f /tmp/systemVpd
imKeyword- 50001000, HW - 0011
Processing with this JSON - /usr/share/vpd/50001000_v2.json
root@rainier:/tmp# ./ibm-read-vpd -f /tmp/systemVpd
imKeyword- 50001000, HW - 0001
Processing with this JSON - /usr/share/vpd/50001000_v1.json
root@rainier:/tmp#
Signed-off-by: Alpana Kumari <alpankum@in.ibm.com>
Change-Id: I36de12d9697039e61e6ad569e1e119f001e782f6
diff --git a/const.hpp b/const.hpp
index 6ab10e5..92107fa 100644
--- a/const.hpp
+++ b/const.hpp
@@ -49,8 +49,10 @@
constexpr uint8_t EXP_LOCATIN_CODE_MIN_LENGTH = 17;
static constexpr auto SE_KWD_LENGTH = 7;
static constexpr auto INVALID_NODE_NUMBER = -1;
-static constexpr auto RAINIER_2U = "50001001";
-static constexpr auto RAINIER_4U = "50001000";
+static constexpr auto RAINIER_2U = "50001001_0001";
+static constexpr auto RAINIER_2U_V2 = "50001001_0002";
+static constexpr auto RAINIER_4U = "50001000_0001";
+static constexpr auto RAINIER_4U_V2 = "50001000_0002";
static constexpr auto RAINIER_1S4U = "50001002";
static constexpr auto EVEREST = "50003000";
diff --git a/ibm_vpd_app.cpp b/ibm_vpd_app.cpp
index 089ad9e..6532982 100644
--- a/ibm_vpd_app.cpp
+++ b/ibm_vpd_app.cpp
@@ -40,7 +40,9 @@
static const deviceTreeMap deviceTreeSystemTypeMap = {
{RAINIER_2U, "conf-aspeed-bmc-ibm-rainier.dtb"},
+ {RAINIER_2U_V2, "conf-aspeed-bmc-ibm-rainier-v2.dtb"},
{RAINIER_4U, "conf-aspeed-bmc-ibm-rainier-4u.dtb"},
+ {RAINIER_4U_V2, "conf-aspeed-bmc-ibm-rainier-4u-v2.dtb"},
{RAINIER_1S4U, "conf-aspeed-bmc-ibm-rainier-1s4u.dtb"},
{EVEREST, "conf-aspeed-bmc-ibm-everest.dtb"}};
@@ -807,59 +809,16 @@
if (isSystemVpd)
{
- vector<uint8_t> imVal;
+ string systemJson{};
if constexpr (is_same<T, Parsed>::value)
{
- auto property = vpdMap.find("VSBP");
- if (property != vpdMap.end())
- {
- auto value = (property->second).find("IM");
- if (value != (property->second).end())
- {
- copy(value->second.begin(), value->second.end(),
- back_inserter(imVal));
- }
- }
+ // pick the right system json
+ systemJson = getSystemsJson(vpdMap);
}
- fs::path target;
+ fs::path target = systemJson;
fs::path link = INVENTORY_JSON_SYM_LINK;
- ostringstream oss;
- for (auto& i : imVal)
- {
- oss << setw(2) << setfill('0') << hex << static_cast<int>(i);
- }
- string imValStr = oss.str();
-
- if ((imValStr == RAINIER_4U) || // 4U
- (imValStr == RAINIER_1S4U))
- {
- target = INVENTORY_JSON_4U;
- }
- else if (imValStr == RAINIER_2U) // 2U
- {
- target = INVENTORY_JSON_2U;
- }
- else if (imValStr == EVEREST)
- {
- target = INVENTORY_JSON_EVEREST;
- }
- else
- {
- PelAdditionalData additionalData{};
- const string& baseFruInventoryPath =
- js["frus"][filePath][0]["inventoryPath"].get_ref<string&>();
- additionalData.emplace("CALLOUT_INVENTORY_PATH",
- INVENTORY_PATH + baseFruInventoryPath);
- additionalData.emplace(
- "DESCRIPTION", "System IM value is erroneous/not supported.");
- additionalData.emplace("INVALID IM VALUE", imValStr);
- createPEL(additionalData, PelSeverity::ERROR, errIntfForInvalidVPD);
- throw runtime_error(
- "Erroneous/Unsupported IM in System VPD. PEL logged.");
- }
-
// Create the directory for hosting the symlink
fs::create_directories(VPD_FILES_PATH);
// unlink the symlink previously created (if any)
@@ -875,15 +834,50 @@
inventory::ObjectMap primeObject = primeInventory(js, vpdMap);
objects.insert(primeObject.begin(), primeObject.end());
- // set the U-boot environment variable for device-tree
- setDevTreeEnv(imValStr);
-
// if system VPD has been restored at standby, update the EEPROM
for (const auto& item : updatedEeproms)
{
updateHardware(get<0>(item), get<1>(item), get<2>(item),
get<3>(item));
}
+
+ // set the U-boot environment variable for device-tree
+ if constexpr (is_same<T, Parsed>::value)
+ {
+ const string imKeyword = getIM(vpdMap);
+ const string hwKeyword = getHW(vpdMap);
+ string systemType = imKeyword;
+
+ // check If system has constraint then append HW version to it.
+ ifstream sysJson(SYSTEM_JSON);
+ if (!sysJson)
+ {
+ throw((VpdJsonException("Failed to access Json path",
+ SYSTEM_JSON)));
+ }
+
+ try
+ {
+ auto systemJson = json::parse(sysJson);
+ }
+ catch (json::parse_error& ex)
+ {
+ throw((VpdJsonException("System Json parsing failed",
+ SYSTEM_JSON)));
+ }
+
+ if (systemJson["system"].find(imKeyword) !=
+ systemJson["system"].end())
+ {
+ if (systemJson["system"][imKeyword].find("constraint") !=
+ systemJson["system"][imKeyword].end())
+ {
+ systemType += "_" + hwKeyword;
+ }
+ }
+
+ setDevTreeEnv(systemType);
+ }
}
// Notify PIM
diff --git a/ibm_vpd_utils.cpp b/ibm_vpd_utils.cpp
index 6577969..15e3116 100644
--- a/ibm_vpd_utils.cpp
+++ b/ibm_vpd_utils.cpp
@@ -318,5 +318,107 @@
return vpdType::INVALID_VPD_FORMAT;
}
+const string getIM(const Parsed& vpdMap)
+{
+ Binary imVal;
+ auto property = vpdMap.find("VSBP");
+ if (property != vpdMap.end())
+ {
+ auto kw = (property->second).find("IM");
+ if (kw != (property->second).end())
+ {
+ copy(kw->second.begin(), kw->second.end(), back_inserter(imVal));
+ }
+ }
+
+ ostringstream oss;
+ for (auto& i : imVal)
+ {
+ oss << setw(2) << setfill('0') << hex << static_cast<int>(i);
+ }
+
+ return oss.str();
+}
+
+const string getHW(const Parsed& vpdMap)
+{
+ Binary hwVal;
+ auto prop = vpdMap.find("VINI");
+ if (prop != vpdMap.end())
+ {
+ auto kw = (prop->second).find("HW");
+ if (kw != (prop->second).end())
+ {
+ copy(kw->second.begin(), kw->second.end(), back_inserter(hwVal));
+ }
+ }
+
+ ostringstream hwString;
+ for (auto& i : hwVal)
+ {
+ hwString << setw(2) << setfill('0') << hex << static_cast<int>(i);
+ }
+
+ return hwString.str();
+}
+
+string getSystemsJson(const Parsed& vpdMap)
+{
+ string jsonPath = "/usr/share/vpd/";
+ string jsonName{};
+
+ ifstream systemJson(SYSTEM_JSON);
+ if (!systemJson)
+ {
+ throw((VpdJsonException("Failed to access Json path", SYSTEM_JSON)));
+ }
+
+ try
+ {
+ auto js = json::parse(systemJson);
+
+ const string hwKeyword = getHW(vpdMap);
+ const string imKeyword = getIM(vpdMap);
+
+ if (js.find("system") == js.end())
+ {
+ throw runtime_error("Invalid systems Json");
+ }
+
+ if (js["system"].find(imKeyword) == js["system"].end())
+ {
+ throw runtime_error(
+ "Invalid system. This system type is not present "
+ "in the systemsJson. IM: " +
+ imKeyword);
+ }
+
+ if ((js["system"][imKeyword].find("constraint") !=
+ js["system"][imKeyword].end()) &&
+ (hwKeyword == js["system"][imKeyword]["constraint"]["HW"]))
+ {
+ jsonName = js["system"][imKeyword]["constraint"]["json"];
+ }
+ else if (js["system"][imKeyword].find("default") !=
+ js["system"][imKeyword].end())
+ {
+ jsonName = js["system"][imKeyword]["default"];
+ }
+ else
+ {
+ throw runtime_error(
+ "Bad System json. Neither constraint nor default found");
+ }
+
+ jsonPath += jsonName;
+ }
+
+ catch (json::parse_error& ex)
+ {
+ throw(VpdJsonException("Json Parsing failed", SYSTEM_JSON));
+ }
+ return jsonPath;
+}
+
} // namespace vpd
-} // namespace openpower
+} // namespace openpower
\ No newline at end of file
diff --git a/ibm_vpd_utils.hpp b/ibm_vpd_utils.hpp
index 9aaebee..29996a9 100644
--- a/ibm_vpd_utils.hpp
+++ b/ibm_vpd_utils.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "const.hpp"
+#include "store.hpp"
#include "types.hpp"
#include <iostream>
@@ -162,5 +163,24 @@
return stdOutput;
}
+/** @brief This API checks for IM and HW keywords, and based
+ * on these values decides which system json to be used.
+ * @param[in] vpdMap - parsed vpd
+ * @returns System json path
+ */
+string getSystemsJson(const Parsed& vpdMap);
+
+/** @brief Reads HW Keyword from the vpd
+ * @param[in] vpdMap - parsed vpd
+ * @returns value of HW Keyword
+ */
+const string getHW(const Parsed& vpdMap);
+
+/** @brief Reads IM Keyword from the vpd
+ * @param[in] vpdMap - parsed vpd
+ * @returns value of IM Keyword
+ */
+const string getIM(const Parsed& vpdMap);
+
} // namespace vpd
-} // namespace openpower
+} // namespace openpower
\ No newline at end of file
diff --git a/meson.build b/meson.build
index e05edc3..f9c340a 100644
--- a/meson.build
+++ b/meson.build
@@ -48,7 +48,8 @@
'INVENTORY_JSON_2U': '"'+get_option('INVENTORY_JSON_2U')+'"',
'INVENTORY_JSON_4U': '"'+get_option('INVENTORY_JSON_4U')+'"',
'INVENTORY_JSON_EVEREST': '"'+get_option('INVENTORY_JSON_EVEREST')+'"',
- 'DBUS_PROP_JSON': '"'+get_option('DBUS_PROP_JSON')+'"'
+ 'DBUS_PROP_JSON': '"'+get_option('DBUS_PROP_JSON')+'"',
+ 'SYSTEM_JSON' : '"'+get_option('SYSTEM_JSON')+'"'
}
)
diff --git a/meson_options.txt b/meson_options.txt
index f5c839c..20697d6 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -21,3 +21,4 @@
option('INVENTORY_JSON_4U',type: 'string', value: '/usr/share/vpd/50001000.json', description: 'Inventory JSON for 4U system.')
option('INVENTORY_JSON_EVEREST',type: 'string', value: '/usr/share/vpd/50003000.json', description: 'Inventory JSON for Everest system.')
option('DBUS_PROP_JSON',type: 'string', value: '/usr/share/vpd/dbus_properties.json', description: 'Json which contains properties specific to dbus.')
+option('SYSTEM_JSON',type: 'string', value: '/usr/share/vpd/systems.json', description: 'JSON file used to pick the right system json')