/* SPDX-License-Identifier: GPL-2.0-or-later */

#include <arch/cpu.h>
#include <assert.h>
#include <cbmem.h>
#include <cf9_reset.h>
#include <console/console.h>
#include <cpu/x86/msr.h>
#include <device/pci_ops.h>
#include <mrc_cache.h>
#include <northbridge/intel/haswell/haswell.h>
#include <northbridge/intel/haswell/raminit.h>
#include <southbridge/intel/lynxpoint/me.h>
#include <southbridge/intel/lynxpoint/pch.h>
#include <types.h>

#include "raminit_native.h"

static void wait_txt_clear(void)
{
	const struct cpuid_result cpuid = cpuid_ext(1, 0);

	/* Check if TXT is supported */
	if (!(cpuid.ecx & BIT(6)))
		return;

	/* Some TXT public bit */
	if (!(read32p(0xfed30010) & 1))
		return;

	/* Wait for TXT clear */
	do {} while (!(read8p(0xfed40000) & (1 << 7)));
}

static enum raminit_boot_mode get_boot_mode(void)
{
	const uint16_t pmcon_2 = pci_read_config16(PCH_LPC_DEV, GEN_PMCON_2);
	const uint16_t bitmask = GEN_PMCON_2_DISB | GEN_PMCON_2_MEM_SR;
	return (pmcon_2 & bitmask) == bitmask ? BOOTMODE_WARM : BOOTMODE_COLD;
}

static bool early_init_native(enum raminit_boot_mode bootmode)
{
	printk(BIOS_DEBUG, "Starting native platform initialisation\n");

	intel_early_me_init();
	bool cpu_replaced = bootmode == BOOTMODE_COLD && intel_early_me_cpu_replacement_check();

	early_pch_init_native(bootmode == BOOTMODE_S3);

	if (!CONFIG(INTEL_LYNXPOINT_LP))
		dmi_early_init();

	return cpu_replaced;
}

#define MRC_CACHE_VERSION 1

struct mrc_data {
	const void *buffer;
	size_t buffer_len;
};

static void save_mrc_data(struct mrc_data *md)
{
	mrc_cache_stash_data(MRC_TRAINING_DATA, MRC_CACHE_VERSION, md->buffer, md->buffer_len);
}

static struct mrc_data prepare_mrc_cache(void)
{
	struct mrc_data md = {0};
	md.buffer = mrc_cache_current_mmap_leak(MRC_TRAINING_DATA,
						MRC_CACHE_VERSION,
						&md.buffer_len);
	return md;
}

static const char *const bm_names[] = {
	"BOOTMODE_COLD",
	"BOOTMODE_WARM",
	"BOOTMODE_S3",
	"BOOTMODE_FAST",
};

static void clear_disb(void)
{
	pci_and_config16(PCH_LPC_DEV, GEN_PMCON_2, ~GEN_PMCON_2_DISB);
}

static void raminit_reset(void)
{
	clear_disb();
	system_reset();
}

static enum raminit_boot_mode do_actual_raminit(
	struct mrc_data *md,
	const bool s3resume,
	const bool cpu_replaced,
	const enum raminit_boot_mode orig_bootmode)
{
	enum raminit_boot_mode bootmode = orig_bootmode;

	bool save_data_valid = md->buffer && md->buffer_len == USHRT_MAX; /** TODO: sizeof() **/

	if (s3resume) {
		if (bootmode == BOOTMODE_COLD) {
			printk(BIOS_EMERG, "Memory may not be in self-refresh for S3 resume\n");
			printk(BIOS_EMERG, "S3 resume and cold boot are mutually exclusive\n");
			raminit_reset();
		}
		/* Only a true mad hatter would replace a CPU in S3 */
		if (cpu_replaced) {
			printk(BIOS_EMERG, "Oh no, CPU was replaced during S3\n");
			/*
			 * No reason to continue, memory consistency is most likely lost
			 * and ME will probably request a reset through DID response too.
			 */
			/** TODO: Figure out why past self commented this out **/
			//raminit_reset();
		}
		bootmode = BOOTMODE_S3;
		if (!save_data_valid) {
			printk(BIOS_EMERG, "No training data, S3 resume is impossible\n");
			/* Failed S3 resume, reset to come up cleanly */
			raminit_reset();
		}
	}
	if (!s3resume && cpu_replaced) {
		printk(BIOS_NOTICE, "CPU was replaced, forcing a cold boot\n");
		/*
		 * Looks like the ME will get angry if raminit takes too long.
		 * It will report that the CPU has been replaced on next boot.
		 * Try to continue anyway. This should not happen in most cases.
		 */
		/** TODO: Figure out why past self commented this out **/
		//save_data_valid = false;
	}
	if (bootmode == BOOTMODE_COLD) {
		/* If possible, promote to a fast boot */
		if (save_data_valid)
			bootmode = BOOTMODE_FAST;

		clear_disb();
	} else if (bootmode == BOOTMODE_WARM) {
		/* If a warm reset happened before raminit is done, force a cold boot */
		if (mchbar_read32(SSKPD) == 0 && mchbar_read32(SSKPD + 4) == 0) {
			printk(BIOS_NOTICE, "Warm reset occurred early in cold boot\n");
			save_data_valid = false;
		}
		if (!save_data_valid)
			bootmode = BOOTMODE_COLD;
	}
	assert(save_data_valid != (bootmode == BOOTMODE_COLD));
	if (save_data_valid) {
		printk(BIOS_INFO, "Using cached memory parameters\n");
		die("RAMINIT: Fast boot is not yet implemented\n");
	}
	printk(RAM_DEBUG, "Initial bootmode: %s\n", bm_names[orig_bootmode]);
	printk(RAM_DEBUG, "Current bootmode: %s\n", bm_names[bootmode]);

	/*
	 * And now, the actual memory initialization thing.
	 */
	printk(RAM_DEBUG, "\nStarting native raminit\n");
	raminit_main(bootmode);

	return bootmode;
}

void perform_raminit(const int s3resume)
{
	/*
	 * See, this function's name is a lie. There are more things to
	 * do that memory initialisation, but they are relatively easy.
	 */
	const enum raminit_boot_mode orig_bootmode = get_boot_mode();

	const bool cpu_replaced = early_init_native(s3resume ? BOOTMODE_S3 : orig_bootmode);

	wait_txt_clear();
	wrmsr(0x2e6, (msr_t) {.lo = 0, .hi = 0});

	struct mrc_data md = prepare_mrc_cache();

	const enum raminit_boot_mode bootmode =
			do_actual_raminit(&md, s3resume, cpu_replaced, orig_bootmode);

	/** TODO: report_memory_config **/

	if (intel_early_me_uma_size() > 0) {
		/*
		 * The 'other' success value is to report loss of memory
		 * consistency to ME if warm boot was downgraded to cold.
		 */
		uint8_t me_status;
		if (BOOTMODE_WARM == orig_bootmode && BOOTMODE_COLD == bootmode)
			me_status = ME_INIT_STATUS_SUCCESS_OTHER;
		else
			me_status = ME_INIT_STATUS_SUCCESS;

		/** TODO: Remove this once raminit is implemented **/
		me_status = ME_INIT_STATUS_ERROR;
		intel_early_me_init_done(me_status);
	}

	intel_early_me_status();

	const bool cbmem_was_initted = !cbmem_recovery(s3resume);
	if (s3resume && !cbmem_was_initted) {
		/* Failed S3 resume, reset to come up cleanly */
		printk(BIOS_CRIT, "Failed to recover CBMEM in S3 resume.\n");
		system_reset();
	}

	/* Save training data on non-S3 resumes */
	if (!s3resume)
		save_mrc_data(&md);

	/** TODO: setup_sdram_meminfo **/
}
