aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVasant Hegde <hegdevasant@linux.vnet.ibm.com>2015-08-10 10:55:41 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-08-14 17:22:12 +1000
commit127a7dacaa4c506053af7b5db9ca9ae522835ab6 (patch)
tree419a22b021270de54747c87e7460f1b3c764df3d
parentfcf76c99620cb2057bdbc4475a96a5a135e851a2 (diff)
downloadskiboot-127a7dacaa4c506053af7b5db9ca9ae522835ab6.zip
skiboot-127a7dacaa4c506053af7b5db9ca9ae522835ab6.tar.gz
skiboot-127a7dacaa4c506053af7b5db9ca9ae522835ab6.tar.bz2
IPMI: Add SEL event with eSEL record ID
Our PEL logs doesn't contain timestamp as we don't have timesource. Hence create SEL event for every eSEL log with eSEL record ID. This event will be used to get PEL event time. New SEL event contains eSEL record ID. Sample output: ------------- SEL Record ID : 0016 Record Type : 02 Timestamp : 08/09/2015 12:35:16 Generator ID : 0020 EvM Revision : 04 Sensor Type : System Event Sensor Number : 61 Event Type : Generic Discrete Event Direction : Assertion Event Event Data (RAW) : 011400 Description : State Asserted Sensor ID : System Event (0x61) Entity ID : 1.0 Sensor Type (Discrete): System Event Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
-rw-r--r--hw/ipmi/ipmi-sel.c83
-rw-r--r--include/ipmi.h1
2 files changed, 84 insertions, 0 deletions
diff --git a/hw/ipmi/ipmi-sel.c b/hw/ipmi/ipmi-sel.c
index 17cb39a..343ca02 100644
--- a/hw/ipmi/ipmi-sel.c
+++ b/hw/ipmi/ipmi-sel.c
@@ -149,6 +149,49 @@ static void ipmi_init_esel_record(void)
sel_record.event_data1 = SEL_DATA1_AMI;
}
+/* Update required fields in SEL record */
+static void ipmi_update_sel_record(uint8_t event_severity, uint16_t esel_record_id)
+{
+ sel_record.record_type = SEL_REC_TYPE_SYS_EVENT;
+ sel_record.event_data2 = esel_record_id & 0xff;
+ sel_record.event_data3 = (esel_record_id >> 8) & 0xff;
+
+ switch (event_severity) {
+ case OPAL_ERROR_PANIC:
+ sel_record.event_dir_type = SEL_EVENT_DIR_TYPE_TRANSITION;
+ sel_record.event_data1 = SEL_DATA1_CRITICAL;
+ break;
+ case OPAL_UNRECOVERABLE_ERR_GENERAL: /* Fall through */
+ case OPAL_UNRECOVERABLE_ERR_DEGRADE_PERF:
+ case OPAL_UNRECOVERABLE_ERR_LOSS_REDUNDANCY:
+ case OPAL_UNRECOVERABLE_ERR_LOSS_REDUNDANCY_PERF:
+ case OPAL_UNRECOVERABLE_ERR_LOSS_OF_FUNCTION:
+ sel_record.event_dir_type = SEL_EVENT_DIR_TYPE_TRANSITION;
+ sel_record.event_data1 = SEL_DATA1_NON_RECOVERABLE;
+ break;
+ case OPAL_PREDICTIVE_ERR_GENERAL: /* Fall through */
+ case OPAL_PREDICTIVE_ERR_DEGRADED_PERF:
+ case OPAL_PREDICTIVE_ERR_FAULT_RECTIFY_REBOOT:
+ case OPAL_PREDICTIVE_ERR_FAULT_RECTIFY_BOOT_DEGRADE_PERF:
+ case OPAL_PREDICTIVE_ERR_LOSS_OF_REDUNDANCY:
+ sel_record.event_dir_type = SEL_EVENT_DIR_TYPE_PREDICTIVE;
+ sel_record.event_data1 = SEL_DATA1_NON_CRIT_FROM_OK;
+ break;
+ case OPAL_RECOVERED_ERR_GENERAL:
+ sel_record.event_dir_type = SEL_EVENT_DIR_TYPE_TRANSITION;
+ sel_record.event_data1 = SEL_DATA1_OK;
+ break;
+ case OPAL_INFO:
+ sel_record.event_dir_type = SEL_EVENT_DIR_TYPE_TRANSITION;
+ sel_record.event_data1 = SEL_DATA1_INFORMATIONAL;
+ break;
+ default:
+ sel_record.event_dir_type = SEL_EVENT_DIR_TYPE_STATE;
+ sel_record.event_data1 = SEL_DATA1_ASSERTED;
+ break;
+ }
+}
+
static void ipmi_elog_error(struct ipmi_msg *msg)
{
if (msg->cc == IPMI_LOST_ARBITRATION_ERR)
@@ -160,6 +203,42 @@ static void ipmi_elog_error(struct ipmi_msg *msg)
}
}
+static void ipmi_log_sel_event_error(struct ipmi_msg *msg)
+{
+ if (msg->cc != IPMI_CC_NO_ERROR)
+ prlog(PR_INFO, "SEL: Failed to log SEL event\n");
+
+ ipmi_free_msg(msg);
+}
+
+static void ipmi_log_sel_event_complete(struct ipmi_msg *msg)
+{
+ prlog(PR_INFO, "SEL: New event logged [ID : %x%x]\n",
+ msg->data[1], msg->data[0]);
+
+ ipmi_free_msg(msg);
+}
+
+/* Log SEL event with eSEL record ID */
+static void ipmi_log_sel_event(uint8_t event_severity, uint16_t esel_record_id)
+{
+ struct ipmi_msg *msg;
+
+ /* Fill required SEL event fields */
+ ipmi_update_sel_record(event_severity, esel_record_id);
+
+ msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_ADD_SEL_EVENT,
+ ipmi_log_sel_event_complete, NULL,
+ &sel_record, sizeof(struct sel_record), 2);
+ if (!msg) {
+ prlog(PR_ERR, "SEL: Failed to allocated IPMI message\n");
+ return;
+ }
+
+ msg->error = ipmi_log_sel_event_error;
+ ipmi_queue_msg(msg);
+}
+
/* Goes through the required steps to add a complete eSEL:
*
* 1. Get a reservation
@@ -224,6 +303,10 @@ static void ipmi_elog_poll(struct ipmi_msg *msg)
* message. */
reservation_id = 0;
esel_index = 0;
+
+ /* Log SEL event */
+ ipmi_log_sel_event(elog_buf->event_severity, record_id);
+
opal_elog_complete(elog_buf, true);
ipmi_free_msg(msg);
return;
diff --git a/include/ipmi.h b/include/ipmi.h
index f34fbbe..54c415b 100644
--- a/include/ipmi.h
+++ b/include/ipmi.h
@@ -103,6 +103,7 @@
#define IPMI_WRITE_FRU IPMI_CODE(IPMI_NETFN_STORAGE, 0x12)
#define IPMI_GET_SEL_INFO IPMI_CODE(IPMI_NETFN_STORAGE, 0x40)
#define IPMI_RESERVE_SEL IPMI_CODE(IPMI_NETFN_STORAGE, 0x42)
+#define IPMI_ADD_SEL_EVENT IPMI_CODE(IPMI_NETFN_STORAGE, 0x44)
#define IPMI_GET_SEL_TIME IPMI_CODE(IPMI_NETFN_STORAGE, 0x48)
#define IPMI_SET_SEL_TIME IPMI_CODE(IPMI_NETFN_STORAGE, 0x49)
#define IPMI_CHASSIS_CONTROL IPMI_CODE(IPMI_NETFN_CHASSIS, 0x02)