/* SPDX-License-Identifier: GPL-2.0-only */

#include <arch/romstage.h>
#include <cbmem.h>
#include <console/console.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/smm.h>
#include <program_loading.h>
#include <reset.h>
#include <rmodule.h>
#include <romstage_handoff.h>
#include <security/vboot/vboot_common.h>
#include <stage_cache.h>
#include <timestamp.h>
#include <types.h>

static size_t var_mtrr_ctx_size(void)
{
	int mtrr_count = get_var_mtrr_count();
	return sizeof(struct var_mtrr_context) + mtrr_count * 2 * sizeof(msr_t);
}

static enum cb_err postcar_frame_init(struct postcar_frame *pcf)
{
	memset(pcf, 0, sizeof(*pcf));

	struct var_mtrr_context *ctx;

	ctx = cbmem_add(CBMEM_ID_ROMSTAGE_RAM_STACK, var_mtrr_ctx_size());
	if (ctx == NULL) {
		printk(BIOS_ERR, "Couldn't add var_mtrr_ctx setup in cbmem.\n");
		return CB_ERR;
	}

	pcf->mtrr = ctx;
	var_mtrr_context_init(pcf->mtrr);

	return CB_SUCCESS;
}

void postcar_frame_add_mtrr(struct postcar_frame *pcf,
				uintptr_t addr, size_t size, int type)
{
	var_mtrr_set(pcf->mtrr, addr, size, type);
}

void postcar_frame_add_romcache(struct postcar_frame *pcf, int type)
{
	if (!CONFIG(BOOT_DEVICE_MEMORY_MAPPED))
		return;
	postcar_frame_add_mtrr(pcf, CACHE_ROM_BASE, CACHE_ROM_SIZE, type);
}

static void postcar_frame_common_mtrrs(struct postcar_frame *pcf)
{
	if (pcf->skip_common_mtrr)
		return;

	/* Cache the ROM as WP just below 4GiB. */
	postcar_frame_add_romcache(pcf, MTRR_TYPE_WRPROT);
}

static void run_postcar_phase(struct postcar_frame *pcf);

/* prepare_and_run_postcar() determines the stack to use after
 * cache-as-ram is torn down as well as the MTRR settings to use. */
void __noreturn prepare_and_run_postcar(void)
{
	struct postcar_frame pcf;

	if (postcar_frame_init(&pcf))
		die("Unable to initialize postcar frame.\n");

	fill_postcar_frame(&pcf);

	postcar_frame_common_mtrrs(&pcf);

	run_postcar_phase(&pcf);
	/* We do not return here. */
	die("Failed to load postcar\n!");
}

static void finalize_load(uintptr_t *reloc_params, uintptr_t mtrr_frame_ptr)
{
	*reloc_params = mtrr_frame_ptr;
	/*
	 * Signal to rest of system that another update was made to the
	 * postcar program prior to running it.
	 */
	prog_segment_loaded((uintptr_t)reloc_params, sizeof(uintptr_t), SEG_FINAL);
	prog_segment_loaded((uintptr_t)mtrr_frame_ptr, var_mtrr_ctx_size(), SEG_FINAL);
}

static void load_postcar_cbfs(struct prog *prog, struct postcar_frame *pcf)
{
	struct rmod_stage_load rsl = {
		.cbmem_id = CBMEM_ID_AFTER_CAR,
		.prog = prog,
	};

	vboot_run_logic();

	if (rmodule_stage_load(&rsl))
		die_with_post_code(POSTCODE_INVALID_ROM,
				   "Failed to load after CAR program.\n");

	/* Set the stack pointer within parameters of the program loaded. */
	if (rsl.params == NULL)
		die_with_post_code(POSTCODE_INVALID_ROM,
				   "No parameters found in after CAR program.\n");

	finalize_load(rsl.params, (uintptr_t)pcf->mtrr);

	stage_cache_add(STAGE_POSTCAR, prog);
}

/*
 * Cache the TSEG region at the top of ram. This region is
 * not restricted to SMM mode until SMM has been relocated.
 * By setting the region to cacheable it provides faster access
 * when relocating the SMM handler as well as using the TSEG
 * region for other purposes.
 */
void postcar_enable_tseg_cache(struct postcar_frame *pcf)
{
	uintptr_t smm_base;
	size_t smm_size;

	smm_region(&smm_base, &smm_size);
	postcar_frame_add_mtrr(pcf, smm_base, smm_size,
				MTRR_TYPE_WRBACK);
}

static void postcar_cache_invalid(void)
{
	printk(BIOS_ERR, "postcar cache invalid.\n");
	board_reset();
}

/*
 * POSTCAR will call invd so don't make assumptions on cbmem
 * and external stage cache being UC.
 */
static void postcar_flush_cache(void)
{
	uintptr_t cbmem_base;
	size_t cbmem_size;
	uintptr_t stage_cache_base;
	size_t stage_cache_size;

	cbmem_get_region((void **)&cbmem_base, &cbmem_size);
	prog_segment_loaded(cbmem_base, cbmem_size, SEG_FINAL);
	if (CONFIG(TSEG_STAGE_CACHE) && !romstage_handoff_is_resume()) {
		stage_cache_external_region((void **)&stage_cache_base, &stage_cache_size);
		prog_segment_loaded(stage_cache_base, stage_cache_size, SEG_FINAL);
	}
}

static void run_postcar_phase(struct postcar_frame *pcf)
{
	struct prog prog =
		PROG_INIT(PROG_POSTCAR, CONFIG_CBFS_PREFIX "/postcar");

	if (resume_from_stage_cache()) {
		stage_cache_load_stage(STAGE_POSTCAR, &prog);
		/* This is here to allow platforms to pass different stack
		   parameters between S3 resume and normal boot. On the
		   platforms where the values are the same it's a nop. */
		finalize_load(prog.arg, (uintptr_t)pcf->mtrr);

		if (prog_entry(&prog) == NULL)
			postcar_cache_invalid();
	} else
		load_postcar_cbfs(&prog, pcf);

	/* As postcar exist, it's end of romstage here */
	timestamp_add_now(TS_ROMSTAGE_END);

	console_time_report();

	postcar_flush_cache();

	prog_set_arg(&prog, cbmem_top());

	prog_run(&prog);
}
