blob: f39c4e01b2f6218a5d8b2f572444fb4ee4140f52 [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>
Chalapathi Venkataramashettyb2134872020-10-02 21:45:36 +000023#include <sdbusplus/asio/property.hpp>
24#include <sdbusplus/unpack_properties.hpp>
AppaRao Pulie63eeda2019-07-05 16:25:38 +053025
AppaRao Pulidcf13122020-05-28 01:21:39 +053026namespace pfr
27{
AppaRao Puli88aa33b2019-07-18 23:49:55 +053028
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +000029static bool i2cConfigLoaded = false;
30
AppaRao Puli88aa33b2019-07-18 23:49:55 +053031static bool stateTimerRunning = false;
AppaRao Puli46cead92019-07-22 16:50:09 +053032bool finishedSettingChkPoint = false;
33static constexpr uint8_t bmcBootFinishedChkPoint = 0x09;
34
AppaRao Puli88aa33b2019-07-18 23:49:55 +053035std::unique_ptr<boost::asio::steady_timer> stateTimer = nullptr;
AppaRao Puli46cead92019-07-22 16:50:09 +053036std::unique_ptr<boost::asio::steady_timer> initTimer = nullptr;
AppaRao Puli88aa33b2019-07-18 23:49:55 +053037
AppaRao Pulidcf13122020-05-28 01:21:39 +053038std::vector<std::unique_ptr<PfrVersion>> pfrVersionObjects;
39std::unique_ptr<PfrConfig> pfrConfigObject;
AppaRao Pulie4e95652019-07-19 16:52:01 +053040
AppaRao Pulie4e95652019-07-19 16:52:01 +053041// List holds <ObjPath> <ImageType> <VersionPurpose>
42static std::vector<std::tuple<std::string, ImageType, std::string>>
43 verComponentList = {
AppaRao Pulie4e95652019-07-19 16:52:01 +053044 std::make_tuple("bmc_recovery", ImageType::bmcRecovery,
45 versionPurposeBMC),
AppaRao Pulie4e95652019-07-19 16:52:01 +053046 std::make_tuple("bios_recovery", ImageType::biosRecovery,
47 versionPurposeHost),
Vikram Bodireddy3c6c8c32019-12-05 11:06:15 +053048 std::make_tuple("cpld_recovery", ImageType::cpldRecovery,
49 versionPurposeOther),
Vikram Bodireddy8292dc62021-05-26 13:31:47 +053050 std::make_tuple("afm_active", ImageType::afmActive,
51 versionPurposeOther),
52 std::make_tuple("afm_recovery", ImageType::afmRecovery,
53 versionPurposeOther),
Vikram Bodireddy3c6c8c32019-12-05 11:06:15 +053054};
AppaRao Pulie4e95652019-07-19 16:52:01 +053055
AppaRao Pulie90f1282019-11-05 01:07:05 +053056// Recovery reason map.
57// {<CPLD association>,{<Redfish MessageID>, <Recovery Reason>}}
58static const boost::container::flat_map<uint8_t,
59 std::pair<std::string, std::string>>
60 recoveryReasonMap = {
61 {0x01,
62 {"BIOSFirmwareRecoveryReason",
Chalapathi3fb544b2020-02-14 15:43:49 +000063 "BIOS active image authentication failure"}},
AppaRao Pulie90f1282019-11-05 01:07:05 +053064 {0x02,
65 {"BIOSFirmwareRecoveryReason",
Chalapathi3fb544b2020-02-14 15:43:49 +000066 "BIOS recovery image authentication failure"}},
AppaRao Pulie90f1282019-11-05 01:07:05 +053067 {0x03, {"MEFirmwareRecoveryReason", "ME launch failure"}},
68 {0x04, {"BIOSFirmwareRecoveryReason", "ACM launch failure"}},
69 {0x05, {"BIOSFirmwareRecoveryReason", "IBB launch failure"}},
70 {0x06, {"BIOSFirmwareRecoveryReason", "OBB launch failure"}},
71 {0x07,
72 {"BMCFirmwareRecoveryReason",
73 "BMC active image authentication failure"}},
74 {0x08,
75 {"BMCFirmwareRecoveryReason",
76 "BMC recovery image authentication failure"}},
77 {0x09, {"BMCFirmwareRecoveryReason", "BMC launch failure"}},
78 {0x0A, {"CPLDFirmwareRecoveryReason", "CPLD watchdog expired"}}};
AppaRao Puli88aa33b2019-07-18 23:49:55 +053079
AppaRao Pulie90f1282019-11-05 01:07:05 +053080// Panic Reason map.
81// {<CPLD association>, {<Redfish MessageID>, <Panic reason> })
82static const boost::container::flat_map<uint8_t,
83 std::pair<std::string, std::string>>
84 panicReasonMap = {
Chalapathi3fb544b2020-02-14 15:43:49 +000085 {0x01, {"BIOSFirmwarePanicReason", "BIOS update intent"}},
86 {0x02, {"BMCFirmwarePanicReason", "BMC update intent"}},
87 {0x03, {"BMCFirmwarePanicReason", "BMC reset detected"}},
88 {0x04, {"BMCFirmwarePanicReason", "BMC watchdog expired"}},
89 {0x05, {"MEFirmwarePanicReason", "ME watchdog expired"}},
90 {0x06, {"BIOSFirmwarePanicReason", "ACM watchdog expired"}},
91 {0x07, {"BIOSFirmwarePanicReason", "IBB watchdog expired"}},
92 {0x08, {"BIOSFirmwarePanicReason", "OBB watchdog expired"}},
AppaRao Pulie90f1282019-11-05 01:07:05 +053093 {0x09,
94 {"BIOSFirmwarePanicReason",
Chalapathi3fb544b2020-02-14 15:43:49 +000095 "ACM or IBB or OBB authentication failure"}}};
AppaRao Puli88aa33b2019-07-18 23:49:55 +053096
AppaRao Puli24766942019-11-13 19:27:08 +053097// Firmware resiliency major map.
98// {<CPLD association>, {<Redfish MessageID>, <Error reason> })
99static const boost::container::flat_map<uint8_t,
100 std::pair<std::string, std::string>>
101 majorErrorCodeMap = {
102 {0x01,
103 {"BMCFirmwareResiliencyError", "BMC image authentication failed"}},
104 {0x02,
105 {"BIOSFirmwareResiliencyError", "BIOS image authentication failed"}},
Chalapathi3fb544b2020-02-14 15:43:49 +0000106 {0x03, {"BIOSFirmwareResiliencyError", "Update from BIOS failed"}},
107 {0x04, {"BMCFirmwareResiliencyError", "Update from BMC failed"}}};
AppaRao Puli24766942019-11-13 19:27:08 +0530108
AppaRao Pulie4e95652019-07-19 16:52:01 +0530109static void updateDbusPropertiesCache()
110{
111 for (const auto& pfrVerObj : pfrVersionObjects)
112 {
113 pfrVerObj->updateVersion();
114 }
115
116 // Update provisoningStatus properties
117 pfrConfigObject->updateProvisioningStatus();
118
119 phosphor::logging::log<phosphor::logging::level::INFO>(
120 "PFR Manager service cache data updated.");
121}
122
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530123static void logLastRecoveryEvent()
124{
125 uint8_t reason = 0;
AppaRao Pulidcf13122020-05-28 01:21:39 +0530126 if (0 != readCpldReg(ActionType::recoveryReason, reason))
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530127 {
128 return;
129 }
130
AppaRao Pulie90f1282019-11-05 01:07:05 +0530131 auto it = recoveryReasonMap.find(reason);
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530132 if (it == recoveryReasonMap.end())
133 {
134 // No matching found. So just return without logging event.
135 return;
136 }
AppaRao Pulie90f1282019-11-05 01:07:05 +0530137 std::string msgId = "OpenBMC.0.1." + it->second.first;
138 sd_journal_send("MESSAGE=%s", "Platform firmware recovery occurred.",
139 "PRIORITY=%i", LOG_WARNING, "REDFISH_MESSAGE_ID=%s",
140 msgId.c_str(), "REDFISH_MESSAGE_ARGS=%s",
141 it->second.second.c_str(), NULL);
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530142}
143
144static void logLastPanicEvent()
145{
146 uint8_t reason = 0;
AppaRao Pulidcf13122020-05-28 01:21:39 +0530147 if (0 != readCpldReg(ActionType::panicReason, reason))
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530148 {
149 return;
150 }
151
AppaRao Pulie90f1282019-11-05 01:07:05 +0530152 auto it = panicReasonMap.find(reason);
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530153 if (it == panicReasonMap.end())
154 {
155 // No matching found. So just return without logging event.
156 return;
157 }
158
AppaRao Pulie90f1282019-11-05 01:07:05 +0530159 std::string msgId = "OpenBMC.0.1." + it->second.first;
160 sd_journal_send("MESSAGE=%s", "Platform firmware panic occurred.",
161 "PRIORITY=%i", LOG_WARNING, "REDFISH_MESSAGE_ID=%s",
162 msgId.c_str(), "REDFISH_MESSAGE_ARGS=%s",
163 it->second.second.c_str(), NULL);
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530164}
165
AppaRao Puli24766942019-11-13 19:27:08 +0530166static void logResiliencyErrorEvent(const uint8_t majorErrorCode,
167 const uint8_t minorErrorCode)
168{
169 auto it = majorErrorCodeMap.find(majorErrorCode);
170 if (it == majorErrorCodeMap.end())
171 {
172 // No matching found. So just return without logging event.
173 return;
174 }
175
176 std::string errorStr =
177 it->second.second + "(MinorCode:0x" + toHexString(minorErrorCode) + ")";
178 std::string msgId = "OpenBMC.0.1." + it->second.first;
179 sd_journal_send(
180 "MESSAGE=%s", "Platform firmware resiliency error occurred.",
181 "PRIORITY=%i", LOG_ERR, "REDFISH_MESSAGE_ID=%s", msgId.c_str(),
182 "REDFISH_MESSAGE_ARGS=%s", errorStr.c_str(), NULL);
183}
184
Chalapathi Venkataramashettyb2134872020-10-02 21:45:36 +0000185static void
186 handleLastCountChange(std::shared_ptr<sdbusplus::asio::connection> conn,
187 std::string eventName, uint8_t currentCount)
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530188{
Chalapathi Venkataramashettyb2134872020-10-02 21:45:36 +0000189 sdbusplus::asio::setProperty(
190 *conn, "xyz.openbmc_project.Settings",
191 "/xyz/openbmc_project/pfr/last_events",
192 "xyz.openbmc_project.PFR.LastEvents", eventName, currentCount,
193 [](boost::system::error_code ec) {
194 if (ec)
195 {
196 phosphor::logging::log<phosphor::logging::level::ERR>(
197 "PFR: Unable to update currentCount",
198 phosphor::logging::entry("MSG=%s", ec.message().c_str()));
199 return;
200 }
201 });
202 return;
203}
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530204
Chalapathi Venkataramashettyb2134872020-10-02 21:45:36 +0000205static void
206 checkAndLogEvents(std::shared_ptr<sdbusplus::asio::connection>& conn)
207{
208 sdbusplus::asio::getAllProperties(
209 *conn, "xyz.openbmc_project.Settings",
210 "/xyz/openbmc_project/pfr/last_events",
211 "xyz.openbmc_project.PFR.LastEvents",
212 [conn](
213 boost::system::error_code ec,
214 std::vector<
215 std::pair<std::string, std::variant<std::monostate, uint8_t>>>&
216 properties) {
217 if (ec)
218 {
219 phosphor::logging::log<phosphor::logging::level::ERR>(
220 "PFR: Unable get PFR last events",
221 phosphor::logging::entry("MSG=%s", ec.message().c_str()));
222 return;
223 }
224 uint8_t lastRecoveryCount = 0;
225 uint8_t lastPanicCount = 0;
226 uint8_t lastMajorErr = 0;
227 uint8_t lastMinorErr = 0;
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530228
Chalapathi Venkataramashettyb2134872020-10-02 21:45:36 +0000229 try
230 {
231 sdbusplus::unpackProperties(
232 properties, "lastRecoveryCount", lastRecoveryCount,
233 "lastPanicCount", lastPanicCount, "lastMajorErr",
234 lastMajorErr, "lastMinorErr", lastMinorErr);
235 }
236 catch (const sdbusplus::exception::UnpackPropertyError& error)
237 {
238 phosphor::logging::log<phosphor::logging::level::ERR>(
239 "PFR: Unpack error",
240 phosphor::logging::entry("MSG=%s", error.what()));
241 return;
242 }
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530243
Chalapathi Venkataramashettyb2134872020-10-02 21:45:36 +0000244 uint8_t currPanicCount = 0;
245 if (0 == readCpldReg(ActionType::panicCount, currPanicCount))
246 {
247 if (lastPanicCount != currPanicCount)
248 {
249 // Update cached data to dbus and log redfish
250 // event by reading reason.
251 handleLastCountChange(conn, "lastPanicCount",
252 currPanicCount);
253 if (currPanicCount)
254 {
255 logLastPanicEvent();
256 }
257 }
258 }
259
260 uint8_t currRecoveryCount = 0;
261 if (0 == readCpldReg(ActionType::recoveryCount, currRecoveryCount))
262 {
263 if (lastRecoveryCount != currRecoveryCount)
264 {
265 // Update cached data to dbus and log redfish
266 // event by reading reason.
267 handleLastCountChange(conn, "lastRecoveryCount",
268 currRecoveryCount);
269 if (currRecoveryCount)
270 {
271 logLastRecoveryEvent();
272 }
273 }
274 }
275
276 uint8_t majorErr = 0;
277 uint8_t minorErr = 0;
278 if ((0 == readCpldReg(ActionType::majorError, majorErr)) &&
279 (0 == readCpldReg(ActionType::minorError, minorErr)))
280 {
281 if ((lastMajorErr != majorErr) || (lastMinorErr != minorErr))
282 {
283 // Update cached data to dbus and log redfish event by
284 // reading reason.
285 handleLastCountChange(conn, "lastMajorErr", majorErr);
286 handleLastCountChange(conn, "lastMinorErr", minorErr);
287 if (majorErr && minorErr)
288 {
289 logResiliencyErrorEvent(majorErr, minorErr);
290 }
291 }
292 }
293 });
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530294}
295
296static void monitorPlatformStateChange(
297 sdbusplus::asio::object_server& server,
298 std::shared_ptr<sdbusplus::asio::connection>& conn)
299{
300 constexpr size_t pollTimeout = 10; // seconds
301 stateTimer->expires_after(std::chrono::seconds(pollTimeout));
302 stateTimer->async_wait(
303 [&server, &conn](const boost::system::error_code& ec) {
304 if (ec == boost::asio::error::operation_aborted)
305 {
306 // Timer reset.
307 return;
308 }
309 if (ec)
310 {
311 // Platform State Monitor - Timer cancelled.
312 return;
313 }
Chalapathi Venkataramashettyb2134872020-10-02 21:45:36 +0000314 checkAndLogEvents(conn);
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530315 monitorPlatformStateChange(server, conn);
316 });
317}
318
AppaRao Puli46cead92019-07-22 16:50:09 +0530319void checkAndSetCheckpoint(sdbusplus::asio::object_server& server,
320 std::shared_ptr<sdbusplus::asio::connection>& conn)
321{
322 // Check whether systemd completed all the loading.
323 conn->async_method_call(
324 [&server, &conn](boost::system::error_code ec,
325 const std::variant<uint64_t>& value) {
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530326 if (!ec)
AppaRao Puli46cead92019-07-22 16:50:09 +0530327 {
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530328 if (std::get<uint64_t>(value))
AppaRao Puli46cead92019-07-22 16:50:09 +0530329 {
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530330 phosphor::logging::log<phosphor::logging::level::INFO>(
331 "PFR: BMC boot completed. Setting checkpoint 9.");
332 if (!finishedSettingChkPoint)
333 {
334 finishedSettingChkPoint = true;
AppaRao Pulidcf13122020-05-28 01:21:39 +0530335 setBMCBootCheckpoint(bmcBootFinishedChkPoint);
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530336 }
337 return;
AppaRao Puli46cead92019-07-22 16:50:09 +0530338 }
339 }
340 else
341 {
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530342 // Failed to get data from systemd. System might not
343 // be ready yet. Attempt again for data.
344 phosphor::logging::log<phosphor::logging::level::ERR>(
345 "PFR: aync call failed to get FinishTimestamp.",
346 phosphor::logging::entry("MSG=%s", ec.message().c_str()));
AppaRao Puli46cead92019-07-22 16:50:09 +0530347 }
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530348 // FIX-ME: Latest up-stream sync caused issue in receiving
349 // StartupFinished signal. Unable to get StartupFinished signal
350 // from systemd1 hence using poll method too, to trigger it
351 // properly.
352 constexpr size_t pollTimeout = 10; // seconds
353 initTimer->expires_after(std::chrono::seconds(pollTimeout));
354 initTimer->async_wait([&server,
355 &conn](const boost::system::error_code& ec) {
356 if (ec == boost::asio::error::operation_aborted)
357 {
358 // Timer reset.
359 phosphor::logging::log<phosphor::logging::level::INFO>(
360 "PFR: Set boot Checkpoint - Timer aborted or stopped.");
361 return;
362 }
363 if (ec)
364 {
365 phosphor::logging::log<phosphor::logging::level::ERR>(
366 "PFR: Set boot Checkpoint - async wait error.");
367 return;
368 }
369 checkAndSetCheckpoint(server, conn);
370 });
AppaRao Puli46cead92019-07-22 16:50:09 +0530371 },
372 "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
373 "org.freedesktop.DBus.Properties", "Get",
374 "org.freedesktop.systemd1.Manager", "FinishTimestamp");
375}
376
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530377void monitorSignals(sdbusplus::asio::object_server& server,
378 std::shared_ptr<sdbusplus::asio::connection>& conn)
AppaRao Pulie63eeda2019-07-05 16:25:38 +0530379{
AppaRao Puli46cead92019-07-22 16:50:09 +0530380 // Monitor Boot finished signal and set the checkpoint 9 to
381 // notify CPLD about BMC boot finish.
382 auto bootFinishedSignal = std::make_unique<sdbusplus::bus::match::match>(
383 static_cast<sdbusplus::bus::bus&>(*conn),
384 "type='signal',"
385 "member='StartupFinished',path='/org/freedesktop/systemd1',"
386 "interface='org.freedesktop.systemd1.Manager'",
387 [&server, &conn](sdbusplus::message::message& msg) {
388 if (!finishedSettingChkPoint)
389 {
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530390 phosphor::logging::log<phosphor::logging::level::INFO>(
391 "PFR: BMC boot completed(StartupFinished). Setting "
392 "checkpoint 9.");
AppaRao Puli46cead92019-07-22 16:50:09 +0530393 finishedSettingChkPoint = true;
AppaRao Pulidcf13122020-05-28 01:21:39 +0530394 setBMCBootCheckpoint(bmcBootFinishedChkPoint);
AppaRao Puli46cead92019-07-22 16:50:09 +0530395 }
396 });
397 checkAndSetCheckpoint(server, conn);
398
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530399 // Capture the Chassis state and Start the monitor timer
400 // if state changed to 'On'. Run timer until OS boot.
401 // Stop timer if state changed to 'Off'.
402 static auto matchChassisState = sdbusplus::bus::match::match(
403 static_cast<sdbusplus::bus::bus&>(*conn),
404 "type='signal',member='PropertiesChanged', "
405 "interface='org.freedesktop.DBus.Properties', "
406 "sender='xyz.openbmc_project.State.Chassis', "
407 "arg0namespace='xyz.openbmc_project.State.Chassis'",
408 [&server, &conn](sdbusplus::message::message& message) {
409 std::string intfName;
410 std::map<std::string, std::variant<std::string>> properties;
411 message.read(intfName, properties);
412
413 const auto it = properties.find("CurrentPowerState");
414 if (it != properties.end())
415 {
416 const std::string* state =
417 std::get_if<std::string>(&it->second);
418 if (state != nullptr)
419 {
420 if ((*state ==
421 "xyz.openbmc_project.State.Chassis.PowerState.On") &&
422 (!stateTimerRunning))
423 {
424 stateTimerRunning = true;
425 monitorPlatformStateChange(server, conn);
426 }
427 else if ((*state == "xyz.openbmc_project.State.Chassis."
428 "PowerState.Off") &&
429 (stateTimerRunning))
430 {
431 stateTimer->cancel();
Chalapathi Venkataramashettyb2134872020-10-02 21:45:36 +0000432 checkAndLogEvents(conn);
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530433 stateTimerRunning = false;
434 }
435 }
AppaRao Pulie4e95652019-07-19 16:52:01 +0530436
437 // Update the D-Bus properties when chassis state changes.
438 updateDbusPropertiesCache();
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530439 }
440 });
441
442 // Capture the Host state and Start the monitor timer
443 // if state changed to 'Running'. Run timer until OS boot.
444 // Stop timer if state changed to 'Off'.
445 static auto matchHostState = sdbusplus::bus::match::match(
446 static_cast<sdbusplus::bus::bus&>(*conn),
447 "type='signal',member='PropertiesChanged', "
448 "interface='org.freedesktop.DBus.Properties', "
449 "sender='xyz.openbmc_project.State.Chassis', "
450 "arg0namespace='xyz.openbmc_project.State.Host'",
451 [&server, &conn](sdbusplus::message::message& message) {
452 std::string intfName;
453 std::map<std::string, std::variant<std::string>> properties;
454 message.read(intfName, properties);
455
456 const auto it = properties.find("CurrentHostState");
457 if (it != properties.end())
458 {
459 const std::string* state =
460 std::get_if<std::string>(&it->second);
461 if (state != nullptr)
462 {
463 if ((*state ==
464 "xyz.openbmc_project.State.Host.HostState.Running") &&
465 (!stateTimerRunning))
466 {
467 stateTimerRunning = true;
468 monitorPlatformStateChange(server, conn);
469 }
470 else if (((*state == "xyz.openbmc_project.State.Host."
471 "HostState.Off") ||
472 (*state == "xyz.openbmc_project.State.Host."
473 "HostState.Quiesced")) &&
474 (stateTimerRunning))
475 {
476 stateTimer->cancel();
Chalapathi Venkataramashettyb2134872020-10-02 21:45:36 +0000477 checkAndLogEvents(conn);
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530478 stateTimerRunning = false;
479 }
480 }
AppaRao Pulie4e95652019-07-19 16:52:01 +0530481
482 // Update the D-Bus properties when host state changes.
483 updateDbusPropertiesCache();
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530484 }
485 });
486
487 // Capture the OS state change and stop monitor timer
488 // if OS boots completly or becomes Inactive.
489 // start timer in other cases to mnitor states.
490 static auto matchOsState = sdbusplus::bus::match::match(
491 static_cast<sdbusplus::bus::bus&>(*conn),
492 "type='signal',member='PropertiesChanged', "
493 "interface='org.freedesktop.DBus.Properties', "
494 "sender='xyz.openbmc_project.State.Chassis', "
495 "arg0namespace='xyz.openbmc_project.State.OperatingSystem.Status'",
496 [&server, &conn](sdbusplus::message::message& message) {
497 std::string intfName;
498 std::map<std::string, std::variant<std::string>> properties;
499 message.read(intfName, properties);
500
501 const auto it = properties.find("OperatingSystemState");
502 if (it != properties.end())
503 {
504 const std::string* state =
505 std::get_if<std::string>(&it->second);
506 if (state != nullptr)
507 {
508 if (((*state == "BootComplete") ||
509 (*state == "Inactive")) &&
510 (stateTimerRunning))
511 {
512 stateTimer->cancel();
Chalapathi Venkataramashettyb2134872020-10-02 21:45:36 +0000513 checkAndLogEvents(conn);
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530514 stateTimerRunning = false;
515 }
516 else if (!stateTimerRunning)
517 {
518 stateTimerRunning = true;
519 monitorPlatformStateChange(server, conn);
520 }
521 }
522 }
523 });
524
525 // First time, check and log events if any.
Chalapathi Venkataramashettyb2134872020-10-02 21:45:36 +0000526 checkAndLogEvents(conn);
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530527}
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530528
Chalapathi Venkataramashettye6fb18e2021-02-03 14:51:00 +0000529static void updateCPLDversion(std::shared_ptr<sdbusplus::asio::connection> conn)
530{
531 std::string cpldVersion = pfr::readCPLDVersion();
532 conn->async_method_call(
533 [](const boost::system::error_code ec) {
534 if (ec)
535 {
536 phosphor::logging::log<phosphor::logging::level::ERR>(
537 "Unable to update cpld_active version",
538 phosphor::logging::entry("MSG=%s", ec.message().c_str()));
539 return;
540 }
541 },
542 "xyz.openbmc_project.Settings",
543 "/xyz/openbmc_project/software/cpld_active",
544 "org.freedesktop.DBus.Properties", "Set",
545 "xyz.openbmc_project.Software.Version", "Version",
546 std::variant<std::string>(cpldVersion));
547 return;
548}
549
AppaRao Pulidcf13122020-05-28 01:21:39 +0530550} // namespace pfr
551
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530552int main()
553{
554 // setup connection to dbus
555 boost::asio::io_service io;
556 auto conn = std::make_shared<sdbusplus::asio::connection>(io);
AppaRao Pulidcf13122020-05-28 01:21:39 +0530557 pfr::stateTimer = std::make_unique<boost::asio::steady_timer>(io);
558 pfr::initTimer = std::make_unique<boost::asio::steady_timer>(io);
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530559 auto server = sdbusplus::asio::object_server(conn, true);
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +0000560 pfr::init(conn, pfr::i2cConfigLoaded);
AppaRao Pulidcf13122020-05-28 01:21:39 +0530561 pfr::monitorSignals(server, conn);
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530562
Chalapathi Venkataramashettye6fb18e2021-02-03 14:51:00 +0000563 // Update CPLD Version to cpld_active object in settings.
564 pfr::updateCPLDversion(conn);
565
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530566 server.add_manager("/xyz/openbmc_project/pfr");
567
568 // Create PFR attributes object and interface
AppaRao Pulidcf13122020-05-28 01:21:39 +0530569 pfr::pfrConfigObject = std::make_unique<pfr::PfrConfig>(server, conn);
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530570
571 // Create Software objects using Versions interface
AppaRao Pulidcf13122020-05-28 01:21:39 +0530572 for (const auto& entry : pfr::verComponentList)
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530573 {
AppaRao Pulidcf13122020-05-28 01:21:39 +0530574 pfr::pfrVersionObjects.emplace_back(std::make_unique<pfr::PfrVersion>(
AppaRao Pulia9bf9712020-01-12 05:45:48 +0530575 server, conn, std::get<0>(entry), std::get<1>(entry),
576 std::get<2>(entry)));
577 }
578
579 conn->request_name("xyz.openbmc_project.PFR.Manager");
AppaRao Pulie63eeda2019-07-05 16:25:38 +0530580 phosphor::logging::log<phosphor::logging::level::INFO>(
581 "Intel PFR service started successfully");
AppaRao Pulie63eeda2019-07-05 16:25:38 +0530582 io.run();
583
584 return 0;
585}