blob: 998c7b975291b46912ba8556806138599899e33f [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 Venkataramashetty00acaff2020-12-24 11:01:17 +000078bool exceptionFlag = true;
sri anjaneyulu alapatibe132592023-07-17 10:16:39 +000079extern bool bmcBootCompleteChkPointDone;
80extern bool unProvChkPointStatus;
Chalapathi Venkataramashetty00acaff2020-12-24 11:01:17 +000081
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +000082void init(std::shared_ptr<sdbusplus::asio::connection> conn,
83 bool& i2cConfigLoaded)
84{
85 conn->async_method_call(
86 [conn, &i2cConfigLoaded](const boost::system::error_code ec,
87 const GetSubTreeType& resp) {
Patrick Williams304e82e2023-05-10 07:51:13 -050088 if (ec || resp.size() != 1)
89 {
90 return;
91 }
92 if (resp[0].second.begin() == resp[0].second.end())
93 return;
94 const std::string& objPath = resp[0].first;
95 const std::string& serviceName = resp[0].second.begin()->first;
Vikram Bodireddy1c06ae42021-07-08 15:26:51 +053096
Patrick Williams304e82e2023-05-10 07:51:13 -050097 const std::string match = "Baseboard/PFR";
98 if (boost::ends_with(objPath, match))
99 {
100 // PFR object found.. check for PFR support
101 conn->async_method_call(
102 [objPath, serviceName, conn, &i2cConfigLoaded](
103 boost::system::error_code ec,
104 const std::vector<std::pair<
105 std::string, std::variant<std::string, uint64_t>>>&
106 propertiesList) {
107 if (ec)
108 {
109 phosphor::logging::log<phosphor::logging::level::ERR>(
110 "Error to Get PFR properties.",
111 phosphor::logging::entry("MSG=%s",
112 ec.message().c_str()));
113 return;
114 }
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +0000115
Patrick Williams304e82e2023-05-10 07:51:13 -0500116 const uint64_t* i2cBus = nullptr;
117 const uint64_t* address = nullptr;
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +0000118
Patrick Williams304e82e2023-05-10 07:51:13 -0500119 for (const auto& [propName, propVariant] : propertiesList)
120 {
121 if (propName == "Address")
122 {
123 address = std::get_if<uint64_t>(&propVariant);
124 }
125 else if (propName == "Bus")
126 {
127 i2cBus = std::get_if<uint64_t>(&propVariant);
128 }
129 }
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +0000130
Patrick Williams304e82e2023-05-10 07:51:13 -0500131 if ((address == nullptr) || (i2cBus == nullptr))
132 {
133 phosphor::logging::log<phosphor::logging::level::ERR>(
134 "Unable to read the pfr properties");
135 return;
136 }
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +0000137
Patrick Williams304e82e2023-05-10 07:51:13 -0500138 i2cBusNumber = static_cast<int>(*i2cBus);
139 i2cSlaveAddress = static_cast<int>(*address);
140 i2cConfigLoaded = true;
Patrick Williams1388f6c2023-10-20 11:19:41 -0500141 },
Patrick Williams304e82e2023-05-10 07:51:13 -0500142 serviceName, objPath, "org.freedesktop.DBus.Properties",
143 "GetAll", "xyz.openbmc_project.Configuration.PFR");
144 }
Patrick Williams1388f6c2023-10-20 11:19:41 -0500145 },
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +0000146 "xyz.openbmc_project.ObjectMapper",
147 "/xyz/openbmc_project/object_mapper",
148 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
149 "/xyz/openbmc_project/inventory/system", 0,
150 std::array<const char*, 1>{"xyz.openbmc_project.Configuration.PFR"});
151 return;
152}
153
AppaRao Pulidbe184d2019-10-09 18:04:22 +0530154std::string toHexString(const uint8_t val)
AppaRao Pulic532f552019-07-05 15:23:50 +0530155{
156 std::stringstream stream;
AppaRao Pulidbe184d2019-10-09 18:04:22 +0530157 stream << std::setfill('0') << std::setw(2) << std::hex
158 << static_cast<int>(val);
AppaRao Pulic532f552019-07-05 15:23:50 +0530159 return stream.str();
160}
161
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000162static std::string readCPLDHash()
163{
164 std::stringstream hashStrStream;
165 static constexpr uint8_t hashLength = 32;
166 std::array<uint8_t, hashLength> hashValue = {0};
167 try
168 {
169 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
170 if (cpldDev.i2cReadBlockData(CPLDHashRegStart, hashLength,
171 hashValue.data()))
172 {
173 for (const auto& i : hashValue)
174 {
175 hashStrStream << std::setfill('0') << std::setw(2) << std::hex
176 << static_cast<int>(i);
177 }
178 }
179 else
180 {
181 // read failed
182 phosphor::logging::log<phosphor::logging::level::ERR>(
183 "Failed to read CPLD Hash string");
184 return "";
185 }
186 }
187 catch (const std::exception& e)
188 {
189 phosphor::logging::log<phosphor::logging::level::ERR>(
190 "Exception caught in readCPLDHash.",
191 phosphor::logging::entry("MSG=%s", e.what()));
192 return "";
193 }
194 return hashStrStream.str();
195}
196
AppaRao Puli4b639a22019-10-01 18:12:59 +0530197static std::string readVersionFromCPLD(const uint8_t majorReg,
198 const uint8_t minorReg)
AppaRao Pulic532f552019-07-05 15:23:50 +0530199{
200 try
201 {
AppaRao Pulic532f552019-07-05 15:23:50 +0530202 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
203 uint8_t majorVer = cpldDev.i2cReadByteData(majorReg);
204 uint8_t minorVer = cpldDev.i2cReadByteData(minorReg);
AppaRao Puli90fb45c2020-01-21 16:50:53 +0530205 // Major and Minor versions should be binary encoded strings.
Patrick Williams304e82e2023-05-10 07:51:13 -0500206 std::string version = std::to_string(majorVer) + "." +
207 std::to_string(minorVer);
AppaRao Pulic532f552019-07-05 15:23:50 +0530208 return version;
209 }
210 catch (const std::exception& e)
211 {
212 phosphor::logging::log<phosphor::logging::level::ERR>(
AppaRao Puli4b639a22019-10-01 18:12:59 +0530213 "Exception caught in readVersionFromCPLD.",
AppaRao Pulic532f552019-07-05 15:23:50 +0530214 phosphor::logging::entry("MSG=%s", e.what()));
215 return "";
216 }
217}
218
AppaRao Puli4b639a22019-10-01 18:12:59 +0530219static std::string readBMCVersionFromSPI(const ImageType& imgType)
220{
221 std::string mtdDev;
222 uint32_t verOffset = verOffsetInPFM;
223 uint32_t bldNumOffset = buildNumOffsetInPFM;
224 uint32_t bldHashOffset = buildHashOffsetInPFM;
225
226 if (imgType == ImageType::bmcActive)
227 {
228 // For Active image, PFM is emulated as separate MTD device.
229 mtdDev = bmcActiveImgPfmMTDDev;
230 }
231 else if (imgType == ImageType::bmcRecovery)
232 {
233 // For Recovery image, PFM is part of compressed Image
234 // at offset 0x400.
235 mtdDev = bmcRecoveryImgMTDDev;
236 verOffset += pfmBaseOffsetInImage;
237 bldNumOffset += pfmBaseOffsetInImage;
238 bldHashOffset += pfmBaseOffsetInImage;
239 }
240 else
241 {
242 phosphor::logging::log<phosphor::logging::level::ERR>(
243 "Invalid image type passed to readBMCVersionFromSPI.");
244 return "";
245 }
246
247 uint8_t buildNo = 0;
248 std::array<uint8_t, 2> ver;
249 std::array<uint8_t, 3> buildHash;
250
251 try
252 {
253 SPIDev spiDev(mtdDev);
254 spiDev.spiReadData(verOffset, ver.size(),
255 reinterpret_cast<void*>(ver.data()));
256 spiDev.spiReadData(bldNumOffset, sizeof(buildNo),
257 reinterpret_cast<void*>(&buildNo));
258 spiDev.spiReadData(bldHashOffset, buildHash.size(),
259 reinterpret_cast<void*>(buildHash.data()));
260 }
261 catch (const std::exception& e)
262 {
263 phosphor::logging::log<phosphor::logging::level::ERR>(
264 "Exception caught in readBMCVersionFromSPI.",
265 phosphor::logging::entry("MSG=%s", e.what()));
266 return "";
267 }
AppaRao Puli90fb45c2020-01-21 16:50:53 +0530268
269 // Version format: <major>.<minor>-<build bum>-g<build hash>
270 // Example: 0.11-7-g1e5c2d
271 // Major, minor and build numberare BCD encoded.
272 std::string version =
273 std::to_string(ver[0]) + "." + std::to_string(ver[1]) + "-" +
274 std::to_string(buildNo) + "-g" + toHexString(buildHash[0]) +
275 toHexString(buildHash[1]) + toHexString(buildHash[2]);
AppaRao Puli4b639a22019-10-01 18:12:59 +0530276 return version;
277}
278
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000279static bool getGPIOInput(const std::string& name, gpiod::line& gpioLine,
280 uint8_t* value)
281{
282 // Find the GPIO line
283 gpioLine = gpiod::find_line(name);
284 if (!gpioLine)
285 {
286 phosphor::logging::log<phosphor::logging::level::ERR>(
287 "Failed to find the GPIO line: ",
288 phosphor::logging::entry("MSG=%s", name.c_str()));
289 return false;
290 }
291 try
292 {
293 gpioLine.request({__FUNCTION__, gpiod::line_request::DIRECTION_INPUT});
294 }
Patrick Williams4990c9e2021-10-06 14:40:02 -0500295 catch (const std::exception& e)
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000296 {
297 phosphor::logging::log<phosphor::logging::level::ERR>(
298 "Failed to request the GPIO line",
299 phosphor::logging::entry("MSG=%s", e.what()));
300 gpioLine.release();
301 return false;
302 }
303 try
304 {
305 *value = gpioLine.get_value();
306 }
Patrick Williams4990c9e2021-10-06 14:40:02 -0500307 catch (const std::exception& e)
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000308 {
309 phosphor::logging::log<phosphor::logging::level::ERR>(
310 "Failed to get the value of GPIO line",
311 phosphor::logging::entry("MSG=%s", e.what()));
312 gpioLine.release();
313 return false;
314 }
315 gpioLine.release();
316 return true;
317}
318
Chalapathi Venkataramashettye6fb18e2021-02-03 14:51:00 +0000319std::string readCPLDVersion()
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000320{
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000321 std::string svnRoTHash = "";
ankita prasad56b0e662023-08-09 12:46:54 +0000322 std::string version = "unknown";
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000323
324 // check if reg 0x00 read 0xde
325 uint8_t cpldRoTValue = 0;
Zhikui Renace48a72020-08-12 15:54:42 -0700326 try
327 {
328 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
329 cpldRoTValue = cpldDev.i2cReadByteData(pfrROTId);
330 }
331 catch (const std::exception& e)
332 {
333 phosphor::logging::log<phosphor::logging::level::ERR>(
334 "Exception caught in readCPLDVersion.",
335 phosphor::logging::entry("MSG=%s", e.what()));
336 }
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000337
338 if (cpldRoTValue == pfrRoTValue)
339 {
ankita prasad56b0e662023-08-09 12:46:54 +0000340 // read RoT Rev and RoT SVN
341 std::string rotRevSVN = readVersionFromCPLD(cpldROTVersion, cpldROTSvn);
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000342
343 // read CPLD hash
344 std::string cpldHash = readCPLDHash();
ankita prasad56b0e662023-08-09 12:46:54 +0000345 version = rotRevSVN + "-" + cpldHash;
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000346 }
347 else
348 {
349 phosphor::logging::log<phosphor::logging::level::INFO>(
350 "PFR-CPLD not present.");
351 }
352
ankita prasad56b0e662023-08-09 12:46:54 +0000353 // ROT FW Version format:
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000354 // When PFR CPLD is present
ankita prasad56b0e662023-08-09 12:46:54 +0000355 // <RoTRev.RoTSVN>-<RoT HASH>
356 // Example: 3.0-<Hash string>
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000357
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000358 return version;
359}
360
AppaRao Puli4b639a22019-10-01 18:12:59 +0530361std::string getFirmwareVersion(const ImageType& imgType)
362{
363 switch (imgType)
364 {
Vikram Bodireddy3c6c8c32019-12-05 11:06:15 +0530365 case (ImageType::cpldActive):
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000366 {
367 return readCPLDVersion();
368 }
Vikram Bodireddy3c6c8c32019-12-05 11:06:15 +0530369 case (ImageType::cpldRecovery):
AppaRao Puli4b639a22019-10-01 18:12:59 +0530370 {
Vikram Bodireddy3c6c8c32019-12-05 11:06:15 +0530371 // TO-DO: Need to update once CPLD supported Firmware is available
AppaRao Puli4b639a22019-10-01 18:12:59 +0530372 return readVersionFromCPLD(cpldROTVersion, cpldROTSvn);
373 }
374 case (ImageType::biosActive):
375 {
376 return readVersionFromCPLD(pchActiveMajorVersion,
377 pchActiveMinorVersion);
378 }
379 case (ImageType::biosRecovery):
380 {
381 return readVersionFromCPLD(pchRecoveryMajorVersion,
382 pchRecoveryMinorVersion);
383 }
384 case (ImageType::bmcActive):
385 case (ImageType::bmcRecovery):
386 {
387 return readBMCVersionFromSPI(imgType);
388 }
Vikram Bodireddy8292dc62021-05-26 13:31:47 +0530389 case (ImageType::afmActive):
390 {
391 return readVersionFromCPLD(afmActiveMajorVersion,
392 afmActiveMinorVersion);
393 }
394 case (ImageType::afmRecovery):
395 {
396 return readVersionFromCPLD(afmRecoveryMajorVersion,
397 afmRecoveryMinorVersion);
398 }
AppaRao Puli4b639a22019-10-01 18:12:59 +0530399 default:
400 // Invalid image Type.
401 return "";
402 }
403}
404
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000405int getProvisioningStatus(bool& ufmLocked, bool& ufmProvisioned,
406 bool& ufmSupport)
AppaRao Pulic532f552019-07-05 15:23:50 +0530407{
408 try
409 {
410 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
411 uint8_t provStatus = cpldDev.i2cReadByteData(provisioningStatus);
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000412 uint8_t pfrRoT = cpldDev.i2cReadByteData(pfrROTId);
AppaRao Pulic532f552019-07-05 15:23:50 +0530413 ufmLocked = (provStatus & ufmLockedMask);
414 ufmProvisioned = (provStatus & ufmProvisionedMask);
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000415 ufmSupport = (pfrRoT & pfrRoTValue);
AppaRao Pulic532f552019-07-05 15:23:50 +0530416 return 0;
417 }
418 catch (const std::exception& e)
419 {
420 phosphor::logging::log<phosphor::logging::level::ERR>(
421 "Exception caught in getProvisioningStatus.",
422 phosphor::logging::entry("MSG=%s", e.what()));
423 return -1;
424 }
425}
426
Zhikui Renc96f37d2021-12-08 15:40:51 -0800427int getPlatformState(uint8_t& state)
428{
429 try
430 {
431 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
432 state = cpldDev.i2cReadByteData(platformState);
433
434 return 0;
435 }
436 catch (const std::exception& e)
437 {
438 phosphor::logging::log<phosphor::logging::level::ERR>(
439 "Exception caught in getPlatformState.",
440 phosphor::logging::entry("MSG=%s", e.what()));
441 return -1;
442 }
443}
444
AppaRao Pulidbe184d2019-10-09 18:04:22 +0530445int readCpldReg(const ActionType& action, uint8_t& value)
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530446{
447 uint8_t cpldReg;
448
449 switch (action)
450 {
Chalapathi Venkataramashettybcc7ce12021-05-17 04:27:21 +0000451 case (ActionType::readRoTRev):
452 cpldReg = cpldROTVersion;
453 break;
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530454 case (ActionType::recoveryCount):
455 cpldReg = recoveryCount;
456 break;
457 case (ActionType::recoveryReason):
458 cpldReg = lastRecoveryReason;
459 break;
460 case (ActionType::panicCount):
461 cpldReg = panicEventCount;
462 break;
463 case (ActionType::panicReason):
464 cpldReg = panicEventReason;
465 break;
466 case (ActionType::majorError):
467 cpldReg = majorErrorCode;
468 break;
469 case (ActionType::minorError):
470 cpldReg = minorErrorCode;
471 break;
472
473 default:
474 phosphor::logging::log<phosphor::logging::level::ERR>(
475 "Invalid CPLD read action.");
476 return -1;
477 }
478
479 try
480 {
481 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
482 value = cpldDev.i2cReadByteData(cpldReg);
483 return 0;
484 }
485 catch (const std::exception& e)
486 {
Chalapathi Venkataramashetty00acaff2020-12-24 11:01:17 +0000487 if (exceptionFlag)
488 {
489 exceptionFlag = false;
490 phosphor::logging::log<phosphor::logging::level::ERR>(
491 "Exception caught in readCpldReg.",
492 phosphor::logging::entry("MSG=%s", e.what()));
493 }
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530494 return -1;
495 }
496}
497
sri anjaneyulu alapatibe132592023-07-17 10:16:39 +0000498int setBMCBootCompleteChkPoint(const uint8_t checkPoint)
AppaRao Puli46cead92019-07-22 16:50:09 +0530499{
Vikram Bodireddy08841912020-08-31 18:11:45 +0530500 uint8_t bmcBootCheckpointReg = bmcBootCheckpoint;
501
502 // check if reg 0x01(RoTRev) is 1 or 2.
503 // checkpoint register changes for RoT Rev 1 and 2
504 uint8_t cpldRoTRev = 0;
AppaRao Puli46cead92019-07-22 16:50:09 +0530505 try
506 {
507 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
Vikram Bodireddy08841912020-08-31 18:11:45 +0530508 cpldRoTRev = cpldDev.i2cReadByteData(cpldROTVersion);
509 }
510 catch (const std::exception& e)
511 {
512 phosphor::logging::log<phosphor::logging::level::ERR>(
513 "Exception caught in reading RoT rev.",
514 phosphor::logging::entry("MSG=%s", e.what()));
515 return -1;
516 }
517
518 // latest PFR has different check point register
519 if (cpldRoTRev <= 1)
520 {
521 bmcBootCheckpointReg = bmcBootCheckpointRev1;
522 }
523
524 try
525 {
526 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
527 cpldDev.i2cWriteByteData(bmcBootCheckpointReg, checkPoint);
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530528 phosphor::logging::log<phosphor::logging::level::INFO>(
529 "Successfully set the PFR CPLD checkpoint 9.");
sri anjaneyulu alapatibe132592023-07-17 10:16:39 +0000530 bmcBootCompleteChkPointDone = true;
531 if (unProvChkPointStatus)
532 {
533 unProvChkPointStatus = false;
534 phosphor::logging::log<phosphor::logging::level::INFO>(
535 "PFR is not provisioned, hence exit the service.");
536 std::exit(EXIT_SUCCESS);
537 }
AppaRao Puli46cead92019-07-22 16:50:09 +0530538 return 0;
539 }
540 catch (const std::exception& e)
541 {
542 phosphor::logging::log<phosphor::logging::level::ERR>(
543 "Exception caught in setBMCBootCheckout.",
544 phosphor::logging::entry("MSG=%s", e.what()));
545 return -1;
546 }
547}
548
deepak kumar agrawalb29a15c2022-03-25 07:45:57 +0000549static bool setMBRegister(uint32_t regOffset, uint8_t regValue)
550{
551 try
552 {
553 I2CFile mailDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
554 mailDev.i2cWriteByteData(regOffset, regValue);
555 return true;
556 }
557 catch (const std::exception& e)
558 {
559 phosphor::logging::log<phosphor::logging::level::ERR>(
560 "Exception caught in setting PFR Mailbox.",
561 phosphor::logging::entry("MSG=%s", e.what()));
562 return false;
563 }
564}
565
566int setBMCBusy(bool setValue)
567{
568 uint32_t bmcBusyReg = 0x63;
Jayaprakash Mutyalaca8aacc2024-05-07 07:16:20 +0000569 uint8_t valHigh = 0x80;
deepak kumar agrawalb29a15c2022-03-25 07:45:57 +0000570 uint8_t mailBoxReply = 0;
571
572 if (getMBRegister(bmcBusyReg, mailBoxReply))
573 {
574 return -1;
575 }
576 uint8_t readValue = mailBoxReply | valHigh;
577 if (setValue == false)
578 {
Jayaprakash Mutyalaca8aacc2024-05-07 07:16:20 +0000579 readValue &= 0b01111111;
deepak kumar agrawalb29a15c2022-03-25 07:45:57 +0000580 }
581 if (!setMBRegister(bmcBusyReg, readValue))
582 {
583 return -1;
584 }
585 if (setValue == false)
586 {
587 phosphor::logging::log<phosphor::logging::level::DEBUG>(
588 "Successfully reset the PFR MailBox register.");
589 }
590 else
591 {
592 phosphor::logging::log<phosphor::logging::level::DEBUG>(
593 "Successfully set the PFR MailBox to BMCBusy.");
594 }
595 return 0;
596}
597
598int getMBRegister(uint32_t regAddr, uint8_t& mailBoxReply)
599{
600 // Read from PFR CPLD's mailbox register
601 try
602 {
603 I2CFile mailReadDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
604
605 mailBoxReply = mailReadDev.i2cReadByteData(regAddr);
606 }
607 catch (const std::exception& e)
608 {
609 phosphor::logging::log<phosphor::logging::level::ERR>(
610 "Exception caught in mailbox reading.",
611 phosphor::logging::entry("MSG=%s", e.what()));
612 throw;
613 }
614 return 0;
615}
616
AppaRao Pulic532f552019-07-05 15:23:50 +0530617} // namespace pfr