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:
Zheng Bao 2020-06-09 09:47:06 +08:00 committed by Patrick Georgi
parent a5b7ddf940
commit 6ba591b447
4 changed files with 98 additions and 9 deletions

View File

@ -54,6 +54,7 @@ config CPU_SPECIFIC_OPTIONS
select FSP_USES_CB_STACK
select UDK_2017_BINDING
select HAVE_CF9_RESET
select SUPPORT_CPU_UCODE_IN_CBFS
config PRERAM_CBMEM_CONSOLE_SIZE
hex

View File

@ -64,6 +64,7 @@ ramstage-y += soc_util.c
ramstage-y += psp.c
ramstage-y += fsp_params.c
ramstage-y += config.c
ramstage-y += update_microcode.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_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_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)
# 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_FILE3)) \
$(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_SMUFW1_SUB1_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_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) \
@ -461,4 +453,6 @@ endif # ifeq ($(CONFIG_AMDFW_OUTSIDE_CBFS),y)
$(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)

View File

@ -16,6 +16,7 @@
#include <soc/smi.h>
#include <soc/iomap.h>
#include <console/console.h>
#include <cpu/amd/microcode.h>
/*
* MP and SMM loading initialization.
@ -108,6 +109,8 @@ static void model_17_init(struct device *dev)
{
check_mca();
setup_lapic();
amd_update_microcode_from_cbfs();
}
static struct device_operations cpu_dev_ops = {

View File

@ -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);
}