diff options
author | Fred Reitberger <reitbergerfred@gmail.com> | 2022-04-12 13:44:34 -0400 |
---|---|---|
committer | Felix Held <felix-coreboot@felixheld.de> | 2022-06-07 12:47:40 +0000 |
commit | 96f7b96866b0bce7a1323c4da478f838f884383f (patch) | |
tree | 14aacbd95bf6c5b76a620b15eded0b3ad018f9fb /src/soc | |
parent | 749f5bd333e34a61d1ea09d8f3b2fd8feb172f6b (diff) |
soc/amd/common/block/cpu/: Make ucode update more generic
Use the equivalent cpuid in the microcode header to name the update file
in cbfs. This allows the SOC to directly locate its microcode file when
there are multiple processor revisions.
TEST: Loaded a chausie with sabrina, cezanne, and picasso microcode
files and booted. Verified that only the sabrina microcode file was
successfully loaded
Change-Id: I84a2480cf8274d53ffdab7864135c1bf001241e6
Signed-off-by: Fred Reitberger <reitbergerfred@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/63589
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Diffstat (limited to 'src/soc')
-rw-r--r-- | src/soc/amd/cezanne/Makefile.inc | 2 | ||||
-rw-r--r-- | src/soc/amd/common/block/cpu/Kconfig | 1 | ||||
-rw-r--r-- | src/soc/amd/common/block/cpu/Makefile.inc | 16 | ||||
-rw-r--r-- | src/soc/amd/common/block/cpu/update_microcode.c | 73 | ||||
-rw-r--r-- | src/soc/amd/picasso/Makefile.inc | 2 | ||||
-rw-r--r-- | src/soc/amd/sabrina/Makefile.inc | 2 |
6 files changed, 50 insertions, 46 deletions
diff --git a/src/soc/amd/cezanne/Makefile.inc b/src/soc/amd/cezanne/Makefile.inc index 302deaa4ce..c46c577e89 100644 --- a/src/soc/amd/cezanne/Makefile.inc +++ b/src/soc/amd/cezanne/Makefile.inc @@ -300,6 +300,6 @@ apu/amdfw_b-position := $(AMD_FW_AB_POSITION) apu/amdfw_b-type := raw endif -cpu_microcode_bins += $(wildcard ${FIRMWARE_LOCATION}/UcodePatch_*.bin) +amd_microcode_bins += $(wildcard ${FIRMWARE_LOCATION}/UcodePatch_*.bin) endif # ($(CONFIG_SOC_AMD_CEZANNE),y) diff --git a/src/soc/amd/common/block/cpu/Kconfig b/src/soc/amd/common/block/cpu/Kconfig index 56e922d39b..1da60e5bfe 100644 --- a/src/soc/amd/common/block/cpu/Kconfig +++ b/src/soc/amd/common/block/cpu/Kconfig @@ -73,7 +73,6 @@ config SOC_AMD_COMMON_BLOCK_TSC_FAM17H_19H config SOC_AMD_COMMON_BLOCK_UCODE bool - select SUPPORT_CPU_UCODE_IN_CBFS help Builds in support for loading uCode. diff --git a/src/soc/amd/common/block/cpu/Makefile.inc b/src/soc/amd/common/block/cpu/Makefile.inc index f402e703c9..34685689de 100644 --- a/src/soc/amd/common/block/cpu/Makefile.inc +++ b/src/soc/amd/common/block/cpu/Makefile.inc @@ -1,2 +1,18 @@ subdirs-y += ./* ramstage-$(CONFIG_SOC_AMD_COMMON_BLOCK_UCODE) += update_microcode.c + +ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_UCODE),y) +define add-ucode-as-cbfs +cbfs-files-y += cpu_microcode_$(2).bin +cpu_microcode_$(2).bin-file := $(1) +cpu_microcode_$(2).bin-type := microcode + +ifeq ($(CONFIG_SOC_AMD_COMMON_BLOCK_LPC_SPI_DMA),y) +cpu_microcode_$(2).bin-align := 64 +else +cpu_microcode_$(2).bin-align := 16 +endif +endef + +$(foreach ucode,$(amd_microcode_bins),$(eval $(call add-ucode-as-cbfs,$(ucode),$(shell hexdump -n 2 -s 0x18 -e '"%x"' $(ucode))))) +endif diff --git a/src/soc/amd/common/block/cpu/update_microcode.c b/src/soc/amd/common/block/cpu/update_microcode.c index 33b244d192..79aaaf5d65 100644 --- a/src/soc/amd/common/block/cpu/update_microcode.c +++ b/src/soc/amd/common/block/cpu/update_microcode.c @@ -1,22 +1,18 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include <arch/cpu.h> -#include <stdint.h> +#include <types.h> #include <cpu/amd/microcode.h> #include <commonlib/helpers.h> #include <console/console.h> #include <cpu/x86/msr.h> #include <cpu/amd/msr.h> #include <cbfs.h> +#include <stdio.h> #include <timestamp.h> -#define CPU_MICROCODE_BLOB_NAME "cpu_microcode_blob.bin" - -_Static_assert(CONFIG_SOC_AMD_COMMON_BLOCK_UCODE_SIZE > 0, - "SOC_AMD_COMMON_BLOCK_UCODE_SIZE is not set"); - -#define MPB_MAX_SIZE CONFIG_SOC_AMD_COMMON_BLOCK_UCODE_SIZE -#define MPB_DATA_OFFSET 32 +#define CPU_MICROCODE_BLOB_NAME "cpu_microcode_XXXX.bin" +#define CPU_MICROCODE_BLOB_FORMAT "cpu_microcode_%04x.bin" struct microcode { uint32_t date_code; @@ -34,12 +30,8 @@ struct microcode { uint8_t chipset2_rev_id; uint8_t reserved2[4]; - - uint8_t m_patch_data[MPB_MAX_SIZE-MPB_DATA_OFFSET]; } __packed; -_Static_assert(sizeof(struct microcode) == MPB_MAX_SIZE, "microcode size is invalid"); - static void apply_microcode_patch(const struct microcode *m) { uint32_t new_patch_id; @@ -50,18 +42,17 @@ static void apply_microcode_patch(const struct microcode *m) wrmsr(MSR_PATCH_LOADER, msr); - printk(BIOS_DEBUG, "microcode: patch id to apply = 0x%08x\n", - m->patch_id); + printk(BIOS_DEBUG, "microcode: patch id to apply = 0x%08x\n", m->patch_id); msr = rdmsr(IA32_BIOS_SIGN_ID); new_patch_id = msr.lo; if (new_patch_id == m->patch_id) printk(BIOS_INFO, "microcode: being updated to patch id = 0x%08x succeeded\n", - new_patch_id); + new_patch_id); else printk(BIOS_ERR, "microcode: being updated to patch id = 0x%08x failed\n", - new_patch_id); + new_patch_id); } static uint16_t get_equivalent_processor_rev_id(void) @@ -71,15 +62,11 @@ static uint16_t get_equivalent_processor_rev_id(void) return (uint16_t)((cpuid_family & 0xff0000) >> 8 | (cpuid_family & 0xff)); } -static const struct microcode *find_microcode(const struct microcode *ucode, size_t ucode_len) +static const struct microcode *find_microcode(const struct microcode *ucode, + uint16_t equivalent_processor_rev_id) { - uint16_t equivalent_processor_rev_id = get_equivalent_processor_rev_id(); - const struct microcode *m; - - for (m = ucode; m < ucode + ucode_len / MPB_MAX_SIZE; m++) { - if (m->processor_rev_id == equivalent_processor_rev_id) - return m; - } + if (ucode->processor_rev_id == equivalent_processor_rev_id) + return ucode; printk(BIOS_WARNING, "Failed to find microcode for processor rev: %hx.\n", equivalent_processor_rev_id); @@ -89,39 +76,37 @@ static const struct microcode *find_microcode(const struct microcode *ucode, siz void amd_update_microcode_from_cbfs(void) { - static struct microcode ucode_cache; + static const struct microcode *ucode_cache; static bool cache_valid; - struct microcode *ucode_list; - const struct microcode *matching_ucode; - size_t ucode_len; + struct microcode *ucode; + char name[] = CPU_MICROCODE_BLOB_NAME; + uint16_t equivalent_processor_rev_id; /* Cache the buffer so each CPU doesn't need to read the uCode from flash */ + /* Note that this code assumes all cores are the same */ if (!cache_valid) { timestamp_add_now(TS_READ_UCODE_START); - ucode_list = cbfs_map(CPU_MICROCODE_BLOB_NAME, &ucode_len); - if (!ucode_list) { - printk(BIOS_WARNING, - CPU_MICROCODE_BLOB_NAME " not found. Skipping updates.\n"); + equivalent_processor_rev_id = get_equivalent_processor_rev_id(); + snprintf(name, sizeof(name), CPU_MICROCODE_BLOB_FORMAT, equivalent_processor_rev_id); + ucode = cbfs_map(name, NULL); + if (!ucode) { + printk(BIOS_WARNING, "%s not found. Skipping updates.\n", name); return; } - matching_ucode = find_microcode(ucode_list, ucode_len); + ucode_cache = find_microcode(ucode, equivalent_processor_rev_id); - if (!matching_ucode) { - cbfs_unmap(ucode_list); + if (!ucode_cache) { + cbfs_unmap(ucode); return; } - ucode_cache = *matching_ucode; cache_valid = true; - - cbfs_unmap(ucode_list); - timestamp_add_now(TS_READ_UCODE_END); } - apply_microcode_patch(&ucode_cache); + apply_microcode_patch(ucode_cache); } void preload_microcode(void) @@ -129,6 +114,10 @@ void preload_microcode(void) if (!CONFIG(CBFS_PRELOAD)) return; - printk(BIOS_DEBUG, "Preloading microcode %s\n", CPU_MICROCODE_BLOB_NAME); - cbfs_preload(CPU_MICROCODE_BLOB_NAME); + char name[] = CPU_MICROCODE_BLOB_NAME; + uint16_t equivalent_processor_rev_id = get_equivalent_processor_rev_id(); + + snprintf(name, sizeof(name), CPU_MICROCODE_BLOB_FORMAT, equivalent_processor_rev_id); + printk(BIOS_DEBUG, "Preloading microcode %s\n", name); + cbfs_preload(name); } diff --git a/src/soc/amd/picasso/Makefile.inc b/src/soc/amd/picasso/Makefile.inc index 8eef1538cc..e4b78e5e83 100644 --- a/src/soc/amd/picasso/Makefile.inc +++ b/src/soc/amd/picasso/Makefile.inc @@ -292,6 +292,6 @@ apu/amdfw_b-position := $(AMD_FW_AB_POSITION) apu/amdfw_b-type := raw endif -cpu_microcode_bins += $(wildcard ${FIRMWARE_LOCATION}/UcodePatch_*.bin) +amd_microcode_bins := $(wildcard ${FIRMWARE_LOCATION}/UcodePatch_*.bin) endif # ($(CONFIG_SOC_AMD_PICASSO),y) diff --git a/src/soc/amd/sabrina/Makefile.inc b/src/soc/amd/sabrina/Makefile.inc index 4163cef989..f256f22b17 100644 --- a/src/soc/amd/sabrina/Makefile.inc +++ b/src/soc/amd/sabrina/Makefile.inc @@ -291,6 +291,6 @@ apu/amdfw_b-position := $(AMD_FW_AB_POSITION) apu/amdfw_b-type := raw endif -cpu_microcode_bins += $(wildcard ${FIRMWARE_LOCATION}/UcodePatch_*.bin) +amd_microcode_bins += $(wildcard ${FIRMWARE_LOCATION}/UcodePatch_*.bin) endif # ($(CONFIG_SOC_AMD_SABRINA),y) |