@@ -270,7 +270,7 @@ static int p8_sreset_thread(struct cpu_thread *cpu)
/* Waking may take up to 5ms for deepest sleep states. Set timeout to 100ms */
#define P9_SPWKUP_POLL_INTERVAL 100
-#define P9_SPWKUP_TIMEOUT 100000
+#define P9_SPWKUP_TIMEOUT 1000000
/*
* This implements direct control facilities of processor cores and threads
@@ -304,7 +304,7 @@ static int p9_core_set_special_wakeup(struct cpu_thread *cpu)
goto out_fail;
}
if (val & P9_SPECIAL_WKUP_DONE)
- return 0;
+ return OPAL_SUCCESS;
time_wait_us(P9_SPWKUP_POLL_INTERVAL);
}
@@ -312,6 +312,7 @@ static int p9_core_set_special_wakeup(struct cpu_thread *cpu)
prlog(PR_ERR, "Could not set special wakeup on %u:%u:"
" timeout waiting for SPECIAL_WKUP_DONE.\n",
chip_id, core_id);
+ return OPAL_SUCCESS;
out_fail:
/* De-assert special wakeup after a small delay. */
@@ -355,7 +356,7 @@ static int p9_core_clear_special_wakeup(struct cpu_thread *cpu)
return OPAL_HARDWARE;
}
if (!(val & P9_SPECIAL_WKUP_DONE))
- return 0;
+ return OPAL_SUCCESS;
time_wait_us(P9_SPWKUP_POLL_INTERVAL);
}
@@ -24,6 +24,7 @@
#include <cec.h>
#include <timebase.h>
#include <pci.h>
+#include <xive.h>
#include <chip.h>
#include <chiptod.h>
#include <ipmi.h>
@@ -61,9 +62,6 @@ static bool cpu_state_wait_all_others(enum cpu_thread_state state,
return true;
}
-extern void *fdt;
-extern struct lock capi_lock;
-
static const char *fast_reboot_disabled = NULL;
void disable_fast_reboot(const char *reason)
@@ -77,7 +75,7 @@ void fast_reboot(void)
static int fast_reboot_count = 0;
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;
@@ -104,10 +102,9 @@ void fast_reboot(void)
return;
}
- prlog(PR_NOTICE, "RESET: Initiating fast reboot %d...\n", ++fast_reboot_count);
-
- free(fdt);
+ /* Should mem_check() all regions before allowing fast reboot */
+ prlog(PR_NOTICE, "RESET: Initiating fast reboot %d...\n", ++fast_reboot_count);
fast_boot_release = false;
sync();
@@ -172,13 +169,15 @@ 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();
+ }
}
/* And we might have lost TB sync */
@@ -252,15 +251,17 @@ 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_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;
@@ -295,6 +296,14 @@ void __noreturn fast_reboot_entry(void)
sync();
fast_boot_release = true;
+ /* Cleanup ourselves */
+ cleanup_cpu_state();
+
+ /* Set our state to active */
+ sync();
+ this_cpu()->state = cpu_state_active;
+ sync();
+
/* Wait for them to respond */
cpu_state_wait_all_others(cpu_state_active, 0);
@@ -305,14 +314,6 @@ void __noreturn fast_reboot_entry(void)
/* Clear release flag for next time */
fast_boot_release = false;
- /* Cleanup ourselves */
- cleanup_cpu_state();
-
- /* Set our state to active */
- sync();
- this_cpu()->state = cpu_state_active;
- sync();
-
/* Let the CPU layer do some last minute global cleanups */
cpu_fast_reboot_complete();
@@ -326,8 +327,15 @@ 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();
+ }
+
+ if (proc_gen == proc_gen_p9) {
+ xive_reset();
+ }
/* Remove all PCI devices */
pci_reset();
@@ -501,18 +501,23 @@ void __noreturn load_and_boot_kernel(bool is_reboot)
/* Wait for FW VPD data read to complete */
fsp_code_update_wait_vpd(true);
- } else
+
+ /*
+ * 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);
+ fdt = NULL;
+
nvram_reinit();
+ }
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) {
@@ -4431,15 +4431,10 @@ static void xive_reset_mask_source_cb(struct irq_source *is,
}
}
-static int64_t opal_xive_reset(uint64_t version)
+static int64_t __xive_reset(uint64_t version)
{
struct proc_chip *chip;
- prlog(PR_DEBUG, "XIVE reset, version: %d...\n", (int)version);
-
- if (version > 1)
- return OPAL_PARAMETER;
-
xive_mode = version;
/* Mask all interrupt sources */
@@ -4474,6 +4469,22 @@ static int64_t opal_xive_reset(uint64_t version)
return OPAL_SUCCESS;
}
+/* Called by fast reboot */
+int64_t xive_reset(void)
+{
+ return __xive_reset(XIVE_MODE_EMU);
+}
+
+static int64_t opal_xive_reset(uint64_t version)
+{
+ prlog(PR_DEBUG, "XIVE reset, version: %d...\n", (int)version);
+
+ if (version > 1)
+ return OPAL_PARAMETER;
+
+ return __xive_reset(version);
+}
+
static int64_t opal_xive_free_vp_block(uint64_t vp_base)
{
uint32_t blk, idx, i, count;
@@ -469,6 +469,7 @@ struct xive_vp {
#define XIVE_IRQ_ERROR 0xffffffff
void init_xive(void);
+int64_t xive_reset(void);
/* Allocate a chunk of HW sources */
uint32_t xive_alloc_hw_irqs(uint32_t chip_id, uint32_t count, uint32_t align);