diff options
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0072-chassishandler-GetSystemBootOptions-to-new-API.patch')
-rw-r--r-- | meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0072-chassishandler-GetSystemBootOptions-to-new-API.patch | 429 |
1 files changed, 429 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0072-chassishandler-GetSystemBootOptions-to-new-API.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0072-chassishandler-GetSystemBootOptions-to-new-API.patch new file mode 100644 index 000000000..272626e07 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0072-chassishandler-GetSystemBootOptions-to-new-API.patch @@ -0,0 +1,429 @@ +From cab3769b39ae6f3cce0119fce2c823ec8e11af11 Mon Sep 17 00:00:00 2001 +From: Jayaprakash Mutyala <mutyalax.jayaprakash@intel.com> +Date: Fri, 4 Sep 2020 12:53:17 +0000 +Subject: [PATCH] chassishandler: GetSystemBootOptions to new API + +Rewrite ipmiChassisGetSytemBootOptions to use newly introduced +IPMI provider API + +Tested: +Verified using ipmi chassis bootparam command + +Command: ipmitool chassis bootparam get 0 +Response: +Boot parameter version: 0 +Boot parameter 0 is valid/unlocked +Boot parameter data: + Set In Progress : set complete + +Command: ipmitool chassis bootparam get 5 +Response: +Boot parameter version: 1 +Boot parameter 5 is valid/unlocked +Boot parameter data: 8008000000 + Boot Flags : + - Boot Flag Valid + - Options apply to only next boot + - BIOS PC Compatible (legacy) boot + - Boot Device Selector : Force Boot from default Hard-Drive + - BIOS verbosity : System Default + - Console Redirection control : Console redirection occurs per BIOS + configuration setting (default) + - BIOS Mux Control Override : BIOS uses recommended setting of the + mux at the end of POST + +Signed-off-by: srikanta mondal <srikantax.mondal@intel.com> +Signed-off-by: Jayaprakash Mutyala <mutyalax.jayaprakash@intel.com> +--- + chassishandler.cpp | 231 +++++++++++++++++++++++---------------------- + chassishandler.hpp | 7 -- + 2 files changed, 119 insertions(+), 119 deletions(-) + +diff --git a/chassishandler.cpp b/chassishandler.cpp +index ca7cd2c..bbb3f81 100644 +--- a/chassishandler.cpp ++++ b/chassishandler.cpp +@@ -44,9 +44,6 @@ static constexpr uint8_t setParmBootFlagsPermanent = 0x40; + static constexpr uint8_t setParmBootFlagsValidOneTime = 0x80; + static constexpr uint8_t setParmBootFlagsValidPermanent = 0xC0; + +-constexpr size_t SIZE_BOOT_OPTION = static_cast<size_t>( +- BootOptionResponseSize::opalNetworkSettings); // Maximum size of the boot +- // option parameters + constexpr size_t sizeVersion = 2; + constexpr size_t DEFAULT_IDENTIFY_TIME_OUT = 15; + +@@ -172,21 +169,7 @@ constexpr auto minutesPerCount = 60; + + } // namespace poh + +-struct get_sys_boot_options_t +-{ +- uint8_t parameter; +- uint8_t set; +- uint8_t block; +-} __attribute__((packed)); +- +-struct get_sys_boot_options_response_t +-{ +- uint8_t version; +- uint8_t parm; +- uint8_t data[SIZE_BOOT_OPTION]; +-} __attribute__((packed)); +- +-int getHostNetworkData(get_sys_boot_options_response_t* respptr) ++int getHostNetworkData(ipmi::message::Payload& payload) + { + ipmi::PropertyMap properties; + int rc = 0; +@@ -238,7 +221,6 @@ int getHostNetworkData(get_sys_boot_options_response_t* respptr) + // don't send blank override. + if ((MACAddress == ipmi::network::DEFAULT_MAC_ADDRESS)) + { +- std::memset(respptr->data, 0, SIZE_BOOT_OPTION); + rc = -1; + return rc; + } +@@ -249,22 +231,27 @@ int getHostNetworkData(get_sys_boot_options_response_t* respptr) + if ((ipAddress == ipmi::network::DEFAULT_ADDRESS) || + (gateway == ipmi::network::DEFAULT_ADDRESS) || (!prefix)) + { +- std::memset(respptr->data, 0, SIZE_BOOT_OPTION); + rc = -1; + return rc; + } + } + +- sscanf(MACAddress.c_str(), ipmi::network::MAC_ADDRESS_FORMAT, +- (respptr->data + macOffset), (respptr->data + macOffset + 1), +- (respptr->data + macOffset + 2), (respptr->data + macOffset + 3), +- (respptr->data + macOffset + 4), +- (respptr->data + macOffset + 5)); ++ std::string token; ++ std::stringstream ss(MACAddress); ++ ++ // First pack macOffset no of bytes in payload. ++ // Latter this PetiBoot-Specific data will be populated. ++ std::vector<uint8_t> payloadInitialBytes(macOffset); ++ payload.pack(payloadInitialBytes); ++ ++ while (std::getline(ss, token, ':')) ++ { ++ payload.pack(stoi(token, nullptr, 16)); ++ } + +- respptr->data[macOffset + 6] = 0x00; ++ payload.pack(0x00); + +- std::memcpy(respptr->data + addrTypeOffset, &isStatic, +- sizeof(isStatic)); ++ payload.pack(isStatic); + + uint8_t addressFamily = (std::get<std::string>(properties["Type"]) == + "xyz.openbmc_project.Network.IP.Protocol.IPv4") +@@ -276,39 +263,58 @@ int getHostNetworkData(get_sys_boot_options_response_t* respptr) + : ipmi::network::IPV6_ADDRESS_SIZE_BYTE; + + // ipaddress and gateway would be in IPv4 format ++ std::vector<uint8_t> addrInBinary(addrSize); + inet_pton(addressFamily, ipAddress.c_str(), +- (respptr->data + ipAddrOffset)); ++ reinterpret_cast<void*>(addrInBinary.data())); + +- uint8_t prefixOffset = ipAddrOffset + addrSize; ++ payload.pack(addrInBinary); + +- std::memcpy(respptr->data + prefixOffset, &prefix, sizeof(prefix)); +- +- uint8_t gatewayOffset = prefixOffset + sizeof(decltype(prefix)); ++ payload.pack(prefix); + ++ std::vector<uint8_t> gatewayDetails(addrSize); + inet_pton(addressFamily, gateway.c_str(), +- (respptr->data + gatewayOffset)); ++ reinterpret_cast<void*>(gatewayDetails.data())); ++ payload.pack(gatewayDetails); + } + catch (InternalFailure& e) + { + commit<InternalFailure>(); +- std::memset(respptr->data, 0, SIZE_BOOT_OPTION); + rc = -1; + return rc; + } + + // PetiBoot-Specific +- // If success then copy the first 9 bytes to the data +- std::memcpy(respptr->data, netConfInitialBytes, +- sizeof(netConfInitialBytes)); ++ // If success then copy the first 9 bytes to the payload message ++ // payload first 2 bytes contain the parameter values. Skip that 2 bytes. ++ uint8_t skipFirstTwoBytes = 2; ++ size_t payloadSize = payload.size(); ++ uint8_t* configDataStartingAddress = payload.data() + skipFirstTwoBytes; + +- std::memcpy(respptr->data + addrSizeOffset, &addrSize, sizeof(addrSize)); ++ if (payloadSize < skipFirstTwoBytes + sizeof(netConfInitialBytes)) ++ { ++ log<level::ERR>("Invalid net config "); ++ rc = -1; ++ return rc; ++ } ++ std::copy(netConfInitialBytes, ++ netConfInitialBytes + sizeof(netConfInitialBytes), ++ configDataStartingAddress); ++ ++ if (payloadSize < skipFirstTwoBytes + addrSizeOffset + sizeof(addrSize)) ++ { ++ log<level::ERR>("Invalid length of address size"); ++ rc = -1; ++ return rc; ++ } ++ std::copy(&addrSize, &(addrSize) + sizeof(addrSize), ++ configDataStartingAddress + addrSizeOffset); + + #ifdef _IPMI_DEBUG_ + std::printf("\n===Printing the IPMI Formatted Data========\n"); + + for (uint8_t pos = 0; pos < index; pos++) + { +- std::printf("%02x ", respptr->data[pos]); ++ std::printf("%02x ", payloadStartingAddress[pos]); + } + #endif + +@@ -1561,44 +1567,52 @@ static ipmi::Cc setBootMode(const Mode::Modes& mode) + static constexpr uint8_t setComplete = 0x0; + static constexpr uint8_t setInProgress = 0x1; + static uint8_t transferStatus = setComplete; ++/** @brief implements the Get Chassis system boot option ++ * @param bootOptionParameter - boot option parameter selector ++ * @param reserved1 - reserved bit ++ * @param setSelector - selects a particular block or set of parameters ++ * under the given parameter selector ++ * write as 00h if parameter doesn't use a setSelector ++ * @param blockSelector- selects a particular block within a set of ++ * parameters write as 00h if parameter doesn't use a ++ * blockSelector ++ * ++ * @return IPMI completion code plus response data ++ * @return Payload contains below parameters: ++ * version - parameter version ++ * bootOptionParameter - boot option parameter selector ++ * parmIndicator - parameter vaild/invaild indicator ++ * data - configuration parameter data ++ */ ++ipmi::RspType<ipmi::message::Payload> ++ ipmiChassisGetSysBootOptions(uint7_t bootOptionParameter, bool reserved1, + +-ipmi_ret_t ipmi_chassis_get_sys_boot_options(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) ++ uint8_t setSelector, uint8_t blockSelector) + { ++ if (reserved1) ++ { ++ return ipmi::responseInvalidFieldRequest(); ++ } ++ ++ constexpr uint4_t version = 0x01; ++ ipmi::message::Payload response; ++ response.pack(version, uint4_t{}); + using namespace boot_options; +- ipmi_ret_t rc = IPMI_CC_PARM_NOT_SUPPORTED; +- char* p = NULL; +- get_sys_boot_options_response_t* resp = +- (get_sys_boot_options_response_t*)response; +- get_sys_boot_options_t* reqptr = (get_sys_boot_options_t*)request; +- IpmiValue bootOption = ipmiDefault; + +- if (reqptr->parameter == ++ IpmiValue bootOption = ipmiDefault; ++ if (static_cast<uint8_t>(bootOptionParameter) == + static_cast<uint8_t>(BootOptionParameter::setInProgress)) + { +- *data_len = static_cast<uint8_t>(BootOptionResponseSize::setInProgress); +- resp->version = setParmVersion; +- resp->parm = static_cast<uint8_t>(BootOptionParameter::setInProgress); +- resp->data[0] = transferStatus; +- return IPMI_CC_OK; ++ return ipmi::response(transferStatus); + } + +- std::memset(resp, 0, sizeof(*resp)); +- resp->version = setParmVersion; +- resp->parm = 5; +- resp->data[0] = setParmBootFlagsValidOneTime; + /* + * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc. + * This is the only parameter used by petitboot. + */ +- if (reqptr->parameter == ++ if (static_cast<uint8_t>(bootOptionParameter) == + static_cast<uint8_t>(BootOptionParameter::bootFlags)) + { +- +- *data_len = static_cast<uint8_t>(BootOptionResponseSize::bootFlags); + using namespace chassis::internal; + using namespace chassis::internal::cache; + +@@ -1619,8 +1633,7 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd, + { + log<level::ERR>("Error in BootSource Get"); + report<InternalFailure>(); +- *data_len = 0; +- return IPMI_CC_UNSPECIFIED_ERROR; ++ return ipmi::responseUnspecifiedError(); + } + std::variant<std::string> result; + reply.read(result); +@@ -1638,8 +1651,7 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd, + { + log<level::ERR>("Error in BootMode Get"); + report<InternalFailure>(); +- *data_len = 0; +- return IPMI_CC_UNSPECIFIED_ERROR; ++ return ipmi::responseUnspecifiedError(); + } + reply.read(result); + auto bootMode = +@@ -1655,59 +1667,54 @@ ipmi_ret_t ipmi_chassis_get_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd, + { + bootOption = modeDbusToIpmi.at(bootMode); + } +- resp->data[1] = (bootOption << 2); + +- resp->data[0] = oneTimeEnabled ? setParmBootFlagsValidOneTime +- : setParmBootFlagsValidPermanent; +- +- rc = IPMI_CC_OK; ++ uint8_t bootOptionParam = oneTimeEnabled ++ ? setParmBootFlagsValidOneTime ++ : setParmBootFlagsValidPermanent; ++ response.pack(bootOptionParameter, reserved1, bootOptionParam, ++ uint2_t{}, uint4_t{bootOption}, uint2_t{}, uint8_t{}, ++ uint8_t{}, uint8_t{}); ++ return ipmi::responseSuccess(std::move(response)); + } + catch (InternalFailure& e) + { + cache::objectsPtr.reset(); + report<InternalFailure>(); +- *data_len = 0; +- return IPMI_CC_UNSPECIFIED_ERROR; ++ return ipmi::responseUnspecifiedError(); + } + } +- else if (reqptr->parameter == +- static_cast<uint8_t>(BootOptionParameter::opalNetworkSettings)) ++ else + { +- +- *data_len = +- static_cast<uint8_t>(BootOptionResponseSize::opalNetworkSettings); +- +- resp->parm = +- static_cast<uint8_t>(BootOptionParameter::opalNetworkSettings); +- +- int ret = getHostNetworkData(resp); +- +- if (ret < 0) ++ if ((bootOptionParameter >= oemParmStart) && ++ (bootOptionParameter <= oemParmEnd)) + { +- +- log<level::ERR>( +- "getHostNetworkData failed for get_sys_boot_options."); +- rc = IPMI_CC_UNSPECIFIED_ERROR; ++ if (static_cast<uint8_t>(bootOptionParameter) == ++ static_cast<uint8_t>(BootOptionParameter::opalNetworkSettings)) ++ { ++ response.pack(bootOptionParameter, reserved1); ++ int ret = getHostNetworkData(response); ++ if (ret < 0) ++ { ++ response.trailingOk = true; ++ log<level::ERR>( ++ "getHostNetworkData failed for GetSysBootOptions."); ++ return ipmi::responseUnspecifiedError(); ++ } ++ else ++ { ++ return ipmi::responseSuccess(std::move(response)); ++ } ++ } + } + else +- rc = IPMI_CC_OK; +- } +- +- else +- { +- log<level::ERR>("Unsupported parameter", +- entry("PARAM=0x%x", reqptr->parameter)); +- } +- +- if (p) +- free(p); +- +- if (rc == IPMI_CC_OK) +- { +- *data_len += 2; ++ { ++ log<level::ERR>( ++ "Unsupported parameter", ++ entry("PARAM=0x%x", static_cast<uint8_t>(bootOptionParameter))); ++ return ipmi::responseUnspecifiedError(); ++ } + } +- +- return rc; ++ return ipmi::responseUnspecifiedError(); + } + + ipmi::RspType<> ipmiChassisSetSysBootOptions(ipmi::Context::ptr ctx, +@@ -1820,7 +1827,6 @@ ipmi::RspType<> ipmiChassisSetSysBootOptions(ipmi::Context::ptr ctx, + if (sourceIpmiToDbus.end() != sourceItr) + { + rc = setBootSource(sourceItr->second); +- + if (rc != ipmi::ccSuccess) + { + log<level::ERR>("ipmiChassisSetSysBootOptions: Error in " +@@ -2067,9 +2073,10 @@ void register_netfn_chassis_functions() + ipmi::Privilege::User, ipmiSetChassisCap); + + // <Get System Boot Options> +- ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_SYS_BOOT_OPTIONS, NULL, +- ipmi_chassis_get_sys_boot_options, +- PRIVILEGE_OPERATOR); ++ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis, ++ ipmi::chassis::cmdGetSystemBootOptions, ++ ipmi::Privilege::Operator, ++ ipmiChassisGetSysBootOptions); + + // <Get Chassis Status> + ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnChassis, +diff --git a/chassishandler.hpp b/chassishandler.hpp +index 479563a..92c165e 100644 +--- a/chassishandler.hpp ++++ b/chassishandler.hpp +@@ -20,13 +20,6 @@ enum ipmi_netfn_chassis_cmds + IPMI_CMD_GET_POH_COUNTER = 0x0F, + }; + +-// Command specific completion codes +-enum ipmi_chassis_return_codes +-{ +- IPMI_OK = 0x0, +- IPMI_CC_PARM_NOT_SUPPORTED = 0x80, +-}; +- + // Generic completion codes, + // see IPMI doc section 5.2 + enum ipmi_generic_return_codes +-- +2.17.1 + |