amd/picasso: Load x86 microcode from CBFS modules
Combine the Ucode binaries for 3 revisions of CPU into one CBFS module. This should be moved to the AMD common code later. BUG=b:153580119 TEST=mandolin Change-Id: Ib08a65b93c045afc97952a809670c85831c0faf7 Signed-off-by: Zheng Bao <zheng.bao@amd.com> Signed-off-by: Zheng Bao <fishbaozi@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/41719 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
This commit is contained in:
parent
a5b7ddf940
commit
6ba591b447
|
@ -54,6 +54,7 @@ config CPU_SPECIFIC_OPTIONS
|
||||||
select FSP_USES_CB_STACK
|
select FSP_USES_CB_STACK
|
||||||
select UDK_2017_BINDING
|
select UDK_2017_BINDING
|
||||||
select HAVE_CF9_RESET
|
select HAVE_CF9_RESET
|
||||||
|
select SUPPORT_CPU_UCODE_IN_CBFS
|
||||||
|
|
||||||
config PRERAM_CBMEM_CONSOLE_SIZE
|
config PRERAM_CBMEM_CONSOLE_SIZE
|
||||||
hex
|
hex
|
||||||
|
|
|
@ -64,6 +64,7 @@ ramstage-y += soc_util.c
|
||||||
ramstage-y += psp.c
|
ramstage-y += psp.c
|
||||||
ramstage-y += fsp_params.c
|
ramstage-y += fsp_params.c
|
||||||
ramstage-y += config.c
|
ramstage-y += config.c
|
||||||
|
ramstage-y += update_microcode.c
|
||||||
|
|
||||||
all-y += reset.c
|
all-y += reset.c
|
||||||
|
|
||||||
|
@ -281,9 +282,6 @@ OPT_PSP_PMUD_FILE1=$(call add_opt_prefix, $(PSP_PMUD_FILE1), --subprogram 0 --in
|
||||||
OPT_PSP_PMUD_FILE2=$(call add_opt_prefix, $(PSP_PMUD_FILE2), --subprogram 0 --instance 4 --pmu-data)
|
OPT_PSP_PMUD_FILE2=$(call add_opt_prefix, $(PSP_PMUD_FILE2), --subprogram 0 --instance 4 --pmu-data)
|
||||||
OPT_PSP_PMUD_FILE3=$(call add_opt_prefix, $(PSP_PMUD_FILE3), --subprogram 1 --instance 1 --pmu-data)
|
OPT_PSP_PMUD_FILE3=$(call add_opt_prefix, $(PSP_PMUD_FILE3), --subprogram 1 --instance 1 --pmu-data)
|
||||||
OPT_PSP_PMUD_FILE4=$(call add_opt_prefix, $(PSP_PMUD_FILE4), --subprogram 1 --instance 4 --pmu-data)
|
OPT_PSP_PMUD_FILE4=$(call add_opt_prefix, $(PSP_PMUD_FILE4), --subprogram 1 --instance 4 --pmu-data)
|
||||||
OPT_PSP_UCODE_FILE1=$(call add_opt_prefix, $(PSP_UCODE_FILE1), --instance 0 --ucode)
|
|
||||||
OPT_PSP_UCODE_FILE2=$(call add_opt_prefix, $(PSP_UCODE_FILE2), --instance 1 --ucode)
|
|
||||||
OPT_PSP_UCODE_FILE3=$(call add_opt_prefix, $(PSP_UCODE_FILE3), --instance 2 --ucode)
|
|
||||||
OPT_MP2CFG_FILE=$(call add_opt_prefix, $(PSP_MP2CFG_FILE), --mp2-config)
|
OPT_MP2CFG_FILE=$(call add_opt_prefix, $(PSP_MP2CFG_FILE), --mp2-config)
|
||||||
|
|
||||||
# Copy prebuild APCBs if they exist
|
# Copy prebuild APCBs if they exist
|
||||||
|
@ -342,9 +340,6 @@ $(obj)/amdfw.rom: $(call strip_quotes, $(CONFIG_AMD_PUBKEY_FILE)) \
|
||||||
$(call strip_quotes, $(PSP_PMUD_FILE2)) \
|
$(call strip_quotes, $(PSP_PMUD_FILE2)) \
|
||||||
$(call strip_quotes, $(PSP_PMUD_FILE3)) \
|
$(call strip_quotes, $(PSP_PMUD_FILE3)) \
|
||||||
$(call strip_quotes, $(PSP_PMUD_FILE4)) \
|
$(call strip_quotes, $(PSP_PMUD_FILE4)) \
|
||||||
$(call strip_quotes, $(PSP_UCODE_FILE1)) \
|
|
||||||
$(call strip_quotes, $(PSP_UCODE_FILE2)) \
|
|
||||||
$(call strip_quotes, $(PSP_UCODE_FILE3)) \
|
|
||||||
$(call strip_quotes, $(PSP_MP2CFG_FILE)) \
|
$(call strip_quotes, $(PSP_MP2CFG_FILE)) \
|
||||||
$(call strip_quotes, $(PSP_SMUFW1_SUB1_FILE)) \
|
$(call strip_quotes, $(PSP_SMUFW1_SUB1_FILE)) \
|
||||||
$(call strip_quotes, $(PSP_SMUFW1_SUB2_FILE)) \
|
$(call strip_quotes, $(PSP_SMUFW1_SUB2_FILE)) \
|
||||||
|
@ -399,9 +394,6 @@ $(obj)/amdfw.rom: $(call strip_quotes, $(CONFIG_AMD_PUBKEY_FILE)) \
|
||||||
$(OPT_PSP_PMUD_FILE2) \
|
$(OPT_PSP_PMUD_FILE2) \
|
||||||
$(OPT_PSP_PMUD_FILE3) \
|
$(OPT_PSP_PMUD_FILE3) \
|
||||||
$(OPT_PSP_PMUD_FILE4) \
|
$(OPT_PSP_PMUD_FILE4) \
|
||||||
$(OPT_PSP_UCODE_FILE1) \
|
|
||||||
$(OPT_PSP_UCODE_FILE2) \
|
|
||||||
$(OPT_PSP_UCODE_FILE3) \
|
|
||||||
$(OPT_MP2CFG_FILE) \
|
$(OPT_MP2CFG_FILE) \
|
||||||
$(OPT_ABL0_FILE) \
|
$(OPT_ABL0_FILE) \
|
||||||
$(OPT_ABL1_FILE) \
|
$(OPT_ABL1_FILE) \
|
||||||
|
@ -461,4 +453,6 @@ endif # ifeq ($(CONFIG_AMDFW_OUTSIDE_CBFS),y)
|
||||||
|
|
||||||
$(call strip_quotes,$(CONFIG_FSP_M_CBFS))-options := -b $(CONFIG_FSP_M_ADDR)
|
$(call strip_quotes,$(CONFIG_FSP_M_CBFS))-options := -b $(CONFIG_FSP_M_ADDR)
|
||||||
|
|
||||||
|
cpu_microcode_bins += $(wildcard 3rdparty/amd_blobs/picasso/PSP/UcodePatch_*.bin)
|
||||||
|
|
||||||
endif # ($(CONFIG_SOC_AMD_PICASSO),y)
|
endif # ($(CONFIG_SOC_AMD_PICASSO),y)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <soc/smi.h>
|
#include <soc/smi.h>
|
||||||
#include <soc/iomap.h>
|
#include <soc/iomap.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
|
#include <cpu/amd/microcode.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MP and SMM loading initialization.
|
* MP and SMM loading initialization.
|
||||||
|
@ -108,6 +109,8 @@ static void model_17_init(struct device *dev)
|
||||||
{
|
{
|
||||||
check_mca();
|
check_mca();
|
||||||
setup_lapic();
|
setup_lapic();
|
||||||
|
|
||||||
|
amd_update_microcode_from_cbfs();
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct device_operations cpu_dev_ops = {
|
static struct device_operations cpu_dev_ops = {
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
|
||||||
|
#include <stdint.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>
|
||||||
|
|
||||||
|
#define MPB_MAX_SIZE 3200
|
||||||
|
#define MPB_DATA_OFFSET 32
|
||||||
|
|
||||||
|
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[MPB_MAX_SIZE-MPB_DATA_OFFSET];
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
static void apply_microcode_patch(const struct microcode *m)
|
||||||
|
{
|
||||||
|
uint32_t new_patch_id;
|
||||||
|
msr_t msr;
|
||||||
|
|
||||||
|
msr.hi = (uint64_t)(uintptr_t)m >> 32;
|
||||||
|
msr.lo = (uintptr_t)m & 0xffffffff;
|
||||||
|
|
||||||
|
wrmsr(MSR_PATCH_LOADER, msr);
|
||||||
|
|
||||||
|
printk(BIOS_DEBUG, "microcode: patch id to apply = 0x%08x\n",
|
||||||
|
m->patch_id);
|
||||||
|
|
||||||
|
msr = rdmsr(MSR_PATCH_LEVEL);
|
||||||
|
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);
|
||||||
|
else
|
||||||
|
printk(BIOS_ERR, "microcode: being updated to patch id = 0x%08x failed\n",
|
||||||
|
new_patch_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t get_equivalent_processor_rev_id(void)
|
||||||
|
{
|
||||||
|
uint32_t cpuid_family = cpuid_eax(1);
|
||||||
|
|
||||||
|
return (uint16_t)((cpuid_family & 0xff0000) >> 8 | (cpuid_family & 0xff));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void amd_update_microcode(const void *ucode, size_t ucode_len,
|
||||||
|
uint16_t equivalent_processor_rev_id)
|
||||||
|
{
|
||||||
|
const struct microcode *m;
|
||||||
|
|
||||||
|
for (m = (struct microcode *)ucode;
|
||||||
|
m < (struct microcode *)ucode + ucode_len/MPB_MAX_SIZE; m++) {
|
||||||
|
if (m->processor_rev_id == equivalent_processor_rev_id)
|
||||||
|
apply_microcode_patch(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void amd_update_microcode_from_cbfs(void)
|
||||||
|
{
|
||||||
|
const void *ucode;
|
||||||
|
size_t ucode_len;
|
||||||
|
uint16_t equivalent_processor_rev_id = get_equivalent_processor_rev_id();
|
||||||
|
|
||||||
|
ucode = cbfs_boot_map_with_leak("cpu_microcode_blob.bin",
|
||||||
|
CBFS_TYPE_MICROCODE, &ucode_len);
|
||||||
|
if (!ucode) {
|
||||||
|
printk(BIOS_WARNING, "cpu_microcode_blob.bin not found. Skipping updates.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
amd_update_microcode(ucode, ucode_len, equivalent_processor_rev_id);
|
||||||
|
}
|
Loading…
Reference in New Issue