blob: 0402641664009da4a9054ac0c6f8e9d9788dce6d [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 }
Vikram Bodireddy1c06ae42021-07-08 15:26:51 +0530102 if (resp[0].second.begin() == resp[0].second.end())
103 return;
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +0000104 const std::string& objPath = resp[0].first;
105 const std::string& serviceName = resp[0].second.begin()->first;
Vikram Bodireddy1c06ae42021-07-08 15:26:51 +0530106
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +0000107 const std::string match = "Baseboard/PFR";
108 if (boost::ends_with(objPath, match))
109 {
110 // PFR object found.. check for PFR support
111 conn->async_method_call(
112 [objPath, serviceName, conn, &i2cConfigLoaded](
113 boost::system::error_code ec,
114 const std::vector<std::pair<
115 std::string, std::variant<std::string, uint64_t>>>&
116 propertiesList) {
117 if (ec)
118 {
119 phosphor::logging::log<
120 phosphor::logging::level::ERR>(
121 "Error to Get PFR properties.",
122 phosphor::logging::entry("MSG=%s",
123 ec.message().c_str()));
124 return;
125 }
126
127 const uint64_t* i2cBus = nullptr;
128 const uint64_t* address = nullptr;
129
130 for (const auto& [propName, propVariant] :
131 propertiesList)
132 {
133 if (propName == "Address")
134 {
135 address = std::get_if<uint64_t>(&propVariant);
136 }
137 else if (propName == "Bus")
138 {
139 i2cBus = std::get_if<uint64_t>(&propVariant);
140 }
141 }
142
143 if ((address == nullptr) || (i2cBus == nullptr))
144 {
145 phosphor::logging::log<
146 phosphor::logging::level::ERR>(
147 "Unable to read the pfr properties");
148 return;
149 }
150
151 i2cBusNumber = static_cast<int>(*i2cBus);
152 i2cSlaveAddress = static_cast<int>(*address);
153 i2cConfigLoaded = true;
154 },
155 serviceName, objPath, "org.freedesktop.DBus.Properties",
156 "GetAll", "xyz.openbmc_project.Configuration.PFR");
157 }
158 },
159 "xyz.openbmc_project.ObjectMapper",
160 "/xyz/openbmc_project/object_mapper",
161 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
162 "/xyz/openbmc_project/inventory/system", 0,
163 std::array<const char*, 1>{"xyz.openbmc_project.Configuration.PFR"});
164 return;
165}
166
AppaRao Pulidbe184d2019-10-09 18:04:22 +0530167std::string toHexString(const uint8_t val)
AppaRao Pulic532f552019-07-05 15:23:50 +0530168{
169 std::stringstream stream;
AppaRao Pulidbe184d2019-10-09 18:04:22 +0530170 stream << std::setfill('0') << std::setw(2) << std::hex
171 << static_cast<int>(val);
AppaRao Pulic532f552019-07-05 15:23:50 +0530172 return stream.str();
173}
174
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000175static std::string readCPLDHash()
176{
177 std::stringstream hashStrStream;
178 static constexpr uint8_t hashLength = 32;
179 std::array<uint8_t, hashLength> hashValue = {0};
180 try
181 {
182 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
183 if (cpldDev.i2cReadBlockData(CPLDHashRegStart, hashLength,
184 hashValue.data()))
185 {
186 for (const auto& i : hashValue)
187 {
188 hashStrStream << std::setfill('0') << std::setw(2) << std::hex
189 << static_cast<int>(i);
190 }
191 }
192 else
193 {
194 // read failed
195 phosphor::logging::log<phosphor::logging::level::ERR>(
196 "Failed to read CPLD Hash string");
197 return "";
198 }
199 }
200 catch (const std::exception& e)
201 {
202 phosphor::logging::log<phosphor::logging::level::ERR>(
203 "Exception caught in readCPLDHash.",
204 phosphor::logging::entry("MSG=%s", e.what()));
205 return "";
206 }
207 return hashStrStream.str();
208}
209
AppaRao Puli4b639a22019-10-01 18:12:59 +0530210static std::string readVersionFromCPLD(const uint8_t majorReg,
211 const uint8_t minorReg)
AppaRao Pulic532f552019-07-05 15:23:50 +0530212{
213 try
214 {
AppaRao Pulic532f552019-07-05 15:23:50 +0530215 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
216 uint8_t majorVer = cpldDev.i2cReadByteData(majorReg);
217 uint8_t minorVer = cpldDev.i2cReadByteData(minorReg);
AppaRao Puli90fb45c2020-01-21 16:50:53 +0530218 // Major and Minor versions should be binary encoded strings.
AppaRao Pulic532f552019-07-05 15:23:50 +0530219 std::string version =
AppaRao Puli90fb45c2020-01-21 16:50:53 +0530220 std::to_string(majorVer) + "." + std::to_string(minorVer);
AppaRao Pulic532f552019-07-05 15:23:50 +0530221 return version;
222 }
223 catch (const std::exception& e)
224 {
225 phosphor::logging::log<phosphor::logging::level::ERR>(
AppaRao Puli4b639a22019-10-01 18:12:59 +0530226 "Exception caught in readVersionFromCPLD.",
AppaRao Pulic532f552019-07-05 15:23:50 +0530227 phosphor::logging::entry("MSG=%s", e.what()));
228 return "";
229 }
230}
231
AppaRao Puli4b639a22019-10-01 18:12:59 +0530232static std::string readBMCVersionFromSPI(const ImageType& imgType)
233{
234 std::string mtdDev;
235 uint32_t verOffset = verOffsetInPFM;
236 uint32_t bldNumOffset = buildNumOffsetInPFM;
237 uint32_t bldHashOffset = buildHashOffsetInPFM;
238
239 if (imgType == ImageType::bmcActive)
240 {
241 // For Active image, PFM is emulated as separate MTD device.
242 mtdDev = bmcActiveImgPfmMTDDev;
243 }
244 else if (imgType == ImageType::bmcRecovery)
245 {
246 // For Recovery image, PFM is part of compressed Image
247 // at offset 0x400.
248 mtdDev = bmcRecoveryImgMTDDev;
249 verOffset += pfmBaseOffsetInImage;
250 bldNumOffset += pfmBaseOffsetInImage;
251 bldHashOffset += pfmBaseOffsetInImage;
252 }
253 else
254 {
255 phosphor::logging::log<phosphor::logging::level::ERR>(
256 "Invalid image type passed to readBMCVersionFromSPI.");
257 return "";
258 }
259
260 uint8_t buildNo = 0;
261 std::array<uint8_t, 2> ver;
262 std::array<uint8_t, 3> buildHash;
263
264 try
265 {
266 SPIDev spiDev(mtdDev);
267 spiDev.spiReadData(verOffset, ver.size(),
268 reinterpret_cast<void*>(ver.data()));
269 spiDev.spiReadData(bldNumOffset, sizeof(buildNo),
270 reinterpret_cast<void*>(&buildNo));
271 spiDev.spiReadData(bldHashOffset, buildHash.size(),
272 reinterpret_cast<void*>(buildHash.data()));
273 }
274 catch (const std::exception& e)
275 {
276 phosphor::logging::log<phosphor::logging::level::ERR>(
277 "Exception caught in readBMCVersionFromSPI.",
278 phosphor::logging::entry("MSG=%s", e.what()));
279 return "";
280 }
AppaRao Puli90fb45c2020-01-21 16:50:53 +0530281
282 // Version format: <major>.<minor>-<build bum>-g<build hash>
283 // Example: 0.11-7-g1e5c2d
284 // Major, minor and build numberare BCD encoded.
285 std::string version =
286 std::to_string(ver[0]) + "." + std::to_string(ver[1]) + "-" +
287 std::to_string(buildNo) + "-g" + toHexString(buildHash[0]) +
288 toHexString(buildHash[1]) + toHexString(buildHash[2]);
AppaRao Puli4b639a22019-10-01 18:12:59 +0530289 return version;
290}
291
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000292static bool getGPIOInput(const std::string& name, gpiod::line& gpioLine,
293 uint8_t* value)
294{
295 // Find the GPIO line
296 gpioLine = gpiod::find_line(name);
297 if (!gpioLine)
298 {
299 phosphor::logging::log<phosphor::logging::level::ERR>(
300 "Failed to find the GPIO line: ",
301 phosphor::logging::entry("MSG=%s", name.c_str()));
302 return false;
303 }
304 try
305 {
306 gpioLine.request({__FUNCTION__, gpiod::line_request::DIRECTION_INPUT});
307 }
Patrick Williams4990c9e2021-10-06 14:40:02 -0500308 catch (const std::exception& e)
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000309 {
310 phosphor::logging::log<phosphor::logging::level::ERR>(
311 "Failed to request the GPIO line",
312 phosphor::logging::entry("MSG=%s", e.what()));
313 gpioLine.release();
314 return false;
315 }
316 try
317 {
318 *value = gpioLine.get_value();
319 }
Patrick Williams4990c9e2021-10-06 14:40:02 -0500320 catch (const std::exception& e)
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000321 {
322 phosphor::logging::log<phosphor::logging::level::ERR>(
323 "Failed to get the value of GPIO line",
324 phosphor::logging::entry("MSG=%s", e.what()));
325 gpioLine.release();
326 return false;
327 }
328 gpioLine.release();
329 return true;
330}
331
Chalapathi Venkataramashettye6fb18e2021-02-03 14:51:00 +0000332std::string readCPLDVersion()
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000333{
334 // CPLD SGPIO lines
335 gpiod::line mainCPLDLine;
336 gpiod::line pldLine;
337 // read main pld and pld version
338 uint8_t mainCPLDVer = 0;
339 uint8_t pldVer = 0;
340 // main CPLD
341 for (const auto& gLine : mainCPLDGpioLines)
342 {
343 uint8_t value = 0;
344 if (getGPIOInput(gLine, mainCPLDLine, &value))
345 {
346 mainCPLDVer <<= 1;
347 mainCPLDVer = mainCPLDVer | value;
348 }
349 else
350 {
351 phosphor::logging::log<phosphor::logging::level::ERR>(
352 "Failed to read GPIO line: ",
353 phosphor::logging::entry("MSG=%s", gLine.c_str()));
354 mainCPLDVer = 0;
355 break;
356 }
357 }
358
359 // pld lines
360 for (const auto& gLine : pldGpioLines)
361 {
362 uint8_t value = 0;
363 if (getGPIOInput(gLine, pldLine, &value))
364 {
365 pldVer <<= 1;
366 pldVer = pldVer | value;
367 }
368 else
369 {
370 phosphor::logging::log<phosphor::logging::level::ERR>(
371 "Failed to read GPIO line: ",
372 phosphor::logging::entry("MSG=%s", gLine.c_str()));
373 pldVer = 0;
374 break;
375 }
376 }
377
378 std::string svnRoTHash = "";
379
380 // check if reg 0x00 read 0xde
381 uint8_t cpldRoTValue = 0;
Zhikui Renace48a72020-08-12 15:54:42 -0700382 try
383 {
384 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
385 cpldRoTValue = cpldDev.i2cReadByteData(pfrROTId);
386 }
387 catch (const std::exception& e)
388 {
389 phosphor::logging::log<phosphor::logging::level::ERR>(
390 "Exception caught in readCPLDVersion.",
391 phosphor::logging::entry("MSG=%s", e.what()));
392 }
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000393
394 if (cpldRoTValue == pfrRoTValue)
395 {
396 // read SVN and RoT version
397 std::string svnRoTver = readVersionFromCPLD(cpldROTVersion, cpldROTSvn);
398
399 // read CPLD hash
400 std::string cpldHash = readCPLDHash();
401 svnRoTHash = "-" + svnRoTver + "-" + cpldHash;
402 }
403 else
404 {
405 phosphor::logging::log<phosphor::logging::level::INFO>(
406 "PFR-CPLD not present.");
407 }
408
409 // CPLD version format:
410 // When PFR CPLD is present
411 // <MainPLDMajorMinor.PLDMajorMinor>-<SVN.RoT>-<CPLD-Hash>
412 // Example: 2.7-1.1-<Hash string>
413
414 // When Non-PFR CPLD is present -> <MainPLDMajorMinor.PLDMajorMinor>
415 // Example: 2.7
416
417 std::string version =
418 std::to_string(mainCPLDVer) + "." + std::to_string(pldVer) + svnRoTHash;
419 return version;
420}
421
AppaRao Puli4b639a22019-10-01 18:12:59 +0530422std::string getFirmwareVersion(const ImageType& imgType)
423{
424 switch (imgType)
425 {
Vikram Bodireddy3c6c8c32019-12-05 11:06:15 +0530426 case (ImageType::cpldActive):
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000427 {
428 return readCPLDVersion();
429 }
Vikram Bodireddy3c6c8c32019-12-05 11:06:15 +0530430 case (ImageType::cpldRecovery):
AppaRao Puli4b639a22019-10-01 18:12:59 +0530431 {
Vikram Bodireddy3c6c8c32019-12-05 11:06:15 +0530432 // TO-DO: Need to update once CPLD supported Firmware is available
AppaRao Puli4b639a22019-10-01 18:12:59 +0530433 return readVersionFromCPLD(cpldROTVersion, cpldROTSvn);
434 }
435 case (ImageType::biosActive):
436 {
437 return readVersionFromCPLD(pchActiveMajorVersion,
438 pchActiveMinorVersion);
439 }
440 case (ImageType::biosRecovery):
441 {
442 return readVersionFromCPLD(pchRecoveryMajorVersion,
443 pchRecoveryMinorVersion);
444 }
445 case (ImageType::bmcActive):
446 case (ImageType::bmcRecovery):
447 {
448 return readBMCVersionFromSPI(imgType);
449 }
Vikram Bodireddy8292dc62021-05-26 13:31:47 +0530450 case (ImageType::afmActive):
451 {
452 return readVersionFromCPLD(afmActiveMajorVersion,
453 afmActiveMinorVersion);
454 }
455 case (ImageType::afmRecovery):
456 {
457 return readVersionFromCPLD(afmRecoveryMajorVersion,
458 afmRecoveryMinorVersion);
459 }
AppaRao Puli4b639a22019-10-01 18:12:59 +0530460 default:
461 // Invalid image Type.
462 return "";
463 }
464}
465
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000466int getProvisioningStatus(bool& ufmLocked, bool& ufmProvisioned,
467 bool& ufmSupport)
AppaRao Pulic532f552019-07-05 15:23:50 +0530468{
469 try
470 {
471 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
472 uint8_t provStatus = cpldDev.i2cReadByteData(provisioningStatus);
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000473 uint8_t pfrRoT = cpldDev.i2cReadByteData(pfrROTId);
AppaRao Pulic532f552019-07-05 15:23:50 +0530474 ufmLocked = (provStatus & ufmLockedMask);
475 ufmProvisioned = (provStatus & ufmProvisionedMask);
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000476 ufmSupport = (pfrRoT & pfrRoTValue);
AppaRao Pulic532f552019-07-05 15:23:50 +0530477 return 0;
478 }
479 catch (const std::exception& e)
480 {
481 phosphor::logging::log<phosphor::logging::level::ERR>(
482 "Exception caught in getProvisioningStatus.",
483 phosphor::logging::entry("MSG=%s", e.what()));
484 return -1;
485 }
486}
487
Zhikui Renc96f37d2021-12-08 15:40:51 -0800488int getPlatformState(uint8_t& state)
489{
490 try
491 {
492 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
493 state = cpldDev.i2cReadByteData(platformState);
494
495 return 0;
496 }
497 catch (const std::exception& e)
498 {
499 phosphor::logging::log<phosphor::logging::level::ERR>(
500 "Exception caught in getPlatformState.",
501 phosphor::logging::entry("MSG=%s", e.what()));
502 return -1;
503 }
504}
505
AppaRao Pulidbe184d2019-10-09 18:04:22 +0530506int readCpldReg(const ActionType& action, uint8_t& value)
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530507{
508 uint8_t cpldReg;
509
510 switch (action)
511 {
Chalapathi Venkataramashettybcc7ce12021-05-17 04:27:21 +0000512 case (ActionType::readRoTRev):
513 cpldReg = cpldROTVersion;
514 break;
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530515 case (ActionType::recoveryCount):
516 cpldReg = recoveryCount;
517 break;
518 case (ActionType::recoveryReason):
519 cpldReg = lastRecoveryReason;
520 break;
521 case (ActionType::panicCount):
522 cpldReg = panicEventCount;
523 break;
524 case (ActionType::panicReason):
525 cpldReg = panicEventReason;
526 break;
527 case (ActionType::majorError):
528 cpldReg = majorErrorCode;
529 break;
530 case (ActionType::minorError):
531 cpldReg = minorErrorCode;
532 break;
533
534 default:
535 phosphor::logging::log<phosphor::logging::level::ERR>(
536 "Invalid CPLD read action.");
537 return -1;
538 }
539
540 try
541 {
542 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
543 value = cpldDev.i2cReadByteData(cpldReg);
544 return 0;
545 }
546 catch (const std::exception& e)
547 {
Chalapathi Venkataramashetty00acaff2020-12-24 11:01:17 +0000548 if (exceptionFlag)
549 {
550 exceptionFlag = false;
551 phosphor::logging::log<phosphor::logging::level::ERR>(
552 "Exception caught in readCpldReg.",
553 phosphor::logging::entry("MSG=%s", e.what()));
554 }
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530555 return -1;
556 }
557}
558
AppaRao Puli46cead92019-07-22 16:50:09 +0530559int setBMCBootCheckpoint(const uint8_t checkPoint)
560{
Vikram Bodireddy08841912020-08-31 18:11:45 +0530561 uint8_t bmcBootCheckpointReg = bmcBootCheckpoint;
562
563 // check if reg 0x01(RoTRev) is 1 or 2.
564 // checkpoint register changes for RoT Rev 1 and 2
565 uint8_t cpldRoTRev = 0;
AppaRao Puli46cead92019-07-22 16:50:09 +0530566 try
567 {
568 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
Vikram Bodireddy08841912020-08-31 18:11:45 +0530569 cpldRoTRev = cpldDev.i2cReadByteData(cpldROTVersion);
570 }
571 catch (const std::exception& e)
572 {
573 phosphor::logging::log<phosphor::logging::level::ERR>(
574 "Exception caught in reading RoT rev.",
575 phosphor::logging::entry("MSG=%s", e.what()));
576 return -1;
577 }
578
579 // latest PFR has different check point register
580 if (cpldRoTRev <= 1)
581 {
582 bmcBootCheckpointReg = bmcBootCheckpointRev1;
583 }
584
585 try
586 {
587 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
588 cpldDev.i2cWriteByteData(bmcBootCheckpointReg, checkPoint);
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530589 phosphor::logging::log<phosphor::logging::level::INFO>(
590 "Successfully set the PFR CPLD checkpoint 9.");
AppaRao Puli46cead92019-07-22 16:50:09 +0530591 return 0;
592 }
593 catch (const std::exception& e)
594 {
595 phosphor::logging::log<phosphor::logging::level::ERR>(
596 "Exception caught in setBMCBootCheckout.",
597 phosphor::logging::entry("MSG=%s", e.what()));
598 return -1;
599 }
600}
601
AppaRao Pulic532f552019-07-05 15:23:50 +0530602} // namespace pfr