/*
 *	Intel CPU microcode early update for Linux
 *
 *	Copyright (C) 2012 Fenghua Yu <fenghua.yu@intel.com>
 *			   H Peter Anvin" <hpa@zytor.com>
 *
 *	This allows to early upgrade microcode on Intel processors
 *	belonging to IA-32 family - PentiumPro, Pentium II,
 *	Pentium III, Xeon, Pentium 4, etc.
 *
 *	Reference: Section 9.11 of Volume 3, IA-32 Intel Architecture
 *	Software Developer's Manual.
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License
 *	as published by the Free Software Foundation; either version
 *	2 of the License, or (at your option) any later version.
 */
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/earlycpio.h>
#include <linux/initrd.h>
#include <linux/cpu.h>
#include <asm/msr.h>
#include <asm/microcode_intel.h>
#include <asm/processor.h>
#include <asm/tlbflush.h>
#include <asm/setup.h>

unsigned long mc_saved_in_initrd[MAX_UCODE_COUNT];
struct mc_saved_data {
	unsigned int mc_saved_count;
	struct microcode_intel **mc_saved;
} mc_saved_data;

static enum ucode_state __cpuinit
generic_load_microcode_early(struct microcode_intel **mc_saved_p,
			     unsigned int mc_saved_count,
			     struct ucode_cpu_info *uci)
{
	struct microcode_intel *ucode_ptr, *new_mc = NULL;
	int new_rev = uci->cpu_sig.rev;
	enum ucode_state state = UCODE_OK;
	unsigned int mc_size;
	struct microcode_header_intel *mc_header;
	unsigned int csig = uci->cpu_sig.sig;
	unsigned int cpf = uci->cpu_sig.pf;
	int i;

	for (i = 0; i < mc_saved_count; i++) {
		ucode_ptr = mc_saved_p[i];

		mc_header = (struct microcode_header_intel *)ucode_ptr;
		mc_size = get_totalsize(mc_header);
		if (get_matching_microcode(csig, cpf, ucode_ptr, new_rev)) {
			new_rev = mc_header->rev;
			new_mc  = ucode_ptr;
		}
	}

	if (!new_mc) {
		state = UCODE_NFOUND;
		goto out;
	}

	uci->mc = (struct microcode_intel *)new_mc;
out:
	return state;
}

static void __cpuinit
microcode_pointer(struct microcode_intel **mc_saved,
		  unsigned long *mc_saved_in_initrd,
		  unsigned long initrd_start, int mc_saved_count)
{
	int i;

	for (i = 0; i < mc_saved_count; i++)
		mc_saved[i] = (struct microcode_intel *)
			      (mc_saved_in_initrd[i] + initrd_start);
}

#ifdef CONFIG_X86_32
static void __cpuinit
microcode_phys(struct microcode_intel **mc_saved_tmp,
	       struct mc_saved_data *mc_saved_data)
{
	int i;
	struct microcode_intel ***mc_saved;

	mc_saved = (struct microcode_intel ***)
		   __pa_nodebug(&mc_saved_data->mc_saved);
	for (i = 0; i < mc_saved_data->mc_saved_count; i++) {
		struct microcode_intel *p;

		p = *(struct microcode_intel **)
			__pa_nodebug(mc_saved_data->mc_saved + i);
		mc_saved_tmp[i] = (struct microcode_intel *)__pa_nodebug(p);
	}
}
#endif

static enum ucode_state __cpuinit
load_microcode(struct mc_saved_data *mc_saved_data,
	       unsigned long *mc_saved_in_initrd,
	       unsigned long initrd_start,
	       struct ucode_cpu_info *uci)
{
	struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
	unsigned int count = mc_saved_data->mc_saved_count;

	if (!mc_saved_data->mc_saved) {
		microcode_pointer(mc_saved_tmp, mc_saved_in_initrd,
				  initrd_start, count);

		return generic_load_microcode_early(mc_saved_tmp, count, uci);
	} else {
#ifdef CONFIG_X86_32
		microcode_phys(mc_saved_tmp, mc_saved_data);
		return generic_load_microcode_early(mc_saved_tmp, count, uci);
#else
		return generic_load_microcode_early(mc_saved_data->mc_saved,
						    count, uci);
#endif
	}
}

static u8 get_x86_family(unsigned long sig)
{
	u8 x86;

	x86 = (sig >> 8) & 0xf;

	if (x86 == 0xf)
		x86 += (sig >> 20) & 0xff;

	return x86;
}

static u8 get_x86_model(unsigned long sig)
{
	u8 x86, x86_model;

	x86 = get_x86_family(sig);
	x86_model = (sig >> 4) & 0xf;

	if (x86 == 0x6 || x86 == 0xf)
		x86_model += ((sig >> 16) & 0xf) << 4;

	return x86_model;
}

/*
 * Given CPU signature and a microcode patch, this function finds if the
 * microcode patch has matching family and model with the CPU.
 */
static enum ucode_state
matching_model_microcode(struct microcode_header_intel *mc_header,
			unsigned long sig)
{
	u8 x86, x86_model;
	u8 x86_ucode, x86_model_ucode;
	struct extended_sigtable *ext_header;
	unsigned long total_size = get_totalsize(mc_header);
	unsigned long data_size = get_datasize(mc_header);
	int ext_sigcount, i;
	struct extended_signature *ext_sig;

	x86 = get_x86_family(sig);
	x86_model = get_x86_model(sig);

	x86_ucode = get_x86_family(mc_header->sig);
	x86_model_ucode = get_x86_model(mc_header->sig);

	if (x86 == x86_ucode && x86_model == x86_model_ucode)
		return UCODE_OK;

	/* Look for ext. headers: */
	if (total_size <= data_size + MC_HEADER_SIZE)
		return UCODE_NFOUND;

	ext_header = (struct extended_sigtable *)
		     mc_header + data_size + MC_HEADER_SIZE;
	ext_sigcount = ext_header->count;
	ext_sig = (void *)ext_header + EXT_HEADER_SIZE;

	for (i = 0; i < ext_sigcount; i++) {
		x86_ucode = get_x86_family(ext_sig->sig);
		x86_model_ucode = get_x86_model(ext_sig->sig);

		if (x86 == x86_ucode && x86_model == x86_model_ucode)
			return UCODE_OK;

		ext_sig++;
	}

	return UCODE_NFOUND;
}

static int
save_microcode(struct mc_saved_data *mc_saved_data,
	       struct microcode_intel **mc_saved_src,
	       unsigned int mc_saved_count)
{
	int i, j;
	struct microcode_intel **mc_saved_p;
	int ret;

	if (!mc_saved_count)
		return -EINVAL;

	/*
	 * Copy new microcode data.
	 */
	mc_saved_p = kmalloc(mc_saved_count*sizeof(struct microcode_intel *),
			     GFP_KERNEL);
	if (!mc_saved_p)
		return -ENOMEM;

	for (i = 0; i < mc_saved_count; i++) {
		struct microcode_intel *mc = mc_saved_src[i];
		struct microcode_header_intel *mc_header = &mc->hdr;
		unsigned long mc_size = get_totalsize(mc_header);
		mc_saved_p[i] = kmalloc(mc_size, GFP_KERNEL);
		if (!mc_saved_p[i]) {
			ret = -ENOMEM;
			goto err;
		}
		if (!mc_saved_src[i]) {
			ret = -EINVAL;
			goto err;
		}
		memcpy(mc_saved_p[i], mc, mc_size);
	}

	/*
	 * Point to newly saved microcode.
	 */
	mc_saved_data->mc_saved = mc_saved_p;
	mc_saved_data->mc_saved_count = mc_saved_count;

	return 0;

err:
	for (j = 0; j <= i; j++)
		kfree(mc_saved_p[j]);
	kfree(mc_saved_p);

	return ret;
}

/*
 * A microcode patch in ucode_ptr is saved into mc_saved
 * - if it has matching signature and newer revision compared to an existing
 *   patch mc_saved.
 * - or if it is a newly discovered microcode patch.
 *
 * The microcode patch should have matching model with CPU.
 */
static void _save_mc(struct microcode_intel **mc_saved, u8 *ucode_ptr,
		     unsigned int *mc_saved_count_p)
{
	int i;
	int found = 0;
	unsigned int mc_saved_count = *mc_saved_count_p;
	struct microcode_header_intel *mc_header;

	mc_header = (struct microcode_header_intel *)ucode_ptr;
	for (i = 0; i < mc_saved_count; i++) {
		unsigned int sig, pf;
		unsigned int new_rev;
		struct microcode_header_intel *mc_saved_header =
			     (struct microcode_header_intel *)mc_saved[i];
		sig = mc_saved_header->sig;
		pf = mc_saved_header->pf;
		new_rev = mc_header->rev;

		if (get_matching_sig(sig, pf, ucode_ptr, new_rev)) {
			found = 1;
			if (update_match_revision(mc_header, new_rev)) {
				/*
				 * Found an older ucode saved before.
				 * Replace the older one with this newer
				 * one.
				 */
				mc_saved[i] =
					(struct microcode_intel *)ucode_ptr;
				break;
			}
		}
	}
	if (i >= mc_saved_count && !found)
		/*
		 * This ucode is first time discovered in ucode file.
		 * Save it to memory.
		 */
		mc_saved[mc_saved_count++] =
				 (struct microcode_intel *)ucode_ptr;

	*mc_saved_count_p = mc_saved_count;
}

/*
 * Get microcode matching with BSP's model. Only CPUs with the same model as
 * BSP can stay in the platform.
 */
static enum ucode_state __init
get_matching_model_microcode(int cpu, unsigned long start,
			     void *data, size_t size,
			     struct mc_saved_data *mc_saved_data,
			     unsigned long *mc_saved_in_initrd,
			     struct ucode_cpu_info *uci)
{
	u8 *ucode_ptr = data;
	unsigned int leftover = size;
	enum ucode_state state = UCODE_OK;
	unsigned int mc_size;
	struct microcode_header_intel *mc_header;
	struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
	unsigned int mc_saved_count = mc_saved_data->mc_saved_count;
	int i;

	while (leftover && mc_saved_count < ARRAY_SIZE(mc_saved_tmp)) {
		mc_header = (struct microcode_header_intel *)ucode_ptr;

		mc_size = get_totalsize(mc_header);
		if (!mc_size || mc_size > leftover ||
			microcode_sanity_check(ucode_ptr, 0) < 0)
			break;

		leftover -= mc_size;

		/*
		 * Since APs with same family and model as the BSP may boot in
		 * the platform, we need to find and save microcode patches
		 * with the same family and model as the BSP.
		 */
		if (matching_model_microcode(mc_header, uci->cpu_sig.sig) !=
			 UCODE_OK) {
			ucode_ptr += mc_size;
			continue;
		}

		_save_mc(mc_saved_tmp, ucode_ptr, &mc_saved_count);

		ucode_ptr += mc_size;
	}

	if (leftover) {
		state = UCODE_ERROR;
		goto out;
	}

	if (mc_saved_count == 0) {
		state = UCODE_NFOUND;
		goto out;
	}

	for (i = 0; i < mc_saved_count; i++)
		mc_saved_in_initrd[i] = (unsigned long)mc_saved_tmp[i] - start;

	mc_saved_data->mc_saved_count = mc_saved_count;
out:
	return state;
}

#define native_rdmsr(msr, val1, val2)		\
do {						\
	u64 __val = native_read_msr((msr));	\
	(void)((val1) = (u32)__val);		\
	(void)((val2) = (u32)(__val >> 32));	\
} while (0)

#define native_wrmsr(msr, low, high)		\
	native_write_msr(msr, low, high);

static int __cpuinit collect_cpu_info_early(struct ucode_cpu_info *uci)
{
	unsigned int val[2];
	u8 x86, x86_model;
	struct cpu_signature csig;
	unsigned int eax, ebx, ecx, edx;

	csig.sig = 0;
	csig.pf = 0;
	csig.rev = 0;

	memset(uci, 0, sizeof(*uci));

	eax = 0x00000001;
	ecx = 0;
	native_cpuid(&eax, &ebx, &ecx, &edx);
	csig.sig = eax;

	x86 = get_x86_family(csig.sig);
	x86_model = get_x86_model(csig.sig);

	if ((x86_model >= 5) || (x86 > 6)) {
		/* get processor flags from MSR 0x17 */
		native_rdmsr(MSR_IA32_PLATFORM_ID, val[0], val[1]);
		csig.pf = 1 << ((val[1] >> 18) & 7);
	}
	native_wrmsr(MSR_IA32_UCODE_REV, 0, 0);

	/* As documented in the SDM: Do a CPUID 1 here */
	sync_core();

	/* get the current revision from MSR 0x8B */
	native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);

	csig.rev = val[1];

	uci->cpu_sig = csig;
	uci->valid = 1;

	return 0;
}

#ifdef DEBUG
static void __ref show_saved_mc(void)
{
	int i, j;
	unsigned int sig, pf, rev, total_size, data_size, date;
	struct ucode_cpu_info uci;

	if (mc_saved_data.mc_saved_count == 0) {
		pr_debug("no micorcode data saved.\n");
		return;
	}
	pr_debug("Total microcode saved: %d\n", mc_saved_data.mc_saved_count);

	collect_cpu_info_early(&uci);

	sig = uci.cpu_sig.sig;
	pf = uci.cpu_sig.pf;
	rev = uci.cpu_sig.rev;
	pr_debug("CPU%d: sig=0x%x, pf=0x%x, rev=0x%x\n",
		 smp_processor_id(), sig, pf, rev);

	for (i = 0; i < mc_saved_data.mc_saved_count; i++) {
		struct microcode_header_intel *mc_saved_header;
		struct extended_sigtable *ext_header;
		int ext_sigcount;
		struct extended_signature *ext_sig;

		mc_saved_header = (struct microcode_header_intel *)
				  mc_saved_data.mc_saved[i];
		sig = mc_saved_header->sig;
		pf = mc_saved_header->pf;
		rev = mc_saved_header->rev;
		total_size = get_totalsize(mc_saved_header);
		data_size = get_datasize(mc_saved_header);
		date = mc_saved_header->date;

		pr_debug("mc_saved[%d]: sig=0x%x, pf=0x%x, rev=0x%x, toal size=0x%x, date = %04x-%02x-%02x\n",
			 i, sig, pf, rev, total_size,
			 date & 0xffff,
			 date >> 24,
			 (date >> 16) & 0xff);

		/* Look for ext. headers: */
		if (total_size <= data_size + MC_HEADER_SIZE)
			continue;

		ext_header = (struct extended_sigtable *)
			     mc_saved_header + data_size + MC_HEADER_SIZE;
		ext_sigcount = ext_header->count;
		ext_sig = (void *)ext_header + EXT_HEADER_SIZE;

		for (j = 0; j < ext_sigcount; j++) {
			sig = ext_sig->sig;
			pf = ext_sig->pf;

			pr_debug("\tExtended[%d]: sig=0x%x, pf=0x%x\n",
				 j, sig, pf);

			ext_sig++;
		}

	}
}
#else
static inline void show_saved_mc(void)
{
}
#endif

#if defined(CONFIG_MICROCODE_INTEL_EARLY) && defined(CONFIG_HOTPLUG_CPU)
static DEFINE_MUTEX(x86_cpu_microcode_mutex);
/*
 * Save this mc into mc_saved_data. So it will be loaded early when a CPU is
 * hot added or resumes.
 *
 * Please make sure this mc should be a valid microcode patch before calling
 * this function.
 */
int save_mc_for_early(u8 *mc)
{
	struct microcode_intel *mc_saved_tmp[MAX_UCODE_COUNT];
	unsigned int mc_saved_count_init;
	unsigned int mc_saved_count;
	struct microcode_intel **mc_saved;
	int ret = 0;
	int i;

	/*
	 * Hold hotplug lock so mc_saved_data is not accessed by a CPU in
	 * hotplug.
	 */
	mutex_lock(&x86_cpu_microcode_mutex);

	mc_saved_count_init = mc_saved_data.mc_saved_count;
	mc_saved_count = mc_saved_data.mc_saved_count;
	mc_saved = mc_saved_data.mc_saved;

	if (mc_saved && mc_saved_count)
		memcpy(mc_saved_tmp, mc_saved,
		       mc_saved_count * sizeof(struct mirocode_intel *));
	/*
	 * Save the microcode patch mc in mc_save_tmp structure if it's a newer
	 * version.
	 */

	_save_mc(mc_saved_tmp, mc, &mc_saved_count);

	/*
	 * Save the mc_save_tmp in global mc_saved_data.
	 */
	ret = save_microcode(&mc_saved_data, mc_saved_tmp, mc_saved_count);
	if (ret) {
		pr_err("Can not save microcode patch.\n");
		goto out;
	}

	show_saved_mc();

	/*
	 * Free old saved microcod data.
	 */
	if (mc_saved) {
		for (i = 0; i < mc_saved_count_init; i++)
			kfree(mc_saved[i]);
		kfree(mc_saved);
	}

out:
	mutex_unlock(&x86_cpu_microcode_mutex);

	return ret;
}
EXPORT_SYMBOL_GPL(save_mc_for_early);
#endif

static __initdata char ucode_name[] = "kernel/x86/microcode/GenuineIntel.bin";
static __init enum ucode_state
scan_microcode(unsigned long start, unsigned long end,
		struct mc_saved_data *mc_saved_data,
		unsigned long *mc_saved_in_initrd,
		struct ucode_cpu_info *uci)
{
	unsigned int size = end - start + 1;
	struct cpio_data cd;
	long offset = 0;
#ifdef CONFIG_X86_32
	char *p = (char *)__pa_nodebug(ucode_name);
#else
	char *p = ucode_name;
#endif

	cd.data = NULL;
	cd.size = 0;

	cd = find_cpio_data(p, (void *)start, size, &offset);
	if (!cd.data)
		return UCODE_ERROR;


	return get_matching_model_microcode(0, start, cd.data, cd.size,
					    mc_saved_data, mc_saved_in_initrd,
					    uci);
}

/*
 * Print ucode update info.
 */
static void __cpuinit
print_ucode_info(struct ucode_cpu_info *uci, unsigned int date)
{
	int cpu = smp_processor_id();

	pr_info("CPU%d microcode updated early to revision 0x%x, date = %04x-%02x-%02x\n",
		cpu,
		uci->cpu_sig.rev,
		date & 0xffff,
		date >> 24,
		(date >> 16) & 0xff);
}

#ifdef CONFIG_X86_32

static int delay_ucode_info;
static int current_mc_date;

/*
 * Print early updated ucode info after printk works. This is delayed info dump.
 */
void __cpuinit show_ucode_info_early(void)
{
	struct ucode_cpu_info uci;

	if (delay_ucode_info) {
		collect_cpu_info_early(&uci);
		print_ucode_info(&uci, current_mc_date);
		delay_ucode_info = 0;
	}
}

/*
 * At this point, we can not call printk() yet. Keep microcode patch number in
 * mc_saved_data.mc_saved and delay printing microcode info in
 * show_ucode_info_early() until printk() works.
 */
static void __cpuinit print_ucode(struct ucode_cpu_info *uci)
{
	struct microcode_intel *mc_intel;
	int *delay_ucode_info_p;
	int *current_mc_date_p;

	mc_intel = uci->mc;
	if (mc_intel == NULL)
		return;

	delay_ucode_info_p = (int *)__pa_nodebug(&delay_ucode_info);
	current_mc_date_p = (int *)__pa_nodebug(&current_mc_date);

	*delay_ucode_info_p = 1;
	*current_mc_date_p = mc_intel->hdr.date;
}
#else

/*
 * Flush global tlb. We only do this in x86_64 where paging has been enabled
 * already and PGE should be enabled as well.
 */
static inline void __cpuinit flush_tlb_early(void)
{
	__native_flush_tlb_global_irq_disabled();
}

static inline void __cpuinit print_ucode(struct ucode_cpu_info *uci)
{
	struct microcode_intel *mc_intel;

	mc_intel = uci->mc;
	if (mc_intel == NULL)
		return;

	print_ucode_info(uci, mc_intel->hdr.date);
}
#endif

static int __cpuinit apply_microcode_early(struct mc_saved_data *mc_saved_data,
					   struct ucode_cpu_info *uci)
{
	struct microcode_intel *mc_intel;
	unsigned int val[2];

	mc_intel = uci->mc;
	if (mc_intel == NULL)
		return 0;

	/* write microcode via MSR 0x79 */
	native_wrmsr(MSR_IA32_UCODE_WRITE,
	      (unsigned long) mc_intel->bits,
	      (unsigned long) mc_intel->bits >> 16 >> 16);
	native_wrmsr(MSR_IA32_UCODE_REV, 0, 0);

	/* As documented in the SDM: Do a CPUID 1 here */
	sync_core();

	/* get the current revision from MSR 0x8B */
	native_rdmsr(MSR_IA32_UCODE_REV, val[0], val[1]);
	if (val[1] != mc_intel->hdr.rev)
		return -1;

#ifdef CONFIG_X86_64
	/* Flush global tlb. This is precaution. */
	flush_tlb_early();
#endif
	uci->cpu_sig.rev = val[1];

	print_ucode(uci);

	return 0;
}

/*
 * This function converts microcode patch offsets previously stored in
 * mc_saved_in_initrd to pointers and stores the pointers in mc_saved_data.
 */
int __init save_microcode_in_initrd(void)
{
	unsigned int count = mc_saved_data.mc_saved_count;
	struct microcode_intel *mc_saved[MAX_UCODE_COUNT];
	int ret = 0;

	if (count == 0)
		return ret;

	microcode_pointer(mc_saved, mc_saved_in_initrd, initrd_start, count);
	ret = save_microcode(&mc_saved_data, mc_saved, count);
	if (ret)
		pr_err("Can not save microcod patches from initrd");

	show_saved_mc();

	return ret;
}

static void __init
_load_ucode_intel_bsp(struct mc_saved_data *mc_saved_data,
		      unsigned long *mc_saved_in_initrd,
		      unsigned long initrd_start_early,
		      unsigned long initrd_end_early,
		      struct ucode_cpu_info *uci)
{
	collect_cpu_info_early(uci);
	scan_microcode(initrd_start_early, initrd_end_early, mc_saved_data,
		       mc_saved_in_initrd, uci);
	load_microcode(mc_saved_data, mc_saved_in_initrd,
		       initrd_start_early, uci);
	apply_microcode_early(mc_saved_data, uci);
}

void __init
load_ucode_intel_bsp(void)
{
	u64 ramdisk_image, ramdisk_size;
	unsigned long initrd_start_early, initrd_end_early;
	struct ucode_cpu_info uci;
#ifdef CONFIG_X86_32
	struct boot_params *boot_params_p;

	boot_params_p = (struct boot_params *)__pa_nodebug(&boot_params);
	ramdisk_image = boot_params_p->hdr.ramdisk_image;
	ramdisk_size  = boot_params_p->hdr.ramdisk_size;
	initrd_start_early = ramdisk_image;
	initrd_end_early = initrd_start_early + ramdisk_size;

	_load_ucode_intel_bsp(
		(struct mc_saved_data *)__pa_nodebug(&mc_saved_data),
		(unsigned long *)__pa_nodebug(&mc_saved_in_initrd),
		initrd_start_early, initrd_end_early, &uci);
#else
	ramdisk_image = boot_params.hdr.ramdisk_image;
	ramdisk_size  = boot_params.hdr.ramdisk_size;
	initrd_start_early = ramdisk_image + PAGE_OFFSET;
	initrd_end_early = initrd_start_early + ramdisk_size;

	_load_ucode_intel_bsp(&mc_saved_data, mc_saved_in_initrd,
			      initrd_start_early, initrd_end_early, &uci);
#endif
}

void __cpuinit load_ucode_intel_ap(void)
{
	struct mc_saved_data *mc_saved_data_p;
	struct ucode_cpu_info uci;
	unsigned long *mc_saved_in_initrd_p;
	unsigned long initrd_start_addr;
#ifdef CONFIG_X86_32
	unsigned long *initrd_start_p;

	mc_saved_in_initrd_p =
		(unsigned long *)__pa_nodebug(mc_saved_in_initrd);
	mc_saved_data_p = (struct mc_saved_data *)__pa_nodebug(&mc_saved_data);
	initrd_start_p = (unsigned long *)__pa_nodebug(&initrd_start);
	initrd_start_addr = (unsigned long)__pa_nodebug(*initrd_start_p);
#else
	mc_saved_data_p = &mc_saved_data;
	mc_saved_in_initrd_p = mc_saved_in_initrd;
	initrd_start_addr = initrd_start;
#endif

	/*
	 * If there is no valid ucode previously saved in memory, no need to
	 * update ucode on this AP.
	 */
	if (mc_saved_data_p->mc_saved_count == 0)
		return;

	collect_cpu_info_early(&uci);
	load_microcode(mc_saved_data_p, mc_saved_in_initrd_p,
		       initrd_start_addr, &uci);
	apply_microcode_early(mc_saved_data_p, &uci);
}
