diff --git a/core/Makefile.inc b/core/Makefile.inc
index ae3c297..f7f464e 100644
--- a/core/Makefile.inc
+++ b/core/Makefile.inc
@@ -8,7 +8,7 @@ CORE_OBJS += pci-opal.o fast-reboot.o device.o exceptions.o trace.o affinity.o
 CORE_OBJS += vpd.o hostservices.o platform.o nvram.o nvram-format.o hmi.o
 CORE_OBJS += console-log.o ipmi.o time-utils.o pel.o pool.o errorlog.o
 CORE_OBJS += timer.o i2c.o rtc.o flash.o sensor.o ipmi-opal.o
-CORE_OBJS += flash-subpartition.o bitmap.o buddy.o
+CORE_OBJS += flash-subpartition.o bitmap.o buddy.o mce.o
 
 ifeq ($(SKIBOOT_GCOV),1)
 CORE_OBJS += gcov-profiling.o
diff --git a/core/exceptions.c b/core/exceptions.c
index c4acf85..5997d49 100644
--- a/core/exceptions.c
+++ b/core/exceptions.c
@@ -56,4 +56,3 @@ static int64_t opal_register_exc_handler(uint64_t opal_exception __unused,
 	return OPAL_UNSUPPORTED;
 }
 opal_call(OPAL_REGISTER_OPAL_EXCEPTION_HANDLER, opal_register_exc_handler, 3);
-
diff --git a/core/mce.c b/core/mce.c
new file mode 100644
index 0000000..8f7548a
--- /dev/null
+++ b/core/mce.c
@@ -0,0 +1,376 @@
+/* Copyright 2017-2018 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *	http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <skiboot.h>
+#include <stack.h>
+#include <opal-api.h>
+#include <processor.h>
+#include <cpu.h>
+
+/*
+ * Machine Check bits on power9
+ */
+#define P9_SRR1_MC_LOADSTORE(srr1)	((srr1) & PPC_BIT(42)) /* P9 */
+
+/*
+ * SRR1 bits for machine check (On Power9)
+ *
+ * I-Side errors are reported through SRR1 bits 36,43:45
+ */
+#define P9_SRR1_MC_IFETCH(srr1)		\
+		((srr1) & (PPC_BIT(36) | PPC_BITMASK(43, 45))) /* P9 */
+
+#define P9_SRR1_MC_IFETCH_UE		(0x1 << PPC_BITLSHIFT(45)) /* P9 */
+#define P9_SRR1_MC_IFETCH_SLB_PARITY	(0x2 << PPC_BITLSHIFT(45)) /* P9 */
+#define P9_SRR1_MC_IFETCH_SLB_MULTIHIT	(0x3 << PPC_BITLSHIFT(45)) /* P9 */
+#define P9_SRR1_MC_IFETCH_ERAT_MULTIHIT	(0x4 << PPC_BITLSHIFT(45)) /* P9 */
+#define P9_SRR1_MC_IFETCH_TLB_MULTIHIT	(0x5 << PPC_BITLSHIFT(45)) /* P9 */
+#define P9_SRR1_MC_IFETCH_UE_TLB_RELOAD	(0x6 << PPC_BITLSHIFT(45)) /* P9 */
+#define P9_SRR1_MC_IFETCH_FSPACE_ADDR	(0x7 << PPC_BITLSHIFT(45)) /* P9 */
+#define P9_SRR1_MC_IFETCH_NEST_ABRT	(PPC_BIT(36))              /* P9 */
+#define P9_SRR1_MC_IFETCH_NEST_ABRT_TABLEWALK		\
+			((PPC_BIT(36)) | (0x1 << PPC_BITLSHIFT(45))) /* P9 */
+#define P9_SRR1_MC_IFETCH_REAL_ADDR			\
+			((PPC_BIT(36)) | (0x3 << PPC_BITLSHIFT(45))) /* P9 */
+#define P9_SRR1_MC_IFETCH_REAL_ADDR_TABLEWALK		\
+			((PPC_BIT(36)) | (0x4 << PPC_BITLSHIFT(45))) /* P9 */
+#define P9_SRR1_MC_IFETCH_HOST_REAL_ADDR		\
+			((PPC_BIT(36)) | (0x7 << PPC_BITLSHIFT(45))) /* P9 */
+
+/* In the Power9 core, there are two asynchronous machine check interrupts.
+ * One is take when store instruction has an out of range real address
+ * associated with it. This is in general a programming error. The second
+ * asynchronous case is when a store is being performed and a foreign link
+ * times out.
+ * Both machine checks will set following bits in SRR1 to identify the
+ * cause:
+ *	SRR1 bit [42]=1, [36]=1 and [43]=1 and 44:45 = 01 0r 10
+ */
+#define P9_SRR1_ASYNC_MC	(PPC_BIT(36) | PPC_BITMASK(42, 43))
+#define P9_SRR1_ASYNC_MC_MASK	(PPC_BIT(36) | PPC_BITMASK(42, 43))
+
+#define P9_SRR1_ASYNC_REAL_ADDR_STORE			\
+			((PPC_BIT(36)) | (0x5 << PPC_BITLSHIFT(45))) /* P9 */
+#define P9_SRR1_ASYNC_NEST_ABRT_STORE			\
+			((PPC_BIT(36)) | (0x6 << PPC_BITLSHIFT(45))) /* P9 */
+
+/* DSISR bits for machine check On Power9. */
+#define P9_DSISR_MC_UE				(PPC_BIT(48))	/* P9 */
+#define P9_DSISR_MC_UE_TABLEWALK		(PPC_BIT(49))	/* P9 */
+#define P9_DSISR_MC_NEST_ABRT_LOAD		(PPC_BIT(50))	/* P9 */
+#define P9_DSISR_MC_NEST_ABRT_TABLEWALK		(PPC_BIT(51))	/* P9 */
+#define P9_DSISR_MC_ERAT_MULTIHIT		(PPC_BIT(52))	/* P9 */
+#define P9_DSISR_MC_TLB_MULTIHIT_MFTLB		(PPC_BIT(53))	/* P9 */
+#define P9_DSISR_MC_TLBIEL_PROG_ERROR		(PPC_BIT(54))	/* P9 */
+#define P9_DSISR_MC_SLB_PARITY_MFSLB		(PPC_BIT(55))	/* P9 */
+#define P9_DSISR_MC_SLB_MULTIHIT		(PPC_BIT(56))	/* P9 */
+#define P9_DSISR_MC_BAD_REAL_ADDR_LOAD		(PPC_BIT(57))	/* P9 */
+#define P9_DSISR_MC_BAD_REAL_ADDR_TABLEWALK	(PPC_BIT(58))	/* P9 */
+#define P9_DSISR_MC_HOST_TO_FSPACE_TRANS	(PPC_BIT(59))	/* P9 */
+#define P9_DSISR_MC_HOST_TO_FSPACE_LOAD_STORE	(PPC_BIT(60))	/* P9 */
+
+/* P9 SLB error bits */
+#define P9_DSISR_MC_SLB_ERRORS		(P9_DSISR_MC_ERAT_MULTIHIT |	\
+					 P9_DSISR_MC_SLB_PARITY_MFSLB | \
+					 P9_DSISR_MC_SLB_MULTIHIT)
+
+/* P9 TLB error bits */
+#define P9_DSISR_MC_TLB_ERRORS		(P9_DSISR_MC_TLB_MULTIHIT_MFTLB | \
+					 P9_DSISR_MC_TLBIEL_PROG_ERROR)
+
+struct mce_error_info {
+	enum MCE_ErrorType error_type:8;
+	union {
+		enum MCE_UeErrorType ue_error_type:8;
+		enum MCE_SlbErrorType slb_error_type:8;
+		enum MCE_EratErrorType erat_error_type:8;
+		enum MCE_TlbErrorType tlb_error_type:8;
+		enum MCE_NestErrorType nest_error_type:8;
+		enum MCE_CrespErrorType cresp_error_type:8;
+		enum MCE_FspaceErrorType fspace_error_type:8;
+		enum MCE_FspaceErrorType async_error_type:8;
+	} u;
+	uint8_t		reserved[2];
+};
+
+struct mce_reason_regs {
+	uint64_t	srr0;
+	uint64_t	srr1;
+	uint64_t	dar;
+	uint64_t	dsisr;
+};
+
+static void mce_get_ierror_p9(struct mce_error_info *mce_err, uint64_t srr1)
+{
+	switch (P9_SRR1_MC_IFETCH(srr1)) {
+	case P9_SRR1_MC_IFETCH_SLB_PARITY:
+		mce_err->error_type = MCE_ERROR_TYPE_SLB;
+		mce_err->u.slb_error_type = MCE_SLB_ERROR_PARITY;
+		break;
+	case P9_SRR1_MC_IFETCH_SLB_MULTIHIT:
+		mce_err->error_type = MCE_ERROR_TYPE_SLB;
+		mce_err->u.slb_error_type = MCE_SLB_ERROR_MULTIHIT;
+		break;
+	case P9_SRR1_MC_IFETCH_ERAT_MULTIHIT:
+		mce_err->error_type = MCE_ERROR_TYPE_ERAT;
+		mce_err->u.erat_error_type = MCE_ERAT_ERROR_MULTIHIT;
+		break;
+	case P9_SRR1_MC_IFETCH_TLB_MULTIHIT:
+		mce_err->error_type = MCE_ERROR_TYPE_TLB;
+		mce_err->u.tlb_error_type = MCE_TLB_ERROR_MULTIHIT;
+		break;
+	case P9_SRR1_MC_IFETCH_UE:
+		mce_err->error_type = MCE_ERROR_TYPE_UE;
+		mce_err->u.ue_error_type = MCE_UE_ERROR_IFETCH;
+		break;
+	case P9_SRR1_MC_IFETCH_UE_TLB_RELOAD:
+		mce_err->error_type = MCE_ERROR_TYPE_UE;
+		mce_err->u.ue_error_type =
+				MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH;
+		break;
+	case P9_SRR1_MC_IFETCH_FSPACE_ADDR:
+		mce_err->error_type = MCE_ERROR_TYPE_FSPACE;
+		mce_err->u.fspace_error_type = MCE_FSPACE_ERROR_IFETCH;
+		break;
+	case P9_SRR1_MC_IFETCH_NEST_ABRT:
+		mce_err->error_type = MCE_ERROR_TYPE_NEST;
+		mce_err->u.nest_error_type = MCE_NEST_ERROR_ABRT_IFETCH;
+		break;
+	case P9_SRR1_MC_IFETCH_NEST_ABRT_TABLEWALK:
+		mce_err->error_type = MCE_ERROR_TYPE_NEST;
+		mce_err->u.nest_error_type =
+				MCE_NEST_ERROR_ABRT_IFETCH_TABLEWALK;
+		break;
+	case P9_SRR1_MC_IFETCH_REAL_ADDR:
+		mce_err->error_type = MCE_ERROR_TYPE_CRESP;
+		mce_err->u.cresp_error_type =
+				MCE_CRESP_ERROR_BAD_RADDR_IFETCH;
+		break;
+	case P9_SRR1_MC_IFETCH_REAL_ADDR_TABLEWALK:
+		mce_err->error_type = MCE_ERROR_TYPE_CRESP;
+		mce_err->u.cresp_error_type =
+				MCE_CRESP_ERROR_BAD_RADDR_IFETCH_TABLEWALK;
+		break;
+	case P9_SRR1_MC_IFETCH_HOST_REAL_ADDR:
+		mce_err->error_type = MCE_ERROR_TYPE_FSPACE;
+		mce_err->u.fspace_error_type =
+					MCE_FSPACE_ERROR_IFETCH_TABLEWALK;
+		break;
+	}
+}
+
+static void mce_get_derror_p9(struct mce_error_info *mce_err, uint64_t dsisr)
+{
+	if (dsisr & P9_DSISR_MC_UE) {
+		mce_err->error_type = MCE_ERROR_TYPE_UE;
+		mce_err->u.ue_error_type = MCE_UE_ERROR_LOAD_STORE;
+	} else if (dsisr & P9_DSISR_MC_UE_TABLEWALK) {
+		mce_err->error_type = MCE_ERROR_TYPE_UE;
+		mce_err->u.ue_error_type =
+				MCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE;
+	} else if (dsisr & P9_DSISR_MC_NEST_ABRT_LOAD) {
+		mce_err->error_type = MCE_ERROR_TYPE_NEST;
+		mce_err->u.nest_error_type = MCE_NEST_ERROR_ABRT_LOAD;
+	} else if (dsisr & P9_DSISR_MC_NEST_ABRT_TABLEWALK) {
+		mce_err->error_type = MCE_ERROR_TYPE_NEST;
+		mce_err->u.nest_error_type =
+				MCE_NEST_ERROR_ABRT_LOAD_TABLEWALK;
+	} else if (dsisr & P9_DSISR_MC_ERAT_MULTIHIT) {
+		mce_err->error_type = MCE_ERROR_TYPE_ERAT;
+		mce_err->u.erat_error_type = MCE_ERAT_ERROR_MULTIHIT;
+	} else if (dsisr & P9_DSISR_MC_TLB_MULTIHIT_MFTLB) {
+		mce_err->error_type = MCE_ERROR_TYPE_TLB;
+		mce_err->u.tlb_error_type = MCE_TLB_ERROR_MULTIHIT;
+	} else if (dsisr & P9_DSISR_MC_TLBIEL_PROG_ERROR) {
+		mce_err->error_type = MCE_ERROR_TYPE_TLB;
+		mce_err->u.tlb_error_type = MCE_TLB_ERROR_TLBIEL_PROG_ERROR;
+	} else if (dsisr & P9_DSISR_MC_SLB_PARITY_MFSLB) {
+		mce_err->error_type = MCE_ERROR_TYPE_SLB;
+		mce_err->u.slb_error_type = MCE_SLB_ERROR_PARITY;
+	} else if (dsisr & P9_DSISR_MC_SLB_MULTIHIT) {
+		mce_err->error_type = MCE_ERROR_TYPE_SLB;
+		mce_err->u.slb_error_type = MCE_SLB_ERROR_MULTIHIT;
+	} else if (dsisr & P9_DSISR_MC_BAD_REAL_ADDR_LOAD) {
+		mce_err->error_type = MCE_ERROR_TYPE_CRESP;
+		mce_err->u.cresp_error_type = MCE_CRESP_ERROR_BAD_RADDR_LOAD;
+	} else if (dsisr & P9_DSISR_MC_BAD_REAL_ADDR_TABLEWALK) {
+		mce_err->error_type = MCE_ERROR_TYPE_CRESP;
+		mce_err->u.cresp_error_type =
+				MCE_CRESP_ERROR_BAD_RADDR_LOAD_TABLEWALK;
+	} else if (dsisr & P9_DSISR_MC_HOST_TO_FSPACE_TRANS) {
+		mce_err->error_type = MCE_ERROR_TYPE_FSPACE;
+		mce_err->u.fspace_error_type =
+				MCE_FSPACE_ERROR_RADDR_TRANSLATION;
+	} else if (dsisr & P9_DSISR_MC_HOST_TO_FSPACE_LOAD_STORE) {
+		mce_err->error_type = MCE_ERROR_TYPE_FSPACE;
+		mce_err->u.fspace_error_type =
+				MCE_FSPACE_ERROR_RADDR_LOAD;
+	}
+}
+
+static void mce_get_async_err_p9(struct mce_error_info *mce_err, uint64_t srr1)
+{
+	switch (P9_SRR1_MC_IFETCH(srr1)) {
+	case P9_SRR1_ASYNC_REAL_ADDR_STORE:
+		mce_err->error_type = MCE_ERROR_TYPE_ASYNC;
+		mce_err->u.async_error_type = MCE_ASYNC_ERROR_REAL_ADDR_STORE;
+		break;
+	case P9_SRR1_ASYNC_NEST_ABRT_STORE:
+		mce_err->error_type = MCE_ERROR_TYPE_ASYNC;
+		mce_err->u.async_error_type = MCE_ASYNC_ERROR_NEST_ABRT_STORE;
+		break;
+	}
+}
+
+
+static void mce_set_error_info(struct OpalMachineCheckEvent *mce,
+			       struct mce_error_info *mce_err)
+{
+	mce->error_type = mce_err->error_type;
+	switch (mce_err->error_type) {
+	case MCE_ERROR_TYPE_UE:
+		mce->u.ue_error.ue_error_type = mce_err->u.ue_error_type;
+		break;
+	case MCE_ERROR_TYPE_SLB:
+		mce->u.slb_error.slb_error_type = mce_err->u.slb_error_type;
+		break;
+	case MCE_ERROR_TYPE_ERAT:
+		mce->u.erat_error.erat_error_type = mce_err->u.erat_error_type;
+		break;
+	case MCE_ERROR_TYPE_TLB:
+		mce->u.tlb_error.tlb_error_type = mce_err->u.tlb_error_type;
+		break;
+	case MCE_ERROR_TYPE_NEST:
+		mce->u.nest_error.nest_error_type = mce_err->u.nest_error_type;
+		break;
+	case MCE_ERROR_TYPE_CRESP:
+		mce->u.cresp_error.cresp_error_type =
+						mce_err->u.cresp_error_type;
+		break;
+	case MCE_ERROR_TYPE_FSPACE:
+		mce->u.fspace_error.fspace_error_type =
+						mce_err->u.fspace_error_type;
+		break;
+	case MCE_ERROR_TYPE_ASYNC:
+		mce->u.async_error.async_error_type =
+						mce_err->u.async_error_type;
+		break;
+	case MCE_ERROR_TYPE_UNKNOWN:
+	default:
+		break;
+	}
+}
+
+static void save_mce_event(struct mce_error_info *mce_err,
+		    uint64_t addr, struct OpalMachineCheckEvent *mce)
+{
+	mce->severity = MCE_SEV_ERROR_SYNC;
+
+	/*
+	 * Populate the mce error_type and type-specific error_type.
+	 */
+	mce_set_error_info(mce, mce_err);
+
+	if (!addr)
+		return;
+
+	if (mce->error_type == MCE_ERROR_TYPE_TLB) {
+		mce->u.tlb_error.effective_address_provided = true;
+		mce->u.tlb_error.effective_address = addr;
+	} else if (mce->error_type == MCE_ERROR_TYPE_SLB) {
+		mce->u.slb_error.effective_address_provided = true;
+		mce->u.slb_error.effective_address = addr;
+	} else if (mce->error_type == MCE_ERROR_TYPE_ERAT) {
+		mce->u.erat_error.effective_address_provided = true;
+		mce->u.erat_error.effective_address = addr;
+	} else if (mce->error_type == MCE_ERROR_TYPE_UE) {
+		mce->u.ue_error.effective_address_provided = true;
+		mce->u.ue_error.effective_address = addr;
+	} else if (mce->error_type == MCE_ERROR_TYPE_NEST) {
+		mce->u.nest_error.effective_address_provided = true;
+		mce->u.nest_error.effective_address = addr;
+	} else if (mce->error_type == MCE_ERROR_TYPE_CRESP) {
+		mce->u.cresp_error.effective_address_provided = true;
+		mce->u.cresp_error.effective_address = addr;
+	} else if (mce->error_type == MCE_ERROR_TYPE_FSPACE) {
+		mce->u.fspace_error.effective_address_provided = true;
+		mce->u.fspace_error.effective_address = addr;
+	}
+	return;
+}
+
+static void __machine_check_p9(struct mce_reason_regs *regs,
+				struct OpalMachineCheckEvent *mce)
+{
+	uint64_t srr1, addr = 0;
+	struct mce_error_info mce_error_info = { 0 };
+
+	srr1 = regs->srr1;
+
+	if ((srr1 & P9_SRR1_ASYNC_MC_MASK) == P9_SRR1_ASYNC_MC) {
+		/* Asynch machine check. */
+		mce_get_async_err_p9(&mce_error_info, srr1);
+		mce->severity = MCE_SEV_WARNING;
+	} else if (P9_SRR1_MC_LOADSTORE(srr1)) {
+		mce_get_derror_p9(&mce_error_info, regs->dsisr);
+		addr = regs->dar;
+	} else {
+		mce_get_ierror_p9(&mce_error_info, srr1);
+		addr = regs->srr0;
+	}
+
+	save_mce_event(&mce_error_info, addr, mce);
+}
+
+static int64_t opal_handle_machine_check(uint64_t srr0, uint64_t srr1,
+				uint64_t dar, uint64_t dsisr,
+				struct OpalMachineCheckEvent *mce)
+{
+	struct mce_reason_regs mce_regs = { 0 };
+
+	if (!mce)
+		return OPAL_PARAMETER;
+
+	/*
+	 * TODO: Add check for P9 chip.
+	 * Handle only for P9 chip.
+	 * For non-p9 chip return OPAL_UNSUPPORTED so that linux
+	 * will fallback to in-kernel MCE handling for older chips.
+	 */
+
+	/* Populate generic machine check event info */
+	mce->version = MCE_V1;
+	mce->srr0 = srr0;
+	mce->srr1 = srr1;
+	mce->in_use = 1;
+
+	mce->initiator = MCE_INITIATOR_CPU;
+	mce->disposition = MCE_DISPOSITION_NOT_RECOVERED;
+	mce->severity = MCE_SEV_ERROR_SYNC;
+
+	mce_regs.srr0 = srr0;
+	mce_regs.srr1 = srr1;
+	mce_regs.dar = dar;
+	mce_regs.dsisr = dsisr;
+	/*
+	 * Populate the mce error_type and type-specific error_type.
+	 */
+	__machine_check_p9(&mce_regs, mce);
+
+	return OPAL_SUCCESS;
+}
+
+opal_call(OPAL_HANDLE_MACHINE_CHECK, opal_handle_machine_check, 5);
diff --git a/include/opal-api.h b/include/opal-api.h
index c891db9..00968f7 100644
--- a/include/opal-api.h
+++ b/include/opal-api.h
@@ -200,7 +200,8 @@
 #define OPAL_XIVE_RESERVED2			142
 #define OPAL_XIVE_RESERVED3			143
 #define OPAL_XIVE_RESERVED4			144
-#define OPAL_LAST				144
+#define OPAL_HANDLE_MACHINE_CHECK		145
+#define OPAL_LAST				145
 
 /* Device tree flags */
 
@@ -740,6 +741,182 @@ struct OpalHMIEvent {
 	} u;
 };
 
+/* Machine Check event */
+enum MCE_Version {
+	MCE_V1 = 1,
+};
+
+enum MCE_Severity {
+	MCE_SEV_NO_ERROR = 0,
+	MCE_SEV_WARNING = 1,
+	MCE_SEV_ERROR_SYNC = 2,
+	MCE_SEV_FATAL = 3,
+	MCE_SEV_ERROR_ASYNC = 4,
+};
+
+enum MCE_Disposition {
+	MCE_DISPOSITION_RECOVERED = 0,
+	MCE_DISPOSITION_NOT_RECOVERED = 1,
+};
+
+enum MCE_Initiator {
+	MCE_INITIATOR_UNKNOWN = 0,
+	MCE_INITIATOR_CPU = 1,
+};
+
+enum MCE_ErrorType {
+	MCE_ERROR_TYPE_UNKNOWN = 0,
+	MCE_ERROR_TYPE_UE = 1,
+	MCE_ERROR_TYPE_SLB = 2,
+	MCE_ERROR_TYPE_ERAT = 3,
+	MCE_ERROR_TYPE_TLB = 4,
+	MCE_ERROR_TYPE_NEST = 5,
+	MCE_ERROR_TYPE_CRESP = 6,
+	MCE_ERROR_TYPE_FSPACE = 7,
+	MCE_ERROR_TYPE_ASYNC = 8,
+};
+
+enum MCE_UeErrorType {
+	MCE_UE_ERROR_INDETERMINATE = 0,
+	MCE_UE_ERROR_IFETCH = 1,
+	MCE_UE_ERROR_PAGE_TABLE_WALK_IFETCH = 2,
+	MCE_UE_ERROR_LOAD_STORE = 3,
+	MCE_UE_ERROR_PAGE_TABLE_WALK_LOAD_STORE = 4,
+};
+
+enum MCE_SlbErrorType {
+	MCE_SLB_ERROR_INDETERMINATE = 0,
+	MCE_SLB_ERROR_PARITY = 1,
+	MCE_SLB_ERROR_MULTIHIT = 2,
+};
+
+enum MCE_EratErrorType {
+	MCE_ERAT_ERROR_INDETERMINATE = 0,
+	MCE_ERAT_ERROR_PARITY = 1,
+	MCE_ERAT_ERROR_MULTIHIT = 2,
+};
+
+enum MCE_TlbErrorType {
+	MCE_TLB_ERROR_INDETERMINATE = 0,
+	MCE_TLB_ERROR_PARITY = 1,
+	MCE_TLB_ERROR_MULTIHIT = 2,
+	MCE_TLB_ERROR_TLBIEL_PROG_ERROR = 3,
+};
+
+enum MCE_NestErrorType {
+	MCE_NEST_ERROR_ABRT_IFETCH = 0,
+	MCE_NEST_ERROR_ABRT_IFETCH_TABLEWALK = 1,
+	MCE_NEST_ERROR_ABRT_LOAD = 2,
+	MCE_NEST_ERROR_ABRT_LOAD_TABLEWALK = 3,
+};
+
+enum MCE_CrespErrorType {
+	MCE_CRESP_ERROR_BAD_RADDR_IFETCH = 0,
+	MCE_CRESP_ERROR_BAD_RADDR_IFETCH_TABLEWALK = 1,
+	MCE_CRESP_ERROR_BAD_RADDR_LOAD = 2,
+	MCE_CRESP_ERROR_BAD_RADDR_LOAD_TABLEWALK = 3,
+};
+
+enum MCE_FspaceErrorType {
+	MCE_FSPACE_ERROR_IFETCH = 0,
+	MCE_FSPACE_ERROR_IFETCH_TABLEWALK = 1,
+	MCE_FSPACE_ERROR_RADDR_TRANSLATION = 2,
+	MCE_FSPACE_ERROR_RADDR_LOAD = 3,
+};
+
+enum MCE_AsyncErrorType {
+	MCE_ASYNC_ERROR_REAL_ADDR_STORE = 0,
+	MCE_ASYNC_ERROR_NEST_ABRT_STORE = 1,
+};
+
+struct OpalMachineCheckEvent {
+	uint8_t			version;	/* 0x00 */
+	uint8_t			in_use;		/* 0x01 */
+	uint8_t			severity;	/* 0x02 */
+	uint8_t			initiator;	/* 0x03 */
+	uint8_t			error_type;	/* 0x04 */
+	uint8_t			disposition;	/* 0x05 */
+	uint8_t			reserved_1[2];	/* 0x06 */
+	uint64_t		gpr3;		/* 0x08 */
+	uint64_t		srr0;		/* 0x10 */
+	uint64_t		srr1;		/* 0x18 */
+
+	union {					/* 0x20 */
+		/* Next 32 bytes contains specific information of MCE error. */
+		struct {
+			/* enum MCE_UeErrorType */
+			uint8_t		ue_error_type;
+			uint8_t		effective_address_provided;
+			uint8_t		physical_address_provided;
+			uint8_t		reserved_1[5];
+			uint64_t	effective_address;
+			uint64_t	physical_address;
+			uint8_t		reserved_2[8];
+		} ue_error;
+
+		struct {
+			/* enum MCE_SlbErrorType */
+			uint8_t		slb_error_type;
+			uint8_t		effective_address_provided;
+			uint8_t		reserved_1[6];
+			uint64_t	effective_address;
+			uint8_t		reserved_2[16];
+		} slb_error;
+
+		struct {
+			/* enum MCE_EratErrorType */
+			uint8_t		erat_error_type;
+			uint8_t		effective_address_provided;
+			uint8_t		reserved_1[6];
+			uint64_t	effective_address;
+			uint8_t		reserved_2[16];
+		} erat_error;
+
+		struct {
+			/* enum MCE_TlbErrorType  */
+			uint8_t		tlb_error_type;
+			uint8_t		effective_address_provided;
+			uint8_t		reserved_1[6];
+			uint64_t	effective_address;
+			uint8_t		reserved_2[16];
+		} tlb_error;
+
+		struct {
+			/* enum MCE_NestErrorType */
+			uint8_t		nest_error_type;
+			uint8_t		effective_address_provided;
+			uint8_t		reserved_1[6];
+			uint64_t	effective_address;
+			uint8_t		reserved_2[16];
+		} nest_error;
+
+		struct {
+			/* enum MCE_CrespErrorType */
+			uint8_t		cresp_error_type;
+			uint8_t		effective_address_provided;
+			uint8_t		reserved_1[6];
+			uint64_t	effective_address;
+			uint8_t		reserved_2[16];
+		} cresp_error;
+
+		struct {
+			/* enum MCE_FspaceErrorType */
+			uint8_t		fspace_error_type;
+			uint8_t		effective_address_provided;
+			uint8_t		reserved_1[6];
+			uint64_t	effective_address;
+			uint8_t		reserved_2[16];
+		} fspace_error;
+
+		struct {
+			/* enum MCE_AsyncErrorType */
+			uint8_t		async_error_type;
+			uint8_t		reserved_1[7];
+			uint8_t		reserved_2[24];
+		} async_error;
+	} u;
+};
+
 enum {
 	OPAL_P7IOC_DIAG_TYPE_NONE	= 0,
 	OPAL_P7IOC_DIAG_TYPE_RGC	= 1,
