blob: db8b3030b81205f159a2892e331c2a7ab5bcedf3 [file] [log] [blame]
John Wangd9659342020-02-27 16:46:05 +08001#pragma once
2
3#include "bios_attribute.hpp"
4#include "bios_table.hpp"
Andrew Jeffery2abbce72023-10-18 10:17:35 +10305#include "common/instance_id.hpp"
Archana Kakani97a0f482025-03-10 05:39:38 -05006#include "common/types.hpp"
Sagar Srinivas11ce8d22022-07-28 11:32:34 -05007#include "oem_handler.hpp"
Kamalkumar Patel3c50c822024-01-30 07:14:40 -06008#include "platform_config.hpp"
Sampa Misrac0c79482021-06-02 08:01:54 -05009#include "requester/handler.hpp"
John Wangd9659342020-02-27 16:46:05 +080010
George Liuc453e162022-12-21 17:16:23 +080011#include <libpldm/bios_table.h>
12
George Liu6492f522020-06-16 10:34:05 +080013#include <nlohmann/json.hpp>
Riya Dixit49cfb132023-03-02 04:26:53 -060014#include <phosphor-logging/lg2.hpp>
George Liu6492f522020-06-16 10:34:05 +080015
John Wangd9659342020-02-27 16:46:05 +080016#include <iostream>
17#include <memory>
John Wangd9659342020-02-27 16:46:05 +080018#include <optional>
19#include <set>
20#include <string>
21#include <vector>
22
Riya Dixit49cfb132023-03-02 04:26:53 -060023PHOSPHOR_LOG2_USING;
24
John Wangd9659342020-02-27 16:46:05 +080025namespace pldm
26{
27namespace responder
28{
29namespace bios
30{
George Liu1b180d82020-07-23 14:01:58 +080031enum class BoundType
32{
33 LowerBound,
34 UpperBound,
35 ScalarIncrement,
36 MinStringLength,
37 MaxStringLength,
38 OneOf
39};
40
Archana Kakani97a0f482025-03-10 05:39:38 -050041using namespace pldm::bios;
George Liu1244acf2020-08-14 09:11:11 +080042
John Wangd9659342020-02-27 16:46:05 +080043/** @class BIOSConfig
44 * @brief Manager BIOS Attributes
45 */
46class BIOSConfig
47{
48 public:
49 BIOSConfig() = delete;
50 BIOSConfig(const BIOSConfig&) = delete;
51 BIOSConfig(BIOSConfig&&) = delete;
52 BIOSConfig& operator=(const BIOSConfig&) = delete;
53 BIOSConfig& operator=(BIOSConfig&&) = delete;
54 ~BIOSConfig() = default;
55
56 /** @brief Construct BIOSConfig
57 * @param[in] jsonDir - The directory where json file exists
58 * @param[in] tableDir - The directory where the persistent table is placed
59 * @param[in] dbusHandler - Dbus Handler
Tom Joseph7f839f92020-09-21 10:20:44 +053060 * @param[in] fd - socket descriptor to communicate to host
61 * @param[in] eid - MCTP EID of host firmware
Andrew Jefferya330b2f2023-05-04 14:55:37 +093062 * @param[in] instanceIdDb - pointer to an InstanceIdDb object
Sampa Misrac0c79482021-06-02 08:01:54 -050063 * @param[in] handler - PLDM request handler
Kamalkumar Patel3c50c822024-01-30 07:14:40 -060064 * @param[in] platformConfigHandler - pointer to platform config Handler
Archana Kakani62dd8ff2024-02-12 10:00:40 -060065 * @param[in] requestPLDMServiceName - Callback for claiming the PLDM
66 * service name Called only after building BIOS tables.
John Wangd9659342020-02-27 16:46:05 +080067 */
Sampa Misrac0c79482021-06-02 08:01:54 -050068 explicit BIOSConfig(
69 const char* jsonDir, const char* tableDir,
Brad Bishop5079ac42021-08-19 18:35:06 -040070 pldm::utils::DBusHandler* const dbusHandler, int fd, uint8_t eid,
Andrew Jefferya330b2f2023-05-04 14:55:37 +093071 pldm::InstanceIdDb* instanceIdDb,
Sagar Srinivas11ce8d22022-07-28 11:32:34 -050072 pldm::requester::Handler<pldm::requester::Request>* handler,
Archana Kakani62dd8ff2024-02-12 10:00:40 -060073 pldm::responder::platform_config::Handler* platformConfigHandler,
74 pldm::responder::bios::Callback requestPLDMServiceName);
John Wangd9659342020-02-27 16:46:05 +080075
76 /** @brief Set attribute value on dbus and attribute value table
77 * @param[in] entry - attribute value entry
78 * @param[in] size - size of the attribute value entry
Sagar Srinivascac0ebb2021-11-23 07:50:28 -060079 * @param[in] isBMC - indicates if the attribute is set by BMC
George Liu6d6d1e82021-02-16 11:08:55 +080080 * @param[in] updateDBus - update Attr value D-Bus property
81 * if this is set to true
Tom Joseph7f839f92020-09-21 10:20:44 +053082 * @param[in] updateBaseBIOSTable - update BaseBIOSTable D-Bus property
83 * if this is set to true
John Wangd9659342020-02-27 16:46:05 +080084 * @return pldm_completion_codes
85 */
Sagar Srinivascac0ebb2021-11-23 07:50:28 -060086 int setAttrValue(const void* entry, size_t size, bool isBMC,
87 bool updateDBus = true, bool updateBaseBIOSTable = true);
John Wangd9659342020-02-27 16:46:05 +080088
89 /** @brief Remove the persistent tables */
90 void removeTables();
91
92 /** @brief Build bios tables(string,attribute,attribute value table)*/
93 void buildTables();
94
95 /** @brief Get BIOS table of specified type
96 * @param[in] tableType - The table type
97 * @return The bios table, std::nullopt if the table is unaviliable
98 */
99 std::optional<Table> getBIOSTable(pldm_bios_table_types tableType);
100
George Liu1b180d82020-07-23 14:01:58 +0800101 /** @brief set BIOS table
102 * @param[in] tableType - Indicates what table is being transferred
103 * {BIOSStringTable=0x0, BIOSAttributeTable=0x1,
104 * BIOSAttributeValueTable=0x2}
105 * @param[in] table - table data
Tom Joseph7f839f92020-09-21 10:20:44 +0530106 * @param[in] updateBaseBIOSTable - update BaseBIOSTable D-Bus property
107 * if this is set to true
George Liu1b180d82020-07-23 14:01:58 +0800108 * @return pldm_completion_codes
109 */
Tom Joseph7f839f92020-09-21 10:20:44 +0530110 int setBIOSTable(uint8_t tableType, const Table& table,
111 bool updateBaseBIOSTable = true);
George Liu1b180d82020-07-23 14:01:58 +0800112
Archana Kakani62dd8ff2024-02-12 10:00:40 -0600113 /** @brief Construct the BIOS Attributes and build the tables
114 * after receiving system type from entity manager.
Archana Kakani46f352e2024-03-17 08:21:08 -0500115 * Also register the Service Name only if
116 * System specific Bios attributes are supported
Archana Kakani62dd8ff2024-02-12 10:00:40 -0600117 * @param[in] String - System Type
Archana Kakani46f352e2024-03-17 08:21:08 -0500118 * @param[in] bool - flag to register service name
Archana Kakani62dd8ff2024-02-12 10:00:40 -0600119 * @return void
120 */
Archana Kakani46f352e2024-03-17 08:21:08 -0500121 void initBIOSAttributes(const std::string& sysType, bool registerService);
Archana Kakani62dd8ff2024-02-12 10:00:40 -0600122
Archana Kakani97a0f482025-03-10 05:39:38 -0500123 /** @brief Set OEM bios handler
124 *
125 * @param[in] oemBiosHandler - OEM Bios handler
126 */
127 inline void setOemBiosHandler(pldm::responder::oem_bios::Handler* handler)
128 {
129 oemBiosHandler = handler;
130 }
131
John Wangd9659342020-02-27 16:46:05 +0800132 private:
Tom Josephca7b2522020-11-18 12:27:11 +0530133 /** @enum Index into the fields in the BaseBIOSTable
134 */
135 enum class Index : uint8_t
136 {
137 attributeType = 0,
138 readOnly,
139 displayName,
140 description,
141 menuPath,
142 currentValue,
143 defaultValue,
144 options,
145 };
146
John Wangd9659342020-02-27 16:46:05 +0800147 const fs::path jsonDir;
148 const fs::path tableDir;
Brad Bishop5079ac42021-08-19 18:35:06 -0400149 pldm::utils::DBusHandler* const dbusHandler;
George Liu1b180d82020-07-23 14:01:58 +0800150 BaseBIOSTable baseBIOSTableMaps;
Archana Kakani97a0f482025-03-10 05:39:38 -0500151 pldm::responder::oem_bios::Handler* oemBiosHandler = nullptr;
John Wangd9659342020-02-27 16:46:05 +0800152
Tom Joseph7f839f92020-09-21 10:20:44 +0530153 /** @brief MCTP EID of host firmware */
154 uint8_t eid;
155
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930156 /** @brief pointer to an Instance ID database object, used to obtain PLDM
157 * instance IDs.
Tom Joseph7f839f92020-09-21 10:20:44 +0530158 */
Andrew Jefferya330b2f2023-05-04 14:55:37 +0930159 pldm::InstanceIdDb* instanceIdDb;
Tom Joseph7f839f92020-09-21 10:20:44 +0530160
Sampa Misrac0c79482021-06-02 08:01:54 -0500161 /** @brief PLDM request handler */
162 pldm::requester::Handler<pldm::requester::Request>* handler;
163
Kamalkumar Patel3c50c822024-01-30 07:14:40 -0600164 /** @brief platform config Handler*/
165 pldm::responder::platform_config::Handler* platformConfigHandler;
Sagar Srinivas11ce8d22022-07-28 11:32:34 -0500166
Archana Kakani62dd8ff2024-02-12 10:00:40 -0600167 /** @brief Callback for registering the PLDM service name */
168 pldm::responder::bios::Callback requestPLDMServiceName;
169
John Wangd9659342020-02-27 16:46:05 +0800170 // vector persists all attributes
171 using BIOSAttributes = std::vector<std::unique_ptr<BIOSAttribute>>;
172 BIOSAttributes biosAttributes;
173
Sampa Misra46ece062020-03-18 07:17:44 -0500174 using propName = std::string;
Brad Bishop5079ac42021-08-19 18:35:06 -0400175 using DbusChObjProperties = std::map<propName, pldm::utils::PropertyValue>;
Sampa Misra46ece062020-03-18 07:17:44 -0500176
Matt Spinlerd987c942023-03-24 10:18:19 -0500177 using ifaceName = std::string;
178 using DbusIfacesAdded = std::map<ifaceName, DbusChObjProperties>;
179
Sampa Misra46ece062020-03-18 07:17:44 -0500180 // vector to catch the D-Bus property change signals for BIOS attributes
Patrick Williams84b790c2022-07-22 19:26:56 -0500181 std::vector<std::unique_ptr<sdbusplus::bus::match_t>> biosAttrMatch;
Sampa Misra46ece062020-03-18 07:17:44 -0500182
Sagar Srinivas11ce8d22022-07-28 11:32:34 -0500183 /** @brief system type/model */
184 std::string sysType;
185
Sampa Misra46ece062020-03-18 07:17:44 -0500186 /** @brief Method to update a BIOS attribute when the corresponding Dbus
187 * property is changed
188 * @param[in] chProperties - list of properties which have changed
189 * @param[in] biosAttrIndex - Index of BIOSAttribute pointer in
190 * biosAttributes
191 * @return - none
192 */
193 void processBiosAttrChangeNotification(
194 const DbusChObjProperties& chProperties, uint32_t biosAttrIndex);
195
Archana Kakani46f352e2024-03-17 08:21:08 -0500196 /** @brief Method is used to initiate bios attributes only if system type
197 * is already populated by entity manager.
198 * Register the callback if system type is yet to be populated by Entity
199 * manager
Archana Kakani62dd8ff2024-02-12 10:00:40 -0600200 */
Archana Kakani46f352e2024-03-17 08:21:08 -0500201 void checkSystemTypeAvailability();
Archana Kakani62dd8ff2024-02-12 10:00:40 -0600202
John Wangd9659342020-02-27 16:46:05 +0800203 /** @brief Construct an attribute and persist it
204 * @tparam T - attribute type
205 * @param[in] entry - json entry
206 */
207 template <typename T>
208 void constructAttribute(const Json& entry)
209 {
210 try
211 {
212 biosAttributes.push_back(std::make_unique<T>(entry, dbusHandler));
Sampa Misra46ece062020-03-18 07:17:44 -0500213 auto biosAttrIndex = biosAttributes.size() - 1;
214 auto dBusMap = biosAttributes[biosAttrIndex]->getDBusMap();
215
216 if (dBusMap.has_value())
217 {
218 using namespace sdbusplus::bus::match::rules;
219 biosAttrMatch.push_back(
Patrick Williams84b790c2022-07-22 19:26:56 -0500220 std::make_unique<sdbusplus::bus::match_t>(
Sampa Misra46ece062020-03-18 07:17:44 -0500221 pldm::utils::DBusHandler::getBus(),
222 propertiesChanged(dBusMap->objectPath,
223 dBusMap->interface),
Patrick Williams84b790c2022-07-22 19:26:56 -0500224 [this, biosAttrIndex](sdbusplus::message_t& msg) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400225 DbusChObjProperties props;
226 std::string iface;
227 msg.read(iface, props);
228 processBiosAttrChangeNotification(props,
229 biosAttrIndex);
230 }));
Matt Spinlerd987c942023-03-24 10:18:19 -0500231
232 biosAttrMatch.push_back(
Patrick Williamsb90fb7f2023-04-12 02:31:38 -0500233 std::make_unique<sdbusplus::bus::match_t>(
Matt Spinlerd987c942023-03-24 10:18:19 -0500234 pldm::utils::DBusHandler::getBus(),
235 interfacesAdded() + argNpath(0, dBusMap->objectPath),
236 [this, biosAttrIndex, interface = dBusMap->interface](
Patrick Williamsb90fb7f2023-04-12 02:31:38 -0500237 sdbusplus::message_t& msg) {
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400238 sdbusplus::message::object_path path;
239 DbusIfacesAdded interfaces;
Matt Spinlerd987c942023-03-24 10:18:19 -0500240
Patrick Williams16c2a0a2024-08-16 15:20:59 -0400241 msg.read(path, interfaces);
242 auto ifaceIt = interfaces.find(interface);
243 if (ifaceIt != interfaces.end())
244 {
245 processBiosAttrChangeNotification(
246 ifaceIt->second, biosAttrIndex);
247 }
248 }));
Sampa Misra46ece062020-03-18 07:17:44 -0500249 }
John Wangd9659342020-02-27 16:46:05 +0800250 }
251 catch (const std::exception& e)
252 {
Riya Dixit89644442024-03-31 05:39:59 -0500253 error("Failed to construct an attribute, error - {ERROR}", "ERROR",
254 e);
John Wangd9659342020-02-27 16:46:05 +0800255 }
256 }
257
258 /** Construct attributes and persist them */
259 void constructAttributes();
260
261 using ParseHandler = std::function<void(const Json& entry)>;
262
263 /** @brief Helper function to parse json
264 * @param[in] filePath - Path of json file
265 * @param[in] handler - Handler to process each entry in the json
266 */
267 void load(const fs::path& filePath, ParseHandler handler);
268
269 /** @brief Build String Table and persist it
270 * @return The built string table, std::nullopt if it fails.
271 */
272 std::optional<Table> buildAndStoreStringTable();
273
Tom Josephca7b2522020-11-18 12:27:11 +0530274 /** @brief Build attribute table and attribute value table and persist them
275 * Read the BaseBIOSTable from the bios-settings-manager and update
276 * attribute table and attribute value table.
277 *
John Wangd9659342020-02-27 16:46:05 +0800278 * @param[in] stringTable - The string Table
279 */
280 void buildAndStoreAttrTables(const Table& stringTable);
281
282 /** @brief Persist the table
283 * @param[in] path - Path to persist the table
284 * @param[in] table - The table
285 */
286 void storeTable(const fs::path& path, const Table& table);
287
288 /** @brief Load bios table to ram
289 * @param[in] path - Path of the table
290 * @return The table, std::nullopt if loading fails
291 */
292 std::optional<Table> loadTable(const fs::path& path);
John Wang8241b342020-06-05 10:49:17 +0800293
Sagar Srinivascac0ebb2021-11-23 07:50:28 -0600294 /** @brief Method to decode the attribute name from the string handle
295 *
296 * @param[in] stringEntry - string entry from string table
297 * @return the decoded string
298 */
299 std::string decodeStringFromStringEntry(
300 const pldm_bios_string_table_entry* stringEntry);
301
302 /** @brief Method to print the string Handle by passing the attribute Handle
303 * of the bios attribute that got updated
304 *
305 * @param[in] handle - the Attribute handle of the bios attribute
306 * @param[in] index - index to the possible value handles
307 * @param[in] attrTable - the attribute table
308 * @param[in] stringTable - the string table
309 * @return string handle from the string table and decoded string to the
310 * name handle
311 */
312 std::string displayStringHandle(uint16_t handle, uint8_t index,
313 const std::optional<Table>& attrTable,
314 const std::optional<Table>& stringTable);
315
316 /** @brief Method to trace the bios attribute which got changed
317 *
318 * @param[in] attrValueEntry - The attribute value entry to update
319 * @param[in] attrEntry - The attribute table entry
320 * @param[in] isBMC - indicates if the attribute is set by BMC
321 */
322 void traceBIOSUpdate(const pldm_bios_attr_val_table_entry* attrValueEntry,
323 const pldm_bios_attr_table_entry* attrEntry,
324 bool isBMC);
325
John Wang8241b342020-06-05 10:49:17 +0800326 /** @brief Check the attribute value to update
327 * @param[in] attrValueEntry - The attribute value entry to update
328 * @param[in] attrEntry - The attribute table entry
329 * @param[in] stringTable - The string table
330 * @return pldm_completion_codes
331 */
332 int checkAttrValueToUpdate(
333 const pldm_bios_attr_val_table_entry* attrValueEntry,
334 const pldm_bios_attr_table_entry* attrEntry, Table& stringTable);
George Liu1b180d82020-07-23 14:01:58 +0800335
336 /** @brief Check the attribute table
337 * @param[in] table - The table
338 * @return pldm_completion_codes
339 */
340 int checkAttributeTable(const Table& table);
341
342 /** @brief Check the attribute value table
343 * @param[in] table - The table
344 * @return pldm_completion_codes
345 */
346 int checkAttributeValueTable(const Table& table);
347
348 /** @brief Update the BaseBIOSTable property of the D-Bus interface
349 */
350 void updateBaseBIOSTableProperty();
George Liu1244acf2020-08-14 09:11:11 +0800351
352 /** @brief Listen the PendingAttributes property of the D-Bus interface and
353 * update BaseBIOSTable
354 */
355 void listenPendingAttributes();
356
357 /** @brief Find attribute handle from bios attribute table
358 * @param[in] attrName - attribute name
359 * @return attribute handle
360 */
361 uint16_t findAttrHandle(const std::string& attrName);
362
363 /** @brief Listen the PendingAttributes property of the D-Bus interface
364 * and update BaseBIOSTable
365 * @param[in] msg - Data associated with subscribed signal
366 */
367 void constructPendingAttribute(const PendingAttributes& pendingAttributes);
John Wangd9659342020-02-27 16:46:05 +0800368};
369
370} // namespace bios
371} // namespace responder
Sampa Misra46ece062020-03-18 07:17:44 -0500372} // namespace pldm