blob: c729bba5a0d0dc184c939fff0228bd18909adaa7 [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
17#include "pfr_mgr.hpp"
AppaRao Pulie63eeda2019-07-05 16:25:38 +053018
deepak kumar agrawalb29a15c2022-03-25 07:45:57 +000019#include "file.hpp"
20
AppaRao Pulie63eeda2019-07-05 16:25:38 +053021namespace pfr
22{
23
Alex Schendel5cf320c2021-12-09 12:11:04 -080024inline void printVersion(const std::string& path, const std::string& version)
25{
26 lg2::info("VERSION INFO - {TYPE} - {VER}", "TYPE", path, "VER", version);
27}
AppaRao Pulie63eeda2019-07-05 16:25:38 +053028static constexpr uint8_t activeImage = 0;
29static constexpr uint8_t recoveryImage = 1;
30
AppaRao Puli0e758912020-01-29 03:07:54 +053031std::shared_ptr<sdbusplus::asio::dbus_interface> associationIface;
32std::set<std::tuple<std::string, std::string, std::string>> associations;
33
deepak kumar agrawalb29a15c2022-03-25 07:45:57 +000034using GetSubTreeType = std::vector<
35 std::pair<std::string,
36 std::vector<std::pair<std::string, std::vector<std::string>>>>>;
37
AppaRao Puli67d184c2020-05-29 00:48:33 +053038PfrVersion::PfrVersion(sdbusplus::asio::object_server& srv_,
39 std::shared_ptr<sdbusplus::asio::connection>& conn_,
40 const std::string& path_, const ImageType& imgType_,
41 const std::string& purpose_) :
AppaRao Pulie63eeda2019-07-05 16:25:38 +053042 server(srv_),
AppaRao Pulie4e95652019-07-19 16:52:01 +053043 conn(conn_), path(path_), imgType(imgType_), purpose(purpose_)
AppaRao Pulie63eeda2019-07-05 16:25:38 +053044{
AppaRao Puli4b639a22019-10-01 18:12:59 +053045 version = getFirmwareVersion(imgType);
AppaRao Pulie63eeda2019-07-05 16:25:38 +053046
Alex Schendel5cf320c2021-12-09 12:11:04 -080047 if (!(version == "0.0" || version.empty()))
48 {
49 printVersion(path, version);
50 }
51
AppaRao Pulie63eeda2019-07-05 16:25:38 +053052 std::string objPath = "/xyz/openbmc_project/software/" + path;
AppaRao Pulie4e95652019-07-19 16:52:01 +053053 versionIface =
AppaRao Pulie63eeda2019-07-05 16:25:38 +053054 server.add_interface(objPath, "xyz.openbmc_project.Software.Version");
AppaRao Pulie63eeda2019-07-05 16:25:38 +053055
Vikram Bodireddy1c06ae42021-07-08 15:26:51 +053056 if (versionIface != nullptr)
57 {
58
59 versionIface->register_property("Purpose", purpose);
60 versionIface->register_property(
61 versionStr, version,
62 // Override set
63 [this](const std::string& req, std::string& propertyValue) {
64 if (internalSet)
65 {
66 if (req != propertyValue)
67 {
68 version = req;
69 propertyValue = req;
70 return 1;
71 }
72 }
73 return 0;
74 });
75
76 versionIface->initialize();
77 }
AppaRao Pulid6f46c42019-07-19 22:34:04 +053078
AppaRao Puli916d6002019-12-18 01:37:02 +053079 std::string activation =
80 "xyz.openbmc_project.Software.Activation.Activations.StandbySpare";
81
82 if ((imgType == ImageType::bmcActive) ||
83 (imgType == ImageType::biosActive) ||
Vikram Bodireddy8292dc62021-05-26 13:31:47 +053084 (imgType == ImageType::cpldActive) || (imgType == ImageType::afmActive))
Vikram Bodireddy0fd4dde2019-12-06 15:48:00 +053085 {
AppaRao Puli916d6002019-12-18 01:37:02 +053086 // Running images so set Activations to "Active"
Vikram Bodireddy0fd4dde2019-12-06 15:48:00 +053087 activation =
88 "xyz.openbmc_project.Software.Activation.Activations.Active";
AppaRao Puli916d6002019-12-18 01:37:02 +053089
AppaRao Puli0e758912020-01-29 03:07:54 +053090 // For all Active images, functional endpoints must be added. This is
91 // used in bmcweb & ipmi for fetching active component versions.
92
93 // TODO: We have redundant active firmware version objects for BMC
94 // and BIOS active images. BMC version is read from /etc/os-release
95 // BIOS version is read from SMBIOS. Since it provides more
96 // version information, Lets expose those as functional.
97 // Down the line, Redundant inventory objects need to be addressed.
Vikram Bodireddy8292dc62021-05-26 13:31:47 +053098 if ((imgType == ImageType::cpldActive) ||
99 (imgType == ImageType::afmActive))
AppaRao Puli0e758912020-01-29 03:07:54 +0530100 {
101 associations.emplace("functional", "software_version", objPath);
102 }
Vikram Bodireddy0fd4dde2019-12-06 15:48:00 +0530103 }
104
AppaRao Pulid6f46c42019-07-19 22:34:04 +0530105 std::string reqActNone =
106 "xyz.openbmc_project.Software.Activation.RequestedActivations.None";
107 auto activationIface = server.add_interface(
108 objPath, "xyz.openbmc_project.Software.Activation");
AppaRao Pulid6f46c42019-07-19 22:34:04 +0530109
Vikram Bodireddy1c06ae42021-07-08 15:26:51 +0530110 if (activationIface != nullptr)
111 {
112
113 activationIface->register_property("Activation", activation);
114 activationIface->register_property("RequestedActivation", reqActNone);
115
116 activationIface->initialize();
117 }
AppaRao Puli0e758912020-01-29 03:07:54 +0530118
119 // All the components exposed under PFR.Manager are updateable.
120 // Lets add objPath endpoints to 'updatable' association
121 associations.emplace("updateable", "software_version", objPath);
122 associationIface->set_property("Associations", associations);
AppaRao Pulie63eeda2019-07-05 16:25:38 +0530123}
124
AppaRao Pulie4e95652019-07-19 16:52:01 +0530125void PfrVersion::updateVersion()
AppaRao Pulie63eeda2019-07-05 16:25:38 +0530126{
AppaRao Pulie4e95652019-07-19 16:52:01 +0530127 if (versionIface && versionIface->is_initialized())
128 {
AppaRao Puli4b639a22019-10-01 18:12:59 +0530129 std::string ver = getFirmwareVersion(imgType);
Alex Schendel5cf320c2021-12-09 12:11:04 -0800130 printVersion(path, ver);
AppaRao Pulie4e95652019-07-19 16:52:01 +0530131 internalSet = true;
132 versionIface->set_property(versionStr, ver);
133 internalSet = false;
134 }
135 return;
AppaRao Pulie63eeda2019-07-05 16:25:38 +0530136}
137
AppaRao Puli67d184c2020-05-29 00:48:33 +0530138PfrConfig::PfrConfig(sdbusplus::asio::object_server& srv_,
139 std::shared_ptr<sdbusplus::asio::connection>& conn_) :
AppaRao Pulie63eeda2019-07-05 16:25:38 +0530140 server(srv_),
141 conn(conn_)
142{
AppaRao Pulicc1ed682019-10-01 12:29:40 +0530143 pfrCfgIface = server.add_interface("/xyz/openbmc_project/pfr",
144 "xyz.openbmc_project.PFR.Attributes");
AppaRao Pulie63eeda2019-07-05 16:25:38 +0530145
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000146 ufmLocked = false;
147 ufmProvisioned = false;
148 ufmSupport = false;
149 getProvisioningStatus(ufmLocked, ufmProvisioned, ufmSupport);
AppaRao Pulie63eeda2019-07-05 16:25:38 +0530150
AppaRao Pulie4e95652019-07-19 16:52:01 +0530151 pfrCfgIface->register_property(ufmProvisionedStr, ufmProvisioned,
152 // Override set
153 [this](const bool req, bool propertyValue) {
154 if (internalSet)
155 {
156 if (req != propertyValue)
157 {
158 ufmProvisioned = req;
159 propertyValue = req;
160 return 1;
161 }
162 }
163 return 0;
164 });
165
166 pfrCfgIface->register_property(ufmLockedStr, ufmLocked,
167 // Override set
168 [this](const bool req, bool propertyValue) {
169 if (internalSet)
170 {
171 if (req != propertyValue)
172 {
173 ufmLocked = req;
174 propertyValue = req;
175 return 1;
176 }
177 }
178 return 0;
179 });
180
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000181 pfrCfgIface->register_property(ufmSupportStr, ufmSupport,
182 // Override set
183 [this](const bool req, bool propertyValue) {
184 if (internalSet)
185 {
186 if (req != propertyValue)
187 {
188 ufmSupport = req;
189 propertyValue = req;
190 return 1;
191 }
192 }
193 return 0;
194 });
195
AppaRao Pulie4e95652019-07-19 16:52:01 +0530196 pfrCfgIface->initialize();
AppaRao Puli0e758912020-01-29 03:07:54 +0530197
deepak kumar agrawalb29a15c2022-03-25 07:45:57 +0000198 /*BMCBusy period MailBox handling */
199 pfrMBIface = server.add_interface("/xyz/openbmc_project/pfr",
200 "xyz.openbmc_project.PFR.Mailbox");
201
202 pfrMBIface->register_method("InitiateBMCBusyPeriod", [](bool setReset) {
203 if (setBMCBusy(setReset) < 0)
204 {
205 return false;
206 }
207 return true;
208 });
209
210 pfrMBIface->register_method("ReadMBRegister", [](uint32_t regAddr) {
211 uint8_t mailBoxReply = 0;
212 try
213 {
214 getMBRegister(regAddr, mailBoxReply);
215 }
216 catch (const std::exception& e)
217 {
218 throw;
219 }
220 return mailBoxReply;
221 });
222 pfrMBIface->initialize();
223
AppaRao Puli0e758912020-01-29 03:07:54 +0530224 associationIface =
225 server.add_interface("/xyz/openbmc_project/software",
226 "xyz.openbmc_project.Association.Definitions");
227 associationIface->register_property("Associations", associations);
228 associationIface->initialize();
AppaRao Pulie4e95652019-07-19 16:52:01 +0530229}
230
231void PfrConfig::updateProvisioningStatus()
232{
233 if (pfrCfgIface && pfrCfgIface->is_initialized())
234 {
235 bool lockVal = false;
236 bool provVal = false;
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000237 bool supportVal = false;
238 getProvisioningStatus(lockVal, provVal, supportVal);
AppaRao Pulie4e95652019-07-19 16:52:01 +0530239 internalSet = true;
240 pfrCfgIface->set_property(ufmProvisionedStr, provVal);
241 pfrCfgIface->set_property(ufmLockedStr, lockVal);
Chalapathi Venkataramashettyf8819702021-02-03 09:43:46 +0000242 pfrCfgIface->set_property(ufmSupportStr, supportVal);
AppaRao Pulie4e95652019-07-19 16:52:01 +0530243 internalSet = false;
244 }
245 return;
AppaRao Pulie63eeda2019-07-05 16:25:38 +0530246}
247
Zhikui Renc96f37d2021-12-08 15:40:51 -0800248static constexpr const char* postcodeStrProp = "PlatformState";
249static constexpr const char* postcodeStrDefault = "Unknown";
250static constexpr const char* postcodeDataProp = "Data";
251static constexpr const char* postcodeIface =
252 "xyz.openbmc_project.State.Boot.Platform";
253
254PfrPostcode::PfrPostcode(sdbusplus::asio::object_server& srv_,
255 std::shared_ptr<sdbusplus::asio::connection>& conn_) :
256 server(srv_),
257 conn(conn_)
258{
259 if (getPlatformState(postcode) < 0)
260 {
261 postcode = 0;
262 }
263
264 pfrPostcodeIface =
265 server.add_interface("/xyz/openbmc_project/pfr", postcodeIface);
266
267 if (pfrPostcodeIface != nullptr)
268 {
269 pfrPostcodeIface->register_property(
270 postcodeDataProp, postcode,
271 // Override set
272 [this](const uint8_t req, uint8_t& propertyValue) {
273 if (internalSet)
274 {
275 if (req != propertyValue)
276 {
277 postcode = req;
278 propertyValue = req;
279 return 1;
280 }
281 }
282 return 0;
283 },
284 [this](uint8_t& propertyValue) {
285 updatePostcode();
286 propertyValue = postcode;
287 return propertyValue;
288 });
289
290 pfrPostcodeIface->register_property(postcodeStrProp,
291 std::string(postcodeStrDefault));
292
293 pfrPostcodeIface->initialize();
294 auto it = postcodeMap.find(postcode);
295 if (it != postcodeMap.end())
296 {
297 pfrPostcodeIface->set_property(postcodeStrProp, it->second);
298 }
299 }
300}
301
302void PfrPostcode::updatePostcode()
303{
304 if (pfrPostcodeIface && pfrPostcodeIface->is_initialized())
305 {
306 if (getPlatformState(postcode) < 0)
307 {
308 postcode = 0;
309 }
310
311 internalSet = true;
312 pfrPostcodeIface->set_property(postcodeDataProp, postcode);
313 auto it = postcodeMap.find(postcode);
314 if (it == postcodeMap.end())
315 {
316 pfrPostcodeIface->set_property(postcodeStrProp, postcodeStrDefault);
317 }
318 else
319 {
320 pfrPostcodeIface->set_property(postcodeStrProp, it->second);
321 }
322 internalSet = false;
323 }
324 return;
325}
326
AppaRao Pulie63eeda2019-07-05 16:25:38 +0530327} // namespace pfr