blob: d05dd6906f7537e538f55343ab769da9f07e0b09 [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 {
Santosh Puranik8c796812021-12-01 19:17:56 +0530116 std::string objPath{path};
117 // Strip any inventory prefix in path
118 if (objPath.find(INVENTORY_PATH) == 0)
119 {
120 objPath = objPath.substr(sizeof(INVENTORY_PATH) - 1);
121 }
122
123 if (frus.find(objPath) == frus.end())
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600124 {
125 throw std::runtime_error("Inventory path not found");
126 }
127
Santosh Puranik8c796812021-12-01 19:17:56 +0530128 inventory::Path vpdFilePath = frus.find(objPath)->second.first;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600129
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500130 // instantiate editor class to update the data
Santosh Puranik8c796812021-12-01 19:17:56 +0530131 EditorImpl edit(vpdFilePath, jsonFile, recordName, keyword, objPath);
PriyangaRamasamyc0a534f2020-08-24 21:29:18 +0530132 edit.updateKeyword(value, true);
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600133
SunnySrivastava198443306542020-04-01 02:50:20 -0500134 // if it is a motehrboard FRU need to check for location expansion
Santosh Puranik8c796812021-12-01 19:17:56 +0530135 if (frus.find(objPath)->second.second)
SunnySrivastava198443306542020-04-01 02:50:20 -0500136 {
137 if (recordName == "VCEN" && (keyword == "FC" || keyword == "SE"))
138 {
139 edit.expandLocationCode("fcs");
140 }
141 else if (recordName == "VSYS" &&
142 (keyword == "TM" || keyword == "SE"))
143 {
144 edit.expandLocationCode("mts");
145 }
146 }
147
SunnySrivastava19846d8314d2020-05-15 09:34:58 -0500148 return;
SunnySrivastava1984f6d541e2020-02-04 12:50:40 -0600149 }
150 catch (const std::exception& e)
151 {
152 std::cerr << e.what() << std::endl;
153 }
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600154}
155
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500156ListOfPaths
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500157 Manager::getFRUsByUnexpandedLocationCode(const LocationCode locationCode,
158 const NodeNumber nodeNumber)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600159{
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500160 ReaderImpl read;
161 return read.getFrusAtLocation(locationCode, nodeNumber, fruLocationCode);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600162}
163
SunnySrivastava19841356d7e2020-04-24 04:29:35 -0500164ListOfPaths
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500165 Manager::getFRUsByExpandedLocationCode(const LocationCode locationCode)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600166{
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500167 ReaderImpl read;
168 return read.getFRUsByExpandedLocationCode(locationCode, fruLocationCode);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600169}
170
SunnySrivastava1984fb5815a2020-04-24 08:03:52 -0500171LocationCode Manager::getExpandedLocationCode(const LocationCode locationCode,
172 const NodeNumber nodeNumber)
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600173{
SunnySrivastava1984bca5aaa2020-04-21 05:31:04 -0500174 ReaderImpl read;
175 return read.getExpandedLocationCode(locationCode, nodeNumber,
176 fruLocationCode);
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600177}
SunnySrivastava1984de3c60d2020-02-03 10:34:33 -0600178
SunnySrivastava19849a195542020-09-07 06:04:50 -0500179void Manager::performVPDRecollection()
180{
181 // get list of FRUs replaceable at standby
182 for (const auto& item : replaceableFrus)
183 {
184 const vector<nlohmann::json>& groupEEPROM = jsonFile["frus"][item];
185 const nlohmann::json& singleFru = groupEEPROM[0];
186
187 const string& inventoryPath =
188 singleFru["inventoryPath"]
189 .get_ref<const nlohmann::json::string_t&>();
190
191 if ((singleFru.find("devAddress") == singleFru.end()) ||
192 (singleFru.find("driverType") == singleFru.end()) ||
193 (singleFru.find("busType") == singleFru.end()))
194 {
195 // The FRUs is marked for replacement but missing mandatory
196 // fields for recollection. Skip to another replaceable fru.
197 log<level::ERR>(
198 "Recollection Failed as mandatory field missing in Json",
199 entry("ERROR=%s",
200 ("Recollection failed for " + inventoryPath).c_str()));
201 continue;
202 }
203
204 string str = "echo ";
205 string deviceAddress = singleFru["devAddress"];
206 const string& driverType = singleFru["driverType"];
207 const string& busType = singleFru["busType"];
208
209 // devTreeStatus flag is present in json as false to mention
210 // that the EEPROM is not mentioned in device tree. If this flag
211 // is absent consider the value to be true, i.e EEPROM is
212 // mentioned in device tree
213 if (!singleFru.value("devTreeStatus", true))
214 {
215 auto pos = deviceAddress.find('-');
216 if (pos != string::npos)
217 {
218 string busNum = deviceAddress.substr(0, pos);
219 deviceAddress =
220 "0x" + deviceAddress.substr(pos + 1, string::npos);
221
222 string deleteDevice = str + deviceAddress + " > /sys/bus/" +
223 busType + "/devices/" + busType + "-" +
224 busNum + "/delete_device";
225 executeCmd(deleteDevice);
226
227 string addDevice = str + driverType + " " + deviceAddress +
228 " > /sys/bus/" + busType + "/devices/" +
229 busType + "-" + busNum + "/new_device";
230 executeCmd(addDevice);
231 }
232 else
233 {
234 log<level::ERR>(
235 "Wrong format of device address in Json",
236 entry(
237 "ERROR=%s",
238 ("Recollection failed for " + inventoryPath).c_str()));
239 continue;
240 }
241 }
242 else
243 {
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500244 executeCmd(createBindUnbindDriverCmnd(deviceAddress, busType,
245 driverType, "/unbind"));
246 executeCmd(createBindUnbindDriverCmnd(deviceAddress, busType,
247 driverType, "/bind"));
SunnySrivastava19849a195542020-09-07 06:04:50 -0500248 }
249 }
250}
251
SunnySrivastava1984b59fd092020-02-03 09:58:56 -0600252} // namespace manager
253} // namespace vpd
Alpana Kumarib17dd3b2020-10-01 00:18:10 -0500254} // namespace openpower