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

#include <console/console.h>
#include <console/usb.h>
#include <string.h>
#include <cbmem.h>
#include <cbfs.h>
#include <cf9_reset.h>
#include <ip_checksum.h>
#include <memory_info.h>
#include <mrc_cache.h>
#include <device/device.h>
#include <device/pci_def.h>
#include <device/pci_ops.h>
#include <device/dram/ddr3.h>
#include <northbridge/intel/haswell/chip.h>
#include <northbridge/intel/haswell/haswell.h>
#include <northbridge/intel/haswell/raminit.h>
#include <smbios.h>
#include <spd.h>
#include <security/vboot/vboot_common.h>
#include <commonlib/region.h>
#include <southbridge/intel/lynxpoint/me.h>
#include <southbridge/intel/lynxpoint/pch.h>
#include <timestamp.h>
#include <types.h>

#include "pei_data.h"

#define MRC_CACHE_VERSION 1

static void save_mrc_data(struct pei_data *pei_data)
{
	/* Save the MRC S3 restore data to cbmem */
	mrc_cache_stash_data(MRC_TRAINING_DATA, MRC_CACHE_VERSION, pei_data->mrc_output,
			     pei_data->mrc_output_len);
}

static void prepare_mrc_cache(struct pei_data *pei_data)
{
	size_t mrc_size;

	/* Preset just in case there is an error */
	pei_data->mrc_input = NULL;
	pei_data->mrc_input_len = 0;

	pei_data->mrc_input =
		mrc_cache_current_mmap_leak(MRC_TRAINING_DATA,
					    MRC_CACHE_VERSION,
					    &mrc_size);
	if (!pei_data->mrc_input)
		/* Error message printed in find_current_mrc_cache */
		return;

	pei_data->mrc_input_len = mrc_size;

	printk(BIOS_DEBUG, "%s: at %p, size %zx\n", __func__,
	       pei_data->mrc_input, mrc_size);
}

static const char *const ecc_decoder[] = {
	"inactive",
	"active on IO",
	"disabled on IO",
	"active",
};

/* Print out the memory controller configuration, as per the values in its registers. */
static void report_memory_config(void)
{
	int i;

	const u32 addr_decoder_common = mchbar_read32(MAD_CHNL);

	printk(BIOS_DEBUG, "memcfg DDR3 clock %d MHz\n",
	       (mchbar_read32(MC_BIOS_DATA) * 13333 * 2 + 50) / 100);

	printk(BIOS_DEBUG, "memcfg channel assignment: A: %d, B % d, C % d\n",
	       (addr_decoder_common >> 0) & 3,
	       (addr_decoder_common >> 2) & 3,
	       (addr_decoder_common >> 4) & 3);

	for (i = 0; i < NUM_CHANNELS; i++) {
		const u32 ch_conf = mchbar_read32(MAD_DIMM(i));

		printk(BIOS_DEBUG, "memcfg channel[%d] config (%8.8x):\n", i, ch_conf);
		printk(BIOS_DEBUG, "   ECC %s\n", ecc_decoder[(ch_conf >> 24) & 3]);
		printk(BIOS_DEBUG, "   enhanced interleave mode %s\n",
		       ((ch_conf >> 22) & 1) ? "on" : "off");

		printk(BIOS_DEBUG, "   rank interleave %s\n",
		       ((ch_conf >> 21) & 1) ? "on" : "off");

		printk(BIOS_DEBUG, "   DIMMA %d MB width %s %s rank%s\n",
		       ((ch_conf >> 0) & 0xff) * 256,
		       ((ch_conf >> 19) & 1) ? "x16" : "x8 or x32",
		       ((ch_conf >> 17) & 1) ? "dual" : "single",
		       ((ch_conf >> 16) & 1) ? "" : ", selected");

		printk(BIOS_DEBUG, "   DIMMB %d MB width %s %s rank%s\n",
		       ((ch_conf >> 8) & 0xff) * 256,
		       ((ch_conf >> 20) & 1) ? "x16" : "x8 or x32",
		       ((ch_conf >> 18) & 1) ? "dual" : "single",
		       ((ch_conf >> 16) & 1) ? ", selected" : "");
	}
}

/**
 * Find PEI executable in coreboot filesystem and execute it.
 *
 * @param pei_data: configuration data for UEFI PEI reference code
 */
static void sdram_initialize(struct pei_data *pei_data)
{
	int (*entry)(struct pei_data *pei_data) __attribute__((regparm(1)));

	printk(BIOS_DEBUG, "Starting UEFI PEI System Agent\n");

	/*
	 * Always pass in mrc_cache data.  The driver will determine
	 * whether to use the data or not.
	 */
	prepare_mrc_cache(pei_data);

	/* If MRC data is not found, we cannot continue S3 resume */
	if (pei_data->boot_mode == 2 && !pei_data->mrc_input) {
		post_code(POST_RESUME_FAILURE);
		printk(BIOS_DEBUG, "Giving up in %s: No MRC data\n", __func__);
		system_reset();
	}

	/* Pass console handler in pei_data */
	pei_data->tx_byte = do_putchar;

	/*
	 * Locate and call UEFI System Agent binary. The binary needs to be at a fixed offset
	 * in the flash and can therefore only reside in the COREBOOT fmap region. We don't care
	 * about leaking the mapping.
	 */
	entry = cbfs_ro_map("mrc.bin", NULL);
	if (entry) {
		int rv = entry(pei_data);

		/* The mrc.bin reconfigures USB, so usbdebug needs to be reinitialized */
		if (CONFIG(USBDEBUG_IN_PRE_RAM))
			usbdebug_hw_init(true);

		if (rv) {
			switch (rv) {
			case -1:
				printk(BIOS_ERR, "PEI version mismatch.\n");
				break;
			case -2:
				printk(BIOS_ERR, "Invalid memory frequency.\n");
				break;
			default:
				printk(BIOS_ERR, "MRC returned %x.\n", rv);
			}
			die_with_post_code(POST_INVALID_VENDOR_BINARY,
					   "Nonzero MRC return value.\n");
		}
	} else {
		die("UEFI PEI System Agent not found.\n");
	}

	/* Print the MRC version after executing the UEFI PEI stage */
	u32 version = mchbar_read32(MRC_REVISION);
	printk(BIOS_DEBUG, "MRC Version %u.%u.%u Build %u\n",
		(version >> 24) & 0xff, (version >> 16) & 0xff,
		(version >>  8) & 0xff, (version >>  0) & 0xff);

	/*
	 * MRC may return zero even when raminit did not complete successfully.
	 * Ensure the mc_init_done_ack bit is set before continuing. Otherwise,
	 * attempting to access memory will lock up the system.
	 */
	if (!(mchbar_read32(MC_INIT_STATE_G) & (1 << 5))) {
		printk(BIOS_EMERG, "Memory controller did not acknowledge raminit.\n");
		die("MRC raminit failed\n");
	}

	report_memory_config();
}

static uint8_t nb_get_ecc_type(const uint32_t capid0_a)
{
	return capid0_a & CAPID_ECCDIS ? MEMORY_ARRAY_ECC_NONE : MEMORY_ARRAY_ECC_SINGLE_BIT;
}

static uint16_t nb_slots_per_channel(const uint32_t capid0_a)
{
	return !(capid0_a & CAPID_DDPCD) + 1;
}

static uint16_t nb_number_of_channels(const uint32_t capid0_a)
{
	return !(capid0_a & CAPID_PDCD) + 1;
}

static uint32_t nb_max_chan_capacity_mib(const uint32_t capid0_a)
{
	uint32_t ddrsz;

	/* Values from documentation, which assume two DIMMs per channel */
	switch (CAPID_DDRSZ(capid0_a)) {
	case 1:
		ddrsz = 8192;
		break;
	case 2:
		ddrsz = 2048;
		break;
	case 3:
		ddrsz = 512;
		break;
	default:
		ddrsz = 16384;
		break;
	}

	/* Account for the maximum number of DIMMs per channel */
	return (ddrsz / 2) * nb_slots_per_channel(capid0_a);
}

static void setup_sdram_meminfo(struct pei_data *pei_data)
{
	struct memory_info *mem_info;
	struct dimm_info *dimm;
	int ch, d_num;
	int dimm_cnt = 0;

	mem_info = cbmem_add(CBMEM_ID_MEMINFO, sizeof(struct memory_info));
	if (!mem_info)
		die("Failed to add memory info to CBMEM.\n");

	memset(mem_info, 0, sizeof(struct memory_info));

	const u32 ddr_frequency = (mchbar_read32(MC_BIOS_DATA) * 13333 * 2 + 50) / 100;

	for (ch = 0; ch < NUM_CHANNELS; ch++) {
		const u32 ch_conf = mchbar_read32(MAD_DIMM(ch));
		/* DIMMs A/B */
		for (d_num = 0; d_num < NUM_SLOTS; d_num++) {
			const u32 dimm_size = ((ch_conf >> (d_num * 8)) & 0xff) * 256;
			if (dimm_size) {
				const int index = ch * NUM_SLOTS + d_num;
				dimm = &mem_info->dimm[dimm_cnt];
				dimm->dimm_size = dimm_size;
				dimm->ddr_type = MEMORY_TYPE_DDR3;
				dimm->ddr_frequency = ddr_frequency;
				dimm->rank_per_dimm = 1 + ((ch_conf >> (17 + d_num)) & 1);
				dimm->channel_num = ch;
				dimm->dimm_num = d_num;
				dimm->bank_locator = ch * 2;
				memcpy(dimm->serial,
					&pei_data->spd_data[index][SPD_DIMM_SERIAL_NUM],
					SPD_DIMM_SERIAL_LEN);
				memcpy(dimm->module_part_number,
					&pei_data->spd_data[index][SPD_DIMM_PART_NUM],
					SPD_DIMM_PART_LEN);
				dimm->mod_id =
					(pei_data->spd_data[index][SPD_DIMM_MOD_ID2] << 8) |
					(pei_data->spd_data[index][SPD_DIMM_MOD_ID1] & 0xff);
				dimm->mod_type = DDR3_SPD_SODIMM;
				dimm->bus_width = MEMORY_BUS_WIDTH_64;
				dimm_cnt++;
			}
		}
	}
	mem_info->dimm_cnt = dimm_cnt;

	const uint32_t capid0_a = pci_read_config32(HOST_BRIDGE, CAPID0_A);

	const uint16_t channels = nb_number_of_channels(capid0_a);

	mem_info->ecc_type = nb_get_ecc_type(capid0_a);
	mem_info->max_capacity_mib = channels * nb_max_chan_capacity_mib(capid0_a);
	mem_info->number_of_devices = channels * nb_slots_per_channel(capid0_a);
}

/* Copy SPD data for on-board memory */
static void copy_spd(struct pei_data *pei_data, struct spd_info *spdi)
{
	if (!CONFIG(HAVE_SPD_IN_CBFS))
		return;

	printk(BIOS_DEBUG, "SPD index %d\n", spdi->spd_index);

	size_t spd_file_len;
	uint8_t *spd_file = cbfs_map("spd.bin", &spd_file_len);

	if (!spd_file)
		die("SPD data not found.");

	if (spd_file_len < ((spdi->spd_index + 1) * SPD_LEN)) {
		printk(BIOS_ERR, "SPD index override to 0 - old hardware?\n");
		spdi->spd_index = 0;
	}

	if (spd_file_len < SPD_LEN)
		die("Missing SPD data.");

	/* MRC only uses index 0, but coreboot uses the other indices */
	memcpy(pei_data->spd_data[0], spd_file + (spdi->spd_index * SPD_LEN), SPD_LEN);

	for (size_t i = 1; i < ARRAY_SIZE(spdi->addresses); i++) {
		if (spdi->addresses[i] == SPD_MEMORY_DOWN)
			memcpy(pei_data->spd_data[i], pei_data->spd_data[0], SPD_LEN);
	}
}

/*
 * 0 = leave channel enabled
 * 1 = disable dimm 0 on channel
 * 2 = disable dimm 1 on channel
 * 3 = disable dimm 0+1 on channel
 */
static int make_channel_disabled_mask(const struct pei_data *pd, int ch)
{
	return (!pd->spd_addresses[ch + ch] << 0) | (!pd->spd_addresses[ch + ch + 1] << 1);
}

static enum pei_usb2_port_location map_to_pei_usb2_location(const enum usb2_port_location loc)
{
	static const enum pei_usb2_port_location map[] = {
		[USB_PORT_SKIP]		= PEI_USB_PORT_SKIP,
		[USB_PORT_BACK_PANEL]	= PEI_USB_PORT_BACK_PANEL,
		[USB_PORT_FRONT_PANEL]	= PEI_USB_PORT_FRONT_PANEL,
		[USB_PORT_DOCK]		= PEI_USB_PORT_DOCK,
		[USB_PORT_MINI_PCIE]	= PEI_USB_PORT_MINI_PCIE,
		[USB_PORT_FLEX]		= PEI_USB_PORT_FLEX,
		[USB_PORT_INTERNAL]	= PEI_USB_PORT_INTERNAL,
	};
	return loc >= ARRAY_SIZE(map) ? PEI_USB_PORT_SKIP : map[loc];
}

static uint8_t map_to_pei_oc_pin(const uint8_t oc_pin)
{
	return oc_pin >= USB_OC_PIN_SKIP ? PEI_USB_OC_PIN_SKIP : oc_pin;
}

void perform_raminit(const int s3resume)
{
	const struct device *gbe = pcidev_on_root(0x19, 0);

	const struct northbridge_intel_haswell_config *cfg = config_of_soc();

	struct pei_data pei_data = {
		.pei_version		= PEI_VERSION,
		.mchbar			= CONFIG_FIXED_MCHBAR_MMIO_BASE,
		.dmibar			= CONFIG_FIXED_DMIBAR_MMIO_BASE,
		.epbar			= CONFIG_FIXED_EPBAR_MMIO_BASE,
		.pciexbar		= CONFIG_ECAM_MMCONF_BASE_ADDRESS,
		.smbusbar		= CONFIG_FIXED_SMBUS_IO_BASE,
		.hpet_address		= CONFIG_HPET_ADDRESS,
		.rcba			= CONFIG_FIXED_RCBA_MMIO_BASE,
		.pmbase			= DEFAULT_PMBASE,
		.gpiobase		= DEFAULT_GPIOBASE,
		.temp_mmio_base		= 0xfed08000,
		.system_type		= get_pch_platform_type(),
		.tseg_size		= CONFIG_SMM_TSEG_SIZE,
		.ec_present		= cfg->ec_present,
		.gbe_enable		= gbe && gbe->enabled,
		.ddr_refresh_2x		= CONFIG(ENABLE_DDR_2X_REFRESH),
		.dq_pins_interleaved	= cfg->dq_pins_interleaved,
		.max_ddr3_freq		= 1600,
		.usb_xhci_on_resume	= cfg->usb_xhci_on_resume,
	};

	for (size_t i = 0; i < ARRAY_SIZE(mainboard_usb2_ports); i++) {
		/* If a port is not enabled, skip it */
		if (!mainboard_usb2_ports[i].enable) {
			pei_data.usb2_ports[i].over_current_pin	= PEI_USB_OC_PIN_SKIP;
			pei_data.usb2_ports[i].location		= PEI_USB_PORT_SKIP;
			continue;
		}
		const enum usb2_port_location loc = mainboard_usb2_ports[i].location;
		const uint8_t oc_pin = mainboard_usb2_ports[i].oc_pin;
		pei_data.usb2_ports[i].length		= mainboard_usb2_ports[i].length;
		pei_data.usb2_ports[i].enable		= mainboard_usb2_ports[i].enable;
		pei_data.usb2_ports[i].over_current_pin	= map_to_pei_oc_pin(oc_pin);
		pei_data.usb2_ports[i].location		= map_to_pei_usb2_location(loc);
	}

	for (size_t i = 0; i < ARRAY_SIZE(mainboard_usb3_ports); i++) {
		const uint8_t oc_pin = mainboard_usb3_ports[i].oc_pin;
		pei_data.usb3_ports[i].enable		= mainboard_usb3_ports[i].enable;
		pei_data.usb3_ports[i].over_current_pin	= map_to_pei_oc_pin(oc_pin);
	}

	/* MRC has hardcoded assumptions of 2 meaning S3 wake. Normalize it here. */
	pei_data.boot_mode = s3resume ? 2 : 0;

	/* Obtain the SPD addresses from mainboard code */
	struct spd_info spdi = {0};
	mb_get_spd_map(&spdi);

	/* MRC expects left-aligned SMBus addresses, and 0xff for memory-down */
	for (size_t i = 0; i < ARRAY_SIZE(spdi.addresses); i++) {
		const uint8_t addr = spdi.addresses[i];
		pei_data.spd_addresses[i] = addr == SPD_MEMORY_DOWN ? 0xff : addr << 1;
	}

	/* Calculate unimplemented DIMM slots for each channel */
	pei_data.dimm_channel0_disabled = make_channel_disabled_mask(&pei_data, 0);
	pei_data.dimm_channel1_disabled = make_channel_disabled_mask(&pei_data, 1);

	timestamp_add_now(TS_BEFORE_INITRAM);

	copy_spd(&pei_data, &spdi);

	sdram_initialize(&pei_data);

	timestamp_add_now(TS_AFTER_INITRAM);

	post_code(0x3b);

	intel_early_me_status();

	int 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 data returned from MRC on non-S3 resumes. */
	if (!s3resume)
		save_mrc_data(&pei_data);

	setup_sdram_meminfo(&pei_data);
}
