[Skiboot] [PATCH V4 2/6] opal/errorlog : Generalizes the error log write path to host

Mukesh Ojha mukesh02 at linux.vnet.ibm.com
Tue Jul 26 15:45:34 AEST 2016


Movement of opal error log generic functions from fsp-elog-write.c to new
file core/errorlog.c . Function declarations are kept in errorlog.h, which
was there in fsp-elog.h earlier and fsp specific header files are kept in
fsp-elog.h .

Implementation of generic init routine for error log writing to host will
be initialised independent of the platform on which it is going to run. It
also involves a common memory buffer which will be used to copy the logs
from opal to host buffer.

Signed-off-by: Mukesh Ojha <mukesh02 at linux.vnet.ibm.com>
---
Changes in V4:
 - V3 1/6 becomes V4 2/6.
 - Took Stewart's comment and moved generic write to host routine
   to core/errorlog.c .
 - Changes are rebased on master.

Changes in V3:
 -Change of letter case in the description.

Changes in V2:
 -No Changes.

 core/errorlog.c            | 197 +++++++++++++++++++++++++++++++++++++++++++++
 hw/fsp/fsp-elog-read.c     |  15 ----
 hw/fsp/fsp-elog-write.c    | 179 ----------------------------------------
 include/errorlog.h         |  26 +++++-
 include/fsp-elog.h         |  31 +------
 platforms/ibm-fsp/common.c |   4 +
 6 files changed, 229 insertions(+), 223 deletions(-)

diff --git a/core/errorlog.c b/core/errorlog.c
index 3c320f4..d192cb6 100644
--- a/core/errorlog.c
+++ b/core/errorlog.c
@@ -22,6 +22,7 @@
 #include <skiboot.h>
 #include <lock.h>
 #include <errorlog.h>
+#include <pel.h>
 #include <pool.h>
 
 /*
@@ -38,9 +39,21 @@ static uint32_t sapphire_elog_id = 0xB0000000;
 
 /* Pool to allocate elog messages from */
 static struct pool elog_pool;
+bool elog_enabled;
 static struct lock elog_lock = LOCK_UNLOCKED;
 static bool elog_available = false;
 
+static LIST_HEAD(elog_write_to_host_pending);
+static LIST_HEAD(elog_write_to_host_processed);
+
+/* Log buffer size to write into PowerNV */
+#define ELOG_WRITE_TO_HOST_BUFFER_SIZE  0x00004000
+void *elog_write_to_host_buffer;
+
+static struct lock elog_write_to_host_lock = LOCK_UNLOCKED;
+/* Manipulate this only with write_lock held */
+static enum elog_head_state elog_write_to_host_head_state = ELOG_STATE_NONE;
+
 static struct errorlog *get_write_buffer(int opal_event_severity)
 {
 	struct errorlog *buf;
@@ -210,6 +223,179 @@ void log_simple_error(struct opal_err_info *e_info, const char *fmt, ...)
 	}
 }
 
+/* This should be called with elog_write_to_host_lock lock */
+static inline void fsp_elog_write_set_head_state(enum elog_head_state state)
+{
+	elog_set_head_state(true, state);
+	elog_write_to_host_head_state = state;
+}
+
+bool opal_elog_info(uint64_t *opal_elog_id, uint64_t *opal_elog_size)
+{
+	struct errorlog *head;
+	bool rc = false;
+
+	lock(&elog_write_to_host_lock);
+	if (elog_write_to_host_head_state == ELOG_STATE_FETCHED_DATA) {
+		head = list_top(&elog_write_to_host_pending,
+				struct errorlog, link);
+		if (!head) {
+			/*
+			 * @fwts-label ElogListInconsistent
+			 * @fwts-advice Bug in interaction between FSP and
+			 * OPAL. The state maintained by OPAL didn't match
+			 * what the FSP sent.
+			 */
+			prlog(PR_ERR, "%s:Inconsistent internal list state !\n",
+					__func__);
+			fsp_elog_write_set_head_state(ELOG_STATE_NONE);
+		} else {
+			*opal_elog_id = head->plid;
+			*opal_elog_size = head->log_size;
+			fsp_elog_write_set_head_state(ELOG_STATE_FETCHED_INFO);
+			rc = true;
+		}
+	}
+
+	unlock(&elog_write_to_host_lock);
+	return rc;
+}
+
+static void opal_commit_elog_in_host(void)
+{
+	struct errorlog *buf;
+
+	lock(&elog_write_to_host_lock);
+	if (!list_empty(&elog_write_to_host_pending) &&
+			(elog_write_to_host_head_state == ELOG_STATE_NONE)) {
+		buf = list_top(&elog_write_to_host_pending,
+				struct errorlog, link);
+		buf->log_size = create_pel_log(buf,
+				(char *)elog_write_to_host_buffer,
+				ELOG_WRITE_TO_HOST_BUFFER_SIZE);
+		fsp_elog_write_set_head_state(ELOG_STATE_FETCHED_DATA);
+	}
+
+	unlock(&elog_write_to_host_lock);
+}
+
+bool opal_elog_read(uint64_t *buffer, uint64_t opal_elog_size,
+		uint64_t opal_elog_id)
+{
+	struct errorlog *log_data;
+	bool rc = false;
+
+	lock(&elog_write_to_host_lock);
+	if (elog_write_to_host_head_state == ELOG_STATE_FETCHED_INFO) {
+		log_data = list_top(&elog_write_to_host_pending,
+				struct errorlog, link);
+		if (!log_data) {
+			fsp_elog_write_set_head_state(ELOG_STATE_NONE);
+			unlock(&elog_write_to_host_lock);
+			return rc;
+		}
+
+		if ((opal_elog_id != log_data->plid) &&
+				(opal_elog_size != log_data->log_size)) {
+			unlock(&elog_write_to_host_lock);
+			return rc;
+		}
+
+		memcpy((void *)buffer, elog_write_to_host_buffer,
+				opal_elog_size);
+		list_del(&log_data->link);
+		list_add(&elog_write_to_host_processed, &log_data->link);
+		fsp_elog_write_set_head_state(ELOG_STATE_NONE);
+		rc = true;
+	}
+
+	unlock(&elog_write_to_host_lock);
+	opal_commit_elog_in_host();
+	return rc;
+}
+
+bool opal_elog_ack(uint64_t ack_id)
+{
+	bool rc = false;
+	struct errorlog *log_data;
+	struct errorlog *record, *next_record;
+
+	lock(&elog_write_to_host_lock);
+	if (!list_empty(&elog_write_to_host_processed)) {
+		list_for_each_safe(&elog_write_to_host_processed, record,
+				next_record, link) {
+			if (record->plid != ack_id)
+				continue;
+
+			list_del(&record->link);
+			opal_elog_complete(record, true);
+			rc = true;
+		}
+	}
+
+	if ((!rc) && (!list_empty(&elog_write_to_host_pending))) {
+		log_data = list_top(&elog_write_to_host_pending,
+				struct errorlog, link);
+		if (ack_id == log_data->plid)
+			fsp_elog_write_set_head_state(ELOG_STATE_NONE);
+
+		list_for_each_safe(&elog_write_to_host_pending, record,
+				next_record, link) {
+			if (record->plid != ack_id)
+				continue;
+
+			list_del(&record->link);
+			opal_elog_complete(record, true);
+			rc = true;
+			unlock(&elog_write_to_host_lock);
+			opal_commit_elog_in_host();
+			return rc;
+		}
+	}
+
+	unlock(&elog_write_to_host_lock);
+	return rc;
+}
+
+void opal_resend_pending_logs(void)
+{
+	struct errorlog *record;
+
+	lock(&elog_write_to_host_lock);
+	while (!list_empty(&elog_write_to_host_processed)) {
+		record = list_pop(&elog_write_to_host_processed,
+				struct errorlog, link);
+		list_add_tail(&elog_write_to_host_pending, &record->link);
+	}
+
+	fsp_elog_write_set_head_state(ELOG_STATE_NONE);
+	unlock(&elog_write_to_host_lock);
+	opal_commit_elog_in_host();
+}
+
+void elog_append_write_to_host(struct errorlog *buf)
+{
+	lock(&elog_write_to_host_lock);
+	if (list_empty(&elog_write_to_host_pending)) {
+		list_add(&elog_write_to_host_pending, &buf->link);
+		unlock(&elog_write_to_host_lock);
+		opal_commit_elog_in_host();
+	} else {
+		list_add_tail(&elog_write_to_host_pending, &buf->link);
+		unlock(&elog_write_to_host_lock);
+	}
+}
+
+/* Disable ELOG event flag until PowerNV is ready to receive event */
+static bool opal_kexec_elog_notify(void *data __unused)
+{
+	lock(&elog_write_to_host_lock);
+	elog_enabled = false;
+	opal_update_pending_evt(OPAL_EVENT_ERROR_LOG_AVAIL, 0);
+	unlock(&elog_write_to_host_lock);
+	return true;
+}
+
 int elog_init(void)
 {
 	/* Pre-allocate memory for records */
@@ -220,3 +406,14 @@ int elog_init(void)
 	elog_available = true;
 	return 0;
 }
+
+void opal_elog_init(void)
+{
+	elog_enabled = true;
+	/* Register for sync on PowerNV reboot call */
+	opal_add_host_sync_notifier(opal_kexec_elog_notify, NULL);
+	elog_write_to_host_buffer = memalign(TCE_PSIZE,
+					ELOG_WRITE_TO_HOST_BUFFER_SIZE);
+	assert(elog_write_to_host_buffer);
+	elog_init();
+}
diff --git a/hw/fsp/fsp-elog-read.c b/hw/fsp/fsp-elog-read.c
index 3a0aa5a..12405c8 100644
--- a/hw/fsp/fsp-elog-read.c
+++ b/hw/fsp/fsp-elog-read.c
@@ -81,7 +81,6 @@ static uint32_t elog_read_retries;	/* Bad response status count */
 
 /* Initialize the state of the log */
 static enum elog_head_state elog_read_from_fsp_head_state = ELOG_STATE_NONE;
-static bool elog_enabled;
 
 /* Need forward declaration because of circular dependency. */
 static void fsp_elog_queue_fetch(void);
@@ -467,17 +466,6 @@ static void fsp_opal_resend_pending_logs(void)
 	fsp_elog_check_and_fetch_head();
 }
 
-/* Disable ELOG event flag until PowerNV is ready to receive event */
-static bool opal_kexec_elog_notify(void *data __unused)
-{
-	lock(&elog_read_lock);
-	elog_reject_head();
-	elog_enabled = false;
-	opal_update_pending_evt(OPAL_EVENT_ERROR_LOG_AVAIL, 0);
-	unlock(&elog_read_lock);
-	return true;
-}
-
 /* FSP elog notify function */
 static bool fsp_elog_msg(uint32_t cmd_sub_mod, struct fsp_msg *msg)
 {
@@ -593,11 +581,8 @@ void fsp_elog_read_init(void)
 	if (val != 0)
 		return;
 
-	elog_enabled = true;
 	/* Register error log class D2 */
 	fsp_register_client(&fsp_get_elog_notify, FSP_MCLASS_ERR_LOG);
-	/* Register for sync on PowerNV reboot call */
-	opal_add_host_sync_notifier(opal_kexec_elog_notify, NULL);
 	/* Register OPAL interface */
 	opal_register(OPAL_ELOG_READ, fsp_opal_elog_read, 3);
 	opal_register(OPAL_ELOG_ACK, fsp_opal_elog_ack, 1);
diff --git a/hw/fsp/fsp-elog-write.c b/hw/fsp/fsp-elog-write.c
index 26bef95..199aed3 100644
--- a/hw/fsp/fsp-elog-write.c
+++ b/hw/fsp/fsp-elog-write.c
@@ -36,12 +36,9 @@
 #include <timebase.h>
 
 static LIST_HEAD(elog_write_to_fsp_pending);
-static LIST_HEAD(elog_write_to_host_pending);
-static LIST_HEAD(elog_write_to_host_processed);
 
 static struct lock elog_write_lock = LOCK_UNLOCKED;
 static struct lock elog_panic_write_lock = LOCK_UNLOCKED;
-static struct lock elog_write_to_host_lock = LOCK_UNLOCKED;
 
 #define ELOG_WRITE_TO_FSP_BUFFER_SIZE	0x00004000
 /* Log buffer to copy OPAL log for write to FSP */
@@ -49,14 +46,10 @@ static void *elog_write_to_fsp_buffer;
 
 #define ELOG_PANIC_WRITE_BUFFER_SIZE	0x00004000
 static void *elog_panic_write_buffer;
-
-#define ELOG_WRITE_TO_HOST_BUFFER_SIZE	0x00004000
-static void *elog_write_to_host_buffer;
 static uint32_t elog_write_retries;
 
 /* Manipulate this only with write_lock held */
 static uint32_t elog_plid_fsp_commit = -1;
-static enum elog_head_state elog_write_to_host_head_state = ELOG_STATE_NONE;
 
 /* Need forward declaration because of circular dependency */
 static int opal_send_elog_to_fsp(void);
@@ -128,157 +121,6 @@ static int64_t fsp_opal_elog_write(size_t opal_elog_size)
 	return OPAL_SUCCESS;
 }
 
-/* This should be called with elog_write_to_host_lock lock */
-static inline void fsp_elog_write_set_head_state(enum elog_head_state state)
-{
-	elog_set_head_state(true, state);
-	elog_write_to_host_head_state = state;
-}
-
-bool opal_elog_info(uint64_t *opal_elog_id, uint64_t *opal_elog_size)
-{
-	struct errorlog *head;
-	bool rc = false;
-
-	lock(&elog_write_to_host_lock);
-	if (elog_write_to_host_head_state == ELOG_STATE_FETCHED_DATA) {
-		head = list_top(&elog_write_to_host_pending,
-					struct errorlog, link);
-		if (!head) {
-			/*
-			 * @fwts-label ElogListInconsistent
-			 * @fwts-advice Bug in interaction between FSP and
-			 * OPAL. The state maintained by OPAL didn't match
-			 * what the FSP sent.
-			 */
-			prlog(PR_ERR,
-			      "%s: Inconsistent internal list state !\n",
-			      __func__);
-			fsp_elog_write_set_head_state(ELOG_STATE_NONE);
-		} else {
-			*opal_elog_id = head->plid;
-			*opal_elog_size = head->log_size;
-			fsp_elog_write_set_head_state(ELOG_STATE_FETCHED_INFO);
-			rc = true;
-		}
-	}
-
-	unlock(&elog_write_to_host_lock);
-	return rc;
-}
-
-static void opal_commit_elog_in_host(void)
-{
-	struct errorlog *buf;
-
-	lock(&elog_write_to_host_lock);
-	if (!list_empty(&elog_write_to_host_pending) &&
-			(elog_write_to_host_head_state == ELOG_STATE_NONE)) {
-		buf = list_top(&elog_write_to_host_pending,
-				struct errorlog, link);
-		buf->log_size = create_pel_log(buf,
-					(char *)elog_write_to_host_buffer,
-					ELOG_WRITE_TO_HOST_BUFFER_SIZE);
-		fsp_elog_write_set_head_state(ELOG_STATE_FETCHED_DATA);
-	}
-
-	unlock(&elog_write_to_host_lock);
-}
-
-bool opal_elog_read(uint64_t *buffer, uint64_t opal_elog_size,
-		    uint64_t opal_elog_id)
-{
-	struct errorlog *log_data;
-	bool rc = false;
-
-	lock(&elog_write_to_host_lock);
-	if (elog_write_to_host_head_state == ELOG_STATE_FETCHED_INFO) {
-		log_data = list_top(&elog_write_to_host_pending,
-					struct errorlog, link);
-		if (!log_data) {
-			fsp_elog_write_set_head_state(ELOG_STATE_NONE);
-			unlock(&elog_write_to_host_lock);
-			return rc;
-		}
-
-		if ((opal_elog_id != log_data->plid) &&
-		    (opal_elog_size != log_data->log_size)) {
-			unlock(&elog_write_to_host_lock);
-			return rc;
-		}
-
-		memcpy((void *)buffer, elog_write_to_host_buffer,
-							opal_elog_size);
-		list_del(&log_data->link);
-		list_add(&elog_write_to_host_processed, &log_data->link);
-		fsp_elog_write_set_head_state(ELOG_STATE_NONE);
-		rc = true;
-	}
-
-	unlock(&elog_write_to_host_lock);
-	opal_commit_elog_in_host();
-	return rc;
-}
-
-bool opal_elog_ack(uint64_t ack_id)
-{
-	bool rc = false;
-	struct errorlog *log_data;
-	struct errorlog *record, *next_record;
-
-	lock(&elog_write_to_host_lock);
-	if (!list_empty(&elog_write_to_host_processed)) {
-		list_for_each_safe(&elog_write_to_host_processed, record,
-							next_record, link) {
-			if (record->plid != ack_id)
-				continue;
-
-			list_del(&record->link);
-			opal_elog_complete(record, true);
-			rc = true;
-		}
-	}
-
-	if ((!rc) && (!list_empty(&elog_write_to_host_pending))) {
-		log_data = list_top(&elog_write_to_host_pending,
-						struct errorlog, link);
-		if (ack_id == log_data->plid)
-			fsp_elog_write_set_head_state(ELOG_STATE_NONE);
-
-		list_for_each_safe(&elog_write_to_host_pending, record,
-						next_record, link) {
-			if (record->plid != ack_id)
-				continue;
-
-			list_del(&record->link);
-			opal_elog_complete(record, true);
-			rc = true;
-			unlock(&elog_write_to_host_lock);
-			opal_commit_elog_in_host();
-			return rc;
-		}
-	}
-
-	unlock(&elog_write_to_host_lock);
-	return rc;
-}
-
-void opal_resend_pending_logs(void)
-{
-	struct errorlog *record;
-
-	lock(&elog_write_to_host_lock);
-	while (!list_empty(&elog_write_to_host_processed)) {
-		record = list_pop(&elog_write_to_host_processed,
-					struct errorlog, link);
-		list_add_tail(&elog_write_to_host_pending, &record->link);
-	}
-
-	fsp_elog_write_set_head_state(ELOG_STATE_NONE);
-	unlock(&elog_write_to_host_lock);
-	opal_commit_elog_in_host();
-}
-
 static int opal_send_elog_to_fsp(void)
 {
 	struct errorlog *head;
@@ -371,19 +213,6 @@ int elog_fsp_commit(struct errorlog *buf)
 	return rc;
 }
 
-static void elog_append_write_to_host(struct errorlog *buf)
-{
-	lock(&elog_write_to_host_lock);
-	if (list_empty(&elog_write_to_host_pending)) {
-		list_add(&elog_write_to_host_pending, &buf->link);
-		unlock(&elog_write_to_host_lock);
-		opal_commit_elog_in_host();
-	} else {
-		list_add_tail(&elog_write_to_host_pending, &buf->link);
-		unlock(&elog_write_to_host_lock);
-	}
-}
-
 static void elog_timeout_poll(void *data __unused)
 {
 	uint64_t now;
@@ -429,19 +258,11 @@ void fsp_elog_write_init(void)
 		return;
 	}
 
-	elog_write_to_host_buffer = memalign(TCE_PSIZE,
-					ELOG_WRITE_TO_HOST_BUFFER_SIZE);
-	if (!elog_write_to_host_buffer) {
-		prerror("FSP: could not allocate ELOG_WRITE_TO_HOST_BUFFER!\n");
-		return;
-	}
-
 	/* Map TCEs */
 	fsp_tce_map(PSI_DMA_ELOG_PANIC_WRITE_BUF, elog_panic_write_buffer,
 					PSI_DMA_ELOG_PANIC_WRITE_BUF_SZ);
 	fsp_tce_map(PSI_DMA_ERRLOG_WRITE_BUF, elog_write_to_fsp_buffer,
 					PSI_DMA_ERRLOG_WRITE_BUF_SZ);
-	elog_init();
 	/* Add a poller */
 	opal_add_poller(elog_timeout_poll, NULL);
 }
diff --git a/include/errorlog.h b/include/errorlog.h
index 2926098..3251cfe 100644
--- a/include/errorlog.h
+++ b/include/errorlog.h
@@ -1,4 +1,4 @@
-/* Copyright 2013-2014 IBM Corp.
+/* Copyright 2013-2016 IBM Corp.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -331,6 +331,20 @@ enum opal_reasoncode {
 	OPAL_RC_ABNORMAL_REBOOT	= OPAL_CE | 0x10,
 };
 
+/* Following variables are used to indicate state of the
+ * head log entry which is being fetched from FSP/OPAL and
+ * these variables are not overwritten until next log is
+ * retrieved from FSP/OPAL.
+ */
+enum elog_head_state {
+	ELOG_STATE_FETCHING,    /*In the process of reading log from FSP. */
+	ELOG_STATE_FETCHED_INFO,/* Indicates reading log info is completed */
+	ELOG_STATE_FETCHED_DATA,/* Indicates reading log is completed */
+	ELOG_STATE_HOST_INFO,   /* Host read log info */
+	ELOG_STATE_NONE,        /* Indicates to fetch next log */
+	ELOG_STATE_REJECTED,    /* resend all pending logs to linux */
+};
+
 #define DEFINE_LOG_ENTRY(reason, type, id, subsys,			\
 severity, subtype) static struct opal_err_info err_##reason =		\
 { .reason_code = reason, .err_type = type, .cmp_id = id,		\
@@ -357,7 +371,15 @@ void log_commit(struct errorlog *elog);
  * backend. If the error could not be logged successfully success is
  * set to false. */
 void opal_elog_complete(struct errorlog *elog, bool success);
-
+void elog_append_write_to_host(struct errorlog *buf);
 int elog_init(void);
+void opal_elog_init(void);
+bool opal_elog_info(uint64_t *opal_elog_id,
+		uint64_t *opal_elog_size) __warn_unused_result;
+bool opal_elog_read(uint64_t *buffer, uint64_t opal_elog_size,
+		uint64_t opal_elog_id) __warn_unused_result;
+bool opal_elog_ack(uint64_t ack_id) __warn_unused_result;
+void opal_resend_pending_logs(void);
+void elog_set_head_state(bool opal_logs, enum elog_head_state state);
 
 #endif /* __ERRORLOG_H */
diff --git a/include/fsp-elog.h b/include/fsp-elog.h
index a796f5e..217cdbe 100644
--- a/include/fsp-elog.h
+++ b/include/fsp-elog.h
@@ -13,44 +13,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+#ifndef __ELOG_H
+#define __ELOG_H
 #include <opal.h>
 #include <errorlog.h>
 #include <pel.h>
-#ifndef __ELOG_H
-#define __ELOG_H
 
 #define ELOG_TYPE_PEL			0
 #define MAX_RETRIES			3
 
-/* Following variables are used to indicate state of the
- * head log entry which is being fetched from FSP/OPAL and
- * these variables are not overwritten until next log is
- * retrieved from FSP/OPAL.
- */
-enum elog_head_state {
-	ELOG_STATE_FETCHING,    /*In the process of reading log from FSP. */
-	ELOG_STATE_FETCHED_INFO,/* Indicates reading log info is completed */
-	ELOG_STATE_FETCHED_DATA,/* Indicates reading log is completed */
-	ELOG_STATE_HOST_INFO,	/* Host read log info */
-	ELOG_STATE_NONE,        /* Indicates to fetch next log */
-	ELOG_STATE_REJECTED,    /* resend all pending logs to linux */
-};
-
 /* Generate src from opal reason code (src_comp) */
 #define generate_src_from_comp(src_comp)  (OPAL_SRC_TYPE_ERROR << 24 | \
 				OPAL_FAILING_SUBSYSTEM << 16 | src_comp)
 
-int elog_fsp_commit(struct errorlog *buf) __warn_unused_result;
-
-bool opal_elog_info(uint64_t *opal_elog_id, uint64_t *opal_elog_size) __warn_unused_result;
-
-bool opal_elog_read(uint64_t *buffer, uint64_t opal_elog_size,
-						uint64_t opal_elog_id) __warn_unused_result;
+extern bool elog_enabled;
 
-bool opal_elog_ack(uint64_t ack_id) __warn_unused_result;
-
-void opal_resend_pending_logs(void);
-
-void elog_set_head_state(bool opal_logs, enum elog_head_state state);
+int elog_fsp_commit(struct errorlog *buf) __warn_unused_result;
 
 #endif /* __ELOG_H */
diff --git a/platforms/ibm-fsp/common.c b/platforms/ibm-fsp/common.c
index dc3a002..ecda07c 100644
--- a/platforms/ibm-fsp/common.c
+++ b/platforms/ibm-fsp/common.c
@@ -22,6 +22,7 @@
 #include <console.h>
 #include <hostservices.h>
 #include <ipmi.h>
+#include <errorlog.h>
 
 #include "ibm-fsp.h"
 
@@ -92,6 +93,9 @@ void ibm_fsp_init(void)
 	/* Get ready to receive OCC related messages */
 	occ_fsp_init();
 
+	/* Initialize the errorlog framework */
+	opal_elog_init();
+
 	/* Get ready to receive Memory [Un]corretable Error messages. */
 	fsp_memory_err_init();
 
-- 
2.7.4



More information about the Skiboot mailing list