Implement Get POH Counter command
It returns a counter value proportional to the system operating
power-on hours.
Partially Resolves openbmc/openbmc#2979
Change-Id: Ib0cd43fe5cbc055ae84991577d766bedae58d775
Signed-off-by: Nagaraju Goruganti <ngorugan@in.ibm.com>
diff --git a/chassishandler.cpp b/chassishandler.cpp
index 0ee593c..2e892b9 100644
--- a/chassishandler.cpp
+++ b/chassishandler.cpp
@@ -33,6 +33,7 @@
#include <xyz/openbmc_project/Control/Boot/Source/server.hpp>
#include <xyz/openbmc_project/Control/Boot/Mode/server.hpp>
#include <xyz/openbmc_project/Control/Power/RestorePolicy/server.hpp>
+#include <xyz/openbmc_project/State/PowerOnHours/server.hpp>
#include "config.h"
@@ -79,6 +80,11 @@
constexpr auto IP_INTERFACE = "xyz.openbmc_project.Network.IP";
constexpr auto MAC_INTERFACE = "xyz.openbmc_project.Network.MACAddress";
+static constexpr auto chassisStateRoot = "/xyz/openbmc_project/state";
+static constexpr auto chassisPOHStateIntf =
+ "xyz.openbmc_project.State.PowerOnHours";
+static constexpr auto pOHCounterProperty = "POHCounter";
+static constexpr auto match = "chassis0";
typedef struct
{
@@ -98,6 +104,15 @@
uint8_t front_panel_button_cap_status;
}__attribute__((packed)) ipmi_get_chassis_status_t;
+/**
+ * @struct Get POH counter command response data
+ */
+struct GetPOHCountResponse
+{
+ uint8_t minPerCount; ///< Minutes per count
+ uint8_t counterReading[4]; ///< Counter reading
+}__attribute__((packed));
+
// Phosphor Host State manager
namespace State = sdbusplus::xyz::openbmc_project::State::server;
@@ -127,6 +142,13 @@
} // namespace internal
} // namespace chassis
+namespace poh
+{
+
+constexpr auto minutesPerCount = 60;
+
+} // namespace poh
+
//TODO : Can remove the below function as we have
// new functions which uses sdbusplus.
//
@@ -581,6 +603,23 @@
return 0;
}
+uint32_t getPOHCounter()
+{
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+
+ auto chassisStateObj = ipmi::getDbusObject(bus, chassisPOHStateIntf,
+ chassisStateRoot, match);
+
+ auto service = ipmi::getService(bus, chassisPOHStateIntf,
+ chassisStateObj.first);
+
+ auto propValue = ipmi::getDbusProperty(bus, service, chassisStateObj.first,
+ chassisPOHStateIntf,
+ pOHCounterProperty);
+
+ return propValue.get<uint32_t>();
+}
+
ipmi_ret_t ipmi_chassis_wildcard(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request,
ipmi_response_t response,
@@ -1505,6 +1544,35 @@
return rc;
}
+ipmi_ret_t ipmiGetPOHCounter(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)
+{
+ // sd_bus error
+ ipmi_ret_t rc = IPMI_CC_OK;
+
+ auto resptr = reinterpret_cast<GetPOHCountResponse*>(response);
+
+ try
+ {
+ auto pohCounter = getPOHCounter();
+ resptr->counterReading[0] = pohCounter;
+ resptr->counterReading[1] = pohCounter >> 8;
+ resptr->counterReading[2] = pohCounter >> 16;
+ resptr->counterReading[3] = pohCounter >> 24;
+ }
+ catch (std::exception& e)
+ {
+ log<level::ERR>(e.what());
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+
+ resptr->minPerCount = poh::minutesPerCount;
+ *data_len = sizeof(GetPOHCountResponse);
+
+ return rc;
+}
+
void register_netfn_chassis_functions()
{
// <Wildcard Command>
@@ -1534,4 +1602,7 @@
// <Set System Boot Options>
ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_SET_SYS_BOOT_OPTIONS, NULL,
ipmi_chassis_set_sys_boot_options, PRIVILEGE_OPERATOR);
+ // <Get POH Counter>
+ ipmi_register_callback(NETFUN_CHASSIS, IPMI_CMD_GET_POH_COUNTER, NULL,
+ ipmiGetPOHCounter, PRIVILEGE_USER);
}