// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/*
 * Full IPL is slow, let's cheat!
 *
 * Copyright 2013-2019 IBM Corp.
 */

#include <skiboot.h>
#include <slw.h>
#include <cpu.h>
#include <console.h>
#include <fsp.h>
#include <psi.h>
#include <opal.h>
#include <mem_region.h>
#include <xscom.h>
#include <interrupts.h>
#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;
static volatile bool spr_set_release;
static volatile bool nmi_mce_release;

static void wait_on(volatile bool *cond)
{
	sync();
	if (!*cond) {
		smt_lowest();
		while (!*cond)
			barrier();
		smt_medium();
	}
	sync();
}

static bool cpu_state_wait_all_others(enum cpu_thread_state state,
					unsigned long timeout_tb)
{
	struct cpu_thread *cpu;
	unsigned long end = mftb() + timeout_tb;

	sync();
	for_each_ungarded_cpu(cpu) {
		if (cpu == this_cpu())
			continue;

		if (cpu->state != state) {
			smt_lowest();
			while (cpu->state != state) {
				barrier();

				if (timeout_tb && (tb_compare(mftb(), end) == TB_AAFTERB)) {
					smt_medium();
					return false;
				}
			}
			smt_medium();
		}
	}
	sync();

	return true;
}

static const char *fast_reboot_disabled = NULL;

void disable_fast_reboot(const char *reason)
{
	if (fast_reboot_disabled)
		return;

	prlog(PR_NOTICE, "RESET: Fast reboot disabled: %s\n", reason);
	fast_reboot_disabled = reason;
}

void add_fast_reboot_dt_entries(void)
{
	dt_check_del_prop(opal_node, "fast-reboot");

	if (fast_reboot_disabled) {
		dt_add_property_string(opal_node, "fast-reboot", fast_reboot_disabled);
	} else {
		dt_add_property_string(opal_node, "fast-reboot", "okay");
	}
}

/*
 * This is called by the reboot CPU after all other CPUs have been
 * quiesced and stopped, to perform various sanity checks on firmware
 * data (and potentially hardware), to determine whether the fast
 * reboot should go ahead.
 */
static bool fast_reboot_sanity_check(void)
{
	if (!mem_check_all()) {
		disable_fast_reboot("Inconsistent firmware data");
		return false;
	}

	if (!verify_romem()) {
		disable_fast_reboot("Inconsistent firmware romem checksum");
		return false;
	}

	return true;
}

void fast_reboot(void)
{
	static int fast_reboot_count = 0;

	if (chip_quirk(QUIRK_NO_DIRECT_CTL)) {
		prlog(PR_DEBUG,
		      "RESET: Fast reboot disabled by quirk\n");
		return;
	}

	/*
	 * Ensure all other CPUs have left OPAL calls.
	 */
	if (!opal_quiesce(QUIESCE_HOLD, -1)) {
		disable_fast_reboot("OPAL quiesce timeout");
		return;
	}

	if (fast_reboot_disabled &&
	    nvram_query_eq_dangerous("force-fast-reset", "1")) {
		/* Do fast reboot even if it's been disabled */
		prlog(PR_NOTICE, "RESET: Ignoring fast reboot disabled: %s\n",
				fast_reboot_disabled);
	} else if (fast_reboot_disabled) {
		prlog(PR_NOTICE, "RESET: Fast reboot disabled: %s\n",
		      fast_reboot_disabled);
		opal_quiesce(QUIESCE_RESUME, -1);
		return;
	}

	prlog(PR_NOTICE, "RESET: Initiating fast reboot %d...\n", ++fast_reboot_count);
	fast_boot_release = false;
	spr_set_release = false;
	nmi_mce_release = false;
	sync();

	/* Put everybody in stop except myself */
	if (sreset_all_prepare()) {
		prlog(PR_NOTICE, "RESET: Fast reboot failed to prepare "
				"secondaries for system reset\n");
		opal_quiesce(QUIESCE_RESUME, -1);
		return;
	}

	if (!fast_reboot_sanity_check()) {
		opal_quiesce(QUIESCE_RESUME, -1);
		return;
	}

	cpu_set_sreset_enable(false);
	cpu_set_ipi_enable(false);

	/*
	 * The fast reboot sreset vector has FIXUP_ENDIAN, so secondaries can
	 * cope with a wrong HILE setting.
	 */
	copy_sreset_vector_fast_reboot();

	/*
	 * 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.
	 */

	/* Send everyone else to 0x100 */
	if (sreset_all_others() != OPAL_SUCCESS) {
		prlog(PR_NOTICE, "RESET: Fast reboot failed to system reset "
				"secondaries\n");
		return;
	}

	/* Ensure all the sresets get through */
	if (!cpu_state_wait_all_others(cpu_state_fast_reboot_entry, msecs_to_tb(1000))) {
		prlog(PR_NOTICE, "RESET: Fast reboot timed out waiting for "
				"secondaries to call in\n");
		return;
	}

	prlog(PR_DEBUG, "RESET: Releasing special wakeups...\n");
	sreset_all_finish();

	/* This resets our quiesce state ready to enter the new kernel. */
	opal_quiesce(QUIESCE_RESUME_FAST_REBOOT, -1);

	console_complete_flush();

	mtmsrd(0, 1); /* Clear MSR[RI] for 0x100 reset */
	asm volatile("ba	0x100\n\t" : : : "memory");
	for (;;)
		;
}

void __noreturn enter_nap(void);

static void check_split_core(void)
{
	struct cpu_thread *cpu;
	u64 mask, hid0;

        hid0 = mfspr(SPR_HID0);
	mask = SPR_HID0_POWER8_4LPARMODE | SPR_HID0_POWER8_2LPARMODE;

	if ((hid0 & mask) == 0)
		return;

	prlog(PR_INFO, "RESET: CPU 0x%04x is split !\n", this_cpu()->pir);

	/* If it's a secondary thread, just send it to nap */
	if (this_cpu()->pir & 7) {
		/* Prepare to be woken up */
		icp_prep_for_pm();
		/* Setup LPCR to wakeup on external interrupts only */
		mtspr(SPR_LPCR, ((mfspr(SPR_LPCR) & ~SPR_LPCR_P8_PECE) |
				 SPR_LPCR_P8_PECE2));
		isync();
		/* Go to nap (doesn't return) */
		enter_nap();
	}

	prlog(PR_INFO, "RESET: Primary, unsplitting... \n");

	/* Trigger unsplit operation and update SLW image */
	hid0 &= ~SPR_HID0_POWER8_DYNLPARDIS;
	set_hid0(hid0);
	opal_slw_set_reg(this_cpu()->pir, SPR_HID0, hid0);

	/* Wait for unsplit */
	while (mfspr(SPR_HID0) & mask)
		cpu_relax();

	/* Now the guys are sleeping, wake'em up. They will come back
	 * via reset and continue the fast reboot process normally.
	 * No need to wait.
	 */
	prlog(PR_INFO, "RESET: Waking unsplit secondaries... \n");

	for_each_cpu(cpu) {
		if (!cpu_is_sibling(cpu, this_cpu()) || (cpu == this_cpu()))
			continue;
		icp_kick_cpu(cpu);
	}
}

static void cleanup_cpu_state(void)
{
	struct cpu_thread *cpu = this_cpu();

	if (proc_gen == proc_gen_p9)
		xive_cpu_reset();
	else if (proc_gen == proc_gen_p10)
		xive2_cpu_reset();

	/* Per core cleanup */
	if (cpu_is_thread0(cpu) || cpu_is_core_chiplet_primary(cpu)) {
		/* Shared SPRs whacked back to normal */

		/* XXX Update the SLW copies ! Also dbl check HIDs etc... */
		init_shared_sprs();

#ifdef CONFIG_P8
		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();
		}
#endif

		/* And we might have lost TB sync */
		chiptod_wakeup_resync();
	}

	/* Per-thread additional cleanup */
	init_replicated_sprs();

	// XXX Cleanup SLW, check HIDs ...
}

/* Entry from asm after a fast reset */
void __noreturn fast_reboot_entry(void);

void __noreturn fast_reboot_entry(void)
{
	struct cpu_thread *cpu = this_cpu();
	void *skiboot_constant_addr kerneal_load_base_addr = KERNEL_LOAD_BASE;
	void *skiboot_constant_addr initramfs_load_base_addr = INITRAMFS_LOAD_BASE;

	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();
	}

	/* Until SPRs (notably HID[HILE]) are set and new exception vectors
	 * installed, nobody should take machine checks. Try to do minimal
	 * work between these points.
	 */
	disable_machine_check();
	mtmsrd(0, 1); /* Clear RI */

	sync();
	cpu->state = cpu_state_fast_reboot_entry;
	sync();
	if (cpu == boot_cpu) {
		cpu_state_wait_all_others(cpu_state_fast_reboot_entry, 0);
		spr_set_release = true;
	} else {
		wait_on(&spr_set_release);
	}


	/* Reset SPRs */
	if (cpu_is_thread0(cpu))
		init_shared_sprs();
	init_replicated_sprs();

	if (cpu == boot_cpu) {
		/* Restore skiboot vectors */
		copy_exception_vectors();
		copy_sreset_vector();
		patch_traps(true);
	}

	/* Must wait for others to because shared SPRs like HID0 are only set
	 * by thread0, so can't enable machine checks until those have been
	 * set.
	 */
	sync();
	cpu->state = cpu_state_present;
	sync();
	if (cpu == boot_cpu) {
		cpu_state_wait_all_others(cpu_state_present, 0);
		nmi_mce_release = true;
	} else {
		wait_on(&nmi_mce_release);
	}

	/* At this point skiboot exception vectors are in place and all
	 * cores/threads have SPRs set for running skiboot.
	 */
	enable_machine_check();
	mtmsrd(MSR_RI, 1);

	cleanup_cpu_state();

	prlog(PR_DEBUG, "RESET: CPU 0x%04x reset in\n", cpu->pir);

	/* The original boot CPU (not the fast reboot initiator) takes
	 * command. Secondaries wait for the signal then go to their secondary
	 * entry point.
	 */
	if (cpu != boot_cpu) {
		wait_on(&fast_boot_release);

		__secondary_cpu_entry();
	}

	if (proc_gen == proc_gen_p9)
		xive_reset();
	else if (proc_gen == proc_gen_p10)
		xive2_reset();

	/* Let the CPU layer do some last minute global cleanups */
	cpu_fast_reboot_complete();

	/* We can now do NAP mode */
	cpu_set_sreset_enable(true);
	cpu_set_ipi_enable(true);

	prlog(PR_INFO, "RESET: Releasing secondaries...\n");

	/* Release everybody */
	sync();
	fast_boot_release = true;
	sync();
	cpu->state = cpu_state_active;
	sync();

	/* Wait for them to respond */
	cpu_state_wait_all_others(cpu_state_active, 0);

	sync();

	prlog(PR_INFO, "RESET: All done, cleaning up...\n");

	/* Clear release flag for next time */
	fast_boot_release = false;

	if (!chip_quirk(QUIRK_MAMBO_CALLOUTS)) {
		/*
		 * mem_region_clear_unused avoids these preload regions
		 * so it can run along side image preloading. Clear these
		 * regions now to catch anything not overwritten by
		 * preload.
		 *
		 * Mambo may have embedded payload here, so don't clear
		 * it at all.
		 */
		memset(kerneal_load_base_addr, 0, KERNEL_LOAD_SIZE);
		memset(initramfs_load_base_addr, 0, INITRAMFS_LOAD_SIZE);
	}

	/* Start preloading kernel and ramdisk */
	start_preload_kernel();

	/* Start clearing memory */
	start_mem_region_clear_unused();

	if (platform.fast_reboot_init)
		platform.fast_reboot_init();

	if (proc_gen == proc_gen_p8) {
		/* XXX */
		/* Reset/EOI the PSI interrupt */
		psi_irq_reset();
	}

	/* update pci nvram settings */
	pci_nvram_init();

	/* Remove all PCI devices */
	if (pci_reset()) {
		prlog(PR_NOTICE, "RESET: Fast reboot failed to reset PCI\n");

		/*
		 * Can't return to caller here because we're past no-return.
		 * Attempt an IPL here which is what the caller would do.
		 */
		if (platform.cec_reboot)
			platform.cec_reboot();
		for (;;)
			;
	}

	ipmi_set_fw_progress_sensor(IPMI_FW_PCI_INIT);

	wait_mem_region_clear_unused();

	/* Load and boot payload */
	load_and_boot_kernel(true);
}
