[Skiboot] [PATCH] IPMI: Add SEL event with eSEL record ID

Vasant Hegde hegdevasant at linux.vnet.ibm.com
Mon Aug 10 15:25:41 AEST 2015


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 at linux.vnet.ibm.com>
---
 hw/ipmi/ipmi-sel.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/ipmi.h     |  1 +
 2 files changed, 84 insertions(+)

diff --git a/hw/ipmi/ipmi-sel.c b/hw/ipmi/ipmi-sel.c
index 2842a0a..872134f 100644
--- a/hw/ipmi/ipmi-sel.c
+++ b/hw/ipmi/ipmi-sel.c
@@ -148,6 +148,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)
@@ -159,6 +202,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
@@ -223,6 +302,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)
-- 
2.1.0



More information about the Skiboot mailing list