summaryrefslogtreecommitdiffstats
path: root/dcmihandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dcmihandler.cpp')
-rw-r--r--dcmihandler.cpp122
1 files changed, 70 insertions, 52 deletions
diff --git a/dcmihandler.cpp b/dcmihandler.cpp
index 9205207..2e0204d 100644
--- a/dcmihandler.cpp
+++ b/dcmihandler.cpp
@@ -23,6 +23,9 @@ constexpr auto POWER_CAP_ENABLE_PROP = "PowerCapEnable";
using namespace phosphor::logging;
+namespace dcmi
+{
+
uint32_t getPcap(sdbusplus::bus::bus& bus)
{
auto settingService = ipmi::getService(bus,
@@ -39,14 +42,12 @@ uint32_t getPcap(sdbusplus::bus::bus& bus)
if (reply.is_method_error())
{
log<level::ERR>("Error in getPcap prop");
- // TODO openbmc/openbmc#851 - Once available, throw returned error
- // and return IPMI_CC_UNSPECIFIED_ERROR to caller
- return 0;
+ elog<InternalFailure>();
}
sdbusplus::message::variant<uint32_t> pcap;
reply.read(pcap);
- return sdbusplus::message::variant_ns::get<uint32_t>(pcap);
+ return pcap.get<uint32_t>();
}
bool getPcapEnabled(sdbusplus::bus::bus& bus)
@@ -65,58 +66,14 @@ bool getPcapEnabled(sdbusplus::bus::bus& bus)
if (reply.is_method_error())
{
log<level::ERR>("Error in getPcapEnabled prop");
- // TODO openbmc/openbmc#851 - Once available, throw returned error
- // and return IPMI_CC_UNSPECIFIED_ERROR to caller
- return false;
+ elog<InternalFailure>();
}
sdbusplus::message::variant<bool> pcapEnabled;
reply.read(pcapEnabled);
- return sdbusplus::message::variant_ns::get<bool>(pcapEnabled);
+ return pcapEnabled.get<bool>();
}
-ipmi_ret_t ipmi_dcmi_get_power_limit(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)
-{
- // Default to no power cap enabled
- ipmi_ret_t rc = IPMI_DCMI_CC_NO_ACTIVE_POWER_LIMIT;
-
- // Get our sdbus object
- sd_bus *bus = ipmid_get_sd_bus_connection();
- sdbusplus::bus::bus sdbus {bus};
-
- // Read our power cap settings
- auto pcap = getPcap(sdbus);
- auto pcapEnable = getPcapEnabled(sdbus);
- if(pcapEnable)
- {
- // indicate power cap enabled with success return code
- rc = IPMI_CC_OK;
- }
-
- uint8_t pcapBytes[2] = {0};
- pcapBytes[1] = (pcap & 0xFF00) >> 8;
- pcapBytes[0] = pcap & 0xFF;
- // dcmi-v1-5-rev-spec.pdf 6.6.2.
- uint8_t data_response[] = { 0xDC, 0x00, 0x00, 0x01, pcapBytes[0],
- pcapBytes[1], 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01};
-
-
- log<level::INFO>("IPMI DCMI POWER CAP INFO",
- entry("DCMI_PCAP=%u",pcap),
- entry("DCMI_PCAP_ENABLE=%u",pcapEnable));
-
- memcpy(response, data_response, sizeof(data_response));
- *data_len = sizeof(data_response);
-
- return rc;
-}
-
-namespace dcmi
-{
-
void readAssetTagObjectTree(dcmi::assettag::ObjectTree& objectTree)
{
static constexpr auto mapperBusName = "xyz.openbmc_project.ObjectMapper";
@@ -210,6 +167,67 @@ void writeAssetTag(const std::string& assetTag)
} // namespace dcmi
+ipmi_ret_t getPowerLimit(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)
+{
+ auto requestData = reinterpret_cast<const dcmi::GetPowerLimitRequest*>
+ (request);
+ std::vector<uint8_t> outPayload(sizeof(dcmi::GetPowerLimitResponse));
+ auto responseData = reinterpret_cast<dcmi::GetPowerLimitResponse*>
+ (outPayload.data());
+
+ if (requestData->groupID != dcmi::groupExtId)
+ {
+ *data_len = 0;
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
+
+ sdbusplus::bus::bus sdbus {ipmid_get_sd_bus_connection()};
+ uint32_t pcapValue = 0;
+ bool pcapEnable = false;
+
+ try
+ {
+ pcapValue = dcmi::getPcap(sdbus);
+ pcapEnable = dcmi::getPcapEnabled(sdbus);
+ }
+ catch (InternalFailure& e)
+ {
+ *data_len = 0;
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+
+ responseData->groupID = dcmi::groupExtId;
+
+ /*
+ * Exception action if power limit is exceeded and cannot be controlled
+ * with the correction time limit is hardcoded to Hard Power Off system
+ * and log event to SEL.
+ */
+ constexpr auto exception = 0x01;
+ responseData->exceptionAction = exception;
+
+ responseData->powerLimit = static_cast<uint16_t>(pcapValue);
+
+ /*
+ * Correction time limit and Statistics sampling period is currently not
+ * populated.
+ */
+
+ *data_len = outPayload.size();
+ memcpy(response, outPayload.data(), *data_len);
+
+ if (pcapEnable)
+ {
+ return IPMI_CC_OK;
+ }
+ else
+ {
+ return IPMI_DCMI_CC_NO_ACTIVE_POWER_LIMIT;
+ }
+}
+
ipmi_ret_t getAssetTag(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)
@@ -348,8 +366,8 @@ ipmi_ret_t setAssetTag(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
void register_netfn_dcmi_functions()
{
// <Get Power Limit>
- printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_POWER);
- ipmi_register_callback(NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_POWER, NULL, ipmi_dcmi_get_power_limit,
+ printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_POWER_LIMIT);
+ ipmi_register_callback(NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_POWER_LIMIT, NULL, getPowerLimit,
PRIVILEGE_USER);
// <Get Asset Tag>
OpenPOWER on IntegriCloud