diff options
author | Dhruvaraj Subhashchandran <dhruvaraj@in.ibm.com> | 2018-01-16 05:11:56 -0600 |
---|---|---|
committer | Tom Joseph <tomjoseph@in.ibm.com> | 2018-01-31 09:13:20 +0000 |
commit | e29be41f1d014a55e93abd3e55ac23f158f5fa16 (patch) | |
tree | f084ca93eb46ef2545fc2e95abef384d1fbd0d84 | |
parent | 9642391d3953754761d5312f59ecbc90341b4759 (diff) | |
download | phosphor-host-ipmid-e29be41f1d014a55e93abd3e55ac23f158f5fa16.tar.gz phosphor-host-ipmid-e29be41f1d014a55e93abd3e55ac23f158f5fa16.zip |
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 <dhruvaraj@in.ibm.com>
-rw-r--r-- | dcmihandler.cpp | 131 | ||||
-rw-r--r-- | dcmihandler.hpp | 62 | ||||
-rw-r--r-- | host-ipmid-whitelist.conf | 1 |
3 files changed, 194 insertions, 0 deletions
diff --git a/dcmihandler.cpp b/dcmihandler.cpp index ab3aa58..aa9f14e 100644 --- a/dcmihandler.cpp +++ b/dcmihandler.cpp @@ -7,6 +7,9 @@ #include <stdio.h> #include <string.h> #include <stdint.h> +#include <fstream> +#include <bitset> +#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<level::ERR>("DCMI Capabilities file not found"); + return IPMI_CC_UNSPECIFIED_ERROR; + } + + auto data = nlohmann::json::parse(dcmiCapFile, nullptr, false); + if (data.is_discarded()) + { + log<level::ERR>("DCMI Capabilities JSON parser failure"); + return IPMI_CC_UNSPECIFIED_ERROR; + } + + auto requestData = reinterpret_cast<const dcmi::GetDCMICapRequest*> + (request); + + //get list of capabilities in a parameter + auto caps = + dcmiCaps.find(static_cast<dcmi::DCMICapParameters>(requestData->param)); + if (caps == dcmiCaps.end()) + { + log<level::ERR>("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<dcmi::GetDCMICapResponse*> + (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<uint16_t*>(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() { // <Get Power Limit> @@ -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); + // <Get DCMI capabilities> + ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::GET_CAPABILITIES, + NULL, getDCMICapabilities, PRIVILEGE_USER); return; } // 956379 diff --git a/dcmihandler.hpp b/dcmihandler.hpp index 91707f3..288e4d7 100644 --- a/dcmihandler.hpp +++ b/dcmihandler.hpp @@ -12,6 +12,7 @@ namespace dcmi enum Commands { // Get capability bits + GET_CAPABILITIES = 0x01, GET_POWER_LIMIT = 0x03, SET_POWER_LIMIT = 0x04, APPLY_POWER_LIMIT = 0x05, @@ -258,6 +259,67 @@ struct SetMgmntCtrlIdStrResponse 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>; + } // namespace dcmi #endif diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf index 68e3233..941800a 100644 --- a/host-ipmid-whitelist.conf +++ b/host-ipmid-whitelist.conf @@ -27,5 +27,6 @@ 0x0A:0x49 //<Storage>:<Set SEL Time> 0x0C:0x02 //<Transport>:<Get LAN Configuration Parameters> 0x2C:0x00 //<Group Extension>:<Group Extension Command> +0x2C:0x01 //<Group Extension>:<Get DCMI Capabilities> 0x2C:0x03 //<Group Extension>:<Get Power Limit> 0x2C:0x06 //<Group Extension>:<Get Asset Tag> |