summaryrefslogtreecommitdiff
path: root/src/cpu/intel/microcode
diff options
context:
space:
mode:
Diffstat (limited to 'src/cpu/intel/microcode')
-rw-r--r--src/cpu/intel/microcode/Kconfig77
-rw-r--r--src/cpu/intel/microcode/Makefile.inc20
-rw-r--r--src/cpu/intel/microcode/microcode.c15
3 files changed, 108 insertions, 4 deletions
diff --git a/src/cpu/intel/microcode/Kconfig b/src/cpu/intel/microcode/Kconfig
index f5f9c761e8..4640c16991 100644
--- a/src/cpu/intel/microcode/Kconfig
+++ b/src/cpu/intel/microcode/Kconfig
@@ -16,3 +16,80 @@ config RELOAD_MICROCODE_PATCH
This feature is mostly required with Intel latest generation
processors starting with Alder Lake (with modified MCHECK init
flow).
+
+config CPU_INTEL_MICROCODE_CBFS_SPLIT_BINS
+ bool "For Intel CPU, include microcode per CPUID into CBFS"
+ depends on CBFS_VERIFICATION && !MICROCODE_UPDATE_PRE_RAM
+ default n
+ help
+ This option controls whether to include external microcode binaries per
+ CPUID in CBFS.
+
+ The current approach of loading microcode blobs post CPU reset is to search
+ the unified blob in the CBFS and then perform the CBFS verification. The bigger
+ the unified microcode blob in size the longer it takes to perform the verification.
+
+ Select this option to store the split microcode blobs per CPUID in the CBFS.
+ As the microcode blobs will be divided into smaller chunks per CPUID, which will
+ reduce the overall search, verify and load time.
+
+ The microcode file may be removed from the ROM image at a later
+ time with cbfstool, if desired.
+
+ If unsure, and applicable, select "Generate from tree"
+
+config CPU_INTEL_UCODE_SPLIT_BINARIES
+ string "Specify the split microcode blob directory path"
+ depends on CPU_INTEL_MICROCODE_CBFS_SPLIT_BINS
+ default ""
+ help
+ Provide the split microcode blob directory path if
+ CPU_INTEL_MICROCODE_CBFS_SPLIT_BINS config is enabled.
+
+ CPU_INTEL_MICROCODE_CBFS_SPLIT_BINS config is allowed to pack the individual microcode
+ patch file per CPUID inside the CBFS.
+
+ Intel distributes CPU microcode updates based on CPUID as part of the github repository
+ in INC format and expects it also getting used in binary form.
+
+ For example: Intel CPU microcode `m506e3.inc` is getting converted into F-MO-S
+ (06-5e-03) binary file for Linux kernel.
+
+ `MicrocodeConverter` is an Intel-provided tool for converting binary form MCU into
+ several other common formats for integration.
+
+ Implementation logic behind CPU_INTEL_MICROCODE_CBFS_SPLIT_BINS config relies on
+ converting Intel CPU microcode INC file into the binary file as per format specified
+ here `cpu_microcode_$(CPUID).bin`. For example: Intel CPU microcode `m506e3.inc` to
+ convert into `cpu_microcode_506e3.bin` binary file for coreboot to integrate if
+ CPU_INTEL_MICROCODE_CBFS_SPLIT_BINS config is enabled.
+
+ This config provides the directory name (including path) that holds the split microcode
+ binary files per CPUID as mentioned above for each coreboot variants. For example: if
+ google/kunimitsu had built with Intel SkyLake processor with CPUID `506e3` and `506e4`
+ then CPU_INTEL_UCODE_SPLIT_BINARIES refers to the directory path that holds the split
+ microcode binary files aka `cpu_microcode_506e3.bin` and `cpu_microcode_506e4.bin`.
+
+ CONFIG_CPU_UCODE_SPLIT_BINARIES="3rdparty/blobs/mainboard/google/kunimitsu/microcode_inputs/kunimitsu"
+ Refer to the file representation below:
+ |---3rdparty
+ | |--- blobs
+ | | |--- mainboard
+ | | | |--- google
+ | | | | |--- kunimitsu
+ | | | | | |--- microcode_inputs
+ | | | | | | |--- kunimitsu
+ | | | | | | | |--- cpu_microcode_506e3.bin
+ | | | | | | | |--- cpu_microcode_506e4.bin
+
+ Users of this config option requires to manually place the microcode binary files per
+ CPUIDs as per the given format (`cpu_microcode_$(CPUID).bin`) in a directory.
+ Finally specify the microcode binary directory path using CPU_UCODE_SPLIT_BINARIES
+ config.
+
+ At runtime (either from romstage/ramstage), coreboot read the CPUID and search for the
+ `cpu_microcode_$(CPUID).bin` file (in this example: cpu_microcode_506e3.bin) inside RW
+ CBFS. Eventually able to locate the appropriate `cpu_microcode_$(CPUID).bin` file and
+ perform the verification prior loading into the CPUs (BSP and APs).
+
+ If unsure, leave this blank.
diff --git a/src/cpu/intel/microcode/Makefile.inc b/src/cpu/intel/microcode/Makefile.inc
index 119c38fac2..4ea8227e13 100644
--- a/src/cpu/intel/microcode/Makefile.inc
+++ b/src/cpu/intel/microcode/Makefile.inc
@@ -3,3 +3,23 @@ bootblock-$(CONFIG_MICROCODE_UPDATE_PRE_RAM) += microcode_asm.S
bootblock-$(CONFIG_SUPPORT_CPU_UCODE_IN_CBFS) += microcode.c
ramstage-$(CONFIG_SUPPORT_CPU_UCODE_IN_CBFS) += microcode.c
romstage-$(CONFIG_SUPPORT_CPU_UCODE_IN_CBFS) += microcode.c
+
+# Pack individual microcodes per CPUID from CONFIG_CPU_INTEL_UCODE_SPLIT_BINARIES directory into the CBFS.
+ifeq ($(CONFIG_CPU_INTEL_MICROCODE_CBFS_SPLIT_BINS),y)
+microcode-params-dir := $(call strip_quotes,$(CONFIG_CPU_INTEL_UCODE_SPLIT_BINARIES))/
+microcode-params := $(shell find "$(microcode-params-dir)" -type f -exec basename {} \;)
+
+# Make "cpu_microcode_$(CPUID).bin" file entry into the FIT table
+$(call add_intermediate, add_mcu_fit, set_fit_ptr $(IFITTOOL))
+ $(foreach params, $(microcode-params), $(shell $(IFITTOOL) -f $< -a -n $(params) -t 1 \
+ -s $(CONFIG_CPU_INTEL_NUM_FIT_ENTRIES) -r COREBOOT)) true
+
+# Add "cpu_microcode_$(CPUID).bin" file into the CBFS
+$(foreach params,$(microcode-params), \
+ $(eval cbfs-files-y += $(params)) \
+ $(eval $(params)-file := $(microcode-params-dir)/$(params)) \
+ $(eval $(params)-type := microcode) \
+ $(eval $(params)-align := $(if $(filter y,$(CONFIG_SOC_AMD_COMMON_BLOCK_LPC_SPI_DMA)),64,16)) \
+)
+
+endif
diff --git a/src/cpu/intel/microcode/microcode.c b/src/cpu/intel/microcode/microcode.c
index 6f6e2f12d0..0d52bafb31 100644
--- a/src/cpu/intel/microcode/microcode.c
+++ b/src/cpu/intel/microcode/microcode.c
@@ -8,6 +8,7 @@
#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)
@@ -170,10 +171,6 @@ static const void *find_cbfs_microcode(void)
msr_t msr;
struct cpuinfo_x86 c;
- ucode_updates = cbfs_map(MICROCODE_CBFS_FILE, &microcode_len);
- if (ucode_updates == NULL)
- return NULL;
-
rev = read_microcode_rev();
eax = cpuid_eax(1);
get_fms(&c, eax);
@@ -188,6 +185,16 @@ static const void *find_cbfs_microcode(void)
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 */