xref: /aosp_15_r20/external/coreboot/src/soc/amd/common/block/cpu/cpu.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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