xref: /openbmc/openpower-vpd-parser/vpd-manager/src/bios_handler.cpp (revision 3aca293156c1a5ef6e32bfd9fd73edce1d5c1aee)
1fa5e4d32SSunny Srivastava #include "config.h"
2fa5e4d32SSunny Srivastava 
3fa5e4d32SSunny Srivastava #include "bios_handler.hpp"
4fa5e4d32SSunny Srivastava 
5fa5e4d32SSunny Srivastava #include "constants.hpp"
6fa5e4d32SSunny Srivastava #include "logger.hpp"
7fa5e4d32SSunny Srivastava 
8fa5e4d32SSunny Srivastava #include <sdbusplus/bus/match.hpp>
9fa5e4d32SSunny Srivastava #include <utility/common_utility.hpp>
10fa5e4d32SSunny Srivastava #include <utility/dbus_utility.hpp>
11fa5e4d32SSunny Srivastava 
12fa5e4d32SSunny Srivastava #include <string>
13fa5e4d32SSunny Srivastava 
14fa5e4d32SSunny Srivastava namespace vpd
15fa5e4d32SSunny Srivastava {
16fa5e4d32SSunny Srivastava // Template declaration to define APIs.
17fa5e4d32SSunny Srivastava template class BiosHandler<IbmBiosHandler>;
18fa5e4d32SSunny Srivastava 
19fa5e4d32SSunny Srivastava template <typename T>
checkAndListenPldmService()20fa5e4d32SSunny Srivastava void BiosHandler<T>::checkAndListenPldmService()
21fa5e4d32SSunny Srivastava {
22fa5e4d32SSunny Srivastava     // Setup a call back match on NameOwnerChanged to determine when PLDM is up.
23fa5e4d32SSunny Srivastava     static std::shared_ptr<sdbusplus::bus::match_t> l_nameOwnerMatch =
24fa5e4d32SSunny Srivastava         std::make_shared<sdbusplus::bus::match_t>(
25fa5e4d32SSunny Srivastava             *m_asioConn,
26fa5e4d32SSunny Srivastava             sdbusplus::bus::match::rules::nameOwnerChanged(
27fa5e4d32SSunny Srivastava                 constants::pldmServiceName),
28fa5e4d32SSunny Srivastava             [this](sdbusplus::message_t& l_msg) {
29fa5e4d32SSunny Srivastava                 if (l_msg.is_method_error())
30fa5e4d32SSunny Srivastava                 {
31fa5e4d32SSunny Srivastava                     logging::logMessage(
32fa5e4d32SSunny Srivastava                         "Error in reading PLDM name owner changed signal.");
33fa5e4d32SSunny Srivastava                     return;
34fa5e4d32SSunny Srivastava                 }
35fa5e4d32SSunny Srivastava 
36fa5e4d32SSunny Srivastava                 std::string l_name;
37fa5e4d32SSunny Srivastava                 std::string l_newOwner;
38fa5e4d32SSunny Srivastava                 std::string l_oldOwner;
39fa5e4d32SSunny Srivastava 
40fa5e4d32SSunny Srivastava                 l_msg.read(l_name, l_oldOwner, l_newOwner);
41fa5e4d32SSunny Srivastava 
42fa5e4d32SSunny Srivastava                 if (!l_newOwner.empty() &&
43fa5e4d32SSunny Srivastava                     (l_name.compare(constants::pldmServiceName) ==
44fa5e4d32SSunny Srivastava                      constants::STR_CMP_SUCCESS))
45fa5e4d32SSunny Srivastava                 {
46fa5e4d32SSunny Srivastava                     m_specificBiosHandler->backUpOrRestoreBiosAttributes();
47fa5e4d32SSunny Srivastava 
48fa5e4d32SSunny Srivastava                     // Start listener now that we have done the restore.
49fa5e4d32SSunny Srivastava                     listenBiosAttributes();
50fa5e4d32SSunny Srivastava 
51fa5e4d32SSunny Srivastava                     //  We don't need the match anymore
52fa5e4d32SSunny Srivastava                     l_nameOwnerMatch.reset();
53fa5e4d32SSunny Srivastava                 }
54fa5e4d32SSunny Srivastava             });
55fa5e4d32SSunny Srivastava 
56fa5e4d32SSunny Srivastava     // Based on PLDM service status reset owner match registered above and
57fa5e4d32SSunny Srivastava     // trigger BIOS attribute sync.
58fa5e4d32SSunny Srivastava     if (dbusUtility::isServiceRunning(constants::pldmServiceName))
59fa5e4d32SSunny Srivastava     {
60fa5e4d32SSunny Srivastava         l_nameOwnerMatch.reset();
61fa5e4d32SSunny Srivastava         m_specificBiosHandler->backUpOrRestoreBiosAttributes();
62fa5e4d32SSunny Srivastava 
63fa5e4d32SSunny Srivastava         // Start listener now that we have done the restore.
64fa5e4d32SSunny Srivastava         listenBiosAttributes();
65fa5e4d32SSunny Srivastava     }
66fa5e4d32SSunny Srivastava }
67fa5e4d32SSunny Srivastava 
68fa5e4d32SSunny Srivastava template <typename T>
listenBiosAttributes()69fa5e4d32SSunny Srivastava void BiosHandler<T>::listenBiosAttributes()
70fa5e4d32SSunny Srivastava {
71fa5e4d32SSunny Srivastava     static std::shared_ptr<sdbusplus::bus::match_t> l_biosMatch =
72fa5e4d32SSunny Srivastava         std::make_shared<sdbusplus::bus::match_t>(
73fa5e4d32SSunny Srivastava             *m_asioConn,
74fa5e4d32SSunny Srivastava             sdbusplus::bus::match::rules::propertiesChanged(
75fa5e4d32SSunny Srivastava                 constants::biosConfigMgrObjPath,
76fa5e4d32SSunny Srivastava                 constants::biosConfigMgrInterface),
77fa5e4d32SSunny Srivastava             [this](sdbusplus::message_t& l_msg) {
78fa5e4d32SSunny Srivastava                 m_specificBiosHandler->biosAttributesCallback(l_msg);
79fa5e4d32SSunny Srivastava             });
80fa5e4d32SSunny Srivastava }
81fa5e4d32SSunny Srivastava 
biosAttributesCallback(sdbusplus::message_t & i_msg)82fa5e4d32SSunny Srivastava void IbmBiosHandler::biosAttributesCallback(sdbusplus::message_t& i_msg)
83fa5e4d32SSunny Srivastava {
84fa5e4d32SSunny Srivastava     if (i_msg.is_method_error())
85fa5e4d32SSunny Srivastava     {
86fa5e4d32SSunny Srivastava         logging::logMessage("Error in reading BIOS attribute signal. ");
87fa5e4d32SSunny Srivastava         return;
88fa5e4d32SSunny Srivastava     }
89fa5e4d32SSunny Srivastava 
90fa5e4d32SSunny Srivastava     std::string l_objPath;
91fa5e4d32SSunny Srivastava     types::BiosBaseTableType l_propMap;
92fa5e4d32SSunny Srivastava     i_msg.read(l_objPath, l_propMap);
93fa5e4d32SSunny Srivastava 
94fa5e4d32SSunny Srivastava     for (auto l_property : l_propMap)
95fa5e4d32SSunny Srivastava     {
96fa5e4d32SSunny Srivastava         if (l_property.first != "BaseBIOSTable")
97fa5e4d32SSunny Srivastava         {
98fa5e4d32SSunny Srivastava             // Looking for change in Base BIOS table only.
99fa5e4d32SSunny Srivastava             continue;
100fa5e4d32SSunny Srivastava         }
101fa5e4d32SSunny Srivastava 
102fa5e4d32SSunny Srivastava         if (auto l_attributeList =
103fa5e4d32SSunny Srivastava                 std::get_if<std::map<std::string, types::BiosProperty>>(
104fa5e4d32SSunny Srivastava                     &(l_property.second)))
105fa5e4d32SSunny Srivastava         {
106fa5e4d32SSunny Srivastava             for (const auto& l_attribute : *l_attributeList)
107fa5e4d32SSunny Srivastava             {
108fa5e4d32SSunny Srivastava                 if (auto l_val = std::get_if<std::string>(
109fa5e4d32SSunny Srivastava                         &(std::get<5>(std::get<1>(l_attribute)))))
110fa5e4d32SSunny Srivastava                 {
111fa5e4d32SSunny Srivastava                     std::string l_attributeName = std::get<0>(l_attribute);
112fa5e4d32SSunny Srivastava                     if (l_attributeName == "hb_memory_mirror_mode")
113fa5e4d32SSunny Srivastava                     {
114fa5e4d32SSunny Srivastava                         saveAmmToVpd(*l_val);
115fa5e4d32SSunny Srivastava                     }
116fa5e4d32SSunny Srivastava 
117fa5e4d32SSunny Srivastava                     if (l_attributeName == "pvm_keep_and_clear")
118fa5e4d32SSunny Srivastava                     {
119fa5e4d32SSunny Srivastava                         saveKeepAndClearToVpd(*l_val);
120fa5e4d32SSunny Srivastava                     }
121fa5e4d32SSunny Srivastava 
122fa5e4d32SSunny Srivastava                     if (l_attributeName == "pvm_create_default_lpar")
123fa5e4d32SSunny Srivastava                     {
124fa5e4d32SSunny Srivastava                         saveCreateDefaultLparToVpd(*l_val);
125fa5e4d32SSunny Srivastava                     }
126fa5e4d32SSunny Srivastava 
127fa5e4d32SSunny Srivastava                     if (l_attributeName == "pvm_clear_nvram")
128fa5e4d32SSunny Srivastava                     {
129fa5e4d32SSunny Srivastava                         saveClearNvramToVpd(*l_val);
130fa5e4d32SSunny Srivastava                     }
131fa5e4d32SSunny Srivastava 
132fa5e4d32SSunny Srivastava                     continue;
133fa5e4d32SSunny Srivastava                 }
134fa5e4d32SSunny Srivastava 
135fa5e4d32SSunny Srivastava                 if (auto l_val = std::get_if<int64_t>(
136fa5e4d32SSunny Srivastava                         &(std::get<5>(std::get<1>(l_attribute)))))
137fa5e4d32SSunny Srivastava                 {
138fa5e4d32SSunny Srivastava                     std::string l_attributeName = std::get<0>(l_attribute);
139fa5e4d32SSunny Srivastava                     if (l_attributeName == "hb_field_core_override")
140fa5e4d32SSunny Srivastava                     {
141fa5e4d32SSunny Srivastava                         saveFcoToVpd(*l_val);
142fa5e4d32SSunny Srivastava                     }
143fa5e4d32SSunny Srivastava                 }
144fa5e4d32SSunny Srivastava             }
145fa5e4d32SSunny Srivastava         }
146fa5e4d32SSunny Srivastava         else
147fa5e4d32SSunny Srivastava         {
148fa5e4d32SSunny Srivastava             // TODO: log a predicitive PEL.
149fa5e4d32SSunny Srivastava             logging::logMessage("Invalid typre received from BIOS table.");
150fa5e4d32SSunny Srivastava             break;
151fa5e4d32SSunny Srivastava         }
152fa5e4d32SSunny Srivastava     }
153fa5e4d32SSunny Srivastava }
154fa5e4d32SSunny Srivastava 
backUpOrRestoreBiosAttributes()155fa5e4d32SSunny Srivastava void IbmBiosHandler::backUpOrRestoreBiosAttributes()
156fa5e4d32SSunny Srivastava {
157fa5e4d32SSunny Srivastava     // process FCO
158fa5e4d32SSunny Srivastava     processFieldCoreOverride();
159fa5e4d32SSunny Srivastava 
160fa5e4d32SSunny Srivastava     // process AMM
161fa5e4d32SSunny Srivastava     processActiveMemoryMirror();
162fa5e4d32SSunny Srivastava 
163fa5e4d32SSunny Srivastava     // process LPAR
164fa5e4d32SSunny Srivastava     processCreateDefaultLpar();
165fa5e4d32SSunny Srivastava 
166fa5e4d32SSunny Srivastava     // process clear NVRAM
167fa5e4d32SSunny Srivastava     processClearNvram();
168fa5e4d32SSunny Srivastava 
169fa5e4d32SSunny Srivastava     // process keep and clear
170fa5e4d32SSunny Srivastava     processKeepAndClear();
171fa5e4d32SSunny Srivastava }
172fa5e4d32SSunny Srivastava 
readBiosAttribute(const std::string & i_attributeName)17343fedabcSPatrick Williams types::BiosAttributeCurrentValue IbmBiosHandler::readBiosAttribute(
17443fedabcSPatrick Williams     const std::string& i_attributeName)
175fa5e4d32SSunny Srivastava {
176fa5e4d32SSunny Srivastava     types::BiosAttributeCurrentValue l_attrValueVariant =
177fa5e4d32SSunny Srivastava         dbusUtility::biosGetAttributeMethodCall(i_attributeName);
178fa5e4d32SSunny Srivastava 
179fa5e4d32SSunny Srivastava     return l_attrValueVariant;
180fa5e4d32SSunny Srivastava }
181fa5e4d32SSunny Srivastava 
processFieldCoreOverride()182fa5e4d32SSunny Srivastava void IbmBiosHandler::processFieldCoreOverride()
183fa5e4d32SSunny Srivastava {
184fa5e4d32SSunny Srivastava     // TODO: Should we avoid doing this at runtime?
185fa5e4d32SSunny Srivastava 
186fa5e4d32SSunny Srivastava     // Read required keyword from Dbus.
187fa5e4d32SSunny Srivastava     auto l_kwdValueVariant = dbusUtility::readDbusProperty(
188fa5e4d32SSunny Srivastava         constants::pimServiceName, constants::systemVpdInvPath,
189fa5e4d32SSunny Srivastava         constants::vsysInf, constants::kwdRG);
190fa5e4d32SSunny Srivastava 
191fa5e4d32SSunny Srivastava     if (auto l_fcoInVpd = std::get_if<types::BinaryVector>(&l_kwdValueVariant))
192fa5e4d32SSunny Srivastava     {
193fa5e4d32SSunny Srivastava         // default length of the keyword is 4 bytes.
194fa5e4d32SSunny Srivastava         if (l_fcoInVpd->size() != constants::VALUE_4)
195fa5e4d32SSunny Srivastava         {
196fa5e4d32SSunny Srivastava             logging::logMessage(
197fa5e4d32SSunny Srivastava                 "Invalid value read for FCO from D-Bus. Skipping.");
198fa5e4d32SSunny Srivastava         }
199fa5e4d32SSunny Srivastava 
200fa5e4d32SSunny Srivastava         //  If FCO in VPD contains anything other that ASCII Space, restore to
201fa5e4d32SSunny Srivastava         //  BIOS
202fa5e4d32SSunny Srivastava         if (std::any_of(l_fcoInVpd->cbegin(), l_fcoInVpd->cend(),
203fa5e4d32SSunny Srivastava                         [](uint8_t l_val) {
204fa5e4d32SSunny Srivastava                             return l_val != constants::ASCII_OF_SPACE;
205fa5e4d32SSunny Srivastava                         }))
206fa5e4d32SSunny Srivastava         {
207fa5e4d32SSunny Srivastava             // Restore the data to BIOS.
208fa5e4d32SSunny Srivastava             saveFcoToBios(*l_fcoInVpd);
209fa5e4d32SSunny Srivastava         }
210fa5e4d32SSunny Srivastava         else
211fa5e4d32SSunny Srivastava         {
212fa5e4d32SSunny Srivastava             types::BiosAttributeCurrentValue l_attrValueVariant =
213fa5e4d32SSunny Srivastava                 readBiosAttribute("hb_field_core_override");
214fa5e4d32SSunny Srivastava 
215fa5e4d32SSunny Srivastava             if (auto l_fcoInBios = std::get_if<int64_t>(&l_attrValueVariant))
216fa5e4d32SSunny Srivastava             {
217fa5e4d32SSunny Srivastava                 // save the BIOS data to VPD
218fa5e4d32SSunny Srivastava                 saveFcoToVpd(*l_fcoInBios);
219fa5e4d32SSunny Srivastava 
220fa5e4d32SSunny Srivastava                 return;
221fa5e4d32SSunny Srivastava             }
222fa5e4d32SSunny Srivastava             logging::logMessage("Invalid type recieved for FCO from BIOS.");
223fa5e4d32SSunny Srivastava         }
224fa5e4d32SSunny Srivastava         return;
225fa5e4d32SSunny Srivastava     }
226fa5e4d32SSunny Srivastava     logging::logMessage("Invalid type recieved for FCO from VPD.");
227fa5e4d32SSunny Srivastava }
228fa5e4d32SSunny Srivastava 
saveFcoToVpd(int64_t i_fcoInBios)229fa5e4d32SSunny Srivastava void IbmBiosHandler::saveFcoToVpd(int64_t i_fcoInBios)
230fa5e4d32SSunny Srivastava {
231fa5e4d32SSunny Srivastava     if (i_fcoInBios < 0)
232fa5e4d32SSunny Srivastava     {
233fa5e4d32SSunny Srivastava         logging::logMessage("Invalid FCO value in BIOS. Skip updating to VPD");
234fa5e4d32SSunny Srivastava         return;
235fa5e4d32SSunny Srivastava     }
236fa5e4d32SSunny Srivastava 
237fa5e4d32SSunny Srivastava     // Read required keyword from Dbus.
238fa5e4d32SSunny Srivastava     auto l_kwdValueVariant = dbusUtility::readDbusProperty(
239fa5e4d32SSunny Srivastava         constants::pimServiceName, constants::systemVpdInvPath,
240fa5e4d32SSunny Srivastava         constants::vsysInf, constants::kwdRG);
241fa5e4d32SSunny Srivastava 
242fa5e4d32SSunny Srivastava     if (auto l_fcoInVpd = std::get_if<types::BinaryVector>(&l_kwdValueVariant))
243fa5e4d32SSunny Srivastava     {
244fa5e4d32SSunny Srivastava         // default length of the keyword is 4 bytes.
245fa5e4d32SSunny Srivastava         if (l_fcoInVpd->size() != constants::VALUE_4)
246fa5e4d32SSunny Srivastava         {
247fa5e4d32SSunny Srivastava             logging::logMessage(
248fa5e4d32SSunny Srivastava                 "Invalid value read for FCO from D-Bus. Skipping.");
249fa5e4d32SSunny Srivastava             return;
250fa5e4d32SSunny Srivastava         }
251fa5e4d32SSunny Srivastava 
252fa5e4d32SSunny Srivastava         // convert to VPD value type
253fa5e4d32SSunny Srivastava         types::BinaryVector l_biosValInVpdFormat = {
254fa5e4d32SSunny Srivastava             0, 0, 0, static_cast<uint8_t>(i_fcoInBios)};
255fa5e4d32SSunny Srivastava 
256fa5e4d32SSunny Srivastava         // Update only when the data are different.
257fa5e4d32SSunny Srivastava         if (std::memcmp(l_biosValInVpdFormat.data(), l_fcoInVpd->data(),
258fa5e4d32SSunny Srivastava                         constants::VALUE_4) != constants::SUCCESS)
259fa5e4d32SSunny Srivastava         {
260fa5e4d32SSunny Srivastava             if (constants::FAILURE ==
261fa5e4d32SSunny Srivastava                 m_manager->updateKeyword(
262fa5e4d32SSunny Srivastava                     SYSTEM_VPD_FILE_PATH,
263fa5e4d32SSunny Srivastava                     types::IpzData("VSYS", constants::kwdRG,
264fa5e4d32SSunny Srivastava                                    l_biosValInVpdFormat)))
265fa5e4d32SSunny Srivastava             {
266fa5e4d32SSunny Srivastava                 logging::logMessage(
267fa5e4d32SSunny Srivastava                     "Failed to update " + std::string(constants::kwdRG) +
268fa5e4d32SSunny Srivastava                     " keyword to VPD.");
269fa5e4d32SSunny Srivastava             }
270fa5e4d32SSunny Srivastava         }
271fa5e4d32SSunny Srivastava     }
272fa5e4d32SSunny Srivastava     else
273fa5e4d32SSunny Srivastava     {
274fa5e4d32SSunny Srivastava         logging::logMessage("Invalid type read for FCO from DBus.");
275fa5e4d32SSunny Srivastava     }
276fa5e4d32SSunny Srivastava }
277fa5e4d32SSunny Srivastava 
saveFcoToBios(const types::BinaryVector & i_fcoVal)278fa5e4d32SSunny Srivastava void IbmBiosHandler::saveFcoToBios(const types::BinaryVector& i_fcoVal)
279fa5e4d32SSunny Srivastava {
280fa5e4d32SSunny Srivastava     if (i_fcoVal.size() != constants::VALUE_4)
281fa5e4d32SSunny Srivastava     {
282fa5e4d32SSunny Srivastava         logging::logMessage("Bad size for FCO received. Skip writing to BIOS");
283fa5e4d32SSunny Srivastava         return;
284fa5e4d32SSunny Srivastava     }
285fa5e4d32SSunny Srivastava 
286fa5e4d32SSunny Srivastava     types::PendingBIOSAttrs l_pendingBiosAttribute;
287fa5e4d32SSunny Srivastava     l_pendingBiosAttribute.push_back(std::make_pair(
288fa5e4d32SSunny Srivastava         "hb_field_core_override",
289fa5e4d32SSunny Srivastava         std::make_tuple(
290fa5e4d32SSunny Srivastava             "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Integer",
291fa5e4d32SSunny Srivastava             i_fcoVal.at(constants::VALUE_3))));
292fa5e4d32SSunny Srivastava 
293c532b188SRekhaAparna01     if (!dbusUtility::writeDbusProperty(
294fa5e4d32SSunny Srivastava             constants::biosConfigMgrService, constants::biosConfigMgrObjPath,
295fa5e4d32SSunny Srivastava             constants::biosConfigMgrInterface, "PendingAttributes",
296c532b188SRekhaAparna01             l_pendingBiosAttribute))
297fa5e4d32SSunny Srivastava     {
298fa5e4d32SSunny Srivastava         // TODO: Should we log informational PEL here as well?
299fa5e4d32SSunny Srivastava         logging::logMessage(
300c532b188SRekhaAparna01             "DBus call to update FCO value in pending attribute failed. ");
301fa5e4d32SSunny Srivastava     }
302fa5e4d32SSunny Srivastava }
303fa5e4d32SSunny Srivastava 
saveAmmToVpd(const std::string & i_memoryMirrorMode)304fa5e4d32SSunny Srivastava void IbmBiosHandler::saveAmmToVpd(const std::string& i_memoryMirrorMode)
305fa5e4d32SSunny Srivastava {
306fa5e4d32SSunny Srivastava     if (i_memoryMirrorMode.empty())
307fa5e4d32SSunny Srivastava     {
308fa5e4d32SSunny Srivastava         logging::logMessage(
309fa5e4d32SSunny Srivastava             "Empty memory mirror mode value from BIOS. Skip writing to VPD");
310fa5e4d32SSunny Srivastava         return;
311fa5e4d32SSunny Srivastava     }
312fa5e4d32SSunny Srivastava 
313fa5e4d32SSunny Srivastava     // Read existing value.
314fa5e4d32SSunny Srivastava     auto l_kwdValueVariant = dbusUtility::readDbusProperty(
315fa5e4d32SSunny Srivastava         constants::pimServiceName, constants::systemVpdInvPath,
316fa5e4d32SSunny Srivastava         constants::utilInf, constants::kwdAMM);
317fa5e4d32SSunny Srivastava 
318fa5e4d32SSunny Srivastava     if (auto l_pVal = std::get_if<types::BinaryVector>(&l_kwdValueVariant))
319fa5e4d32SSunny Srivastava     {
320fa5e4d32SSunny Srivastava         auto l_ammValInVpd = *l_pVal;
321fa5e4d32SSunny Srivastava 
322fa5e4d32SSunny Srivastava         types::BinaryVector l_valToUpdateInVpd{
323fa5e4d32SSunny Srivastava             (i_memoryMirrorMode == "Enabled" ? constants::AMM_ENABLED_IN_VPD
324fa5e4d32SSunny Srivastava                                              : constants::AMM_DISABLED_IN_VPD)};
325fa5e4d32SSunny Srivastava 
326fa5e4d32SSunny Srivastava         // Check if value is already updated on VPD.
327fa5e4d32SSunny Srivastava         if (l_ammValInVpd.at(0) == l_valToUpdateInVpd.at(0))
328fa5e4d32SSunny Srivastava         {
329fa5e4d32SSunny Srivastava             return;
330fa5e4d32SSunny Srivastava         }
331fa5e4d32SSunny Srivastava 
332fa5e4d32SSunny Srivastava         if (constants::FAILURE ==
333fa5e4d32SSunny Srivastava             m_manager->updateKeyword(
334fa5e4d32SSunny Srivastava                 SYSTEM_VPD_FILE_PATH,
335fa5e4d32SSunny Srivastava                 types::IpzData("UTIL", constants::kwdAMM, l_valToUpdateInVpd)))
336fa5e4d32SSunny Srivastava         {
337fa5e4d32SSunny Srivastava             logging::logMessage(
338fa5e4d32SSunny Srivastava                 "Failed to update " + std::string(constants::kwdAMM) +
339fa5e4d32SSunny Srivastava                 " keyword to VPD");
340fa5e4d32SSunny Srivastava         }
341fa5e4d32SSunny Srivastava     }
342fa5e4d32SSunny Srivastava     else
343fa5e4d32SSunny Srivastava     {
344fa5e4d32SSunny Srivastava         // TODO: Add PEL
345fa5e4d32SSunny Srivastava         logging::logMessage(
346fa5e4d32SSunny Srivastava             "Invalid type read for memory mirror mode value from DBus. Skip writing to VPD");
347fa5e4d32SSunny Srivastava     }
348fa5e4d32SSunny Srivastava }
349fa5e4d32SSunny Srivastava 
saveAmmToBios(const uint8_t & i_ammVal)350*3aca2931SAnupama B R void IbmBiosHandler::saveAmmToBios(const uint8_t& i_ammVal)
351fa5e4d32SSunny Srivastava {
352fa5e4d32SSunny Srivastava     const std::string l_valtoUpdate =
353*3aca2931SAnupama B R         (i_ammVal == constants::VALUE_2) ? "Enabled" : "Disabled";
354fa5e4d32SSunny Srivastava 
355fa5e4d32SSunny Srivastava     types::PendingBIOSAttrs l_pendingBiosAttribute;
356fa5e4d32SSunny Srivastava     l_pendingBiosAttribute.push_back(std::make_pair(
357fa5e4d32SSunny Srivastava         "hb_memory_mirror_mode",
358fa5e4d32SSunny Srivastava         std::make_tuple(
359fa5e4d32SSunny Srivastava             "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Enumeration",
360fa5e4d32SSunny Srivastava             l_valtoUpdate)));
361fa5e4d32SSunny Srivastava 
362c532b188SRekhaAparna01     if (!dbusUtility::writeDbusProperty(
363fa5e4d32SSunny Srivastava             constants::biosConfigMgrService, constants::biosConfigMgrObjPath,
364fa5e4d32SSunny Srivastava             constants::biosConfigMgrInterface, "PendingAttributes",
365c532b188SRekhaAparna01             l_pendingBiosAttribute))
366fa5e4d32SSunny Srivastava     {
367fa5e4d32SSunny Srivastava         // TODO: Should we log informational PEL here as well?
368fa5e4d32SSunny Srivastava         logging::logMessage(
369c532b188SRekhaAparna01             "DBus call to update AMM value in pending attribute failed.");
370fa5e4d32SSunny Srivastava     }
371fa5e4d32SSunny Srivastava }
372fa5e4d32SSunny Srivastava 
processActiveMemoryMirror()373fa5e4d32SSunny Srivastava void IbmBiosHandler::processActiveMemoryMirror()
374fa5e4d32SSunny Srivastava {
375fa5e4d32SSunny Srivastava     auto l_kwdValueVariant = dbusUtility::readDbusProperty(
376fa5e4d32SSunny Srivastava         constants::pimServiceName, constants::systemVpdInvPath,
377fa5e4d32SSunny Srivastava         constants::utilInf, constants::kwdAMM);
378fa5e4d32SSunny Srivastava 
379fa5e4d32SSunny Srivastava     if (auto pVal = std::get_if<types::BinaryVector>(&l_kwdValueVariant))
380fa5e4d32SSunny Srivastava     {
381fa5e4d32SSunny Srivastava         auto l_ammValInVpd = *pVal;
382fa5e4d32SSunny Srivastava 
383fa5e4d32SSunny Srivastava         // Check if active memory mirror value is default in VPD.
384fa5e4d32SSunny Srivastava         if (l_ammValInVpd.at(0) == constants::VALUE_0)
385fa5e4d32SSunny Srivastava         {
386fa5e4d32SSunny Srivastava             types::BiosAttributeCurrentValue l_attrValueVariant =
387fa5e4d32SSunny Srivastava                 readBiosAttribute("hb_memory_mirror_mode");
388fa5e4d32SSunny Srivastava 
389fa5e4d32SSunny Srivastava             if (auto pVal = std::get_if<std::string>(&l_attrValueVariant))
390fa5e4d32SSunny Srivastava             {
391fa5e4d32SSunny Srivastava                 saveAmmToVpd(*pVal);
392fa5e4d32SSunny Srivastava                 return;
393fa5e4d32SSunny Srivastava             }
394fa5e4d32SSunny Srivastava             logging::logMessage(
395fa5e4d32SSunny Srivastava                 "Invalid type recieved for auto memory mirror mode from BIOS.");
396fa5e4d32SSunny Srivastava             return;
397fa5e4d32SSunny Srivastava         }
398fa5e4d32SSunny Srivastava         else
399fa5e4d32SSunny Srivastava         {
400*3aca2931SAnupama B R             saveAmmToBios(l_ammValInVpd.at(0));
401fa5e4d32SSunny Srivastava         }
402fa5e4d32SSunny Srivastava         return;
403fa5e4d32SSunny Srivastava     }
404fa5e4d32SSunny Srivastava     logging::logMessage(
405fa5e4d32SSunny Srivastava         "Invalid type recieved for auto memory mirror mode from VPD.");
406fa5e4d32SSunny Srivastava }
407fa5e4d32SSunny Srivastava 
saveCreateDefaultLparToVpd(const std::string & i_createDefaultLparVal)408fa5e4d32SSunny Srivastava void IbmBiosHandler::saveCreateDefaultLparToVpd(
409fa5e4d32SSunny Srivastava     const std::string& i_createDefaultLparVal)
410fa5e4d32SSunny Srivastava {
411fa5e4d32SSunny Srivastava     if (i_createDefaultLparVal.empty())
412fa5e4d32SSunny Srivastava     {
413fa5e4d32SSunny Srivastava         logging::logMessage(
414fa5e4d32SSunny Srivastava             "Empty value received for Lpar from BIOS. Skip writing in VPD.");
415fa5e4d32SSunny Srivastava         return;
416fa5e4d32SSunny Srivastava     }
417fa5e4d32SSunny Srivastava 
418fa5e4d32SSunny Srivastava     // Read required keyword from DBus as we need to set only a Bit.
419fa5e4d32SSunny Srivastava     auto l_kwdValueVariant = dbusUtility::readDbusProperty(
420fa5e4d32SSunny Srivastava         constants::pimServiceName, constants::systemVpdInvPath,
421fa5e4d32SSunny Srivastava         constants::utilInf, constants::kwdClearNVRAM_CreateLPAR);
422fa5e4d32SSunny Srivastava 
423fa5e4d32SSunny Srivastava     if (auto l_pVal = std::get_if<types::BinaryVector>(&l_kwdValueVariant))
424fa5e4d32SSunny Srivastava     {
425fa5e4d32SSunny Srivastava         commonUtility::toLower(
426fa5e4d32SSunny Srivastava             const_cast<std::string&>(i_createDefaultLparVal));
427fa5e4d32SSunny Srivastava 
428fa5e4d32SSunny Srivastava         // Check for second bit. Bit set for enabled else disabled.
429fa5e4d32SSunny Srivastava         if (((((*l_pVal).at(0) & 0x02) == 0x02) &&
430fa5e4d32SSunny Srivastava              (i_createDefaultLparVal.compare("enabled") ==
431fa5e4d32SSunny Srivastava               constants::STR_CMP_SUCCESS)) ||
432fa5e4d32SSunny Srivastava             ((((*l_pVal).at(0) & 0x02) == 0x00) &&
433fa5e4d32SSunny Srivastava              (i_createDefaultLparVal.compare("disabled") ==
434fa5e4d32SSunny Srivastava               constants::STR_CMP_SUCCESS)))
435fa5e4d32SSunny Srivastava         {
436fa5e4d32SSunny Srivastava             // Values are same, Don;t update.
437fa5e4d32SSunny Srivastava             return;
438fa5e4d32SSunny Srivastava         }
439fa5e4d32SSunny Srivastava 
440fa5e4d32SSunny Srivastava         types::BinaryVector l_valToUpdateInVpd;
441fa5e4d32SSunny Srivastava         if (i_createDefaultLparVal.compare("enabled") ==
442fa5e4d32SSunny Srivastava             constants::STR_CMP_SUCCESS)
443fa5e4d32SSunny Srivastava         {
444fa5e4d32SSunny Srivastava             // 2nd Bit is used to store the value.
445fa5e4d32SSunny Srivastava             l_valToUpdateInVpd.emplace_back((*l_pVal).at(0) | 0x02);
446fa5e4d32SSunny Srivastava         }
447fa5e4d32SSunny Srivastava         else
448fa5e4d32SSunny Srivastava         {
449fa5e4d32SSunny Srivastava             // 2nd Bit is used to store the value.
450fa5e4d32SSunny Srivastava             l_valToUpdateInVpd.emplace_back((*l_pVal).at(0) & ~(0x02));
451fa5e4d32SSunny Srivastava         }
452fa5e4d32SSunny Srivastava 
453fa5e4d32SSunny Srivastava         if (-1 ==
454fa5e4d32SSunny Srivastava             m_manager->updateKeyword(
455fa5e4d32SSunny Srivastava                 SYSTEM_VPD_FILE_PATH,
456fa5e4d32SSunny Srivastava                 types::IpzData("UTIL", constants::kwdClearNVRAM_CreateLPAR,
457fa5e4d32SSunny Srivastava                                l_valToUpdateInVpd)))
458fa5e4d32SSunny Srivastava         {
459fa5e4d32SSunny Srivastava             logging::logMessage(
460fa5e4d32SSunny Srivastava                 "Failed to update " +
461fa5e4d32SSunny Srivastava                 std::string(constants::kwdClearNVRAM_CreateLPAR) +
462fa5e4d32SSunny Srivastava                 " keyword to VPD");
463fa5e4d32SSunny Srivastava         }
464fa5e4d32SSunny Srivastava 
465fa5e4d32SSunny Srivastava         return;
466fa5e4d32SSunny Srivastava     }
467fa5e4d32SSunny Srivastava     logging::logMessage(
468fa5e4d32SSunny Srivastava         "Invalid type recieved for create default Lpar from VPD.");
469fa5e4d32SSunny Srivastava }
470fa5e4d32SSunny Srivastava 
saveCreateDefaultLparToBios(const std::string & i_createDefaultLparVal)471fa5e4d32SSunny Srivastava void IbmBiosHandler::saveCreateDefaultLparToBios(
472fa5e4d32SSunny Srivastava     const std::string& i_createDefaultLparVal)
473fa5e4d32SSunny Srivastava {
474fa5e4d32SSunny Srivastava     // checking for exact length as it is a string and can have garbage value.
475fa5e4d32SSunny Srivastava     if (i_createDefaultLparVal.size() != constants::VALUE_1)
476fa5e4d32SSunny Srivastava     {
477fa5e4d32SSunny Srivastava         logging::logMessage(
478fa5e4d32SSunny Srivastava             "Bad size for Create default LPAR in VPD. Skip writing to BIOS.");
479fa5e4d32SSunny Srivastava         return;
480fa5e4d32SSunny Srivastava     }
481fa5e4d32SSunny Srivastava 
482fa5e4d32SSunny Srivastava     std::string l_valtoUpdate =
483fa5e4d32SSunny Srivastava         (i_createDefaultLparVal.at(0) & 0x02) ? "Enabled" : "Disabled";
484fa5e4d32SSunny Srivastava 
485fa5e4d32SSunny Srivastava     types::PendingBIOSAttrs l_pendingBiosAttribute;
486fa5e4d32SSunny Srivastava     l_pendingBiosAttribute.push_back(std::make_pair(
487fa5e4d32SSunny Srivastava         "pvm_create_default_lpar",
488fa5e4d32SSunny Srivastava         std::make_tuple(
489fa5e4d32SSunny Srivastava             "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Enumeration",
490fa5e4d32SSunny Srivastava             l_valtoUpdate)));
491fa5e4d32SSunny Srivastava 
492c532b188SRekhaAparna01     if (!dbusUtility::writeDbusProperty(
493fa5e4d32SSunny Srivastava             constants::biosConfigMgrService, constants::biosConfigMgrObjPath,
494fa5e4d32SSunny Srivastava             constants::biosConfigMgrInterface, "PendingAttributes",
495c532b188SRekhaAparna01             l_pendingBiosAttribute))
496fa5e4d32SSunny Srivastava     {
497fa5e4d32SSunny Srivastava         logging::logMessage(
498c532b188SRekhaAparna01             "DBus call to update lpar value in pending attribute failed.");
499fa5e4d32SSunny Srivastava     }
500fa5e4d32SSunny Srivastava 
501fa5e4d32SSunny Srivastava     return;
502fa5e4d32SSunny Srivastava }
503fa5e4d32SSunny Srivastava 
processCreateDefaultLpar()504fa5e4d32SSunny Srivastava void IbmBiosHandler::processCreateDefaultLpar()
505fa5e4d32SSunny Srivastava {
506fa5e4d32SSunny Srivastava     // Read required keyword from DBus.
507fa5e4d32SSunny Srivastava     auto l_kwdValueVariant = dbusUtility::readDbusProperty(
508fa5e4d32SSunny Srivastava         constants::pimServiceName, constants::systemVpdInvPath,
509fa5e4d32SSunny Srivastava         constants::utilInf, constants::kwdClearNVRAM_CreateLPAR);
510fa5e4d32SSunny Srivastava 
511fa5e4d32SSunny Srivastava     if (auto l_pVal = std::get_if<types::BinaryVector>(&l_kwdValueVariant))
512fa5e4d32SSunny Srivastava     {
513fa5e4d32SSunny Srivastava         saveCreateDefaultLparToBios(std::to_string(l_pVal->at(0)));
514fa5e4d32SSunny Srivastava         return;
515fa5e4d32SSunny Srivastava     }
516fa5e4d32SSunny Srivastava     logging::logMessage(
517fa5e4d32SSunny Srivastava         "Invalid type recieved for create default Lpar from VPD.");
518fa5e4d32SSunny Srivastava }
519fa5e4d32SSunny Srivastava 
saveClearNvramToVpd(const std::string & i_clearNvramVal)520fa5e4d32SSunny Srivastava void IbmBiosHandler::saveClearNvramToVpd(const std::string& i_clearNvramVal)
521fa5e4d32SSunny Srivastava {
522fa5e4d32SSunny Srivastava     if (i_clearNvramVal.empty())
523fa5e4d32SSunny Srivastava     {
524fa5e4d32SSunny Srivastava         logging::logMessage(
525fa5e4d32SSunny Srivastava             "Empty value received for clear NVRAM from BIOS. Skip updating to VPD.");
526fa5e4d32SSunny Srivastava         return;
527fa5e4d32SSunny Srivastava     }
528fa5e4d32SSunny Srivastava 
529fa5e4d32SSunny Srivastava     // Read required keyword from DBus as we need to set only a Bit.
530fa5e4d32SSunny Srivastava     auto l_kwdValueVariant = dbusUtility::readDbusProperty(
531fa5e4d32SSunny Srivastava         constants::pimServiceName, constants::systemVpdInvPath,
532fa5e4d32SSunny Srivastava         constants::utilInf, constants::kwdClearNVRAM_CreateLPAR);
533fa5e4d32SSunny Srivastava 
534fa5e4d32SSunny Srivastava     if (auto l_pVal = std::get_if<types::BinaryVector>(&l_kwdValueVariant))
535fa5e4d32SSunny Srivastava     {
536fa5e4d32SSunny Srivastava         commonUtility::toLower(const_cast<std::string&>(i_clearNvramVal));
537fa5e4d32SSunny Srivastava 
538fa5e4d32SSunny Srivastava         // Check for third bit. Bit set for enabled else disabled.
539fa5e4d32SSunny Srivastava         if (((((*l_pVal).at(0) & 0x04) == 0x04) &&
540fa5e4d32SSunny Srivastava              (i_clearNvramVal.compare("enabled") ==
541fa5e4d32SSunny Srivastava               constants::STR_CMP_SUCCESS)) ||
542fa5e4d32SSunny Srivastava             ((((*l_pVal).at(0) & 0x04) == 0x00) &&
543fa5e4d32SSunny Srivastava              (i_clearNvramVal.compare("disabled") ==
544fa5e4d32SSunny Srivastava               constants::STR_CMP_SUCCESS)))
545fa5e4d32SSunny Srivastava         {
546fa5e4d32SSunny Srivastava             // Don't update, values are same.
547fa5e4d32SSunny Srivastava             return;
548fa5e4d32SSunny Srivastava         }
549fa5e4d32SSunny Srivastava 
550fa5e4d32SSunny Srivastava         types::BinaryVector l_valToUpdateInVpd;
551fa5e4d32SSunny Srivastava         if (i_clearNvramVal.compare("enabled") == constants::STR_CMP_SUCCESS)
552fa5e4d32SSunny Srivastava         {
553fa5e4d32SSunny Srivastava             // 3rd bit is used to store the value.
554fa5e4d32SSunny Srivastava             l_valToUpdateInVpd.emplace_back(
555fa5e4d32SSunny Srivastava                 (*l_pVal).at(0) | constants::VALUE_4);
556fa5e4d32SSunny Srivastava         }
557fa5e4d32SSunny Srivastava         else
558fa5e4d32SSunny Srivastava         {
559fa5e4d32SSunny Srivastava             // 3rd bit is used to store the value.
560fa5e4d32SSunny Srivastava             l_valToUpdateInVpd.emplace_back(
561fa5e4d32SSunny Srivastava                 (*l_pVal).at(0) & ~(constants::VALUE_4));
562fa5e4d32SSunny Srivastava         }
563fa5e4d32SSunny Srivastava 
564fa5e4d32SSunny Srivastava         if (-1 ==
565fa5e4d32SSunny Srivastava             m_manager->updateKeyword(
566fa5e4d32SSunny Srivastava                 SYSTEM_VPD_FILE_PATH,
567fa5e4d32SSunny Srivastava                 types::IpzData("UTIL", constants::kwdClearNVRAM_CreateLPAR,
568fa5e4d32SSunny Srivastava                                l_valToUpdateInVpd)))
569fa5e4d32SSunny Srivastava         {
570fa5e4d32SSunny Srivastava             logging::logMessage(
571fa5e4d32SSunny Srivastava                 "Failed to update " +
572fa5e4d32SSunny Srivastava                 std::string(constants::kwdClearNVRAM_CreateLPAR) +
573fa5e4d32SSunny Srivastava                 " keyword to VPD");
574fa5e4d32SSunny Srivastava         }
575fa5e4d32SSunny Srivastava 
576fa5e4d32SSunny Srivastava         return;
577fa5e4d32SSunny Srivastava     }
578fa5e4d32SSunny Srivastava     logging::logMessage("Invalid type recieved for clear NVRAM from VPD.");
579fa5e4d32SSunny Srivastava }
580fa5e4d32SSunny Srivastava 
saveClearNvramToBios(const std::string & i_clearNvramVal)581fa5e4d32SSunny Srivastava void IbmBiosHandler::saveClearNvramToBios(const std::string& i_clearNvramVal)
582fa5e4d32SSunny Srivastava {
583fa5e4d32SSunny Srivastava     // Check for the exact length as it is a string and it can have a garbage
584fa5e4d32SSunny Srivastava     // value.
585fa5e4d32SSunny Srivastava     if (i_clearNvramVal.size() != constants::VALUE_1)
586fa5e4d32SSunny Srivastava     {
587fa5e4d32SSunny Srivastava         logging::logMessage(
588fa5e4d32SSunny Srivastava             "Bad size for clear NVRAM in VPD. Skip writing to BIOS.");
589fa5e4d32SSunny Srivastava         return;
590fa5e4d32SSunny Srivastava     }
591fa5e4d32SSunny Srivastava 
592fa5e4d32SSunny Srivastava     // 3rd bit is used to store clear NVRAM value.
593fa5e4d32SSunny Srivastava     std::string l_valtoUpdate =
594fa5e4d32SSunny Srivastava         (i_clearNvramVal.at(0) & constants::VALUE_4) ? "Enabled" : "Disabled";
595fa5e4d32SSunny Srivastava 
596fa5e4d32SSunny Srivastava     types::PendingBIOSAttrs l_pendingBiosAttribute;
597fa5e4d32SSunny Srivastava     l_pendingBiosAttribute.push_back(std::make_pair(
598fa5e4d32SSunny Srivastava         "pvm_clear_nvram",
599fa5e4d32SSunny Srivastava         std::make_tuple(
600fa5e4d32SSunny Srivastava             "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Enumeration",
601fa5e4d32SSunny Srivastava             l_valtoUpdate)));
602fa5e4d32SSunny Srivastava 
603c532b188SRekhaAparna01     if (!dbusUtility::writeDbusProperty(
604fa5e4d32SSunny Srivastava             constants::biosConfigMgrService, constants::biosConfigMgrObjPath,
605fa5e4d32SSunny Srivastava             constants::biosConfigMgrInterface, "PendingAttributes",
606c532b188SRekhaAparna01             l_pendingBiosAttribute))
607fa5e4d32SSunny Srivastava     {
608fa5e4d32SSunny Srivastava         logging::logMessage(
609c532b188SRekhaAparna01             "DBus call to update NVRAM value in pending attribute failed.");
610fa5e4d32SSunny Srivastava     }
611fa5e4d32SSunny Srivastava }
612fa5e4d32SSunny Srivastava 
processClearNvram()613fa5e4d32SSunny Srivastava void IbmBiosHandler::processClearNvram()
614fa5e4d32SSunny Srivastava {
615fa5e4d32SSunny Srivastava     // Read required keyword from VPD.
616fa5e4d32SSunny Srivastava     auto l_kwdValueVariant = dbusUtility::readDbusProperty(
617fa5e4d32SSunny Srivastava         constants::pimServiceName, constants::systemVpdInvPath,
618fa5e4d32SSunny Srivastava         constants::utilInf, constants::kwdClearNVRAM_CreateLPAR);
619fa5e4d32SSunny Srivastava 
620fa5e4d32SSunny Srivastava     if (auto l_pVal = std::get_if<types::BinaryVector>(&l_kwdValueVariant))
621fa5e4d32SSunny Srivastava     {
622fa5e4d32SSunny Srivastava         saveClearNvramToBios(std::to_string(l_pVal->at(0)));
623fa5e4d32SSunny Srivastava         return;
624fa5e4d32SSunny Srivastava     }
625fa5e4d32SSunny Srivastava     logging::logMessage("Invalid type recieved for clear NVRAM from VPD.");
626fa5e4d32SSunny Srivastava }
627fa5e4d32SSunny Srivastava 
saveKeepAndClearToVpd(const std::string & i_KeepAndClearVal)628fa5e4d32SSunny Srivastava void IbmBiosHandler::saveKeepAndClearToVpd(const std::string& i_KeepAndClearVal)
629fa5e4d32SSunny Srivastava {
630fa5e4d32SSunny Srivastava     if (i_KeepAndClearVal.empty())
631fa5e4d32SSunny Srivastava     {
632fa5e4d32SSunny Srivastava         logging::logMessage(
633fa5e4d32SSunny Srivastava             "Empty value received for keep and clear from BIOS. Skip updating to VPD.");
634fa5e4d32SSunny Srivastava         return;
635fa5e4d32SSunny Srivastava     }
636fa5e4d32SSunny Srivastava 
637fa5e4d32SSunny Srivastava     // Read required keyword from DBus as we need to set only a Bit.
638fa5e4d32SSunny Srivastava     auto l_kwdValueVariant = dbusUtility::readDbusProperty(
639fa5e4d32SSunny Srivastava         constants::pimServiceName, constants::systemVpdInvPath,
640fa5e4d32SSunny Srivastava         constants::utilInf, constants::kwdKeepAndClear);
641fa5e4d32SSunny Srivastava 
642fa5e4d32SSunny Srivastava     if (auto l_pVal = std::get_if<types::BinaryVector>(&l_kwdValueVariant))
643fa5e4d32SSunny Srivastava     {
644fa5e4d32SSunny Srivastava         commonUtility::toLower(const_cast<std::string&>(i_KeepAndClearVal));
645fa5e4d32SSunny Srivastava 
646fa5e4d32SSunny Srivastava         // Check for first bit. Bit set for enabled else disabled.
647fa5e4d32SSunny Srivastava         if (((((*l_pVal).at(0) & 0x01) == 0x01) &&
648fa5e4d32SSunny Srivastava              (i_KeepAndClearVal.compare("enabled") ==
649fa5e4d32SSunny Srivastava               constants::STR_CMP_SUCCESS)) ||
650fa5e4d32SSunny Srivastava             ((((*l_pVal).at(0) & 0x01) == 0x00) &&
651fa5e4d32SSunny Srivastava              (i_KeepAndClearVal.compare("disabled") ==
652fa5e4d32SSunny Srivastava               constants::STR_CMP_SUCCESS)))
653fa5e4d32SSunny Srivastava         {
654fa5e4d32SSunny Srivastava             // Don't update, values are same.
655fa5e4d32SSunny Srivastava             return;
656fa5e4d32SSunny Srivastava         }
657fa5e4d32SSunny Srivastava 
658fa5e4d32SSunny Srivastava         types::BinaryVector l_valToUpdateInVpd;
659fa5e4d32SSunny Srivastava         if (i_KeepAndClearVal.compare("enabled") == constants::STR_CMP_SUCCESS)
660fa5e4d32SSunny Srivastava         {
661fa5e4d32SSunny Srivastava             // 1st bit is used to store the value.
662fa5e4d32SSunny Srivastava             l_valToUpdateInVpd.emplace_back(
663fa5e4d32SSunny Srivastava                 (*l_pVal).at(0) | constants::VALUE_1);
664fa5e4d32SSunny Srivastava         }
665fa5e4d32SSunny Srivastava         else
666fa5e4d32SSunny Srivastava         {
667fa5e4d32SSunny Srivastava             // 1st bit is used to store the value.
668fa5e4d32SSunny Srivastava             l_valToUpdateInVpd.emplace_back(
669fa5e4d32SSunny Srivastava                 (*l_pVal).at(0) & ~(constants::VALUE_1));
670fa5e4d32SSunny Srivastava         }
671fa5e4d32SSunny Srivastava 
672fa5e4d32SSunny Srivastava         if (-1 == m_manager->updateKeyword(
673fa5e4d32SSunny Srivastava                       SYSTEM_VPD_FILE_PATH,
674fa5e4d32SSunny Srivastava                       types::IpzData("UTIL", constants::kwdKeepAndClear,
675fa5e4d32SSunny Srivastava                                      l_valToUpdateInVpd)))
676fa5e4d32SSunny Srivastava         {
677fa5e4d32SSunny Srivastava             logging::logMessage(
678fa5e4d32SSunny Srivastava                 "Failed to update " + std::string(constants::kwdKeepAndClear) +
679fa5e4d32SSunny Srivastava                 " keyword to VPD");
680fa5e4d32SSunny Srivastava         }
681fa5e4d32SSunny Srivastava 
682fa5e4d32SSunny Srivastava         return;
683fa5e4d32SSunny Srivastava     }
684fa5e4d32SSunny Srivastava     logging::logMessage("Invalid type recieved for keep and clear from VPD.");
685fa5e4d32SSunny Srivastava }
686fa5e4d32SSunny Srivastava 
saveKeepAndClearToBios(const std::string & i_KeepAndClearVal)68743fedabcSPatrick Williams void IbmBiosHandler::saveKeepAndClearToBios(
68843fedabcSPatrick Williams     const std::string& i_KeepAndClearVal)
689fa5e4d32SSunny Srivastava {
690fa5e4d32SSunny Srivastava     // checking for exact length as it is a string and can have garbage value.
691fa5e4d32SSunny Srivastava     if (i_KeepAndClearVal.size() != constants::VALUE_1)
692fa5e4d32SSunny Srivastava     {
693fa5e4d32SSunny Srivastava         logging::logMessage(
694fa5e4d32SSunny Srivastava             "Bad size for keep and clear in VPD. Skip writing to BIOS.");
695fa5e4d32SSunny Srivastava         return;
696fa5e4d32SSunny Srivastava     }
697fa5e4d32SSunny Srivastava 
698fa5e4d32SSunny Srivastava     // 1st bit is used to store keep and clear value.
699fa5e4d32SSunny Srivastava     std::string l_valtoUpdate =
700fa5e4d32SSunny Srivastava         (i_KeepAndClearVal.at(0) & constants::VALUE_1) ? "Enabled" : "Disabled";
701fa5e4d32SSunny Srivastava 
702fa5e4d32SSunny Srivastava     types::PendingBIOSAttrs l_pendingBiosAttribute;
703fa5e4d32SSunny Srivastava     l_pendingBiosAttribute.push_back(std::make_pair(
704fa5e4d32SSunny Srivastava         "pvm_keep_and_clear",
705fa5e4d32SSunny Srivastava         std::make_tuple(
706fa5e4d32SSunny Srivastava             "xyz.openbmc_project.BIOSConfig.Manager.AttributeType.Enumeration",
707fa5e4d32SSunny Srivastava             l_valtoUpdate)));
708fa5e4d32SSunny Srivastava 
709c532b188SRekhaAparna01     if (!dbusUtility::writeDbusProperty(
710fa5e4d32SSunny Srivastava             constants::biosConfigMgrService, constants::biosConfigMgrObjPath,
711fa5e4d32SSunny Srivastava             constants::biosConfigMgrInterface, "PendingAttributes",
712c532b188SRekhaAparna01             l_pendingBiosAttribute))
713fa5e4d32SSunny Srivastava     {
714fa5e4d32SSunny Srivastava         logging::logMessage(
715c532b188SRekhaAparna01             "DBus call to update keep and clear value in pending attribute failed.");
716fa5e4d32SSunny Srivastava     }
717fa5e4d32SSunny Srivastava }
718fa5e4d32SSunny Srivastava 
processKeepAndClear()719fa5e4d32SSunny Srivastava void IbmBiosHandler::processKeepAndClear()
720fa5e4d32SSunny Srivastava {
721fa5e4d32SSunny Srivastava     // Read required keyword from VPD.
722fa5e4d32SSunny Srivastava     auto l_kwdValueVariant = dbusUtility::readDbusProperty(
723fa5e4d32SSunny Srivastava         constants::pimServiceName, constants::systemVpdInvPath,
724fa5e4d32SSunny Srivastava         constants::utilInf, constants::kwdKeepAndClear);
725fa5e4d32SSunny Srivastava 
726fa5e4d32SSunny Srivastava     if (auto l_pVal = std::get_if<types::BinaryVector>(&l_kwdValueVariant))
727fa5e4d32SSunny Srivastava     {
728fa5e4d32SSunny Srivastava         saveKeepAndClearToBios(std::to_string(l_pVal->at(0)));
729fa5e4d32SSunny Srivastava         return;
730fa5e4d32SSunny Srivastava     }
731fa5e4d32SSunny Srivastava     logging::logMessage("Invalid type recieved for keep and clear from VPD.");
732fa5e4d32SSunny Srivastava }
733fa5e4d32SSunny Srivastava } // namespace vpd
734