Skip to content

Commit

Permalink
core/fast-reboot: fast reboot specific sreset patch
Browse files Browse the repository at this point in the history
Provide an sreset handler specifically for fast reboots, which allows
FIXUP_ENDIAN to be removed from the normal sreset handler in the next
patch.

The save_1 == 0 condition is no longer required to signal a fast
reboot.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Stewart Smith <stewart@linux.ibm.com>
  • Loading branch information
npiggin authored and stewartsmith committed Feb 13, 2019
1 parent 75669cb commit 37baa97
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 24 deletions.
37 changes: 25 additions & 12 deletions asm/head.S
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
19 changes: 8 additions & 11 deletions core/fast-reboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) &&
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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");

Expand Down Expand Up @@ -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);
Expand Down
13 changes: 12 additions & 1 deletion core/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions include/skiboot.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 37baa97

Please sign in to comment.