From 6c8d51baee01211c671567881dec27c327ae2c86 Mon Sep 17 00:00:00 2001 From: Tom Joseph Date: Wed, 26 Jul 2017 18:18:06 +0530 Subject: dcmi: Implement activate/deactivate power limit Resolves openbmc/openbmc#1955 Change-Id: I4f97e3f22e9a36879dba56a06ae3c6bb5d34e34c Signed-off-by: Tom Joseph --- dcmihandler.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ dcmihandler.hpp | 28 +++++++++++++++++++++++++ 2 files changed, 93 insertions(+) diff --git a/dcmihandler.cpp b/dcmihandler.cpp index 11a3730..0508b81 100644 --- a/dcmihandler.cpp +++ b/dcmihandler.cpp @@ -95,6 +95,27 @@ void setPcap(sdbusplus::bus::bus& bus, const uint32_t powerCap) } } +void setPcapEnable(sdbusplus::bus::bus& bus, bool enabled) +{ + auto service = ipmi::getService(bus, PCAP_INTERFACE, PCAP_PATH); + + auto method = bus.new_method_call(service.c_str(), + PCAP_PATH, + "org.freedesktop.DBus.Properties", + "Set"); + + method.append(PCAP_INTERFACE, POWER_CAP_ENABLE_PROP); + method.append(sdbusplus::message::variant(enabled)); + + auto reply = bus.call(method); + + if (reply.is_method_error()) + { + log("Error in setPcapEnabled property"); + elog(); + } +} + void readAssetTagObjectTree(dcmi::assettag::ObjectTree& objectTree) { static constexpr auto mapperBusName = "xyz.openbmc_project.ObjectMapper"; @@ -288,6 +309,45 @@ ipmi_ret_t setPowerLimit(ipmi_netfn_t netfn, ipmi_cmd_t cmd, return IPMI_CC_OK; } +ipmi_ret_t applyPowerLimit(ipmi_netfn_t netfn, ipmi_cmd_t cmd, + ipmi_request_t request, ipmi_response_t response, + ipmi_data_len_t data_len, ipmi_context_t context) +{ + auto requestData = reinterpret_cast + (request); + std::vector outPayload(sizeof(dcmi::ApplyPowerLimitResponse)); + auto responseData = reinterpret_cast + (outPayload.data()); + + if (requestData->groupID != dcmi::groupExtId) + { + *data_len = 0; + return IPMI_CC_INVALID_FIELD_REQUEST; + } + + sdbusplus::bus::bus sdbus {ipmid_get_sd_bus_connection()}; + + try + { + dcmi::setPcapEnable(sdbus, + static_cast(requestData->powerLimitAction)); + } + catch (InternalFailure& e) + { + *data_len = 0; + return IPMI_CC_UNSPECIFIED_ERROR; + } + + log("Set Power Cap Enable", + entry("POWERCAPENABLE=%u", requestData->powerLimitAction)); + + responseData->groupID = dcmi::groupExtId; + memcpy(response, outPayload.data(), outPayload.size()); + *data_len = outPayload.size(); + + return IPMI_CC_OK; +} + ipmi_ret_t getAssetTag(ipmi_netfn_t netfn, ipmi_cmd_t cmd, ipmi_request_t request, ipmi_response_t response, ipmi_data_len_t data_len, ipmi_context_t context) @@ -435,6 +495,11 @@ void register_netfn_dcmi_functions() ipmi_register_callback(NETFUN_GRPEXT, IPMI_CMD_DCMI_SET_POWER_LIMIT, NULL, setPowerLimit, PRIVILEGE_OPERATOR); + // + printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_GRPEXT, IPMI_CMD_DCMI_APPLY_POWER_LIMIT); + ipmi_register_callback(NETFUN_GRPEXT, IPMI_CMD_DCMI_APPLY_POWER_LIMIT, NULL, applyPowerLimit, + PRIVILEGE_OPERATOR); + // printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_ASSET_TAG); ipmi_register_callback(NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_ASSET_TAG, NULL, getAssetTag, diff --git a/dcmihandler.hpp b/dcmihandler.hpp index e318294..cb46d5c 100644 --- a/dcmihandler.hpp +++ b/dcmihandler.hpp @@ -12,6 +12,7 @@ enum ipmi_netfn_sen_cmds // Get capability bits IPMI_CMD_DCMI_GET_POWER_LIMIT = 0x03, IPMI_CMD_DCMI_SET_POWER_LIMIT = 0x04, + IPMI_CMD_DCMI_APPLY_POWER_LIMIT = 0x05, IPMI_CMD_DCMI_GET_ASSET_TAG = 0x06, IPMI_CMD_DCMI_SET_ASSET_TAG = 0x08, }; @@ -178,6 +179,33 @@ 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)); + } // namespace dcmi #endif -- cgit v1.2.1