diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/cpu.c | 11 | ||||
-rw-r--r-- | core/exceptions.c | 17 |
2 files changed, 24 insertions, 4 deletions
@@ -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, |