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

/* Microcode update for Intel PIII and later CPUs */

#include <cbfs.h>
#include <console/console.h>
#include <cpu/cpu.h>
#include <cpu/intel/microcode.h>
#include <cpu/x86/msr.h>
#include <smp/spinlock.h>
#include <stdio.h>
#include <types.h>

DECLARE_SPIN_LOCK(microcode_lock)

struct microcode {
	u32 hdrver;	/* Header Version */
	u32 rev;	/* Update Revision */
	u32 date;	/* Date */
	u32 sig;	/* Processor Signature */

	u32 cksum;	/* Checksum */
	u32 ldrver;	/* Loader Revision */
	u32 pf;		/* Processor Flags */

	u32 data_size;	/* Data Size */
	u32 total_size;	/* Total Size */

	u32 reserved[3];
};

struct ext_sig_table {
	u32 ext_sig_cnt;
	u32 ext_tbl_chksm;
	u32 res[3];
};

struct ext_sig_entry {
	u32 sig;
	u32 pf;
	u32 chksm;
};

static inline u32 read_microcode_rev(void)
{
	/* Some Intel CPUs can be very finicky about the
	 * CPUID sequence used.  So this is implemented in
	 * assembly so that it works reliably.
	 */
	msr_t msr;
	asm volatile (
		"xorl %%eax, %%eax\n\t"
		"xorl %%edx, %%edx\n\t"
		"movl $0x8b, %%ecx\n\t"
		"wrmsr\n\t"
		"movl $0x01, %%eax\n\t"
		"cpuid\n\t"
		"movl $0x08b, %%ecx\n\t"
		"rdmsr\n\t"
		: /* outputs */
		"=a" (msr.lo), "=d" (msr.hi)
		: /* inputs */
		: /* trashed */
		 "ebx", "ecx"
	);
	return msr.hi;
}

#define MICROCODE_CBFS_FILE "cpu_microcode_blob.bin"

static int load_microcode(const struct microcode *ucode_patch)
{
	u32 current_rev;
	msr_t msr;

	msr.lo = (unsigned long)ucode_patch + sizeof(struct microcode);
	msr.hi = 0;
	wrmsr(IA32_BIOS_UPDT_TRIG, msr);

	current_rev = read_microcode_rev();
	if (current_rev == ucode_patch->rev) {
		printk(BIOS_INFO, "microcode: updated to revision "
		    "0x%x date=%04x-%02x-%02x\n", read_microcode_rev(),
		    ucode_patch->date & 0xffff, (ucode_patch->date >> 24) & 0xff,
		    (ucode_patch->date >> 16) & 0xff);
		return 0;
	}

	return -1;
}

void intel_microcode_load_unlocked(const void *microcode_patch)
{
	u32 current_rev;
	const struct microcode *m = microcode_patch;

	if (!m) {
		printk(BIOS_WARNING, "microcode: failed because no ucode was found\n");
		return;
	}

	current_rev = read_microcode_rev();

	/* No use loading the same revision. */
	if (current_rev == m->rev) {
		printk(BIOS_INFO, "microcode: Update skipped, already up-to-date\n");
		return;
	}

#if ENV_RAMSTAGE
	/*SoC specific check to update microcode*/
	if (soc_skip_ucode_update(current_rev, m->rev)) {
		printk(BIOS_DEBUG, "Skip microcode update\n");
		return;
	}
#endif

	printk(BIOS_INFO, "microcode: load microcode patch\n");
	if (load_microcode(m) < 0)
		printk(BIOS_ERR, "microcode: Update failed\n");
}

uint32_t get_current_microcode_rev(void)
{
	return read_microcode_rev();
}

uint32_t get_microcode_rev(const void *microcode)
{
	return ((struct microcode *)microcode)->rev;
}

uint32_t get_microcode_size(const void *microcode)
{
	return ((struct microcode *)microcode)->total_size;
}

uint32_t get_microcode_checksum(const void *microcode)
{
	return ((struct microcode *)microcode)->cksum;
}


static struct ext_sig_table *ucode_get_ext_sig_table(const struct microcode *ucode)
{
	struct ext_sig_table *ext_tbl;
	/* header + ucode data blob size */
	u32 size = ucode->data_size + sizeof(struct microcode);

	ssize_t ext_tbl_len = ucode->total_size - size;

	if (ext_tbl_len < (ssize_t)sizeof(struct ext_sig_table))
		return NULL;

	ext_tbl = (struct ext_sig_table *)((uintptr_t)ucode + size);

	if (ext_tbl_len < (sizeof(struct ext_sig_table) +
				ext_tbl->ext_sig_cnt * sizeof(struct ext_sig_entry)))
		return NULL;

	return ext_tbl;
}

static const void *find_cbfs_microcode(void)
{
	const struct microcode *ucode_updates;
	struct ext_sig_table *ext_tbl;
	size_t microcode_len;
	u32 eax;
	u32 pf, rev, sig, update_size;
	msr_t msr;
	struct cpuinfo_x86 c;

	rev = read_microcode_rev();
	eax = cpuid_eax(1);
	get_fms(&c, eax);
	sig = eax;

	pf = 0;
	if ((c.x86_model >= 5) || (c.x86 > 6)) {
		msr = rdmsr(IA32_PLATFORM_ID);
		pf = 1 << ((msr.hi >> 18) & 7);
	}

	printk(BIOS_DEBUG, "microcode: sig=0x%x pf=0x%x revision=0x%x\n",
			sig, pf, rev);

	if (CONFIG(CPU_INTEL_MICROCODE_CBFS_SPLIT_BINS)) {
		char cbfs_filename[25];
		snprintf(cbfs_filename, sizeof(cbfs_filename), "cpu_microcode_%x.bin", sig);
		ucode_updates = cbfs_map(cbfs_filename, &microcode_len);
	} else {
		ucode_updates = cbfs_map(MICROCODE_CBFS_FILE, &microcode_len);
	}
	if (ucode_updates == NULL)
		return NULL;

	while (microcode_len >= sizeof(*ucode_updates)) {
		/* Newer microcode updates include a size field, whereas older
		 * containers set it at 0 and are exactly 2048 bytes long */
		if (ucode_updates->total_size) {
			update_size = ucode_updates->total_size;
		} else {
			printk(BIOS_SPEW, "Microcode size field is 0\n");
			update_size = 2048;
		}

		/* Checkpoint 1: The microcode update falls within CBFS */
		if (update_size > microcode_len) {
			printk(BIOS_WARNING, "Microcode header corrupted!\n");
			break;
		}

		if ((ucode_updates->sig == sig) && (ucode_updates->pf & pf))
			return ucode_updates;


		/* Check if there is extended signature table */
		ext_tbl = ucode_get_ext_sig_table(ucode_updates);

		if (ext_tbl != NULL) {
			int i;
			struct ext_sig_entry *entry = (struct ext_sig_entry *)(ext_tbl + 1);

			for (i = 0; i < ext_tbl->ext_sig_cnt; i++, entry++) {
				if ((sig == entry->sig) && (pf & entry->pf)) {
					return ucode_updates;
				}
			}
		}

		ucode_updates = (void *)((char *)ucode_updates + update_size);
		microcode_len -= update_size;
	}

	return NULL;
}

const void *intel_microcode_find(void)
{
	static bool microcode_checked;
	static const void *ucode_update;

	if (ENV_CACHE_AS_RAM) {
		printk(BIOS_ERR, "Microcode Error: Early microcode patching is not supported due"
				"to NEM limitation\n");
		return NULL;
	}

	if (microcode_checked)
		return ucode_update;

	/*
	 * Since this function caches the found microcode (NULL or a valid
	 * microcode pointer), it is expected to be run from BSP before starting
	 * any other APs. This sequence is not multithread safe otherwise.
	 */
	ucode_update = find_cbfs_microcode();
	microcode_checked = true;

	return ucode_update;
}

void intel_update_microcode_from_cbfs(void)
{
	const void *patch = intel_microcode_find();

	spin_lock(&microcode_lock);

	intel_microcode_load_unlocked(patch);

	spin_unlock(&microcode_lock);
}

void intel_reload_microcode(void)
{
	if (!CONFIG(RELOAD_MICROCODE_PATCH))
		return;

	const struct microcode *m = intel_microcode_find();

	if (!m) {
		printk(BIOS_WARNING, "microcode: failed because no ucode was found\n");
		return;
	}

	printk(BIOS_INFO, "microcode: Re-load microcode patch\n");

	if (load_microcode(m) < 0)
		printk(BIOS_ERR, "microcode: Re-load failed\n");
}

#if ENV_RAMSTAGE
__weak int soc_skip_ucode_update(u32 current_patch_id,
	u32 new_patch_id)
{
	return 0;
}
#endif
