1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 #include <acpi/acpi.h>
4 #include <amdblocks/cpu.h>
5 #include <console/console.h>
6 #include <cpu/amd/cpuid.h>
7 #include <cpu/amd/msr.h>
8 #include <cpu/cpu.h>
9 #include <cpu/x86/mp.h>
10 #include <cpu/x86/msr.h>
11 #include <device/device.h>
12
get_cpu_count(void)13 int get_cpu_count(void)
14 {
15 return 1 + (cpuid_ecx(0x80000008) & 0xff);
16 }
17
get_threads_per_core(void)18 unsigned int get_threads_per_core(void)
19 {
20 return 1 + ((cpuid_ebx(CPUID_EBX_CORE_ID) & CPUID_EBX_THREADS_MASK)
21 >> CPUID_EBX_THREADS_SHIFT);
22 }
23
24 /* Being called via mp_run_on_all_cpus() ensures this will run on the BSP first, then APs */
sync_psp_addr_msr(void * unused)25 static void sync_psp_addr_msr(void *unused)
26 {
27 static msr_t psp_addr_base;
28 msr_t msr_temp;
29
30 if (psp_addr_base.raw == 0ul) {
31 msr_temp = rdmsr(PSP_ADDR_MSR);
32 if (msr_temp.raw == 0ul) {
33 printk(BIOS_ERR, "PSP_ADDR_MSR on BSP is 0; cannot program MSR on APs\n");
34 return;
35 }
36 psp_addr_base.lo = msr_temp.lo;
37 printk(BIOS_SPEW, "Read PSP_ADDR_MSR 0x%x from BSP\n", psp_addr_base.lo);
38 } else {
39 msr_temp = rdmsr(PSP_ADDR_MSR);
40 if (msr_temp.raw == 0ul) {
41 wrmsr(PSP_ADDR_MSR, psp_addr_base);
42 printk(BIOS_SPEW, "Wrote PSP_ADDR_MSR 0x%x to AP\n", psp_addr_base.lo);
43 }
44 }
45 }
46
post_mp_init(struct device * unused)47 static void post_mp_init(struct device *unused)
48 {
49 if (CONFIG(SOC_AMD_COMMON_BLOCK_CPU_SYNC_PSP_ADDR_MSR))
50 mp_run_on_all_cpus(sync_psp_addr_msr, NULL);
51 }
52
53 struct device_operations amd_cpu_bus_ops = {
54 .read_resources = noop_read_resources,
55 .set_resources = noop_set_resources,
56 .init = mp_cpu_bus_init,
57 #if CONFIG(HAVE_ACPI_TABLES)
58 .acpi_fill_ssdt = generate_cpu_entries,
59 #endif
60 .final = post_mp_init,
61 };
62