aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm/head.S37
-rw-r--r--core/fast-reboot.c19
-rw-r--r--core/init.c13
-rw-r--r--include/skiboot.h3
4 files changed, 48 insertions, 24 deletions
diff --git a/asm/head.S b/asm/head.S
index 16ebf93..1659c1b 100644
--- a/asm/head.S
+++ b/asm/head.S
@@ -700,12 +700,7 @@ reset_wakeup:
GET_CPU()
/* Restore original stack pointer */
- ld %r3,CPUTHREAD_SAVE_R1(%r13)
-
- /* If it's 0, we are doing a fast reboot */
- cmpldi %r3,0
- beq fast_reset_entry
- mr %r1,%r3
+ ld %r1,CPUTHREAD_SAVE_R1(%r13)
/* Restore more stuff */
lwz %r3,STACK_CR(%r1)
@@ -742,13 +737,31 @@ reset_wakeup:
mtlr %r0
blr
-/* Fast reset code. We clean up the TLB and a few SPRs and
- * return to C code. All CPUs do that, the CPU triggering the
- * reset does it to itself last. The C code will sort out who
- * the master is. We come from the trampoline above with
- * r30 containing SKIBOOT_BASE
+.global reset_fast_reboot_patch_start
+reset_fast_reboot_patch_start:
+ FIXUP_ENDIAN /* HILE bit may or may not be set */
+ smt_medium
+ LOAD_IMM64(%r30, SKIBOOT_BASE)
+ LOAD_IMM32(%r3, reset_fast_reboot_wakeup - __head)
+ add %r3,%r30,%r3
+ mtctr %r3
+ bctr
+.global reset_fast_reboot_patch_end
+reset_fast_reboot_patch_end:
+
+/* Fast reset code. We reset the stack, clean up the TLB and a few SPRs and
+ * jump to C code. All CPUs do that, the CPU triggering the reset does it to
+ * itself last. The C code will sort out who the master is. We come from the
+ * trampoline above with r30 containing SKIBOOT_BASE
*/
-fast_reset_entry:
+reset_fast_reboot_wakeup:
+ /* Get PIR */
+ mfspr %r31,SPR_PIR
+
+ /* Get that CPU stack base and use it to restore r13 */
+ GET_STACK(%r1,%r31)
+ GET_CPU()
+
/* Clear out SLB */
li %r6,0
slbmte %r6,%r6
diff --git a/core/fast-reboot.c b/core/fast-reboot.c
index d3cc8cf..d841474 100644
--- a/core/fast-reboot.c
+++ b/core/fast-reboot.c
@@ -110,7 +110,6 @@ static bool fast_reboot_sanity_check(void)
void fast_reboot(void)
{
- struct cpu_thread *cpu;
static int fast_reboot_count = 0;
if (!chip_quirk(QUIRK_MAMBO_CALLOUTS) &&
@@ -157,19 +156,15 @@ void fast_reboot(void)
return;
}
+ cpu_set_sreset_enable(false);
+ cpu_set_ipi_enable(false);
+
/*
* There is no point clearing special wakeup or un-quiesce due to
* failure after this point, because we will be going to full IPL.
* Less cleanup work means less opportunity to fail.
*/
- for_each_ungarded_cpu(cpu) {
- /* Also make sure that saved_r1 is 0 ! That's what will
- * make our reset vector jump to fast_reboot_entry
- */
- cpu->save_r1 = 0;
- }
-
/*
* Move SPRs and exception vectors back to OPAL-mode while all
* others are quiesced. MSR[ME] is disabled while these are switched,
@@ -206,7 +201,7 @@ void fast_reboot(void)
* sreset vector has a FIXUP_ENDIAN sequence at the start, so
* secondaries can cope.
*/
- copy_sreset_vector();
+ copy_sreset_vector_fast_reboot();
/* Send everyone else to 0x100 */
if (sreset_all_others() != OPAL_SUCCESS) {
@@ -374,9 +369,8 @@ void __noreturn fast_reboot_entry(void)
*/
cpu_state_wait_all_others(cpu_state_present, 0);
- if (proc_gen == proc_gen_p9) {
+ if (proc_gen == proc_gen_p9)
xive_reset();
- }
prlog(PR_INFO, "RESET: Releasing secondaries...\n");
@@ -405,6 +399,9 @@ void __noreturn fast_reboot_entry(void)
/* Let the CPU layer do some last minute global cleanups */
cpu_fast_reboot_complete();
+ /* Restore OPAL's sreset vector now that all CPUs have HILE clear */
+ copy_sreset_vector();
+
/* We can now do NAP mode */
cpu_set_sreset_enable(true);
cpu_set_ipi_enable(true);
diff --git a/core/init.c b/core/init.c
index 3f7dd14..e095507 100644
--- a/core/init.c
+++ b/core/init.c
@@ -793,7 +793,18 @@ void copy_sreset_vector(void)
while(src < &reset_patch_end)
*(dst++) = *(src++);
sync_icache();
- cpu_set_sreset_enable(true);
+}
+
+void copy_sreset_vector_fast_reboot(void)
+{
+ uint32_t *src, *dst;
+
+ /* Copy the reset code over the entry point. */
+ src = &reset_fast_reboot_patch_start;
+ dst = (uint32_t *)0x100;
+ while(src < &reset_fast_reboot_patch_end)
+ *(dst++) = *(src++);
+ sync_icache();
}
void copy_exception_vectors(void)
diff --git a/include/skiboot.h b/include/skiboot.h
index fedd7b3..96caa27 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -200,6 +200,7 @@ extern void init_replicated_sprs(void);
extern bool start_preload_kernel(void);
extern void copy_exception_vectors(void);
extern void copy_sreset_vector(void);
+extern void copy_sreset_vector_fast_reboot(void);
/* Various probe routines, to replace with an initcall system */
extern void probe_p7ioc(void);
@@ -292,6 +293,8 @@ extern void enter_p9_pm_state(uint64_t psscr);
extern void enter_p9_pm_lite_state(uint64_t psscr);
extern uint32_t reset_patch_start;
extern uint32_t reset_patch_end;
+extern uint32_t reset_fast_reboot_patch_start;
+extern uint32_t reset_fast_reboot_patch_end;
/* Fallback fake NVRAM */
extern int fake_nvram_info(uint32_t *total_size);