
The microcode update data block encoded in Device Tree is used by the bootstrap processor (BSP) but not passed to the other CPUs (AP).
If the bootstrap processor successfully performs a microcode update from Device Tree, use the same data block for the other processors.
Signed-off-by: Ivan Gorinov ivan.gorinov@intel.com --- arch/x86/cpu/i386/cpu.c | 3 ++- arch/x86/cpu/intel_common/car.S | 2 ++ arch/x86/cpu/intel_common/microcode.c | 10 +++++++--- arch/x86/include/asm/microcode.h | 1 + arch/x86/lib/fsp/fsp_car.S | 2 ++ 5 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/arch/x86/cpu/i386/cpu.c b/arch/x86/cpu/i386/cpu.c index aabdc94..05d8312 100644 --- a/arch/x86/cpu/i386/cpu.c +++ b/arch/x86/cpu/i386/cpu.c @@ -26,6 +26,7 @@ #include <asm/mp.h> #include <asm/msr.h> #include <asm/mtrr.h> +#include <asm/microcode.h> #include <asm/processor-flags.h>
DECLARE_GLOBAL_DATA_PTR; @@ -586,7 +587,7 @@ int x86_mp_init(void) mp_params.parallel_microcode_load = 0, mp_params.flight_plan = &mp_steps[0]; mp_params.num_records = ARRAY_SIZE(mp_steps); - mp_params.microcode_pointer = 0; + mp_params.microcode_pointer = (void *)ucode_base;
if (mp_init(&mp_params)) { printf("Warning: MP init failure\n"); diff --git a/arch/x86/cpu/intel_common/car.S b/arch/x86/cpu/intel_common/car.S index 6e0db96..099bf28 100644 --- a/arch/x86/cpu/intel_common/car.S +++ b/arch/x86/cpu/intel_common/car.S @@ -240,4 +240,6 @@ _dt_ucode_base_size: .globl ucode_base ucode_base: /* Declared in microcode.h */ .long 0 /* microcode base */ +.globl ucode_size +ucode_size: /* Declared in microcode.h */ .long 0 /* microcode size */ diff --git a/arch/x86/cpu/intel_common/microcode.c b/arch/x86/cpu/intel_common/microcode.c index 8813258..9321ae1 100644 --- a/arch/x86/cpu/intel_common/microcode.c +++ b/arch/x86/cpu/intel_common/microcode.c @@ -44,8 +44,6 @@ static int microcode_decode_node(const void *blob, int node, update->data = fdt_getprop(blob, node, "data", &update->size); if (!update->data) return -ENOENT; - update->data += UCODE_HEADER_LEN; - update->size -= UCODE_HEADER_LEN;
update->header_version = fdtdec_get_int(blob, node, "intel,header-version", 0); @@ -125,6 +123,7 @@ static void microcode_read_cpu(struct microcode_update *cpu) int microcode_update_intel(void) { struct microcode_update cpu, update; + ulong address; const void *blob = gd->fdt_blob; int skipped; int count; @@ -168,7 +167,8 @@ int microcode_update_intel(void) skipped++; continue; } - wrmsr(MSR_IA32_UCODE_WRITE, (ulong)update.data, 0); + address = (ulong)update.data + UCODE_HEADER_LEN; + wrmsr(MSR_IA32_UCODE_WRITE, address, 0); rev = microcode_read_rev(); debug("microcode: updated to revision 0x%x date=%04x-%02x-%02x\n", rev, update.date_code & 0xffff, @@ -179,5 +179,9 @@ int microcode_update_intel(void) return -EFAULT; } count++; + if (!ucode_base) { + ucode_base = (ulong)update.data; + ucode_size = update.size; + } } while (1); } diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h index 29bf060..b30b8b6 100644 --- a/arch/x86/include/asm/microcode.h +++ b/arch/x86/include/asm/microcode.h @@ -11,6 +11,7 @@
/* This is a declaration for ucode_base in start.S */ extern u32 ucode_base; +extern u32 ucode_size;
/** * microcode_update_intel() - Apply microcode updates diff --git a/arch/x86/lib/fsp/fsp_car.S b/arch/x86/lib/fsp/fsp_car.S index fbe8aef..157600a 100644 --- a/arch/x86/lib/fsp/fsp_car.S +++ b/arch/x86/lib/fsp/fsp_car.S @@ -105,6 +105,8 @@ _dt_ucode_base_size: .globl ucode_base ucode_base: /* Declared in micrcode.h */ .long 0 /* microcode base */ +.globl ucode_size +ucode_size: /* Declared in micrcode.h */ .long 0 /* microcode size */ .long CONFIG_SYS_MONITOR_BASE /* code region base */ .long CONFIG_SYS_MONITOR_LEN /* code region size */