aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/cpu.c11
-rw-r--r--core/exceptions.c17
2 files changed, 24 insertions, 4 deletions
diff --git a/core/cpu.c b/core/cpu.c
index 85a1478..d9d4713 100644
--- a/core/cpu.c
+++ b/core/cpu.c
@@ -426,8 +426,7 @@ static unsigned int cpu_idle_p8(enum cpu_wake_cause wake_on)
isync();
/* Enter nap */
- enter_p8_pm_state(false);
- vec = 0x100;
+ vec = enter_p8_pm_state(false);
skip_sleep:
/* Restore */
@@ -486,8 +485,7 @@ static unsigned int cpu_idle_p9(enum cpu_wake_cause wake_on)
/* PSSCR SD=0 ESL=1 EC=1 PSSL=0 TR=3 MTL=0 RL=1 */
psscr = PPC_BIT(42) | PPC_BIT(43) |
PPC_BITMASK(54, 55) | PPC_BIT(63);
- enter_p9_pm_state(psscr);
- vec = 0x100;
+ vec = enter_p9_pm_state(psscr);
} else {
/* stop with EC=0 (resumes) which does not require sreset. */
/* PSSCR SD=0 ESL=0 EC=0 PSSL=0 TR=3 MTL=0 RL=1 */
@@ -535,6 +533,11 @@ static void cpu_idle_pm(enum cpu_wake_cause wake_on)
break;
}
mtmsrd(MSR_RI, 1);
+
+ } else if (vec == 0x200) {
+ exception_entry_pm_mce();
+ enable_machine_check();
+ mtmsrd(MSR_RI, 1);
}
}
diff --git a/core/exceptions.c b/core/exceptions.c
index 779cd62..e15848a 100644
--- a/core/exceptions.c
+++ b/core/exceptions.c
@@ -127,6 +127,23 @@ void exception_entry_pm_sreset(void)
backtrace();
}
+void __noreturn exception_entry_pm_mce(void)
+{
+ const size_t max = 320;
+ char buf[max];
+ size_t l;
+
+ prerror("***********************************************\n");
+ l = 0;
+ l += snprintf(buf + l, max - l,
+ "Fatal MCE in sleep");
+ prerror("%s\n", buf);
+ prerror("SRR0 : "REG" SRR1 : "REG"\n",
+ (uint64_t)mfspr(SPR_SRR0), (uint64_t)mfspr(SPR_SRR1));
+ prerror("DSISR: "REG32" DAR : "REG"\n",
+ (uint32_t)mfspr(SPR_DSISR), (uint64_t)mfspr(SPR_DAR));
+ abort();
+}
static int64_t opal_register_exc_handler(uint64_t opal_exception __unused,
uint64_t handler_address __unused,