#pragma once #include "const.hpp" #include "store.hpp" #include "types.hpp" #include #include #include #include namespace openpower { namespace vpd { // Map which holds system vpd keywords which can be restored at standby and via // vpd-tool and also can be used to reset keywords to its defaults at // manufacturing. The list of keywords for VSYS record is as per the S0 system. // Should be updated for another type of systems For those keywords whose // default value is system specific, the default value field is left empty. // Record : {Keyword, Default value, Is PEL required on restore failure, Is MFG // reset required, backupVpdRecName, backupVpdKwName} static const inventory::SystemKeywordsMap svpdKwdMap{ {"VSYS", {inventory::SystemKeywordInfo("BR", Binary(2, 0x20), true, true, "VSBK", "BR"), inventory::SystemKeywordInfo("TM", Binary(8, 0x20), true, true, "VSBK", "TM"), inventory::SystemKeywordInfo("SE", Binary(7, 0x20), true, true, "VSBK", "SE"), inventory::SystemKeywordInfo("SU", Binary(6, 0x20), true, true, "VSBK", "SU"), inventory::SystemKeywordInfo("RB", Binary(4, 0x20), true, true, "VSBK", "RB"), inventory::SystemKeywordInfo("WN", Binary(12, 0x20), true, true, "VSBK", "WN"), inventory::SystemKeywordInfo("RG", Binary(4, 0x20), true, true, "VSBK", "RG"), inventory::SystemKeywordInfo("FV", Binary(32, 0x20), false, true, "VSBK", "FV")}}, {"VCEN", {inventory::SystemKeywordInfo("FC", Binary(8, 0x20), true, false, "VSBK", "FC"), inventory::SystemKeywordInfo("SE", Binary(7, 0x20), true, true, "VSBK", "ES")}}, {"LXR0", {inventory::SystemKeywordInfo("LX", Binary(8, 0x00), true, false, "VSBK", "LX")}}, {"UTIL", {inventory::SystemKeywordInfo("D0", Binary(1, 0x00), true, true, "VSBK", "D0"), inventory::SystemKeywordInfo("D1", Binary(1, 0x00), false, true, "VSBK", "D1"), inventory::SystemKeywordInfo("F0", Binary(8, 0x00), false, true, "VSBK", "F0"), inventory::SystemKeywordInfo("F5", Binary(16, 0x00), false, true, "VSBK", "F5"), inventory::SystemKeywordInfo("F6", Binary(16, 0x00), false, true, "VSBK", "F6")}}}; /** @brief Return the hex representation of the incoming byte * * @param [in] c - The input byte * @returns The hex representation of the byte as a character. */ constexpr auto toHex(size_t c) { constexpr auto map = "0123456789abcdef"; return map[c]; } namespace inventory { /** @brief API to obtain a dictionary of path -> services * where path is in subtree and services is of the type * returned by the GetObject method. * * @param [in] root - Root path for object subtree * @param [in] depth - Maximum subtree depth required * @param [in] interfaces - Array to interfaces for which * result is required. * @return A dictionary of Path -> services */ MapperResponse getObjectSubtreeForInterfaces(const std::string& root, const int32_t depth, const std::vector& interfaces); /** * @brief API to call GetObject API of mapper. * * @param[in] objectPath - inventory path. * @param[in] interfaces - List of interfaces. * * @return - response of the API call. */ MapperGetObjectResponse getObject(const std::string& objectPath, const std::vector& interfaces); } // namespace inventory /**@brief This API reads 2 Bytes of data and swap the read data * @param[in] iterator- Pointer pointing to the data to be read * @return returns 2 Byte data read at the given pointer */ openpower::vpd::constants::LE2ByteData readUInt16LE(Binary::const_iterator iterator); /** @brief Encodes a keyword for D-Bus. * @param[in] kw - kwd data in string format * @param[in] encoding - required for kwd data */ std::string encodeKeyword(const std::string& kw, const std::string& encoding); /** @brief Reads a property from the inventory manager given object path, * intreface and property. * @param[in] obj - object path * @param[in] inf - interface * @param[in] prop - property whose value is fetched * @return [out] - value of the property */ std::string readBusProperty(const std::string& obj, const std::string& inf, const std::string& prop); /** @brief A templated function to read D-Bus properties. * * @param[in] service - Service path * @param[in] object - object path * @param[in] inf - interface * @param[in] prop - property whose value is fetched * @return The property value of its own type. */ template T readDBusProperty(const std::string& service, const std::string& object, const std::string& inf, const std::string& prop) { T retVal{}; try { auto bus = sdbusplus::bus::new_default(); auto properties = bus.new_method_call(service.c_str(), object.c_str(), "org.freedesktop.DBus.Properties", "Get"); properties.append(inf); properties.append(prop); auto result = bus.call(properties); result.read(retVal); } catch (const sdbusplus::exception::SdBusError& e) { std::cerr << e.what(); } return retVal; } /** @brief A templated method to get all D-Bus properties * * @param[in] service - Service path * @param[in] object - Object path * @param[in] inf - Interface * * @return All properties under the given interface. */ template T getAllDBusProperty(const std::string& service, const std::string& object, const std::string& inf) { T retVal{}; try { auto bus = sdbusplus::bus::new_default(); auto allProperties = bus.new_method_call(service.c_str(), object.c_str(), "org.freedesktop.DBus.Properties", "GetAll"); allProperties.append(inf); auto result = bus.call(allProperties); result.read(retVal); } catch (const sdbusplus::exception::SdBusError& e) { std::cerr << e.what(); } return retVal; } /** * @brief API to create PEL entry * The api makes synchronous call to phosphor-logging create api. * @param[in] additionalData - Map holding the additional data * @param[in] sev - Severity * @param[in] errIntf - error interface */ void createSyncPEL(const std::map& additionalData, const constants::PelSeverity& sev, const std::string& errIntf); /** * @brief Api to create PEL. * A wrapper api through which sync/async call to phosphor-logging create api * can be made as and when required. * sdBus as nullptr will result in sync call else async call will be made with * just "DESCRIPTION" key/value pair in additional data. * To make asyn call with more fields in additional data call * "sd_bus_call_method_async" in place. * * @param[in] additionalData - Map of additional data. * @param[in] sev - severity of the PEL. * @param[in] errIntf - Error interface to be used in PEL. * @param[in] sdBus - Pointer to Sd-Bus */ void createPEL(const std::map& additionalData, const constants::PelSeverity& sev, const std::string& errIntf, sd_bus* sdBus); /** * @brief getVpdFilePath * Get vpd file path corresponding to the given object path. * @param[in] - json file path * @param[in] - Object path * @return - Vpd file path */ inventory::VPDfilepath getVpdFilePath(const std::string& jsonFile, const std::string& ObjPath); /** * @brief isPathInJson * API which checks for the presence of the given eeprom path in the given json. * @param[in] - eepromPath * @return - true if the eeprom is present in the json; false otherwise */ bool isPathInJson(const std::string& eepromPath); /** * @brief isRecKwInDbusJson * API which checks whether the given keyword under the given record is to be * published on dbus or not. Checks against the keywords present in * dbus_property.json. * @param[in] - record name * @param[in] - keyword name * @return - true if the record-keyword pair is present in dbus_property.json; * false otherwise. */ bool isRecKwInDbusJson(const std::string& record, const std::string& keyword); /** * @brief Check the type of VPD. * * Checks the type of vpd based on the start tag. * @param[in] vector - Vpd data in vector format * * @return enum of type vpdType */ constants::vpdType vpdTypeCheck(const Binary& vector); /* * @brief This method does nothing. Just an empty function to return null * at the end of variadic template args */ inline std::string getCommand() { return ""; } /** * @brief This function to arrange all arguments to make commandy * @param[in] arguments to create the command * @return cmd - command string */ template inline std::string getCommand(T arg1, Types... args) { std::string cmd = " " + arg1 + getCommand(args...); return cmd; } /** * @brief This API takes arguments, creates a shell command line and executes * them. * @param[in] arguments for command * @returns output of that command */ template inline std::vector executeCmd(T&& path, Types... args) { std::vector stdOutput; std::array buffer; std::string cmd = path + getCommand(args...); std::unique_ptr pipe(popen(cmd.c_str(), "r"), pclose); if (!pipe) { throw std::runtime_error("popen() failed!"); } while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) { stdOutput.emplace_back(buffer.data()); } return stdOutput; } /** @brief This API checks for IM and HW keywords, and based * on these values decides which system json to be used. * @param[in] vpdMap - parsed vpd * @returns System json path */ std::string getSystemsJson(const Parsed& vpdMap); /** @brief Reads HW Keyword from the vpd * @param[in] vpdMap - parsed vpd * @returns value of HW Keyword */ const std::string getHW(const Parsed& vpdMap); /** @brief Reads IM Keyword from the vpd * @param[in] vpdMap - parsed vpd * @returns value of IM Keyword */ const std::string getIM(const Parsed& vpdMap); /** @brief Translate udev event generated path to a generic /sys/bus eeprom path * @param[io] file - path generated from udev event. * @param[in] driver - kernel driver used by the device. */ void udevToGenericPath(std::string& file, const std::string& driver); /** * @brief API to generate a vpd name in some pattern. * This vpd-name denotes name of the bad vpd file. * For i2c eeproms - the pattern of the vpd-name will be * i2c--. For spi eeproms - the pattern of the * vpd-name will be spi-. * * @param[in] file - file path of the vpd * @return the vpd-name. */ std::string getBadVpdName(const std::string& file); /** * @brief API which dumps the broken/bad vpd in a directory * When the vpd is bad, this api places the bad vpd file inside * "/tmp/bad-vpd" in BMC, in order to collect bad VPD data as a part of user * initiated BMC dump. * * @param[in] file - bad vpd file path * @param[in] vpdVector - bad vpd vector */ void dumpBadVpd(const std::string& file, const Binary& vpdVector); /* * @brief This function fetches the value for given keyword in the given record * from vpd data and returns this value. * * @param[in] vpdMap - vpd to find out the data * @param[in] rec - Record under which desired keyword exists * @param[in] kwd - keyword to read the data from * * @returns keyword value if record/keyword combination found * empty string if record or keyword is not found. */ const std::string getKwVal(const Parsed& vpdMap, const std::string& rec, const std::string& kwd); /** @brief This creates a complete command using all it's input parameters, * to bind or unbind the driver. * @param[in] devNameAddr - device address on that bus * @param[in] busType - i2c, spi * @param[in] driverType - type of driver like at24 * @param[in] bindOrUnbind - either bind or unbind * @returns Command to bind or unbind the driver. */ inline std::string createBindUnbindDriverCmnd(const std::string& devNameAddr, const std::string& busType, const std::string& driverType, const std::string& bindOrUnbind) { return ("echo " + devNameAddr + " > /sys/bus/" + busType + "/drivers/" + driverType + "/" + bindOrUnbind); } /** * @brief Get Printable Value * * Checks if the value has non printable characters. * Returns hex value if non printable char is found else * returns ascii value. * * @param[in] kwVal - Reference of the input data, Keyword value * @return printable value - either in hex or in ascii. */ std::string getPrintableValue(const std::variant& kwVal); /** * @brief Convert array to hex string. * @param[in] kwVal - input data, Keyword value * @return hexadecimal string of bytes. */ std::string hexString(const std::variant& kwVal); /** * @brief Return presence of the FRU. * * This API returns the presence information of the FRU corresponding to the * given EEPROM. If the JSON contains no information about presence detect, this * will return an empty optional. Else it will get the presence GPIO information * from the JSON and return the appropriate present status. * In case of GPIO find/read errors, it will return false. * * @param[in] json - The VPD JSON * @param[in] file - EEPROM file path * @return Empty optional if there is no presence info. Else returns presence * based on the GPIO read. */ std::optional isPresent(const nlohmann::json& json, const std::string& file); /** * @brief Performs any pre-action needed to get the FRU setup for * collection. * * @param[in] json - json object * @param[in] file - eeprom file path * @return - success or failure */ bool executePreAction(const nlohmann::json& json, const std::string& file); /** * @brief This API will be called at the end of VPD collection to perform any * post actions. * * @param[in] json - json object * @param[in] file - eeprom file path */ void executePostFailAction(const nlohmann::json& json, const std::string& file); /** * @brief Helper function to insert or merge in map. * * This method checks in the given inventory::InterfaceMap if the given * interface key is existing or not. If the interface key already exists, given * property map is inserted into it. If the key does'nt exist then given * interface and property map pair is newly created. If the property present in * propertymap already exist in the InterfaceMap, then the new property value is * ignored. * * @param[in,out] map - map object of type inventory::InterfaceMap only. * @param[in] interface - Interface name. * @param[in] property - new property map that needs to be emplaced. */ void insertOrMerge(inventory::InterfaceMap& map, const inventory::Interface& interface, inventory::PropertyMap&& property); /** * @brief Utility API to set a D-Bus property * * This calls org.freedesktop.DBus.Properties;Set method with the supplied * arguments * * @tparam T Template type of the D-Bus property * @param service[in] - The D-Bus service name. * @param object[in] - The D-Bus object on which the property is to be set. * @param interface[in] - The D-Bus interface to which the property belongs. * @param propertyName[in] - The name of the property to set. * @param propertyValue[in] - The value of the property. */ template void setBusProperty(const std::string& service, const std::string& object, const std::string& interface, const std::string& propertyName, const std::variant& propertyValue) { try { auto bus = sdbusplus::bus::new_default(); auto method = bus.new_method_call(service.c_str(), object.c_str(), "org.freedesktop.DBus.Properties", "Set"); method.append(interface); method.append(propertyName); method.append(propertyValue); bus.call(method); } catch (const sdbusplus::exception::SdBusError& e) { std::cerr << e.what() << std::endl; } } /** * @brief Reads BIOS Attribute by name. * * @param attrName[in] - The BIOS attribute name. * @return std::variant - The BIOS attribute value. */ std::variant readBIOSAttribute(const std::string& attrName); /** * @brief Returns the power state for chassis0 * @return The chassis power state. */ std::string getPowerState(); /** * @brief Reads VPD from the supplied EEPROM * * This function reads the given VPD EEPROM file and returns its contents as a * byte array. It handles any offsets into the file that need to be taken care * of by looking up the VPD JSON for a possible offset key. * * @param js[in] - The VPD JSON Object * @param file[in] - The path to the EEPROM to read * @return A byte array containing the raw VPD. */ Binary getVpdDataInVector(const nlohmann::json& js, const std::string& file); /** * @brief Get D-bus name for the keyword * Some of the VPD keywords has different name in PIM when compared with its * name from hardware. This method returns the D-bus name for the given keyword. * * @param[in] keyword - Keyword name * @return D-bus name for the keyword */ std::string getDbusNameForThisKw(const std::string& keyword); /** * @brief API to remove VPD data from Dbus on removal of FRU. * * @param[in] objPath - Inventory path of the FRU. * @param[out] interfacesPropMap - Map of interface, property and value. */ void clearVpdOnRemoval(const std::string& objPath, inventory::InterfaceMap& interfacesPropMap); /** * @brief Find backup VPD path if any for the system VPD * * @param[out] backupEepromPath - Backup VPD path * @param[out] backupInvPath - Backup inventory path * @param[in] js - Inventory JSON object */ void findBackupVPDPaths(std::string& backupEepromPath, std::string& backupInvPath, const nlohmann::json& js); /** * @brief Get backup VPD's record and keyword for the given system VPD keyword * * @param[in,out] record - Record name * @param[in,out] keyword - Keyword name */ void getBackupRecordKeyword(std::string& record, std::string& keyword); } // namespace vpd } // namespace openpower