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 <matt.devillier@amd.corp-partner.google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/76808
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Felix Held <felix-coreboot@felixheld.de>
diff --git a/src/soc/amd/common/block/cpu/Kconfig b/src/soc/amd/common/block/cpu/Kconfig
index 03a3b72..6c5329a 100644
--- a/src/soc/amd/common/block/cpu/Kconfig
+++ b/src/soc/amd/common/block/cpu/Kconfig
@@ -106,6 +106,12 @@
 	  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 c122474..13c98b1 100644
--- a/src/soc/amd/common/block/cpu/cpu.c
+++ b/src/soc/amd/common/block/cpu/cpu.c
@@ -2,8 +2,12 @@
 
 #include <acpi/acpi.h>
 #include <amdblocks/cpu.h>
+#include <console/console.h>
 #include <cpu/amd/cpuid.h>
+#include <cpu/amd/msr.h>
 #include <cpu/cpu.h>
+#include <cpu/x86/mp.h>
+#include <cpu/x86/msr.h>
 #include <device/device.h>
 
 int get_cpu_count(void)
@@ -17,6 +21,35 @@
 		    >> 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 @@
 #if CONFIG(HAVE_ACPI_TABLES)
 	.acpi_fill_ssdt	= generate_cpu_entries,
 #endif
+	.final = post_mp_init,
 };