IPMI OEM Get 80 Port Record
Register an IPMI command handler
NetFn: 0x30 Cmd: 0x49
This handler is for user from host to get POST code sequence.
The maximum return size is 224 due to IPMB limitation.
Test Case:
Call IPMI OEM get 80 port record
Signed-off-by: Bonnie Lo <Bonnie_Lo@wiwynn.com>
Change-Id: Iaf8c060b1e8340280928e195c205455b88df5dfd
diff --git a/meson.build b/meson.build
index 4736ea0..fccd790 100644
--- a/meson.build
+++ b/meson.build
@@ -34,6 +34,7 @@
conf_data = configuration_data()
conf_data.set_quoted('INSTANCES',host_instances)
+conf_data.set('POST_CODE_BYTES', get_option('post-code-bytes'))
configure_file(input: 'meson_config.h.in',
output: 'config.h',
diff --git a/meson_config.h.in b/meson_config.h.in
index ff7109c..6b8af72 100644
--- a/meson_config.h.in
+++ b/meson_config.h.in
@@ -1,3 +1,5 @@
#pragma once
inline static const std::string hostInstances = @INSTANCES@;
+
+inline static const size_t postCodeSize = @POST_CODE_BYTES@;
diff --git a/meson_options.txt b/meson_options.txt
index 5c9d771..7f150ab 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,5 +1,6 @@
option('tests', type: 'feature', description: 'Build tests')
option('bic', type: 'feature', description: 'Enable bic handlers')
+option('post-code-bytes', type: 'integer', description: 'Post code byte size.', value: 1)
option(
'host-instances',
type: 'string',
diff --git a/src/oemcommands.cpp b/src/oemcommands.cpp
index ca56c45..d781964 100644
--- a/src/oemcommands.cpp
+++ b/src/oemcommands.cpp
@@ -819,6 +819,69 @@
return IPMI_CC_OK;
}
+//----------------------------------------------------------------------
+// Get port 80 record (CMD_OEM_GET_80PORT_RECORD)
+//----------------------------------------------------------------------
+ipmi::RspType<std::vector<uint8_t>>
+ ipmiOemGet80PortRecord(ipmi::Context::ptr ctx)
+{
+ auto postCodeService = "xyz.openbmc_project.State.Boot.PostCode" +
+ std::to_string(ctx->hostIdx + 1);
+ auto postCodeObjPath = "/xyz/openbmc_project/State/Boot/PostCode" +
+ std::to_string(ctx->hostIdx + 1);
+ constexpr auto postCodeInterface =
+ "xyz.openbmc_project.State.Boot.PostCode";
+ const static uint16_t lastestPostCodeIndex = 1;
+ constexpr const auto maxPostCodeLen =
+ 224; // The length must be lower than IPMB limitation
+ size_t startIndex = 0;
+
+ std::vector<std::tuple<uint64_t, std::vector<uint8_t>>> postCodes;
+ std::vector<uint8_t> resData;
+
+ auto conn = getSdBus();
+ /* Get the post codes by calling GetPostCodes method */
+ auto msg =
+ conn->new_method_call(postCodeService.c_str(), postCodeObjPath.c_str(),
+ postCodeInterface, "GetPostCodes");
+ msg.append(lastestPostCodeIndex);
+
+ try
+ {
+ auto reply = conn->call(msg);
+ reply.read(postCodes);
+ }
+ catch (const sdbusplus::exception::SdBusError& e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "IPMI Get80PortRecord Failed in call method",
+ phosphor::logging::entry("ERROR=%s", e.what()));
+ return ipmi::responseUnspecifiedError();
+ }
+
+ /* Get post code data */
+ for (size_t i = 0; i < postCodes.size(); ++i)
+ {
+ uint64_t primaryPostCode = std::get<uint64_t>(postCodes[i]);
+ for (int j = postCodeSize - 1; j >= 0; --j)
+ {
+ uint8_t postCode =
+ ((primaryPostCode >> (sizeof(uint64_t) * j)) & 0xFF);
+ resData.emplace_back(postCode);
+ }
+ }
+
+ std::vector<uint8_t> response;
+ if (resData.size() > maxPostCodeLen)
+ {
+ startIndex = resData.size() - maxPostCodeLen;
+ }
+
+ response.assign(resData.begin() + startIndex, resData.end());
+
+ return ipmi::responseSuccess(response);
+}
+
/* Helper functions to set boot order */
void setBootOrder(std::string bootObjPath, uint8_t* data,
std::string bootOrderKey)
@@ -2057,6 +2120,9 @@
ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_GET_BOARD_ID, NULL,
ipmiOemGetBoardID,
PRIVILEGE_USER); // Get Board ID
+ ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnOemOne,
+ CMD_OEM_GET_80PORT_RECORD, ipmi::Privilege::User,
+ ipmiOemGet80PortRecord); // Get 80 Port Record
ipmiPrintAndRegister(NETFUN_NONE, CMD_OEM_SET_MACHINE_CONFIG_INFO, NULL,
ipmiOemSetMachineCfgInfo,
PRIVILEGE_USER); // Set Machine Config Info