/* 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 <stage_cache.h>
#include <timestamp.h>
#include <security/vboot/vboot_common.h>

static inline void stack_push(struct postcar_frame *pcf, uint32_t val)
{
	uint32_t *ptr;

	pcf->stack -= sizeof(val);
	ptr = (void *)pcf->stack;
	*ptr = val;
}

static void postcar_frame_prepare(struct postcar_frame *pcf)
{
	var_mtrr_context_init(&pcf->ctx, pcf);
}

int postcar_frame_init(struct postcar_frame *pcf, size_t stack_size)
{
	void *stack;

	/*
	 * Use default postcar stack size of 4 KiB. This value should
	 * not be decreased, because if mainboards use vboot, 1 KiB will
	 * not be enough anymore.
	 */

	if (stack_size == 0)
		stack_size = 4 * KiB;

	stack = cbmem_add(CBMEM_ID_ROMSTAGE_RAM_STACK, stack_size);
	if (stack == NULL) {
		printk(BIOS_ERR, "Couldn't add %zd byte stack in cbmem.\n",
			stack_size);
		return -1;
	}

	postcar_frame_prepare(pcf);
	pcf->stack = (uintptr_t)stack;
	pcf->stack += stack_size;
	return 0;
}

static void postcar_var_mtrr_set(const struct var_mtrr_context *ctx,
				uintptr_t addr, size_t size,
				msr_t base, msr_t mask)
{
	struct postcar_frame *pcf = ctx->arg;

	printk(BIOS_DEBUG, "MTRR Range: Start=%lx End=%lx (Size %zx)\n",
			addr, addr + size, size);

	stack_push(pcf, mask.hi);
	stack_push(pcf, mask.lo);
	stack_push(pcf, base.hi);
	stack_push(pcf, base.lo);
}

void postcar_frame_add_mtrr(struct postcar_frame *pcf,
				uintptr_t addr, size_t size, int type)
{
	var_mtrr_set_with_cb(&pcf->ctx, addr, size, type, postcar_var_mtrr_set);
}

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

/* 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 prepare_and_run_postcar(struct postcar_frame *pcf)
{
	if (postcar_frame_init(pcf, 0))
		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. */
}

static void postcar_commit_mtrrs(struct postcar_frame *pcf)
{
	/*
	 * Place the number of used variable MTRRs on stack then max number
	 * of variable MTRRs supported in the system.
	 */
	stack_push(pcf, pcf->ctx.used_var_mtrrs);
	stack_push(pcf, pcf->ctx.max_var_mtrrs);
}

static void finalize_load(uintptr_t *stack_top_ptr, uintptr_t stack_top)
{
	*stack_top_ptr = stack_top;
	/*
	 * Signal to rest of system that another update was made to the
	 * postcar program prior to running it.
	 */
	prog_segment_loaded((uintptr_t)stack_top_ptr, sizeof(uintptr_t),
		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 (prog_locate(prog))
		die_with_post_code(POST_INVALID_ROM,
				   "Failed to locate after CAR program.\n");
	if (rmodule_stage_load(&rsl))
		die_with_post_code(POST_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(POST_INVALID_ROM,
				   "No parameters found in after CAR program.\n");

	finalize_load(rsl.params, pcf->stack);

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

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

	postcar_commit_mtrrs(pcf);

	if (!CONFIG(NO_STAGE_CACHE) &&
				romstage_handoff_is_resume()) {
		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, pcf->stack);

		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_END_ROMSTAGE);

	console_time_report();

	prog_set_arg(&prog, cbmem_top());

	prog_run(&prog);
}
