blob: 316bdda9710cfceb9c7de6a5e37dc0574b1575dd [file] [log] [blame]
AppaRao Pulie63eeda2019-07-05 16:25:38 +05301/*
2// Copyright (c) 2019 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16
AppaRao Puli67d184c2020-05-29 00:48:33 +053017#include "pfr.hpp"
18#include "pfr_mgr.hpp"
19
AppaRao Puli88aa33b2019-07-18 23:49:55 +053020#include <systemd/sd-journal.h>
21
AppaRao Puli46cead92019-07-22 16:50:09 +053022#include <boost/asio.hpp>
AppaRao Pulie63eeda2019-07-05 16:25:38 +053023
AppaRao Pulidcf13122020-05-28 01:21:39 +053024namespace pfr
25{
AppaRao Puli88aa33b2019-07-18 23:49:55 +053026// Caches the last Recovery/Panic Count to
27// identify any new Recovery/panic actions.
28/* TODO: When BMC Reset's, these values will be lost
29 * Persist this info using settingsd */
30static uint8_t lastRecoveryCount = 0;
31static uint8_t lastPanicCount = 0;
32static uint8_t lastMajorErr = 0;
33static uint8_t lastMinorErr = 0;
34
35static bool stateTimerRunning = false;
AppaRao Puli46cead92019-07-22 16:50:09 +053036bool finishedSettingChkPoint = false;
37static constexpr uint8_t bmcBootFinishedChkPoint = 0x09;
38
AppaRao Puli88aa33b2019-07-18 23:49:55 +053039std::unique_ptr<boost::asio::steady_timer> stateTimer = nullptr;
AppaRao Puli46cead92019-07-22 16:50:09 +053040std::unique_ptr<boost::asio::steady_timer> initTimer = nullptr;
AppaRao Puli88aa33b2019-07-18 23:49:55 +053041
AppaRao Pulidcf13122020-05-28 01:21:39 +053042std::vector<std::unique_ptr<PfrVersion>> pfrVersionObjects;
43std::unique_ptr<PfrConfig> pfrConfigObject;
AppaRao Pulie4e95652019-07-19 16:52:01 +053044
AppaRao Pulie4e95652019-07-19 16:52:01 +053045// List holds <ObjPath> <ImageType> <VersionPurpose>
46static std::vector<std::tuple<std::string, ImageType, std::string>>
47 verComponentList = {
AppaRao Pulie4e95652019-07-19 16:52:01 +053048 std::make_tuple("bmc_recovery", ImageType::bmcRecovery,
49 versionPurposeBMC),
AppaRao Pulie4e95652019-07-19 16:52:01 +053050 std::make_tuple("bios_recovery", ImageType::biosRecovery,
51 versionPurposeHost),
Vikram Bodireddy3c6c8c32019-12-05 11:06:15 +053052 std::make_tuple("cpld_active", ImageType::cpldActive,
53 versionPurposeOther),
54 std::make_tuple("cpld_recovery", ImageType::cpldRecovery,
55 versionPurposeOther),
56};
AppaRao Pulie4e95652019-07-19 16:52:01 +053057
AppaRao Pulie90f1282019-11-05 01:07:05 +053058// Recovery reason map.
59// {<CPLD association>,{<Redfish MessageID>, <Recovery Reason>}}
60static const boost::container::flat_map<uint8_t,
61 std::pair<std::string, std::string>>
62 recoveryReasonMap = {
63 {0x01,
64 {"BIOSFirmwareRecoveryReason",
Chalapathi3fb544b2020-02-14 15:43:49 +000065 "BIOS active image authentication failure"}},
AppaRao Pulie90f1282019-11-05 01:07:05 +053066 {0x02,
67 {"BIOSFirmwareRecoveryReason",
Chalapathi3fb544b2020-02-14 15:43:49 +000068 "BIOS recovery image authentication failure"}},
AppaRao Pulie90f1282019-11-05 01:07:05 +053069 {0x03, {"MEFirmwareRecoveryReason", "ME launch failure"}},
70 {0x04, {"BIOSFirmwareRecoveryReason", "ACM launch failure"}},
71 {0x05, {"BIOSFirmwareRecoveryReason", "IBB launch failure"}},
72 {0x06, {"BIOSFirmwareRecoveryReason", "OBB launch failure"}},
73 {0x07,
74 {"BMCFirmwareRecoveryReason",
75 "BMC active image authentication failure"}},
76 {0x08,
77 {"BMCFirmwareRecoveryReason",
78 "BMC recovery image authentication failure"}},
79 {0x09, {"BMCFirmwareRecoveryReason", "BMC launch failure"}},
80 {0x0A, {"CPLDFirmwareRecoveryReason", "CPLD watchdog expired"}}};
AppaRao Puli88aa33b2019-07-18 23:49:55 +053081
AppaRao Pulie90f1282019-11-05 01:07:05 +053082// Panic Reason map.
83// {<CPLD association>, {<Redfish MessageID>, <Panic reason> })
84static const boost::container::flat_map<uint8_t,
85 std::pair<std::string, std::string>>
86 panicReasonMap = {
Chalapathi3fb544b2020-02-14 15:43:49 +000087 {0x01, {"BIOSFirmwarePanicReason", "BIOS update intent"}},
88 {0x02, {"BMCFirmwarePanicReason", "BMC update intent"}},
89 {0x03, {"BMCFirmwarePanicReason", "BMC reset detected"}},
90 {0x04, {"BMCFirmwarePanicReason", "BMC watchdog expired"}},
91 {0x05, {"MEFirmwarePanicReason", "ME watchdog expired"}},
92 {0x06, {"BIOSFirmwarePanicReason", "ACM watchdog expired"}},
93 {0x07, {"BIOSFirmwarePanicReason", "IBB watchdog expired"}},
94 {0x08, {"BIOSFirmwarePanicReason", "OBB watchdog expired"}},
AppaRao Pulie90f1282019-11-05 01:07:05 +053095 {0x09,
96 {"BIOSFirmwarePanicReason",
Chalapathi3fb544b2020-02-14 15:43:49 +000097 "ACM or IBB or OBB authentication failure"}}};
AppaRao Puli88aa33b2019-07-18 23:49:55 +053098
AppaRao Puli24766942019-11-13 19:27:08 +053099// Firmware resiliency major map.
100// {<CPLD association>, {<Redfish MessageID>, <Error reason> })
101static const boost::container::flat_map<uint8_t,
102 std::pair<std::string, std::string>>
103 majorErrorCodeMap = {
104 {0x01,
105 {"BMCFirmwareResiliencyError", "BMC image authentication failed"}},
106 {0x02,
107 {"BIOSFirmwareResiliencyError", "BIOS image authentication failed"}},
Chalapathi3fb544b2020-02-14 15:43:49 +0000108 {0x03, {"BIOSFirmwareResiliencyError", "Update from BIOS failed"}},
109 {0x04, {"BMCFirmwareResiliencyError", "Update from BMC failed"}}};
AppaRao Puli24766942019-11-13 19:27:08 +0530110
AppaRao Pulie4e95652019-07-19 16:52:01 +0530111static void updateDbusPropertiesCache()
112{
113 for (const auto& pfrVerObj : pfrVersionObjects)
114 {
115 pfrVerObj->updateVersion();
116 }
117
118 // Update provisoningStatus properties
119 pfrConfigObject->updateProvisioningStatus();
120
121 phosphor::logging::log<phosphor::logging::level::INFO>(
122 "PFR Manager service cache data updated.");
123}
124
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530125static void logLastRecoveryEvent()
126{
127 uint8_t reason = 0;
AppaRao Pulidcf13122020-05-28 01:21:39 +0530128 if (0 != readCpldReg(ActionType::recoveryReason, reason))
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530129 {
130 return;
131 }
132
AppaRao Pulie90f1282019-11-05 01:07:05 +0530133 auto it = recoveryReasonMap.find(reason);
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530134 if (it == recoveryReasonMap.end())
135 {
136 // No matching found. So just return without logging event.
137 return;
138 }
AppaRao Pulie90f1282019-11-05 01:07:05 +0530139 std::string msgId = "OpenBMC.0.1." + it->second.first;
140 sd_journal_send("MESSAGE=%s", "Platform firmware recovery occurred.",
141 "PRIORITY=%i", LOG_WARNING, "REDFISH_MESSAGE_ID=%s",
142 msgId.c_str(), "REDFISH_MESSAGE_ARGS=%s",
143 it->second.second.c_str(), NULL);
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530144}
145
146static void logLastPanicEvent()
147{
148 uint8_t reason = 0;
AppaRao Pulidcf13122020-05-28 01:21:39 +0530149 if (0 != readCpldReg(ActionType::panicReason, reason))
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530150 {
151 return;
152 }
153
AppaRao Pulie90f1282019-11-05 01:07:05 +0530154 auto it = panicReasonMap.find(reason);
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530155 if (it == panicReasonMap.end())
156 {
157 // No matching found. So just return without logging event.
158 return;
159 }
160
AppaRao Pulie90f1282019-11-05 01:07:05 +0530161 std::string msgId = "OpenBMC.0.1." + it->second.first;
162 sd_journal_send("MESSAGE=%s", "Platform firmware panic occurred.",
163 "PRIORITY=%i", LOG_WARNING, "REDFISH_MESSAGE_ID=%s",
164 msgId.c_str(), "REDFISH_MESSAGE_ARGS=%s",
165 it->second.second.c_str(), NULL);
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530166}
167
AppaRao Puli24766942019-11-13 19:27:08 +0530168static void logResiliencyErrorEvent(const uint8_t majorErrorCode,
169 const uint8_t minorErrorCode)
170{
171 auto it = majorErrorCodeMap.find(majorErrorCode);
172 if (it == majorErrorCodeMap.end())
173 {
174 // No matching found. So just return without logging event.
175 return;
176 }
177
178 std::string errorStr =
179 it->second.second + "(MinorCode:0x" + toHexString(minorErrorCode) + ")";
180 std::string msgId = "OpenBMC.0.1." + it->second.first;
181 sd_journal_send(
182 "MESSAGE=%s", "Platform firmware resiliency error occurred.",
183 "PRIORITY=%i", LOG_ERR, "REDFISH_MESSAGE_ID=%s", msgId.c_str(),
184 "REDFISH_MESSAGE_ARGS=%s", errorStr.c_str(), NULL);
185}
186
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530187static void checkAndLogEvents()
188{
189 uint8_t currPanicCount = 0;
AppaRao Pulidcf13122020-05-28 01:21:39 +0530190 if (0 == readCpldReg(ActionType::panicCount, currPanicCount))
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530191 {
192 if (lastPanicCount != currPanicCount)
193 {
194 // Update cached data and log redfish event by reading reason.
195 lastPanicCount = currPanicCount;
196 logLastPanicEvent();
197 }
198 }
199
200 uint8_t currRecoveryCount = 0;
AppaRao Pulidcf13122020-05-28 01:21:39 +0530201 if (0 == readCpldReg(ActionType::recoveryCount, currRecoveryCount))
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530202 {
203 if (lastRecoveryCount != currRecoveryCount)
204 {
205 // Update cached data and log redfish event by reading reason.
206 lastRecoveryCount = currRecoveryCount;
207 logLastRecoveryEvent();
208 }
209 }
210
211 uint8_t majorErr = 0;
212 uint8_t minorErr = 0;
AppaRao Pulidcf13122020-05-28 01:21:39 +0530213 if ((0 == readCpldReg(ActionType::majorError, majorErr)) &&
214 (0 == readCpldReg(ActionType::minorError, minorErr)))
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530215 {
216 if ((lastMajorErr != majorErr) || (lastMinorErr != minorErr))
217 {
218 lastMajorErr = majorErr;
219 lastMinorErr = minorErr;
220
AppaRao Puli24766942019-11-13 19:27:08 +0530221 logResiliencyErrorEvent(majorErr, minorErr);
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530222 }
223 }
224}
225
226static void monitorPlatformStateChange(
227 sdbusplus::asio::object_server& server,
228 std::shared_ptr<sdbusplus::asio::connection>& conn)
229{
230 constexpr size_t pollTimeout = 10; // seconds
231 stateTimer->expires_after(std::chrono::seconds(pollTimeout));
232 stateTimer->async_wait(
233 [&server, &conn](const boost::system::error_code& ec) {
234 if (ec == boost::asio::error::operation_aborted)
235 {
236 // Timer reset.
237 return;
238 }
239 if (ec)
240 {
241 // Platform State Monitor - Timer cancelled.
242 return;
243 }
244 checkAndLogEvents();
245 monitorPlatformStateChange(server, conn);
246 });
247}
248
AppaRao Puli46cead92019-07-22 16:50:09 +0530249void checkAndSetCheckpoint(sdbusplus::asio::object_server& server,
250 std::shared_ptr<sdbusplus::asio::connection>& conn)
251{
252 // Check whether systemd completed all the loading.
253 conn->async_method_call(
254 [&server, &conn](boost::system::error_code ec,
255 const std::variant<uint64_t>& value) {
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530256 if (!ec)
AppaRao Puli46cead92019-07-22 16:50:09 +0530257 {
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530258 if (std::get<uint64_t>(value))
AppaRao Puli46cead92019-07-22 16:50:09 +0530259 {
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530260 phosphor::logging::log<phosphor::logging::level::INFO>(
261 "PFR: BMC boot completed. Setting checkpoint 9.");
262 if (!finishedSettingChkPoint)
263 {
264 finishedSettingChkPoint = true;
AppaRao Pulidcf13122020-05-28 01:21:39 +0530265 setBMCBootCheckpoint(bmcBootFinishedChkPoint);
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530266 }
267 return;
AppaRao Puli46cead92019-07-22 16:50:09 +0530268 }
269 }
270 else
271 {
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530272 // Failed to get data from systemd. System might not
273 // be ready yet. Attempt again for data.
274 phosphor::logging::log<phosphor::logging::level::ERR>(
275 "PFR: aync call failed to get FinishTimestamp.",
276 phosphor::logging::entry("MSG=%s", ec.message().c_str()));
AppaRao Puli46cead92019-07-22 16:50:09 +0530277 }
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530278 // FIX-ME: Latest up-stream sync caused issue in receiving
279 // StartupFinished signal. Unable to get StartupFinished signal
280 // from systemd1 hence using poll method too, to trigger it
281 // properly.
282 constexpr size_t pollTimeout = 10; // seconds
283 initTimer->expires_after(std::chrono::seconds(pollTimeout));
284 initTimer->async_wait([&server,
285 &conn](const boost::system::error_code& ec) {
286 if (ec == boost::asio::error::operation_aborted)
287 {
288 // Timer reset.
289 phosphor::logging::log<phosphor::logging::level::INFO>(
290 "PFR: Set boot Checkpoint - Timer aborted or stopped.");
291 return;
292 }
293 if (ec)
294 {
295 phosphor::logging::log<phosphor::logging::level::ERR>(
296 "PFR: Set boot Checkpoint - async wait error.");
297 return;
298 }
299 checkAndSetCheckpoint(server, conn);
300 });
AppaRao Puli46cead92019-07-22 16:50:09 +0530301 },
302 "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
303 "org.freedesktop.DBus.Properties", "Get",
304 "org.freedesktop.systemd1.Manager", "FinishTimestamp");
305}
306
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530307void monitorSignals(sdbusplus::asio::object_server& server,
308 std::shared_ptr<sdbusplus::asio::connection>& conn)
AppaRao Pulie63eeda2019-07-05 16:25:38 +0530309{
AppaRao Puli46cead92019-07-22 16:50:09 +0530310 // Monitor Boot finished signal and set the checkpoint 9 to
311 // notify CPLD about BMC boot finish.
312 auto bootFinishedSignal = std::make_unique<sdbusplus::bus::match::match>(
313 static_cast<sdbusplus::bus::bus&>(*conn),
314 "type='signal',"
315 "member='StartupFinished',path='/org/freedesktop/systemd1',"
316 "interface='org.freedesktop.systemd1.Manager'",
317 [&server, &conn](sdbusplus::message::message& msg) {
318 if (!finishedSettingChkPoint)
319 {
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530320 phosphor::logging::log<phosphor::logging::level::INFO>(
321 "PFR: BMC boot completed(StartupFinished). Setting "
322 "checkpoint 9.");
AppaRao Puli46cead92019-07-22 16:50:09 +0530323 finishedSettingChkPoint = true;
AppaRao Pulidcf13122020-05-28 01:21:39 +0530324 setBMCBootCheckpoint(bmcBootFinishedChkPoint);
AppaRao Puli46cead92019-07-22 16:50:09 +0530325 }
326 });
327 checkAndSetCheckpoint(server, conn);
328
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530329 // Capture the Chassis state and Start the monitor timer
330 // if state changed to 'On'. Run timer until OS boot.
331 // Stop timer if state changed to 'Off'.
332 static auto matchChassisState = sdbusplus::bus::match::match(
333 static_cast<sdbusplus::bus::bus&>(*conn),
334 "type='signal',member='PropertiesChanged', "
335 "interface='org.freedesktop.DBus.Properties', "
336 "sender='xyz.openbmc_project.State.Chassis', "
337 "arg0namespace='xyz.openbmc_project.State.Chassis'",
338 [&server, &conn](sdbusplus::message::message& message) {
339 std::string intfName;
340 std::map<std::string, std::variant<std::string>> properties;
341 message.read(intfName, properties);
342
343 const auto it = properties.find("CurrentPowerState");
344 if (it != properties.end())
345 {
346 const std::string* state =
347 std::get_if<std::string>(&it->second);
348 if (state != nullptr)
349 {
350 if ((*state ==
351 "xyz.openbmc_project.State.Chassis.PowerState.On") &&
352 (!stateTimerRunning))
353 {
354 stateTimerRunning = true;
355 monitorPlatformStateChange(server, conn);
356 }
357 else if ((*state == "xyz.openbmc_project.State.Chassis."
358 "PowerState.Off") &&
359 (stateTimerRunning))
360 {
361 stateTimer->cancel();
362 checkAndLogEvents();
363 stateTimerRunning = false;
364 }
365 }
AppaRao Pulie4e95652019-07-19 16:52:01 +0530366
367 // Update the D-Bus properties when chassis state changes.
368 updateDbusPropertiesCache();
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530369 }
370 });
371
372 // Capture the Host state and Start the monitor timer
373 // if state changed to 'Running'. Run timer until OS boot.
374 // Stop timer if state changed to 'Off'.
375 static auto matchHostState = sdbusplus::bus::match::match(
376 static_cast<sdbusplus::bus::bus&>(*conn),
377 "type='signal',member='PropertiesChanged', "
378 "interface='org.freedesktop.DBus.Properties', "
379 "sender='xyz.openbmc_project.State.Chassis', "
380 "arg0namespace='xyz.openbmc_project.State.Host'",
381 [&server, &conn](sdbusplus::message::message& message) {
382 std::string intfName;
383 std::map<std::string, std::variant<std::string>> properties;
384 message.read(intfName, properties);
385
386 const auto it = properties.find("CurrentHostState");
387 if (it != properties.end())
388 {
389 const std::string* state =
390 std::get_if<std::string>(&it->second);
391 if (state != nullptr)
392 {
393 if ((*state ==
394 "xyz.openbmc_project.State.Host.HostState.Running") &&
395 (!stateTimerRunning))
396 {
397 stateTimerRunning = true;
398 monitorPlatformStateChange(server, conn);
399 }
400 else if (((*state == "xyz.openbmc_project.State.Host."
401 "HostState.Off") ||
402 (*state == "xyz.openbmc_project.State.Host."
403 "HostState.Quiesced")) &&
404 (stateTimerRunning))
405 {
406 stateTimer->cancel();
407 checkAndLogEvents();
408 stateTimerRunning = false;
409 }
410 }
AppaRao Pulie4e95652019-07-19 16:52:01 +0530411
412 // Update the D-Bus properties when host state changes.
413 updateDbusPropertiesCache();
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530414 }
415 });
416
417 // Capture the OS state change and stop monitor timer
418 // if OS boots completly or becomes Inactive.
419 // start timer in other cases to mnitor states.
420 static auto matchOsState = sdbusplus::bus::match::match(
421 static_cast<sdbusplus::bus::bus&>(*conn),
422 "type='signal',member='PropertiesChanged', "
423 "interface='org.freedesktop.DBus.Properties', "
424 "sender='xyz.openbmc_project.State.Chassis', "
425 "arg0namespace='xyz.openbmc_project.State.OperatingSystem.Status'",
426 [&server, &conn](sdbusplus::message::message& message) {
427 std::string intfName;
428 std::map<std::string, std::variant<std::string>> properties;
429 message.read(intfName, properties);
430
431 const auto it = properties.find("OperatingSystemState");
432 if (it != properties.end())
433 {
434 const std::string* state =
435 std::get_if<std::string>(&it->second);
436 if (state != nullptr)
437 {
438 if (((*state == "BootComplete") ||
439 (*state == "Inactive")) &&
440 (stateTimerRunning))
441 {
442 stateTimer->cancel();
443 checkAndLogEvents();
444 stateTimerRunning = false;
445 }
446 else if (!stateTimerRunning)
447 {
448 stateTimerRunning = true;
449 monitorPlatformStateChange(server, conn);
450 }
451 }
452 }
453 });
454
455 // First time, check and log events if any.
456 checkAndLogEvents();
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530457}
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530458
AppaRao Pulidcf13122020-05-28 01:21:39 +0530459} // namespace pfr
460
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530461int main()
462{
463 // setup connection to dbus
464 boost::asio::io_service io;
465 auto conn = std::make_shared<sdbusplus::asio::connection>(io);
AppaRao Pulidcf13122020-05-28 01:21:39 +0530466 pfr::stateTimer = std::make_unique<boost::asio::steady_timer>(io);
467 pfr::initTimer = std::make_unique<boost::asio::steady_timer>(io);
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530468 auto server = sdbusplus::asio::object_server(conn, true);
AppaRao Pulidcf13122020-05-28 01:21:39 +0530469 pfr::monitorSignals(server, conn);
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530470
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530471 server.add_manager("/xyz/openbmc_project/pfr");
472
473 // Create PFR attributes object and interface
AppaRao Pulidcf13122020-05-28 01:21:39 +0530474 pfr::pfrConfigObject = std::make_unique<pfr::PfrConfig>(server, conn);
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530475
476 // Create Software objects using Versions interface
AppaRao Pulidcf13122020-05-28 01:21:39 +0530477 for (const auto& entry : pfr::verComponentList)
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530478 {
AppaRao Pulidcf13122020-05-28 01:21:39 +0530479 pfr::pfrVersionObjects.emplace_back(std::make_unique<pfr::PfrVersion>(
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530480 server, conn, std::get<0>(entry), std::get<1>(entry),
481 std::get<2>(entry)));
482 }
483
484 conn->request_name("xyz.openbmc_project.PFR.Manager");
AppaRao Pulie63eeda2019-07-05 16:25:38 +0530485 phosphor::logging::log<phosphor::logging::level::INFO>(
486 "Intel PFR service started successfully");
AppaRao Pulie63eeda2019-07-05 16:25:38 +0530487 io.run();
488
489 return 0;
490}