summaryrefslogtreecommitdiff
path: root/src/soc/amd/common/block/cpu/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/amd/common/block/cpu/cpu.c')
-rw-r--r--src/soc/amd/common/block/cpu/cpu.c34
1 files changed, 34 insertions, 0 deletions
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 <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 @@ 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,
};