Arthur Heymans has uploaded this change for review. ( https://review.coreboot.org/27091
Change subject: [WIP]src/cpu/intel/car: Update microcode before setting up CARe ......................................................................
[WIP]src/cpu/intel/car: Update microcode before setting up CARe
This reuses cbfstool adding a FIT table with pointers to microcode headers meant for later Intel CPUs.
Change-Id: I8bd192f3f345651db0010239f99293ae63b00652 Signed-off-by: Arthur Heymans arthur@aheymans.xyz --- M src/cpu/intel/car/p4-netburst/cache_as_ram_bootblock.S A src/cpu/intel/microcode/microcode.S M src/cpu/intel/socket_LGA775/Kconfig M src/cpu/intel/socket_LGA775/Makefile.inc 4 files changed, 157 insertions(+), 6 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/91/27091/1
diff --git a/src/cpu/intel/car/p4-netburst/cache_as_ram_bootblock.S b/src/cpu/intel/car/p4-netburst/cache_as_ram_bootblock.S index 351f98c..40b7733 100644 --- a/src/cpu/intel/car/p4-netburst/cache_as_ram_bootblock.S +++ b/src/cpu/intel/car/p4-netburst/cache_as_ram_bootblock.S @@ -28,13 +28,9 @@ #define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE #define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
-.global bootblock_pre_c_entry +.global setup_car
- -.code32 -bootblock_pre_c_entry: -_cache_as_ram_setup: - +setup_car: cache_as_ram: post_code(0x20)
diff --git a/src/cpu/intel/microcode/microcode.S b/src/cpu/intel/microcode/microcode.S new file mode 100644 index 0000000..5114069 --- /dev/null +++ b/src/cpu/intel/microcode/microcode.S @@ -0,0 +1,149 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2018 Arthur Heymans arthur@aheymans.xyz + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <cpu/x86/post_code.h> + +.global bootblock_pre_c_entry + +.code32 +bootblock_pre_c_entry: +_update_bsp_microcode: + + /* Follow the _FIT_ pointer */ + movl $0xffffffc0, %edi + cmpl $0, (%edi) + je end_microcode_update + /* %edi points at the start of the FIT table */ + movl (%edi), %eax + movl %eax, %edi + +check_fit_header: + /* Check if the FIT table starts with "_FIT_ " */ + movl 0(%edi), %ebx + cmpl %ebx, fit_header + jne end_microcode_update + movl 4(%edi), %ebx + cmpl %ebx, fit_header+4 + jne end_microcode_update + +check_fit_entry_checksum_valid: + movb 14(%edi), %bl + cmpb $0x80, %bl + jne end_microcode_update + +check_fit_checksum: + /* All bytes of the table must add up to a 0 byte */ + movl 8(%edi), %ecx + shl $4, %ecx + movl %edi, %esi + movb $0, %al + +1: + movb (%esi), %dl + addb %dl, %al + inc %esi + dec %ecx + jnz 1b + + cmp $0, %al + + jne end_microcode_update + + mov $CONFIG_CPU_INTEL_NUM_FIT_ENTRIES, %ecx + +/* + * The microcode header is 24 bytes wide and has the following + * structure: + * Header Version : 32bit + * Update Revision : 32bit + * Date : 32bit + * Processor Signature : 32bit + * Checksum : 32bit + * Loader Revision : 32bit + * Processor Flags : 32bit + * Data Size : 32bit + * Total Size : 32bit + * Reserved : 96bit + * + * We only check if the Processor signature and flags match and check + * if the revision of the update is newer than what is installed + */ + +check_microcode_entry: + /* Save %ecx for loop, we need it for wrmsr */ + movl %ecx, %ebp + + /* Go to the next FIT entry */ + add $16, %edi + /* empty entry */ + cmpl $0, (%edi) + je end_microcode_update + /* Check fit entry for microcode type */ + + cmpb $0x01, 14(%edi) + jne end_microcode_update + + /* ESI holds the microcode pointer */ + movl 0(%edi), %esi + + /* Processor family+model signature=cpuid_eax(1) */ + movl $1, %eax + cpuid + cmpl 12(%esi), %eax + jne next_entry + + /* Processor flags + rdmsr 0x17 + pf = 1 << ((msr.hi >> 18) & 7) */ + movl $0x17, %ecx + rdmsr + shr $18, %edx + andl $7, %edx + movl $1, %eax + /* needs to be %cl for shl */ + mov %edx, %ecx + shl %cl, %eax + cmpl %eax, 24(%esi) + jnz next_entry + + /* Check if revision is higher than current */ + movl $0x8b, %ecx + rdmsr + cmpl 4(%esi), %edx + /* Don't upgrade if already greater or equal */ + jge end_microcode_update + + /* do actual update */ + mov %esi, %eax + add $48, %eax + xorl %edx, %edx + movl $0x79, %ecx + wrmsr + + jmp end_microcode_update + +next_entry: + movl %ebp, %ecx + dec %ecx + jnz check_microcode_entry + + +end_microcode_update: + jmp setup_car + +_update_bsp_microcode_end: + +fit_header: + .ascii "_FIT_ " diff --git a/src/cpu/intel/socket_LGA775/Kconfig b/src/cpu/intel/socket_LGA775/Kconfig index 9fec0d2..98d73d0 100644 --- a/src/cpu/intel/socket_LGA775/Kconfig +++ b/src/cpu/intel/socket_LGA775/Kconfig @@ -14,6 +14,11 @@ select MMX select SSE select SIPI_VECTOR_IN_ROM + select CPU_INTEL_FIRMWARE_INTERFACE_TABLE + +config CPU_INTEL_NUM_FIT_ENTRIES + int + default 45
config DCACHE_RAM_SIZE hex diff --git a/src/cpu/intel/socket_LGA775/Makefile.inc b/src/cpu/intel/socket_LGA775/Makefile.inc index a37a1ca..34afb74 100644 --- a/src/cpu/intel/socket_LGA775/Makefile.inc +++ b/src/cpu/intel/socket_LGA775/Makefile.inc @@ -16,6 +16,7 @@ ifneq ($(CONFIG_C_ENVIRONMENT_BOOTBLOCK),y) cpu_incs-y += $(src)/cpu/intel/car/p4-netburst/cache_as_ram.S else +bootblock-y += ../microcode/microcode.S bootblock-y += ../car/p4-netburst/cache_as_ram_bootblock.S bootblock-y += ../car/bootblock.c endif