| #ifndef __HOST_IPMI_DCMI_HANDLER_H__ |
| #define __HOST_IPMI_DCMI_HANDLER_H__ |
| |
| #include "nlohmann/json.hpp" |
| |
| #include <map> |
| #include <sdbusplus/bus.hpp> |
| #include <string> |
| #include <vector> |
| |
| namespace dcmi |
| { |
| |
| using NumInstances = size_t; |
| using Json = nlohmann::json; |
| |
| enum Commands |
| { |
| // Get capability bits |
| GET_CAPABILITIES = 0x01, |
| GET_POWER_READING = 0x02, |
| GET_POWER_LIMIT = 0x03, |
| SET_POWER_LIMIT = 0x04, |
| APPLY_POWER_LIMIT = 0x05, |
| GET_ASSET_TAG = 0x06, |
| GET_SENSOR_INFO = 0x07, |
| SET_ASSET_TAG = 0x08, |
| GET_MGMNT_CTRL_ID_STR = 0x09, |
| SET_MGMNT_CTRL_ID_STR = 0x0A, |
| GET_TEMP_READINGS = 0x10, |
| SET_CONF_PARAMS = 0x12, |
| GET_CONF_PARAMS = 0x13, |
| }; |
| |
| static constexpr auto propIntf = "org.freedesktop.DBus.Properties"; |
| static constexpr auto assetTagIntf = |
| "xyz.openbmc_project.Inventory.Decorator.AssetTag"; |
| static constexpr auto assetTagProp = "AssetTag"; |
| static constexpr auto networkServiceName = "xyz.openbmc_project.Network"; |
| static constexpr auto networkConfigObj = "/xyz/openbmc_project/network/config"; |
| static constexpr auto networkConfigIntf = |
| "xyz.openbmc_project.Network.SystemConfiguration"; |
| static constexpr auto hostNameProp = "HostName"; |
| static constexpr auto temperatureSensorType = 0x01; |
| static constexpr auto maxInstances = 255; |
| static constexpr auto configFile = |
| "/usr/share/ipmi-providers/dcmi_sensors.json"; |
| static constexpr auto ethernetIntf = |
| "xyz.openbmc_project.Network.EthernetInterface"; |
| static constexpr auto ethernetDefaultChannelNum = 0x1; |
| static constexpr auto networkRoot = "/xyz/openbmc_project/network"; |
| static constexpr auto dhcpObj = "/xyz/openbmc_project/network/config/dhcp"; |
| static constexpr auto dhcpIntf = |
| "xyz.openbmc_project.Network.DHCPConfiguration"; |
| static constexpr auto systemBusName = "org.freedesktop.systemd1"; |
| static constexpr auto systemPath = "/org/freedesktop/systemd1"; |
| static constexpr auto systemIntf = "org.freedesktop.systemd1.Manager"; |
| |
| namespace assettag |
| { |
| |
| using ObjectPath = std::string; |
| using Service = std::string; |
| using Interfaces = std::vector<std::string>; |
| using ObjectTree = std::map<ObjectPath, std::map<Service, Interfaces>>; |
| |
| } // namespace assettag |
| |
| namespace temp_readings |
| { |
| static constexpr auto maxDataSets = 8; |
| static constexpr auto maxTemp = 127; // degrees C |
| |
| /** @struct Response |
| * |
| * DCMI payload for Get Temperature Readings response |
| */ |
| struct Response |
| { |
| #if BYTE_ORDER == LITTLE_ENDIAN |
| uint8_t temperature : 7; //!< Temperature reading in Celsius |
| uint8_t sign : 1; //!< Sign bit |
| #endif |
| #if BYTE_ORDER == BIG_ENDIAN |
| uint8_t sign : 1; //!< Sign bit |
| uint8_t temperature : 7; //!< Temperature reading in Celsius |
| #endif |
| uint8_t instance; //!< Entity instance number |
| } __attribute__((packed)); |
| |
| using ResponseList = std::vector<Response>; |
| using Value = uint8_t; |
| using Sign = bool; |
| using Temperature = std::tuple<Value, Sign>; |
| } // namespace temp_readings |
| |
| namespace sensor_info |
| { |
| static constexpr auto maxRecords = 8; |
| |
| /** @struct Response |
| * |
| * DCMI payload for Get Sensor Info response |
| */ |
| struct Response |
| { |
| uint8_t recordIdLsb; //!< SDR record id LS byte |
| uint8_t recordIdMsb; //!< SDR record id MS byte |
| } __attribute__((packed)); |
| |
| using ResponseList = std::vector<Response>; |
| } // namespace sensor_info |
| |
| static constexpr auto groupExtId = 0xDC; |
| |
| static constexpr auto assetTagMaxOffset = 62; |
| static constexpr auto assetTagMaxSize = 63; |
| static constexpr auto maxBytes = 16; |
| static constexpr size_t maxCtrlIdStrLen = 63; |
| |
| /** @struct GetAssetTagRequest |
| * |
| * DCMI payload for Get Asset Tag command request. |
| */ |
| struct GetAssetTagRequest |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t offset; //!< Offset to read. |
| uint8_t bytes; //!< Number of bytes to read. |
| } __attribute__((packed)); |
| |
| /** @struct GetAssetTagResponse |
| * |
| * DCMI payload for Get Asset Tag command response. |
| */ |
| struct GetAssetTagResponse |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t tagLength; //!< Total asset tag length. |
| } __attribute__((packed)); |
| |
| /** @struct SetAssetTagRequest |
| * |
| * DCMI payload for Set Asset Tag command request. |
| */ |
| struct SetAssetTagRequest |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t offset; //!< Offset to write. |
| uint8_t bytes; //!< Number of bytes to write. |
| } __attribute__((packed)); |
| |
| /** @struct SetAssetTagResponse |
| * |
| * DCMI payload for Set Asset Tag command response. |
| */ |
| struct SetAssetTagResponse |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t tagLength; //!< Total asset tag length. |
| } __attribute__((packed)); |
| |
| /** @brief Read the object tree to fetch the object path that implemented the |
| * Asset tag interface. |
| * |
| * @param[in,out] objectTree - object tree |
| * |
| * @return On success return the object tree with the object path that |
| * implemented the AssetTag interface. |
| */ |
| void readAssetTagObjectTree(dcmi::assettag::ObjectTree& objectTree); |
| |
| /** @brief Read the asset tag of the server |
| * |
| * @return On success return the asset tag. |
| */ |
| std::string readAssetTag(); |
| |
| /** @brief Write the asset tag to the asset tag DBUS property |
| * |
| * @param[in] assetTag - Asset Tag to be written to the property. |
| */ |
| void writeAssetTag(const std::string& assetTag); |
| |
| /** @brief Read the current power cap value |
| * |
| * @param[in] bus - dbus connection |
| * |
| * @return On success return the power cap value. |
| */ |
| uint32_t getPcap(sdbusplus::bus::bus& bus); |
| |
| /** @brief Check if the power capping is enabled |
| * |
| * @param[in] bus - dbus connection |
| * |
| * @return true if the powerCap is enabled and false if the powercap |
| * is disabled. |
| */ |
| bool getPcapEnabled(sdbusplus::bus::bus& bus); |
| |
| /** @struct GetPowerLimitRequest |
| * |
| * DCMI payload for Get Power Limit command request. |
| */ |
| struct GetPowerLimitRequest |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint16_t reserved; //!< Reserved |
| } __attribute__((packed)); |
| |
| /** @struct GetPowerLimitResponse |
| * |
| * DCMI payload for Get Power Limit command response. |
| */ |
| struct GetPowerLimitResponse |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint16_t reserved; //!< Reserved. |
| uint8_t exceptionAction; //!< Exception action. |
| uint16_t powerLimit; //!< Power limit requested in watts. |
| uint32_t correctionTime; //!< Correction time limit in milliseconds. |
| uint16_t reserved1; //!< Reserved. |
| uint16_t samplingPeriod; //!< Statistics sampling period in seconds. |
| } __attribute__((packed)); |
| |
| /** @brief Set the power cap value |
| * |
| * @param[in] bus - dbus connection |
| * @param[in] powerCap - power cap value |
| */ |
| void setPcap(sdbusplus::bus::bus& bus, const uint32_t powerCap); |
| |
| /** @struct SetPowerLimitRequest |
| * |
| * DCMI payload for Set Power Limit command request. |
| */ |
| struct SetPowerLimitRequest |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint16_t reserved; //!< Reserved |
| uint8_t reserved1; //!< Reserved |
| uint8_t exceptionAction; //!< Exception action. |
| uint16_t powerLimit; //!< Power limit requested in watts. |
| uint32_t correctionTime; //!< Correction time limit in milliseconds. |
| uint16_t reserved2; //!< Reserved. |
| uint16_t samplingPeriod; //!< Statistics sampling period in seconds. |
| } __attribute__((packed)); |
| |
| /** @struct SetPowerLimitResponse |
| * |
| * DCMI payload for Set Power Limit command response. |
| */ |
| struct SetPowerLimitResponse |
| { |
| uint8_t groupID; //!< Group extension identification. |
| } __attribute__((packed)); |
| |
| /** @brief Enable or disable the power capping |
| * |
| * @param[in] bus - dbus connection |
| * @param[in] enabled - enable/disable |
| */ |
| void setPcapEnable(sdbusplus::bus::bus& bus, bool enabled); |
| |
| /** @struct ApplyPowerLimitRequest |
| * |
| * DCMI payload for Activate/Deactivate Power Limit command request. |
| */ |
| struct ApplyPowerLimitRequest |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t powerLimitAction; //!< Power limit activation |
| uint16_t reserved; //!< Reserved |
| } __attribute__((packed)); |
| |
| /** @struct ApplyPowerLimitResponse |
| * |
| * DCMI payload for Acticate/Deactivate Power Limit command response. |
| */ |
| struct ApplyPowerLimitResponse |
| { |
| uint8_t groupID; //!< Group extension identification. |
| } __attribute__((packed)); |
| |
| /** @struct GetMgmntCtrlIdStrRequest |
| * |
| * DCMI payload for Get Management Controller Identifier String cmd request. |
| */ |
| struct GetMgmntCtrlIdStrRequest |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t offset; //!< Offset to read. |
| uint8_t bytes; //!< Number of bytes to read. |
| } __attribute__((packed)); |
| |
| /** @struct GetMgmntCtrlIdStrResponse |
| * |
| * DCMI payload for Get Management Controller Identifier String cmd response. |
| */ |
| struct GetMgmntCtrlIdStrResponse |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t strLen; //!< ID string length. |
| char data[]; //!< ID string |
| } __attribute__((packed)); |
| |
| /** @struct SetMgmntCtrlIdStrRequest |
| * |
| * DCMI payload for Set Management Controller Identifier String cmd request. |
| */ |
| struct SetMgmntCtrlIdStrRequest |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t offset; //!< Offset to write. |
| uint8_t bytes; //!< Number of bytes to read. |
| char data[]; //!< ID string |
| } __attribute__((packed)); |
| |
| /** @struct GetMgmntCtrlIdStrResponse |
| * |
| * DCMI payload for Get Management Controller Identifier String cmd response. |
| */ |
| struct SetMgmntCtrlIdStrResponse |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t offset; //!< Last Offset Written. |
| } __attribute__((packed)); |
| |
| /** @enum DCMICapParameters |
| * |
| * DCMI Capability parameters |
| */ |
| enum class DCMICapParameters |
| { |
| SUPPORTED_DCMI_CAPS = 0x01, //!< Supported DCMI Capabilities |
| MANDATORY_PLAT_ATTRIBUTES = 0x02, //!< Mandatory Platform Attributes |
| OPTIONAL_PLAT_ATTRIBUTES = 0x03, //!< Optional Platform Attributes |
| MANAGEABILITY_ACCESS_ATTRIBUTES = 0x04, //!< Manageability Access Attributes |
| }; |
| |
| /** @struct GetDCMICapRequest |
| * |
| * DCMI payload for Get capabilities cmd request. |
| */ |
| struct GetDCMICapRequest |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t param; //!< Capability parameter selector. |
| } __attribute__((packed)); |
| |
| /** @struct GetDCMICapRequest |
| * |
| * DCMI payload for Get capabilities cmd response. |
| */ |
| struct GetDCMICapResponse |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t major; //!< DCMI Specification Conformance - major ver |
| uint8_t minor; //!< DCMI Specification Conformance - minor ver |
| uint8_t paramRevision; //!< Parameter Revision = 02h |
| uint8_t data[]; //!< Capability array |
| } __attribute__((packed)); |
| |
| /** @struct DCMICap |
| * |
| * DCMI capabilities protocol info. |
| */ |
| struct DCMICap |
| { |
| std::string name; //!< Name of DCMI capability. |
| uint8_t bytePosition; //!< Starting byte number from DCMI spec. |
| uint8_t position; //!< bit position from the DCMI spec. |
| uint8_t length; //!< Length of the value from DCMI spec. |
| }; |
| |
| using DCMICapList = std::vector<DCMICap>; |
| |
| /** @struct DCMICapEntry |
| * |
| * DCMI capabilities list and size for each parameter. |
| */ |
| struct DCMICapEntry |
| { |
| uint8_t size; //!< Size of capability array in bytes. |
| DCMICapList capList; //!< List of capabilities for a parameter. |
| }; |
| |
| using DCMICaps = std::map<DCMICapParameters, DCMICapEntry>; |
| |
| /** @struct GetTempReadingsRequest |
| * |
| * DCMI payload for Get Temperature Readings request |
| */ |
| struct GetTempReadingsRequest |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t sensorType; //!< Type of the sensor |
| uint8_t entityId; //!< Entity ID |
| uint8_t entityInstance; //!< Entity Instance (0 means all instances) |
| uint8_t instanceStart; //!< Instance start (used if instance is 0) |
| } __attribute__((packed)); |
| |
| /** @struct GetTempReadingsResponse |
| * |
| * DCMI header for Get Temperature Readings response |
| */ |
| struct GetTempReadingsResponseHdr |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t numInstances; //!< No. of instances for requested id |
| uint8_t numDataSets; //!< No. of sets of temperature data |
| } __attribute__((packed)); |
| |
| /** @brief Parse out JSON config file containing information |
| * related to sensors. |
| * |
| * @return A json object |
| */ |
| Json parseSensorConfig(); |
| |
| namespace temp_readings |
| { |
| /** @brief Read temperature from a d-bus object, scale it as per dcmi |
| * get temperature reading requirements. |
| * |
| * @param[in] dbusService - the D-Bus service |
| * @param[in] dbusPath - the D-Bus path |
| * |
| * @return A temperature reading |
| */ |
| Temperature readTemp(const std::string& dbusService, |
| const std::string& dbusPath); |
| |
| /** @brief Read temperatures and fill up DCMI response for the Get |
| * Temperature Readings command. This looks at a specific |
| * instance. |
| * |
| * @param[in] type - one of "inlet", "cpu", "baseboard" |
| * @param[in] instance - A non-zero Entity instance number |
| * |
| * @return A tuple, containing a temperature reading and the |
| * number of instances. |
| */ |
| std::tuple<Response, NumInstances> read(const std::string& type, |
| uint8_t instance); |
| |
| /** @brief Read temperatures and fill up DCMI response for the Get |
| * Temperature Readings command. This looks at a range of |
| * instances. |
| * |
| * @param[in] type - one of "inlet", "cpu", "baseboard" |
| * @param[in] instanceStart - Entity instance start index |
| * |
| * @return A tuple, containing a list of temperature readings and the |
| * number of instances. |
| */ |
| std::tuple<ResponseList, NumInstances> readAll(const std::string& type, |
| uint8_t instanceStart); |
| } // namespace temp_readings |
| |
| namespace sensor_info |
| { |
| /** @brief Create response from JSON config. |
| * |
| * @param[in] config - JSON config info about DCMI sensors |
| * |
| * @return Sensor info response |
| */ |
| Response createFromJson(const Json& config); |
| |
| /** @brief Read sensor info and fill up DCMI response for the Get |
| * Sensor Info command. This looks at a specific |
| * instance. |
| * |
| * @param[in] type - one of "inlet", "cpu", "baseboard" |
| * @param[in] instance - A non-zero Entity instance number |
| * @param[in] config - JSON config info about DCMI sensors |
| * |
| * @return A tuple, containing a sensor info response and |
| * number of instances. |
| */ |
| std::tuple<Response, NumInstances> read(const std::string& type, |
| uint8_t instance, const Json& config); |
| |
| /** @brief Read sensor info and fill up DCMI response for the Get |
| * Sensor Info command. This looks at a range of |
| * instances. |
| * |
| * @param[in] type - one of "inlet", "cpu", "baseboard" |
| * @param[in] instanceStart - Entity instance start index |
| * @param[in] config - JSON config info about DCMI sensors |
| * |
| * @return A tuple, containing a list of sensor info responses and the |
| * number of instances. |
| */ |
| std::tuple<ResponseList, NumInstances> |
| readAll(const std::string& type, uint8_t instanceStart, const Json& config); |
| } // namespace sensor_info |
| |
| /** @brief Read power reading from power reading sensor object |
| * |
| * @param[in] bus - dbus connection |
| * |
| * @return total power reading |
| */ |
| int64_t getPowerReading(sdbusplus::bus::bus& bus); |
| |
| /** @struct GetPowerReadingRequest |
| * |
| * DCMI Get Power Reading command request. |
| * Refer DCMI specification Version 1.1 Section 6.6.1 |
| */ |
| struct GetPowerReadingRequest |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t mode; //!< Mode |
| uint8_t modeAttribute; //!< Mode Attributes |
| } __attribute__((packed)); |
| |
| /** @struct GetPowerReadingResponse |
| * |
| * DCMI Get Power Reading command response. |
| * Refer DCMI specification Version 1.1 Section 6.6.1 |
| */ |
| struct GetPowerReadingResponse |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint16_t currentPower; //!< Current power in watts |
| uint16_t minimumPower; //!< Minimum power over sampling duration |
| //!< in watts |
| uint16_t maximumPower; //!< Maximum power over sampling duration |
| //!< in watts |
| uint16_t averagePower; //!< Average power over sampling duration |
| //!< in watts |
| uint32_t timeStamp; //!< IPMI specification based time stamp |
| uint32_t timeFrame; //!< Statistics reporting time period in milli |
| //!< seconds. |
| uint8_t powerReadingState; //!< Power Reading State |
| } __attribute__((packed)); |
| |
| /** @struct GetSensorInfoRequest |
| * |
| * DCMI payload for Get Sensor Info request |
| */ |
| struct GetSensorInfoRequest |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t sensorType; //!< Type of the sensor |
| uint8_t entityId; //!< Entity ID |
| uint8_t entityInstance; //!< Entity Instance (0 means all instances) |
| uint8_t instanceStart; //!< Instance start (used if instance is 0) |
| } __attribute__((packed)); |
| |
| /** @struct GetSensorInfoResponseHdr |
| * |
| * DCMI header for Get Sensor Info response |
| */ |
| struct GetSensorInfoResponseHdr |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t numInstances; //!< No. of instances for requested id |
| uint8_t numRecords; //!< No. of record ids in the response |
| } __attribute__((packed)); |
| /** |
| * @brief Parameters for DCMI Configuration Parameters |
| */ |
| enum class DCMIConfigParameters : uint8_t |
| { |
| ActivateDHCP = 1, |
| DiscoveryConfig, |
| DHCPTiming1, |
| DHCPTiming2, |
| DHCPTiming3, |
| }; |
| |
| /** @struct SetConfParamsRequest |
| * |
| * DCMI Set DCMI Configuration Parameters Command. |
| * Refer DCMI specification Version 1.1 Section 6.1.2 |
| */ |
| struct SetConfParamsRequest |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t paramSelect; //!< Parameter selector. |
| uint8_t setSelect; //!< Set Selector (use 00h for parameters that only |
| //!< have one set). |
| uint8_t data[]; //!< Configuration parameter data. |
| } __attribute__((packed)); |
| |
| /** @struct SetConfParamsResponse |
| * |
| * DCMI Set DCMI Configuration Parameters Command response. |
| * Refer DCMI specification Version 1.1 Section 6.1.2 |
| */ |
| struct SetConfParamsResponse |
| { |
| uint8_t groupID; //!< Group extension identification. |
| } __attribute__((packed)); |
| |
| /** @struct GetConfParamsRequest |
| * |
| * DCMI Get DCMI Configuration Parameters Command. |
| * Refer DCMI specification Version 1.1 Section 6.1.3 |
| */ |
| struct GetConfParamsRequest |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t paramSelect; //!< Parameter selector. |
| uint8_t setSelect; //!< Set Selector. Selects a given set of parameters |
| //!< under a given Parameter selector value. 00h if |
| //!< parameter doesn't use a Set Selector. |
| } __attribute__((packed)); |
| |
| /** @struct GetConfParamsResponse |
| * |
| * DCMI Get DCMI Configuration Parameters Command response. |
| * Refer DCMI specification Version 1.1 Section 6.1.3 |
| */ |
| struct GetConfParamsResponse |
| { |
| uint8_t groupID; //!< Group extension identification. |
| uint8_t major; //!< DCMI Spec Conformance - major ver = 01h. |
| uint8_t minor; //!< DCMI Spec Conformance - minor ver = 05h. |
| uint8_t paramRevision; //!< Parameter Revision = 01h. |
| uint8_t data[]; //!< Parameter data. |
| |
| } __attribute__((packed)); |
| |
| } // namespace dcmi |
| |
| #endif |