blob: edef56bee667ad9f210359c3e2b8683f06f4e336 [file] [log] [blame]
SunnySrivastava1984b59fd092020-02-03 09:58:56 -06001#include "config.h"
2
3#include "manager.hpp"
4
SunnySrivastava1984d076da82020-03-05 05:33:35 -06005#include "editor_impl.hpp"
Alpana Kumarib17dd3b2020-10-01 00:18:10 -05006#include "gpioMonitor.hpp"
Sunny Srivastava6c71c9d2021-04-15 04:43:54 -05007#include "ibm_vpd_utils.hpp"
SunnySrivastava1984e12b1812020-05-26 02:23:11 -05008#include "ipz_parser.hpp"
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -05009#include "reader_impl.hpp"
SunnySrivastava19849a195542020-09-07 06:04:50 -050010#include "vpd_exceptions.hpp"
11
12#include <phosphor-logging/elog-errors.hpp>
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060013
Alpana Kumarib17dd3b2020-10-01 00:18:10 -050014using namespace openpower::vpd::manager;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060015using namespace openpower::vpd::constants;
SunnySrivastava19841356d7e2020-04-24 04:29:35 -050016using namespace openpower::vpd::inventory;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -060017using namespace openpower::vpd::manager::editor;
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050018using namespace openpower::vpd::manager::reader;
SunnySrivastava19849a195542020-09-07 06:04:50 -050019using namespace std;
20using namespace openpower::vpd::parser;
21using namespace openpower::vpd::exceptions;
22using namespace phosphor::logging;
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060023
24namespace openpower
25{
26namespace vpd
27{
28namespace manager
29{
30Manager::Manager(sdbusplus::bus::bus&& bus, const char* busName,
Priyanga Ramasamy9d149342020-07-16 23:41:26 +053031 const char* objPath, const char* /*iFace*/) :
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060032 ServerObject<ManagerIface>(bus, objPath),
33 _bus(std::move(bus)), _manager(_bus, objPath)
34{
35 _bus.request_name(busName);
36}
37
38void Manager::run()
39{
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -060040 try
41 {
42 processJSON();
Alpana Kumarib17dd3b2020-10-01 00:18:10 -050043
44 auto event = sdeventplus::Event::get_default();
45 GpioMonitor gpioMon1(jsonFile, event);
46
47 _bus.attach_event(event.get(), SD_EVENT_PRIORITY_IMPORTANT);
48 cout << "VPD manager event loop started\n";
49 event.loop();
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -060050 }
51 catch (const std::exception& e)
52 {
53 std::cerr << e.what() << "\n";
54 }
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -060055}
56
57void Manager::processJSON()
58{
Santosh Puranik0246a4d2020-11-04 16:57:39 +053059 std::ifstream json(INVENTORY_JSON_SYM_LINK, std::ios::binary);
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -060060
61 if (!json)
62 {
63 throw std::runtime_error("json file not found");
64 }
65
66 jsonFile = nlohmann::json::parse(json);
67 if (jsonFile.find("frus") == jsonFile.end())
68 {
69 throw std::runtime_error("frus group not found in json");
70 }
71
72 const nlohmann::json& groupFRUS =
73 jsonFile["frus"].get_ref<const nlohmann::json::object_t&>();
74 for (const auto& itemFRUS : groupFRUS.items())
75 {
76 const std::vector<nlohmann::json>& groupEEPROM =
77 itemFRUS.value().get_ref<const nlohmann::json::array_t&>();
78 for (const auto& itemEEPROM : groupEEPROM)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -060079 {
SunnySrivastava198443306542020-04-01 02:50:20 -050080 bool isMotherboard = false;
81 if (itemEEPROM["extraInterfaces"].find(
82 "xyz.openbmc_project.Inventory.Item.Board.Motherboard") !=
83 itemEEPROM["extraInterfaces"].end())
84 {
85 isMotherboard = true;
86 }
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -060087 frus.emplace(itemEEPROM["inventoryPath"]
88 .get_ref<const nlohmann::json::string_t&>(),
SunnySrivastava198443306542020-04-01 02:50:20 -050089 std::make_pair(itemFRUS.key(), isMotherboard));
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -050090
Alpana Kumari414d5ae2021-03-04 21:06:35 +000091 if (itemEEPROM["extraInterfaces"].find(IBM_LOCATION_CODE_INF) !=
Alpana Kumari920408d2020-05-14 00:07:03 -050092 itemEEPROM["extraInterfaces"].end())
93 {
94 fruLocationCode.emplace(
Alpana Kumari414d5ae2021-03-04 21:06:35 +000095 itemEEPROM["extraInterfaces"][IBM_LOCATION_CODE_INF]
Alpana Kumari920408d2020-05-14 00:07:03 -050096 ["LocationCode"]
97 .get_ref<const nlohmann::json::string_t&>(),
98 itemEEPROM["inventoryPath"]
99 .get_ref<const nlohmann::json::string_t&>());
100 }
SunnySrivastava19849a195542020-09-07 06:04:50 -0500101
102 if (itemEEPROM.value("isReplaceable", false))
103 {
104 replaceableFrus.emplace_back(itemFRUS.key());
105 }
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600106 }
107 }
108}
109
110void Manager::writeKeyword(const sdbusplus::message::object_path path,
111 const std::string recordName,
112 const std::string keyword, const Binary value)
113{
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600114 try
115 {
116 if (frus.find(path) == frus.end())
117 {
118 throw std::runtime_error("Inventory path not found");
119 }
120
SunnySrivastava198443306542020-04-01 02:50:20 -0500121 inventory::Path vpdFilePath = frus.find(path)->second.first;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600122
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500123 // instantiate editor class to update the data
Alpana Kumari920408d2020-05-14 00:07:03 -0500124 EditorImpl edit(vpdFilePath, jsonFile, recordName, keyword, path);
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530125 edit.updateKeyword(value, true);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600126
SunnySrivastava198443306542020-04-01 02:50:20 -0500127 // if it is a motehrboard FRU need to check for location expansion
128 if (frus.find(path)->second.second)
129 {
130 if (recordName == "VCEN" && (keyword == "FC" || keyword == "SE"))
131 {
132 edit.expandLocationCode("fcs");
133 }
134 else if (recordName == "VSYS" &&
135 (keyword == "TM" || keyword == "SE"))
136 {
137 edit.expandLocationCode("mts");
138 }
139 }
140
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500141 return;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600142 }
143 catch (const std::exception& e)
144 {
145 std::cerr << e.what() << std::endl;
146 }
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600147}
148
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500149ListOfPaths
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500150 Manager::getFRUsByUnexpandedLocationCode(const LocationCode locationCode,
151 const NodeNumber nodeNumber)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600152{
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500153 ReaderImpl read;
154 return read.getFrusAtLocation(locationCode, nodeNumber, fruLocationCode);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600155}
156
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500157ListOfPaths
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500158 Manager::getFRUsByExpandedLocationCode(const LocationCode locationCode)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600159{
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500160 ReaderImpl read;
161 return read.getFRUsByExpandedLocationCode(locationCode, fruLocationCode);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600162}
163
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500164LocationCode Manager::getExpandedLocationCode(const LocationCode locationCode,
165 const NodeNumber nodeNumber)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600166{
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -0500167 ReaderImpl read;
168 return read.getExpandedLocationCode(locationCode, nodeNumber,
169 fruLocationCode);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600170}
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -0600171
SunnySrivastava19849a195542020-09-07 06:04:50 -0500172void Manager::performVPDRecollection()
173{
174 // get list of FRUs replaceable at standby
175 for (const auto& item : replaceableFrus)
176 {
177 const vector<nlohmann::json>& groupEEPROM = jsonFile["frus"][item];
178 const nlohmann::json& singleFru = groupEEPROM[0];
179
180 const string& inventoryPath =
181 singleFru["inventoryPath"]
182 .get_ref<const nlohmann::json::string_t&>();
183
184 if ((singleFru.find("devAddress") == singleFru.end()) ||
185 (singleFru.find("driverType") == singleFru.end()) ||
186 (singleFru.find("busType") == singleFru.end()))
187 {
188 // The FRUs is marked for replacement but missing mandatory
189 // fields for recollection. Skip to another replaceable fru.
190 log<level::ERR>(
191 "Recollection Failed as mandatory field missing in Json",
192 entry("ERROR=%s",
193 ("Recollection failed for " + inventoryPath).c_str()));
194 continue;
195 }
196
197 string str = "echo ";
198 string deviceAddress = singleFru["devAddress"];
199 const string& driverType = singleFru["driverType"];
200 const string& busType = singleFru["busType"];
201
202 // devTreeStatus flag is present in json as false to mention
203 // that the EEPROM is not mentioned in device tree. If this flag
204 // is absent consider the value to be true, i.e EEPROM is
205 // mentioned in device tree
206 if (!singleFru.value("devTreeStatus", true))
207 {
208 auto pos = deviceAddress.find('-');
209 if (pos != string::npos)
210 {
211 string busNum = deviceAddress.substr(0, pos);
212 deviceAddress =
213 "0x" + deviceAddress.substr(pos + 1, string::npos);
214
215 string deleteDevice = str + deviceAddress + " > /sys/bus/" +
216 busType + "/devices/" + busType + "-" +
217 busNum + "/delete_device";
218 executeCmd(deleteDevice);
219
220 string addDevice = str + driverType + " " + deviceAddress +
221 " > /sys/bus/" + busType + "/devices/" +
222 busType + "-" + busNum + "/new_device";
223 executeCmd(addDevice);
224 }
225 else
226 {
227 log<level::ERR>(
228 "Wrong format of device address in Json",
229 entry(
230 "ERROR=%s",
231 ("Recollection failed for " + inventoryPath).c_str()));
232 continue;
233 }
234 }
235 else
236 {
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500237 executeCmd(createBindUnbindDriverCmnd(deviceAddress, busType,
238 driverType, "/unbind"));
239 executeCmd(createBindUnbindDriverCmnd(deviceAddress, busType,
240 driverType, "/bind"));
SunnySrivastava19849a195542020-09-07 06:04:50 -0500241 }
242 }
243}
244
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600245} // namespace manager
246} // namespace vpd
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500247} // namespace openpower