[Skiboot] [PATCH 2/3] core/init: manage MSR[ME] explicitly, always enable

Nicholas Piggin npiggin at gmail.com
Fri Feb 2 16:34:09 AEDT 2018


The current boot sequence inherits MSR[ME] from the IPL firmware, and
never changes it. Some environments disable MSR[ME] (e.g., mambo), and
others can enable it (hostboot).

This has two problems. First, MSR[ME] must be disabled while in the
process of taking over the interrupt vector from the previous
environment.  Second, after installing our machine check handler,
MSR[ME] should be enabled to get some useful output rather than a
checkstop.

Signed-off-by: Nicholas Piggin <npiggin at gmail.com>
---
 asm/head.S        | 29 +++++++++++++++++++++++++++++
 core/init.c       | 15 +++++++++++++++
 include/skiboot.h |  2 ++
 3 files changed, 46 insertions(+)

diff --git a/asm/head.S b/asm/head.S
index 264899b12..e2ddc9151 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -479,6 +479,35 @@ call_relocate:
        .long 0xa6037b7d; /* mtsrr1 r11                         */ \
        .long 0x2400004c  /* rfid                               */
 
+.global enable_machine_check
+enable_machine_check:
+	mflr	%r0
+	bcl	20,31,$+4
+0:	mflr	%r3
+	addi	%r3,%r3,(1f - 0b)
+	mtspr	SPR_HSRR0,%r3
+	mfmsr	%r3
+	ori	%r3,%r3,MSR_ME
+	mtspr	SPR_HSRR1,%r3
+	hrfid
+1:	mtlr	%r0
+	blr
+
+.global disable_machine_check
+disable_machine_check:
+	mflr	%r0
+	bcl	20,31,$+4
+0:	mflr	%r3
+	addi	%r3,%r3,(1f - 0b)
+	mtspr	SPR_HSRR0,%r3
+	mfmsr	%r3
+	li	%r4,MSR_ME
+	andc	%r3,%r3,%r4
+	mtspr	SPR_HSRR1,%r3
+	hrfid
+1:	mtlr	%r0
+	blr
+
 pm_save_regs:
 	SAVE_GPR(2,%r1)
 	SAVE_GPR(14,%r1)
diff --git a/core/init.c b/core/init.c
index ec9f32981..13ed746ce 100644
--- a/core/init.c
+++ b/core/init.c
@@ -808,9 +808,24 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt)
 	 */
 	clear_console();
 
+	/*
+	 * Some boot firmwares enter OPAL with MSR[ME]=1, as they presumably
+	 * handle machine checks until we take over. As we overwrite the
+	 * previous exception vectors with our own handlers, disable MSR[ME].
+	 * This could be done atomically by patching in a branch then patching
+	 * it out last, but that's a lot of effort.
+	 */
+	disable_machine_check();
+
 	/* Copy all vectors down to 0 */
 	copy_exception_vectors();
 
+	/*
+	 * Enable MSR[ME] bit so we can take MCEs. We don't currently
+	 * recover, but we print some useful information.
+	 */
+	enable_machine_check();
+
 	/* Setup a NULL catcher to catch accidental NULL ptr calls */
 	setup_branch_null_catcher();
 
diff --git a/include/skiboot.h b/include/skiboot.h
index fd751dced..d1de10a44 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -332,6 +332,8 @@ extern void fast_sleep_exit(void);
 extern void fake_rtc_init(void);
 
 /* Assembly in head.S */
+extern void disable_machine_check(void);
+extern void enable_machine_check(void);
 extern void enter_p8_pm_state(bool winkle);
 extern void enter_p9_pm_state(uint64_t psscr);
 extern void enter_p9_pm_lite_state(uint64_t psscr);
-- 
2.15.1



More information about the Skiboot mailing list