From b9d86f4c791823c8bc0387578effcf2ef88c0231 Mon Sep 17 00:00:00 2001 From: Tom Joseph Date: Wed, 26 Jul 2017 18:03:47 +0530 Subject: dcmi: Refactor get power limit command Change-Id: I31755eaccb17c013fd2c1a3e43e7ec95a1947ba3 Signed-off-by: Tom Joseph --- dcmihandler.cpp | 122 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 70 insertions(+), 52 deletions(-) (limited to 'dcmihandler.cpp') diff --git a/dcmihandler.cpp b/dcmihandler.cpp index 9205207..2e0204d 100644 --- a/dcmihandler.cpp +++ b/dcmihandler.cpp @@ -23,6 +23,9 @@ constexpr auto POWER_CAP_ENABLE_PROP = "PowerCapEnable"; using namespace phosphor::logging; +namespace dcmi +{ + uint32_t getPcap(sdbusplus::bus::bus& bus) { auto settingService = ipmi::getService(bus, @@ -39,14 +42,12 @@ uint32_t getPcap(sdbusplus::bus::bus& bus) if (reply.is_method_error()) { log("Error in getPcap prop"); - // TODO openbmc/openbmc#851 - Once available, throw returned error - // and return IPMI_CC_UNSPECIFIED_ERROR to caller - return 0; + elog(); } sdbusplus::message::variant pcap; reply.read(pcap); - return sdbusplus::message::variant_ns::get(pcap); + return pcap.get(); } bool getPcapEnabled(sdbusplus::bus::bus& bus) @@ -65,58 +66,14 @@ bool getPcapEnabled(sdbusplus::bus::bus& bus) if (reply.is_method_error()) { log("Error in getPcapEnabled prop"); - // TODO openbmc/openbmc#851 - Once available, throw returned error - // and return IPMI_CC_UNSPECIFIED_ERROR to caller - return false; + elog(); } sdbusplus::message::variant pcapEnabled; reply.read(pcapEnabled); - return sdbusplus::message::variant_ns::get(pcapEnabled); + return pcapEnabled.get(); } -ipmi_ret_t ipmi_dcmi_get_power_limit(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) -{ - // Default to no power cap enabled - ipmi_ret_t rc = IPMI_DCMI_CC_NO_ACTIVE_POWER_LIMIT; - - // Get our sdbus object - sd_bus *bus = ipmid_get_sd_bus_connection(); - sdbusplus::bus::bus sdbus {bus}; - - // Read our power cap settings - auto pcap = getPcap(sdbus); - auto pcapEnable = getPcapEnabled(sdbus); - if(pcapEnable) - { - // indicate power cap enabled with success return code - rc = IPMI_CC_OK; - } - - uint8_t pcapBytes[2] = {0}; - pcapBytes[1] = (pcap & 0xFF00) >> 8; - pcapBytes[0] = pcap & 0xFF; - // dcmi-v1-5-rev-spec.pdf 6.6.2. - uint8_t data_response[] = { 0xDC, 0x00, 0x00, 0x01, pcapBytes[0], - pcapBytes[1], 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01}; - - - log("IPMI DCMI POWER CAP INFO", - entry("DCMI_PCAP=%u",pcap), - entry("DCMI_PCAP_ENABLE=%u",pcapEnable)); - - memcpy(response, data_response, sizeof(data_response)); - *data_len = sizeof(data_response); - - return rc; -} - -namespace dcmi -{ - void readAssetTagObjectTree(dcmi::assettag::ObjectTree& objectTree) { static constexpr auto mapperBusName = "xyz.openbmc_project.ObjectMapper"; @@ -210,6 +167,67 @@ void writeAssetTag(const std::string& assetTag) } // namespace dcmi +ipmi_ret_t getPowerLimit(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::GetPowerLimitResponse)); + 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()}; + uint32_t pcapValue = 0; + bool pcapEnable = false; + + try + { + pcapValue = dcmi::getPcap(sdbus); + pcapEnable = dcmi::getPcapEnabled(sdbus); + } + catch (InternalFailure& e) + { + *data_len = 0; + return IPMI_CC_UNSPECIFIED_ERROR; + } + + responseData->groupID = dcmi::groupExtId; + + /* + * Exception action if power limit is exceeded and cannot be controlled + * with the correction time limit is hardcoded to Hard Power Off system + * and log event to SEL. + */ + constexpr auto exception = 0x01; + responseData->exceptionAction = exception; + + responseData->powerLimit = static_cast(pcapValue); + + /* + * Correction time limit and Statistics sampling period is currently not + * populated. + */ + + *data_len = outPayload.size(); + memcpy(response, outPayload.data(), *data_len); + + if (pcapEnable) + { + return IPMI_CC_OK; + } + else + { + return IPMI_DCMI_CC_NO_ACTIVE_POWER_LIMIT; + } +} + 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) @@ -348,8 +366,8 @@ ipmi_ret_t setAssetTag(ipmi_netfn_t netfn, ipmi_cmd_t cmd, void register_netfn_dcmi_functions() { // - printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_POWER); - ipmi_register_callback(NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_POWER, NULL, ipmi_dcmi_get_power_limit, + printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_POWER_LIMIT); + ipmi_register_callback(NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_POWER_LIMIT, NULL, getPowerLimit, PRIVILEGE_USER); // -- cgit v1.2.1