From e29be41f1d014a55e93abd3e55ac23f158f5fa16 Mon Sep 17 00:00:00 2001 From: Dhruvaraj Subhashchandran Date: Tue, 16 Jan 2018 05:11:56 -0600 Subject: DCMI: Implement Get DCMI capabilities info command. This commit adds ipmi changes for supporting the get DCMI capabilities command Resolves openbmc/openbmc#2618 Change-Id: I7d0e7c132f4a8d459351e025fa2bfca9fcf1340b Signed-off-by: Dhruvaraj Subhashchandran --- dcmihandler.cpp | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) (limited to 'dcmihandler.cpp') diff --git a/dcmihandler.cpp b/dcmihandler.cpp index ab3aa58..aa9f14e 100644 --- a/dcmihandler.cpp +++ b/dcmihandler.cpp @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include "nlohmann/json.hpp" #include "xyz/openbmc_project/Common/error.hpp" using namespace phosphor::logging; @@ -21,6 +24,11 @@ constexpr auto PCAP_INTERFACE = "xyz.openbmc_project.Control.Power.Cap"; constexpr auto POWER_CAP_PROP = "PowerCap"; constexpr auto POWER_CAP_ENABLE_PROP = "PowerCapEnable"; +constexpr auto DCMI_PARAMETER_REVISION = 2; +constexpr auto DCMI_SPEC_MAJOR_VERSION = 1; +constexpr auto DCMI_SPEC_MINOR_VERSION = 5; +constexpr auto DCMI_CAP_JSON_FILE = "/usr/share/ipmi-providers/dcmi_cap.json"; + using namespace phosphor::logging; namespace dcmi @@ -603,6 +611,126 @@ ipmi_ret_t setMgmntCtrlIdStr(ipmi_netfn_t netfn, ipmi_cmd_t cmd, return IPMI_CC_OK; } +//List of the capabilities under each parameter +dcmi::DCMICaps dcmiCaps = +{ +//Supported DCMI Capabilities + { + dcmi::DCMICapParameters::SUPPORTED_DCMI_CAPS, + { + 3, {{"PowerManagement", 2, 0, 1}, + {"OOBSecondaryLan", 3, 2, 1}, + {"SerialTMODE", 3, 1, 1}, + {"InBandSystemInterfaceChannel", 3, 0, 1} + } + } + }, +//Mandatory Platform Attributes + { + dcmi::DCMICapParameters::MANDATORY_PLAT_ATTRIBUTES, + { + 5, {{"SELAutoRollOver", 1, 15, 1}, + {"FlushEntireSELUponRollOver", 1, 14, 1}, + {"RecordLevelSELFlushUponRollOver", 1, 13, 1}, + {"NumberOfSELEntries", 1, 0, 12}, + {"TempMonitoringSamplingFreq", 5, 0, 8} + } + } + }, +//Optional Platform Attributes + { + dcmi::DCMICapParameters::OPTIONAL_PLAT_ATTRIBUTES, + { + 2, {{"PowerMgmtDeviceSlaveAddress", 1, 1, 7}, + {"BMCChannelNumber", 2, 4, 4}, + {"DeviceRivision", 2, 0, 4} + } + } + }, +//Manageability Access Attributes + { + dcmi::DCMICapParameters::MANAGEABILITY_ACCESS_ATTRIBUTES, + { + 3, {{"MandatoryPrimaryLanOOBSupport", 1, 0, 8}, + {"OptionalSecondaryLanOOBSupport", 2, 0, 8}, + {"OptionalSerialOOBMTMODECapability", 3, 0, 8} + } + } + } +}; + +ipmi_ret_t getDCMICapabilities(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) +{ + + std::ifstream dcmiCapFile(DCMI_CAP_JSON_FILE); + if (!dcmiCapFile.is_open()) + { + log("DCMI Capabilities file not found"); + return IPMI_CC_UNSPECIFIED_ERROR; + } + + auto data = nlohmann::json::parse(dcmiCapFile, nullptr, false); + if (data.is_discarded()) + { + log("DCMI Capabilities JSON parser failure"); + return IPMI_CC_UNSPECIFIED_ERROR; + } + + auto requestData = reinterpret_cast + (request); + + //get list of capabilities in a parameter + auto caps = + dcmiCaps.find(static_cast(requestData->param)); + if (caps == dcmiCaps.end()) + { + log("Invalid input parameter"); + return IPMI_CC_INVALID_FIELD_REQUEST; + } + + if (requestData->groupID != dcmi::groupExtId) + { + *data_len = 0; + return IPMI_CC_INVALID_FIELD_REQUEST; + } + + auto responseData = reinterpret_cast + (response); + + //For each capabilities in a parameter fill the data from + //the json file based on the capability name. + for (auto cap : caps->second.capList) + { + //If the data is beyond first byte boundary, insert in a + //16bit pattern for example number of SEL entries are represented + //in 12bits. + if ((cap.length + cap.position) > 8) + { + //Read the value corresponding to capability name and assign to + //16bit bitset. + std::bitset<16> val(data.value(cap.name.c_str(), 0)); + val <<= cap.position; + reinterpret_cast(responseData->data)[ + (cap.bytePosition - 1) / sizeof(uint16_t)] |= val.to_ulong(); + } + else + { + responseData->data[cap.bytePosition - 1] |= + data.value(cap.name.c_str(), 0) << cap.position; + } + } + + responseData->groupID = dcmi::groupExtId; + responseData->major = DCMI_SPEC_MAJOR_VERSION; + responseData->minor = DCMI_SPEC_MINOR_VERSION; + responseData->paramRevision = DCMI_PARAMETER_REVISION; + *data_len = sizeof(*responseData) + caps->second.size; + + return IPMI_CC_OK; +} + void register_netfn_dcmi_functions() { // @@ -653,6 +781,9 @@ void register_netfn_dcmi_functions() ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::SET_MGMNT_CTRL_ID_STR, NULL, setMgmntCtrlIdStr, PRIVILEGE_ADMIN); + // + ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::GET_CAPABILITIES, + NULL, getDCMICapabilities, PRIVILEGE_USER); return; } // 956379 -- cgit v1.2.1