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" 7c0c79481SSampa Misra #include "requester/handler.hpp" 8d965934fSJohn Wang 9c453e164SGeorge Liu #include <libpldm/bios_table.h> 10c453e164SGeorge Liu 116492f524SGeorge Liu #include <nlohmann/json.hpp> 1249cfb138SRiya Dixit #include <phosphor-logging/lg2.hpp> 136492f524SGeorge Liu 14d965934fSJohn Wang #include <functional> 15d965934fSJohn Wang #include <iostream> 16d965934fSJohn Wang #include <memory> 17d965934fSJohn Wang #include <optional> 18d965934fSJohn Wang #include <set> 19d965934fSJohn Wang #include <string> 20d965934fSJohn Wang #include <vector> 21d965934fSJohn Wang 2249cfb138SRiya Dixit PHOSPHOR_LOG2_USING; 2349cfb138SRiya Dixit 24d965934fSJohn Wang namespace pldm 25d965934fSJohn Wang { 26d965934fSJohn Wang namespace responder 27d965934fSJohn Wang { 28d965934fSJohn Wang namespace bios 29d965934fSJohn Wang { 301b180d8aSGeorge Liu enum class BoundType 311b180d8aSGeorge Liu { 321b180d8aSGeorge Liu LowerBound, 331b180d8aSGeorge Liu UpperBound, 341b180d8aSGeorge Liu ScalarIncrement, 351b180d8aSGeorge Liu MinStringLength, 361b180d8aSGeorge Liu MaxStringLength, 371b180d8aSGeorge Liu OneOf 381b180d8aSGeorge Liu }; 391b180d8aSGeorge Liu 401b180d8aSGeorge Liu using AttributeName = std::string; 411b180d8aSGeorge Liu using AttributeType = std::string; 421b180d8aSGeorge Liu using ReadonlyStatus = bool; 431b180d8aSGeorge Liu using DisplayName = std::string; 441b180d8aSGeorge Liu using Description = std::string; 451b180d8aSGeorge Liu using MenuPath = std::string; 461b180d8aSGeorge Liu using CurrentValue = std::variant<int64_t, std::string>; 471b180d8aSGeorge Liu using DefaultValue = std::variant<int64_t, std::string>; 481b180d8aSGeorge Liu using OptionString = std::string; 491b180d8aSGeorge Liu using OptionValue = std::variant<int64_t, std::string>; 50*7927f90cSSagar Srinivas using ValueDisplayName = std::string; 51*7927f90cSSagar Srinivas using Option = 52*7927f90cSSagar Srinivas std::vector<std::tuple<OptionString, OptionValue, ValueDisplayName>>; 531b180d8aSGeorge Liu using BIOSTableObj = 541b180d8aSGeorge Liu std::tuple<AttributeType, ReadonlyStatus, DisplayName, Description, 551b180d8aSGeorge Liu MenuPath, CurrentValue, DefaultValue, Option>; 561b180d8aSGeorge Liu using BaseBIOSTable = std::map<AttributeName, BIOSTableObj>; 571b180d8aSGeorge Liu 581244acfdSGeorge Liu using PendingObj = std::tuple<AttributeType, CurrentValue>; 591244acfdSGeorge Liu using PendingAttributes = std::map<AttributeName, PendingObj>; 601244acfdSGeorge Liu 61d965934fSJohn Wang /** @class BIOSConfig 62d965934fSJohn Wang * @brief Manager BIOS Attributes 63d965934fSJohn Wang */ 64d965934fSJohn Wang class BIOSConfig 65d965934fSJohn Wang { 66d965934fSJohn Wang public: 67d965934fSJohn Wang BIOSConfig() = delete; 68d965934fSJohn Wang BIOSConfig(const BIOSConfig&) = delete; 69d965934fSJohn Wang BIOSConfig(BIOSConfig&&) = delete; 70d965934fSJohn Wang BIOSConfig& operator=(const BIOSConfig&) = delete; 71d965934fSJohn Wang BIOSConfig& operator=(BIOSConfig&&) = delete; 72d965934fSJohn Wang ~BIOSConfig() = default; 73d965934fSJohn Wang 74d965934fSJohn Wang /** @brief Construct BIOSConfig 75d965934fSJohn Wang * @param[in] jsonDir - The directory where json file exists 76d965934fSJohn Wang * @param[in] tableDir - The directory where the persistent table is placed 77d965934fSJohn Wang * @param[in] dbusHandler - Dbus Handler 787f839f9dSTom Joseph * @param[in] fd - socket descriptor to communicate to host 797f839f9dSTom Joseph * @param[in] eid - MCTP EID of host firmware 80a330b2f0SAndrew Jeffery * @param[in] instanceIdDb - pointer to an InstanceIdDb object 81c0c79481SSampa Misra * @param[in] handler - PLDM request handler 8211ce8d22SSagar Srinivas * @param[in] oemBiosHandler - pointer to oem Bios Handler 83d965934fSJohn Wang */ 84c0c79481SSampa Misra explicit BIOSConfig( 85c0c79481SSampa Misra const char* jsonDir, const char* tableDir, 865079ac4aSBrad Bishop pldm::utils::DBusHandler* const dbusHandler, int fd, uint8_t eid, 87a330b2f0SAndrew Jeffery pldm::InstanceIdDb* instanceIdDb, 8811ce8d22SSagar Srinivas pldm::requester::Handler<pldm::requester::Request>* handler, 8911ce8d22SSagar Srinivas pldm::responder::oem_bios::Handler* oemBiosHandler); 90d965934fSJohn Wang 91d965934fSJohn Wang /** @brief Set attribute value on dbus and attribute value table 92d965934fSJohn Wang * @param[in] entry - attribute value entry 93d965934fSJohn Wang * @param[in] size - size of the attribute value entry 94cac0ebb2SSagar Srinivas * @param[in] isBMC - indicates if the attribute is set by BMC 956d6d1e8dSGeorge Liu * @param[in] updateDBus - update Attr value D-Bus property 966d6d1e8dSGeorge Liu * if this is set to true 977f839f9dSTom Joseph * @param[in] updateBaseBIOSTable - update BaseBIOSTable D-Bus property 987f839f9dSTom Joseph * if this is set to true 99d965934fSJohn Wang * @return pldm_completion_codes 100d965934fSJohn Wang */ 101cac0ebb2SSagar Srinivas int setAttrValue(const void* entry, size_t size, bool isBMC, 102cac0ebb2SSagar Srinivas bool updateDBus = true, bool updateBaseBIOSTable = true); 103d965934fSJohn Wang 104d965934fSJohn Wang /** @brief Remove the persistent tables */ 105d965934fSJohn Wang void removeTables(); 106d965934fSJohn Wang 107d965934fSJohn Wang /** @brief Build bios tables(string,attribute,attribute value table)*/ 108d965934fSJohn Wang void buildTables(); 109d965934fSJohn Wang 110d965934fSJohn Wang /** @brief Get BIOS table of specified type 111d965934fSJohn Wang * @param[in] tableType - The table type 112d965934fSJohn Wang * @return The bios table, std::nullopt if the table is unaviliable 113d965934fSJohn Wang */ 114d965934fSJohn Wang std::optional<Table> getBIOSTable(pldm_bios_table_types tableType); 115d965934fSJohn Wang 1161b180d8aSGeorge Liu /** @brief set BIOS table 1171b180d8aSGeorge Liu * @param[in] tableType - Indicates what table is being transferred 1181b180d8aSGeorge Liu * {BIOSStringTable=0x0, BIOSAttributeTable=0x1, 1191b180d8aSGeorge Liu * BIOSAttributeValueTable=0x2} 1201b180d8aSGeorge Liu * @param[in] table - table data 1217f839f9dSTom Joseph * @param[in] updateBaseBIOSTable - update BaseBIOSTable D-Bus property 1227f839f9dSTom Joseph * if this is set to true 1231b180d8aSGeorge Liu * @return pldm_completion_codes 1241b180d8aSGeorge Liu */ 1257f839f9dSTom Joseph int setBIOSTable(uint8_t tableType, const Table& table, 1267f839f9dSTom Joseph bool updateBaseBIOSTable = true); 1271b180d8aSGeorge Liu 128d965934fSJohn Wang private: 129ca7b2524STom Joseph /** @enum Index into the fields in the BaseBIOSTable 130ca7b2524STom Joseph */ 131ca7b2524STom Joseph enum class Index : uint8_t 132ca7b2524STom Joseph { 133ca7b2524STom Joseph attributeType = 0, 134ca7b2524STom Joseph readOnly, 135ca7b2524STom Joseph displayName, 136ca7b2524STom Joseph description, 137ca7b2524STom Joseph menuPath, 138ca7b2524STom Joseph currentValue, 139ca7b2524STom Joseph defaultValue, 140ca7b2524STom Joseph options, 141ca7b2524STom Joseph }; 142ca7b2524STom Joseph 143d965934fSJohn Wang const fs::path jsonDir; 144d965934fSJohn Wang const fs::path tableDir; 1455079ac4aSBrad Bishop pldm::utils::DBusHandler* const dbusHandler; 1461b180d8aSGeorge Liu BaseBIOSTable baseBIOSTableMaps; 147d965934fSJohn Wang 1487f839f9dSTom Joseph /** @brief socket descriptor to communicate to host */ 1497f839f9dSTom Joseph int fd; 1507f839f9dSTom Joseph 1517f839f9dSTom Joseph /** @brief MCTP EID of host firmware */ 1527f839f9dSTom Joseph uint8_t eid; 1537f839f9dSTom Joseph 154a330b2f0SAndrew Jeffery /** @brief pointer to an Instance ID database object, used to obtain PLDM 155a330b2f0SAndrew Jeffery * instance IDs. 1567f839f9dSTom Joseph */ 157a330b2f0SAndrew Jeffery pldm::InstanceIdDb* instanceIdDb; 1587f839f9dSTom Joseph 159c0c79481SSampa Misra /** @brief PLDM request handler */ 160c0c79481SSampa Misra pldm::requester::Handler<pldm::requester::Request>* handler; 161c0c79481SSampa Misra 16211ce8d22SSagar Srinivas /** @brief oem Bios Handler*/ 16311ce8d22SSagar Srinivas pldm::responder::oem_bios::Handler* oemBiosHandler; 16411ce8d22SSagar Srinivas 165d965934fSJohn Wang // vector persists all attributes 166d965934fSJohn Wang using BIOSAttributes = std::vector<std::unique_ptr<BIOSAttribute>>; 167d965934fSJohn Wang BIOSAttributes biosAttributes; 168d965934fSJohn Wang 16946ece063SSampa Misra using propName = std::string; 1705079ac4aSBrad Bishop using DbusChObjProperties = std::map<propName, pldm::utils::PropertyValue>; 17146ece063SSampa Misra 172d987c94cSMatt Spinler using ifaceName = std::string; 173d987c94cSMatt Spinler using DbusIfacesAdded = std::map<ifaceName, DbusChObjProperties>; 174d987c94cSMatt Spinler 17546ece063SSampa Misra // vector to catch the D-Bus property change signals for BIOS attributes 17684b790cbSPatrick Williams std::vector<std::unique_ptr<sdbusplus::bus::match_t>> biosAttrMatch; 17746ece063SSampa Misra 17811ce8d22SSagar Srinivas /** @brief system type/model */ 17911ce8d22SSagar Srinivas std::string sysType; 18011ce8d22SSagar Srinivas 18146ece063SSampa Misra /** @brief Method to update a BIOS attribute when the corresponding Dbus 18246ece063SSampa Misra * property is changed 18346ece063SSampa Misra * @param[in] chProperties - list of properties which have changed 18446ece063SSampa Misra * @param[in] biosAttrIndex - Index of BIOSAttribute pointer in 18546ece063SSampa Misra * biosAttributes 18646ece063SSampa Misra * @return - none 18746ece063SSampa Misra */ 18846ece063SSampa Misra void processBiosAttrChangeNotification( 18946ece063SSampa Misra const DbusChObjProperties& chProperties, uint32_t biosAttrIndex); 19046ece063SSampa Misra 191d965934fSJohn Wang /** @brief Construct an attribute and persist it 192d965934fSJohn Wang * @tparam T - attribute type 193d965934fSJohn Wang * @param[in] entry - json entry 194d965934fSJohn Wang */ 195d965934fSJohn Wang template <typename T> 196d965934fSJohn Wang void constructAttribute(const Json& entry) 197d965934fSJohn Wang { 198d965934fSJohn Wang try 199d965934fSJohn Wang { 200d965934fSJohn Wang biosAttributes.push_back(std::make_unique<T>(entry, dbusHandler)); 20146ece063SSampa Misra auto biosAttrIndex = biosAttributes.size() - 1; 20246ece063SSampa Misra auto dBusMap = biosAttributes[biosAttrIndex]->getDBusMap(); 20346ece063SSampa Misra 20446ece063SSampa Misra if (dBusMap.has_value()) 20546ece063SSampa Misra { 20646ece063SSampa Misra using namespace sdbusplus::bus::match::rules; 20746ece063SSampa Misra biosAttrMatch.push_back( 20884b790cbSPatrick Williams std::make_unique<sdbusplus::bus::match_t>( 20946ece063SSampa Misra pldm::utils::DBusHandler::getBus(), 21046ece063SSampa Misra propertiesChanged(dBusMap->objectPath, 21146ece063SSampa Misra dBusMap->interface), 21284b790cbSPatrick Williams [this, biosAttrIndex](sdbusplus::message_t& msg) { 21346ece063SSampa Misra DbusChObjProperties props; 21446ece063SSampa Misra std::string iface; 21546ece063SSampa Misra msg.read(iface, props); 2166da4f91bSPatrick Williams processBiosAttrChangeNotification(props, biosAttrIndex); 21746ece063SSampa Misra })); 218d987c94cSMatt Spinler 219d987c94cSMatt Spinler biosAttrMatch.push_back( 220b90fb7fdSPatrick Williams std::make_unique<sdbusplus::bus::match_t>( 221d987c94cSMatt Spinler pldm::utils::DBusHandler::getBus(), 222d987c94cSMatt Spinler interfacesAdded() + argNpath(0, dBusMap->objectPath), 223d987c94cSMatt Spinler [this, biosAttrIndex, interface = dBusMap->interface]( 224b90fb7fdSPatrick Williams sdbusplus::message_t& msg) { 225d987c94cSMatt Spinler sdbusplus::message::object_path path; 226d987c94cSMatt Spinler DbusIfacesAdded interfaces; 227d987c94cSMatt Spinler 228d987c94cSMatt Spinler msg.read(path, interfaces); 229d987c94cSMatt Spinler auto ifaceIt = interfaces.find(interface); 230d987c94cSMatt Spinler if (ifaceIt != interfaces.end()) 231d987c94cSMatt Spinler { 2326da4f91bSPatrick Williams processBiosAttrChangeNotification(ifaceIt->second, 2336da4f91bSPatrick Williams biosAttrIndex); 234d987c94cSMatt Spinler } 235d987c94cSMatt Spinler })); 23646ece063SSampa Misra } 237d965934fSJohn Wang } 238d965934fSJohn Wang catch (const std::exception& e) 239d965934fSJohn Wang { 24049cfb138SRiya Dixit error("Constructs Attribute Error, {ERR_EXCEP}", "ERR_EXCEP", 24149cfb138SRiya Dixit e.what()); 242d965934fSJohn Wang } 243d965934fSJohn Wang } 244d965934fSJohn Wang 245d965934fSJohn Wang /** Construct attributes and persist them */ 246d965934fSJohn Wang void constructAttributes(); 247d965934fSJohn Wang 248d965934fSJohn Wang using ParseHandler = std::function<void(const Json& entry)>; 249d965934fSJohn Wang 250d965934fSJohn Wang /** @brief Helper function to parse json 251d965934fSJohn Wang * @param[in] filePath - Path of json file 252d965934fSJohn Wang * @param[in] handler - Handler to process each entry in the json 253d965934fSJohn Wang */ 254d965934fSJohn Wang void load(const fs::path& filePath, ParseHandler handler); 255d965934fSJohn Wang 256d965934fSJohn Wang /** @brief Build String Table and persist it 257d965934fSJohn Wang * @return The built string table, std::nullopt if it fails. 258d965934fSJohn Wang */ 259d965934fSJohn Wang std::optional<Table> buildAndStoreStringTable(); 260d965934fSJohn Wang 261ca7b2524STom Joseph /** @brief Build attribute table and attribute value table and persist them 262ca7b2524STom Joseph * Read the BaseBIOSTable from the bios-settings-manager and update 263ca7b2524STom Joseph * attribute table and attribute value table. 264ca7b2524STom Joseph * 265d965934fSJohn Wang * @param[in] stringTable - The string Table 266d965934fSJohn Wang */ 267d965934fSJohn Wang void buildAndStoreAttrTables(const Table& stringTable); 268d965934fSJohn Wang 269d965934fSJohn Wang /** @brief Persist the table 270d965934fSJohn Wang * @param[in] path - Path to persist the table 271d965934fSJohn Wang * @param[in] table - The table 272d965934fSJohn Wang */ 273d965934fSJohn Wang void storeTable(const fs::path& path, const Table& table); 274d965934fSJohn Wang 275d965934fSJohn Wang /** @brief Load bios table to ram 276d965934fSJohn Wang * @param[in] path - Path of the table 277d965934fSJohn Wang * @return The table, std::nullopt if loading fails 278d965934fSJohn Wang */ 279d965934fSJohn Wang std::optional<Table> loadTable(const fs::path& path); 2808241b340SJohn Wang 281cac0ebb2SSagar Srinivas /** @brief Method to decode the attribute name from the string handle 282cac0ebb2SSagar Srinivas * 283cac0ebb2SSagar Srinivas * @param[in] stringEntry - string entry from string table 284cac0ebb2SSagar Srinivas * @return the decoded string 285cac0ebb2SSagar Srinivas */ 286cac0ebb2SSagar Srinivas std::string decodeStringFromStringEntry( 287cac0ebb2SSagar Srinivas const pldm_bios_string_table_entry* stringEntry); 288cac0ebb2SSagar Srinivas 289cac0ebb2SSagar Srinivas /** @brief Method to print the string Handle by passing the attribute Handle 290cac0ebb2SSagar Srinivas * of the bios attribute that got updated 291cac0ebb2SSagar Srinivas * 292cac0ebb2SSagar Srinivas * @param[in] handle - the Attribute handle of the bios attribute 293cac0ebb2SSagar Srinivas * @param[in] index - index to the possible value handles 294cac0ebb2SSagar Srinivas * @param[in] attrTable - the attribute table 295cac0ebb2SSagar Srinivas * @param[in] stringTable - the string table 296cac0ebb2SSagar Srinivas * @return string handle from the string table and decoded string to the 297cac0ebb2SSagar Srinivas * name handle 298cac0ebb2SSagar Srinivas */ 299cac0ebb2SSagar Srinivas std::string displayStringHandle(uint16_t handle, uint8_t index, 300cac0ebb2SSagar Srinivas const std::optional<Table>& attrTable, 301cac0ebb2SSagar Srinivas const std::optional<Table>& stringTable); 302cac0ebb2SSagar Srinivas 303cac0ebb2SSagar Srinivas /** @brief Method to trace the bios attribute which got changed 304cac0ebb2SSagar Srinivas * 305cac0ebb2SSagar Srinivas * @param[in] attrValueEntry - The attribute value entry to update 306cac0ebb2SSagar Srinivas * @param[in] attrEntry - The attribute table entry 307cac0ebb2SSagar Srinivas * @param[in] isBMC - indicates if the attribute is set by BMC 308cac0ebb2SSagar Srinivas */ 309cac0ebb2SSagar Srinivas void traceBIOSUpdate(const pldm_bios_attr_val_table_entry* attrValueEntry, 310cac0ebb2SSagar Srinivas const pldm_bios_attr_table_entry* attrEntry, 311cac0ebb2SSagar Srinivas bool isBMC); 312cac0ebb2SSagar Srinivas 3138241b340SJohn Wang /** @brief Check the attribute value to update 3148241b340SJohn Wang * @param[in] attrValueEntry - The attribute value entry to update 3158241b340SJohn Wang * @param[in] attrEntry - The attribute table entry 3168241b340SJohn Wang * @param[in] stringTable - The string table 3178241b340SJohn Wang * @return pldm_completion_codes 3188241b340SJohn Wang */ 3198241b340SJohn Wang int checkAttrValueToUpdate( 3208241b340SJohn Wang const pldm_bios_attr_val_table_entry* attrValueEntry, 3218241b340SJohn Wang const pldm_bios_attr_table_entry* attrEntry, Table& stringTable); 3221b180d8aSGeorge Liu 3231b180d8aSGeorge Liu /** @brief Check the attribute table 3241b180d8aSGeorge Liu * @param[in] table - The table 3251b180d8aSGeorge Liu * @return pldm_completion_codes 3261b180d8aSGeorge Liu */ 3271b180d8aSGeorge Liu int checkAttributeTable(const Table& table); 3281b180d8aSGeorge Liu 3291b180d8aSGeorge Liu /** @brief Check the attribute value table 3301b180d8aSGeorge Liu * @param[in] table - The table 3311b180d8aSGeorge Liu * @return pldm_completion_codes 3321b180d8aSGeorge Liu */ 3331b180d8aSGeorge Liu int checkAttributeValueTable(const Table& table); 3341b180d8aSGeorge Liu 3351b180d8aSGeorge Liu /** @brief Update the BaseBIOSTable property of the D-Bus interface 3361b180d8aSGeorge Liu */ 3371b180d8aSGeorge Liu void updateBaseBIOSTableProperty(); 3381244acfdSGeorge Liu 3391244acfdSGeorge Liu /** @brief Listen the PendingAttributes property of the D-Bus interface and 3401244acfdSGeorge Liu * update BaseBIOSTable 3411244acfdSGeorge Liu */ 3421244acfdSGeorge Liu void listenPendingAttributes(); 3431244acfdSGeorge Liu 3441244acfdSGeorge Liu /** @brief Find attribute handle from bios attribute table 3451244acfdSGeorge Liu * @param[in] attrName - attribute name 3461244acfdSGeorge Liu * @return attribute handle 3471244acfdSGeorge Liu */ 3481244acfdSGeorge Liu uint16_t findAttrHandle(const std::string& attrName); 3491244acfdSGeorge Liu 3501244acfdSGeorge Liu /** @brief Listen the PendingAttributes property of the D-Bus interface 3511244acfdSGeorge Liu * and update BaseBIOSTable 3521244acfdSGeorge Liu * @param[in] msg - Data associated with subscribed signal 3531244acfdSGeorge Liu */ 3541244acfdSGeorge Liu void constructPendingAttribute(const PendingAttributes& pendingAttributes); 355d965934fSJohn Wang }; 356d965934fSJohn Wang 357d965934fSJohn Wang } // namespace bios 358d965934fSJohn Wang } // namespace responder 359d965934fSJohn Wang } // namespace pldm 360