blob: 913190f00d3e6338da93a3727bb823bd1756b9b0 [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 Williams1695ee32024-08-16 15:21:41 -040088 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 Williams1695ee32024-08-16 15:21:41 -040097 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<
110 phosphor::logging::level::ERR>(
111 "Error to Get PFR properties.",
112 phosphor::logging::entry("MSG=%s",
113 ec.message().c_str()));
114 return;
115 }
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +0000116
Patrick Williams1695ee32024-08-16 15:21:41 -0400117 const uint64_t* i2cBus = nullptr;
118 const uint64_t* address = nullptr;
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +0000119
Patrick Williams1695ee32024-08-16 15:21:41 -0400120 for (const auto& [propName, propVariant] :
121 propertiesList)
122 {
123 if (propName == "Address")
124 {
125 address = std::get_if<uint64_t>(&propVariant);
126 }
127 else if (propName == "Bus")
128 {
129 i2cBus = std::get_if<uint64_t>(&propVariant);
130 }
131 }
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +0000132
Patrick Williams1695ee32024-08-16 15:21:41 -0400133 if ((address == nullptr) || (i2cBus == nullptr))
134 {
135 phosphor::logging::log<
136 phosphor::logging::level::ERR>(
137 "Unable to read the pfr properties");
138 return;
139 }
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +0000140
Patrick Williams1695ee32024-08-16 15:21:41 -0400141 i2cBusNumber = static_cast<int>(*i2cBus);
142 i2cSlaveAddress = static_cast<int>(*address);
143 i2cConfigLoaded = true;
144 },
145 serviceName, objPath, "org.freedesktop.DBus.Properties",
146 "GetAll", "xyz.openbmc_project.Configuration.PFR");
147 }
148 },
Chalapathi Venkataramashetty55e79342021-03-29 10:17:48 +0000149 "xyz.openbmc_project.ObjectMapper",
150 "/xyz/openbmc_project/object_mapper",
151 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
152 "/xyz/openbmc_project/inventory/system", 0,
153 std::array<const char*, 1>{"xyz.openbmc_project.Configuration.PFR"});
154 return;
155}
156
AppaRao Pulidbe184d2019-10-09 18:04:22 +0530157std::string toHexString(const uint8_t val)
AppaRao Pulic532f552019-07-05 15:23:50 +0530158{
159 std::stringstream stream;
AppaRao Pulidbe184d2019-10-09 18:04:22 +0530160 stream << std::setfill('0') << std::setw(2) << std::hex
161 << static_cast<int>(val);
AppaRao Pulic532f552019-07-05 15:23:50 +0530162 return stream.str();
163}
164
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000165static std::string readCPLDHash()
166{
167 std::stringstream hashStrStream;
168 static constexpr uint8_t hashLength = 32;
169 std::array<uint8_t, hashLength> hashValue = {0};
170 try
171 {
172 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
173 if (cpldDev.i2cReadBlockData(CPLDHashRegStart, hashLength,
174 hashValue.data()))
175 {
176 for (const auto& i : hashValue)
177 {
178 hashStrStream << std::setfill('0') << std::setw(2) << std::hex
179 << static_cast<int>(i);
180 }
181 }
182 else
183 {
184 // read failed
185 phosphor::logging::log<phosphor::logging::level::ERR>(
186 "Failed to read CPLD Hash string");
187 return "";
188 }
189 }
190 catch (const std::exception& e)
191 {
192 phosphor::logging::log<phosphor::logging::level::ERR>(
193 "Exception caught in readCPLDHash.",
194 phosphor::logging::entry("MSG=%s", e.what()));
195 return "";
196 }
197 return hashStrStream.str();
198}
199
AppaRao Puli4b639a22019-10-01 18:12:59 +0530200static std::string readVersionFromCPLD(const uint8_t majorReg,
201 const uint8_t minorReg)
AppaRao Pulic532f552019-07-05 15:23:50 +0530202{
203 try
204 {
AppaRao Pulic532f552019-07-05 15:23:50 +0530205 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
206 uint8_t majorVer = cpldDev.i2cReadByteData(majorReg);
207 uint8_t minorVer = cpldDev.i2cReadByteData(minorReg);
AppaRao Puli90fb45c2020-01-21 16:50:53 +0530208 // Major and Minor versions should be binary encoded strings.
Patrick Williams1695ee32024-08-16 15:21:41 -0400209 std::string version =
210 std::to_string(majorVer) + "." + std::to_string(minorVer);
AppaRao Pulic532f552019-07-05 15:23:50 +0530211 return version;
212 }
213 catch (const std::exception& e)
214 {
215 phosphor::logging::log<phosphor::logging::level::ERR>(
AppaRao Puli4b639a22019-10-01 18:12:59 +0530216 "Exception caught in readVersionFromCPLD.",
AppaRao Pulic532f552019-07-05 15:23:50 +0530217 phosphor::logging::entry("MSG=%s", e.what()));
218 return "";
219 }
220}
221
AppaRao Puli4b639a22019-10-01 18:12:59 +0530222static std::string readBMCVersionFromSPI(const ImageType& imgType)
223{
224 std::string mtdDev;
225 uint32_t verOffset = verOffsetInPFM;
226 uint32_t bldNumOffset = buildNumOffsetInPFM;
227 uint32_t bldHashOffset = buildHashOffsetInPFM;
228
229 if (imgType == ImageType::bmcActive)
230 {
231 // For Active image, PFM is emulated as separate MTD device.
232 mtdDev = bmcActiveImgPfmMTDDev;
233 }
234 else if (imgType == ImageType::bmcRecovery)
235 {
236 // For Recovery image, PFM is part of compressed Image
237 // at offset 0x400.
238 mtdDev = bmcRecoveryImgMTDDev;
239 verOffset += pfmBaseOffsetInImage;
240 bldNumOffset += pfmBaseOffsetInImage;
241 bldHashOffset += pfmBaseOffsetInImage;
242 }
243 else
244 {
245 phosphor::logging::log<phosphor::logging::level::ERR>(
246 "Invalid image type passed to readBMCVersionFromSPI.");
247 return "";
248 }
249
250 uint8_t buildNo = 0;
251 std::array<uint8_t, 2> ver;
252 std::array<uint8_t, 3> buildHash;
253
254 try
255 {
256 SPIDev spiDev(mtdDev);
257 spiDev.spiReadData(verOffset, ver.size(),
258 reinterpret_cast<void*>(ver.data()));
259 spiDev.spiReadData(bldNumOffset, sizeof(buildNo),
260 reinterpret_cast<void*>(&buildNo));
261 spiDev.spiReadData(bldHashOffset, buildHash.size(),
262 reinterpret_cast<void*>(buildHash.data()));
263 }
264 catch (const std::exception& e)
265 {
266 phosphor::logging::log<phosphor::logging::level::ERR>(
267 "Exception caught in readBMCVersionFromSPI.",
268 phosphor::logging::entry("MSG=%s", e.what()));
269 return "";
270 }
AppaRao Puli90fb45c2020-01-21 16:50:53 +0530271
272 // Version format: <major>.<minor>-<build bum>-g<build hash>
273 // Example: 0.11-7-g1e5c2d
274 // Major, minor and build numberare BCD encoded.
275 std::string version =
276 std::to_string(ver[0]) + "." + std::to_string(ver[1]) + "-" +
277 std::to_string(buildNo) + "-g" + toHexString(buildHash[0]) +
278 toHexString(buildHash[1]) + toHexString(buildHash[2]);
AppaRao Puli4b639a22019-10-01 18:12:59 +0530279 return version;
280}
281
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000282static bool getGPIOInput(const std::string& name, gpiod::line& gpioLine,
283 uint8_t* value)
284{
285 // Find the GPIO line
286 gpioLine = gpiod::find_line(name);
287 if (!gpioLine)
288 {
289 phosphor::logging::log<phosphor::logging::level::ERR>(
290 "Failed to find the GPIO line: ",
291 phosphor::logging::entry("MSG=%s", name.c_str()));
292 return false;
293 }
294 try
295 {
296 gpioLine.request({__FUNCTION__, gpiod::line_request::DIRECTION_INPUT});
297 }
Patrick Williams4990c9e2021-10-06 14:40:02 -0500298 catch (const std::exception& e)
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000299 {
300 phosphor::logging::log<phosphor::logging::level::ERR>(
301 "Failed to request the GPIO line",
302 phosphor::logging::entry("MSG=%s", e.what()));
303 gpioLine.release();
304 return false;
305 }
306 try
307 {
308 *value = gpioLine.get_value();
309 }
Patrick Williams4990c9e2021-10-06 14:40:02 -0500310 catch (const std::exception& e)
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000311 {
312 phosphor::logging::log<phosphor::logging::level::ERR>(
313 "Failed to get the value of GPIO line",
314 phosphor::logging::entry("MSG=%s", e.what()));
315 gpioLine.release();
316 return false;
317 }
318 gpioLine.release();
319 return true;
320}
321
Chalapathi Venkataramashettye6fb18e2021-02-03 14:51:00 +0000322std::string readCPLDVersion()
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000323{
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000324 std::string svnRoTHash = "";
ankita prasad56b0e662023-08-09 12:46:54 +0000325 std::string version = "unknown";
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000326
327 // check if reg 0x00 read 0xde
328 uint8_t cpldRoTValue = 0;
Zhikui Renace48a72020-08-12 15:54:42 -0700329 try
330 {
331 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
332 cpldRoTValue = cpldDev.i2cReadByteData(pfrROTId);
333 }
334 catch (const std::exception& e)
335 {
336 phosphor::logging::log<phosphor::logging::level::ERR>(
337 "Exception caught in readCPLDVersion.",
338 phosphor::logging::entry("MSG=%s", e.what()));
339 }
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000340
341 if (cpldRoTValue == pfrRoTValue)
342 {
ankita prasad56b0e662023-08-09 12:46:54 +0000343 // read RoT Rev and RoT SVN
344 std::string rotRevSVN = readVersionFromCPLD(cpldROTVersion, cpldROTSvn);
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000345
346 // read CPLD hash
347 std::string cpldHash = readCPLDHash();
ankita prasad56b0e662023-08-09 12:46:54 +0000348 version = rotRevSVN + "-" + cpldHash;
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000349 }
350 else
351 {
352 phosphor::logging::log<phosphor::logging::level::INFO>(
353 "PFR-CPLD not present.");
354 }
355
ankita prasad56b0e662023-08-09 12:46:54 +0000356 // ROT FW Version format:
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000357 // When PFR CPLD is present
ankita prasad56b0e662023-08-09 12:46:54 +0000358 // <RoTRev.RoTSVN>-<RoT HASH>
359 // Example: 3.0-<Hash string>
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000360
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000361 return version;
362}
363
AppaRao Puli4b639a22019-10-01 18:12:59 +0530364std::string getFirmwareVersion(const ImageType& imgType)
365{
366 switch (imgType)
367 {
Vikram Bodireddy3c6c8c32019-12-05 11:06:15 +0530368 case (ImageType::cpldActive):
Chalapathi Venkataramashetty53b87002020-07-03 09:52:44 +0000369 {
370 return readCPLDVersion();
371 }
Vikram Bodireddy3c6c8c32019-12-05 11:06:15 +0530372 case (ImageType::cpldRecovery):
AppaRao Puli4b639a22019-10-01 18:12:59 +0530373 {
Vikram Bodireddy3c6c8c32019-12-05 11:06:15 +0530374 // TO-DO: Need to update once CPLD supported Firmware is available
AppaRao Puli4b639a22019-10-01 18:12:59 +0530375 return readVersionFromCPLD(cpldROTVersion, cpldROTSvn);
376 }
377 case (ImageType::biosActive):
378 {
379 return readVersionFromCPLD(pchActiveMajorVersion,
380 pchActiveMinorVersion);
381 }
382 case (ImageType::biosRecovery):
383 {
384 return readVersionFromCPLD(pchRecoveryMajorVersion,
385 pchRecoveryMinorVersion);
386 }
387 case (ImageType::bmcActive):
388 case (ImageType::bmcRecovery):
389 {
390 return readBMCVersionFromSPI(imgType);
391 }
Vikram Bodireddy8292dc62021-05-26 13:31:47 +0530392 case (ImageType::afmActive):
393 {
394 return readVersionFromCPLD(afmActiveMajorVersion,
395 afmActiveMinorVersion);
396 }
397 case (ImageType::afmRecovery):
398 {
399 return readVersionFromCPLD(afmRecoveryMajorVersion,
400 afmRecoveryMinorVersion);
401 }
AppaRao Puli4b639a22019-10-01 18:12:59 +0530402 default:
403 // Invalid image Type.
404 return "";
405 }
406}
407
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000408int getProvisioningStatus(bool& ufmLocked, bool& ufmProvisioned,
409 bool& ufmSupport)
AppaRao Pulic532f552019-07-05 15:23:50 +0530410{
411 try
412 {
413 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
414 uint8_t provStatus = cpldDev.i2cReadByteData(provisioningStatus);
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000415 uint8_t pfrRoT = cpldDev.i2cReadByteData(pfrROTId);
AppaRao Pulic532f552019-07-05 15:23:50 +0530416 ufmLocked = (provStatus & ufmLockedMask);
417 ufmProvisioned = (provStatus & ufmProvisionedMask);
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000418 ufmSupport = (pfrRoT & pfrRoTValue);
AppaRao Pulic532f552019-07-05 15:23:50 +0530419 return 0;
420 }
421 catch (const std::exception& e)
422 {
423 phosphor::logging::log<phosphor::logging::level::ERR>(
424 "Exception caught in getProvisioningStatus.",
425 phosphor::logging::entry("MSG=%s", e.what()));
426 return -1;
427 }
428}
429
Zhikui Renc96f37d2021-12-08 15:40:51 -0800430int getPlatformState(uint8_t& state)
431{
432 try
433 {
434 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
435 state = cpldDev.i2cReadByteData(platformState);
436
437 return 0;
438 }
439 catch (const std::exception& e)
440 {
441 phosphor::logging::log<phosphor::logging::level::ERR>(
442 "Exception caught in getPlatformState.",
443 phosphor::logging::entry("MSG=%s", e.what()));
444 return -1;
445 }
446}
447
AppaRao Pulidbe184d2019-10-09 18:04:22 +0530448int readCpldReg(const ActionType& action, uint8_t& value)
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530449{
450 uint8_t cpldReg;
451
452 switch (action)
453 {
Chalapathi Venkataramashettybcc7ce12021-05-17 04:27:21 +0000454 case (ActionType::readRoTRev):
455 cpldReg = cpldROTVersion;
456 break;
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530457 case (ActionType::recoveryCount):
458 cpldReg = recoveryCount;
459 break;
460 case (ActionType::recoveryReason):
461 cpldReg = lastRecoveryReason;
462 break;
463 case (ActionType::panicCount):
464 cpldReg = panicEventCount;
465 break;
466 case (ActionType::panicReason):
467 cpldReg = panicEventReason;
468 break;
469 case (ActionType::majorError):
470 cpldReg = majorErrorCode;
471 break;
472 case (ActionType::minorError):
473 cpldReg = minorErrorCode;
474 break;
475
476 default:
477 phosphor::logging::log<phosphor::logging::level::ERR>(
478 "Invalid CPLD read action.");
479 return -1;
480 }
481
482 try
483 {
484 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
485 value = cpldDev.i2cReadByteData(cpldReg);
486 return 0;
487 }
488 catch (const std::exception& e)
489 {
Chalapathi Venkataramashetty00acaff2020-12-24 11:01:17 +0000490 if (exceptionFlag)
491 {
492 exceptionFlag = false;
493 phosphor::logging::log<phosphor::logging::level::ERR>(
494 "Exception caught in readCpldReg.",
495 phosphor::logging::entry("MSG=%s", e.what()));
496 }
AppaRao Puli88aa33b2019-07-18 23:49:55 +0530497 return -1;
498 }
499}
500
sri anjaneyulu alapatibe132592023-07-17 10:16:39 +0000501int setBMCBootCompleteChkPoint(const uint8_t checkPoint)
AppaRao Puli46cead92019-07-22 16:50:09 +0530502{
Vikram Bodireddy08841912020-08-31 18:11:45 +0530503 uint8_t bmcBootCheckpointReg = bmcBootCheckpoint;
504
505 // check if reg 0x01(RoTRev) is 1 or 2.
506 // checkpoint register changes for RoT Rev 1 and 2
507 uint8_t cpldRoTRev = 0;
AppaRao Puli46cead92019-07-22 16:50:09 +0530508 try
509 {
510 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
Vikram Bodireddy08841912020-08-31 18:11:45 +0530511 cpldRoTRev = cpldDev.i2cReadByteData(cpldROTVersion);
512 }
513 catch (const std::exception& e)
514 {
515 phosphor::logging::log<phosphor::logging::level::ERR>(
516 "Exception caught in reading RoT rev.",
517 phosphor::logging::entry("MSG=%s", e.what()));
518 return -1;
519 }
520
521 // latest PFR has different check point register
522 if (cpldRoTRev <= 1)
523 {
524 bmcBootCheckpointReg = bmcBootCheckpointRev1;
525 }
526
527 try
528 {
529 I2CFile cpldDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
530 cpldDev.i2cWriteByteData(bmcBootCheckpointReg, checkPoint);
AppaRao Pulib7e172c2019-12-13 14:46:25 +0530531 phosphor::logging::log<phosphor::logging::level::INFO>(
532 "Successfully set the PFR CPLD checkpoint 9.");
sri anjaneyulu alapatibe132592023-07-17 10:16:39 +0000533 bmcBootCompleteChkPointDone = true;
534 if (unProvChkPointStatus)
535 {
536 unProvChkPointStatus = false;
537 phosphor::logging::log<phosphor::logging::level::INFO>(
538 "PFR is not provisioned, hence exit the service.");
539 std::exit(EXIT_SUCCESS);
540 }
AppaRao Puli46cead92019-07-22 16:50:09 +0530541 return 0;
542 }
543 catch (const std::exception& e)
544 {
545 phosphor::logging::log<phosphor::logging::level::ERR>(
546 "Exception caught in setBMCBootCheckout.",
547 phosphor::logging::entry("MSG=%s", e.what()));
548 return -1;
549 }
550}
551
deepak kumar agrawalb29a15c2022-03-25 07:45:57 +0000552static bool setMBRegister(uint32_t regOffset, uint8_t regValue)
553{
554 try
555 {
556 I2CFile mailDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
557 mailDev.i2cWriteByteData(regOffset, regValue);
558 return true;
559 }
560 catch (const std::exception& e)
561 {
562 phosphor::logging::log<phosphor::logging::level::ERR>(
563 "Exception caught in setting PFR Mailbox.",
564 phosphor::logging::entry("MSG=%s", e.what()));
565 return false;
566 }
567}
568
569int setBMCBusy(bool setValue)
570{
571 uint32_t bmcBusyReg = 0x63;
Jayaprakash Mutyalaca8aacc2024-05-07 07:16:20 +0000572 uint8_t valHigh = 0x80;
deepak kumar agrawalb29a15c2022-03-25 07:45:57 +0000573 uint8_t mailBoxReply = 0;
574
575 if (getMBRegister(bmcBusyReg, mailBoxReply))
576 {
577 return -1;
578 }
579 uint8_t readValue = mailBoxReply | valHigh;
580 if (setValue == false)
581 {
Jayaprakash Mutyalaca8aacc2024-05-07 07:16:20 +0000582 readValue &= 0b01111111;
deepak kumar agrawalb29a15c2022-03-25 07:45:57 +0000583 }
584 if (!setMBRegister(bmcBusyReg, readValue))
585 {
586 return -1;
587 }
588 if (setValue == false)
589 {
590 phosphor::logging::log<phosphor::logging::level::DEBUG>(
591 "Successfully reset the PFR MailBox register.");
592 }
593 else
594 {
595 phosphor::logging::log<phosphor::logging::level::DEBUG>(
596 "Successfully set the PFR MailBox to BMCBusy.");
597 }
598 return 0;
599}
600
601int getMBRegister(uint32_t regAddr, uint8_t& mailBoxReply)
602{
603 // Read from PFR CPLD's mailbox register
604 try
605 {
606 I2CFile mailReadDev(i2cBusNumber, i2cSlaveAddress, O_RDWR | O_CLOEXEC);
607
608 mailBoxReply = mailReadDev.i2cReadByteData(regAddr);
609 }
610 catch (const std::exception& e)
611 {
612 phosphor::logging::log<phosphor::logging::level::ERR>(
613 "Exception caught in mailbox reading.",
614 phosphor::logging::entry("MSG=%s", e.what()));
615 throw;
616 }
617 return 0;
618}
619
AppaRao Pulic532f552019-07-05 15:23:50 +0530620} // namespace pfr