[U-Boot] [PATCH 21/22] x86: ivybridge: Update microcode early in boot
Simon Glass
sjg at chromium.org
Thu Jan 1 23:37:36 CET 2015
Hi Bin,
On 30 December 2014 at 23:45, Bin Meng <bmeng.cn at gmail.com> wrote:
> Hi Simon,
>
> On Sun, Dec 28, 2014 at 10:20 AM, Simon Glass <sjg at chromium.org> wrote:
>> At present the normal update (which happens much later) does not work. This
>> seems to have something to do with the 'no eviction' mode in the CAR, or at
>> least moving the microcode update after that causes it not to work.
>>
>> For now, do an update early on so that it definitely works. Also refuse to
>> continue unless the microcode update check (later in boot) is successful.
>>
>> Signed-off-by: Simon Glass <sjg at chromium.org>
>> ---
>>
>> arch/x86/cpu/ivybridge/car.S | 14 ++++++++++++++
>> arch/x86/cpu/ivybridge/cpu.c | 2 +-
>> arch/x86/cpu/ivybridge/microcode_intel.c | 9 +++++++--
>> arch/x86/dts/link.dts | 3 ---
>> 4 files changed, 22 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/x86/cpu/ivybridge/car.S b/arch/x86/cpu/ivybridge/car.S
>> index 6e7e1e4..95da087 100644
>> --- a/arch/x86/cpu/ivybridge/car.S
>> +++ b/arch/x86/cpu/ivybridge/car.S
>> @@ -45,6 +45,14 @@ car_init:
>> movl $0xFEE00300, %esi
>> movl %eax, (%esi)
>>
>> + /* TODO: Load microcode later - the 'no eviction' mode breaks this */
>> + movl $0x79, %ecx
>
> Replace 0x79 to MSR_IA32_UCODE_WRITE from msr-index.h
>
>> + xorl %edx, %edx
>> + movl $_dt_ucode_base_size, %eax
>> + movl (%eax), %eax
>> + addl $0x30, %eax
>
> And here 0x30 to something like MICROCODE_HEADER_LEN.
>
>> + wrmsr
>> +
>> post_code(POST_CAR_SIPI)
>> /* Zero out all fixed range and variable range MTRRs */
>> movl $mtrr_table, %esi
>> @@ -228,3 +236,9 @@ mtrr_table:
>> .word 0x20C, 0x20D, 0x20E, 0x20F
>> .word 0x210, 0x211, 0x212, 0x213
>> mtrr_table_end:
>> +
>> + .align 4
>> +_dt_ucode_base_size:
>> + /* These next two fields are filled in by ifdtool */
>> + .long 0 /* microcode base */
>> + .long 0 /* microcode size */
>> diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
>> index 0543e06..e925310 100644
>> --- a/arch/x86/cpu/ivybridge/cpu.c
>> +++ b/arch/x86/cpu/ivybridge/cpu.c
>> @@ -263,7 +263,7 @@ int print_cpuinfo(void)
>> enable_lapic();
>>
>> ret = microcode_update_intel();
>
> Since we already did the microcode update in car_init, why should we
> do this again here?
The car_init() version is a work-around that I would like to remove.
This update actually checks that it happened and fails with an error
if not. For car we don't have a way yet of displaying an error.
>
>> - if (ret && ret != -ENOENT && ret != -EEXIST)
>> + if (ret)
>> return ret;
>>
>> /* Enable upper 128bytes of CMOS */
>> diff --git a/arch/x86/cpu/ivybridge/microcode_intel.c b/arch/x86/cpu/ivybridge/microcode_intel.c
>> index 0817751..c012820 100644
>> --- a/arch/x86/cpu/ivybridge/microcode_intel.c
>> +++ b/arch/x86/cpu/ivybridge/microcode_intel.c
>> @@ -120,6 +120,7 @@ int microcode_update_intel(void)
>> int count;
>> int node;
>> int ret;
>> + int rev;
>>
>> microcode_read_cpu(&cpu);
>> node = 0;
>> @@ -147,12 +148,16 @@ int microcode_update_intel(void)
>> skipped++;
>> continue;
>> }
>> - ret = microcode_read_rev();
>> wrmsr(0x79, (ulong)update.data, 0);
>> + rev = microcode_read_rev();
>> debug("microcode: updated to revision 0x%x date=%04x-%02x-%02x\n",
>> - microcode_read_rev(), update.date_code & 0xffff,
>> + rev, update.date_code & 0xffff,
>> (update.date_code >> 24) & 0xff,
>> (update.date_code >> 16) & 0xff);
>> + if (update.update_revision != rev) {
>> + printf("Microcode update failed\n");
>> + return -EFAULT;
>> + }
>> count++;
>> } while (1);
>> }
>> diff --git a/arch/x86/dts/link.dts b/arch/x86/dts/link.dts
>> index a739080..1ebc334 100644
>> --- a/arch/x86/dts/link.dts
>> +++ b/arch/x86/dts/link.dts
>> @@ -214,9 +214,6 @@
>>
>> microcode {
>> update at 0 {
>> -#include "microcode/m12206a7_00000029.dtsi"
>> - };
>> - update at 1 {
>> #include "microcode/m12306a9_0000001b.dtsi"
>> };
>> };
>> --
>
Regards,
Simon
More information about the U-Boot
mailing list