blob: b52ba2287c00c7c9eb247ad0405491e30521ba40 [file] [log] [blame]
AppaRao Pulic532f552019-07-05 15:23:50 +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 Pulic532f552019-07-05 15:23:50 +053017#include "pfr.hpp"
AppaRao Puli67d184c2020-05-29 00:48:33 +053018
AppaRao Pulic532f552019-07-05 15:23:50 +053019#include "file.hpp"
AppaRao Puli4b639a22019-10-01 18:12:59 +053020#include "spiDev.hpp"
AppaRao Pulic532f552019-07-05 15:23:50 +053021
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +000022#include <gpiod.hpp>
23
AppaRao Puli67d184c2020-05-29 00:48:33 +053024#include <iomanip>
25#include <iostream>
26#include <sstream>
27
AppaRao Pulic532f552019-07-05 15:23:50 +053028namespace pfr
29{
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +000030
31using GetSubTreeType = std::vector<
32 std::pair<std::string,
33 std::vector<std::pair<std::string, std::vector<std::string>>>>>;
34
35static int i2cBusNumber = 4;
36static int i2cSlaveAddress = 56;
AppaRao Pulic532f552019-07-05 15:23:50 +053037
38// CPLD mailbox registers
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +000039static constexpr uint8_t pfrROTId = 0x00;
AppaRao Pulic532f552019-07-05 15:23:50 +053040static constexpr uint8_t cpldROTVersion = 0x01;
41static constexpr uint8_t cpldROTSvn = 0x02;
42static constexpr uint8_t platformState = 0x03;
43static constexpr uint8_t recoveryCount = 0x04;
44static constexpr uint8_t lastRecoveryReason = 0x05;
45static constexpr uint8_t panicEventCount = 0x06;
46static constexpr uint8_t panicEventReason = 0x07;
47static constexpr uint8_t majorErrorCode = 0x08;
48static constexpr uint8_t minorErrorCode = 0x09;
49static constexpr uint8_t provisioningStatus = 0x0A;
Vikram Bodireddy08841912020-08-31 18:11:45 +053050static constexpr uint8_t bmcBootCheckpointRev1 = 0x0F;
51static constexpr uint8_t bmcBootCheckpoint = 0x60;
AppaRao Pulia04c8252019-07-31 22:59:28 +053052static constexpr uint8_t pchActiveMajorVersion = 0x15;
53static constexpr uint8_t pchActiveMinorVersion = 0x16;
AppaRao Pulia04c8252019-07-31 22:59:28 +053054static constexpr uint8_t pchRecoveryMajorVersion = 0x1B;
55static constexpr uint8_t pchRecoveryMinorVersion = 0x1C;
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +000056static constexpr uint8_t CPLDHashRegStart = 0x20;
57static constexpr uint8_t pfrRoTValue = 0xDE;
Vikram Bodireddy8292dc62021-05-26 13:31:47 +053058static constexpr uint8_t afmActiveMajorVersion = 0x75;
59static constexpr uint8_t afmActiveMinorVersion = 0x76;
60static constexpr uint8_t afmRecoveryMajorVersion = 0x78;
61static constexpr uint8_t afmRecoveryMinorVersion = 0x79;
AppaRao Pulic532f552019-07-05 15:23:50 +053062
63static constexpr uint8_t ufmLockedMask = (0x1 << 0x04);
64static constexpr uint8_t ufmProvisionedMask = (0x1 << 0x05);
65
AppaRao Puli4b639a22019-10-01 18:12:59 +053066// PFR MTD devices
67static constexpr const char* bmcActiveImgPfmMTDDev = "/dev/mtd/pfm";
68static constexpr const char* bmcRecoveryImgMTDDev = "/dev/mtd/rc-image";
69
70// PFM offset in full image
71static constexpr const uint32_t pfmBaseOffsetInImage = 0x400;
72
73// OFFSET values in PFM
74static constexpr const uint32_t verOffsetInPFM = 0x406;
75static constexpr const uint32_t buildNumOffsetInPFM = 0x40C;
76static constexpr const uint32_t buildHashOffsetInPFM = 0x40D;
77
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +000078static const std::array<std::string, 8> mainCPLDGpioLines = {
79 "MAIN_PLD_MAJOR_REV_BIT3", "MAIN_PLD_MAJOR_REV_BIT2",
80 "MAIN_PLD_MAJOR_REV_BIT1", "MAIN_PLD_MAJOR_REV_BIT0",
81 "MAIN_PLD_MINOR_REV_BIT3", "MAIN_PLD_MINOR_REV_BIT2",
82 "MAIN_PLD_MINOR_REV_BIT1", "MAIN_PLD_MINOR_REV_BIT0"};
83
84static const std::array<std::string, 8> pldGpioLines = {
85 "SGPIO_PLD_MAJOR_REV_BIT3", "SGPIO_PLD_MAJOR_REV_BIT2",
86 "SGPIO_PLD_MAJOR_REV_BIT1", "SGPIO_PLD_MAJOR_REV_BIT0",
87 "SGPIO_PLD_MINOR_REV_BIT3", "SGPIO_PLD_MINOR_REV_BIT2",
88 "SGPIO_PLD_MINOR_REV_BIT1", "SGPIO_PLD_MINOR_REV_BIT0"};
89
Chalapathi Venkataramashetty00acaff2020-12-24 11:01:17 +000090bool exceptionFlag = true;
91
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +000092void init(std::shared_ptr<sdbusplus::asio::connection> conn,
93 bool& i2cConfigLoaded)
94{
95 conn->async_method_call(
96 [conn, &i2cConfigLoaded](const boost::system::error_code ec,
97 const GetSubTreeType& resp) {
98 if (ec || resp.size() != 1)
99 {
100 return;
101 }
102
103 const std::string& objPath = resp[0].first;
104 const std::string& serviceName = resp[0].second.begin()->first;
105 const std::string match = "Baseboard/PFR";
106 if (boost::ends_with(objPath, match))
107 {
108 // PFR object found.. check for PFR support
109 conn->async_method_call(
110 [objPath, serviceName, conn, &i2cConfigLoaded](
111 boost::system::error_code ec,
112 const std::vector<std::pair<
113 std::string, std::variant<std::string, uint64_t>>>&
114 propertiesList) {
115 if (ec)
116 {
117 phosphor::logging::log<
118 phosphor::logging::level::ERR>(
119 "Error to Get PFR properties.",
120 phosphor::logging::entry("MSG=%s",
121 ec.message().c_str()));
122 return;
123 }
124
125 const uint64_t* i2cBus = nullptr;
126 const uint64_t* address = nullptr;
127
128 for (const auto& [propName, propVariant] :
129 propertiesList)
130 {
131 if (propName == "Address")
132 {
133 address = std::get_if<uint64_t>(&propVariant);
134 }
135 else if (propName == "Bus")
136 {
137 i2cBus = std::get_if<uint64_t>(&propVariant);
138 }
139 }
140
141 if ((address == nullptr) || (i2cBus == nullptr))
142 {
143 phosphor::logging::log<
144 phosphor::logging::level::ERR>(
145 "Unable to read the pfr properties");
146 return;
147 }
148
149 i2cBusNumber = static_cast<int>(*i2cBus);
150 i2cSlaveAddress = static_cast<int>(*address);
151 i2cConfigLoaded = true;
152 },
153 serviceName, objPath, "org.freedesktop.DBus.Properties",
154 "GetAll", "xyz.openbmc_project.Configuration.PFR");
155 }
156 },
157 "xyz.openbmc_project.ObjectMapper",
158 "/xyz/openbmc_project/object_mapper",
159 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
160 "/xyz/openbmc_project/inventory/system", 0,
161 std::array<const char*, 1>{"xyz.openbmc_project.Configuration.PFR"});
162 return;
163}
164
AppaRao Pulidbe184d2019-10-09 18:04:22 +0530165std::string toHexString(const uint8_t val)
AppaRao Pulic532f552019-07-05 15:23:50 +0530166{
167 std::stringstream stream;
AppaRao Pulidbe184d2019-10-09 18:04:22 +0530168 stream << std::setfill('0') << std::setw(2) << std::hex
169 << static_cast<int>(val);
AppaRao Pulic532f552019-07-05 15:23:50 +0530170 return stream.str();
171}
172
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000173static std::string readCPLDHash()
174{
175 std::stringstream hashStrStream;
176 static constexpr uint8_t hashLength = 32;
177 std::array<uint8_t, hashLength> hashValue = {0};
178 try
179 {
180 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
181 if (cpldDev.i2cReadBlockData(CPLDHashRegStart, hashLength,
182 hashValue.data()))
183 {
184 for (const auto& i : hashValue)
185 {
186 hashStrStream << std::setfill('0') << std::setw(2) << std::hex
187 << static_cast<int>(i);
188 }
189 }
190 else
191 {
192 // read failed
193 phosphor::logging::log<phosphor::logging::level::ERR>(
194 "Failed to read CPLD Hash string");
195 return "";
196 }
197 }
198 catch (const std::exception& e)
199 {
200 phosphor::logging::log<phosphor::logging::level::ERR>(
201 "Exception caught in readCPLDHash.",
202 phosphor::logging::entry("MSG=%s", e.what()));
203 return "";
204 }
205 return hashStrStream.str();
206}
207
AppaRao Puli4b639a22019-10-01 18:12:59 +0530208static std::string readVersionFromCPLD(const uint8_t majorReg,
209 const uint8_t minorReg)
AppaRao Pulic532f552019-07-05 15:23:50 +0530210{
211 try
212 {
AppaRao Pulic532f552019-07-05 15:23:50 +0530213 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
214 uint8_t majorVer = cpldDev.i2cReadByteData(majorReg);
215 uint8_t minorVer = cpldDev.i2cReadByteData(minorReg);
AppaRao Puli90fb45c2020-01-21 16:50:53 +0530216 // Major and Minor versions should be binary encoded strings.
AppaRao Pulic532f552019-07-05 15:23:50 +0530217 std::string version =
AppaRao Puli90fb45c2020-01-21 16:50:53 +0530218 std::to_string(majorVer) + "." + std::to_string(minorVer);
AppaRao Pulic532f552019-07-05 15:23:50 +0530219 return version;
220 }
221 catch (const std::exception& e)
222 {
223 phosphor::logging::log<phosphor::logging::level::ERR>(
AppaRao Puli4b639a22019-10-01 18:12:59 +0530224 "Exception caught in readVersionFromCPLD.",
AppaRao Pulic532f552019-07-05 15:23:50 +0530225 phosphor::logging::entry("MSG=%s", e.what()));
226 return "";
227 }
228}
229
AppaRao Puli4b639a22019-10-01 18:12:59 +0530230static std::string readBMCVersionFromSPI(const ImageType& imgType)
231{
232 std::string mtdDev;
233 uint32_t verOffset = verOffsetInPFM;
234 uint32_t bldNumOffset = buildNumOffsetInPFM;
235 uint32_t bldHashOffset = buildHashOffsetInPFM;
236
237 if (imgType == ImageType::bmcActive)
238 {
239 // For Active image, PFM is emulated as separate MTD device.
240 mtdDev = bmcActiveImgPfmMTDDev;
241 }
242 else if (imgType == ImageType::bmcRecovery)
243 {
244 // For Recovery image, PFM is part of compressed Image
245 // at offset 0x400.
246 mtdDev = bmcRecoveryImgMTDDev;
247 verOffset += pfmBaseOffsetInImage;
248 bldNumOffset += pfmBaseOffsetInImage;
249 bldHashOffset += pfmBaseOffsetInImage;
250 }
251 else
252 {
253 phosphor::logging::log<phosphor::logging::level::ERR>(
254 "Invalid image type passed to readBMCVersionFromSPI.");
255 return "";
256 }
257
258 uint8_t buildNo = 0;
259 std::array<uint8_t, 2> ver;
260 std::array<uint8_t, 3> buildHash;
261
262 try
263 {
264 SPIDev spiDev(mtdDev);
265 spiDev.spiReadData(verOffset, ver.size(),
266 reinterpret_cast<void*>(ver.data()));
267 spiDev.spiReadData(bldNumOffset, sizeof(buildNo),
268 reinterpret_cast<void*>(&buildNo));
269 spiDev.spiReadData(bldHashOffset, buildHash.size(),
270 reinterpret_cast<void*>(buildHash.data()));
271 }
272 catch (const std::exception& e)
273 {
274 phosphor::logging::log<phosphor::logging::level::ERR>(
275 "Exception caught in readBMCVersionFromSPI.",
276 phosphor::logging::entry("MSG=%s", e.what()));
277 return "";
278 }
AppaRao Puli90fb45c2020-01-21 16:50:53 +0530279
280 // Version format: <major>.<minor>-<build bum>-g<build hash>
281 // Example: 0.11-7-g1e5c2d
282 // Major, minor and build numberare BCD encoded.
283 std::string version =
284 std::to_string(ver[0]) + "." + std::to_string(ver[1]) + "-" +
285 std::to_string(buildNo) + "-g" + toHexString(buildHash[0]) +
286 toHexString(buildHash[1]) + toHexString(buildHash[2]);
AppaRao Puli4b639a22019-10-01 18:12:59 +0530287 return version;
288}
289
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000290static bool getGPIOInput(const std::string& name, gpiod::line& gpioLine,
291 uint8_t* value)
292{
293 // Find the GPIO line
294 gpioLine = gpiod::find_line(name);
295 if (!gpioLine)
296 {
297 phosphor::logging::log<phosphor::logging::level::ERR>(
298 "Failed to find the GPIO line: ",
299 phosphor::logging::entry("MSG=%s", name.c_str()));
300 return false;
301 }
302 try
303 {
304 gpioLine.request({__FUNCTION__, gpiod::line_request::DIRECTION_INPUT});
305 }
306 catch (std::exception& e)
307 {
308 phosphor::logging::log<phosphor::logging::level::ERR>(
309 "Failed to request the GPIO line",
310 phosphor::logging::entry("MSG=%s", e.what()));
311 gpioLine.release();
312 return false;
313 }
314 try
315 {
316 *value = gpioLine.get_value();
317 }
318 catch (std::exception& e)
319 {
320 phosphor::logging::log<phosphor::logging::level::ERR>(
321 "Failed to get the value of GPIO line",
322 phosphor::logging::entry("MSG=%s", e.what()));
323 gpioLine.release();
324 return false;
325 }
326 gpioLine.release();
327 return true;
328}
329
Chalapathi Venkataramashettye6fb18e2021-02-03 14:51:00 +0000330std::string readCPLDVersion()
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000331{
332 // CPLD SGPIO lines
333 gpiod::line mainCPLDLine;
334 gpiod::line pldLine;
335 // read main pld and pld version
336 uint8_t mainCPLDVer = 0;
337 uint8_t pldVer = 0;
338 // main CPLD
339 for (const auto& gLine : mainCPLDGpioLines)
340 {
341 uint8_t value = 0;
342 if (getGPIOInput(gLine, mainCPLDLine, &value))
343 {
344 mainCPLDVer <<= 1;
345 mainCPLDVer = mainCPLDVer | value;
346 }
347 else
348 {
349 phosphor::logging::log<phosphor::logging::level::ERR>(
350 "Failed to read GPIO line: ",
351 phosphor::logging::entry("MSG=%s", gLine.c_str()));
352 mainCPLDVer = 0;
353 break;
354 }
355 }
356
357 // pld lines
358 for (const auto& gLine : pldGpioLines)
359 {
360 uint8_t value = 0;
361 if (getGPIOInput(gLine, pldLine, &value))
362 {
363 pldVer <<= 1;
364 pldVer = pldVer | value;
365 }
366 else
367 {
368 phosphor::logging::log<phosphor::logging::level::ERR>(
369 "Failed to read GPIO line: ",
370 phosphor::logging::entry("MSG=%s", gLine.c_str()));
371 pldVer = 0;
372 break;
373 }
374 }
375
376 std::string svnRoTHash = "";
377
378 // check if reg 0x00 read 0xde
379 uint8_t cpldRoTValue = 0;
Zhikui Renace48a72020-08-12 15:54:42 -0700380 try
381 {
382 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
383 cpldRoTValue = cpldDev.i2cReadByteData(pfrROTId);
384 }
385 catch (const std::exception& e)
386 {
387 phosphor::logging::log<phosphor::logging::level::ERR>(
388 "Exception caught in readCPLDVersion.",
389 phosphor::logging::entry("MSG=%s", e.what()));
390 }
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000391
392 if (cpldRoTValue == pfrRoTValue)
393 {
394 // read SVN and RoT version
395 std::string svnRoTver = readVersionFromCPLD(cpldROTVersion, cpldROTSvn);
396
397 // read CPLD hash
398 std::string cpldHash = readCPLDHash();
399 svnRoTHash = "-" + svnRoTver + "-" + cpldHash;
400 }
401 else
402 {
403 phosphor::logging::log<phosphor::logging::level::INFO>(
404 "PFR-CPLD not present.");
405 }
406
407 // CPLD version format:
408 // When PFR CPLD is present
409 // <MainPLDMajorMinor.PLDMajorMinor>-<SVN.RoT>-<CPLD-Hash>
410 // Example: 2.7-1.1-<Hash string>
411
412 // When Non-PFR CPLD is present -> <MainPLDMajorMinor.PLDMajorMinor>
413 // Example: 2.7
414
415 std::string version =
416 std::to_string(mainCPLDVer) + "." + std::to_string(pldVer) + svnRoTHash;
417 return version;
418}
419
AppaRao Puli4b639a22019-10-01 18:12:59 +0530420std::string getFirmwareVersion(const ImageType& imgType)
421{
422 switch (imgType)
423 {
Vikram Bodireddy3c6c8c32019-12-05 11:06:15 +0530424 case (ImageType::cpldActive):
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000425 {
426 return readCPLDVersion();
427 }
Vikram Bodireddy3c6c8c32019-12-05 11:06:15 +0530428 case (ImageType::cpldRecovery):
AppaRao Puli4b639a22019-10-01 18:12:59 +0530429 {
Vikram Bodireddy3c6c8c32019-12-05 11:06:15 +0530430 // TO-DO: Need to update once CPLD supported Firmware is available
AppaRao Puli4b639a22019-10-01 18:12:59 +0530431 return readVersionFromCPLD(cpldROTVersion, cpldROTSvn);
432 }
433 case (ImageType::biosActive):
434 {
435 return readVersionFromCPLD(pchActiveMajorVersion,
436 pchActiveMinorVersion);
437 }
438 case (ImageType::biosRecovery):
439 {
440 return readVersionFromCPLD(pchRecoveryMajorVersion,
441 pchRecoveryMinorVersion);
442 }
443 case (ImageType::bmcActive):
444 case (ImageType::bmcRecovery):
445 {
446 return readBMCVersionFromSPI(imgType);
447 }
Vikram Bodireddy8292dc62021-05-26 13:31:47 +0530448 case (ImageType::afmActive):
449 {
450 return readVersionFromCPLD(afmActiveMajorVersion,
451 afmActiveMinorVersion);
452 }
453 case (ImageType::afmRecovery):
454 {
455 return readVersionFromCPLD(afmRecoveryMajorVersion,
456 afmRecoveryMinorVersion);
457 }
AppaRao Puli4b639a22019-10-01 18:12:59 +0530458 default:
459 // Invalid image Type.
460 return "";
461 }
462}
463
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000464int getProvisioningStatus(bool& ufmLocked, bool& ufmProvisioned,
465 bool& ufmSupport)
AppaRao Pulic532f552019-07-05 15:23:50 +0530466{
467 try
468 {
469 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
470 uint8_t provStatus = cpldDev.i2cReadByteData(provisioningStatus);
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000471 uint8_t pfrRoT = cpldDev.i2cReadByteData(pfrROTId);
AppaRao Pulic532f552019-07-05 15:23:50 +0530472 ufmLocked = (provStatus & ufmLockedMask);
473 ufmProvisioned = (provStatus & ufmProvisionedMask);
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000474 ufmSupport = (pfrRoT & pfrRoTValue);
AppaRao Pulic532f552019-07-05 15:23:50 +0530475 return 0;
476 }
477 catch (const std::exception& e)
478 {
479 phosphor::logging::log<phosphor::logging::level::ERR>(
480 "Exception caught in getProvisioningStatus.",
481 phosphor::logging::entry("MSG=%s", e.what()));
482 return -1;
483 }
484}
485
AppaRao Pulidbe184d2019-10-09 18:04:22 +0530486int readCpldReg(const ActionType& action, uint8_t& value)
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530487{
488 uint8_t cpldReg;
489
490 switch (action)
491 {
492 case (ActionType::recoveryCount):
493 cpldReg = recoveryCount;
494 break;
495 case (ActionType::recoveryReason):
496 cpldReg = lastRecoveryReason;
497 break;
498 case (ActionType::panicCount):
499 cpldReg = panicEventCount;
500 break;
501 case (ActionType::panicReason):
502 cpldReg = panicEventReason;
503 break;
504 case (ActionType::majorError):
505 cpldReg = majorErrorCode;
506 break;
507 case (ActionType::minorError):
508 cpldReg = minorErrorCode;
509 break;
510
511 default:
512 phosphor::logging::log<phosphor::logging::level::ERR>(
513 "Invalid CPLD read action.");
514 return -1;
515 }
516
517 try
518 {
519 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
520 value = cpldDev.i2cReadByteData(cpldReg);
521 return 0;
522 }
523 catch (const std::exception& e)
524 {
Chalapathi Venkataramashetty00acaff2020-12-24 11:01:17 +0000525 if (exceptionFlag)
526 {
527 exceptionFlag = false;
528 phosphor::logging::log<phosphor::logging::level::ERR>(
529 "Exception caught in readCpldReg.",
530 phosphor::logging::entry("MSG=%s", e.what()));
531 }
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530532 return -1;
533 }
534}
535
AppaRao Puli46cead92019-07-22 16:50:09 +0530536int setBMCBootCheckpoint(const uint8_t checkPoint)
537{
Vikram Bodireddy08841912020-08-31 18:11:45 +0530538 uint8_t bmcBootCheckpointReg = bmcBootCheckpoint;
539
540 // check if reg 0x01(RoTRev) is 1 or 2.
541 // checkpoint register changes for RoT Rev 1 and 2
542 uint8_t cpldRoTRev = 0;
AppaRao Puli46cead92019-07-22 16:50:09 +0530543 try
544 {
545 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
Vikram Bodireddy08841912020-08-31 18:11:45 +0530546 cpldRoTRev = cpldDev.i2cReadByteData(cpldROTVersion);
547 }
548 catch (const std::exception& e)
549 {
550 phosphor::logging::log<phosphor::logging::level::ERR>(
551 "Exception caught in reading RoT rev.",
552 phosphor::logging::entry("MSG=%s", e.what()));
553 return -1;
554 }
555
556 // latest PFR has different check point register
557 if (cpldRoTRev <= 1)
558 {
559 bmcBootCheckpointReg = bmcBootCheckpointRev1;
560 }
561
562 try
563 {
564 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
565 cpldDev.i2cWriteByteData(bmcBootCheckpointReg, checkPoint);
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530566 phosphor::logging::log<phosphor::logging::level::INFO>(
567 "Successfully set the PFR CPLD checkpoint 9.");
AppaRao Puli46cead92019-07-22 16:50:09 +0530568 return 0;
569 }
570 catch (const std::exception& e)
571 {
572 phosphor::logging::log<phosphor::logging::level::ERR>(
573 "Exception caught in setBMCBootCheckout.",
574 phosphor::logging::entry("MSG=%s", e.what()));
575 return -1;
576 }
577}
578
AppaRao Pulic532f552019-07-05 15:23:50 +0530579} // namespace pfr