xref: /openbmc/openpower-vpd-parser/vpd-manager/include/bios_handler.hpp (revision bd9dc3f1c9fd82f60b8746530a5ce8e266ac9249)
1 #pragma once
2 #include "logger.hpp"
3 #include "manager.hpp"
4 #include "types.hpp"
5 
6 #include <sdbusplus/asio/connection.hpp>
7 #include <sdbusplus/bus.hpp>
8 
9 namespace vpd
10 {
11 
12 /**
13  * @brief Interface class for BIOS handling.
14  *
15  * The class layout has the virtual methods required to be implemented by any
16  * concrete class that intends to use the feature provided via BIOS handler
17  * class.
18  */
19 class BiosHandlerInterface
20 {
21   public:
22     /**
23      * @brief API to back up or restore BIOS attributes.
24      *
25      * Concrete class should implement the API and read the backed up data from
26      * its designated location and take a call if it should be backed up or
27      * restored.
28      */
29     virtual void backUpOrRestoreBiosAttributes() = 0;
30 
31     /**
32      * @brief Callback API to be triggered on BIOS attribute change.
33      *
34      * Concrete class should implement the API to extract the attribute and its
35      * value from DBus message broadcasted on BIOS attribute change.
36      * The definition should be overridden in concrete class to deal with BIOS
37      * attributes interested in.
38      *
39      * @param[in] i_msg - The callback message.
40      */
41     virtual void biosAttributesCallback(sdbusplus::message_t& i_msg) = 0;
42 };
43 
44 /**
45  * @brief IBM specifc BIOS handler class.
46  */
47 class IbmBiosHandler : public BiosHandlerInterface
48 {
49   public:
50     /**
51      * @brief Construct a new IBM BIOS Handler object
52      *
53      * This constructor constructs a new IBM BIOS Handler object
54      * @param[in] i_manager - Manager object.
55      */
56     explicit IbmBiosHandler(const std::shared_ptr<Manager>& i_manager);
57 
58     /**
59      * @brief API to back up or restore BIOS attributes.
60      *
61      * The API will read the backed up data from the VPD keyword and based on
62      * its value, either backs up or restores the data.
63      */
64     virtual void backUpOrRestoreBiosAttributes();
65 
66     /**
67      * @brief Callback API to be triggered on BIOS attribute change.
68      *
69      * The API to extract the required attribute and its value from DBus message
70      * broadcasted on BIOS attribute change.
71      *
72      * @param[in] i_msg - The callback message.
73      */
74     virtual void biosAttributesCallback(sdbusplus::message_t& i_msg);
75 
76   private:
77     /**
78      * @brief API to read given attribute from BIOS table.
79      *
80      * @param[in] attributeName - Attribute to be read.
81      * @return - Bios attribute current value.
82      */
83     types::BiosAttributeCurrentValue readBiosAttribute(
84         const std::string& attributeName);
85 
86     /**
87      * @brief API to process "hb_field_core_override" attribute.
88      *
89      * The API checks value stored in VPD. If found default then the BIOS value
90      * is saved to VPD else VPD value is restored in BIOS pending attribute
91      * table.
92      *
93      * @param[in] i_attributeData - JSON object containing the VPD record and
94      * keyword mapping for FCO attribute.
95      *
96      */
97     void processFieldCoreOverride(const nlohmann::json& i_attributeData);
98 
99     /**
100      * @brief API to save FCO data into VPD.
101      *
102      * @param[in] i_fcoInBios - FCO value.
103      * @param[in] i_attributeData - JSON object containing the VPD record and
104      * keyword mapping for FCO attribute.
105      */
106     void saveFcoToVpd(int64_t i_fcoInBios,
107                       const nlohmann::json& i_attributeData);
108 
109     /**
110      * @brief API to save given value to "hb_field_core_override" attribute.
111      *
112      * @param[in] i_fcoVal - FCO value.
113      */
114     void saveFcoToBios(const types::BinaryVector& i_fcoVal);
115 
116     /**
117      * @brief API to save AMM data into VPD.
118      *
119      * @param[in] i_memoryMirrorMode - Memory mirror mode value.
120      * @param[in] i_attributeData - JSON object containing the VPD record and
121      * keyword mapping for AMM attribute.
122      *
123      */
124     void saveAmmToVpd(const std::string& i_memoryMirrorMode,
125                       const nlohmann::json& i_attributeData);
126 
127     /**
128      * @brief API to save given value to "hb_memory_mirror_mode" attribute.
129      *
130      * @param[in] i_ammVal - AMM value.
131      */
132     void saveAmmToBios(const uint8_t& i_ammVal);
133 
134     /**
135      * @brief API to process "hb_memory_mirror_mode" attribute.
136      *
137      * The API checks value stored in VPD. If found default then the BIOS value
138      * is saved to VPD else VPD value is restored in BIOS pending attribute
139      * table.
140      *
141      * @param[in] i_attributeData - JSON object containing the VPD record and
142      * keyword mapping for "hb_memory_mirror_mode" attribute.
143      *
144      */
145     void processActiveMemoryMirror(const nlohmann::json& i_attributeData);
146 
147     /**
148      * @brief API to process "pvm_create_default_lpar" attribute.
149      *
150      * The API reads the value from VPD and restore it to the BIOS attribute
151      * in BIOS pending attribute table.
152      *
153      * @param[in] i_attributeData - JSON object containing the VPD record and
154      * keyword mapping for "pvm_create_default_lpar" attribute.
155      */
156     void processCreateDefaultLpar(const nlohmann::json& i_attributeData);
157 
158     /**
159      * @brief API to save given value to "pvm_create_default_lpar" attribute.
160      *
161      * @param[in] i_createDefaultLparVal - Value to be saved;
162      */
163     void saveCreateDefaultLparToBios(const std::string& i_createDefaultLparVal);
164 
165     /**
166      * @brief API to save given value to VPD.
167      *
168      * @param[in] i_createDefaultLparVal - Value to be saved.
169      * @param[in] i_attributeData - JSON object containing the VPD record and
170      * keyword mapping for "pvm_create_default_lpar" attribute.
171      *
172      */
173     void saveCreateDefaultLparToVpd(const std::string& i_createDefaultLparVal,
174                                     const nlohmann::json& i_attributeData);
175 
176     /**
177      * @brief API to process "pvm_clear_nvram" attribute.
178      *
179      * The API reads the value from VPD and restores it to the BIOS pending
180      * attribute table.
181      *
182      * @param[in] i_attributeData - JSON object containing the VPD record and
183      * keyword mapping for "pvm_clear_nvram" attribute.
184      *
185      */
186     void processClearNvram(const nlohmann::json& i_attributeData);
187 
188     /**
189      * @brief API to save given value to "pvm_clear_nvram" attribute.
190      *
191      * @param[in] i_clearNvramVal - Value to be saved.
192      */
193     void saveClearNvramToBios(const std::string& i_clearNvramVal);
194 
195     /**
196      * @brief API to save given value to VPD.
197      *
198      * @param[in] i_clearNvramVal - Value to be saved.
199      * @param[in] i_attributeData - JSON object containing the VPD record and
200      * keyword mapping for "pvm_clear_nvram" attribute.
201      */
202     void saveClearNvramToVpd(const std::string& i_clearNvramVal,
203                              const nlohmann::json& i_attributeData);
204 
205     /**
206      * @brief API to process "pvm_keep_and_clear" attribute.
207      *
208      * The API reads the value from VPD and restore it to the BIOS pending
209      * attribute table.
210      *
211      * @param[in] i_attributeData - JSON object containing the VPD record and
212      * keyword mapping for "pvm_keep_and_clear" attribute.
213      *
214      */
215     void processKeepAndClear(const nlohmann::json& i_attributeData);
216 
217     /**
218      * @brief API to save given value to "pvm_keep_and_clear" attribute.
219      *
220      * @param[in] i_KeepAndClearVal - Value to be saved.
221      */
222     void saveKeepAndClearToBios(const std::string& i_KeepAndClearVal);
223 
224     /**
225      * @brief API to save given value to VPD.
226      *
227      * @param[in] i_KeepAndClearVal - Value to be saved.
228      *  @param[in] i_attributeData - JSON object containing the VPD record and
229      * keyword mapping for "pvm_keep_and_clear" attribute.
230      */
231     void saveKeepAndClearToVpd(const std::string& i_KeepAndClearVal,
232                                const nlohmann::json& i_attributeData);
233 
234     // const reference to shared pointer to Manager object.
235     const std::shared_ptr<Manager>& m_manager;
236 
237     // Shared pointer to Logger object
238     std::shared_ptr<Logger> m_logger;
239 
240     // Bios config json object
241     nlohmann::json m_biosConfigJson{};
242 };
243 
244 /**
245  * @brief A class to operate upon BIOS attributes.
246  *
247  * The class along with specific BIOS handler class(es), provides a feature
248  * where specific BIOS attributes identified by the concrete specific class can
249  * be listened for any change and can be backed up to a desired location or
250  * restored back to the BIOS table.
251  *
252  * To use the feature, "BiosHandlerInterface" should be implemented by a
253  * concrete class and the same should be used to instantiate BiosHandler.
254  *
255  * This class registers call back to listen to PLDM service as it is being used
256  * for reading/writing BIOS attributes.
257  *
258  * The feature can be used in a factory reset scenario where backed up values
259  * can be used to restore BIOS.
260  *
261  */
262 template <typename T>
263 class BiosHandler
264 {
265   public:
266     // deleted APIs
267     BiosHandler() = delete;
268     BiosHandler(const BiosHandler&) = delete;
269     BiosHandler& operator=(const BiosHandler&) = delete;
270     BiosHandler& operator=(BiosHandler&&) = delete;
271     ~BiosHandler() = default;
272 
273     /**
274      * @brief Constructor.
275      *
276      * @param[in] i_connection - Asio connection object.
277      * @param[in] i_manager - Manager object.
278      */
BiosHandler(const std::shared_ptr<sdbusplus::asio::connection> & i_connection,const std::shared_ptr<Manager> & i_manager)279     BiosHandler(
280         const std::shared_ptr<sdbusplus::asio::connection>& i_connection,
281         const std::shared_ptr<Manager>& i_manager) : m_asioConn(i_connection)
282     {
283         try
284         {
285             m_specificBiosHandler = std::make_shared<T>(i_manager);
286             checkAndListenPldmService();
287         }
288         catch (std::exception& l_ex)
289         {
290             // catch any exception here itself and don't pass it to main as it
291             // will mark the service failed. Since VPD-Manager is a critical
292             // service, failing it can push BMC to quiesced state whic is not
293             // required in this case.
294             std::string l_errMsg = "Instantiation of BIOS Handler failed. { ";
295             l_errMsg += l_ex.what() + std::string(" }");
296             EventLogger::createSyncPel(
297                 types::ErrorType::FirmwareError, types::SeverityType::Warning,
298                 __FILE__, __FUNCTION__, 0, l_errMsg, std::nullopt, std::nullopt,
299                 std::nullopt, std::nullopt);
300         }
301     }
302 
303   private:
304     /**
305      * @brief API to check if PLDM service is running and run BIOS sync.
306      *
307      * This API checks if the PLDM service is running and if yes it will start
308      * an immediate sync of BIOS attributes. If the service is not running, it
309      * registers a listener to be notified when the service starts so that a
310      * restore can be performed.
311      */
312     void checkAndListenPldmService();
313 
314     /**
315      * @brief Register listener for BIOS attribute property change.
316      *
317      * The VPD manager needs to listen for property change of certain BIOS
318      * attributes that are backed in VPD. When the attributes change, the new
319      * value is written back to the VPD keywords that backs them up.
320      */
321     void listenBiosAttributes();
322 
323     // Reference to the connection.
324     const std::shared_ptr<sdbusplus::asio::connection>& m_asioConn;
325 
326     // shared pointer to specific BIOS handler.
327     std::shared_ptr<T> m_specificBiosHandler;
328 };
329 } // namespace vpd
330