summaryrefslogtreecommitdiff
path: root/src/soc/amd/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/amd/common')
-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
3 files changed, 47 insertions, 43 deletions
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);
}