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

#include <acpi/acpi.h>
#include <amdblocks/acpi.h>
#include <amdblocks/agesawrapper_call.h>
#include <amdblocks/agesawrapper.h>
#include <amdblocks/biosram.h>
#include <amdblocks/post_codes.h>
#include <amdblocks/psp.h>
#include <arch/romstage.h>
#include <cbmem.h>
#include <commonlib/helpers.h>
#include <console/console.h>
#include <cpu/amd/mtrr.h>
#include <cpu/cpu.h>
#include <cpu/x86/msr.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/smm.h>
#include <device/device.h>
#include <device/pci_ops.h>
#include <elog.h>
#include <program_loading.h>
#include <romstage_common.h>
#include <romstage_handoff.h>
#include <soc/iomap.h>
#include <soc/northbridge.h>
#include <soc/pci_devs.h>
#include <soc/southbridge.h>
#include <stdint.h>

#include "chip.h"

void __weak mainboard_romstage_entry(void)
{
	/* By default, don't do anything */
}

static void agesa_call(void)
{
	post_code(POSTCODE_AGESA_AMDINITRESET);
	do_agesawrapper(AMD_INIT_RESET, "amdinitreset");

	post_code(POSTCODE_AGESA_AMDINITEARLY);
	/* APs will not exit amdinitearly */
	do_agesawrapper(AMD_INIT_EARLY, "amdinitearly");
}

static void bsp_agesa_call(void)
{
	set_ap_entry_ptr(agesa_call); /* indicate the path to the AP */
	agesa_call();
}
void __noreturn romstage_main(void)
{
	msr_t base, mask;
	msr_t mtrr_cap = rdmsr(MTRR_CAP_MSR);
	int vmtrrs = mtrr_cap.lo & MTRR_CAP_VCNT;
	int s3_resume = acpi_is_wakeup_s3();
	int i;

	soc_enable_psp_early();
	if (CONFIG(SOC_AMD_PSP_SELECTABLE_SMU_FW))
		psp_load_named_blob(BLOB_SMU_FW, "smu_fw");

	mainboard_romstage_entry();
	elog_boot_notify(s3_resume);

	bsp_agesa_call();

	if (!s3_resume) {
		post_code(POSTCODE_AGESA_AMDINITPOST);
		do_agesawrapper(AMD_INIT_POST, "amdinitpost");

		post_code(POSTCODE_AGESA_AMDINITPOST_DONE);
		/*
		 * TODO: This is a hack to work around current AGESA behavior.
		 *       AGESA needs to change to reflect that coreboot owns
		 *       the MTRRs.
		 *
		 * After setting up DRAM, AGESA also completes the configuration
		 * of the MTRRs, setting regions to WB.  Anything written to
		 * memory between now and when CAR is dismantled will be
		 * in cache and lost.  For now, set the regions UC to ensure
		 * the writes get to DRAM.
		 */
		for (i = 0 ; i < vmtrrs ; i++) {
			base = rdmsr(MTRR_PHYS_BASE(i));
			mask = rdmsr(MTRR_PHYS_MASK(i));
			if (!(mask.lo & MTRR_PHYS_MASK_VALID))
				continue;

			if ((base.lo & 0x7) == MTRR_TYPE_WRBACK) {
				base.lo &= ~0x7;
				base.lo |= MTRR_TYPE_UNCACHEABLE;
				wrmsr(MTRR_PHYS_BASE(i), base);
			}
		}
		/* Disable WB from to region 4GB-TOM2. */
		msr_t sys_cfg = rdmsr(SYSCFG_MSR);
		sys_cfg.lo &= ~SYSCFG_MSR_TOM2WB;
		wrmsr(SYSCFG_MSR, sys_cfg);
	} else {
		printk(BIOS_INFO, "S3 detected\n");
		post_code(POSTCODE_AGESA_AMDINITRESUME);
		do_agesawrapper(AMD_INIT_RESUME, "amdinitresume");

		post_code(POSTCODE_AGESA_AMDINITRESUME_DONE);
	}

	post_code(POSTCODE_PSP_NOTIFY_DRAM);
	psp_notify_dram();

	post_code(POSTCODE_PSP_NOTIFY_DRAM_DONE);
	if (cbmem_recovery(s3_resume))
		printk(BIOS_CRIT, "Failed to recover cbmem\n");
	if (romstage_handoff_init(s3_resume))
		printk(BIOS_ERR, "Failed to set romstage handoff data\n");

	if (CONFIG(SMM_TSEG))
		smm_list_regions();

	post_code(POSTCODE_ROMSTAGE_RUN_POSTCAR);
	prepare_and_run_postcar();
}

void fill_postcar_frame(struct postcar_frame *pcf)
{
	uintptr_t top_of_ram = (uintptr_t)cbmem_top();
	postcar_frame_add_mtrr(pcf, top_of_ram - 16 * MiB, 16 * MiB, MTRR_TYPE_WRBACK);

	/* Cache the TSEG region */
	postcar_enable_tseg_cache(pcf);
}

void SetMemParams(AMD_POST_PARAMS *PostParams)
{
	const struct soc_amd_stoneyridge_config *cfg;
	const struct device *dev = pcidev_path_on_root(GNB_DEVFN);

	if (!dev || !dev->chip_info) {
		printk(BIOS_ERR, "Cannot find SoC devicetree config\n");
		/* In case of a BIOS error, only attempt to set UMA. */
		PostParams->MemConfig.UmaMode = CONFIG(GFXUMA) ?
					UMA_AUTO : UMA_NONE;
		return;
	}

	cfg = dev->chip_info;

	PostParams->MemConfig.EnableMemClr = cfg->dram_clear_on_reset;

	switch (cfg->uma_mode) {
	case UMAMODE_NONE:
		PostParams->MemConfig.UmaMode = UMA_NONE;
		break;
	case UMAMODE_SPECIFIED_SIZE:
		PostParams->MemConfig.UmaMode = UMA_SPECIFIED;
		/* 64 KiB blocks. */
		PostParams->MemConfig.UmaSize = cfg->uma_size / (64 * KiB);
		break;
	case UMAMODE_AUTO_LEGACY:
		PostParams->MemConfig.UmaMode = UMA_AUTO;
		PostParams->MemConfig.UmaVersion = UMA_LEGACY;
		break;
	case UMAMODE_AUTO_NON_LEGACY:
		PostParams->MemConfig.UmaMode = UMA_AUTO;
		PostParams->MemConfig.UmaVersion = UMA_NON_LEGACY;
		break;
	}
}

void soc_customize_init_early(AMD_EARLY_PARAMS *InitEarly)
{
	const struct soc_amd_stoneyridge_config *cfg;
	const struct device *dev = pcidev_path_on_root(GNB_DEVFN);
	struct _PLATFORM_CONFIGURATION *platform;

	if (!dev || !dev->chip_info) {
		printk(BIOS_WARNING, "Cannot find SoC devicetree"
					" config, STAPM unchanged\n");
		return;
	}
	cfg = dev->chip_info;
	platform = &InitEarly->PlatformConfig;
	if ((cfg->stapm_percent) && (cfg->stapm_time_ms) &&
				    (cfg->stapm_power_mw)) {
		platform->PlatStapmConfig.CfgStapmScalar = cfg->stapm_percent;
		platform->PlatStapmConfig.CfgStapmTimeConstant =
							cfg->stapm_time_ms;
		platform->PkgPwrLimitDC = cfg->stapm_power_mw;
		platform->PkgPwrLimitAC = cfg->stapm_power_mw;
		platform->PlatStapmConfig.CfgStapmBoost = StapmBoostEnabled;
	}

	/* Make binaryPi use ACPI_CSTATE_CONTROL as C state control IO range. It gets written
	   into MSR_CSTATE_ADDRESS and used in the _CST packages in the PSTATE SSDT. */
	platform->CStateIoBaseAddress = ACPI_CSTATE_CONTROL;
}

static void migrate_power_state(int is_recovery)
{
	struct chipset_power_state *state;
	state = cbmem_add(CBMEM_ID_POWER_STATE, sizeof(*state));
	if (state) {
		acpi_fill_pm_gpe_state(&state->gpe_state);
		acpi_pm_gpe_add_events_print_events();
	}
}
CBMEM_CREATION_HOOK(migrate_power_state);
