Showing with 73 additions and 0 deletions.
  1. +71 −0 chassishandler.cpp
  2. +1 −0 chassishandler.h
  3. +1 −0 host-ipmid-whitelist.conf
@@ -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 SETTINGS_MATCH = "host0";
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 @@ typedef struct
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 @@ settings::Objects objects(dbus,
} // 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 @@ int setHostNetworkData(set_sys_boot_options_t* reqptr)
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 @@ ipmi_ret_t ipmi_chassis_set_sys_boot_options(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
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 @@ void register_netfn_chassis_functions()
// <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);
}
@@ -16,6 +16,7 @@ enum ipmi_netfn_app_cmds
// Get capability bits
IPMI_CMD_SET_SYS_BOOT_OPTIONS = 0x08,
IPMI_CMD_GET_SYS_BOOT_OPTIONS = 0x09,
IPMI_CMD_GET_POH_COUNTER = 0x0F,
};

// Command specific completion codes
@@ -4,6 +4,7 @@
0x00:0x02 //<Chassis>:<Chassis Control>
0x00:0x08 //<Chassis>:<Set System Boot Options>
0x00:0x09 //<Chassis>:<Get System Boot Options>
0x00:0x0F //<Chassis>:<Get POH Counter Command>
0x04:0x2D //<Sensor/Event>:<Get Sensor Reading>
0x04:0x2F //<Sensor/Event>:<Get Sensor Type>
0x04:0x30 //<Sensor/Event>:<Set Sensor Reading and Event Status>