IPMI OEM Get BIC GPIO State
Register an IPMI command handler - NetFn: 0x38 Cmd: 0x03.
Send command through IPMB to get BIC GPIO state.
Add Meta IANA definition for future utilization.
Limitation:
1. Could only get the state of BIC GPIOs which are configured as GPIO
2. Couldn't get all BIC GPIO states
Test Case:
Call IPMI OEM get BIC GPIO state
Signed-off-by: Bonnie Lo <Bonnie_Lo@wiwynn.com>
Change-Id: Idda8d4c532b2971c14662e7b34ea101cf584fa22
diff --git a/src/biccommands.cpp b/src/biccommands.cpp
index 0813593..5212452 100644
--- a/src/biccommands.cpp
+++ b/src/biccommands.cpp
@@ -37,15 +37,18 @@
extern message::Response::ptr executeIpmiCommand(message::Request::ptr);
+int sendBicCmd(uint8_t, uint8_t, uint8_t, std::vector<uint8_t>&,
+ std::vector<uint8_t>&);
+
//----------------------------------------------------------------------
// ipmiOemBicHandler (IPMI/Section - ) (CMD_OEM_BIC_INFO)
// This Function will handle BIC request for netfn=0x38 and cmd=1
// send the response back to the sender.
//----------------------------------------------------------------------
-ipmi::RspType<std::array<uint8_t, 3>, uint8_t, uint2_t, uint6_t, uint8_t,
- uint8_t, ipmi::message::Payload>
- ipmiOemBicHandler(ipmi::Context::ptr ctx, std::array<uint8_t, 3> iana,
+ipmi::RspType<IanaType, uint8_t, uint2_t, uint6_t, uint8_t, uint8_t,
+ ipmi::message::Payload>
+ ipmiOemBicHandler(ipmi::Context::ptr ctx, IanaType reqIana,
uint8_t interface, uint2_t lun, uint6_t netFnReq,
uint8_t cmdReq, SecureBuffer data)
{
@@ -63,7 +66,7 @@
res = ipmi::executeIpmiCommand(req);
// sending the response with headers and payload
- return ipmi::responseSuccess(iana, interface, lun, ++netFnReq, cmdReq,
+ return ipmi::responseSuccess(reqIana, interface, lun, ++netFnReq, cmdReq,
res->cc, res->payload);
}
@@ -73,9 +76,10 @@
// netfn=0x38 and cmd=0x08 send the response back to the sender.
//----------------------------------------------------------------------
-ipmi::RspType<std::array<uint8_t, 3>>
- ipmiOemPostCodeHandler(ipmi::Context::ptr ctx, std::array<uint8_t, 3> iana,
- uint8_t dataLen, std::vector<uint8_t> data)
+ipmi::RspType<IanaType> ipmiOemPostCodeHandler(ipmi::Context::ptr ctx,
+ IanaType reqIana,
+ uint8_t dataLen,
+ std::vector<uint8_t> data)
{
// creating bus connection
auto conn = getSdBus();
@@ -113,7 +117,42 @@
}
}
- return ipmi::responseSuccess(iana);
+ return ipmi::responseSuccess(reqIana);
+}
+
+//----------------------------------------------------------------------
+// ipmiOemGetBicGpioState (CMD_OEM_GET_BIC_GPIO_STATE)
+// This Function will handle BIC GPIO stats for
+// netfn=0x38 and cmd=0x03 send the response back to the sender.
+//----------------------------------------------------------------------
+
+ipmi::RspType<IanaType, std::vector<uint8_t>>
+ ipmiOemGetBicGpioState(ipmi::Context::ptr ctx, std::vector<uint8_t> reqIana)
+{
+ std::vector<uint8_t> respData;
+
+ if (std::equal(reqIana.begin(), reqIana.end(), iana.begin()) == false)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Invalid IANA number");
+ return ipmi::responseInvalidFieldRequest();
+ }
+
+ uint8_t bicAddr = (uint8_t)ctx->hostIdx << 2;
+
+ if (sendBicCmd(ctx->netFn, ctx->cmd, bicAddr, reqIana, respData))
+ {
+ return ipmi::responseUnspecifiedError();
+ }
+
+ std::vector<uint8_t> gpioState;
+ IanaType respIana;
+
+ auto r =
+ std::ranges::copy_n(respData.begin(), iana.size(), respIana.begin()).in;
+ std::copy(r, respData.end(), std::back_inserter(gpioState));
+
+ return ipmi::responseSuccess(respIana, gpioState);
}
[[maybe_unused]] static void registerBICFunctions(void)
@@ -123,11 +162,16 @@
"Registering BIC commands");
ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemFive,
- cmdOemBicInfo, ipmi::Privilege::User,
- ipmiOemBicHandler);
- ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnOemFive,
- cmdOemSendPostBufferToBMC, ipmi::Privilege::User,
- ipmiOemPostCodeHandler);
+ static_cast<Cmd>(fb_bic_cmds::CMD_OEM_BIC_INFO),
+ ipmi::Privilege::User, ipmiOemBicHandler);
+ ipmi::registerHandler(
+ ipmi::prioOpenBmcBase, ipmi::netFnOemFive,
+ static_cast<Cmd>(fb_bic_cmds::CMD_OEM_SEND_POST_BUFFER_TO_BMC),
+ ipmi::Privilege::User, ipmiOemPostCodeHandler);
+ ipmi::registerHandler(
+ ipmi::prioOemBase, ipmi::netFnOemFive,
+ static_cast<Cmd>(fb_bic_cmds::CMD_OEM_GET_BIC_GPIO_STATE),
+ ipmi::Privilege::User, ipmiOemGetBicGpioState);
return;
}