diff --git a/hw/ipmi/ipmi-sel.c b/hw/ipmi/ipmi-sel.c
index e672ecf..f03f19e 100644
--- a/hw/ipmi/ipmi-sel.c
+++ b/hw/ipmi/ipmi-sel.c
@@ -44,6 +44,74 @@
 #define RELEASE_PNOR		0x00
 #define REQUEST_PNOR		0x01
 
+/* 32.1 SEL Event Records type */
+#define SEL_REC_TYPE_SYS_EVENT	0x02
+#define SEL_REC_TYPE_AMI_ESEL	0xDF
+
+/* OEM SEL generator ID for AMI */
+#define SEL_GENERATOR_ID_AMI	0x2000
+
+/* IPMI SEL version */
+#define SEL_EVM_VER_1		0x03
+#define SEL_EVM_VER_2		0x04
+
+/*
+ * Sensor type for System events
+ *
+ * Sensor information (type, number, etc) is passed to us via
+ * device tree. Currently we are using System Event type to
+ * log OPAL events.
+ */
+#define SENSOR_TYPE_SYS_EVENT	0x12
+
+/*
+ * 42.1 Event/Reading Type Codes
+ *
+ * Note that device hotplug and availability related events
+ * are not defined as we are not using those events type.
+ */
+#define SEL_EVENT_DIR_TYPE_UNSPECIFIED	0x00
+#define SEL_EVENT_DIR_TYPE_THRESHOLD	0x01
+#define SEL_EVENT_DIR_TYPE_STATE	0x03
+#define SEL_EVENT_DIR_TYPE_PREDICTIVE	0x04
+#define SEL_EVENT_DIR_TYPE_LIMIT	0x05
+#define SEL_EVENT_DIR_TYPE_PERFORMANCE	0x06
+#define SEL_EVENT_DIR_TYPE_TRANSITION	0x07
+#define SEL_EVENT_DIR_TYPE_OEM		0x70
+
+/*
+ * 42.1 Event/Reading Type Codes
+ */
+#define SEL_DATA1_AMI			0xAA
+#define SEL_DATA1_DEASSERTED		0x00
+#define SEL_DATA1_ASSERTED		0x01
+#define SEL_DATA1_OK			0x00
+#define SEL_DATA1_NON_CRIT_FROM_OK	0x01
+#define SEL_DATA1_CRIT_FROM_LESS_SEV	0x02
+#define SEL_DATA1_NON_REC_FROM_LESS_SEV	0x03
+#define SEL_DATA1_NON_CRIT		0x04
+#define SEL_DATA1_CRITICAL		0x05
+#define SEL_DATA1_NON_RECOVERABLE	0X06
+#define SEL_DATA1_MONITOR		0x07
+#define SEL_DATA1_INFORMATIONAL		0x08
+
+/* SEL Record Entry */
+struct sel_record {
+	le16		record_id;
+	uint8_t		record_type;
+	le32		timestamp;
+	le16		generator_id;
+	uint8_t		evm_ver;
+	uint8_t		sensor_type;
+	uint8_t		sensor_number;
+	uint8_t		event_dir_type;
+	uint8_t		event_data1;
+	uint8_t		event_data2;
+	uint8_t		event_data3;
+} __packed;
+
+static struct sel_record sel_record;
+
 struct oem_sel {
 	/* SEL header */
 	uint8_t id[2];
@@ -65,6 +133,21 @@ struct oem_sel {
 
 #define ESEL_HDR_SIZE 7
 
+
+/* Initialize eSEL record */
+static void ipmi_init_esel_record(void)
+{
+	memset(&sel_record, 0, sizeof(struct sel_record));
+	sel_record.record_type = SEL_REC_TYPE_AMI_ESEL;
+	sel_record.generator_id = SEL_GENERATOR_ID_AMI;
+	sel_record.evm_ver = SEL_EVM_VER_2;
+	sel_record.sensor_type	= SENSOR_TYPE_SYS_EVENT;
+	sel_record.sensor_number =
+		ipmi_get_sensor_number(SENSOR_TYPE_SYS_EVENT);
+	sel_record.event_dir_type = SEL_EVENT_DIR_TYPE_OEM;
+	sel_record.event_data1 = SEL_DATA1_AMI;
+}
+
 static void ipmi_elog_error(struct ipmi_msg *msg)
 {
 	if (msg->cc == IPMI_LOST_ARBITRATION_ERR)
@@ -79,7 +162,8 @@ static void ipmi_elog_error(struct ipmi_msg *msg)
 /* Goes through the required steps to add a complete eSEL:
  *
  *  1. Get a reservation
- *  2. Partially add data to the SEL
+ *  2. Add eSEL header
+ *  3. Partially add data to the SEL
  *
  * Because a reservation is needed we need to ensure eSEL's are added
  * as a single transaction as concurrent/interleaved adds would cancel
@@ -96,15 +180,21 @@ static void ipmi_elog_error(struct ipmi_msg *msg)
  */
 static void ipmi_elog_poll(struct ipmi_msg *msg)
 {
+	static bool first = false;
 	static char pel_buf[MAX_PEL_SIZE];
 	static size_t pel_size;
-	static int index = 0;
+	static size_t esel_size;
+	static int esel_index = 0;
+	int pel_index;
 	static unsigned int reservation_id = 0;
 	static unsigned int record_id = 0;
 	struct errorlog *elog_buf = (struct errorlog *) msg->user_data;
 	size_t req_size;
 
+	ipmi_init_esel_record();
+
 	if (msg->cmd == IPMI_CMD(IPMI_RESERVE_SEL)) {
+		first = true;
 		reservation_id = msg->data[0];
 		reservation_id |= msg->data[1] << 8;
 		if (!reservation_id) {
@@ -118,7 +208,8 @@ static void ipmi_elog_poll(struct ipmi_msg *msg)
 		}
 
 		pel_size = create_pel_log(elog_buf, pel_buf, MAX_PEL_SIZE);
-		index = 0;
+		esel_size = pel_size + sizeof(struct sel_record);
+		esel_index = 0;
 		record_id = 0;
 	} else {
 		record_id = msg->data[0];
@@ -126,21 +217,21 @@ static void ipmi_elog_poll(struct ipmi_msg *msg)
 	}
 
 	/* Start or continue the IPMI_PARTIAL_ADD_SEL */
-	if (index >= pel_size) {
+	if (esel_index >= esel_size) {
 		/* We're all done. Invalidate the resevation id to
 		 * ensure we get an error if we cut in on another eSEL
 		 * message. */
 		reservation_id = 0;
-		index = 0;
+		esel_index = 0;
 		opal_elog_complete(elog_buf, true);
 		ipmi_free_msg(msg);
 		return;
 	}
 
-	if ((pel_size - index) < (IPMI_MAX_REQ_SIZE - ESEL_HDR_SIZE)) {
+	if ((esel_size - esel_index) < (IPMI_MAX_REQ_SIZE - ESEL_HDR_SIZE)) {
 		/* Last data to send */
 		msg->data[6] = 1;
-		req_size = pel_size - index + ESEL_HDR_SIZE;
+		req_size = esel_size - esel_index + ESEL_HDR_SIZE;
 	} else {
 		msg->data[6] = 0;
 		req_size = IPMI_MAX_REQ_SIZE;
@@ -153,11 +244,21 @@ static void ipmi_elog_poll(struct ipmi_msg *msg)
 	msg->data[1] = (reservation_id >> 8) & 0xff;
 	msg->data[2] = record_id & 0xff;
 	msg->data[3] = (record_id >> 8) & 0xff;
-	msg->data[4] = index & 0xff;
-	msg->data[5] = (index >> 8) & 0xff;
-
-	memcpy(&msg->data[ESEL_HDR_SIZE], &pel_buf[index], msg->req_size - ESEL_HDR_SIZE);
-	index += msg->req_size - ESEL_HDR_SIZE;
+	msg->data[4] = esel_index & 0xff;
+	msg->data[5] = (esel_index >> 8) & 0xff;
+
+	if (first) {
+		first = false;
+		memcpy(&msg->data[ESEL_HDR_SIZE],
+		       &sel_record, sizeof(struct sel_record));
+		esel_index = sizeof(struct sel_record);
+		msg->req_size = esel_index + ESEL_HDR_SIZE;
+	} else {
+		pel_index = esel_index - sizeof(struct sel_record);
+		memcpy(&msg->data[ESEL_HDR_SIZE],
+		       &pel_buf[pel_index], msg->req_size - ESEL_HDR_SIZE);
+		esel_index += msg->req_size - ESEL_HDR_SIZE;
+	}
 
 	ipmi_queue_msg_head(msg);
 	return;
diff --git a/hw/ipmi/ipmi-sensor.c b/hw/ipmi/ipmi-sensor.c
index d890534..c8723ae 100644
--- a/hw/ipmi/ipmi-sensor.c
+++ b/hw/ipmi/ipmi-sensor.c
@@ -36,6 +36,11 @@ struct set_sensor_req {
 	u8 event_data[3];
 };
 
+uint8_t ipmi_get_sensor_number(uint8_t sensor_type)
+{
+	return sensors[sensor_type];
+}
+
 int ipmi_set_boot_count(void)
 {
 	struct set_sensor_req req;
diff --git a/include/ipmi.h b/include/ipmi.h
index 3aaa041..f34fbbe 100644
--- a/include/ipmi.h
+++ b/include/ipmi.h
@@ -258,6 +258,9 @@ void ipmi_wdt_final_reset(void);
 /* Discover id of settable ipmi sensors */
 void ipmi_sensor_init(void);
 
+/* Get sensor number for given sensor type */
+uint8_t ipmi_get_sensor_number(uint8_t sensor_type);
+
 /* Set the boot count once the OS is up and running */
 int ipmi_set_boot_count(void);
 
