summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJia, Chunhui <chunhui.jia@linux.intel.com>2018-12-29 13:32:26 +0800
committerVernon Mauery <vernon.mauery@linux.intel.com>2019-02-07 18:16:58 +0000
commit3342a8e0876909b34c076172727b8cac861f5277 (patch)
tree702186dee879466dd209c532e3e92b95e7b68934
parent4e1df0895e0664ca6f89321e6d600b8227b7475e (diff)
downloadphosphor-host-ipmid-3342a8e0876909b34c076172727b8cac861f5277.tar.gz
phosphor-host-ipmid-3342a8e0876909b34c076172727b8cac861f5277.zip
Platform event command
This command is used for logging SEL. Tested: 1. test with netipmid and ipmid. 2. test pass with good parameter ipmitool raw 0x4 0x2 0x20 0x11 0x04 0x11 0x80 0xc0 0x10 0xFF ipmitool raw 0x4 0x2 0x20 0x11 0x04 0x11 0x00 0x30 0x10 0xab 3. test pass with bad parameter (expect invalid data length error) ipmitool raw 0x4 0x2 0x20 0x11 0x04 0x11 0x00 0x30 ipmitool raw 0x4 0x2 0x20 0x11 0x04 0x11 0x00 0x30 0x11 ipmitool raw 0x4 0x2 0x20 0x11 0x04 0x11 0x00 0xc0 ipmitool raw 0x4 0x2 0x20 0x11 0x04 0x11 0x00 Change-Id: I7d51aac8fee2edb1faeb91f4c96a033736068779 Signed-off-by: Jia, Chunhui <chunhui.jia@linux.intel.com>
-rw-r--r--host-ipmid-whitelist.conf1
-rw-r--r--sensorhandler.cpp93
-rw-r--r--sensorhandler.hpp23
3 files changed, 117 insertions, 0 deletions
diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf
index e5cd0b5..d5dd754 100644
--- a/host-ipmid-whitelist.conf
+++ b/host-ipmid-whitelist.conf
@@ -7,6 +7,7 @@
0x00:0x08 //<Chassis>:<Set System Boot Options>
0x00:0x09 //<Chassis>:<Get System Boot Options>
0x00:0x0F //<Chassis>:<Get POH Counter Command>
+0x04:0x02 //<Sensor/Event>:<Platform event>
0x04:0x2D //<Sensor/Event>:<Get Sensor Reading>
0x04:0x2F //<Sensor/Event>:<Get Sensor Type>
0x04:0x30 //<Sensor/Event>:<Set Sensor Reading and Event Status>
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index 3edf198..8a0d23c 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -869,12 +869,105 @@ ipmi_ret_t ipmi_sen_get_sdr(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
return ret;
}
+static bool isFromSystemChannel()
+{
+ // TODO we could not figure out where the request is from based on IPMI
+ // command handler parameters. because of it, we can not differentiate
+ // request from SMS/SMM or IPMB channel
+ return true;
+}
+
+ipmi_ret_t ipmicmdPlatformEvent(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ ipmi_request_t request,
+ ipmi_response_t response,
+ ipmi_data_len_t dataLen, ipmi_context_t context)
+{
+ uint16_t generatorID;
+ size_t count;
+ bool assert = true;
+ std::string sensorPath;
+ size_t paraLen = *dataLen;
+ PlatformEventRequest* req;
+ *dataLen = 0;
+
+ if ((paraLen < selSystemEventSizeWith1Bytes) ||
+ (paraLen > selSystemEventSizeWith3Bytes))
+ {
+ return IPMI_CC_REQ_DATA_LEN_INVALID;
+ }
+
+ if (isFromSystemChannel())
+ { // first byte for SYSTEM Interface is Generator ID
+ // +1 to get common struct
+ req = reinterpret_cast<PlatformEventRequest*>((uint8_t*)request + 1);
+ // Capture the generator ID
+ generatorID = *reinterpret_cast<uint8_t*>(request);
+ // Platform Event usually comes from other firmware, like BIOS.
+ // Unlike BMC sensor, it does not have BMC DBUS sensor path.
+ sensorPath = "System";
+ }
+ else
+ {
+ req = reinterpret_cast<PlatformEventRequest*>(request);
+ // TODO GenratorID for IPMB is combination of RqSA and RqLUN
+ generatorID = 0xff;
+ sensorPath = "IPMB";
+ }
+ // Content of event data field depends on sensor class.
+ // When data0 bit[5:4] is non-zero, valid data counts is 3.
+ // When data0 bit[7:6] is non-zero, valid data counts is 2.
+ if (((req->data[0] & byte3EnableMask) != 0 &&
+ paraLen < selSystemEventSizeWith3Bytes) ||
+ ((req->data[0] & byte2EnableMask) != 0 &&
+ paraLen < selSystemEventSizeWith2Bytes))
+ {
+ return IPMI_CC_REQ_DATA_LEN_INVALID;
+ }
+
+ // Count bytes of Event Data
+ if ((req->data[0] & byte3EnableMask) != 0)
+ {
+ count = 3;
+ }
+ else if ((req->data[0] & byte2EnableMask) != 0)
+ {
+ count = 2;
+ }
+ else
+ {
+ count = 1;
+ }
+ assert = req->eventDirectionType & directionMask ? false : true;
+ std::vector<uint8_t> eventData(req->data, req->data + count);
+
+ sdbusplus::bus::bus dbus(bus);
+ std::string service =
+ ipmi::getService(dbus, ipmiSELAddInterface, ipmiSELPath);
+ sdbusplus::message::message writeSEL = dbus.new_method_call(
+ service.c_str(), ipmiSELPath, ipmiSELAddInterface, "IpmiSelAdd");
+ writeSEL.append(ipmiSELAddMessage, sensorPath, eventData, assert,
+ generatorID);
+ try
+ {
+ dbus.call(writeSEL);
+ }
+ catch (sdbusplus::exception_t& e)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(e.what());
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+ return IPMI_CC_OK;
+}
+
void register_netfn_sen_functions()
{
// <Wildcard Command>
ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_WILDCARD, nullptr,
ipmi_sen_wildcard, PRIVILEGE_USER);
+ // <Platform Event Message>
+ ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_PLATFORM_EVENT, nullptr,
+ ipmicmdPlatformEvent, PRIVILEGE_OPERATOR);
// <Get Sensor Type>
ipmi_register_callback(NETFUN_SENSOR, IPMI_CMD_GET_SENSOR_TYPE, nullptr,
ipmi_sen_get_sensor_type, PRIVILEGE_USER);
diff --git a/sensorhandler.hpp b/sensorhandler.hpp
index 1d455f3..0338597 100644
--- a/sensorhandler.hpp
+++ b/sensorhandler.hpp
@@ -8,6 +8,7 @@
// IPMI commands for net functions.
enum ipmi_netfn_sen_cmds
{
+ IPMI_CMD_PLATFORM_EVENT = 0x2,
IPMI_CMD_GET_DEVICE_SDR_INFO = 0x20,
IPMI_CMD_GET_DEVICE_SDR = 0x21,
IPMI_CMD_RESERVE_DEVICE_SDR_REPO = 0x22,
@@ -48,6 +49,28 @@ struct dbus_interface_t
char interface[MAX_DBUS_PATH];
};
+struct PlatformEventRequest
+{
+ uint8_t eventMessageRevision;
+ uint8_t sensorType;
+ uint8_t sensorNumber;
+ uint8_t eventDirectionType;
+ uint8_t data[3];
+};
+
+static constexpr char const* ipmiSELPath = "/xyz/openbmc_project/Logging/IPMI";
+static constexpr char const* ipmiSELAddInterface =
+ "xyz.openbmc_project.Logging.IPMI";
+static const std::string ipmiSELAddMessage = "SEL Entry";
+
+static constexpr int selSystemEventSizeWith3Bytes = 8;
+static constexpr int selSystemEventSizeWith2Bytes = 7;
+static constexpr int selSystemEventSizeWith1Bytes = 6;
+static constexpr int selIPMBEventSize = 7;
+static constexpr uint8_t directionMask = 0x80;
+static constexpr uint8_t byte3EnableMask = 0x30;
+static constexpr uint8_t byte2EnableMask = 0xC0;
+
int set_sensor_dbus_state_s(uint8_t, const char*, const char*);
int set_sensor_dbus_state_y(uint8_t, const char*, const uint8_t);
int find_openbmc_path(uint8_t, dbus_interface_t*);
OpenPOWER on IntegriCloud