1d965934fSJohn Wang #pragma once 2d965934fSJohn Wang 3d965934fSJohn Wang #include "bios_attribute.hpp" 4d965934fSJohn Wang #include "bios_table.hpp" 57f839f9dSTom Joseph #include "pldmd/dbus_impl_requester.hpp" 6c0c79481SSampa Misra #include "requester/handler.hpp" 7d965934fSJohn Wang 8c453e164SGeorge Liu #include <libpldm/bios_table.h> 9c453e164SGeorge Liu 106492f524SGeorge Liu #include <nlohmann/json.hpp> 1149cfb138SRiya Dixit #include <phosphor-logging/lg2.hpp> 126492f524SGeorge Liu 13d965934fSJohn Wang #include <functional> 14d965934fSJohn Wang #include <iostream> 15d965934fSJohn Wang #include <memory> 16d965934fSJohn Wang #include <optional> 17d965934fSJohn Wang #include <set> 18d965934fSJohn Wang #include <string> 19d965934fSJohn Wang #include <vector> 20d965934fSJohn Wang 2149cfb138SRiya Dixit PHOSPHOR_LOG2_USING; 2249cfb138SRiya Dixit 23d965934fSJohn Wang namespace pldm 24d965934fSJohn Wang { 25d965934fSJohn Wang namespace responder 26d965934fSJohn Wang { 27d965934fSJohn Wang namespace bios 28d965934fSJohn Wang { 291b180d8aSGeorge Liu enum class BoundType 301b180d8aSGeorge Liu { 311b180d8aSGeorge Liu LowerBound, 321b180d8aSGeorge Liu UpperBound, 331b180d8aSGeorge Liu ScalarIncrement, 341b180d8aSGeorge Liu MinStringLength, 351b180d8aSGeorge Liu MaxStringLength, 361b180d8aSGeorge Liu OneOf 371b180d8aSGeorge Liu }; 381b180d8aSGeorge Liu 391b180d8aSGeorge Liu using AttributeName = std::string; 401b180d8aSGeorge Liu using AttributeType = std::string; 411b180d8aSGeorge Liu using ReadonlyStatus = bool; 421b180d8aSGeorge Liu using DisplayName = std::string; 431b180d8aSGeorge Liu using Description = std::string; 441b180d8aSGeorge Liu using MenuPath = std::string; 451b180d8aSGeorge Liu using CurrentValue = std::variant<int64_t, std::string>; 461b180d8aSGeorge Liu using DefaultValue = std::variant<int64_t, std::string>; 471b180d8aSGeorge Liu using OptionString = std::string; 481b180d8aSGeorge Liu using OptionValue = std::variant<int64_t, std::string>; 491b180d8aSGeorge Liu using Option = std::vector<std::tuple<OptionString, OptionValue>>; 501b180d8aSGeorge Liu using BIOSTableObj = 511b180d8aSGeorge Liu std::tuple<AttributeType, ReadonlyStatus, DisplayName, Description, 521b180d8aSGeorge Liu MenuPath, CurrentValue, DefaultValue, Option>; 531b180d8aSGeorge Liu using BaseBIOSTable = std::map<AttributeName, BIOSTableObj>; 541b180d8aSGeorge Liu 551244acfdSGeorge Liu using PendingObj = std::tuple<AttributeType, CurrentValue>; 561244acfdSGeorge Liu using PendingAttributes = std::map<AttributeName, PendingObj>; 571244acfdSGeorge Liu 58d965934fSJohn Wang /** @class BIOSConfig 59d965934fSJohn Wang * @brief Manager BIOS Attributes 60d965934fSJohn Wang */ 61d965934fSJohn Wang class BIOSConfig 62d965934fSJohn Wang { 63d965934fSJohn Wang public: 64d965934fSJohn Wang BIOSConfig() = delete; 65d965934fSJohn Wang BIOSConfig(const BIOSConfig&) = delete; 66d965934fSJohn Wang BIOSConfig(BIOSConfig&&) = delete; 67d965934fSJohn Wang BIOSConfig& operator=(const BIOSConfig&) = delete; 68d965934fSJohn Wang BIOSConfig& operator=(BIOSConfig&&) = delete; 69d965934fSJohn Wang ~BIOSConfig() = default; 70d965934fSJohn Wang 71d965934fSJohn Wang /** @brief Construct BIOSConfig 72d965934fSJohn Wang * @param[in] jsonDir - The directory where json file exists 73d965934fSJohn Wang * @param[in] tableDir - The directory where the persistent table is placed 74d965934fSJohn Wang * @param[in] dbusHandler - Dbus Handler 757f839f9dSTom Joseph * @param[in] fd - socket descriptor to communicate to host 767f839f9dSTom Joseph * @param[in] eid - MCTP EID of host firmware 777f839f9dSTom Joseph * @param[in] requester - pointer to Requester object 78c0c79481SSampa Misra * @param[in] handler - PLDM request handler 79d965934fSJohn Wang */ 80c0c79481SSampa Misra explicit BIOSConfig( 81c0c79481SSampa Misra const char* jsonDir, const char* tableDir, 825079ac4aSBrad Bishop pldm::utils::DBusHandler* const dbusHandler, int fd, uint8_t eid, 83c0c79481SSampa Misra dbus_api::Requester* requester, 84c0c79481SSampa Misra pldm::requester::Handler<pldm::requester::Request>* handler); 85d965934fSJohn Wang 86d965934fSJohn Wang /** @brief Set attribute value on dbus and attribute value table 87d965934fSJohn Wang * @param[in] entry - attribute value entry 88d965934fSJohn Wang * @param[in] size - size of the attribute value entry 89cac0ebb2SSagar Srinivas * @param[in] isBMC - indicates if the attribute is set by BMC 906d6d1e8dSGeorge Liu * @param[in] updateDBus - update Attr value D-Bus property 916d6d1e8dSGeorge Liu * if this is set to true 927f839f9dSTom Joseph * @param[in] updateBaseBIOSTable - update BaseBIOSTable D-Bus property 937f839f9dSTom Joseph * if this is set to true 94d965934fSJohn Wang * @return pldm_completion_codes 95d965934fSJohn Wang */ 96cac0ebb2SSagar Srinivas int setAttrValue(const void* entry, size_t size, bool isBMC, 97cac0ebb2SSagar Srinivas bool updateDBus = true, bool updateBaseBIOSTable = true); 98d965934fSJohn Wang 99d965934fSJohn Wang /** @brief Remove the persistent tables */ 100d965934fSJohn Wang void removeTables(); 101d965934fSJohn Wang 102d965934fSJohn Wang /** @brief Build bios tables(string,attribute,attribute value table)*/ 103d965934fSJohn Wang void buildTables(); 104d965934fSJohn Wang 105d965934fSJohn Wang /** @brief Get BIOS table of specified type 106d965934fSJohn Wang * @param[in] tableType - The table type 107d965934fSJohn Wang * @return The bios table, std::nullopt if the table is unaviliable 108d965934fSJohn Wang */ 109d965934fSJohn Wang std::optional<Table> getBIOSTable(pldm_bios_table_types tableType); 110d965934fSJohn Wang 1111b180d8aSGeorge Liu /** @brief set BIOS table 1121b180d8aSGeorge Liu * @param[in] tableType - Indicates what table is being transferred 1131b180d8aSGeorge Liu * {BIOSStringTable=0x0, BIOSAttributeTable=0x1, 1141b180d8aSGeorge Liu * BIOSAttributeValueTable=0x2} 1151b180d8aSGeorge Liu * @param[in] table - table data 1167f839f9dSTom Joseph * @param[in] updateBaseBIOSTable - update BaseBIOSTable D-Bus property 1177f839f9dSTom Joseph * if this is set to true 1181b180d8aSGeorge Liu * @return pldm_completion_codes 1191b180d8aSGeorge Liu */ 1207f839f9dSTom Joseph int setBIOSTable(uint8_t tableType, const Table& table, 1217f839f9dSTom Joseph bool updateBaseBIOSTable = true); 1221b180d8aSGeorge Liu 123d965934fSJohn Wang private: 124ca7b2524STom Joseph /** @enum Index into the fields in the BaseBIOSTable 125ca7b2524STom Joseph */ 126ca7b2524STom Joseph enum class Index : uint8_t 127ca7b2524STom Joseph { 128ca7b2524STom Joseph attributeType = 0, 129ca7b2524STom Joseph readOnly, 130ca7b2524STom Joseph displayName, 131ca7b2524STom Joseph description, 132ca7b2524STom Joseph menuPath, 133ca7b2524STom Joseph currentValue, 134ca7b2524STom Joseph defaultValue, 135ca7b2524STom Joseph options, 136ca7b2524STom Joseph }; 137ca7b2524STom Joseph 138d965934fSJohn Wang const fs::path jsonDir; 139d965934fSJohn Wang const fs::path tableDir; 1405079ac4aSBrad Bishop pldm::utils::DBusHandler* const dbusHandler; 1411b180d8aSGeorge Liu BaseBIOSTable baseBIOSTableMaps; 142d965934fSJohn Wang 1437f839f9dSTom Joseph /** @brief socket descriptor to communicate to host */ 1447f839f9dSTom Joseph int fd; 1457f839f9dSTom Joseph 1467f839f9dSTom Joseph /** @brief MCTP EID of host firmware */ 1477f839f9dSTom Joseph uint8_t eid; 1487f839f9dSTom Joseph 1497f839f9dSTom Joseph /** @brief pointer to Requester object, primarily used to access API to 1507f839f9dSTom Joseph * obtain PLDM instance id. 1517f839f9dSTom Joseph */ 1527f839f9dSTom Joseph dbus_api::Requester* requester; 1537f839f9dSTom Joseph 154c0c79481SSampa Misra /** @brief PLDM request handler */ 155c0c79481SSampa Misra pldm::requester::Handler<pldm::requester::Request>* handler; 156c0c79481SSampa Misra 157d965934fSJohn Wang // vector persists all attributes 158d965934fSJohn Wang using BIOSAttributes = std::vector<std::unique_ptr<BIOSAttribute>>; 159d965934fSJohn Wang BIOSAttributes biosAttributes; 160d965934fSJohn Wang 16146ece063SSampa Misra using propName = std::string; 1625079ac4aSBrad Bishop using DbusChObjProperties = std::map<propName, pldm::utils::PropertyValue>; 16346ece063SSampa Misra 164d987c94cSMatt Spinler using ifaceName = std::string; 165d987c94cSMatt Spinler using DbusIfacesAdded = std::map<ifaceName, DbusChObjProperties>; 166d987c94cSMatt Spinler 16746ece063SSampa Misra // vector to catch the D-Bus property change signals for BIOS attributes 16884b790cbSPatrick Williams std::vector<std::unique_ptr<sdbusplus::bus::match_t>> biosAttrMatch; 16946ece063SSampa Misra 17046ece063SSampa Misra /** @brief Method to update a BIOS attribute when the corresponding Dbus 17146ece063SSampa Misra * property is changed 17246ece063SSampa Misra * @param[in] chProperties - list of properties which have changed 17346ece063SSampa Misra * @param[in] biosAttrIndex - Index of BIOSAttribute pointer in 17446ece063SSampa Misra * biosAttributes 17546ece063SSampa Misra * @return - none 17646ece063SSampa Misra */ 17746ece063SSampa Misra void processBiosAttrChangeNotification( 17846ece063SSampa Misra const DbusChObjProperties& chProperties, uint32_t biosAttrIndex); 17946ece063SSampa Misra 180d965934fSJohn Wang /** @brief Construct an attribute and persist it 181d965934fSJohn Wang * @tparam T - attribute type 182d965934fSJohn Wang * @param[in] entry - json entry 183d965934fSJohn Wang */ 184d965934fSJohn Wang template <typename T> 185d965934fSJohn Wang void constructAttribute(const Json& entry) 186d965934fSJohn Wang { 187d965934fSJohn Wang try 188d965934fSJohn Wang { 189d965934fSJohn Wang biosAttributes.push_back(std::make_unique<T>(entry, dbusHandler)); 19046ece063SSampa Misra auto biosAttrIndex = biosAttributes.size() - 1; 19146ece063SSampa Misra auto dBusMap = biosAttributes[biosAttrIndex]->getDBusMap(); 19246ece063SSampa Misra 19346ece063SSampa Misra if (dBusMap.has_value()) 19446ece063SSampa Misra { 19546ece063SSampa Misra using namespace sdbusplus::bus::match::rules; 19646ece063SSampa Misra biosAttrMatch.push_back( 19784b790cbSPatrick Williams std::make_unique<sdbusplus::bus::match_t>( 19846ece063SSampa Misra pldm::utils::DBusHandler::getBus(), 19946ece063SSampa Misra propertiesChanged(dBusMap->objectPath, 20046ece063SSampa Misra dBusMap->interface), 20184b790cbSPatrick Williams [this, biosAttrIndex](sdbusplus::message_t& msg) { 20246ece063SSampa Misra DbusChObjProperties props; 20346ece063SSampa Misra std::string iface; 20446ece063SSampa Misra msg.read(iface, props); 205*6da4f91bSPatrick Williams processBiosAttrChangeNotification(props, biosAttrIndex); 20646ece063SSampa Misra })); 207d987c94cSMatt Spinler 208d987c94cSMatt Spinler biosAttrMatch.push_back( 209b90fb7fdSPatrick Williams std::make_unique<sdbusplus::bus::match_t>( 210d987c94cSMatt Spinler pldm::utils::DBusHandler::getBus(), 211d987c94cSMatt Spinler interfacesAdded() + argNpath(0, dBusMap->objectPath), 212d987c94cSMatt Spinler [this, biosAttrIndex, interface = dBusMap->interface]( 213b90fb7fdSPatrick Williams sdbusplus::message_t& msg) { 214d987c94cSMatt Spinler sdbusplus::message::object_path path; 215d987c94cSMatt Spinler DbusIfacesAdded interfaces; 216d987c94cSMatt Spinler 217d987c94cSMatt Spinler msg.read(path, interfaces); 218d987c94cSMatt Spinler auto ifaceIt = interfaces.find(interface); 219d987c94cSMatt Spinler if (ifaceIt != interfaces.end()) 220d987c94cSMatt Spinler { 221*6da4f91bSPatrick Williams processBiosAttrChangeNotification(ifaceIt->second, 222*6da4f91bSPatrick Williams biosAttrIndex); 223d987c94cSMatt Spinler } 224d987c94cSMatt Spinler })); 22546ece063SSampa Misra } 226d965934fSJohn Wang } 227d965934fSJohn Wang catch (const std::exception& e) 228d965934fSJohn Wang { 22949cfb138SRiya Dixit error("Constructs Attribute Error, {ERR_EXCEP}", "ERR_EXCEP", 23049cfb138SRiya Dixit e.what()); 231d965934fSJohn Wang } 232d965934fSJohn Wang } 233d965934fSJohn Wang 234d965934fSJohn Wang /** Construct attributes and persist them */ 235d965934fSJohn Wang void constructAttributes(); 236d965934fSJohn Wang 237d965934fSJohn Wang using ParseHandler = std::function<void(const Json& entry)>; 238d965934fSJohn Wang 239d965934fSJohn Wang /** @brief Helper function to parse json 240d965934fSJohn Wang * @param[in] filePath - Path of json file 241d965934fSJohn Wang * @param[in] handler - Handler to process each entry in the json 242d965934fSJohn Wang */ 243d965934fSJohn Wang void load(const fs::path& filePath, ParseHandler handler); 244d965934fSJohn Wang 245d965934fSJohn Wang /** @brief Build String Table and persist it 246d965934fSJohn Wang * @return The built string table, std::nullopt if it fails. 247d965934fSJohn Wang */ 248d965934fSJohn Wang std::optional<Table> buildAndStoreStringTable(); 249d965934fSJohn Wang 250ca7b2524STom Joseph /** @brief Build attribute table and attribute value table and persist them 251ca7b2524STom Joseph * Read the BaseBIOSTable from the bios-settings-manager and update 252ca7b2524STom Joseph * attribute table and attribute value table. 253ca7b2524STom Joseph * 254d965934fSJohn Wang * @param[in] stringTable - The string Table 255d965934fSJohn Wang */ 256d965934fSJohn Wang void buildAndStoreAttrTables(const Table& stringTable); 257d965934fSJohn Wang 258d965934fSJohn Wang /** @brief Persist the table 259d965934fSJohn Wang * @param[in] path - Path to persist the table 260d965934fSJohn Wang * @param[in] table - The table 261d965934fSJohn Wang */ 262d965934fSJohn Wang void storeTable(const fs::path& path, const Table& table); 263d965934fSJohn Wang 264d965934fSJohn Wang /** @brief Load bios table to ram 265d965934fSJohn Wang * @param[in] path - Path of the table 266d965934fSJohn Wang * @return The table, std::nullopt if loading fails 267d965934fSJohn Wang */ 268d965934fSJohn Wang std::optional<Table> loadTable(const fs::path& path); 2698241b340SJohn Wang 270cac0ebb2SSagar Srinivas /** @brief Method to decode the attribute name from the string handle 271cac0ebb2SSagar Srinivas * 272cac0ebb2SSagar Srinivas * @param[in] stringEntry - string entry from string table 273cac0ebb2SSagar Srinivas * @return the decoded string 274cac0ebb2SSagar Srinivas */ 275cac0ebb2SSagar Srinivas std::string decodeStringFromStringEntry( 276cac0ebb2SSagar Srinivas const pldm_bios_string_table_entry* stringEntry); 277cac0ebb2SSagar Srinivas 278cac0ebb2SSagar Srinivas /** @brief Method to print the string Handle by passing the attribute Handle 279cac0ebb2SSagar Srinivas * of the bios attribute that got updated 280cac0ebb2SSagar Srinivas * 281cac0ebb2SSagar Srinivas * @param[in] handle - the Attribute handle of the bios attribute 282cac0ebb2SSagar Srinivas * @param[in] index - index to the possible value handles 283cac0ebb2SSagar Srinivas * @param[in] attrTable - the attribute table 284cac0ebb2SSagar Srinivas * @param[in] stringTable - the string table 285cac0ebb2SSagar Srinivas * @return string handle from the string table and decoded string to the 286cac0ebb2SSagar Srinivas * name handle 287cac0ebb2SSagar Srinivas */ 288cac0ebb2SSagar Srinivas std::string displayStringHandle(uint16_t handle, uint8_t index, 289cac0ebb2SSagar Srinivas const std::optional<Table>& attrTable, 290cac0ebb2SSagar Srinivas const std::optional<Table>& stringTable); 291cac0ebb2SSagar Srinivas 292cac0ebb2SSagar Srinivas /** @brief Method to trace the bios attribute which got changed 293cac0ebb2SSagar Srinivas * 294cac0ebb2SSagar Srinivas * @param[in] attrValueEntry - The attribute value entry to update 295cac0ebb2SSagar Srinivas * @param[in] attrEntry - The attribute table entry 296cac0ebb2SSagar Srinivas * @param[in] isBMC - indicates if the attribute is set by BMC 297cac0ebb2SSagar Srinivas */ 298cac0ebb2SSagar Srinivas void traceBIOSUpdate(const pldm_bios_attr_val_table_entry* attrValueEntry, 299cac0ebb2SSagar Srinivas const pldm_bios_attr_table_entry* attrEntry, 300cac0ebb2SSagar Srinivas bool isBMC); 301cac0ebb2SSagar Srinivas 3028241b340SJohn Wang /** @brief Check the attribute value to update 3038241b340SJohn Wang * @param[in] attrValueEntry - The attribute value entry to update 3048241b340SJohn Wang * @param[in] attrEntry - The attribute table entry 3058241b340SJohn Wang * @param[in] stringTable - The string table 3068241b340SJohn Wang * @return pldm_completion_codes 3078241b340SJohn Wang */ 3088241b340SJohn Wang int checkAttrValueToUpdate( 3098241b340SJohn Wang const pldm_bios_attr_val_table_entry* attrValueEntry, 3108241b340SJohn Wang const pldm_bios_attr_table_entry* attrEntry, Table& stringTable); 3111b180d8aSGeorge Liu 3121b180d8aSGeorge Liu /** @brief Check the attribute table 3131b180d8aSGeorge Liu * @param[in] table - The table 3141b180d8aSGeorge Liu * @return pldm_completion_codes 3151b180d8aSGeorge Liu */ 3161b180d8aSGeorge Liu int checkAttributeTable(const Table& table); 3171b180d8aSGeorge Liu 3181b180d8aSGeorge Liu /** @brief Check the attribute value table 3191b180d8aSGeorge Liu * @param[in] table - The table 3201b180d8aSGeorge Liu * @return pldm_completion_codes 3211b180d8aSGeorge Liu */ 3221b180d8aSGeorge Liu int checkAttributeValueTable(const Table& table); 3231b180d8aSGeorge Liu 3241b180d8aSGeorge Liu /** @brief Update the BaseBIOSTable property of the D-Bus interface 3251b180d8aSGeorge Liu */ 3261b180d8aSGeorge Liu void updateBaseBIOSTableProperty(); 3271244acfdSGeorge Liu 3281244acfdSGeorge Liu /** @brief Listen the PendingAttributes property of the D-Bus interface and 3291244acfdSGeorge Liu * update BaseBIOSTable 3301244acfdSGeorge Liu */ 3311244acfdSGeorge Liu void listenPendingAttributes(); 3321244acfdSGeorge Liu 3331244acfdSGeorge Liu /** @brief Find attribute handle from bios attribute table 3341244acfdSGeorge Liu * @param[in] attrName - attribute name 3351244acfdSGeorge Liu * @return attribute handle 3361244acfdSGeorge Liu */ 3371244acfdSGeorge Liu uint16_t findAttrHandle(const std::string& attrName); 3381244acfdSGeorge Liu 3391244acfdSGeorge Liu /** @brief Listen the PendingAttributes property of the D-Bus interface 3401244acfdSGeorge Liu * and update BaseBIOSTable 3411244acfdSGeorge Liu * @param[in] msg - Data associated with subscribed signal 3421244acfdSGeorge Liu */ 3431244acfdSGeorge Liu void constructPendingAttribute(const PendingAttributes& pendingAttributes); 344d965934fSJohn Wang }; 345d965934fSJohn Wang 346d965934fSJohn Wang } // namespace bios 347d965934fSJohn Wang } // namespace responder 348d965934fSJohn Wang } // namespace pldm 349