| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1 | #include "config.h" | 
 | 2 |  | 
| Sunny Srivastava | 6c71c9d | 2021-04-15 04:43:54 -0500 | [diff] [blame] | 3 | #include "common_utility.hpp" | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 4 | #include "defines.hpp" | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 5 | #include "editor_impl.hpp" | 
| Sunny Srivastava | 6c71c9d | 2021-04-15 04:43:54 -0500 | [diff] [blame] | 6 | #include "ibm_vpd_utils.hpp" | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 7 | #include "ipz_parser.hpp" | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 8 | #include "keyword_vpd_parser.hpp" | 
| Alpana Kumari | a00936f | 2020-04-14 07:15:46 -0500 | [diff] [blame] | 9 | #include "memory_vpd_parser.hpp" | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 10 | #include "parser_factory.hpp" | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 11 | #include "vpd_exceptions.hpp" | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 12 |  | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 13 | #include <assert.h> | 
| Alpana Kumari | 8ea3f6d | 2020-04-02 00:26:07 -0500 | [diff] [blame] | 14 | #include <ctype.h> | 
 | 15 |  | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 16 | #include <CLI/CLI.hpp> | 
| alpana07 | 7ce6872 | 2021-07-25 13:23:59 -0500 | [diff] [blame] | 17 | #include <boost/algorithm/string.hpp> | 
| Patrick Williams | c78d887 | 2023-05-10 07:50:56 -0500 | [diff] [blame] | 18 | #include <gpiod.hpp> | 
 | 19 | #include <phosphor-logging/log.hpp> | 
 | 20 |  | 
 | 21 | #include <algorithm> | 
| Alpana Kumari | 65b8360 | 2020-09-01 00:24:56 -0500 | [diff] [blame] | 22 | #include <cstdarg> | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 23 | #include <exception> | 
| PriyangaRamasamy | 83a1d5d | 2020-04-30 19:15:43 +0530 | [diff] [blame] | 24 | #include <filesystem> | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 25 | #include <fstream> | 
 | 26 | #include <iostream> | 
 | 27 | #include <iterator> | 
| alpana07 | 7ce6872 | 2021-07-25 13:23:59 -0500 | [diff] [blame] | 28 | #include <regex> | 
| Santosh Puranik | 253fbe9 | 2022-10-06 22:38:09 +0530 | [diff] [blame] | 29 | #include <thread> | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 30 |  | 
 | 31 | using namespace std; | 
 | 32 | using namespace openpower::vpd; | 
 | 33 | using namespace CLI; | 
 | 34 | using namespace vpd::keyword::parser; | 
| PriyangaRamasamy | 83a1d5d | 2020-04-30 19:15:43 +0530 | [diff] [blame] | 35 | using namespace openpower::vpd::constants; | 
 | 36 | namespace fs = filesystem; | 
 | 37 | using json = nlohmann::json; | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 38 | using namespace openpower::vpd::parser::factory; | 
| SunnySrivastava1984 | 945a02d | 2020-05-06 01:55:41 -0500 | [diff] [blame] | 39 | using namespace openpower::vpd::inventory; | 
| Alpana Kumari | a00936f | 2020-04-14 07:15:46 -0500 | [diff] [blame] | 40 | using namespace openpower::vpd::memory::parser; | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 41 | using namespace openpower::vpd::parser::interface; | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 42 | using namespace openpower::vpd::exceptions; | 
| Andrew Geissler | 280197e | 2020-12-08 20:51:49 -0600 | [diff] [blame] | 43 | using namespace phosphor::logging; | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 44 | using namespace openpower::vpd::manager::editor; | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 45 |  | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 46 | /** | 
| Sunny Srivastava | 37992a6 | 2023-07-11 05:18:41 -0500 | [diff] [blame] | 47 |  * @brief API declaration, Populate Dbus. | 
 | 48 |  * | 
 | 49 |  * This method invokes all the populateInterface functions | 
 | 50 |  * and notifies PIM about dbus object. | 
 | 51 |  * | 
 | 52 |  * @param[in] vpdMap - Either IPZ vpd map or Keyword vpd map based on the | 
 | 53 |  * input. | 
 | 54 |  * @param[in] js - Inventory json object | 
 | 55 |  * @param[in] filePath - Path of the vpd file | 
 | 56 |  * @param[in] preIntrStr - Interface string | 
 | 57 |  */ | 
 | 58 | template <typename T> | 
 | 59 | static void populateDbus(T& vpdMap, nlohmann::json& js, const string& filePath); | 
 | 60 |  | 
 | 61 | /** | 
| Santosh Puranik | e9c5753 | 2022-03-15 16:51:51 +0530 | [diff] [blame] | 62 |  * @brief Returns the BMC state | 
 | 63 |  */ | 
 | 64 | static auto getBMCState() | 
 | 65 | { | 
 | 66 |     std::string bmcState; | 
 | 67 |     try | 
 | 68 |     { | 
 | 69 |         auto bus = sdbusplus::bus::new_default(); | 
 | 70 |         auto properties = bus.new_method_call( | 
 | 71 |             "xyz.openbmc_project.State.BMC", "/xyz/openbmc_project/state/bmc0", | 
 | 72 |             "org.freedesktop.DBus.Properties", "Get"); | 
 | 73 |         properties.append("xyz.openbmc_project.State.BMC"); | 
 | 74 |         properties.append("CurrentBMCState"); | 
 | 75 |         auto result = bus.call(properties); | 
 | 76 |         std::variant<std::string> val; | 
 | 77 |         result.read(val); | 
 | 78 |         if (auto pVal = std::get_if<std::string>(&val)) | 
 | 79 |         { | 
 | 80 |             bmcState = *pVal; | 
 | 81 |         } | 
 | 82 |     } | 
 | 83 |     catch (const sdbusplus::exception::SdBusError& e) | 
 | 84 |     { | 
 | 85 |         // Ignore any error | 
 | 86 |         std::cerr << "Failed to get BMC state: " << e.what() << "\n"; | 
| Jinu Joy Thomas | 0b33b34 | 2024-02-27 21:44:24 -0600 | [diff] [blame] | 87 |         // Since we failed set to not ready state | 
 | 88 |         bmcState = "xyz.openbmc_project.State.BMC.BMCState.NotReady"; | 
| Santosh Puranik | e9c5753 | 2022-03-15 16:51:51 +0530 | [diff] [blame] | 89 |     } | 
 | 90 |     return bmcState; | 
 | 91 | } | 
 | 92 |  | 
 | 93 | /** | 
 | 94 |  * @brief Check if the FRU is in the cache | 
 | 95 |  * | 
 | 96 |  * Checks if the FRU associated with the supplied D-Bus object path is already | 
 | 97 |  * on D-Bus. This can be used to test if a VPD collection is required for this | 
 | 98 |  * FRU. It uses the "xyz.openbmc_project.Inventory.Item, Present" property to | 
 | 99 |  * determine the presence of a FRU in the cache. | 
 | 100 |  * | 
 | 101 |  * @param objectPath - The D-Bus object path without the PIM prefix. | 
 | 102 |  * @return true if the object exists on D-Bus, false otherwise. | 
 | 103 |  */ | 
 | 104 | static auto isFruInVpdCache(const std::string& objectPath) | 
 | 105 | { | 
 | 106 |     try | 
 | 107 |     { | 
 | 108 |         auto bus = sdbusplus::bus::new_default(); | 
 | 109 |         auto invPath = std::string{pimPath} + objectPath; | 
 | 110 |         auto props = bus.new_method_call( | 
 | 111 |             "xyz.openbmc_project.Inventory.Manager", invPath.c_str(), | 
 | 112 |             "org.freedesktop.DBus.Properties", "Get"); | 
 | 113 |         props.append("xyz.openbmc_project.Inventory.Item"); | 
 | 114 |         props.append("Present"); | 
 | 115 |         auto result = bus.call(props); | 
 | 116 |         std::variant<bool> present; | 
 | 117 |         result.read(present); | 
 | 118 |         if (auto pVal = std::get_if<bool>(&present)) | 
 | 119 |         { | 
 | 120 |             return *pVal; | 
 | 121 |         } | 
 | 122 |         return false; | 
 | 123 |     } | 
 | 124 |     catch (const sdbusplus::exception::SdBusError& e) | 
 | 125 |     { | 
 | 126 |         std::cout << "FRU: " << objectPath << " not in D-Bus\n"; | 
 | 127 |         // Assume not present in case of an error | 
 | 128 |         return false; | 
 | 129 |     } | 
 | 130 | } | 
 | 131 |  | 
 | 132 | /** | 
 | 133 |  * @brief Check if VPD recollection is needed for the given EEPROM | 
 | 134 |  * | 
 | 135 |  * Not all FRUs can be swapped at BMC ready state. This function does the | 
 | 136 |  * following: | 
 | 137 |  * -- Check if the FRU is marked as "pluggableAtStandby" OR | 
 | 138 |  *    "concurrentlyMaintainable". If so, return true. | 
 | 139 |  * -- Check if we are at BMC NotReady state. If we are, then return true. | 
 | 140 |  * -- Else check if the FRU is not present in the VPD cache (to cover for VPD | 
 | 141 |  *    force collection). If not found in the cache, return true. | 
 | 142 |  * -- Else return false. | 
 | 143 |  * | 
 | 144 |  * @param js - JSON Object. | 
 | 145 |  * @param filePath - The EEPROM file. | 
 | 146 |  * @return true if collection should be attempted, false otherwise. | 
 | 147 |  */ | 
 | 148 | static auto needsRecollection(const nlohmann::json& js, const string& filePath) | 
 | 149 | { | 
 | 150 |     if (js["frus"][filePath].at(0).value("pluggableAtStandby", false) || | 
 | 151 |         js["frus"][filePath].at(0).value("concurrentlyMaintainable", false)) | 
 | 152 |     { | 
 | 153 |         return true; | 
 | 154 |     } | 
 | 155 |     if (getBMCState() == "xyz.openbmc_project.State.BMC.BMCState.NotReady") | 
 | 156 |     { | 
 | 157 |         return true; | 
 | 158 |     } | 
 | 159 |     if (!isFruInVpdCache(js["frus"][filePath].at(0).value("inventoryPath", ""))) | 
 | 160 |     { | 
 | 161 |         return true; | 
 | 162 |     } | 
 | 163 |     return false; | 
 | 164 | } | 
 | 165 |  | 
 | 166 | /** | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 167 |  * @brief Expands location codes | 
 | 168 |  */ | 
 | 169 | static auto expandLocationCode(const string& unexpanded, const Parsed& vpdMap, | 
 | 170 |                                bool isSystemVpd) | 
 | 171 | { | 
 | 172 |     auto expanded{unexpanded}; | 
 | 173 |     static constexpr auto SYSTEM_OBJECT = "/system/chassis/motherboard"; | 
 | 174 |     static constexpr auto VCEN_IF = "com.ibm.ipzvpd.VCEN"; | 
 | 175 |     static constexpr auto VSYS_IF = "com.ibm.ipzvpd.VSYS"; | 
 | 176 |     size_t idx = expanded.find("fcs"); | 
 | 177 |     try | 
 | 178 |     { | 
 | 179 |         if (idx != string::npos) | 
 | 180 |         { | 
 | 181 |             string fc{}; | 
 | 182 |             string se{}; | 
 | 183 |             if (isSystemVpd) | 
 | 184 |             { | 
 | 185 |                 const auto& fcData = vpdMap.at("VCEN").at("FC"); | 
 | 186 |                 const auto& seData = vpdMap.at("VCEN").at("SE"); | 
 | 187 |                 fc = string(fcData.data(), fcData.size()); | 
 | 188 |                 se = string(seData.data(), seData.size()); | 
 | 189 |             } | 
 | 190 |             else | 
 | 191 |             { | 
 | 192 |                 fc = readBusProperty(SYSTEM_OBJECT, VCEN_IF, "FC"); | 
 | 193 |                 se = readBusProperty(SYSTEM_OBJECT, VCEN_IF, "SE"); | 
 | 194 |             } | 
 | 195 |  | 
| Alpana Kumari | 81671f6 | 2021-02-10 02:21:59 -0600 | [diff] [blame] | 196 |             // TODO: See if ND0 can be placed in the JSON | 
 | 197 |             expanded.replace(idx, 3, fc.substr(0, 4) + ".ND0." + se); | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 198 |         } | 
 | 199 |         else | 
 | 200 |         { | 
 | 201 |             idx = expanded.find("mts"); | 
 | 202 |             if (idx != string::npos) | 
 | 203 |             { | 
 | 204 |                 string mt{}; | 
 | 205 |                 string se{}; | 
 | 206 |                 if (isSystemVpd) | 
 | 207 |                 { | 
 | 208 |                     const auto& mtData = vpdMap.at("VSYS").at("TM"); | 
 | 209 |                     const auto& seData = vpdMap.at("VSYS").at("SE"); | 
 | 210 |                     mt = string(mtData.data(), mtData.size()); | 
 | 211 |                     se = string(seData.data(), seData.size()); | 
 | 212 |                 } | 
 | 213 |                 else | 
 | 214 |                 { | 
 | 215 |                     mt = readBusProperty(SYSTEM_OBJECT, VSYS_IF, "TM"); | 
 | 216 |                     se = readBusProperty(SYSTEM_OBJECT, VSYS_IF, "SE"); | 
 | 217 |                 } | 
 | 218 |  | 
 | 219 |                 replace(mt.begin(), mt.end(), '-', '.'); | 
 | 220 |                 expanded.replace(idx, 3, mt + "." + se); | 
 | 221 |             } | 
 | 222 |         } | 
 | 223 |     } | 
| Patrick Williams | 8e15b93 | 2021-10-06 13:04:22 -0500 | [diff] [blame] | 224 |     catch (const exception& e) | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 225 |     { | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 226 |         std::cerr << "Failed to expand location code with exception: " | 
 | 227 |                   << e.what() << "\n"; | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 228 |     } | 
 | 229 |     return expanded; | 
 | 230 | } | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 231 |  | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 232 | /** | 
 | 233 |  * @brief Populate FRU specific interfaces. | 
 | 234 |  * | 
 | 235 |  * This is a common method which handles both | 
 | 236 |  * ipz and keyword specific interfaces thus, | 
 | 237 |  * reducing the code redundancy. | 
 | 238 |  * @param[in] map - Reference to the innermost keyword-value map. | 
 | 239 |  * @param[in] preIntrStr - Reference to the interface string. | 
 | 240 |  * @param[out] interfaces - Reference to interface map. | 
 | 241 |  */ | 
 | 242 | template <typename T> | 
| Patrick Williams | 08dc31c | 2024-08-16 15:21:06 -0400 | [diff] [blame] | 243 | static void populateFruSpecificInterfaces( | 
 | 244 |     const T& map, const string& preIntrStr, inventory::InterfaceMap& interfaces) | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 245 | { | 
 | 246 |     inventory::PropertyMap prop; | 
 | 247 |  | 
 | 248 |     for (const auto& kwVal : map) | 
 | 249 |     { | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 250 |         auto kw = kwVal.first; | 
 | 251 |  | 
 | 252 |         if (kw[0] == '#') | 
 | 253 |         { | 
| Alpana Kumari | 58e2214 | 2020-05-05 00:22:12 -0500 | [diff] [blame] | 254 |             kw = string("PD_") + kw[1]; | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 255 |         } | 
| Alpana Kumari | 8ea3f6d | 2020-04-02 00:26:07 -0500 | [diff] [blame] | 256 |         else if (isdigit(kw[0])) | 
 | 257 |         { | 
| Alpana Kumari | 58e2214 | 2020-05-05 00:22:12 -0500 | [diff] [blame] | 258 |             kw = string("N_") + kw; | 
| Alpana Kumari | 8ea3f6d | 2020-04-02 00:26:07 -0500 | [diff] [blame] | 259 |         } | 
| Alpana Kumari | 3ab26a7 | 2021-04-05 19:09:19 +0000 | [diff] [blame] | 260 |         if constexpr (is_same<T, KeywordVpdMap>::value) | 
 | 261 |         { | 
| jinuthomas | d640f69 | 2023-03-28 04:13:23 -0500 | [diff] [blame] | 262 |             if (auto keywordValue = get_if<Binary>(&kwVal.second)) | 
| Alpana Kumari | 3ab26a7 | 2021-04-05 19:09:19 +0000 | [diff] [blame] | 263 |             { | 
| jinuthomas | d640f69 | 2023-03-28 04:13:23 -0500 | [diff] [blame] | 264 |                 Binary vec((*keywordValue).begin(), (*keywordValue).end()); | 
| Alpana Kumari | 3ab26a7 | 2021-04-05 19:09:19 +0000 | [diff] [blame] | 265 |                 prop.emplace(move(kw), move(vec)); | 
 | 266 |             } | 
| jinuthomas | d640f69 | 2023-03-28 04:13:23 -0500 | [diff] [blame] | 267 |             else if (auto keywordValue = get_if<std::string>(&kwVal.second)) | 
 | 268 |             { | 
 | 269 |                 Binary vec((*keywordValue).begin(), (*keywordValue).end()); | 
 | 270 |                 prop.emplace(move(kw), move(vec)); | 
 | 271 |             } | 
 | 272 |             else if (auto keywordValue = get_if<size_t>(&kwVal.second)) | 
| Alpana Kumari | 3ab26a7 | 2021-04-05 19:09:19 +0000 | [diff] [blame] | 273 |             { | 
 | 274 |                 if (kw == "MemorySizeInKB") | 
 | 275 |                 { | 
 | 276 |                     inventory::PropertyMap memProp; | 
| jinuthomas | d640f69 | 2023-03-28 04:13:23 -0500 | [diff] [blame] | 277 |                     memProp.emplace(move(kw), ((*keywordValue))); | 
 | 278 |                     interfaces.emplace( | 
 | 279 |                         "xyz.openbmc_project.Inventory.Item.Dimm", | 
 | 280 |                         move(memProp)); | 
| Alpana Kumari | 3ab26a7 | 2021-04-05 19:09:19 +0000 | [diff] [blame] | 281 |                 } | 
| jinuthomas | d640f69 | 2023-03-28 04:13:23 -0500 | [diff] [blame] | 282 |                 else | 
 | 283 |                 { | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 284 |                     std::cerr << "Unknown Keyword[" << kw << "] found "; | 
| jinuthomas | d640f69 | 2023-03-28 04:13:23 -0500 | [diff] [blame] | 285 |                 } | 
 | 286 |             } | 
 | 287 |             else | 
 | 288 |             { | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 289 |                 std::cerr << "Unknown Variant found "; | 
| Alpana Kumari | 3ab26a7 | 2021-04-05 19:09:19 +0000 | [diff] [blame] | 290 |             } | 
 | 291 |         } | 
 | 292 |         else | 
 | 293 |         { | 
 | 294 |             Binary vec(kwVal.second.begin(), kwVal.second.end()); | 
 | 295 |             prop.emplace(move(kw), move(vec)); | 
 | 296 |         } | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 297 |     } | 
 | 298 |  | 
 | 299 |     interfaces.emplace(preIntrStr, move(prop)); | 
 | 300 | } | 
 | 301 |  | 
 | 302 | /** | 
 | 303 |  * @brief Populate Interfaces. | 
 | 304 |  * | 
 | 305 |  * This method populates common and extra interfaces to dbus. | 
 | 306 |  * @param[in] js - json object | 
 | 307 |  * @param[out] interfaces - Reference to interface map | 
 | 308 |  * @param[in] vpdMap - Reference to the parsed vpd map. | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 309 |  * @param[in] isSystemVpd - Denotes whether we are collecting the system VPD. | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 310 |  */ | 
 | 311 | template <typename T> | 
 | 312 | static void populateInterfaces(const nlohmann::json& js, | 
 | 313 |                                inventory::InterfaceMap& interfaces, | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 314 |                                const T& vpdMap, bool isSystemVpd) | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 315 | { | 
 | 316 |     for (const auto& ifs : js.items()) | 
 | 317 |     { | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 318 |         string inf = ifs.key(); | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 319 |         inventory::PropertyMap props; | 
 | 320 |  | 
 | 321 |         for (const auto& itr : ifs.value().items()) | 
 | 322 |         { | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 323 |             const string& busProp = itr.key(); | 
 | 324 |  | 
| Alpana Kumari | 31970de | 2020-02-17 06:49:57 -0600 | [diff] [blame] | 325 |             if (itr.value().is_boolean()) | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 326 |             { | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 327 |                 props.emplace(busProp, itr.value().get<bool>()); | 
 | 328 |             } | 
 | 329 |             else if (itr.value().is_string()) | 
 | 330 |             { | 
| Priyanga Ramasamy | 0d61c58 | 2022-01-21 04:38:22 -0600 | [diff] [blame] | 331 |                 if (busProp == "LocationCode" && inf == IBM_LOCATION_CODE_INF) | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 332 |                 { | 
| Priyanga Ramasamy | 0d61c58 | 2022-01-21 04:38:22 -0600 | [diff] [blame] | 333 |                     std::string prop; | 
 | 334 |                     if constexpr (is_same<T, Parsed>::value) | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 335 |                     { | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 336 |                         // TODO deprecate the com.ibm interface later | 
| Priyanga Ramasamy | 0d61c58 | 2022-01-21 04:38:22 -0600 | [diff] [blame] | 337 |                         prop = expandLocationCode(itr.value().get<string>(), | 
 | 338 |                                                   vpdMap, isSystemVpd); | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 339 |                     } | 
| Priyanga Ramasamy | 0d61c58 | 2022-01-21 04:38:22 -0600 | [diff] [blame] | 340 |                     else if constexpr (is_same<T, KeywordVpdMap>::value) | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 341 |                     { | 
| Priyanga Ramasamy | 0d61c58 | 2022-01-21 04:38:22 -0600 | [diff] [blame] | 342 |                         // Send empty Parsed object to expandLocationCode api. | 
 | 343 |                         prop = expandLocationCode(itr.value().get<string>(), | 
 | 344 |                                                   Parsed{}, false); | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 345 |                     } | 
| Priyanga Ramasamy | 0d61c58 | 2022-01-21 04:38:22 -0600 | [diff] [blame] | 346 |                     props.emplace(busProp, prop); | 
 | 347 |                     interfaces.emplace(XYZ_LOCATION_CODE_INF, props); | 
 | 348 |                     interfaces.emplace(IBM_LOCATION_CODE_INF, props); | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 349 |                 } | 
 | 350 |                 else | 
 | 351 |                 { | 
 | 352 |                     props.emplace(busProp, itr.value().get<string>()); | 
 | 353 |                 } | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 354 |             } | 
| Santosh Puranik | ed609af | 2021-06-21 11:30:07 +0530 | [diff] [blame] | 355 |             else if (itr.value().is_array()) | 
 | 356 |             { | 
 | 357 |                 try | 
 | 358 |                 { | 
 | 359 |                     props.emplace(busProp, itr.value().get<Binary>()); | 
 | 360 |                 } | 
| Patrick Williams | 8e15b93 | 2021-10-06 13:04:22 -0500 | [diff] [blame] | 361 |                 catch (const nlohmann::detail::type_error& e) | 
| Santosh Puranik | ed609af | 2021-06-21 11:30:07 +0530 | [diff] [blame] | 362 |                 { | 
 | 363 |                     std::cerr << "Type exception: " << e.what() << "\n"; | 
 | 364 |                     // Ignore any type errors | 
 | 365 |                 } | 
 | 366 |             } | 
| Alpana Kumari | 31970de | 2020-02-17 06:49:57 -0600 | [diff] [blame] | 367 |             else if (itr.value().is_object()) | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 368 |             { | 
| Alpana Kumari | 31970de | 2020-02-17 06:49:57 -0600 | [diff] [blame] | 369 |                 const string& rec = itr.value().value("recordName", ""); | 
 | 370 |                 const string& kw = itr.value().value("keywordName", ""); | 
 | 371 |                 const string& encoding = itr.value().value("encoding", ""); | 
 | 372 |  | 
| Alpana Kumari | 58e2214 | 2020-05-05 00:22:12 -0500 | [diff] [blame] | 373 |                 if constexpr (is_same<T, Parsed>::value) | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 374 |                 { | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 375 |                     if (!rec.empty() && !kw.empty() && vpdMap.count(rec) && | 
 | 376 |                         vpdMap.at(rec).count(kw)) | 
| Alpana Kumari | 31970de | 2020-02-17 06:49:57 -0600 | [diff] [blame] | 377 |                     { | 
| Patrick Williams | 08dc31c | 2024-08-16 15:21:06 -0400 | [diff] [blame] | 378 |                         auto encoded = | 
 | 379 |                             encodeKeyword(vpdMap.at(rec).at(kw), encoding); | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 380 |                         props.emplace(busProp, encoded); | 
| Alpana Kumari | 31970de | 2020-02-17 06:49:57 -0600 | [diff] [blame] | 381 |                     } | 
 | 382 |                 } | 
| Alpana Kumari | 58e2214 | 2020-05-05 00:22:12 -0500 | [diff] [blame] | 383 |                 else if constexpr (is_same<T, KeywordVpdMap>::value) | 
| Alpana Kumari | 31970de | 2020-02-17 06:49:57 -0600 | [diff] [blame] | 384 |                 { | 
 | 385 |                     if (!kw.empty() && vpdMap.count(kw)) | 
 | 386 |                     { | 
| jinuthomas | d640f69 | 2023-03-28 04:13:23 -0500 | [diff] [blame] | 387 |                         if (auto kwValue = get_if<Binary>(&vpdMap.at(kw))) | 
| Alpana Kumari | 3ab26a7 | 2021-04-05 19:09:19 +0000 | [diff] [blame] | 388 |                         { | 
| Patrick Williams | 08dc31c | 2024-08-16 15:21:06 -0400 | [diff] [blame] | 389 |                             auto prop = | 
 | 390 |                                 string((*kwValue).begin(), (*kwValue).end()); | 
| Alpana Kumari | 3ab26a7 | 2021-04-05 19:09:19 +0000 | [diff] [blame] | 391 |  | 
 | 392 |                             auto encoded = encodeKeyword(prop, encoding); | 
 | 393 |  | 
 | 394 |                             props.emplace(busProp, encoded); | 
 | 395 |                         } | 
| jinuthomas | d640f69 | 2023-03-28 04:13:23 -0500 | [diff] [blame] | 396 |                         else if (auto kwValue = | 
 | 397 |                                      get_if<std::string>(&vpdMap.at(kw))) | 
 | 398 |                         { | 
| Patrick Williams | 08dc31c | 2024-08-16 15:21:06 -0400 | [diff] [blame] | 399 |                             auto prop = | 
 | 400 |                                 string((*kwValue).begin(), (*kwValue).end()); | 
| jinuthomas | d640f69 | 2023-03-28 04:13:23 -0500 | [diff] [blame] | 401 |  | 
 | 402 |                             auto encoded = encodeKeyword(prop, encoding); | 
 | 403 |  | 
 | 404 |                             props.emplace(busProp, encoded); | 
 | 405 |                         } | 
 | 406 |                         else if (auto uintValue = | 
 | 407 |                                      get_if<size_t>(&vpdMap.at(kw))) | 
| Alpana Kumari | 3ab26a7 | 2021-04-05 19:09:19 +0000 | [diff] [blame] | 408 |                         { | 
 | 409 |                             props.emplace(busProp, *uintValue); | 
 | 410 |                         } | 
| jinuthomas | d640f69 | 2023-03-28 04:13:23 -0500 | [diff] [blame] | 411 |                         else | 
 | 412 |                         { | 
 | 413 |                             std::cerr << " Unknown Keyword [" << kw | 
 | 414 |                                       << "] Encountered"; | 
 | 415 |                         } | 
| Alpana Kumari | 31970de | 2020-02-17 06:49:57 -0600 | [diff] [blame] | 416 |                     } | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 417 |                 } | 
 | 418 |             } | 
| Matt Spinler | b1e64bb | 2021-09-08 09:57:48 -0500 | [diff] [blame] | 419 |             else if (itr.value().is_number()) | 
 | 420 |             { | 
 | 421 |                 // For now assume the value is a size_t.  In the future it would | 
 | 422 |                 // be nice to come up with a way to get the type from the JSON. | 
 | 423 |                 props.emplace(busProp, itr.value().get<size_t>()); | 
 | 424 |             } | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 425 |         } | 
| Priyanga Ramasamy | aa8a893 | 2022-01-27 09:12:41 -0600 | [diff] [blame] | 426 |         insertOrMerge(interfaces, inf, move(props)); | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 427 |     } | 
 | 428 | } | 
 | 429 |  | 
| alpana07 | 5cb3b1f | 2021-12-16 11:19:36 -0600 | [diff] [blame] | 430 | /** | 
 | 431 |  * @brief This API checks if this FRU is pcie_devices. If yes then it further | 
 | 432 |  *        checks whether it is PASS1 planar. | 
 | 433 |  */ | 
 | 434 | static bool isThisPcieOnPass1planar(const nlohmann::json& js, | 
 | 435 |                                     const string& file) | 
 | 436 | { | 
 | 437 |     auto isThisPCIeDev = false; | 
 | 438 |     auto isPASS1 = false; | 
 | 439 |  | 
 | 440 |     // Check if it is a PCIE device | 
 | 441 |     if (js["frus"].find(file) != js["frus"].end()) | 
 | 442 |     { | 
| Santosh Puranik | c03f390 | 2022-04-14 10:58:26 +0530 | [diff] [blame] | 443 |         if ((js["frus"][file].at(0).find("extraInterfaces") != | 
 | 444 |              js["frus"][file].at(0).end())) | 
| alpana07 | 5cb3b1f | 2021-12-16 11:19:36 -0600 | [diff] [blame] | 445 |         { | 
| Santosh Puranik | c03f390 | 2022-04-14 10:58:26 +0530 | [diff] [blame] | 446 |             if (js["frus"][file].at(0)["extraInterfaces"].find( | 
| alpana07 | 5cb3b1f | 2021-12-16 11:19:36 -0600 | [diff] [blame] | 447 |                     "xyz.openbmc_project.Inventory.Item.PCIeDevice") != | 
| Santosh Puranik | c03f390 | 2022-04-14 10:58:26 +0530 | [diff] [blame] | 448 |                 js["frus"][file].at(0)["extraInterfaces"].end()) | 
| alpana07 | 5cb3b1f | 2021-12-16 11:19:36 -0600 | [diff] [blame] | 449 |             { | 
 | 450 |                 isThisPCIeDev = true; | 
 | 451 |             } | 
 | 452 |         } | 
 | 453 |     } | 
 | 454 |  | 
 | 455 |     if (isThisPCIeDev) | 
 | 456 |     { | 
| Alpana Kumari | a6181e2 | 2022-05-12 05:01:53 -0500 | [diff] [blame] | 457 |         // Collect HW version and SystemType to know if it is PASS1 planar. | 
| alpana07 | 5cb3b1f | 2021-12-16 11:19:36 -0600 | [diff] [blame] | 458 |         auto bus = sdbusplus::bus::new_default(); | 
| Alpana Kumari | a6181e2 | 2022-05-12 05:01:53 -0500 | [diff] [blame] | 459 |         auto property1 = bus.new_method_call( | 
| alpana07 | 5cb3b1f | 2021-12-16 11:19:36 -0600 | [diff] [blame] | 460 |             INVENTORY_MANAGER_SERVICE, | 
 | 461 |             "/xyz/openbmc_project/inventory/system/chassis/motherboard", | 
 | 462 |             "org.freedesktop.DBus.Properties", "Get"); | 
| Alpana Kumari | a6181e2 | 2022-05-12 05:01:53 -0500 | [diff] [blame] | 463 |         property1.append("com.ibm.ipzvpd.VINI"); | 
 | 464 |         property1.append("HW"); | 
 | 465 |         auto result1 = bus.call(property1); | 
 | 466 |         inventory::Value hwVal; | 
 | 467 |         result1.read(hwVal); | 
| alpana07 | 5cb3b1f | 2021-12-16 11:19:36 -0600 | [diff] [blame] | 468 |  | 
| Alpana Kumari | a6181e2 | 2022-05-12 05:01:53 -0500 | [diff] [blame] | 469 |         // SystemType | 
 | 470 |         auto property2 = bus.new_method_call( | 
 | 471 |             INVENTORY_MANAGER_SERVICE, | 
 | 472 |             "/xyz/openbmc_project/inventory/system/chassis/motherboard", | 
 | 473 |             "org.freedesktop.DBus.Properties", "Get"); | 
 | 474 |         property2.append("com.ibm.ipzvpd.VSBP"); | 
 | 475 |         property2.append("IM"); | 
 | 476 |         auto result2 = bus.call(property2); | 
 | 477 |         inventory::Value imVal; | 
 | 478 |         result2.read(imVal); | 
 | 479 |  | 
 | 480 |         auto pVal1 = get_if<Binary>(&hwVal); | 
 | 481 |         auto pVal2 = get_if<Binary>(&imVal); | 
 | 482 |  | 
 | 483 |         if (pVal1 && pVal2) | 
| alpana07 | 5cb3b1f | 2021-12-16 11:19:36 -0600 | [diff] [blame] | 484 |         { | 
| Alpana Kumari | a6181e2 | 2022-05-12 05:01:53 -0500 | [diff] [blame] | 485 |             auto hwVersion = *pVal1; | 
 | 486 |             auto systemType = *pVal2; | 
 | 487 |  | 
 | 488 |             // IM kw for Everest | 
 | 489 |             Binary everestSystem{80, 00, 48, 00}; | 
 | 490 |  | 
 | 491 |             if (systemType == everestSystem) | 
 | 492 |             { | 
 | 493 |                 if (hwVersion[1] < 21) | 
 | 494 |                 { | 
 | 495 |                     isPASS1 = true; | 
 | 496 |                 } | 
 | 497 |             } | 
 | 498 |             else if (hwVersion[1] < 2) | 
 | 499 |             { | 
| alpana07 | 5cb3b1f | 2021-12-16 11:19:36 -0600 | [diff] [blame] | 500 |                 isPASS1 = true; | 
| Alpana Kumari | a6181e2 | 2022-05-12 05:01:53 -0500 | [diff] [blame] | 501 |             } | 
| alpana07 | 5cb3b1f | 2021-12-16 11:19:36 -0600 | [diff] [blame] | 502 |         } | 
 | 503 |     } | 
 | 504 |  | 
 | 505 |     return (isThisPCIeDev && isPASS1); | 
 | 506 | } | 
 | 507 |  | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 508 | /** Performs any pre-action needed to get the FRU setup for collection. | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 509 |  * | 
 | 510 |  * @param[in] json - json object | 
 | 511 |  * @param[in] file - eeprom file path | 
 | 512 |  */ | 
 | 513 | static void preAction(const nlohmann::json& json, const string& file) | 
 | 514 | { | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 515 |     if ((json["frus"][file].at(0)).find("preAction") == | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 516 |         json["frus"][file].at(0).end()) | 
 | 517 |     { | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 518 |         return; | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 519 |     } | 
 | 520 |  | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 521 |     try | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 522 |     { | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 523 |         if (executePreAction(json, file)) | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 524 |         { | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 525 |             if (json["frus"][file].at(0).find("devAddress") != | 
 | 526 |                 json["frus"][file].at(0).end()) | 
| Alpana Kumari | 40d1c19 | 2022-03-09 21:16:02 -0600 | [diff] [blame] | 527 |             { | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 528 |                 // Now bind the device | 
 | 529 |                 string bind = json["frus"][file].at(0).value("devAddress", ""); | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 530 |                 std::cout << "Binding device " << bind << std::endl; | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 531 |                 string bindCmd = string("echo \"") + bind + | 
 | 532 |                                  string("\" > /sys/bus/i2c/drivers/at24/bind"); | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 533 |                 std::cout << bindCmd << std::endl; | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 534 |                 executeCmd(bindCmd); | 
 | 535 |  | 
 | 536 |                 // Check if device showed up (test for file) | 
 | 537 |                 if (!fs::exists(file)) | 
 | 538 |                 { | 
| Patrick Williams | 08dc31c | 2024-08-16 15:21:06 -0400 | [diff] [blame] | 539 |                     std::cerr | 
 | 540 |                         << "EEPROM " << file | 
 | 541 |                         << " does not exist. Take failure action" << std::endl; | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 542 |                     // If not, then take failure postAction | 
 | 543 |                     executePostFailAction(json, file); | 
 | 544 |                 } | 
 | 545 |             } | 
 | 546 |             else | 
 | 547 |             { | 
| Manojkiran Eda | af92175 | 2024-06-17 15:10:21 +0530 | [diff] [blame] | 548 |                 // missing required information | 
 | 549 |                 std::cerr << "VPD inventory JSON missing basic information of " | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 550 |                              "preAction " | 
 | 551 |                              "for this FRU : [" | 
 | 552 |                           << file << "]. Executing executePostFailAction." | 
 | 553 |                           << std::endl; | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 554 |  | 
 | 555 |                 // Take failure postAction | 
| Alpana Kumari | 40d1c19 | 2022-03-09 21:16:02 -0600 | [diff] [blame] | 556 |                 executePostFailAction(json, file); | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 557 |                 return; | 
| Alpana Kumari | 40d1c19 | 2022-03-09 21:16:02 -0600 | [diff] [blame] | 558 |             } | 
 | 559 |         } | 
| Santosh Puranik | dedb5a6 | 2022-12-19 23:58:32 +0530 | [diff] [blame] | 560 |         else | 
 | 561 |         { | 
 | 562 |             // If the FRU is not there, clear the VINI/CCIN data. | 
| Manojkiran Eda | af92175 | 2024-06-17 15:10:21 +0530 | [diff] [blame] | 563 |             // Entity manager probes for this keyword to look for this | 
| Santosh Puranik | dedb5a6 | 2022-12-19 23:58:32 +0530 | [diff] [blame] | 564 |             // FRU, now if the data is persistent on BMC and FRU is | 
 | 565 |             // removed this can lead to ambiguity. Hence clearing this | 
 | 566 |             // Keyword if FRU is absent. | 
 | 567 |             const auto& invPath = | 
 | 568 |                 json["frus"][file].at(0).value("inventoryPath", ""); | 
 | 569 |  | 
 | 570 |             if (!invPath.empty()) | 
 | 571 |             { | 
 | 572 |                 inventory::ObjectMap pimObjMap{ | 
 | 573 |                     {invPath, {{"com.ibm.ipzvpd.VINI", {{"CC", Binary{}}}}}}}; | 
 | 574 |  | 
 | 575 |                 common::utility::callPIM(move(pimObjMap)); | 
 | 576 |             } | 
 | 577 |             else | 
 | 578 |             { | 
 | 579 |                 throw std::runtime_error("Path empty in Json"); | 
 | 580 |             } | 
 | 581 |         } | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 582 |     } | 
 | 583 |     catch (const GpioException& e) | 
 | 584 |     { | 
 | 585 |         PelAdditionalData additionalData{}; | 
 | 586 |         additionalData.emplace("DESCRIPTION", e.what()); | 
 | 587 |         createPEL(additionalData, PelSeverity::WARNING, errIntfForGpioError, | 
 | 588 |                   nullptr); | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 589 |     } | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 590 | } | 
 | 591 |  | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 592 | /** | 
| Santosh Puranik | f3e6968 | 2022-03-31 17:52:38 +0530 | [diff] [blame] | 593 |  * @brief Fills the Decorator.AssetTag property into the interfaces map | 
 | 594 |  * | 
 | 595 |  * This function should only be called in cases where we did not find a JSON | 
 | 596 |  * symlink. A missing symlink in /var/lib will be considered as a factory reset | 
 | 597 |  * and this function will be used to default the AssetTag property. | 
 | 598 |  * | 
 | 599 |  * @param interfaces A possibly pre-populated map of inetrfaces to properties. | 
 | 600 |  * @param vpdMap A VPD map of the system VPD data. | 
 | 601 |  */ | 
 | 602 | static void fillAssetTag(inventory::InterfaceMap& interfaces, | 
 | 603 |                          const Parsed& vpdMap) | 
 | 604 | { | 
 | 605 |     // Read the system serial number and MTM | 
 | 606 |     // Default asset tag is Server-MTM-System Serial | 
 | 607 |     inventory::Interface assetIntf{ | 
 | 608 |         "xyz.openbmc_project.Inventory.Decorator.AssetTag"}; | 
 | 609 |     inventory::PropertyMap assetTagProps; | 
 | 610 |     std::string defaultAssetTag = | 
 | 611 |         std::string{"Server-"} + getKwVal(vpdMap, "VSYS", "TM") + | 
 | 612 |         std::string{"-"} + getKwVal(vpdMap, "VSYS", "SE"); | 
 | 613 |     assetTagProps.emplace("AssetTag", defaultAssetTag); | 
 | 614 |     insertOrMerge(interfaces, assetIntf, std::move(assetTagProps)); | 
 | 615 | } | 
 | 616 |  | 
 | 617 | /** | 
| Santosh Puranik | d3a379a | 2021-08-23 19:12:59 +0530 | [diff] [blame] | 618 |  * @brief Set certain one time properties in the inventory | 
 | 619 |  * Use this function to insert the Functional and Enabled properties into the | 
 | 620 |  * inventory map. This function first checks if the object in question already | 
 | 621 |  * has these properties hosted on D-Bus, if the property is already there, it is | 
 | 622 |  * not modified, hence the name "one time". If the property is not already | 
 | 623 |  * present, it will be added to the map with a suitable default value (true for | 
| Santosh Puranik | dedb5a6 | 2022-12-19 23:58:32 +0530 | [diff] [blame] | 624 |  * Functional and Enabled) | 
| Santosh Puranik | d3a379a | 2021-08-23 19:12:59 +0530 | [diff] [blame] | 625 |  * | 
| Manojkiran Eda | af92175 | 2024-06-17 15:10:21 +0530 | [diff] [blame] | 626 |  * @param[in] object - The inventory D-Bus object without the inventory prefix. | 
 | 627 |  * @param[in,out] interfaces - Reference to a map of inventory interfaces to | 
| Santosh Puranik | d3a379a | 2021-08-23 19:12:59 +0530 | [diff] [blame] | 628 |  * which the properties will be attached. | 
 | 629 |  */ | 
 | 630 | static void setOneTimeProperties(const std::string& object, | 
 | 631 |                                  inventory::InterfaceMap& interfaces) | 
 | 632 | { | 
 | 633 |     auto bus = sdbusplus::bus::new_default(); | 
 | 634 |     auto objectPath = INVENTORY_PATH + object; | 
 | 635 |     auto prop = bus.new_method_call("xyz.openbmc_project.Inventory.Manager", | 
 | 636 |                                     objectPath.c_str(), | 
 | 637 |                                     "org.freedesktop.DBus.Properties", "Get"); | 
 | 638 |     prop.append("xyz.openbmc_project.State.Decorator.OperationalStatus"); | 
 | 639 |     prop.append("Functional"); | 
 | 640 |     try | 
 | 641 |     { | 
 | 642 |         auto result = bus.call(prop); | 
 | 643 |     } | 
 | 644 |     catch (const sdbusplus::exception::SdBusError& e) | 
 | 645 |     { | 
 | 646 |         // Treat as property unavailable | 
 | 647 |         inventory::PropertyMap prop; | 
 | 648 |         prop.emplace("Functional", true); | 
 | 649 |         interfaces.emplace( | 
 | 650 |             "xyz.openbmc_project.State.Decorator.OperationalStatus", | 
 | 651 |             move(prop)); | 
 | 652 |     } | 
 | 653 |     prop = bus.new_method_call("xyz.openbmc_project.Inventory.Manager", | 
 | 654 |                                objectPath.c_str(), | 
 | 655 |                                "org.freedesktop.DBus.Properties", "Get"); | 
 | 656 |     prop.append("xyz.openbmc_project.Object.Enable"); | 
 | 657 |     prop.append("Enabled"); | 
 | 658 |     try | 
 | 659 |     { | 
 | 660 |         auto result = bus.call(prop); | 
 | 661 |     } | 
 | 662 |     catch (const sdbusplus::exception::SdBusError& e) | 
 | 663 |     { | 
 | 664 |         // Treat as property unavailable | 
 | 665 |         inventory::PropertyMap prop; | 
| Santosh Puranik | dedb5a6 | 2022-12-19 23:58:32 +0530 | [diff] [blame] | 666 |         prop.emplace("Enabled", true); | 
| Santosh Puranik | d3a379a | 2021-08-23 19:12:59 +0530 | [diff] [blame] | 667 |         interfaces.emplace("xyz.openbmc_project.Object.Enable", move(prop)); | 
 | 668 |     } | 
 | 669 | } | 
 | 670 |  | 
 | 671 | /** | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 672 |  * @brief Prime the Inventory | 
 | 673 |  * Prime the inventory by populating only the location code, | 
 | 674 |  * type interface and the inventory object for the frus | 
 | 675 |  * which are not system vpd fru. | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 676 |  * | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 677 |  * @param[in] jsObject - Reference to vpd inventory json object | 
 | 678 |  * @param[in] vpdMap -  Reference to the parsed vpd map | 
 | 679 |  * | 
 | 680 |  * @returns Map of items in extraInterface. | 
 | 681 |  */ | 
 | 682 | template <typename T> | 
| Patrick Williams | 08dc31c | 2024-08-16 15:21:06 -0400 | [diff] [blame] | 683 | inventory::ObjectMap | 
 | 684 |     primeInventory(const nlohmann::json& jsObject, const T& vpdMap) | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 685 | { | 
 | 686 |     inventory::ObjectMap objects; | 
 | 687 |  | 
 | 688 |     for (auto& itemFRUS : jsObject["frus"].items()) | 
 | 689 |     { | 
 | 690 |         for (auto& itemEEPROM : itemFRUS.value()) | 
 | 691 |         { | 
| Alpana Kumari | 2e6c6f7 | 2020-12-03 00:10:03 -0600 | [diff] [blame] | 692 |             // Take pre actions if needed | 
 | 693 |             if (itemEEPROM.find("preAction") != itemEEPROM.end()) | 
 | 694 |             { | 
 | 695 |                 preAction(jsObject, itemFRUS.key()); | 
 | 696 |             } | 
 | 697 |  | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 698 |             inventory::InterfaceMap interfaces; | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 699 |             inventory::Object object(itemEEPROM.at("inventoryPath")); | 
 | 700 |  | 
| Santosh Puranik | 50f60bf | 2021-05-26 17:55:06 +0530 | [diff] [blame] | 701 |             if ((itemFRUS.key() != systemVpdFilePath) && | 
 | 702 |                 !itemEEPROM.value("noprime", false)) | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 703 |             { | 
| Alpana Kumari | cfd7a75 | 2021-02-07 23:23:01 -0600 | [diff] [blame] | 704 |                 inventory::PropertyMap presProp; | 
| Priyanga Ramasamy | e358acb | 2022-03-21 14:21:50 -0500 | [diff] [blame] | 705 |  | 
 | 706 |                 // Do not populate Present property for frus whose | 
| Priyanga Ramasamy | aca6137 | 2023-01-24 08:02:28 -0600 | [diff] [blame] | 707 |                 // synthesized=true. synthesized=true says the fru VPD is | 
 | 708 |                 // synthesized and owned by a separate component. | 
 | 709 |                 // In some cases, the FRU has its own VPD, but still a separate | 
 | 710 |                 // application handles the FRU's presence. So VPD parser skips | 
 | 711 |                 // populating Present property by checking the JSON flag, | 
 | 712 |                 // "handlePresence". | 
| Priyanga Ramasamy | e358acb | 2022-03-21 14:21:50 -0500 | [diff] [blame] | 713 |                 if (!itemEEPROM.value("synthesized", false)) | 
 | 714 |                 { | 
| Priyanga Ramasamy | aca6137 | 2023-01-24 08:02:28 -0600 | [diff] [blame] | 715 |                     if (itemEEPROM.value("handlePresence", true)) | 
 | 716 |                     { | 
 | 717 |                         presProp.emplace("Present", false); | 
 | 718 |                         interfaces.emplace("xyz.openbmc_project.Inventory.Item", | 
 | 719 |                                            presProp); | 
 | 720 |                     } | 
| Priyanga Ramasamy | e358acb | 2022-03-21 14:21:50 -0500 | [diff] [blame] | 721 |                 } | 
| Priyanga Ramasamy | aca6137 | 2023-01-24 08:02:28 -0600 | [diff] [blame] | 722 |  | 
| Santosh Puranik | d3a379a | 2021-08-23 19:12:59 +0530 | [diff] [blame] | 723 |                 setOneTimeProperties(object, interfaces); | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 724 |                 if (itemEEPROM.find("extraInterfaces") != itemEEPROM.end()) | 
 | 725 |                 { | 
 | 726 |                     for (const auto& eI : itemEEPROM["extraInterfaces"].items()) | 
 | 727 |                     { | 
 | 728 |                         inventory::PropertyMap props; | 
| Alpana Kumari | 414d5ae | 2021-03-04 21:06:35 +0000 | [diff] [blame] | 729 |                         if (eI.key() == IBM_LOCATION_CODE_INF) | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 730 |                         { | 
 | 731 |                             if constexpr (std::is_same<T, Parsed>::value) | 
 | 732 |                             { | 
 | 733 |                                 for (auto& lC : eI.value().items()) | 
 | 734 |                                 { | 
 | 735 |                                     auto propVal = expandLocationCode( | 
 | 736 |                                         lC.value().get<string>(), vpdMap, true); | 
 | 737 |  | 
 | 738 |                                     props.emplace(move(lC.key()), | 
 | 739 |                                                   move(propVal)); | 
| Santosh Puranik | b0f3749 | 2021-06-21 09:42:47 +0530 | [diff] [blame] | 740 |                                     interfaces.emplace(XYZ_LOCATION_CODE_INF, | 
 | 741 |                                                        props); | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 742 |                                     interfaces.emplace(move(eI.key()), | 
 | 743 |                                                        move(props)); | 
 | 744 |                                 } | 
 | 745 |                             } | 
 | 746 |                         } | 
| Santosh Puranik | d3a379a | 2021-08-23 19:12:59 +0530 | [diff] [blame] | 747 |                         else if (eI.key() == | 
 | 748 |                                  "xyz.openbmc_project.Inventory.Item") | 
 | 749 |                         { | 
 | 750 |                             for (auto& val : eI.value().items()) | 
 | 751 |                             { | 
 | 752 |                                 if (val.key() == "PrettyName") | 
 | 753 |                                 { | 
 | 754 |                                     presProp.emplace(val.key(), | 
 | 755 |                                                      val.value().get<string>()); | 
 | 756 |                                 } | 
 | 757 |                             } | 
 | 758 |                             // Use insert_or_assign here as we may already have | 
 | 759 |                             // inserted the present property only earlier in | 
 | 760 |                             // this function under this same interface. | 
 | 761 |                             interfaces.insert_or_assign(eI.key(), | 
 | 762 |                                                         move(presProp)); | 
 | 763 |                         } | 
| Sunny Srivastava | 1bb8716 | 2024-02-13 00:09:09 -0600 | [diff] [blame] | 764 |                         else | 
 | 765 |                         { | 
 | 766 |                             interfaces.emplace(move(eI.key()), move(props)); | 
 | 767 |                         } | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 768 |                     } | 
 | 769 |                 } | 
 | 770 |                 objects.emplace(move(object), move(interfaces)); | 
 | 771 |             } | 
 | 772 |         } | 
 | 773 |     } | 
 | 774 |     return objects; | 
 | 775 | } | 
 | 776 |  | 
| Alpana Kumari | 65b8360 | 2020-09-01 00:24:56 -0500 | [diff] [blame] | 777 | /** | 
 | 778 |  * @brief This API executes command to set environment variable | 
 | 779 |  *        And then reboot the system | 
 | 780 |  * @param[in] key   -env key to set new value | 
 | 781 |  * @param[in] value -value to set. | 
 | 782 |  */ | 
 | 783 | void setEnvAndReboot(const string& key, const string& value) | 
 | 784 | { | 
 | 785 |     // set env and reboot and break. | 
 | 786 |     executeCmd("/sbin/fw_setenv", key, value); | 
| Andrew Geissler | 280197e | 2020-12-08 20:51:49 -0600 | [diff] [blame] | 787 |     log<level::INFO>("Rebooting BMC to pick up new device tree"); | 
| Alpana Kumari | 65b8360 | 2020-09-01 00:24:56 -0500 | [diff] [blame] | 788 |     // make dbus call to reboot | 
 | 789 |     auto bus = sdbusplus::bus::new_default_system(); | 
 | 790 |     auto method = bus.new_method_call( | 
 | 791 |         "org.freedesktop.systemd1", "/org/freedesktop/systemd1", | 
 | 792 |         "org.freedesktop.systemd1.Manager", "Reboot"); | 
 | 793 |     bus.call_noreply(method); | 
 | 794 | } | 
 | 795 |  | 
 | 796 | /* | 
 | 797 |  * @brief This API checks for env var fitconfig. | 
 | 798 |  *        If not initialised OR updated as per the current system type, | 
 | 799 |  *        update this env var and reboot the system. | 
 | 800 |  * | 
 | 801 |  * @param[in] systemType IM kwd in vpd tells about which system type it is. | 
 | 802 |  * */ | 
 | 803 | void setDevTreeEnv(const string& systemType) | 
 | 804 | { | 
| Alpana Kumari | 37e7270 | 2021-11-18 11:18:04 -0600 | [diff] [blame] | 805 |     // Init with default dtb | 
 | 806 |     string newDeviceTree = "conf-aspeed-bmc-ibm-rainier-p1.dtb"; | 
| Santosh Puranik | e5f177a | 2022-01-24 20:14:46 +0530 | [diff] [blame] | 807 |     static const deviceTreeMap deviceTreeSystemTypeMap = { | 
 | 808 |         {RAINIER_2U, "conf-aspeed-bmc-ibm-rainier-p1.dtb"}, | 
 | 809 |         {RAINIER_2U_V2, "conf-aspeed-bmc-ibm-rainier.dtb"}, | 
 | 810 |         {RAINIER_4U, "conf-aspeed-bmc-ibm-rainier-4u-p1.dtb"}, | 
 | 811 |         {RAINIER_4U_V2, "conf-aspeed-bmc-ibm-rainier-4u.dtb"}, | 
 | 812 |         {RAINIER_1S4U, "conf-aspeed-bmc-ibm-rainier-1s4u.dtb"}, | 
| Alpana Kumari | 1b02611 | 2022-03-02 23:41:38 -0600 | [diff] [blame] | 813 |         {EVEREST, "conf-aspeed-bmc-ibm-everest.dtb"}, | 
| Santosh Puranik | dedb5a6 | 2022-12-19 23:58:32 +0530 | [diff] [blame] | 814 |         {EVEREST_V2, "conf-aspeed-bmc-ibm-everest.dtb"}, | 
| Jinu Joy Thomas | 3b61ff5 | 2024-07-18 23:24:01 -0500 | [diff] [blame] | 815 |         {BONNELL, "conf-aspeed-bmc-ibm-bonnell.dtb"}, | 
 | 816 |         {BLUERIDGE_2U, "conf-aspeed-bmc-ibm-blueridge-p1.dtb"}, | 
 | 817 |         {BLUERIDGE_2U_V2, "conf-aspeed-bmc-ibm-blueridge.dtb"}, | 
 | 818 |         {BLUERIDGE_4U, "conf-aspeed-bmc-ibm-blueridge-4u-p1.dtb"}, | 
 | 819 |         {BLUERIDGE_4U_V2, "conf-aspeed-bmc-ibm-blueridge-4u.dtb"}, | 
 | 820 |         {BLUERIDGE_1S4U, "conf-aspeed-bmc-ibm-blueridge-1s4u.dtb"}, | 
 | 821 |         {FUJI, "conf-aspeed-bmc-ibm-fuji.dtb"}, | 
| Jinu Joy Thomas | c023f9b | 2024-08-25 22:42:34 -0500 | [diff] [blame^] | 822 |         {HUYGENS, "conf-aspeed-bmc-ibm-huygens.dtb"}, | 
| Jinu Joy Thomas | 3b61ff5 | 2024-07-18 23:24:01 -0500 | [diff] [blame] | 823 |         {FUJI_V2, "conf-aspeed-bmc-ibm-fuji.dtb"}}; | 
| Alpana Kumari | 65b8360 | 2020-09-01 00:24:56 -0500 | [diff] [blame] | 824 |  | 
 | 825 |     if (deviceTreeSystemTypeMap.find(systemType) != | 
 | 826 |         deviceTreeSystemTypeMap.end()) | 
 | 827 |     { | 
 | 828 |         newDeviceTree = deviceTreeSystemTypeMap.at(systemType); | 
 | 829 |     } | 
| Alpana Kumari | 37e7270 | 2021-11-18 11:18:04 -0600 | [diff] [blame] | 830 |     else | 
 | 831 |     { | 
 | 832 |         // System type not supported | 
| Alpana Kumari | ab1e22c | 2021-11-24 11:03:38 -0600 | [diff] [blame] | 833 |         string err = "This System type not found/supported in dtb table " + | 
 | 834 |                      systemType + | 
 | 835 |                      ".Please check the HW and IM keywords in the system " | 
 | 836 |                      "VPD.Breaking..."; | 
 | 837 |  | 
 | 838 |         // map to hold additional data in case of logging pel | 
 | 839 |         PelAdditionalData additionalData{}; | 
 | 840 |         additionalData.emplace("DESCRIPTION", err); | 
 | 841 |         createPEL(additionalData, PelSeverity::WARNING, | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 842 |                   errIntfForInvalidSystemType, nullptr); | 
| Alpana Kumari | ab1e22c | 2021-11-24 11:03:38 -0600 | [diff] [blame] | 843 |         exit(-1); | 
| Alpana Kumari | 37e7270 | 2021-11-18 11:18:04 -0600 | [diff] [blame] | 844 |     } | 
| Alpana Kumari | 65b8360 | 2020-09-01 00:24:56 -0500 | [diff] [blame] | 845 |  | 
 | 846 |     string readVarValue; | 
 | 847 |     bool envVarFound = false; | 
 | 848 |  | 
 | 849 |     vector<string> output = executeCmd("/sbin/fw_printenv"); | 
 | 850 |     for (const auto& entry : output) | 
 | 851 |     { | 
 | 852 |         size_t pos = entry.find("="); | 
 | 853 |         string key = entry.substr(0, pos); | 
 | 854 |         if (key != "fitconfig") | 
 | 855 |         { | 
 | 856 |             continue; | 
 | 857 |         } | 
 | 858 |  | 
 | 859 |         envVarFound = true; | 
 | 860 |         if (pos + 1 < entry.size()) | 
 | 861 |         { | 
 | 862 |             readVarValue = entry.substr(pos + 1); | 
 | 863 |             if (readVarValue.find(newDeviceTree) != string::npos) | 
 | 864 |             { | 
 | 865 |                 // fitconfig is Updated. No action needed | 
 | 866 |                 break; | 
 | 867 |             } | 
 | 868 |         } | 
 | 869 |         // set env and reboot and break. | 
 | 870 |         setEnvAndReboot(key, newDeviceTree); | 
 | 871 |         exit(0); | 
 | 872 |     } | 
 | 873 |  | 
 | 874 |     // check If env var Not found | 
 | 875 |     if (!envVarFound) | 
 | 876 |     { | 
 | 877 |         setEnvAndReboot("fitconfig", newDeviceTree); | 
 | 878 |     } | 
 | 879 | } | 
 | 880 |  | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 881 | /** | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 882 |  * @brief Parse the given EEPROM file. | 
 | 883 |  * | 
 | 884 |  * @param[in] vpdFilePath - Path of EEPROM file | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 885 |  * @param[in] js- Reference to vpd inventory json object | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 886 |  * @return Parsed VPD map | 
 | 887 |  */ | 
 | 888 | std::variant<KeywordVpdMap, openpower::vpd::Store> | 
| Sunny Srivastava | 37992a6 | 2023-07-11 05:18:41 -0500 | [diff] [blame] | 889 |     parseVpdFile(const std::string& vpdFilePath, const nlohmann::json& js) | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 890 | { | 
 | 891 |     uint32_t vpdStartOffset = 0; | 
 | 892 |     for (const auto& item : js["frus"][vpdFilePath]) | 
 | 893 |     { | 
 | 894 |         if (item.find("offset") != item.end()) | 
 | 895 |         { | 
 | 896 |             vpdStartOffset = item["offset"]; | 
| Sunny Srivastava | 37992a6 | 2023-07-11 05:18:41 -0500 | [diff] [blame] | 897 |             break; | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 898 |         } | 
 | 899 |     } | 
 | 900 |  | 
 | 901 |     Binary vpdVector = getVpdDataInVector(js, vpdFilePath); | 
 | 902 |  | 
 | 903 |     ParserInterface* parser = ParserFactory::getParser( | 
| Sunny Srivastava | 37992a6 | 2023-07-11 05:18:41 -0500 | [diff] [blame] | 904 |         vpdVector, | 
 | 905 |         (pimPath + js["frus"][vpdFilePath][0]["inventoryPath"] | 
 | 906 |                        .get_ref<const nlohmann::json::string_t&>()), | 
 | 907 |         vpdFilePath, vpdStartOffset); | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 908 |  | 
 | 909 |     auto parseResult = parser->parse(); | 
 | 910 |  | 
 | 911 |     // release the parser object | 
 | 912 |     ParserFactory::freeParser(parser); | 
 | 913 |  | 
 | 914 |     return parseResult; | 
 | 915 | } | 
 | 916 |  | 
 | 917 | /* | 
 | 918 |  * @brief This API retrieves the hardware backup in map | 
 | 919 |  * | 
 | 920 |  * @param[in] systemVpdBackupPath - The path that backs up the system VPD. | 
 | 921 |  * @param[in] backupVpdInvPath - FRU inventory path. | 
 | 922 |  * @param[in] js - JSON object. | 
 | 923 |  * @param[out] backupVpdMap - An IPZ VPD map containing the parsed backup VPD. | 
 | 924 |  * | 
 | 925 |  * */ | 
 | 926 | void getBackupVpdInMap(const string& systemVpdBackupPath, | 
 | 927 |                        const string& backupVpdInvPath, const nlohmann::json& js, | 
 | 928 |                        Parsed& backupVpdMap) | 
 | 929 | { | 
 | 930 |     PelAdditionalData additionalData{}; | 
 | 931 |  | 
 | 932 |     if (!fs::exists(systemVpdBackupPath)) | 
 | 933 |     { | 
 | 934 |         string errorMsg = "Device path "; | 
 | 935 |         errorMsg += systemVpdBackupPath; | 
 | 936 |         errorMsg += " does not exist"; | 
 | 937 |  | 
 | 938 |         additionalData.emplace("DESCRIPTION", errorMsg); | 
 | 939 |  | 
 | 940 |         additionalData.emplace("CALLOUT_INVENTORY_PATH", | 
 | 941 |                                INVENTORY_PATH + backupVpdInvPath); | 
 | 942 |  | 
 | 943 |         createPEL(additionalData, PelSeverity::ERROR, errIntfForStreamFail, | 
 | 944 |                   nullptr); | 
 | 945 |     } | 
 | 946 |     else | 
 | 947 |     { | 
| Sunny Srivastava | 37992a6 | 2023-07-11 05:18:41 -0500 | [diff] [blame] | 948 |         auto backupVpdParsedResult = parseVpdFile(systemVpdBackupPath, js); | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 949 |  | 
 | 950 |         if (auto pVal = get_if<Store>(&backupVpdParsedResult)) | 
 | 951 |         { | 
 | 952 |             backupVpdMap = pVal->getVpdMap(); | 
 | 953 |         } | 
| Sunny Srivastava | 37992a6 | 2023-07-11 05:18:41 -0500 | [diff] [blame] | 954 |         else | 
 | 955 |         { | 
 | 956 |             std::cerr << "Invalid format of VPD in back up. Restore aborted." | 
 | 957 |                       << std::endl; | 
 | 958 |         } | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 959 |     } | 
 | 960 | } | 
 | 961 |  | 
 | 962 | void updateVpdDataOnHw(const std::string& vpdFilePath, nlohmann::json& js, | 
 | 963 |                        const std::string& recName, const std::string& kwName, | 
 | 964 |                        const Binary& kwdData) | 
 | 965 | { | 
 | 966 |     const std::string& fruInvPath = | 
 | 967 |         js["frus"][vpdFilePath][0]["inventoryPath"] | 
 | 968 |             .get_ref<const nlohmann::json::string_t&>(); | 
 | 969 |  | 
 | 970 |     EditorImpl edit(vpdFilePath, js, recName, kwName, fruInvPath); | 
 | 971 |  | 
 | 972 |     uint32_t offset = 0; | 
 | 973 |     // Setup offset, if any | 
 | 974 |     for (const auto& item : js["frus"][vpdFilePath]) | 
 | 975 |     { | 
 | 976 |         if (item.find("offset") != item.end()) | 
 | 977 |         { | 
 | 978 |             offset = item["offset"]; | 
 | 979 |             break; | 
 | 980 |         } | 
 | 981 |     } | 
 | 982 |  | 
 | 983 |     // update keyword data on to EEPROM file | 
 | 984 |     // Note: Updating keyword data on cache is | 
 | 985 |     // handled via PIM Notify call hence passing | 
 | 986 |     // the updCache flag value as false here. | 
 | 987 |     edit.updateKeyword(kwdData, offset, false); | 
 | 988 | } | 
 | 989 |  | 
 | 990 | /** | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 991 |  * @brief API to check if we need to restore system VPD | 
 | 992 |  * This functionality is only applicable for IPZ VPD data. | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 993 |  | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 994 |  * @param[in] vpdMap - IPZ vpd map | 
 | 995 |  * @param[in] objectPath - Object path for the FRU | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 996 |  * @param[in] js - JSON Object | 
 | 997 |  * @param[in] isBackupOnCache - Denotes whether the backup is on cache/hardware | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 998 |  */ | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 999 | void restoreSystemVPD(Parsed& vpdMap, const string& objectPath, | 
 | 1000 |                       nlohmann::json& js, bool isBackupOnCache = true) | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1001 | { | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1002 |     std::string systemVpdBackupPath{}; | 
 | 1003 |     std::string backupVpdInvPath{}; | 
 | 1004 |     Parsed backupVpdMap{}; | 
 | 1005 |  | 
 | 1006 |     if (!isBackupOnCache) | 
 | 1007 |     { | 
 | 1008 |         // Get the value of systemvpdBackupPath field from json | 
 | 1009 |         systemVpdBackupPath = js["frus"][systemVpdFilePath].at(0).value( | 
 | 1010 |             "systemVpdBackupPath", ""); | 
 | 1011 |  | 
 | 1012 |         backupVpdInvPath = js["frus"][systemVpdBackupPath][0]["inventoryPath"] | 
 | 1013 |                                .get_ref<const nlohmann::json::string_t&>(); | 
 | 1014 |  | 
 | 1015 |         getBackupVpdInMap(systemVpdBackupPath, backupVpdInvPath, js, | 
 | 1016 |                           backupVpdMap); | 
 | 1017 |  | 
 | 1018 |         if (backupVpdMap.empty()) | 
 | 1019 |         { | 
| Sunny Srivastava | 37992a6 | 2023-07-11 05:18:41 -0500 | [diff] [blame] | 1020 |             std::cerr << "Backup VPD map is empty" << std::endl; | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1021 |             return; | 
 | 1022 |         } | 
 | 1023 |     } | 
 | 1024 |  | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1025 |     for (const auto& systemRecKwdPair : svpdKwdMap) | 
 | 1026 |     { | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1027 |         const string& recordName = systemRecKwdPair.first; | 
 | 1028 |         auto it = vpdMap.find(recordName); | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1029 |  | 
 | 1030 |         // check if record is found in map we got by parser | 
 | 1031 |         if (it != vpdMap.end()) | 
 | 1032 |         { | 
 | 1033 |             const auto& kwdListForRecord = systemRecKwdPair.second; | 
| Priyanga Ramasamy | 952d6c5 | 2022-11-07 07:20:24 -0600 | [diff] [blame] | 1034 |             for (const auto& keywordInfo : kwdListForRecord) | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1035 |             { | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1036 |                 const auto keywordName = get<0>(keywordInfo); | 
| Priyanga Ramasamy | 952d6c5 | 2022-11-07 07:20:24 -0600 | [diff] [blame] | 1037 |  | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1038 |                 DbusPropertyMap& kwdValMap = it->second; | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1039 |                 auto iterator = kwdValMap.find(keywordName); | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1040 |  | 
 | 1041 |                 if (iterator != kwdValMap.end()) | 
 | 1042 |                 { | 
 | 1043 |                     string& kwdValue = iterator->second; | 
 | 1044 |  | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1045 |                     std::string backupValue{}; | 
| Priyanga Ramasamy | 952d6c5 | 2022-11-07 07:20:24 -0600 | [diff] [blame] | 1046 |                     const auto& defaultValue = get<1>(keywordInfo); | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1047 |                     const auto& backupVpdRecName = get<4>(keywordInfo); | 
 | 1048 |                     const auto& backupVpdKwName = get<5>(keywordInfo); | 
 | 1049 |  | 
 | 1050 |                     // If the 'isBackupOnCache' flag is false, we need | 
 | 1051 |                     // to backup the systemVPD on the specified fru's eeprom | 
 | 1052 |                     // path or restore it from the specified fru's eeprom path. | 
 | 1053 |                     if (isBackupOnCache) | 
 | 1054 |                     { | 
 | 1055 |                         // check bus data | 
 | 1056 |                         backupValue = readBusProperty( | 
 | 1057 |                             objectPath, ipzVpdInf + recordName, keywordName); | 
 | 1058 |                     } | 
 | 1059 |                     else | 
 | 1060 |                     { | 
| Sunny Srivastava | 37992a6 | 2023-07-11 05:18:41 -0500 | [diff] [blame] | 1061 |                         backupValue = getKwVal(backupVpdMap, backupVpdRecName, | 
 | 1062 |                                                backupVpdKwName); | 
 | 1063 |  | 
 | 1064 |                         if (backupValue.empty()) | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1065 |                         { | 
| Sunny Srivastava | 37992a6 | 2023-07-11 05:18:41 -0500 | [diff] [blame] | 1066 |                             string errorMsg{}; | 
 | 1067 |                             if (backupVpdMap.find(backupVpdRecName) == | 
 | 1068 |                                 backupVpdMap.end()) | 
 | 1069 |                             { | 
 | 1070 |                                 errorMsg = backupVpdRecName + | 
 | 1071 |                                            " Record does not exist in " | 
 | 1072 |                                            "the EEPROM file "; | 
 | 1073 |                             } | 
 | 1074 |                             else | 
 | 1075 |                             { | 
 | 1076 |                                 errorMsg = backupVpdKwName + | 
 | 1077 |                                            " Keyword not found or empty."; | 
 | 1078 |                             } | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1079 |  | 
 | 1080 |                             errorMsg += systemVpdBackupPath; | 
 | 1081 |  | 
 | 1082 |                             PelAdditionalData additionalData; | 
 | 1083 |                             additionalData.emplace("DESCRIPTION", errorMsg); | 
 | 1084 |  | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1085 |                             createPEL(additionalData, PelSeverity::ERROR, | 
 | 1086 |                                       errIntfForInvalidVPD, nullptr); | 
 | 1087 |  | 
 | 1088 |                             continue; | 
 | 1089 |                         } | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1090 |                     } | 
 | 1091 |  | 
 | 1092 |                     Binary backupDataInBinary(backupValue.begin(), | 
 | 1093 |                                               backupValue.end()); | 
 | 1094 |  | 
| Priyanga Ramasamy | 952d6c5 | 2022-11-07 07:20:24 -0600 | [diff] [blame] | 1095 |                     Binary kwdDataInBinary(kwdValue.begin(), kwdValue.end()); | 
| Sunny Srivastava | a559c2d | 2022-05-02 11:56:45 -0500 | [diff] [blame] | 1096 |  | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1097 |                     if (backupDataInBinary != defaultValue) | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1098 |                     { | 
| Priyanga Ramasamy | 952d6c5 | 2022-11-07 07:20:24 -0600 | [diff] [blame] | 1099 |                         if (kwdDataInBinary != defaultValue) | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1100 |                         { | 
 | 1101 |                             // both the data are present, check for mismatch | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1102 |                             if (backupValue != kwdValue) | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1103 |                             { | 
| Priyanga Ramasamy | 2494223 | 2023-01-05 04:54:59 -0600 | [diff] [blame] | 1104 |                                 string errMsg = "Mismatch found between backup " | 
 | 1105 |                                                 "and primary VPD for record: "; | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1106 |                                 errMsg += (*it).first; | 
 | 1107 |                                 errMsg += " and keyword: "; | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1108 |                                 errMsg += keywordName; | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1109 |  | 
| Santosh Puranik | dedb5a6 | 2022-12-19 23:58:32 +0530 | [diff] [blame] | 1110 |                                 std::ostringstream busStream; | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1111 |                                 for (uint16_t byte : backupValue) | 
| Santosh Puranik | dedb5a6 | 2022-12-19 23:58:32 +0530 | [diff] [blame] | 1112 |                                 { | 
| Patrick Williams | 08dc31c | 2024-08-16 15:21:06 -0400 | [diff] [blame] | 1113 |                                     busStream | 
 | 1114 |                                         << std::setfill('0') << std::setw(2) | 
 | 1115 |                                         << std::hex << "0x" << byte << " "; | 
| Santosh Puranik | dedb5a6 | 2022-12-19 23:58:32 +0530 | [diff] [blame] | 1116 |                                 } | 
 | 1117 |  | 
 | 1118 |                                 std::ostringstream vpdStream; | 
 | 1119 |                                 for (uint16_t byte : kwdValue) | 
 | 1120 |                                 { | 
| Patrick Williams | 08dc31c | 2024-08-16 15:21:06 -0400 | [diff] [blame] | 1121 |                                     vpdStream | 
 | 1122 |                                         << std::setfill('0') << std::setw(2) | 
 | 1123 |                                         << std::hex << "0x" << byte << " "; | 
| Santosh Puranik | dedb5a6 | 2022-12-19 23:58:32 +0530 | [diff] [blame] | 1124 |                                 } | 
 | 1125 |  | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1126 |                                 // data mismatch | 
 | 1127 |                                 PelAdditionalData additionalData; | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1128 |  | 
 | 1129 |                                 additionalData.emplace("DESCRIPTION", errMsg); | 
| Santosh Puranik | dedb5a6 | 2022-12-19 23:58:32 +0530 | [diff] [blame] | 1130 |                                 additionalData.emplace( | 
| Priyanga Ramasamy | 2494223 | 2023-01-05 04:54:59 -0600 | [diff] [blame] | 1131 |                                     "Value read from Backup: ", | 
 | 1132 |                                     busStream.str()); | 
 | 1133 |                                 additionalData.emplace( | 
 | 1134 |                                     "Value read from Primary: ", | 
| Santosh Puranik | dedb5a6 | 2022-12-19 23:58:32 +0530 | [diff] [blame] | 1135 |                                     vpdStream.str()); | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1136 |  | 
| Sunny Srivastava | 0746eee | 2021-03-22 13:36:54 -0500 | [diff] [blame] | 1137 |                                 createPEL(additionalData, PelSeverity::WARNING, | 
| Priyanga Ramasamy | 2494223 | 2023-01-05 04:54:59 -0600 | [diff] [blame] | 1138 |                                           errIntfForVPDMismatch, nullptr); | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1139 |  | 
 | 1140 |                                 if (!isBackupOnCache) | 
 | 1141 |                                 { | 
 | 1142 |                                     // Backing up or restoring from a hardware | 
 | 1143 |                                     // path does not requires copying the backup | 
 | 1144 |                                     // data to the VPD map, as this will result | 
 | 1145 |                                     // in a mismatch between the primary VPD and | 
 | 1146 |                                     // its cache. | 
 | 1147 |                                     continue; | 
 | 1148 |                                 } | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1149 |                             } | 
| Sunny Srivastava | 37992a6 | 2023-07-11 05:18:41 -0500 | [diff] [blame] | 1150 |                             else | 
 | 1151 |                             { | 
 | 1152 |                                 // both the backup and primary data is | 
 | 1153 |                                 // non-default and same. Nothing needs to be | 
 | 1154 |                                 // done. | 
 | 1155 |                                 continue; | 
 | 1156 |                             } | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1157 |                         } | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1158 |  | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1159 |                         // If the backup is on the cache we need to copy the | 
 | 1160 |                         // backup data to the VPD map to ensure there is no | 
| Manojkiran Eda | af92175 | 2024-06-17 15:10:21 +0530 | [diff] [blame] | 1161 |                         // mismatch b/n them. So if backup data is not default, | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1162 |                         // then irrespective of primary data(default or other | 
 | 1163 |                         // than backup), copy the backup data to vpd map as we | 
 | 1164 |                         // don't need to change the backup data in either case | 
 | 1165 |                         // in the process of restoring system vpd. | 
 | 1166 |                         kwdValue = backupValue; | 
 | 1167 |  | 
 | 1168 |                         // If the backup data is on the base panel the restoring | 
 | 1169 |                         // of Backup VPD on to the system backplane VPD | 
 | 1170 |                         // file is done here not through the VPD manager code | 
 | 1171 |                         // path. This is to have the logic of restoring data on | 
 | 1172 |                         // to the cache & hardware in the same code path. | 
 | 1173 |                         if (!isBackupOnCache) | 
 | 1174 |                         { | 
 | 1175 |                             // copy backup VPD on to system backplane | 
 | 1176 |                             // EEPROM  file. | 
 | 1177 |                             updateVpdDataOnHw(systemVpdFilePath, js, recordName, | 
 | 1178 |                                               keywordName, backupDataInBinary); | 
 | 1179 |                         } | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1180 |                     } | 
| Priyanga Ramasamy | 952d6c5 | 2022-11-07 07:20:24 -0600 | [diff] [blame] | 1181 |                     else if (kwdDataInBinary == defaultValue && | 
 | 1182 |                              get<2>(keywordInfo)) // Check isPELRequired is true | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1183 |                     { | 
| Priyanga Ramasamy | 2494223 | 2023-01-05 04:54:59 -0600 | [diff] [blame] | 1184 |                         string errMsg = "Found default value on both backup " | 
 | 1185 |                                         "and primary VPD for record: "; | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1186 |                         errMsg += (*it).first; | 
 | 1187 |                         errMsg += " and keyword: "; | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1188 |                         errMsg += keywordName; | 
| Sunny Srivastava | 37992a6 | 2023-07-11 05:18:41 -0500 | [diff] [blame] | 1189 |                         errMsg += ". Update primary VPD."; | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1190 |  | 
| Priyanga Ramasamy | 2494223 | 2023-01-05 04:54:59 -0600 | [diff] [blame] | 1191 |                         // mfg default on both backup and primary, log PEL | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1192 |                         PelAdditionalData additionalData; | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1193 |                         additionalData.emplace("DESCRIPTION", errMsg); | 
 | 1194 |  | 
| Sunny Srivastava | 0746eee | 2021-03-22 13:36:54 -0500 | [diff] [blame] | 1195 |                         createPEL(additionalData, PelSeverity::ERROR, | 
| Priyanga Ramasamy | 2494223 | 2023-01-05 04:54:59 -0600 | [diff] [blame] | 1196 |                                   errIntfForVPDDefault, nullptr); | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1197 |  | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1198 |                         continue; | 
 | 1199 |                     } | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1200 |                     else if ((kwdDataInBinary != defaultValue) && | 
 | 1201 |                              (!isBackupOnCache)) | 
 | 1202 |                     { | 
 | 1203 |                         // update primary VPD on to backup VPD file | 
 | 1204 |                         updateVpdDataOnHw(systemVpdBackupPath, js, | 
 | 1205 |                                           backupVpdRecName, backupVpdKwName, | 
 | 1206 |                                           kwdDataInBinary); | 
 | 1207 |  | 
 | 1208 |                         // copy primary VPD to backup VPD to publish on | 
 | 1209 |                         // DBus | 
 | 1210 |                         backupVpdMap.find(backupVpdRecName) | 
 | 1211 |                             ->second.find(backupVpdKwName) | 
 | 1212 |                             ->second = kwdValue; | 
 | 1213 |                     } | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1214 |                 } | 
 | 1215 |             } | 
 | 1216 |         } | 
 | 1217 |     } | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1218 | } | 
 | 1219 |  | 
 | 1220 | /** | 
| alpana07 | 7ce6872 | 2021-07-25 13:23:59 -0500 | [diff] [blame] | 1221 |  * @brief This checks for is this FRU a processor | 
 | 1222 |  *        And if yes, then checks for is this primary | 
 | 1223 |  * | 
 | 1224 |  * @param[in] js- vpd json to get the information about this FRU | 
 | 1225 |  * @param[in] filePath- FRU vpd | 
 | 1226 |  * | 
 | 1227 |  * @return true/false | 
 | 1228 |  */ | 
 | 1229 | bool isThisPrimaryProcessor(nlohmann::json& js, const string& filePath) | 
 | 1230 | { | 
 | 1231 |     bool isProcessor = false; | 
 | 1232 |     bool isPrimary = false; | 
 | 1233 |  | 
 | 1234 |     for (const auto& item : js["frus"][filePath]) | 
 | 1235 |     { | 
 | 1236 |         if (item.find("extraInterfaces") != item.end()) | 
 | 1237 |         { | 
 | 1238 |             for (const auto& eI : item["extraInterfaces"].items()) | 
 | 1239 |             { | 
 | 1240 |                 if (eI.key().find("Inventory.Item.Cpu") != string::npos) | 
 | 1241 |                 { | 
 | 1242 |                     isProcessor = true; | 
 | 1243 |                 } | 
 | 1244 |             } | 
 | 1245 |         } | 
 | 1246 |  | 
 | 1247 |         if (isProcessor) | 
 | 1248 |         { | 
 | 1249 |             string cpuType = item.value("cpuType", ""); | 
 | 1250 |             if (cpuType == "primary") | 
 | 1251 |             { | 
 | 1252 |                 isPrimary = true; | 
 | 1253 |             } | 
 | 1254 |         } | 
 | 1255 |     } | 
 | 1256 |  | 
 | 1257 |     return (isProcessor && isPrimary); | 
 | 1258 | } | 
 | 1259 |  | 
 | 1260 | /** | 
 | 1261 |  * @brief This finds DIMM vpd in vpd json and enables them by binding the device | 
 | 1262 |  *        driver | 
 | 1263 |  * @param[in] js- vpd json to iterate through and take action if it is DIMM | 
 | 1264 |  */ | 
 | 1265 | void doEnableAllDimms(nlohmann::json& js) | 
 | 1266 | { | 
 | 1267 |     // iterate over each fru | 
 | 1268 |     for (const auto& eachFru : js["frus"].items()) | 
 | 1269 |     { | 
 | 1270 |         // skip the driver binding if eeprom already exists | 
 | 1271 |         if (fs::exists(eachFru.key())) | 
 | 1272 |         { | 
 | 1273 |             continue; | 
 | 1274 |         } | 
 | 1275 |  | 
 | 1276 |         for (const auto& eachInventory : eachFru.value()) | 
 | 1277 |         { | 
 | 1278 |             if (eachInventory.find("extraInterfaces") != eachInventory.end()) | 
 | 1279 |             { | 
 | 1280 |                 for (const auto& eI : eachInventory["extraInterfaces"].items()) | 
 | 1281 |                 { | 
 | 1282 |                     if (eI.key().find("Inventory.Item.Dimm") != string::npos) | 
 | 1283 |                     { | 
 | 1284 |                         string dimmVpd = eachFru.key(); | 
 | 1285 |                         // fetch it from | 
 | 1286 |                         // "/sys/bus/i2c/drivers/at24/414-0050/eeprom" | 
 | 1287 |  | 
 | 1288 |                         regex matchPatern("([0-9]+-[0-9]{4})"); | 
 | 1289 |                         smatch matchFound; | 
 | 1290 |                         if (regex_search(dimmVpd, matchFound, matchPatern)) | 
 | 1291 |                         { | 
 | 1292 |                             vector<string> i2cReg; | 
 | 1293 |                             boost::split(i2cReg, matchFound.str(0), | 
 | 1294 |                                          boost::is_any_of("-")); | 
 | 1295 |  | 
| Manojkiran Eda | af92175 | 2024-06-17 15:10:21 +0530 | [diff] [blame] | 1296 |                             // remove 0s from beginning | 
| alpana07 | 7ce6872 | 2021-07-25 13:23:59 -0500 | [diff] [blame] | 1297 |                             const regex pattern("^0+(?!$)"); | 
 | 1298 |                             for (auto& i : i2cReg) | 
 | 1299 |                             { | 
 | 1300 |                                 i = regex_replace(i, pattern, ""); | 
 | 1301 |                             } | 
 | 1302 |  | 
| Jinu Joy Thomas | 63cce0f | 2024-01-29 00:47:47 -0600 | [diff] [blame] | 1303 |                             // For ISDIMM which uses ee1004 driver | 
 | 1304 |                             // the below is done | 
 | 1305 |                             size_t stringFound = dimmVpd.find("ee1004"); | 
 | 1306 |                             if (stringFound != string::npos) | 
 | 1307 |                             { | 
 | 1308 |                                 // echo ee1004 0x50 > | 
 | 1309 |                                 // /sys/bus/i2c/devices/i2c-110/new_device | 
 | 1310 |                                 string cmnd = "echo ee1004 0x" + i2cReg[1] + | 
 | 1311 |                                               " > /sys/bus/i2c/devices/i2c-" + | 
 | 1312 |                                               i2cReg[0] + "/new_device"; | 
 | 1313 |                                 executeCmd(cmnd); | 
 | 1314 |                             } | 
 | 1315 |                             else if (i2cReg.size() == 2) | 
| alpana07 | 7ce6872 | 2021-07-25 13:23:59 -0500 | [diff] [blame] | 1316 |                             { | 
 | 1317 |                                 // echo 24c32 0x50 > | 
 | 1318 |                                 // /sys/bus/i2c/devices/i2c-16/new_device | 
 | 1319 |                                 string cmnd = "echo 24c32 0x" + i2cReg[1] + | 
 | 1320 |                                               " > /sys/bus/i2c/devices/i2c-" + | 
 | 1321 |                                               i2cReg[0] + "/new_device"; | 
| alpana07 | 7ce6872 | 2021-07-25 13:23:59 -0500 | [diff] [blame] | 1322 |                                 executeCmd(cmnd); | 
 | 1323 |                             } | 
 | 1324 |                         } | 
 | 1325 |                     } | 
 | 1326 |                 } | 
 | 1327 |             } | 
 | 1328 |         } | 
 | 1329 |     } | 
 | 1330 | } | 
 | 1331 |  | 
 | 1332 | /** | 
| Priyanga Ramasamy | 6abdeb6 | 2022-01-09 23:15:11 -0600 | [diff] [blame] | 1333 |  * @brief Check if the given CPU is an IO only chip. | 
 | 1334 |  * The CPU is termed as IO, whose all of the cores are bad and can never be | 
 | 1335 |  * used. Those CPU chips can be used for IO purpose like connecting PCIe devices | 
 | 1336 |  * etc., The CPU whose every cores are bad, can be identified from the CP00 | 
 | 1337 |  * record's PG keyword, only if all of the 8 EQs' value equals 0xE7F9FF. (1EQ | 
 | 1338 |  * has 4 cores grouped together by sharing its cache memory.) | 
 | 1339 |  * @param [in] pgKeyword - PG Keyword of CPU. | 
 | 1340 |  * @return true if the given cpu is an IO, false otherwise. | 
 | 1341 |  */ | 
 | 1342 | static bool isCPUIOGoodOnly(const string& pgKeyword) | 
 | 1343 | { | 
 | 1344 |     const unsigned char io[] = {0xE7, 0xF9, 0xFF, 0xE7, 0xF9, 0xFF, 0xE7, 0xF9, | 
 | 1345 |                                 0xFF, 0xE7, 0xF9, 0xFF, 0xE7, 0xF9, 0xFF, 0xE7, | 
 | 1346 |                                 0xF9, 0xFF, 0xE7, 0xF9, 0xFF, 0xE7, 0xF9, 0xFF}; | 
 | 1347 |     // EQ0 index (in PG keyword) starts at 97 (with offset starting from 0). | 
 | 1348 |     // Each EQ carries 3 bytes of data. Totally there are 8 EQs. If all EQs' | 
 | 1349 |     // value equals 0xE7F9FF, then the cpu has no good cores and its treated as | 
 | 1350 |     // IO. | 
 | 1351 |     if (memcmp(io, pgKeyword.data() + 97, 24) == 0) | 
 | 1352 |     { | 
 | 1353 |         return true; | 
 | 1354 |     } | 
 | 1355 |  | 
 | 1356 |     // The CPU is not an IO | 
 | 1357 |     return false; | 
 | 1358 | } | 
 | 1359 |  | 
 | 1360 | /** | 
| Jinu Joy Thomas | 9a60c8b | 2024-01-16 22:52:25 -0600 | [diff] [blame] | 1361 |  * @brief Function to bring MUX out of idle state | 
 | 1362 |  * | 
 | 1363 |  *        This finds All the MUX defined in the system json and enables | 
 | 1364 |  *        them by setting the holdidle parameter to 0. | 
 | 1365 |  * @param[in] js- system json to iterate through and take action | 
 | 1366 |  */ | 
 | 1367 | void doEnableAllMuxChips(const nlohmann::json& js) | 
 | 1368 | { | 
 | 1369 |     // Do we have the mandatory "muxes" section? | 
 | 1370 |     if (js.find("muxes") != js.end()) | 
 | 1371 |     { | 
 | 1372 |         std::cout << "Enabling all the MUX on the system " << std::endl; | 
 | 1373 |         // iterate over each MUX detail and enable them | 
 | 1374 |         for (const auto& item : js["muxes"]) | 
 | 1375 |         { | 
 | 1376 |             if (item.find("holdidlepath") != item.end()) | 
 | 1377 |             { | 
| Jinu Joy Thomas | 63cce0f | 2024-01-29 00:47:47 -0600 | [diff] [blame] | 1378 |                 const std::string& holdidle = item["holdidlepath"]; | 
| Jinu Joy Thomas | 9a60c8b | 2024-01-16 22:52:25 -0600 | [diff] [blame] | 1379 |                 std::cout << "Setting holdidle state for " << holdidle | 
 | 1380 |                           << "to 0 " << std::endl; | 
 | 1381 |                 string cmd = "echo 0 > " + holdidle; | 
 | 1382 |                 executeCmd(cmd); | 
 | 1383 |             } | 
 | 1384 |         } | 
 | 1385 |         std::cout << "Completed enabling all the MUX on the system " | 
 | 1386 |                   << std::endl; | 
 | 1387 |     } | 
 | 1388 |     else | 
 | 1389 |     { | 
 | 1390 |         std::cout << "No MUX was defined for the system" << std::endl; | 
 | 1391 |     } | 
 | 1392 | } | 
 | 1393 |  | 
 | 1394 | /** | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 1395 |  * @brief Populate Dbus. | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1396 |  * This method invokes all the populateInterface functions | 
 | 1397 |  * and notifies PIM about dbus object. | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 1398 |  * @param[in] vpdMap - Either IPZ vpd map or Keyword vpd map based on the | 
 | 1399 |  * input. | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1400 |  * @param[in] js - Inventory json object | 
 | 1401 |  * @param[in] filePath - Path of the vpd file | 
 | 1402 |  * @param[in] preIntrStr - Interface string | 
 | 1403 |  */ | 
 | 1404 | template <typename T> | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1405 | static void populateDbus(T& vpdMap, nlohmann::json& js, const string& filePath) | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1406 | { | 
 | 1407 |     inventory::InterfaceMap interfaces; | 
 | 1408 |     inventory::ObjectMap objects; | 
 | 1409 |     inventory::PropertyMap prop; | 
| Shantappa Teekappanavar | 6aa5450 | 2021-12-09 12:59:56 -0600 | [diff] [blame] | 1410 |     string ccinFromVpd; | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1411 |  | 
| Santosh Puranik | 50f60bf | 2021-05-26 17:55:06 +0530 | [diff] [blame] | 1412 |     bool isSystemVpd = (filePath == systemVpdFilePath); | 
 | 1413 |     if constexpr (is_same<T, Parsed>::value) | 
 | 1414 |     { | 
| Shantappa Teekappanavar | 6aa5450 | 2021-12-09 12:59:56 -0600 | [diff] [blame] | 1415 |         ccinFromVpd = getKwVal(vpdMap, "VINI", "CC"); | 
 | 1416 |         transform(ccinFromVpd.begin(), ccinFromVpd.end(), ccinFromVpd.begin(), | 
 | 1417 |                   ::toupper); | 
 | 1418 |  | 
| Santosh Puranik | 50f60bf | 2021-05-26 17:55:06 +0530 | [diff] [blame] | 1419 |         if (isSystemVpd) | 
 | 1420 |         { | 
| Santosh Puranik | 50f60bf | 2021-05-26 17:55:06 +0530 | [diff] [blame] | 1421 |             string mboardPath = | 
 | 1422 |                 js["frus"][filePath].at(0).value("inventoryPath", ""); | 
 | 1423 |  | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1424 |             // Get the value of systemvpdBackupPath field from json | 
 | 1425 |             const std::string& systemVpdBackupPath = | 
 | 1426 |                 js["frus"][filePath].at(0).value("systemVpdBackupPath", ""); | 
 | 1427 |  | 
 | 1428 |             if (systemVpdBackupPath.empty()) | 
| Santosh Puranik | 50f60bf | 2021-05-26 17:55:06 +0530 | [diff] [blame] | 1429 |             { | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1430 |                 std::vector<std::string> interfaces = {motherBoardInterface}; | 
 | 1431 |                 // call mapper to check for object path creation | 
 | 1432 |                 MapperResponse subTree = | 
 | 1433 |                     getObjectSubtreeForInterfaces(pimPath, 0, interfaces); | 
 | 1434 |  | 
 | 1435 |                 // Attempt system VPD restore if we have a motherboard | 
 | 1436 |                 // object in the inventory. | 
 | 1437 |                 if ((subTree.size() != 0) && | 
 | 1438 |                     (subTree.find(pimPath + mboardPath) != subTree.end())) | 
 | 1439 |                 { | 
 | 1440 |                     restoreSystemVPD(vpdMap, mboardPath, js); | 
 | 1441 |                 } | 
 | 1442 |                 else | 
 | 1443 |                 { | 
 | 1444 |                     log<level::ERR>("No object path found"); | 
 | 1445 |                 } | 
| Santosh Puranik | 50f60bf | 2021-05-26 17:55:06 +0530 | [diff] [blame] | 1446 |             } | 
 | 1447 |             else | 
 | 1448 |             { | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1449 |                 restoreSystemVPD(vpdMap, mboardPath, js, false); | 
| Santosh Puranik | 50f60bf | 2021-05-26 17:55:06 +0530 | [diff] [blame] | 1450 |             } | 
 | 1451 |         } | 
| alpana07 | 7ce6872 | 2021-07-25 13:23:59 -0500 | [diff] [blame] | 1452 |         else | 
 | 1453 |         { | 
 | 1454 |             // check if it is processor vpd. | 
 | 1455 |             auto isPrimaryCpu = isThisPrimaryProcessor(js, filePath); | 
 | 1456 |  | 
 | 1457 |             if (isPrimaryCpu) | 
 | 1458 |             { | 
 | 1459 |                 auto ddVersion = getKwVal(vpdMap, "CRP0", "DD"); | 
 | 1460 |  | 
 | 1461 |                 auto chipVersion = atoi(ddVersion.substr(1, 2).c_str()); | 
 | 1462 |  | 
 | 1463 |                 if (chipVersion >= 2) | 
 | 1464 |                 { | 
 | 1465 |                     doEnableAllDimms(js); | 
| Santosh Puranik | 253fbe9 | 2022-10-06 22:38:09 +0530 | [diff] [blame] | 1466 |                     // Sleep for a few seconds to let the DIMM parses start | 
 | 1467 |                     using namespace std::chrono_literals; | 
 | 1468 |                     std::this_thread::sleep_for(5s); | 
| alpana07 | 7ce6872 | 2021-07-25 13:23:59 -0500 | [diff] [blame] | 1469 |                 } | 
 | 1470 |             } | 
 | 1471 |         } | 
| Santosh Puranik | 50f60bf | 2021-05-26 17:55:06 +0530 | [diff] [blame] | 1472 |     } | 
 | 1473 |  | 
| Santosh Puranik | f3e6968 | 2022-03-31 17:52:38 +0530 | [diff] [blame] | 1474 |     auto processFactoryReset = false; | 
 | 1475 |  | 
| Priyanga Ramasamy | 32c687f | 2022-01-04 23:14:03 -0600 | [diff] [blame] | 1476 |     if (isSystemVpd) | 
 | 1477 |     { | 
 | 1478 |         string systemJsonName{}; | 
 | 1479 |         if constexpr (is_same<T, Parsed>::value) | 
 | 1480 |         { | 
 | 1481 |             // pick the right system json | 
 | 1482 |             systemJsonName = getSystemsJson(vpdMap); | 
 | 1483 |         } | 
 | 1484 |  | 
 | 1485 |         fs::path target = systemJsonName; | 
 | 1486 |         fs::path link = INVENTORY_JSON_SYM_LINK; | 
 | 1487 |  | 
| Santosh Puranik | f3e6968 | 2022-03-31 17:52:38 +0530 | [diff] [blame] | 1488 |         // If the symlink does not exist, we treat that as a factory reset | 
 | 1489 |         processFactoryReset = !fs::exists(INVENTORY_JSON_SYM_LINK); | 
 | 1490 |  | 
| Priyanga Ramasamy | 32c687f | 2022-01-04 23:14:03 -0600 | [diff] [blame] | 1491 |         // Create the directory for hosting the symlink | 
 | 1492 |         fs::create_directories(VPD_FILES_PATH); | 
 | 1493 |         // unlink the symlink previously created (if any) | 
 | 1494 |         remove(INVENTORY_JSON_SYM_LINK); | 
 | 1495 |         // create a new symlink based on the system | 
 | 1496 |         fs::create_symlink(target, link); | 
 | 1497 |  | 
 | 1498 |         // Reloading the json | 
 | 1499 |         ifstream inventoryJson(link); | 
 | 1500 |         js = json::parse(inventoryJson); | 
 | 1501 |         inventoryJson.close(); | 
| Sunny Srivastava | 7ef9c8c | 2024-05-03 00:57:43 -0500 | [diff] [blame] | 1502 |  | 
 | 1503 |         // enable the muxes again here to cover the case where during first boot | 
 | 1504 |         // after reset, system would have come up with default JSON | 
 | 1505 |         // configuration and have skipped enabling mux at the beginning. | 
 | 1506 |         // Default config JSON does not have mux entries. | 
 | 1507 |         doEnableAllMuxChips(js); | 
| Priyanga Ramasamy | 32c687f | 2022-01-04 23:14:03 -0600 | [diff] [blame] | 1508 |     } | 
 | 1509 |  | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1510 |     for (const auto& item : js["frus"][filePath]) | 
 | 1511 |     { | 
 | 1512 |         const auto& objectPath = item["inventoryPath"]; | 
 | 1513 |         sdbusplus::message::object_path object(objectPath); | 
| SunnySrivastava1984 | 9094d4f | 2020-08-05 09:32:29 -0500 | [diff] [blame] | 1514 |  | 
| Shantappa Teekappanavar | 6aa5450 | 2021-12-09 12:59:56 -0600 | [diff] [blame] | 1515 |         vector<string> ccinList; | 
 | 1516 |         if (item.find("ccin") != item.end()) | 
 | 1517 |         { | 
 | 1518 |             for (const auto& cc : item["ccin"]) | 
 | 1519 |             { | 
 | 1520 |                 string ccin = cc; | 
 | 1521 |                 transform(ccin.begin(), ccin.end(), ccin.begin(), ::toupper); | 
 | 1522 |                 ccinList.push_back(ccin); | 
 | 1523 |             } | 
 | 1524 |         } | 
 | 1525 |  | 
 | 1526 |         if (!ccinFromVpd.empty() && !ccinList.empty() && | 
 | 1527 |             (find(ccinList.begin(), ccinList.end(), ccinFromVpd) == | 
 | 1528 |              ccinList.end())) | 
 | 1529 |         { | 
 | 1530 |             continue; | 
 | 1531 |         } | 
 | 1532 |  | 
| Priyanga Ramasamy | e3fed70 | 2022-01-11 01:05:32 -0600 | [diff] [blame] | 1533 |         if ((isSystemVpd) || (item.value("noprime", false))) | 
| Santosh Puranik | d3a379a | 2021-08-23 19:12:59 +0530 | [diff] [blame] | 1534 |         { | 
| Priyanga Ramasamy | e3fed70 | 2022-01-11 01:05:32 -0600 | [diff] [blame] | 1535 |             // Populate one time properties for the system VPD and its sub-frus | 
 | 1536 |             // and for other non-primeable frus. | 
| Santosh Puranik | d3a379a | 2021-08-23 19:12:59 +0530 | [diff] [blame] | 1537 |             // For the remaining FRUs, this will get handled as a part of | 
 | 1538 |             // priming the inventory. | 
 | 1539 |             setOneTimeProperties(objectPath, interfaces); | 
 | 1540 |         } | 
 | 1541 |  | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1542 |         // Populate the VPD keywords and the common interfaces only if we | 
 | 1543 |         // are asked to inherit that data from the VPD, else only add the | 
 | 1544 |         // extraInterfaces. | 
 | 1545 |         if (item.value("inherit", true)) | 
 | 1546 |         { | 
| Alpana Kumari | 58e2214 | 2020-05-05 00:22:12 -0500 | [diff] [blame] | 1547 |             if constexpr (is_same<T, Parsed>::value) | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1548 |             { | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 1549 |                 // Each record in the VPD becomes an interface and all | 
 | 1550 |                 // keyword within the record are properties under that | 
 | 1551 |                 // interface. | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1552 |                 for (const auto& record : vpdMap) | 
 | 1553 |                 { | 
 | 1554 |                     populateFruSpecificInterfaces( | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 1555 |                         record.second, ipzVpdInf + record.first, interfaces); | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1556 |                 } | 
 | 1557 |             } | 
| Alpana Kumari | 58e2214 | 2020-05-05 00:22:12 -0500 | [diff] [blame] | 1558 |             else if constexpr (is_same<T, KeywordVpdMap>::value) | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1559 |             { | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 1560 |                 populateFruSpecificInterfaces(vpdMap, kwdVpdInf, interfaces); | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1561 |             } | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 1562 |             if (js.find("commonInterfaces") != js.end()) | 
 | 1563 |             { | 
 | 1564 |                 populateInterfaces(js["commonInterfaces"], interfaces, vpdMap, | 
 | 1565 |                                    isSystemVpd); | 
 | 1566 |             } | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1567 |         } | 
| Santosh Puranik | 0859eb6 | 2020-03-16 02:56:29 -0500 | [diff] [blame] | 1568 |         else | 
 | 1569 |         { | 
 | 1570 |             // Check if we have been asked to inherit specific record(s) | 
| Alpana Kumari | 58e2214 | 2020-05-05 00:22:12 -0500 | [diff] [blame] | 1571 |             if constexpr (is_same<T, Parsed>::value) | 
| Santosh Puranik | 0859eb6 | 2020-03-16 02:56:29 -0500 | [diff] [blame] | 1572 |             { | 
 | 1573 |                 if (item.find("copyRecords") != item.end()) | 
 | 1574 |                 { | 
 | 1575 |                     for (const auto& record : item["copyRecords"]) | 
 | 1576 |                     { | 
 | 1577 |                         const string& recordName = record; | 
 | 1578 |                         if (vpdMap.find(recordName) != vpdMap.end()) | 
 | 1579 |                         { | 
 | 1580 |                             populateFruSpecificInterfaces( | 
| SunnySrivastava1984 | e12b181 | 2020-05-26 02:23:11 -0500 | [diff] [blame] | 1581 |                                 vpdMap.at(recordName), ipzVpdInf + recordName, | 
| Santosh Puranik | 0859eb6 | 2020-03-16 02:56:29 -0500 | [diff] [blame] | 1582 |                                 interfaces); | 
 | 1583 |                         } | 
 | 1584 |                     } | 
 | 1585 |                 } | 
 | 1586 |             } | 
 | 1587 |         } | 
| Santosh Puranik | 32c4650 | 2022-02-10 08:55:07 +0530 | [diff] [blame] | 1588 |         // Populate interfaces and properties that are common to every FRU | 
 | 1589 |         // and additional interface that might be defined on a per-FRU | 
 | 1590 |         // basis. | 
 | 1591 |         if (item.find("extraInterfaces") != item.end()) | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1592 |         { | 
| Santosh Puranik | 32c4650 | 2022-02-10 08:55:07 +0530 | [diff] [blame] | 1593 |             populateInterfaces(item["extraInterfaces"], interfaces, vpdMap, | 
 | 1594 |                                isSystemVpd); | 
| Priyanga Ramasamy | 6abdeb6 | 2022-01-09 23:15:11 -0600 | [diff] [blame] | 1595 |             if constexpr (is_same<T, Parsed>::value) | 
 | 1596 |             { | 
 | 1597 |                 if (item["extraInterfaces"].find( | 
 | 1598 |                         "xyz.openbmc_project.Inventory.Item.Cpu") != | 
 | 1599 |                     item["extraInterfaces"].end()) | 
 | 1600 |                 { | 
 | 1601 |                     if (isCPUIOGoodOnly(getKwVal(vpdMap, "CP00", "PG"))) | 
 | 1602 |                     { | 
| Priyanga Ramasamy | 2c607a9 | 2022-04-08 00:30:17 -0500 | [diff] [blame] | 1603 |                         interfaces[invItemIntf]["PrettyName"] = "IO Module"; | 
| Priyanga Ramasamy | 6abdeb6 | 2022-01-09 23:15:11 -0600 | [diff] [blame] | 1604 |                     } | 
 | 1605 |                 } | 
 | 1606 |             } | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1607 |         } | 
| Priyanga Ramasamy | e358acb | 2022-03-21 14:21:50 -0500 | [diff] [blame] | 1608 |  | 
 | 1609 |         // embedded property(true or false) says whether the subfru is embedded | 
 | 1610 |         // into the parent fru (or) not. VPD sets Present property only for | 
 | 1611 |         // embedded frus. If the subfru is not an embedded FRU, the subfru may | 
 | 1612 |         // or may not be physically present. Those non embedded frus will always | 
 | 1613 |         // have Present=false irrespective of its physical presence or absence. | 
 | 1614 |         // Eg: nvme drive in nvme slot is not an embedded FRU. So don't set | 
 | 1615 |         // Present to true for such sub frus. | 
 | 1616 |         // Eg: ethernet port is embedded into bmc card. So set Present to true | 
| Manojkiran Eda | af92175 | 2024-06-17 15:10:21 +0530 | [diff] [blame] | 1617 |         // for such sub frus. Also do not populate present property for embedded | 
| Priyanga Ramasamy | e358acb | 2022-03-21 14:21:50 -0500 | [diff] [blame] | 1618 |         // subfru which is synthesized. Currently there is no subfru which are | 
 | 1619 |         // both embedded and synthesized. But still the case is handled here. | 
 | 1620 |         if ((item.value("embedded", true)) && | 
 | 1621 |             (!item.value("synthesized", false))) | 
 | 1622 |         { | 
| Priyanga Ramasamy | aca6137 | 2023-01-24 08:02:28 -0600 | [diff] [blame] | 1623 |             // Check if its required to handle presence for this FRU. | 
 | 1624 |             if (item.value("handlePresence", true)) | 
 | 1625 |             { | 
 | 1626 |                 inventory::PropertyMap presProp; | 
 | 1627 |                 presProp.emplace("Present", true); | 
 | 1628 |                 insertOrMerge(interfaces, invItemIntf, move(presProp)); | 
 | 1629 |             } | 
| Priyanga Ramasamy | e358acb | 2022-03-21 14:21:50 -0500 | [diff] [blame] | 1630 |         } | 
| Priyanga Ramasamy | aa8a893 | 2022-01-27 09:12:41 -0600 | [diff] [blame] | 1631 |  | 
| Santosh Puranik | f3e6968 | 2022-03-31 17:52:38 +0530 | [diff] [blame] | 1632 |         if constexpr (is_same<T, Parsed>::value) | 
 | 1633 |         { | 
 | 1634 |             // Restore asset tag, if needed | 
 | 1635 |             if (processFactoryReset && objectPath == "/system") | 
 | 1636 |             { | 
 | 1637 |                 fillAssetTag(interfaces, vpdMap); | 
 | 1638 |             } | 
 | 1639 |         } | 
 | 1640 |  | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1641 |         objects.emplace(move(object), move(interfaces)); | 
 | 1642 |     } | 
 | 1643 |  | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 1644 |     if (isSystemVpd) | 
 | 1645 |     { | 
 | 1646 |         inventory::ObjectMap primeObject = primeInventory(js, vpdMap); | 
 | 1647 |         objects.insert(primeObject.begin(), primeObject.end()); | 
| Alpana Kumari | 65b8360 | 2020-09-01 00:24:56 -0500 | [diff] [blame] | 1648 |  | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 1649 |         // set the U-boot environment variable for device-tree | 
 | 1650 |         if constexpr (is_same<T, Parsed>::value) | 
 | 1651 |         { | 
| Santosh Puranik | e5f177a | 2022-01-24 20:14:46 +0530 | [diff] [blame] | 1652 |             setDevTreeEnv(fs::path(getSystemsJson(vpdMap)).filename()); | 
| Alpana Kumari | f05effd | 2021-04-07 07:32:53 -0500 | [diff] [blame] | 1653 |         } | 
| PriyangaRamasamy | 8e140a1 | 2020-04-13 19:24:03 +0530 | [diff] [blame] | 1654 |     } | 
 | 1655 |  | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1656 |     // Notify PIM | 
| Sunny Srivastava | 6c71c9d | 2021-04-15 04:43:54 -0500 | [diff] [blame] | 1657 |     common::utility::callPIM(move(objects)); | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1658 | } | 
 | 1659 |  | 
 | 1660 | int main(int argc, char** argv) | 
 | 1661 | { | 
 | 1662 |     int rc = 0; | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 1663 |     json js{}; | 
| PriyangaRamasamy | c2fe40f | 2021-03-02 06:27:33 -0600 | [diff] [blame] | 1664 |     Binary vpdVector{}; | 
 | 1665 |     string file{}; | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1666 |     string driver{}; | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 1667 |     // map to hold additional data in case of logging pel | 
 | 1668 |     PelAdditionalData additionalData{}; | 
 | 1669 |  | 
 | 1670 |     // this is needed to hold base fru inventory path in case there is ECC or | 
 | 1671 |     // vpd exception while parsing the file | 
 | 1672 |     std::string baseFruInventoryPath = {}; | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1673 |  | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1674 |     // It holds the backup EEPROM file path for the system backplane's critical | 
 | 1675 |     // data | 
 | 1676 |     std::string systemVpdBackupPath{}; | 
 | 1677 |  | 
 | 1678 |     // It holds the inventory path of backup EEPROM file | 
 | 1679 |     std::string backupVpdInvPath{}; | 
 | 1680 |  | 
 | 1681 |     bool isSystemVpd = false; | 
 | 1682 |  | 
| Sunny Srivastava | 0746eee | 2021-03-22 13:36:54 -0500 | [diff] [blame] | 1683 |     // severity for PEL | 
 | 1684 |     PelSeverity pelSeverity = PelSeverity::WARNING; | 
 | 1685 |  | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1686 |     try | 
 | 1687 |     { | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1688 |         App app{"ibm-read-vpd - App to read IPZ/Jedec format VPD, parse it and " | 
 | 1689 |                 "store it in DBUS"}; | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1690 |  | 
 | 1691 |         app.add_option("-f, --file", file, "File containing VPD (IPZ/KEYWORD)") | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 1692 |             ->required(); | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1693 |  | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1694 |         app.add_option("--driver", driver, | 
 | 1695 |                        "Driver used by kernel (at24,at25,ee1004)") | 
 | 1696 |             ->required(); | 
 | 1697 |  | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1698 |         CLI11_PARSE(app, argc, argv); | 
 | 1699 |  | 
| Sunny Srivastava | 0746eee | 2021-03-22 13:36:54 -0500 | [diff] [blame] | 1700 |         // PEL severity should be ERROR in case of any system VPD failure | 
 | 1701 |         if (file == systemVpdFilePath) | 
 | 1702 |         { | 
 | 1703 |             pelSeverity = PelSeverity::ERROR; | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1704 |             isSystemVpd = true; | 
| Sunny Srivastava | 0746eee | 2021-03-22 13:36:54 -0500 | [diff] [blame] | 1705 |         } | 
 | 1706 |  | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1707 |         // Check if input file is not empty. | 
 | 1708 |         if ((file.empty()) || (driver.empty())) | 
 | 1709 |         { | 
 | 1710 |             std::cerr << "Encountered empty input parameter file [" << file | 
 | 1711 |                       << "] driver [" << driver << "]" << std::endl; | 
 | 1712 |             return 0; | 
 | 1713 |         } | 
 | 1714 |  | 
 | 1715 |         // Check if currently supported driver or not | 
 | 1716 |         if ((driver != at24driver) && (driver != at25driver) && | 
 | 1717 |             (driver != ee1004driver)) | 
 | 1718 |         { | 
 | 1719 |             std::cerr << "The driver [" << driver << "] is not supported." | 
 | 1720 |                       << std::endl; | 
 | 1721 |             return 0; | 
 | 1722 |         } | 
 | 1723 |  | 
| Santosh Puranik | 0246a4d | 2020-11-04 16:57:39 +0530 | [diff] [blame] | 1724 |         auto jsonToParse = INVENTORY_JSON_DEFAULT; | 
 | 1725 |  | 
 | 1726 |         // If the symlink exists, it means it has been setup for us, switch the | 
 | 1727 |         // path | 
 | 1728 |         if (fs::exists(INVENTORY_JSON_SYM_LINK)) | 
 | 1729 |         { | 
 | 1730 |             jsonToParse = INVENTORY_JSON_SYM_LINK; | 
 | 1731 |         } | 
 | 1732 |  | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1733 |         // Make sure that the file path we get is for a supported EEPROM | 
| Santosh Puranik | 0246a4d | 2020-11-04 16:57:39 +0530 | [diff] [blame] | 1734 |         ifstream inventoryJson(jsonToParse); | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 1735 |         if (!inventoryJson) | 
 | 1736 |         { | 
| Sunny Srivastava | 0746eee | 2021-03-22 13:36:54 -0500 | [diff] [blame] | 1737 |             throw(VpdJsonException("Failed to access Json path", jsonToParse)); | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 1738 |         } | 
 | 1739 |  | 
 | 1740 |         try | 
 | 1741 |         { | 
 | 1742 |             js = json::parse(inventoryJson); | 
 | 1743 |         } | 
| Patrick Williams | 8e15b93 | 2021-10-06 13:04:22 -0500 | [diff] [blame] | 1744 |         catch (const json::parse_error& ex) | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 1745 |         { | 
| Sunny Srivastava | 0746eee | 2021-03-22 13:36:54 -0500 | [diff] [blame] | 1746 |             throw(VpdJsonException("Json parsing failed", jsonToParse)); | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 1747 |         } | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1748 |  | 
| Santosh Puranik | 12e24ff | 2021-05-11 19:33:50 +0530 | [diff] [blame] | 1749 |         // Do we have the mandatory "frus" section? | 
 | 1750 |         if (js.find("frus") == js.end()) | 
 | 1751 |         { | 
 | 1752 |             throw(VpdJsonException("FRUs section not found in JSON", | 
 | 1753 |                                    jsonToParse)); | 
 | 1754 |         } | 
 | 1755 |  | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 1756 |         // Check if it's a udev path - patterned as(/ahb/ahb:apb/ahb:apb:bus@) | 
 | 1757 |         if (file.find("/ahb:apb") != string::npos) | 
 | 1758 |         { | 
 | 1759 |             // Translate udev path to a generic /sys/bus/.. file path. | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1760 |             udevToGenericPath(file, driver); | 
| Santosh Puranik | 12e24ff | 2021-05-11 19:33:50 +0530 | [diff] [blame] | 1761 |  | 
 | 1762 |             if ((js["frus"].find(file) != js["frus"].end()) && | 
| Santosh Puranik | 50f60bf | 2021-05-26 17:55:06 +0530 | [diff] [blame] | 1763 |                 (file == systemVpdFilePath)) | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 1764 |             { | 
| Manojkiran Eda | af92175 | 2024-06-17 15:10:21 +0530 | [diff] [blame] | 1765 |                 std::cout << "We have already collected system VPD, skipping." | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1766 |                           << std::endl; | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 1767 |                 return 0; | 
 | 1768 |             } | 
 | 1769 |         } | 
 | 1770 |  | 
| Jinu Joy Thomas | 2cb6769 | 2024-01-30 10:30:26 -0600 | [diff] [blame] | 1771 |         // Enable all mux which are used for connecting to the i2c on the pcie | 
 | 1772 |         // slots for pcie cards. These are not enabled by kernel due to an issue | 
 | 1773 |         // seen with Castello cards, where the i2c line hangs on a probe. | 
 | 1774 |         // To run it only once have kept it under System vpd check. | 
 | 1775 |         // we need to run this on all BMC reboots so kept here | 
 | 1776 |         if (file == systemVpdFilePath) | 
 | 1777 |         { | 
 | 1778 |             doEnableAllMuxChips(js); | 
 | 1779 |         } | 
 | 1780 |  | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 1781 |         if (file.empty()) | 
 | 1782 |         { | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1783 |             std::cerr << "The EEPROM path <" << file << "> is not valid."; | 
| PriyangaRamasamy | 647868e | 2020-09-08 17:03:19 +0530 | [diff] [blame] | 1784 |             return 0; | 
 | 1785 |         } | 
| Santosh Puranik | 12e24ff | 2021-05-11 19:33:50 +0530 | [diff] [blame] | 1786 |         if (js["frus"].find(file) == js["frus"].end()) | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1787 |         { | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1788 |             std::cerr << "The EEPROM path [" << file | 
 | 1789 |                       << "] is not found in the json." << std::endl; | 
| Santosh Puranik | 88edeb6 | 2020-03-02 12:00:09 +0530 | [diff] [blame] | 1790 |             return 0; | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1791 |         } | 
 | 1792 |  | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 1793 |         if (!fs::exists(file)) | 
 | 1794 |         { | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1795 |             std::cout << "Device path: " << file | 
 | 1796 |                       << " does not exist. Spurious udev event? Exiting." | 
 | 1797 |                       << std::endl; | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 1798 |             return 0; | 
 | 1799 |         } | 
 | 1800 |  | 
| Santosh Puranik | dedb5a6 | 2022-12-19 23:58:32 +0530 | [diff] [blame] | 1801 |         // In case of system VPD it will already be filled, Don't have to | 
 | 1802 |         // overwrite that. | 
 | 1803 |         if (baseFruInventoryPath.empty()) | 
 | 1804 |         { | 
 | 1805 |             baseFruInventoryPath = js["frus"][file][0]["inventoryPath"]; | 
 | 1806 |         } | 
 | 1807 |  | 
| Santosh Puranik | 8589375 | 2020-11-10 21:31:43 +0530 | [diff] [blame] | 1808 |         // Check if we can read the VPD file based on the power state | 
| Santosh Puranik | 27a5e95 | 2021-10-07 22:08:01 -0500 | [diff] [blame] | 1809 |         // We skip reading VPD when the power is ON in two scenarios: | 
| Santosh Puranik | 31d50fa | 2022-04-04 12:04:37 +0530 | [diff] [blame] | 1810 |         // 1) The eeprom we are trying to read is that of the system VPD and the | 
 | 1811 |         // JSON symlink is already setup (the symlink's existence tells us we | 
 | 1812 |         // are not coming out of a factory reset) | 
 | 1813 |         // 2) The JSON tells us that the FRU EEPROM cannot be | 
 | 1814 |         // read when we are powered ON. | 
| Santosh Puranik | 27a5e95 | 2021-10-07 22:08:01 -0500 | [diff] [blame] | 1815 |         if (js["frus"][file].at(0).value("powerOffOnly", false) || | 
| Santosh Puranik | 31d50fa | 2022-04-04 12:04:37 +0530 | [diff] [blame] | 1816 |             (file == systemVpdFilePath && fs::exists(INVENTORY_JSON_SYM_LINK))) | 
| Santosh Puranik | 8589375 | 2020-11-10 21:31:43 +0530 | [diff] [blame] | 1817 |         { | 
 | 1818 |             if ("xyz.openbmc_project.State.Chassis.PowerState.On" == | 
 | 1819 |                 getPowerState()) | 
 | 1820 |             { | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1821 |                 std::cout << "This VPD cannot be read when power is ON" | 
 | 1822 |                           << std::endl; | 
| Santosh Puranik | 8589375 | 2020-11-10 21:31:43 +0530 | [diff] [blame] | 1823 |                 return 0; | 
 | 1824 |             } | 
 | 1825 |         } | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 1826 |  | 
| Santosh Puranik | e9c5753 | 2022-03-15 16:51:51 +0530 | [diff] [blame] | 1827 |         // Check if this VPD should be recollected at all | 
 | 1828 |         if (!needsRecollection(js, file)) | 
 | 1829 |         { | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1830 |             std::cout << "Skip VPD recollection for: " << file << std::endl; | 
| Santosh Puranik | e9c5753 | 2022-03-15 16:51:51 +0530 | [diff] [blame] | 1831 |             return 0; | 
 | 1832 |         } | 
 | 1833 |  | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 1834 |         try | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1835 |         { | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1836 |             variant<KeywordVpdMap, Store> parseResult; | 
| Sunny Srivastava | 37992a6 | 2023-07-11 05:18:41 -0500 | [diff] [blame] | 1837 |             parseResult = parseVpdFile(file, js); | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1838 |  | 
 | 1839 |             if (isSystemVpd) | 
| girik | 18bb985 | 2022-11-16 05:48:13 -0600 | [diff] [blame] | 1840 |             { | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1841 |                 // Get the value of systemVpdBackupPath field from json | 
 | 1842 |                 systemVpdBackupPath = js["frus"][systemVpdFilePath].at(0).value( | 
 | 1843 |                     "systemVpdBackupPath", ""); | 
 | 1844 |  | 
 | 1845 |                 if (!systemVpdBackupPath.empty()) | 
| girik | 18bb985 | 2022-11-16 05:48:13 -0600 | [diff] [blame] | 1846 |                 { | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1847 |                     backupVpdInvPath = | 
 | 1848 |                         js["frus"][systemVpdBackupPath][0]["inventoryPath"] | 
 | 1849 |                             .get_ref<const nlohmann::json::string_t&>(); | 
| girik | 18bb985 | 2022-11-16 05:48:13 -0600 | [diff] [blame] | 1850 |                 } | 
 | 1851 |             } | 
| SunnySrivastava1984 | 9a19554 | 2020-09-07 06:04:50 -0500 | [diff] [blame] | 1852 |  | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 1853 |             if (auto pVal = get_if<Store>(&parseResult)) | 
 | 1854 |             { | 
 | 1855 |                 populateDbus(pVal->getVpdMap(), js, file); | 
 | 1856 |             } | 
 | 1857 |             else if (auto pVal = get_if<KeywordVpdMap>(&parseResult)) | 
 | 1858 |             { | 
 | 1859 |                 populateDbus(*pVal, js, file); | 
 | 1860 |             } | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 1861 |         } | 
| Patrick Williams | 8e15b93 | 2021-10-06 13:04:22 -0500 | [diff] [blame] | 1862 |         catch (const exception& e) | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 1863 |         { | 
| Sunny Srivastava | 37992a6 | 2023-07-11 05:18:41 -0500 | [diff] [blame] | 1864 |             if (!systemVpdBackupPath.empty()) | 
 | 1865 |             { | 
 | 1866 |                 file = systemVpdBackupPath; | 
 | 1867 |                 baseFruInventoryPath = backupVpdInvPath; | 
 | 1868 |             } | 
 | 1869 |  | 
| Alpana Kumari | 735dee9 | 2022-03-25 01:24:40 -0500 | [diff] [blame] | 1870 |             executePostFailAction(js, file); | 
| PriyangaRamasamy | a504c3e | 2020-12-06 12:14:52 -0600 | [diff] [blame] | 1871 |             throw; | 
| Alpana Kumari | 2f79304 | 2020-08-18 05:51:03 -0500 | [diff] [blame] | 1872 |         } | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1873 |     } | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 1874 |     catch (const VpdJsonException& ex) | 
 | 1875 |     { | 
 | 1876 |         additionalData.emplace("JSON_PATH", ex.getJsonPath()); | 
 | 1877 |         additionalData.emplace("DESCRIPTION", ex.what()); | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 1878 |         createPEL(additionalData, pelSeverity, errIntfForJsonFailure, nullptr); | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 1879 |  | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1880 |         std::cerr << ex.what() << "\n"; | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 1881 |         rc = -1; | 
 | 1882 |     } | 
 | 1883 |     catch (const VpdEccException& ex) | 
 | 1884 |     { | 
 | 1885 |         additionalData.emplace("DESCRIPTION", "ECC check failed"); | 
 | 1886 |         additionalData.emplace("CALLOUT_INVENTORY_PATH", | 
 | 1887 |                                INVENTORY_PATH + baseFruInventoryPath); | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 1888 |         createPEL(additionalData, pelSeverity, errIntfForEccCheckFail, nullptr); | 
| Kantesh Nagaradder | 38ee9c8 | 2023-04-07 00:58:12 -0500 | [diff] [blame] | 1889 |  | 
 | 1890 |         if (systemVpdBackupPath.empty()) | 
 | 1891 |         { | 
 | 1892 |             dumpBadVpd(file, vpdVector); | 
 | 1893 |         } | 
 | 1894 |  | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1895 |         std::cerr << ex.what() << "\n"; | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 1896 |         rc = -1; | 
 | 1897 |     } | 
 | 1898 |     catch (const VpdDataException& ex) | 
 | 1899 |     { | 
| alpana07 | 5cb3b1f | 2021-12-16 11:19:36 -0600 | [diff] [blame] | 1900 |         if (isThisPcieOnPass1planar(js, file)) | 
 | 1901 |         { | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1902 |             std::cout << "Pcie_device  [" << file | 
 | 1903 |                       << "]'s VPD is not valid on PASS1 planar.Ignoring.\n"; | 
| alpana07 | 5cb3b1f | 2021-12-16 11:19:36 -0600 | [diff] [blame] | 1904 |             rc = 0; | 
 | 1905 |         } | 
| Santosh Puranik | 53b38ed | 2022-04-10 23:15:22 +0530 | [diff] [blame] | 1906 |         else if (!(isPresent(js, file).value_or(true))) | 
 | 1907 |         { | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1908 |             std::cout << "FRU at: " << file | 
 | 1909 |                       << " is not detected present. Ignore parser error.\n"; | 
| Santosh Puranik | 53b38ed | 2022-04-10 23:15:22 +0530 | [diff] [blame] | 1910 |             rc = 0; | 
 | 1911 |         } | 
| alpana07 | 5cb3b1f | 2021-12-16 11:19:36 -0600 | [diff] [blame] | 1912 |         else | 
 | 1913 |         { | 
 | 1914 |             string errorMsg = | 
 | 1915 |                 "VPD file is either empty or invalid. Parser failed for ["; | 
 | 1916 |             errorMsg += file; | 
 | 1917 |             errorMsg += "], with error = " + std::string(ex.what()); | 
 | 1918 |  | 
 | 1919 |             additionalData.emplace("DESCRIPTION", errorMsg); | 
 | 1920 |             additionalData.emplace("CALLOUT_INVENTORY_PATH", | 
 | 1921 |                                    INVENTORY_PATH + baseFruInventoryPath); | 
| Sunny Srivastava | a2ddc96 | 2022-06-29 08:53:16 -0500 | [diff] [blame] | 1922 |             createPEL(additionalData, pelSeverity, errIntfForInvalidVPD, | 
 | 1923 |                       nullptr); | 
| alpana07 | 5cb3b1f | 2021-12-16 11:19:36 -0600 | [diff] [blame] | 1924 |  | 
 | 1925 |             rc = -1; | 
 | 1926 |         } | 
| SunnySrivastava1984 | a20be8e | 2020-08-26 02:00:50 -0500 | [diff] [blame] | 1927 |     } | 
| Patrick Williams | 8e15b93 | 2021-10-06 13:04:22 -0500 | [diff] [blame] | 1928 |     catch (const exception& e) | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1929 |     { | 
| PriyangaRamasamy | c2fe40f | 2021-03-02 06:27:33 -0600 | [diff] [blame] | 1930 |         dumpBadVpd(file, vpdVector); | 
| jinuthomas | f457a3e | 2023-04-13 12:22:48 -0500 | [diff] [blame] | 1931 |         std::cerr << e.what() << "\n"; | 
| PriyangaRamasamy | abb87ed | 2019-11-19 17:25:35 +0530 | [diff] [blame] | 1932 |         rc = -1; | 
 | 1933 |     } | 
 | 1934 |  | 
 | 1935 |     return rc; | 
| Patrick Williams | c78d887 | 2023-05-10 07:50:56 -0500 | [diff] [blame] | 1936 | } |