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 -#include +#include #include #include #include #include #include #include +#include #include -#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)