diff options
author | Vasant Hegde <hegdevasant@linux.vnet.ibm.com> | 2015-08-10 10:55:41 +0530 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2015-08-14 17:22:12 +1000 |
commit | 127a7dacaa4c506053af7b5db9ca9ae522835ab6 (patch) | |
tree | 419a22b021270de54747c87e7460f1b3c764df3d /hw | |
parent | fcf76c99620cb2057bdbc4475a96a5a135e851a2 (diff) | |
download | skiboot-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>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/ipmi/ipmi-sel.c | 83 |
1 files changed, 83 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; |