aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorNicholas Piggin <npiggin@gmail.com>2017-11-29 15:37:06 +1000
committerStewart Smith <stewart@linux.vnet.ibm.com>2017-12-03 22:10:56 -0600
commitd0e44ad2a9633c9d49504f4a0c69ac730cdc0561 (patch)
tree54f8a0a0484cb64cbd8239f411c5eca79a13c132 /core
parent6d033ce35dc1071949d3be79a62d8964465b4b4f (diff)
downloadskiboot-d0e44ad2a9633c9d49504f4a0c69ac730cdc0561.zip
skiboot-d0e44ad2a9633c9d49504f4a0c69ac730cdc0561.tar.gz
skiboot-d0e44ad2a9633c9d49504f4a0c69ac730cdc0561.tar.bz2
fast-reboot: bare bones fast reboot implementation for POWER9
This is an initial fast reboot implementation for p9 which has only been tested on the Witherspoon platform, and without the use of NPUs, NX/VAS, etc. This has worked reasonably well so far, with no failures in about 100 reboots. It is hidden behind the traditional fast-reboot experimental nvram option, until more platforms and configurations are tested. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'core')
-rw-r--r--core/fast-reboot.c64
-rw-r--r--core/init.c14
2 files changed, 50 insertions, 28 deletions
diff --git a/core/fast-reboot.c b/core/fast-reboot.c
index 2f1a500..1c76c08 100644
--- a/core/fast-reboot.c
+++ b/core/fast-reboot.c
@@ -24,10 +24,12 @@
#include <cec.h>
#include <timebase.h>
#include <pci.h>
+#include <xive.h>
#include <chip.h>
#include <chiptod.h>
#include <ipmi.h>
#include <direct-controls.h>
+#include <nvram.h>
/* Flag tested by the OPAL entry code */
static volatile bool fast_boot_release;
@@ -73,8 +75,13 @@ void fast_reboot(void)
struct cpu_thread *cpu;
static int fast_reboot_count = 0;
+ if (proc_gen == proc_gen_p9) {
+ if (!nvram_query_eq("experimental-fast-reset","feeling-lucky"))
+ return;
+ }
+
if (!chip_quirk(QUIRK_MAMBO_CALLOUTS) &&
- proc_gen != proc_gen_p8) {
+ (proc_gen != proc_gen_p8 && proc_gen != proc_gen_p9)) {
prlog(PR_DEBUG,
"RESET: Fast reboot not available on this CPU\n");
return;
@@ -168,20 +175,24 @@ static void cleanup_cpu_state(void)
/* XXX Update the SLW copies ! Also dbl check HIDs etc... */
init_shared_sprs();
- /* If somebody was in fast_sleep, we may have a workaround
- * to undo
- */
- if (cpu->in_fast_sleep) {
- prlog(PR_DEBUG, "RESET: CPU 0x%04x in fast sleep"
- " undoing workarounds...\n", cpu->pir);
- fast_sleep_exit();
+ if (proc_gen == proc_gen_p8) {
+ /* If somebody was in fast_sleep, we may have a
+ * workaround to undo
+ */
+ if (cpu->in_fast_sleep) {
+ prlog(PR_DEBUG, "RESET: CPU 0x%04x in fast sleep"
+ " undoing workarounds...\n", cpu->pir);
+ fast_sleep_exit();
+ }
+
+ /* The TLB surely contains garbage.
+ * P9 clears TLBs in cpu_fast_reboot_complete
+ */
+ cleanup_local_tlb();
}
/* And we might have lost TB sync */
chiptod_wakeup_resync();
-
- /* The TLB surely contains garbage */
- cleanup_local_tlb();
}
/* Per-thread additional cleanup */
@@ -248,15 +259,19 @@ void __noreturn fast_reboot_entry(void)
{
prlog(PR_DEBUG, "RESET: CPU 0x%04x reset in\n", this_cpu()->pir);
- /* We reset our ICP first ! Otherwise we might get stray interrupts
- * when unsplitting
- */
- reset_cpu_icp();
+ if (proc_gen == proc_gen_p9) {
+ reset_cpu_xive();
+ } else if (proc_gen == proc_gen_p8) {
+ /* We reset our ICP first ! Otherwise we might get stray
+ * interrupts when unsplitting
+ */
+ reset_cpu_icp();
- /* If we are split, we need to unsplit. Since that can send us
- * to NAP, which will come back via reset, we do it now
- */
- check_split_core();
+ /* If we are split, we need to unsplit. Since that can send us
+ * to NAP, which will come back via reset, we do it now
+ */
+ check_split_core();
+ }
sync();
this_cpu()->state = cpu_state_present;
@@ -285,6 +300,10 @@ void __noreturn fast_reboot_entry(void)
*/
cpu_state_wait_all_others(cpu_state_present, 0);
+ if (proc_gen == proc_gen_p9) {
+ xive_reset();
+ }
+
prlog(PR_INFO, "RESET: Releasing secondaries...\n");
/* Release everybody */
@@ -322,8 +341,11 @@ void __noreturn fast_reboot_entry(void)
/* Poke the consoles (see comments in the code there) */
fsp_console_reset();
- /* Reset/EOI the PSI interrupt */
- psi_irq_reset();
+ if (proc_gen == proc_gen_p8) {
+ /* XXX */
+ /* Reset/EOI the PSI interrupt */
+ psi_irq_reset();
+ }
/* Remove all PCI devices */
pci_reset();
diff --git a/core/init.c b/core/init.c
index 0fdd7f0..2eeba75 100644
--- a/core/init.c
+++ b/core/init.c
@@ -502,6 +502,13 @@ void __noreturn load_and_boot_kernel(bool is_reboot)
/* Wait for FW VPD data read to complete */
fsp_code_update_wait_vpd(true);
+ /*
+ * OCC takes few secs to boot. Call this as late as
+ * as possible to avoid delay.
+ */
+ occ_pstates_init();
+ occ_sensors_init();
+
} else {
/* fdt will be rebuilt */
free(fdt);
@@ -512,13 +519,6 @@ void __noreturn load_and_boot_kernel(bool is_reboot)
fsp_console_select_stdout();
- /*
- * OCC takes few secs to boot. Call this as late as
- * as possible to avoid delay.
- */
- occ_pstates_init();
- occ_sensors_init();
-
/* Use nvram bootargs over device tree */
cmdline = nvram_query("bootargs");
if (cmdline) {