manager: Sync pvm_clear_nvram BIOS Attribute
This commit adds support to synchronize the pvm_clear_nvram BIOS
attribute to bit 2 in the UTIL/D1 keyword of the motherboard VPD.
The attribute will be used by PHYP to determine when to clear their
NVRAM content.
A value of "Disabled" in the BIOS attribute maps to the D1:2 bit being 0
and a value of "Enabled: maps to the D1:2 bit being 1.
Signed-off-by: Santosh Puranik <santosh.puranik@in.ibm.com>
Change-Id: Ia0f3cfa92a98a2a1a95dd67ca598770459b9b7f2
diff --git a/vpd-manager/bios_handler.cpp b/vpd-manager/bios_handler.cpp
index 1f0306c..ff8ad37 100644
--- a/vpd-manager/bios_handler.cpp
+++ b/vpd-manager/bios_handler.cpp
@@ -155,6 +155,15 @@
saveCreateDefaultLparToVPD(*val);
}
}
+ else if (attributeName == "pvm_clear_nvram")
+ {
+ auto attrValue = std::get<5>(std::get<1>(item));
+ auto val = std::get_if<std::string>(&attrValue);
+ if (val)
+ {
+ saveClearNVRAMToVPD(*val);
+ }
+ }
}
}
}
@@ -200,7 +209,7 @@
if (mirrorMode != "Enabled" && mirrorMode != "Disabled")
{
- std::cerr << "Bad value for Mirror mode BIOS arttribute: " << mirrorMode
+ std::cerr << "Bad value for Mirror mode BIOS attribute: " << mirrorMode
<< std::endl;
return;
}
@@ -238,7 +247,7 @@
if (keepAndClear != "Enabled" && keepAndClear != "Disabled")
{
- std::cerr << "Bad value for keep and clear BIOS arttribute: "
+ std::cerr << "Bad value for keep and clear BIOS attribute: "
<< keepAndClear << std::endl;
return;
}
@@ -277,7 +286,7 @@
if (createDefaultLpar != "Enabled" && createDefaultLpar != "Disabled")
{
- std::cerr << "Bad value for create default lpar BIOS arttribute: "
+ std::cerr << "Bad value for create default lpar BIOS attribute: "
<< createDefaultLpar << std::endl;
return;
}
@@ -301,6 +310,44 @@
}
}
+void BiosHandler::saveClearNVRAMToVPD(const std::string& clearNVRAM)
+{
+ 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 (clearNVRAM != "Enabled" && clearNVRAM != "Disabled")
+ {
+ std::cerr << "Bad value for clear NVRAM BIOS attribute: " << clearNVRAM
+ << std::endl;
+ return;
+ }
+
+ // Write to VPD only if the value is not already what we want to write.
+ if (clearNVRAM == "Enabled" && ((valInVPD.at(0) & 0x04) != 0x04))
+ {
+ vpdVal.emplace_back(valInVPD.at(0) | 0x04);
+ }
+ else if (clearNVRAM == "Disabled" && ((valInVPD.at(0) & 0x04) != 0))
+ {
+ vpdVal.emplace_back(valInVPD.at(0) & ~(0x04));
+ }
+
+ if (!vpdVal.empty())
+ {
+ std::cout << "Writing clear NVRAM 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;
@@ -365,6 +412,22 @@
return createDefaultLpar;
}
+std::string BiosHandler::readBIOSClearNVRAM()
+{
+ std::string clearNVRAM{};
+ auto val = readBIOSAttribute("pvm_clear_nvram");
+
+ if (auto pVal = std::get_if<std::string>(&val))
+ {
+ clearNVRAM = *pVal;
+ }
+ else
+ {
+ std::cerr << "Clear NVRAM is not a string" << std::endl;
+ }
+ return clearNVRAM;
+}
+
void BiosHandler::saveFCOToBIOS(const std::string& fcoVal, int64_t fcoInBIOS)
{
if (fcoVal.size() != 4)
@@ -512,17 +575,52 @@
biosAttrs);
}
+void BiosHandler::saveClearNVRAMToBIOS(const std::string& clearNVRAM,
+ const std::string& clearNVRAMInBIOS)
+{
+ if (clearNVRAM.size() != 1)
+ {
+ std::cerr << "Bad size for Clear NVRAM in VPD: " << clearNVRAM.size()
+ << std::endl;
+ return;
+ }
+
+ // Need to write?
+ std::string toWrite = (clearNVRAM.at(0) & 0x04) ? "Enabled" : "Disabled";
+ if (clearNVRAMInBIOS == toWrite)
+ {
+ std::cout << "Skip Clear NVRAM BIOS write, value is already: "
+ << toWrite << std::endl;
+ return;
+ }
+
+ PendingBIOSAttrsType biosAttrs;
+ biosAttrs.push_back(
+ std::make_pair("pvm_clear_nvram",
+ std::make_tuple("xyz.openbmc_project.BIOSConfig.Manager."
+ "AttributeType.Enumeration",
+ toWrite)));
+
+ std::cout << "Set pvm_clear_nvram 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, 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.
+ // Check if the VPD contains valid data for FCO, AMM, Keep and Clear,
+ // Create default LPAR and Clear NVRAM *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 =
@@ -531,6 +629,7 @@
auto ammInBIOS = readBIOSAMM();
auto keepAndClearInBIOS = readBIOSKeepAndClear();
auto createDefaultLparInBIOS = readBIOSCreateDefaultLpar();
+ auto clearNVRAMInBIOS = readBIOSClearNVRAM();
if (fcoInVPD == " ")
{
@@ -550,8 +649,9 @@
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.
+ // No uninitialized handling needed for keep and clear, create default
+ // lpar and clear nvram 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.
@@ -560,6 +660,10 @@
saveCreateDefaultLparToBIOS(createDefaultLparInVPD,
createDefaultLparInBIOS);
+ auto clearNVRAMInVPD =
+ readBusProperty(SYSTEM_OBJECT, "com.ibm.ipzvpd.UTIL", "D1");
+ saveClearNVRAMToBIOS(clearNVRAMInVPD, clearNVRAMInBIOS);
+
// Start listener now that we have done the restore
listenBiosAttribs();
}