blob: 14e10953492b5946a70203b107c67ac76662c964 [file] [log] [blame]
Santosh Puranikf2d3b532022-04-19 06:44:07 -05001#include "config.h"
2
3#include "bios_handler.hpp"
4
5#include "const.hpp"
6#include "ibm_vpd_utils.hpp"
7#include "manager.hpp"
8#include "types.hpp"
9
Patrick Williamsc78d8872023-05-10 07:50:56 -050010#include <sdbusplus/bus.hpp>
11
Santosh Puranikf2d3b532022-04-19 06:44:07 -050012#include <iostream>
13#include <memory>
Santosh Puranikf2d3b532022-04-19 06:44:07 -050014#include <string>
15#include <tuple>
16#include <variant>
17
18using namespace openpower::vpd;
19using namespace openpower::vpd::constants;
20
21namespace openpower
22{
23namespace vpd
24{
25namespace manager
26{
27void BiosHandler::checkAndListenPLDMService()
28{
29 // Setup a match on NameOwnerChanged to determine when PLDM is up. In
30 // the signal handler, call restoreBIOSAttribs
Patrick Williams2eb01762022-07-22 19:26:56 -050031 static std::shared_ptr<sdbusplus::bus::match_t> nameOwnerMatch =
32 std::make_shared<sdbusplus::bus::match_t>(
Sunny Srivastava523af2e2022-02-14 07:30:10 -060033 *conn,
Santosh Puranikf2d3b532022-04-19 06:44:07 -050034 sdbusplus::bus::match::rules::nameOwnerChanged(
35 "xyz.openbmc_project.PLDM"),
Patrick Williams2eb01762022-07-22 19:26:56 -050036 [this](sdbusplus::message_t& msg) {
Patrick Williams08dc31c2024-08-16 15:21:06 -040037 if (msg.is_method_error())
38 {
39 std::cerr
40 << "Error in reading name owner signal " << std::endl;
41 return;
42 }
43 std::string name;
44 std::string newOwner;
45 std::string oldOwner;
Santosh Puranikf2d3b532022-04-19 06:44:07 -050046
Patrick Williams08dc31c2024-08-16 15:21:06 -040047 msg.read(name, oldOwner, newOwner);
48 if (newOwner != "" && name == "xyz.openbmc_project.PLDM")
49 {
50 this->restoreBIOSAttribs();
51 // We don't need the match anymore
52 nameOwnerMatch.reset();
53 }
54 });
Santosh Puranikf2d3b532022-04-19 06:44:07 -050055 // Check if PLDM is already running, if it is, we can go ahead and attempt
56 // to sync BIOS attributes (since PLDM would have initialized them by the
57 // time it acquires a bus name).
58 bool isPLDMRunning = false;
59 try
60 {
61 auto bus = sdbusplus::bus::new_default();
62 auto method =
63 bus.new_method_call("org.freedesktop.DBus", "/org/freedesktop/DBus",
64 "org.freedesktop.DBus", "NameHasOwner");
65 method.append("xyz.openbmc_project.PLDM");
66
67 auto result = bus.call(method);
68 result.read(isPLDMRunning);
69 }
70 catch (const sdbusplus::exception::SdBusError& e)
71 {
72 std::cerr << "Failed to check if PLDM is running, assume false"
73 << std::endl;
74 std::cerr << e.what() << std::endl;
75 }
76
77 std::cout << "Is PLDM running: " << isPLDMRunning << std::endl;
78
79 if (isPLDMRunning)
80 {
81 nameOwnerMatch.reset();
82 restoreBIOSAttribs();
83 }
84}
85
86void BiosHandler::listenBiosAttribs()
87{
Patrick Williams2eb01762022-07-22 19:26:56 -050088 static std::shared_ptr<sdbusplus::bus::match_t> biosMatcher =
89 std::make_shared<sdbusplus::bus::match_t>(
Sunny Srivastava523af2e2022-02-14 07:30:10 -060090 *conn,
Santosh Puranikf2d3b532022-04-19 06:44:07 -050091 sdbusplus::bus::match::rules::propertiesChanged(
92 "/xyz/openbmc_project/bios_config/manager",
93 "xyz.openbmc_project.BIOSConfig.Manager"),
Patrick Williams2eb01762022-07-22 19:26:56 -050094 [this](sdbusplus::message_t& msg) { biosAttribsCallback(msg); });
Santosh Puranikf2d3b532022-04-19 06:44:07 -050095}
96
Patrick Williams2eb01762022-07-22 19:26:56 -050097void BiosHandler::biosAttribsCallback(sdbusplus::message_t& msg)
Santosh Puranikf2d3b532022-04-19 06:44:07 -050098{
99 if (msg.is_method_error())
100 {
101 std::cerr << "Error in reading BIOS attribute signal " << std::endl;
102 return;
103 }
104 using BiosProperty = std::tuple<
105 std::string, bool, std::string, std::string, std::string,
106 std::variant<int64_t, std::string>, std::variant<int64_t, std::string>,
107 std::vector<
108 std::tuple<std::string, std::variant<int64_t, std::string>>>>;
109 using BiosBaseTable = std::variant<std::map<std::string, BiosProperty>>;
110 using BiosBaseTableType = std::map<std::string, BiosBaseTable>;
111
112 std::string object;
113 BiosBaseTableType propMap;
114 msg.read(object, propMap);
115 for (auto prop : propMap)
116 {
117 if (prop.first == "BaseBIOSTable")
118 {
119 auto list = std::get<0>(prop.second);
120 for (const auto& item : list)
121 {
122 std::string attributeName = std::get<0>(item);
123 if (attributeName == "hb_memory_mirror_mode")
124 {
125 auto attrValue = std::get<5>(std::get<1>(item));
126 auto val = std::get_if<std::string>(&attrValue);
127 if (val)
128 {
129 saveAMMToVPD(*val);
130 }
131 }
132 else if (attributeName == "hb_field_core_override")
133 {
134 auto attrValue = std::get<5>(std::get<1>(item));
135 auto val = std::get_if<int64_t>(&attrValue);
136 if (val)
137 {
138 saveFCOToVPD(*val);
139 }
140 }
Santosh Puranikb2c2ccc2022-05-14 05:15:44 -0500141 else if (attributeName == "pvm_keep_and_clear")
142 {
143 auto attrValue = std::get<5>(std::get<1>(item));
144 auto val = std::get_if<std::string>(&attrValue);
145 if (val)
146 {
147 saveKeepAndClearToVPD(*val);
148 }
149 }
150 else if (attributeName == "pvm_create_default_lpar")
151 {
152 auto attrValue = std::get<5>(std::get<1>(item));
153 auto val = std::get_if<std::string>(&attrValue);
154 if (val)
155 {
156 saveCreateDefaultLparToVPD(*val);
157 }
158 }
Santosh Puranika97b63e2022-05-20 05:22:27 -0500159 else if (attributeName == "pvm_clear_nvram")
160 {
161 auto attrValue = std::get<5>(std::get<1>(item));
162 auto val = std::get_if<std::string>(&attrValue);
163 if (val)
164 {
165 saveClearNVRAMToVPD(*val);
166 }
167 }
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500168 }
169 }
170 }
171}
172
173void BiosHandler::saveFCOToVPD(int64_t fcoVal)
174{
175 if (fcoVal == -1)
176 {
177 std::cerr << "Invalid FCO value from BIOS: " << fcoVal << std::endl;
178 return;
179 }
180
181 Binary vpdVal = {0, 0, 0, static_cast<uint8_t>(fcoVal)};
182 auto valInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VSYS", "RG");
183
184 if (valInVPD.size() != 4)
185 {
186 std::cerr << "Read bad size for VSYS/RG: " << valInVPD.size()
187 << std::endl;
188 return;
189 }
190
Priyanga Ramasamy84d61e82022-07-22 03:51:02 -0500191 if (std::memcmp(vpdVal.data(), valInVPD.data(), 4) != 0)
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500192 {
193 std::cout << "Writing FCO to VPD: " << fcoVal << std::endl;
194 manager.writeKeyword(sdbusplus::message::object_path{SYSTEM_OBJECT},
195 "VSYS", "RG", vpdVal);
196 }
197}
198
199void BiosHandler::saveAMMToVPD(const std::string& mirrorMode)
200{
201 Binary vpdVal;
202 auto valInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D0");
203
204 if (valInVPD.size() != 1)
205 {
206 std::cerr << "Read bad size for UTIL/D0: " << valInVPD.size()
207 << std::endl;
208 return;
209 }
210
211 if (mirrorMode != "Enabled" && mirrorMode != "Disabled")
212 {
Santosh Puranika97b63e2022-05-20 05:22:27 -0500213 std::cerr << "Bad value for Mirror mode BIOS attribute: " << mirrorMode
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500214 << std::endl;
215 return;
216 }
217
218 // Write to VPD only if the value is not already what we want to write.
219 if (mirrorMode == "Enabled" && valInVPD.at(0) != 2)
220 {
221 vpdVal.emplace_back(2);
222 }
223 else if (mirrorMode == "Disabled" && valInVPD.at(0) != 1)
224 {
225 vpdVal.emplace_back(1);
226 }
227
228 if (!vpdVal.empty())
229 {
230 std::cout << "Writing AMM to VPD: " << static_cast<int>(vpdVal.at(0))
231 << std::endl;
232 manager.writeKeyword(sdbusplus::message::object_path{SYSTEM_OBJECT},
233 "UTIL", "D0", vpdVal);
234 }
235}
236
Santosh Puranikb2c2ccc2022-05-14 05:15:44 -0500237void BiosHandler::saveKeepAndClearToVPD(const std::string& keepAndClear)
238{
239 Binary vpdVal;
240 auto valInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");
241
242 if (valInVPD.size() != 1)
243 {
244 std::cerr << "Read bad size for UTIL/D1: " << valInVPD.size()
245 << std::endl;
246 return;
247 }
248
249 if (keepAndClear != "Enabled" && keepAndClear != "Disabled")
250 {
Santosh Puranika97b63e2022-05-20 05:22:27 -0500251 std::cerr << "Bad value for keep and clear BIOS attribute: "
Santosh Puranikb2c2ccc2022-05-14 05:15:44 -0500252 << keepAndClear << std::endl;
253 return;
254 }
255
256 // Write to VPD only if the value is not already what we want to write.
257 if (keepAndClear == "Enabled" && ((valInVPD.at(0) & 0x01) != 0x01))
258 {
259 vpdVal.emplace_back(valInVPD.at(0) | 0x01);
260 }
261 else if (keepAndClear == "Disabled" && ((valInVPD.at(0) & 0x01) != 0))
262 {
263 vpdVal.emplace_back(valInVPD.at(0) & ~(0x01));
264 }
265
266 if (!vpdVal.empty())
267 {
268 std::cout << "Writing Keep and Clear to VPD: "
269 << static_cast<int>(vpdVal.at(0)) << std::endl;
270 manager.writeKeyword(sdbusplus::message::object_path{SYSTEM_OBJECT},
271 "UTIL", "D1", vpdVal);
272 }
273}
274
275void BiosHandler::saveCreateDefaultLparToVPD(
276 const std::string& createDefaultLpar)
277{
278 Binary vpdVal;
279 auto valInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");
280
281 if (valInVPD.size() != 1)
282 {
283 std::cerr << "Read bad size for UTIL/D1: " << valInVPD.size()
284 << std::endl;
285 return;
286 }
287
288 if (createDefaultLpar != "Enabled" && createDefaultLpar != "Disabled")
289 {
Santosh Puranika97b63e2022-05-20 05:22:27 -0500290 std::cerr << "Bad value for create default lpar BIOS attribute: "
Santosh Puranikb2c2ccc2022-05-14 05:15:44 -0500291 << createDefaultLpar << std::endl;
292 return;
293 }
294
295 // Write to VPD only if the value is not already what we want to write.
296 if (createDefaultLpar == "Enabled" && ((valInVPD.at(0) & 0x02) != 0x02))
297 {
298 vpdVal.emplace_back(valInVPD.at(0) | 0x02);
299 }
300 else if (createDefaultLpar == "Disabled" && ((valInVPD.at(0) & 0x02) != 0))
301 {
302 vpdVal.emplace_back(valInVPD.at(0) & ~(0x02));
303 }
304
305 if (!vpdVal.empty())
306 {
307 std::cout << "Writing create default lpar to VPD: "
308 << static_cast<int>(vpdVal.at(0)) << std::endl;
309 manager.writeKeyword(sdbusplus::message::object_path{SYSTEM_OBJECT},
310 "UTIL", "D1", vpdVal);
311 }
312}
313
Santosh Puranika97b63e2022-05-20 05:22:27 -0500314void BiosHandler::saveClearNVRAMToVPD(const std::string& clearNVRAM)
315{
316 Binary vpdVal;
317 auto valInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");
318
319 if (valInVPD.size() != 1)
320 {
321 std::cerr << "Read bad size for UTIL/D1: " << valInVPD.size()
322 << std::endl;
323 return;
324 }
325
326 if (clearNVRAM != "Enabled" && clearNVRAM != "Disabled")
327 {
328 std::cerr << "Bad value for clear NVRAM BIOS attribute: " << clearNVRAM
329 << std::endl;
330 return;
331 }
332
333 // Write to VPD only if the value is not already what we want to write.
334 if (clearNVRAM == "Enabled" && ((valInVPD.at(0) & 0x04) != 0x04))
335 {
336 vpdVal.emplace_back(valInVPD.at(0) | 0x04);
337 }
338 else if (clearNVRAM == "Disabled" && ((valInVPD.at(0) & 0x04) != 0))
339 {
340 vpdVal.emplace_back(valInVPD.at(0) & ~(0x04));
341 }
342
343 if (!vpdVal.empty())
344 {
345 std::cout << "Writing clear NVRAM to VPD: "
346 << static_cast<int>(vpdVal.at(0)) << std::endl;
347 manager.writeKeyword(sdbusplus::message::object_path{SYSTEM_OBJECT},
348 "UTIL", "D1", vpdVal);
349 }
350}
351
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500352int64_t BiosHandler::readBIOSFCO()
353{
354 int64_t fcoVal = -1;
355 auto val = readBIOSAttribute("hb_field_core_override");
356
357 if (auto pVal = std::get_if<int64_t>(&val))
358 {
359 fcoVal = *pVal;
360 }
361 else
362 {
363 std::cerr << "FCO is not an int" << std::endl;
364 }
365 return fcoVal;
366}
367
368std::string BiosHandler::readBIOSAMM()
369{
370 std::string ammVal{};
371 auto val = readBIOSAttribute("hb_memory_mirror_mode");
372
373 if (auto pVal = std::get_if<std::string>(&val))
374 {
375 ammVal = *pVal;
376 }
377 else
378 {
379 std::cerr << "AMM is not a string" << std::endl;
380 }
381 return ammVal;
382}
383
Santosh Puranikb2c2ccc2022-05-14 05:15:44 -0500384std::string BiosHandler::readBIOSKeepAndClear()
385{
386 std::string keepAndClear{};
387 auto val = readBIOSAttribute("pvm_keep_and_clear");
388
389 if (auto pVal = std::get_if<std::string>(&val))
390 {
391 keepAndClear = *pVal;
392 }
393 else
394 {
395 std::cerr << "Keep and clear is not a string" << std::endl;
396 }
397 return keepAndClear;
398}
399
400std::string BiosHandler::readBIOSCreateDefaultLpar()
401{
402 std::string createDefaultLpar{};
403 auto val = readBIOSAttribute("pvm_create_default_lpar");
404
405 if (auto pVal = std::get_if<std::string>(&val))
406 {
407 createDefaultLpar = *pVal;
408 }
409 else
410 {
411 std::cerr << "Create default LPAR is not a string" << std::endl;
412 }
413 return createDefaultLpar;
414}
415
Santosh Puranika97b63e2022-05-20 05:22:27 -0500416std::string BiosHandler::readBIOSClearNVRAM()
417{
418 std::string clearNVRAM{};
419 auto val = readBIOSAttribute("pvm_clear_nvram");
420
421 if (auto pVal = std::get_if<std::string>(&val))
422 {
423 clearNVRAM = *pVal;
424 }
425 else
426 {
427 std::cerr << "Clear NVRAM is not a string" << std::endl;
428 }
429 return clearNVRAM;
430}
431
Santosh Puranikf7f8da62022-05-06 13:01:19 -0500432void BiosHandler::saveFCOToBIOS(const std::string& fcoVal, int64_t fcoInBIOS)
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500433{
434 if (fcoVal.size() != 4)
435 {
436 std::cerr << "Bad size for FCO in VPD: " << fcoVal.size() << std::endl;
437 return;
438 }
Santosh Puranikf7f8da62022-05-06 13:01:19 -0500439
440 // Need to write?
441 if (fcoInBIOS == static_cast<int64_t>(fcoVal.at(3)))
442 {
443 std::cout << "Skip FCO BIOS write, value is already: " << fcoInBIOS
444 << std::endl;
445 return;
446 }
447
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500448 PendingBIOSAttrsType biosAttrs;
449 biosAttrs.push_back(
450 std::make_pair("hb_field_core_override",
451 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
452 "AttributeType.Integer",
453 fcoVal.at(3))));
454
455 std::cout << "Set hb_field_core_override to: "
456 << static_cast<int>(fcoVal.at(3)) << std::endl;
457
458 setBusProperty<PendingBIOSAttrsType>(
459 "xyz.openbmc_project.BIOSConfigManager",
460 "/xyz/openbmc_project/bios_config/manager",
461 "xyz.openbmc_project.BIOSConfig.Manager", "PendingAttributes",
462 biosAttrs);
463}
464
Santosh Puranikf7f8da62022-05-06 13:01:19 -0500465void BiosHandler::saveAMMToBIOS(const std::string& ammVal,
466 const std::string& ammInBIOS)
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500467{
468 if (ammVal.size() != 1)
469 {
470 std::cerr << "Bad size for AMM in VPD: " << ammVal.size() << std::endl;
471 return;
472 }
473
474 // Make sure data in VPD is sane
475 if (ammVal.at(0) != 1 && ammVal.at(0) != 2)
476 {
477 std::cerr << "Bad value for AMM read from VPD: "
478 << static_cast<int>(ammVal.at(0)) << std::endl;
479 return;
480 }
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500481
Santosh Puranikf7f8da62022-05-06 13:01:19 -0500482 // Need to write?
483 std::string toWrite = (ammVal.at(0) == 2) ? "Enabled" : "Disabled";
484 if (ammInBIOS == toWrite)
485 {
486 std::cout << "Skip AMM BIOS write, value is already: " << toWrite
487 << std::endl;
488 return;
489 }
490
491 PendingBIOSAttrsType biosAttrs;
492 biosAttrs.push_back(
493 std::make_pair("hb_memory_mirror_mode",
494 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
495 "AttributeType.Enumeration",
496 toWrite)));
497
498 std::cout << "Set hb_memory_mirror_mode to: " << toWrite << std::endl;
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500499
500 setBusProperty<PendingBIOSAttrsType>(
501 "xyz.openbmc_project.BIOSConfigManager",
502 "/xyz/openbmc_project/bios_config/manager",
503 "xyz.openbmc_project.BIOSConfig.Manager", "PendingAttributes",
504 biosAttrs);
505}
506
Santosh Puranikb2c2ccc2022-05-14 05:15:44 -0500507void BiosHandler::saveKeepAndClearToBIOS(const std::string& keepAndClear,
508 const std::string& keepAndClearInBIOS)
509{
510 if (keepAndClear.size() != 1)
511 {
512 std::cerr << "Bad size for Keep and Clear in VPD: "
513 << keepAndClear.size() << std::endl;
514 return;
515 }
516
517 // Need to write?
518 std::string toWrite = (keepAndClear.at(0) & 0x01) ? "Enabled" : "Disabled";
519 if (keepAndClearInBIOS == toWrite)
520 {
521 std::cout << "Skip Keep and Clear BIOS write, value is already: "
522 << toWrite << std::endl;
523 return;
524 }
525
526 PendingBIOSAttrsType biosAttrs;
527 biosAttrs.push_back(
528 std::make_pair("pvm_keep_and_clear",
529 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
530 "AttributeType.Enumeration",
531 toWrite)));
532
533 std::cout << "Set pvm_keep_and_clear to: " << toWrite << std::endl;
534
535 setBusProperty<PendingBIOSAttrsType>(
536 "xyz.openbmc_project.BIOSConfigManager",
537 "/xyz/openbmc_project/bios_config/manager",
538 "xyz.openbmc_project.BIOSConfig.Manager", "PendingAttributes",
539 biosAttrs);
540}
541
542void BiosHandler::saveCreateDefaultLparToBIOS(
543 const std::string& createDefaultLpar,
544 const std::string& createDefaultLparInBIOS)
545{
546 if (createDefaultLpar.size() != 1)
547 {
548 std::cerr << "Bad size for Create default LPAR in VPD: "
549 << createDefaultLpar.size() << std::endl;
550 return;
551 }
552
553 // Need to write?
Patrick Williams08dc31c2024-08-16 15:21:06 -0400554 std::string toWrite =
555 (createDefaultLpar.at(0) & 0x02) ? "Enabled" : "Disabled";
Santosh Puranikb2c2ccc2022-05-14 05:15:44 -0500556 if (createDefaultLparInBIOS == toWrite)
557 {
558 std::cout << "Skip Create default LPAR BIOS write, value is already: "
559 << toWrite << std::endl;
560 return;
561 }
562
563 PendingBIOSAttrsType biosAttrs;
564 biosAttrs.push_back(
565 std::make_pair("pvm_create_default_lpar",
566 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
567 "AttributeType.Enumeration",
568 toWrite)));
569
570 std::cout << "Set pvm_create_default_lpar to: " << toWrite << std::endl;
571
572 setBusProperty<PendingBIOSAttrsType>(
573 "xyz.openbmc_project.BIOSConfigManager",
574 "/xyz/openbmc_project/bios_config/manager",
575 "xyz.openbmc_project.BIOSConfig.Manager", "PendingAttributes",
576 biosAttrs);
577}
578
Santosh Puranika97b63e2022-05-20 05:22:27 -0500579void BiosHandler::saveClearNVRAMToBIOS(const std::string& clearNVRAM,
580 const std::string& clearNVRAMInBIOS)
581{
582 if (clearNVRAM.size() != 1)
583 {
584 std::cerr << "Bad size for Clear NVRAM in VPD: " << clearNVRAM.size()
585 << std::endl;
586 return;
587 }
588
589 // Need to write?
590 std::string toWrite = (clearNVRAM.at(0) & 0x04) ? "Enabled" : "Disabled";
591 if (clearNVRAMInBIOS == toWrite)
592 {
593 std::cout << "Skip Clear NVRAM BIOS write, value is already: "
594 << toWrite << std::endl;
595 return;
596 }
597
598 PendingBIOSAttrsType biosAttrs;
599 biosAttrs.push_back(
600 std::make_pair("pvm_clear_nvram",
601 std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
602 "AttributeType.Enumeration",
603 toWrite)));
604
605 std::cout << "Set pvm_clear_nvram to: " << toWrite << std::endl;
606
607 setBusProperty<PendingBIOSAttrsType>(
608 "xyz.openbmc_project.BIOSConfigManager",
609 "/xyz/openbmc_project/bios_config/manager",
610 "xyz.openbmc_project.BIOSConfig.Manager", "PendingAttributes",
611 biosAttrs);
612}
613
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500614void BiosHandler::restoreBIOSAttribs()
615{
616 // TODO: We could make this slightly more scalable by defining a table of
617 // attributes and their corresponding VPD keywords. However, that needs much
618 // more thought.
619 std::cout << "Attempting BIOS attribute reset" << std::endl;
Santosh Puranika97b63e2022-05-20 05:22:27 -0500620 // Check if the VPD contains valid data for FCO, AMM, Keep and Clear,
621 // Create default LPAR and Clear NVRAM *and* that it differs from the data
622 // already in the attributes. If so, set the BIOS attributes as per the
623 // value in the VPD. If the VPD contains default data, then initialize the
624 // VPD keywords with data taken from the BIOS.
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500625 auto fcoInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VSYS", "RG");
626 auto ammInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D0");
Patrick Williams08dc31c2024-08-16 15:21:06 -0400627 auto keepAndClearInVPD =
628 readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500629 auto fcoInBIOS = readBIOSFCO();
630 auto ammInBIOS = readBIOSAMM();
Santosh Puranikb2c2ccc2022-05-14 05:15:44 -0500631 auto keepAndClearInBIOS = readBIOSKeepAndClear();
632 auto createDefaultLparInBIOS = readBIOSCreateDefaultLpar();
Santosh Puranika97b63e2022-05-20 05:22:27 -0500633 auto clearNVRAMInBIOS = readBIOSClearNVRAM();
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500634
635 if (fcoInVPD == " ")
636 {
637 saveFCOToVPD(fcoInBIOS);
638 }
639 else
640 {
Santosh Puranikf7f8da62022-05-06 13:01:19 -0500641 saveFCOToBIOS(fcoInVPD, fcoInBIOS);
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500642 }
643
644 if (ammInVPD.at(0) == 0)
645 {
646 saveAMMToVPD(ammInBIOS);
647 }
648 else
649 {
Santosh Puranikf7f8da62022-05-06 13:01:19 -0500650 saveAMMToBIOS(ammInVPD, ammInBIOS);
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500651 }
652
Santosh Puranika97b63e2022-05-20 05:22:27 -0500653 // No uninitialized handling needed for keep and clear, create default
654 // lpar and clear nvram attributes. Their defaults in VPD are 0's which is
655 // what we want.
Santosh Puranikb2c2ccc2022-05-14 05:15:44 -0500656 saveKeepAndClearToBIOS(keepAndClearInVPD, keepAndClearInBIOS);
657 // Have to read D1 again because two attributes are stored in the same
658 // keyword.
Patrick Williams08dc31c2024-08-16 15:21:06 -0400659 auto createDefaultLparInVPD =
660 readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");
Santosh Puranikb2c2ccc2022-05-14 05:15:44 -0500661 saveCreateDefaultLparToBIOS(createDefaultLparInVPD,
662 createDefaultLparInBIOS);
663
Patrick Williams08dc31c2024-08-16 15:21:06 -0400664 auto clearNVRAMInVPD =
665 readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");
Santosh Puranika97b63e2022-05-20 05:22:27 -0500666 saveClearNVRAMToBIOS(clearNVRAMInVPD, clearNVRAMInBIOS);
667
Santosh Puranikf2d3b532022-04-19 06:44:07 -0500668 // Start listener now that we have done the restore
669 listenBiosAttribs();
670}
671} // namespace manager
672} // namespace vpd
Patrick Williamsc78d8872023-05-10 07:50:56 -0500673} // namespace openpower