manager: Add some attributes to BIOS restore
This commit adds support to synchronize the pvm_keep_and_clear
and pvm_create_default_lpar BIOS attributes to the UTIL/D1
keyword in the motherboard VPD.
The use-case for doing this is the same as the other attributes we
already handle - that to restore them post a factory reset.
pvm_keep_and_clear - Backed up to UTIL/D1, bit 0
pvm_create_default_lpar - Backed up to UTIL/D1, bit 1
Signed-off-by: Santosh Puranik <santosh.puranik@in.ibm.com>
Change-Id: I8a2c08a06a17d15ed9a607a482a2c8a88173fddd
Signed-off-by: Santosh Puranik <santosh.puranik@in.ibm.com>
diff --git a/vpd-manager/bios_handler.cpp b/vpd-manager/bios_handler.cpp
index 417852e..1f0306c 100644
--- a/vpd-manager/bios_handler.cpp
+++ b/vpd-manager/bios_handler.cpp
@@ -137,6 +137,24 @@
saveFCOToVPD(*val);
}
}
+ else if (attributeName == "pvm_keep_and_clear")
+ {
+ auto attrValue = std::get<5>(std::get<1>(item));
+ auto val = std::get_if<std::string>(&attrValue);
+ if (val)
+ {
+ saveKeepAndClearToVPD(*val);
+ }
+ }
+ else if (attributeName == "pvm_create_default_lpar")
+ {
+ auto attrValue = std::get<5>(std::get<1>(item));
+ auto val = std::get_if<std::string>(&attrValue);
+ if (val)
+ {
+ saveCreateDefaultLparToVPD(*val);
+ }
+ }
}
}
}
@@ -206,6 +224,83 @@
}
}
+void BiosHandler::saveKeepAndClearToVPD(const std::string& keepAndClear)
+{
+ Binary vpdVal;
+ auto valInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");
+
+ if (valInVPD.size() != 1)
+ {
+ std::cerr << "Read bad size for UTIL/D1: " << valInVPD.size()
+ << std::endl;
+ return;
+ }
+
+ if (keepAndClear != "Enabled" && keepAndClear != "Disabled")
+ {
+ std::cerr << "Bad value for keep and clear BIOS arttribute: "
+ << keepAndClear << std::endl;
+ return;
+ }
+
+ // Write to VPD only if the value is not already what we want to write.
+ if (keepAndClear == "Enabled" && ((valInVPD.at(0) & 0x01) != 0x01))
+ {
+ vpdVal.emplace_back(valInVPD.at(0) | 0x01);
+ }
+ else if (keepAndClear == "Disabled" && ((valInVPD.at(0) & 0x01) != 0))
+ {
+ vpdVal.emplace_back(valInVPD.at(0) & ~(0x01));
+ }
+
+ if (!vpdVal.empty())
+ {
+ std::cout << "Writing Keep and Clear to VPD: "
+ << static_cast<int>(vpdVal.at(0)) << std::endl;
+ manager.writeKeyword(sdbusplus::message::object_path{SYSTEM_OBJECT},
+ "UTIL", "D1", vpdVal);
+ }
+}
+
+void BiosHandler::saveCreateDefaultLparToVPD(
+ const std::string& createDefaultLpar)
+{
+ Binary vpdVal;
+ auto valInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");
+
+ if (valInVPD.size() != 1)
+ {
+ std::cerr << "Read bad size for UTIL/D1: " << valInVPD.size()
+ << std::endl;
+ return;
+ }
+
+ if (createDefaultLpar != "Enabled" && createDefaultLpar != "Disabled")
+ {
+ std::cerr << "Bad value for create default lpar BIOS arttribute: "
+ << createDefaultLpar << std::endl;
+ return;
+ }
+
+ // Write to VPD only if the value is not already what we want to write.
+ if (createDefaultLpar == "Enabled" && ((valInVPD.at(0) & 0x02) != 0x02))
+ {
+ vpdVal.emplace_back(valInVPD.at(0) | 0x02);
+ }
+ else if (createDefaultLpar == "Disabled" && ((valInVPD.at(0) & 0x02) != 0))
+ {
+ vpdVal.emplace_back(valInVPD.at(0) & ~(0x02));
+ }
+
+ if (!vpdVal.empty())
+ {
+ std::cout << "Writing create default lpar to VPD: "
+ << static_cast<int>(vpdVal.at(0)) << std::endl;
+ manager.writeKeyword(sdbusplus::message::object_path{SYSTEM_OBJECT},
+ "UTIL", "D1", vpdVal);
+ }
+}
+
int64_t BiosHandler::readBIOSFCO()
{
int64_t fcoVal = -1;
@@ -238,6 +333,38 @@
return ammVal;
}
+std::string BiosHandler::readBIOSKeepAndClear()
+{
+ std::string keepAndClear{};
+ auto val = readBIOSAttribute("pvm_keep_and_clear");
+
+ if (auto pVal = std::get_if<std::string>(&val))
+ {
+ keepAndClear = *pVal;
+ }
+ else
+ {
+ std::cerr << "Keep and clear is not a string" << std::endl;
+ }
+ return keepAndClear;
+}
+
+std::string BiosHandler::readBIOSCreateDefaultLpar()
+{
+ std::string createDefaultLpar{};
+ auto val = readBIOSAttribute("pvm_create_default_lpar");
+
+ if (auto pVal = std::get_if<std::string>(&val))
+ {
+ createDefaultLpar = *pVal;
+ }
+ else
+ {
+ std::cerr << "Create default LPAR is not a string" << std::endl;
+ }
+ return createDefaultLpar;
+}
+
void BiosHandler::saveFCOToBIOS(const std::string& fcoVal, int64_t fcoInBIOS)
{
if (fcoVal.size() != 4)
@@ -313,21 +440,97 @@
biosAttrs);
}
+void BiosHandler::saveKeepAndClearToBIOS(const std::string& keepAndClear,
+ const std::string& keepAndClearInBIOS)
+{
+ if (keepAndClear.size() != 1)
+ {
+ std::cerr << "Bad size for Keep and Clear in VPD: "
+ << keepAndClear.size() << std::endl;
+ return;
+ }
+
+ // Need to write?
+ std::string toWrite = (keepAndClear.at(0) & 0x01) ? "Enabled" : "Disabled";
+ if (keepAndClearInBIOS == toWrite)
+ {
+ std::cout << "Skip Keep and Clear BIOS write, value is already: "
+ << toWrite << std::endl;
+ return;
+ }
+
+ PendingBIOSAttrsType biosAttrs;
+ biosAttrs.push_back(
+ std::make_pair("pvm_keep_and_clear",
+ std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
+ "AttributeType.Enumeration",
+ toWrite)));
+
+ std::cout << "Set pvm_keep_and_clear to: " << toWrite << std::endl;
+
+ setBusProperty<PendingBIOSAttrsType>(
+ "xyz.openbmc_project.BIOSConfigManager",
+ "/xyz/openbmc_project/bios_config/manager",
+ "xyz.openbmc_project.BIOSConfig.Manager", "PendingAttributes",
+ biosAttrs);
+}
+
+void BiosHandler::saveCreateDefaultLparToBIOS(
+ const std::string& createDefaultLpar,
+ const std::string& createDefaultLparInBIOS)
+{
+ if (createDefaultLpar.size() != 1)
+ {
+ std::cerr << "Bad size for Create default LPAR in VPD: "
+ << createDefaultLpar.size() << std::endl;
+ return;
+ }
+
+ // Need to write?
+ std::string toWrite =
+ (createDefaultLpar.at(0) & 0x02) ? "Enabled" : "Disabled";
+ if (createDefaultLparInBIOS == toWrite)
+ {
+ std::cout << "Skip Create default LPAR BIOS write, value is already: "
+ << toWrite << std::endl;
+ return;
+ }
+
+ PendingBIOSAttrsType biosAttrs;
+ biosAttrs.push_back(
+ std::make_pair("pvm_create_default_lpar",
+ std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
+ "AttributeType.Enumeration",
+ toWrite)));
+
+ std::cout << "Set pvm_create_default_lpar to: " << toWrite << std::endl;
+
+ setBusProperty<PendingBIOSAttrsType>(
+ "xyz.openbmc_project.BIOSConfigManager",
+ "/xyz/openbmc_project/bios_config/manager",
+ "xyz.openbmc_project.BIOSConfig.Manager", "PendingAttributes",
+ biosAttrs);
+}
+
void BiosHandler::restoreBIOSAttribs()
{
// TODO: We could make this slightly more scalable by defining a table of
// attributes and their corresponding VPD keywords. However, that needs much
// more thought.
std::cout << "Attempting BIOS attribute reset" << std::endl;
- // Check if the VPD contains valid data for FCO and AMM *and* that it
- // differs from the data already in the attributes. If so, set the BIOS
- // attributes as per the value in the VPD.
+ // Check if the VPD contains valid data for FCO, AMM, Keep and Clear and
+ // Create default LPAR *and* that it differs from the data already in the
+ // attributes. If so, set the BIOS attributes as per the value in the VPD.
// If the VPD contains default data, then initialize the VPD keywords with
// data taken from the BIOS.
auto fcoInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.VSYS", "RG");
auto ammInVPD = readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D0");
+ auto keepAndClearInVPD =
+ readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");
auto fcoInBIOS = readBIOSFCO();
auto ammInBIOS = readBIOSAMM();
+ auto keepAndClearInBIOS = readBIOSKeepAndClear();
+ auto createDefaultLparInBIOS = readBIOSCreateDefaultLpar();
if (fcoInVPD == " ")
{
@@ -347,6 +550,16 @@
saveAMMToBIOS(ammInVPD, ammInBIOS);
}
+ // No uninitialized handling needed for keep and clear and create default
+ // lpar attributes. Their defaults in VPD are 0's which is what we want.
+ saveKeepAndClearToBIOS(keepAndClearInVPD, keepAndClearInBIOS);
+ // Have to read D1 again because two attributes are stored in the same
+ // keyword.
+ auto createDefaultLparInVPD =
+ readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");
+ saveCreateDefaultLparToBIOS(createDefaultLparInVPD,
+ createDefaultLparInBIOS);
+
// Start listener now that we have done the restore
listenBiosAttribs();
}