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