From 3a795e0b23c812d5a576fbb44b20668190334ad6 Mon Sep 17 00:00:00 2001 From: Matt DeVillier Date: Fri, 28 Jul 2023 13:43:36 -0500 Subject: [PATCH] soc/amd/common/cpu: Add Kconfig to program the PSP_ADDR MSR The PSP_ADDR_MSR is programmed into the BSP by FSP, but not always propagated to the other cores/APs. Add a hook to run a function which will read the MSR value from the BSP, and program it into the APs, guarded by a Kconfig. SoCs which wish to utilize this feature can select the Kconfig. BUG=b:293571109 BRANCH=skyrim TEST=tested with rest of patch train Change-Id: I14af1a092965254979df404d8d7d9a28a15b44b8 Signed-off-by: Matt DeVillier Reviewed-on: https://review.coreboot.org/c/coreboot/+/76808 Tested-by: build bot (Jenkins) Reviewed-by: Felix Held --- src/soc/amd/common/block/cpu/Kconfig | 6 +++++ src/soc/amd/common/block/cpu/cpu.c | 34 ++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/soc/amd/common/block/cpu/Kconfig b/src/soc/amd/common/block/cpu/Kconfig index 03a3b7295b..6c5329aa9b 100644 --- a/src/soc/amd/common/block/cpu/Kconfig +++ b/src/soc/amd/common/block/cpu/Kconfig @@ -106,6 +106,12 @@ config SOC_AMD_COMMON_BLOCK_TSC frequency of AMD family 17h, 19h and 1Ah CPUs/APUs and to provide TSC-based monotonic timer functionality to the build. +config SOC_AMD_COMMON_BLOCK_CPU_SYNC_PSP_ADDR_MSR + bool + help + Select this option to have coreboot sync the PSP_ADDR_MSR from + the BSP to all APs. + config SOC_AMD_COMMON_BLOCK_UCODE bool help diff --git a/src/soc/amd/common/block/cpu/cpu.c b/src/soc/amd/common/block/cpu/cpu.c index c122474d81..13c98b1875 100644 --- a/src/soc/amd/common/block/cpu/cpu.c +++ b/src/soc/amd/common/block/cpu/cpu.c @@ -2,8 +2,12 @@ #include #include +#include #include +#include #include +#include +#include #include int get_cpu_count(void) @@ -17,6 +21,35 @@ unsigned int get_threads_per_core(void) >> CPUID_EBX_THREADS_SHIFT); } +/* Being called via mp_run_on_all_cpus() ensures this will run on the BSP first, then APs */ +static void sync_psp_addr_msr(void *unused) +{ + static msr_t psp_addr_base; + msr_t msr_temp; + + if (psp_addr_base.raw == 0ul) { + msr_temp = rdmsr(PSP_ADDR_MSR); + if (msr_temp.raw == 0ul) { + printk(BIOS_ERR, "PSP_ADDR_MSR on BSP is 0; cannot program MSR on APs\n"); + return; + } + psp_addr_base.lo = msr_temp.lo; + printk(BIOS_SPEW, "Read PSP_ADDR_MSR 0x%x from BSP\n", psp_addr_base.lo); + } else { + msr_temp = rdmsr(PSP_ADDR_MSR); + if (msr_temp.raw == 0ul) { + wrmsr(PSP_ADDR_MSR, psp_addr_base); + printk(BIOS_SPEW, "Wrote PSP_ADDR_MSR 0x%x to AP\n", psp_addr_base.lo); + } + } +} + +static void post_mp_init(struct device *unused) +{ + if (CONFIG(SOC_AMD_COMMON_BLOCK_CPU_SYNC_PSP_ADDR_MSR)) + mp_run_on_all_cpus(sync_psp_addr_msr, NULL); +} + struct device_operations amd_cpu_bus_ops = { .read_resources = noop_read_resources, .set_resources = noop_set_resources, @@ -24,4 +57,5 @@ struct device_operations amd_cpu_bus_ops = { #if CONFIG(HAVE_ACPI_TABLES) .acpi_fill_ssdt = generate_cpu_entries, #endif + .final = post_mp_init, };