Hello Zheng Bao,
I'd like you to do a code review. Please visit
https://review.coreboot.org/c/coreboot/+/41719
to review the following change.
Change subject: Picasso: Load x86 microcode from CBFS modules ......................................................................
Picasso: Load x86 microcode from CBFS modules
Combine the Ucode binaries for 3 revisions of CPU into one CBFS module. "Include external microcode binary" need to be seleceted. The size of each binary is hardcoded.
Change-Id: Ib08a65b93c045afc97952a809670c85831c0faf7 Signed-off-by: Zheng Bao zheng.bao@amd.com --- M src/soc/amd/picasso/Kconfig M src/soc/amd/picasso/Makefile.inc M src/soc/amd/picasso/cpu.c A src/soc/amd/picasso/microcode_picasso.c A src/soc/amd/picasso/update_microcode.c 5 files changed, 194 insertions(+), 3 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/19/41719/1
diff --git a/src/soc/amd/picasso/Kconfig b/src/soc/amd/picasso/Kconfig index 27c0232..5c205e7 100644 --- a/src/soc/amd/picasso/Kconfig +++ b/src/soc/amd/picasso/Kconfig @@ -60,6 +60,8 @@ select FSP_USES_CB_STACK select UDK_2017_BINDING select HAVE_CF9_RESET + select SUPPORT_CPU_UCODE_IN_CBFS + select MICROCODE_BLOB_UNDISCLOSED
config AMD_FP5 def_bool y if !AMD_FT5 @@ -382,6 +384,9 @@ depends on HAVE_PSP_WHITELIST_FILE default "3rdparty/blobs/soc/amd/picasso/PSP/wtl-rvn.sbin"
+config CPU_UCODE_BINARIES + default "3rdparty/blobs/soc/amd/picasso/PSP/UcodePatch_PCO_B0.bin 3rdparty/blobs/soc/amd/picasso/PSP/UcodePatch_PCO_B1.bin 3rdparty/blobs/soc/amd/picasso/PSP/UcodePatch_RV2_A0.bin" + endmenu
endif # SOC_AMD_PICASSO diff --git a/src/soc/amd/picasso/Makefile.inc b/src/soc/amd/picasso/Makefile.inc index 9dda834..f88695e 100644 --- a/src/soc/amd/picasso/Makefile.inc +++ b/src/soc/amd/picasso/Makefile.inc @@ -81,6 +81,8 @@ ramstage-y += finalize.c ramstage-y += soc_util.c ramstage-y += psp.c +ramstage-y += update_microcode.c +ramstage-y += microcode_picasso.c
all-y += reset.c
@@ -367,9 +369,6 @@ $(OPT_PSP_PMUD_FILE2) \ $(OPT_PSP_PMUD_FILE3) \ $(OPT_PSP_PMUD_FILE4) \ - $(OPT_PSP_UCODE_FILE1) \ - $(OPT_PSP_UCODE_FILE2) \ - $(OPT_PSP_UCODE_FILE3) \ $(OPT_MP2CFG_FILE) \ $(OPT_ABL0_FILE) \ $(OPT_ABL1_FILE) \ diff --git a/src/soc/amd/picasso/cpu.c b/src/soc/amd/picasso/cpu.c index 2325994..c0589f2 100644 --- a/src/soc/amd/picasso/cpu.c +++ b/src/soc/amd/picasso/cpu.c @@ -17,6 +17,7 @@ #include <soc/smi.h> #include <soc/iomap.h> #include <console/console.h> +#include <cpu/amd/microcode.h>
/* * MP and SMM loading initialization. @@ -109,6 +110,8 @@ { check_mca(); setup_lapic(); + + update_microcode(cpuid_eax(1)); }
static struct device_operations cpu_dev_ops = { @@ -117,6 +120,8 @@
static struct cpu_device_id cpu_table[] = { { X86_VENDOR_AMD, 0x810f80 }, + { X86_VENDOR_AMD, 0x810f81 }, + { X86_VENDOR_AMD, 0x820f81 }, { X86_VENDOR_AMD, PICASSO_CPUID }, { X86_VENDOR_AMD, RAVEN2_CPUID }, { 0, 0 }, diff --git a/src/soc/amd/picasso/microcode_picasso.c b/src/soc/amd/picasso/microcode_picasso.c new file mode 100644 index 0000000..fdc0bc6 --- /dev/null +++ b/src/soc/amd/picasso/microcode_picasso.c @@ -0,0 +1,135 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* This file is part of the coreboot project. */ + +#include <stdint.h> +#include <console/console.h> +#include <cpu/x86/msr.h> +#include <cpu/amd/microcode.h> +#include <cbfs.h> + +/* + * Values and header structure from: + * BKDG for AMD Family 16h Models 30h-3Fh Processors + * 52740 Rev 3.06 - March 18, 2016 + */ + +#define F16H_MPB_MAX_SIZE 3458 +#define F16H_MPB_DATA_OFFSET 32 + + /* + * STRUCTURE OF A MICROCODE (UCODE) FILE FOR FAM16h + * Microcode Patch Block + * Microcode Header + * Microcode "Blob" + * ... + * ... + * (end of file) + * + * + * MICROCODE HEADER (offset 0 bytes from start of file) + * Total size = 32 bytes + * [0:3] Date code (32 bits) + * [4:7] Patch level (32 bits) + * [8:9] Microcode patch data ID (16 bits) + * [10:15] Reserved (48 bits) + * [16:19] Chipset 1 device ID (32 bits) + * [20:23] Chipset 2 device ID (32 bits) + * [24:25] Processor Revisions ID (16 bits) + * [26] Chipset 1 revision ID (8 bits) + * [27] Chipset 2 revision ID (8 bits) + * [28:31] Reserved (32 bits) + * + * MICROCODE BLOB (offset += 32) + * Total size = m bytes + * + */ + +struct microcode { + uint32_t date_code; + uint32_t patch_id; + + uint16_t mc_patch_data_id; + uint8_t reserved1[6]; + + uint32_t chipset1_dev_id; + uint32_t chipset2_dev_id; + + uint16_t processor_rev_id; + + uint8_t chipset1_rev_id; + uint8_t chipset2_rev_id; + + uint8_t reserved2[4]; + + uint8_t m_patch_data[F16H_MPB_MAX_SIZE-F16H_MPB_DATA_OFFSET]; + +}; + +static void apply_microcode_patch(const struct microcode *m) +{ + uint32_t new_patch_id; + msr_t msr; + + /* apply patch */ + msr.hi = 0; + msr.lo = (uint32_t)m; + + wrmsr(0xc0010020, msr); + + printk(BIOS_DEBUG, "microcode: patch id to apply = 0x%08x\n", + m->patch_id); + + /* patch authentication */ + msr = rdmsr(0x8b); + new_patch_id = msr.lo; + + printk(BIOS_DEBUG, "microcode: updated to patch id = 0x%08x %s\n", + new_patch_id, + (new_patch_id == m->patch_id) ? "success" : "fail"); +} + +static void amd_update_microcode(const void *ucode, size_t ucode_len, + uint32_t equivalent_processor_rev_id) +{ + const struct microcode *m; + const uint8_t *c = ucode; + + m = (struct microcode *)c; + + while ((uint32_t)m < (uint32_t)c + ucode_len) { + if (m->processor_rev_id == equivalent_processor_rev_id) + apply_microcode_patch(m); + m = (struct microcode *)((uint32_t)m + 3200); + } +} + +void amd_update_microcode_from_cbfs(uint32_t equivalent_processor_rev_id) +{ + const void *ucode; + size_t ucode_len; + + if (equivalent_processor_rev_id == 0) { + printk(BIOS_DEBUG, "microcode: rev id not found. " + "Skipping microcode patch!\n"); + return; + } + ucode = cbfs_boot_map_with_leak("cpu_microcode_blob.bin", + CBFS_TYPE_MICROCODE, + &ucode_len); + if (!ucode) { + printk(BIOS_DEBUG, "cpu_microcode_blob.bin not found. " + "Skipping updates.\n"); + return; + } + + #if 0 + if (ucode_len > F16H_MPB_MAX_SIZE || + ucode_len < F16H_MPB_DATA_OFFSET) { + printk(BIOS_DEBUG, "microcode file invalid. Skipping " + "updates.\n"); + return; + } + #endif + + amd_update_microcode(ucode, ucode_len, equivalent_processor_rev_id); +} diff --git a/src/soc/amd/picasso/update_microcode.c b/src/soc/amd/picasso/update_microcode.c new file mode 100644 index 0000000..ab7da2c --- /dev/null +++ b/src/soc/amd/picasso/update_microcode.c @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* This file is part of the coreboot project. */ + +#include <stdint.h> +#include <cpu/amd/microcode.h> + +struct id_mapping { + uint32_t orig_id; + uint16_t new_id; +}; + +static u16 get_equivalent_processor_rev_id(u32 orig_id) +{ + static const struct id_mapping id_mapping_table[] = { + /* Family 16h */ + + /* TODO This equivalent processor revisions ID needs verification */ + { 0x730f01, 0x7301 }, + { 0x810f81, 0x8181 }, + { 0x820f01, 0x8201 }, + //{ 0x810f81, 0x8180 }, + + /* Array terminator */ + { 0xffffff, 0x0000 }, + }; + + u32 new_id; + int i; + + new_id = 0; + + for (i = 0; id_mapping_table[i].orig_id != 0xffffff; i++) { + if (id_mapping_table[i].orig_id == orig_id) { + new_id = id_mapping_table[i].new_id; + break; + } + } + + return new_id; +} + +void update_microcode(u32 cpu_deviceid) +{ + u32 equivalent_processor_rev_id = + get_equivalent_processor_rev_id(cpu_deviceid); + amd_update_microcode_from_cbfs(equivalent_processor_rev_id); +}