1d965934fSJohn Wang #pragma once 2d965934fSJohn Wang 3d965934fSJohn Wang #include "bios_attribute.hpp" 4d965934fSJohn Wang #include "bios_table.hpp" 52abbce76SAndrew Jeffery #include "common/instance_id.hpp" 611ce8d22SSagar Srinivas #include "oem_handler.hpp" 73c50c82aSKamalkumar Patel #include "platform_config.hpp" 8c0c79481SSampa Misra #include "requester/handler.hpp" 9d965934fSJohn Wang 10c453e164SGeorge Liu #include <libpldm/bios_table.h> 11c453e164SGeorge Liu 126492f524SGeorge Liu #include <nlohmann/json.hpp> 1349cfb138SRiya Dixit #include <phosphor-logging/lg2.hpp> 146492f524SGeorge Liu 15d965934fSJohn Wang #include <functional> 16d965934fSJohn Wang #include <iostream> 17d965934fSJohn Wang #include <memory> 18d965934fSJohn Wang #include <optional> 19d965934fSJohn Wang #include <set> 20d965934fSJohn Wang #include <string> 21d965934fSJohn Wang #include <vector> 22d965934fSJohn Wang 2349cfb138SRiya Dixit PHOSPHOR_LOG2_USING; 2449cfb138SRiya Dixit 25d965934fSJohn Wang namespace pldm 26d965934fSJohn Wang { 27d965934fSJohn Wang namespace responder 28d965934fSJohn Wang { 29d965934fSJohn Wang namespace bios 30d965934fSJohn Wang { 311b180d8aSGeorge Liu enum class BoundType 321b180d8aSGeorge Liu { 331b180d8aSGeorge Liu LowerBound, 341b180d8aSGeorge Liu UpperBound, 351b180d8aSGeorge Liu ScalarIncrement, 361b180d8aSGeorge Liu MinStringLength, 371b180d8aSGeorge Liu MaxStringLength, 381b180d8aSGeorge Liu OneOf 391b180d8aSGeorge Liu }; 401b180d8aSGeorge Liu 411b180d8aSGeorge Liu using AttributeName = std::string; 421b180d8aSGeorge Liu using AttributeType = std::string; 431b180d8aSGeorge Liu using ReadonlyStatus = bool; 441b180d8aSGeorge Liu using DisplayName = std::string; 451b180d8aSGeorge Liu using Description = std::string; 461b180d8aSGeorge Liu using MenuPath = std::string; 471b180d8aSGeorge Liu using CurrentValue = std::variant<int64_t, std::string>; 481b180d8aSGeorge Liu using DefaultValue = std::variant<int64_t, std::string>; 491b180d8aSGeorge Liu using OptionString = std::string; 501b180d8aSGeorge Liu using OptionValue = std::variant<int64_t, std::string>; 517927f90cSSagar Srinivas using ValueDisplayName = std::string; 527927f90cSSagar Srinivas using Option = 537927f90cSSagar Srinivas std::vector<std::tuple<OptionString, OptionValue, ValueDisplayName>>; 541b180d8aSGeorge Liu using BIOSTableObj = 551b180d8aSGeorge Liu std::tuple<AttributeType, ReadonlyStatus, DisplayName, Description, 561b180d8aSGeorge Liu MenuPath, CurrentValue, DefaultValue, Option>; 571b180d8aSGeorge Liu using BaseBIOSTable = std::map<AttributeName, BIOSTableObj>; 581b180d8aSGeorge Liu 591244acfdSGeorge Liu using PendingObj = std::tuple<AttributeType, CurrentValue>; 601244acfdSGeorge Liu using PendingAttributes = std::map<AttributeName, PendingObj>; 6162dd8ff2SArchana Kakani using Callback = std::function<void()>; 621244acfdSGeorge Liu 63d965934fSJohn Wang /** @class BIOSConfig 64d965934fSJohn Wang * @brief Manager BIOS Attributes 65d965934fSJohn Wang */ 66d965934fSJohn Wang class BIOSConfig 67d965934fSJohn Wang { 68d965934fSJohn Wang public: 69d965934fSJohn Wang BIOSConfig() = delete; 70d965934fSJohn Wang BIOSConfig(const BIOSConfig&) = delete; 71d965934fSJohn Wang BIOSConfig(BIOSConfig&&) = delete; 72d965934fSJohn Wang BIOSConfig& operator=(const BIOSConfig&) = delete; 73d965934fSJohn Wang BIOSConfig& operator=(BIOSConfig&&) = delete; 74d965934fSJohn Wang ~BIOSConfig() = default; 75d965934fSJohn Wang 76d965934fSJohn Wang /** @brief Construct BIOSConfig 77d965934fSJohn Wang * @param[in] jsonDir - The directory where json file exists 78d965934fSJohn Wang * @param[in] tableDir - The directory where the persistent table is placed 79d965934fSJohn Wang * @param[in] dbusHandler - Dbus Handler 807f839f9dSTom Joseph * @param[in] fd - socket descriptor to communicate to host 817f839f9dSTom Joseph * @param[in] eid - MCTP EID of host firmware 82a330b2f0SAndrew Jeffery * @param[in] instanceIdDb - pointer to an InstanceIdDb object 83c0c79481SSampa Misra * @param[in] handler - PLDM request handler 843c50c82aSKamalkumar Patel * @param[in] platformConfigHandler - pointer to platform config Handler 8562dd8ff2SArchana Kakani * @param[in] requestPLDMServiceName - Callback for claiming the PLDM 8662dd8ff2SArchana Kakani * service name Called only after building BIOS tables. 87d965934fSJohn Wang */ 88c0c79481SSampa Misra explicit BIOSConfig( 89c0c79481SSampa Misra const char* jsonDir, const char* tableDir, 905079ac4aSBrad Bishop pldm::utils::DBusHandler* const dbusHandler, int fd, uint8_t eid, 91a330b2f0SAndrew Jeffery pldm::InstanceIdDb* instanceIdDb, 9211ce8d22SSagar Srinivas pldm::requester::Handler<pldm::requester::Request>* handler, 9362dd8ff2SArchana Kakani pldm::responder::platform_config::Handler* platformConfigHandler, 9462dd8ff2SArchana Kakani pldm::responder::bios::Callback requestPLDMServiceName); 95d965934fSJohn Wang 96d965934fSJohn Wang /** @brief Set attribute value on dbus and attribute value table 97d965934fSJohn Wang * @param[in] entry - attribute value entry 98d965934fSJohn Wang * @param[in] size - size of the attribute value entry 99cac0ebb2SSagar Srinivas * @param[in] isBMC - indicates if the attribute is set by BMC 1006d6d1e8dSGeorge Liu * @param[in] updateDBus - update Attr value D-Bus property 1016d6d1e8dSGeorge Liu * if this is set to true 1027f839f9dSTom Joseph * @param[in] updateBaseBIOSTable - update BaseBIOSTable D-Bus property 1037f839f9dSTom Joseph * if this is set to true 104d965934fSJohn Wang * @return pldm_completion_codes 105d965934fSJohn Wang */ 106cac0ebb2SSagar Srinivas int setAttrValue(const void* entry, size_t size, bool isBMC, 107cac0ebb2SSagar Srinivas bool updateDBus = true, bool updateBaseBIOSTable = true); 108d965934fSJohn Wang 109d965934fSJohn Wang /** @brief Remove the persistent tables */ 110d965934fSJohn Wang void removeTables(); 111d965934fSJohn Wang 112d965934fSJohn Wang /** @brief Build bios tables(string,attribute,attribute value table)*/ 113d965934fSJohn Wang void buildTables(); 114d965934fSJohn Wang 115d965934fSJohn Wang /** @brief Get BIOS table of specified type 116d965934fSJohn Wang * @param[in] tableType - The table type 117d965934fSJohn Wang * @return The bios table, std::nullopt if the table is unaviliable 118d965934fSJohn Wang */ 119d965934fSJohn Wang std::optional<Table> getBIOSTable(pldm_bios_table_types tableType); 120d965934fSJohn Wang 1211b180d8aSGeorge Liu /** @brief set BIOS table 1221b180d8aSGeorge Liu * @param[in] tableType - Indicates what table is being transferred 1231b180d8aSGeorge Liu * {BIOSStringTable=0x0, BIOSAttributeTable=0x1, 1241b180d8aSGeorge Liu * BIOSAttributeValueTable=0x2} 1251b180d8aSGeorge Liu * @param[in] table - table data 1267f839f9dSTom Joseph * @param[in] updateBaseBIOSTable - update BaseBIOSTable D-Bus property 1277f839f9dSTom Joseph * if this is set to true 1281b180d8aSGeorge Liu * @return pldm_completion_codes 1291b180d8aSGeorge Liu */ 1307f839f9dSTom Joseph int setBIOSTable(uint8_t tableType, const Table& table, 1317f839f9dSTom Joseph bool updateBaseBIOSTable = true); 1321b180d8aSGeorge Liu 13362dd8ff2SArchana Kakani /** @brief Construct the BIOS Attributes and build the tables 13462dd8ff2SArchana Kakani * after receiving system type from entity manager. 13546f352edSArchana Kakani * Also register the Service Name only if 13646f352edSArchana Kakani * System specific Bios attributes are supported 13762dd8ff2SArchana Kakani * @param[in] String - System Type 13846f352edSArchana Kakani * @param[in] bool - flag to register service name 13962dd8ff2SArchana Kakani * @return void 14062dd8ff2SArchana Kakani */ 14146f352edSArchana Kakani void initBIOSAttributes(const std::string& sysType, bool registerService); 14262dd8ff2SArchana Kakani 143d965934fSJohn Wang private: 144ca7b2524STom Joseph /** @enum Index into the fields in the BaseBIOSTable 145ca7b2524STom Joseph */ 146ca7b2524STom Joseph enum class Index : uint8_t 147ca7b2524STom Joseph { 148ca7b2524STom Joseph attributeType = 0, 149ca7b2524STom Joseph readOnly, 150ca7b2524STom Joseph displayName, 151ca7b2524STom Joseph description, 152ca7b2524STom Joseph menuPath, 153ca7b2524STom Joseph currentValue, 154ca7b2524STom Joseph defaultValue, 155ca7b2524STom Joseph options, 156ca7b2524STom Joseph }; 157ca7b2524STom Joseph 158d965934fSJohn Wang const fs::path jsonDir; 159d965934fSJohn Wang const fs::path tableDir; 1605079ac4aSBrad Bishop pldm::utils::DBusHandler* const dbusHandler; 1611b180d8aSGeorge Liu BaseBIOSTable baseBIOSTableMaps; 162d965934fSJohn Wang 1637f839f9dSTom Joseph /** @brief socket descriptor to communicate to host */ 1647f839f9dSTom Joseph int fd; 1657f839f9dSTom Joseph 1667f839f9dSTom Joseph /** @brief MCTP EID of host firmware */ 1677f839f9dSTom Joseph uint8_t eid; 1687f839f9dSTom Joseph 169a330b2f0SAndrew Jeffery /** @brief pointer to an Instance ID database object, used to obtain PLDM 170a330b2f0SAndrew Jeffery * instance IDs. 1717f839f9dSTom Joseph */ 172a330b2f0SAndrew Jeffery pldm::InstanceIdDb* instanceIdDb; 1737f839f9dSTom Joseph 174c0c79481SSampa Misra /** @brief PLDM request handler */ 175c0c79481SSampa Misra pldm::requester::Handler<pldm::requester::Request>* handler; 176c0c79481SSampa Misra 1773c50c82aSKamalkumar Patel /** @brief platform config Handler*/ 1783c50c82aSKamalkumar Patel pldm::responder::platform_config::Handler* platformConfigHandler; 17911ce8d22SSagar Srinivas 18062dd8ff2SArchana Kakani /** @brief Callback for registering the PLDM service name */ 18162dd8ff2SArchana Kakani pldm::responder::bios::Callback requestPLDMServiceName; 18262dd8ff2SArchana Kakani 183d965934fSJohn Wang // vector persists all attributes 184d965934fSJohn Wang using BIOSAttributes = std::vector<std::unique_ptr<BIOSAttribute>>; 185d965934fSJohn Wang BIOSAttributes biosAttributes; 186d965934fSJohn Wang 18746ece063SSampa Misra using propName = std::string; 1885079ac4aSBrad Bishop using DbusChObjProperties = std::map<propName, pldm::utils::PropertyValue>; 18946ece063SSampa Misra 190d987c94cSMatt Spinler using ifaceName = std::string; 191d987c94cSMatt Spinler using DbusIfacesAdded = std::map<ifaceName, DbusChObjProperties>; 192d987c94cSMatt Spinler 19346ece063SSampa Misra // vector to catch the D-Bus property change signals for BIOS attributes 19484b790cbSPatrick Williams std::vector<std::unique_ptr<sdbusplus::bus::match_t>> biosAttrMatch; 19546ece063SSampa Misra 19611ce8d22SSagar Srinivas /** @brief system type/model */ 19711ce8d22SSagar Srinivas std::string sysType; 19811ce8d22SSagar Srinivas 19946ece063SSampa Misra /** @brief Method to update a BIOS attribute when the corresponding Dbus 20046ece063SSampa Misra * property is changed 20146ece063SSampa Misra * @param[in] chProperties - list of properties which have changed 20246ece063SSampa Misra * @param[in] biosAttrIndex - Index of BIOSAttribute pointer in 20346ece063SSampa Misra * biosAttributes 20446ece063SSampa Misra * @return - none 20546ece063SSampa Misra */ 20646ece063SSampa Misra void processBiosAttrChangeNotification( 20746ece063SSampa Misra const DbusChObjProperties& chProperties, uint32_t biosAttrIndex); 20846ece063SSampa Misra 20946f352edSArchana Kakani /** @brief Method is used to initiate bios attributes only if system type 21046f352edSArchana Kakani * is already populated by entity manager. 21146f352edSArchana Kakani * Register the callback if system type is yet to be populated by Entity 21246f352edSArchana Kakani * manager 21362dd8ff2SArchana Kakani */ 21446f352edSArchana Kakani void checkSystemTypeAvailability(); 21562dd8ff2SArchana Kakani 216d965934fSJohn Wang /** @brief Construct an attribute and persist it 217d965934fSJohn Wang * @tparam T - attribute type 218d965934fSJohn Wang * @param[in] entry - json entry 219d965934fSJohn Wang */ 220d965934fSJohn Wang template <typename T> 221d965934fSJohn Wang void constructAttribute(const Json& entry) 222d965934fSJohn Wang { 223d965934fSJohn Wang try 224d965934fSJohn Wang { 225d965934fSJohn Wang biosAttributes.push_back(std::make_unique<T>(entry, dbusHandler)); 22646ece063SSampa Misra auto biosAttrIndex = biosAttributes.size() - 1; 22746ece063SSampa Misra auto dBusMap = biosAttributes[biosAttrIndex]->getDBusMap(); 22846ece063SSampa Misra 22946ece063SSampa Misra if (dBusMap.has_value()) 23046ece063SSampa Misra { 23146ece063SSampa Misra using namespace sdbusplus::bus::match::rules; 23246ece063SSampa Misra biosAttrMatch.push_back( 23384b790cbSPatrick Williams std::make_unique<sdbusplus::bus::match_t>( 23446ece063SSampa Misra pldm::utils::DBusHandler::getBus(), 23546ece063SSampa Misra propertiesChanged(dBusMap->objectPath, 23646ece063SSampa Misra dBusMap->interface), 23784b790cbSPatrick Williams [this, biosAttrIndex](sdbusplus::message_t& msg) { 23846ece063SSampa Misra DbusChObjProperties props; 23946ece063SSampa Misra std::string iface; 24046ece063SSampa Misra msg.read(iface, props); 2416da4f91bSPatrick Williams processBiosAttrChangeNotification(props, biosAttrIndex); 24246ece063SSampa Misra })); 243d987c94cSMatt Spinler 244d987c94cSMatt Spinler biosAttrMatch.push_back( 245b90fb7fdSPatrick Williams std::make_unique<sdbusplus::bus::match_t>( 246d987c94cSMatt Spinler pldm::utils::DBusHandler::getBus(), 247d987c94cSMatt Spinler interfacesAdded() + argNpath(0, dBusMap->objectPath), 248d987c94cSMatt Spinler [this, biosAttrIndex, interface = dBusMap->interface]( 249b90fb7fdSPatrick Williams sdbusplus::message_t& msg) { 250d987c94cSMatt Spinler sdbusplus::message::object_path path; 251d987c94cSMatt Spinler DbusIfacesAdded interfaces; 252d987c94cSMatt Spinler 253d987c94cSMatt Spinler msg.read(path, interfaces); 254d987c94cSMatt Spinler auto ifaceIt = interfaces.find(interface); 255d987c94cSMatt Spinler if (ifaceIt != interfaces.end()) 256d987c94cSMatt Spinler { 2576da4f91bSPatrick Williams processBiosAttrChangeNotification(ifaceIt->second, 2586da4f91bSPatrick Williams biosAttrIndex); 259d987c94cSMatt Spinler } 260d987c94cSMatt Spinler })); 26146ece063SSampa Misra } 262d965934fSJohn Wang } 263d965934fSJohn Wang catch (const std::exception& e) 264d965934fSJohn Wang { 265*89644441SRiya Dixit error("Failed to construct an attribute, error - {ERROR}", "ERROR", 266*89644441SRiya Dixit e); 267d965934fSJohn Wang } 268d965934fSJohn Wang } 269d965934fSJohn Wang 270d965934fSJohn Wang /** Construct attributes and persist them */ 271d965934fSJohn Wang void constructAttributes(); 272d965934fSJohn Wang 273d965934fSJohn Wang using ParseHandler = std::function<void(const Json& entry)>; 274d965934fSJohn Wang 275d965934fSJohn Wang /** @brief Helper function to parse json 276d965934fSJohn Wang * @param[in] filePath - Path of json file 277d965934fSJohn Wang * @param[in] handler - Handler to process each entry in the json 278d965934fSJohn Wang */ 279d965934fSJohn Wang void load(const fs::path& filePath, ParseHandler handler); 280d965934fSJohn Wang 281d965934fSJohn Wang /** @brief Build String Table and persist it 282d965934fSJohn Wang * @return The built string table, std::nullopt if it fails. 283d965934fSJohn Wang */ 284d965934fSJohn Wang std::optional<Table> buildAndStoreStringTable(); 285d965934fSJohn Wang 286ca7b2524STom Joseph /** @brief Build attribute table and attribute value table and persist them 287ca7b2524STom Joseph * Read the BaseBIOSTable from the bios-settings-manager and update 288ca7b2524STom Joseph * attribute table and attribute value table. 289ca7b2524STom Joseph * 290d965934fSJohn Wang * @param[in] stringTable - The string Table 291d965934fSJohn Wang */ 292d965934fSJohn Wang void buildAndStoreAttrTables(const Table& stringTable); 293d965934fSJohn Wang 294d965934fSJohn Wang /** @brief Persist the table 295d965934fSJohn Wang * @param[in] path - Path to persist the table 296d965934fSJohn Wang * @param[in] table - The table 297d965934fSJohn Wang */ 298d965934fSJohn Wang void storeTable(const fs::path& path, const Table& table); 299d965934fSJohn Wang 300d965934fSJohn Wang /** @brief Load bios table to ram 301d965934fSJohn Wang * @param[in] path - Path of the table 302d965934fSJohn Wang * @return The table, std::nullopt if loading fails 303d965934fSJohn Wang */ 304d965934fSJohn Wang std::optional<Table> loadTable(const fs::path& path); 3058241b340SJohn Wang 306cac0ebb2SSagar Srinivas /** @brief Method to decode the attribute name from the string handle 307cac0ebb2SSagar Srinivas * 308cac0ebb2SSagar Srinivas * @param[in] stringEntry - string entry from string table 309cac0ebb2SSagar Srinivas * @return the decoded string 310cac0ebb2SSagar Srinivas */ 311cac0ebb2SSagar Srinivas std::string decodeStringFromStringEntry( 312cac0ebb2SSagar Srinivas const pldm_bios_string_table_entry* stringEntry); 313cac0ebb2SSagar Srinivas 314cac0ebb2SSagar Srinivas /** @brief Method to print the string Handle by passing the attribute Handle 315cac0ebb2SSagar Srinivas * of the bios attribute that got updated 316cac0ebb2SSagar Srinivas * 317cac0ebb2SSagar Srinivas * @param[in] handle - the Attribute handle of the bios attribute 318cac0ebb2SSagar Srinivas * @param[in] index - index to the possible value handles 319cac0ebb2SSagar Srinivas * @param[in] attrTable - the attribute table 320cac0ebb2SSagar Srinivas * @param[in] stringTable - the string table 321cac0ebb2SSagar Srinivas * @return string handle from the string table and decoded string to the 322cac0ebb2SSagar Srinivas * name handle 323cac0ebb2SSagar Srinivas */ 324cac0ebb2SSagar Srinivas std::string displayStringHandle(uint16_t handle, uint8_t index, 325cac0ebb2SSagar Srinivas const std::optional<Table>& attrTable, 326cac0ebb2SSagar Srinivas const std::optional<Table>& stringTable); 327cac0ebb2SSagar Srinivas 328cac0ebb2SSagar Srinivas /** @brief Method to trace the bios attribute which got changed 329cac0ebb2SSagar Srinivas * 330cac0ebb2SSagar Srinivas * @param[in] attrValueEntry - The attribute value entry to update 331cac0ebb2SSagar Srinivas * @param[in] attrEntry - The attribute table entry 332cac0ebb2SSagar Srinivas * @param[in] isBMC - indicates if the attribute is set by BMC 333cac0ebb2SSagar Srinivas */ 334cac0ebb2SSagar Srinivas void traceBIOSUpdate(const pldm_bios_attr_val_table_entry* attrValueEntry, 335cac0ebb2SSagar Srinivas const pldm_bios_attr_table_entry* attrEntry, 336cac0ebb2SSagar Srinivas bool isBMC); 337cac0ebb2SSagar Srinivas 3388241b340SJohn Wang /** @brief Check the attribute value to update 3398241b340SJohn Wang * @param[in] attrValueEntry - The attribute value entry to update 3408241b340SJohn Wang * @param[in] attrEntry - The attribute table entry 3418241b340SJohn Wang * @param[in] stringTable - The string table 3428241b340SJohn Wang * @return pldm_completion_codes 3438241b340SJohn Wang */ 3448241b340SJohn Wang int checkAttrValueToUpdate( 3458241b340SJohn Wang const pldm_bios_attr_val_table_entry* attrValueEntry, 3468241b340SJohn Wang const pldm_bios_attr_table_entry* attrEntry, Table& stringTable); 3471b180d8aSGeorge Liu 3481b180d8aSGeorge Liu /** @brief Check the attribute table 3491b180d8aSGeorge Liu * @param[in] table - The table 3501b180d8aSGeorge Liu * @return pldm_completion_codes 3511b180d8aSGeorge Liu */ 3521b180d8aSGeorge Liu int checkAttributeTable(const Table& table); 3531b180d8aSGeorge Liu 3541b180d8aSGeorge Liu /** @brief Check the attribute value table 3551b180d8aSGeorge Liu * @param[in] table - The table 3561b180d8aSGeorge Liu * @return pldm_completion_codes 3571b180d8aSGeorge Liu */ 3581b180d8aSGeorge Liu int checkAttributeValueTable(const Table& table); 3591b180d8aSGeorge Liu 3601b180d8aSGeorge Liu /** @brief Update the BaseBIOSTable property of the D-Bus interface 3611b180d8aSGeorge Liu */ 3621b180d8aSGeorge Liu void updateBaseBIOSTableProperty(); 3631244acfdSGeorge Liu 3641244acfdSGeorge Liu /** @brief Listen the PendingAttributes property of the D-Bus interface and 3651244acfdSGeorge Liu * update BaseBIOSTable 3661244acfdSGeorge Liu */ 3671244acfdSGeorge Liu void listenPendingAttributes(); 3681244acfdSGeorge Liu 3691244acfdSGeorge Liu /** @brief Find attribute handle from bios attribute table 3701244acfdSGeorge Liu * @param[in] attrName - attribute name 3711244acfdSGeorge Liu * @return attribute handle 3721244acfdSGeorge Liu */ 3731244acfdSGeorge Liu uint16_t findAttrHandle(const std::string& attrName); 3741244acfdSGeorge Liu 3751244acfdSGeorge Liu /** @brief Listen the PendingAttributes property of the D-Bus interface 3761244acfdSGeorge Liu * and update BaseBIOSTable 3771244acfdSGeorge Liu * @param[in] msg - Data associated with subscribed signal 3781244acfdSGeorge Liu */ 3791244acfdSGeorge Liu void constructPendingAttribute(const PendingAttributes& pendingAttributes); 380d965934fSJohn Wang }; 381d965934fSJohn Wang 382d965934fSJohn Wang } // namespace bios 383d965934fSJohn Wang } // namespace responder 384d965934fSJohn Wang } // namespace pldm 385