summaryrefslogtreecommitdiff
path: root/src/soc
diff options
context:
space:
mode:
authorFred Reitberger <reitbergerfred@gmail.com>2022-04-12 13:44:34 -0400
committerFelix Held <felix-coreboot@felixheld.de>2022-06-07 12:47:40 +0000
commit96f7b96866b0bce7a1323c4da478f838f884383f (patch)
tree14aacbd95bf6c5b76a620b15eded0b3ad018f9fb /src/soc
parent749f5bd333e34a61d1ea09d8f3b2fd8feb172f6b (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.inc2
-rw-r--r--src/soc/amd/common/block/cpu/Kconfig1
-rw-r--r--src/soc/amd/common/block/cpu/Makefile.inc16
-rw-r--r--src/soc/amd/common/block/cpu/update_microcode.c73
-rw-r--r--src/soc/amd/picasso/Makefile.inc2
-rw-r--r--src/soc/amd/sabrina/Makefile.inc2
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)