xref: /aosp_15_r20/external/coreboot/src/include/cpu/intel/smm_reloc.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef __INTEL_SMM_RELOC_H__
4 #define __INTEL_SMM_RELOC_H__
5 
6 #include <console/console.h>
7 #include <types.h>
8 #include <cpu/x86/msr.h>
9 #include <cpu/x86/mtrr.h>
10 
11 struct smm_relocation_params {
12 	uintptr_t ied_base;
13 	size_t ied_size;
14 	msr_t smrr_base;
15 	msr_t smrr_mask;
16 	msr_t prmrr_base;
17 	msr_t prmrr_mask;
18 	msr_t uncore_prmrr_base;
19 	msr_t uncore_prmrr_mask;
20 	/*
21 	 * The smm_save_state_in_msrs field indicates if SMM save state
22 	 * locations live in MSRs. This indicates to the CPUs how to adjust
23 	 * the SMMBASE and IEDBASE
24 	 */
25 	int smm_save_state_in_msrs;
26 };
27 
28 extern struct smm_relocation_params smm_reloc_params;
29 
30 struct ied_header {
31 	char signature[10];
32 	u32 size;
33 	u8 reserved[34];
34 } __packed;
35 
36 /* These helpers are for performing SMM relocation. */
37 void northbridge_write_smram(u8 smram);
38 
39 void smm_close(void);
40 void smm_open(void);
41 void smm_lock(void);
42 void smm_relocate(void);
43 
44 /* The initialization of the southbridge is split into 2 components. One is
45  * for clearing the state in the SMM registers. The other is for enabling
46  * SMIs. They are split so that other work between the 2 actions. */
47 void smm_southbridge_clear_state(void);
48 
49 /* To be removed. */
50 void smm_initialize(void);
51 void smm_info(uintptr_t *perm_smbase, size_t *perm_smsize, size_t *smm_save_state_size);
52 void smm_relocation_handler(int cpu, uintptr_t curr_smbase, uintptr_t staggered_smbase);
53 
54 bool cpu_has_alternative_smrr(void);
55 
56 #define MSR_PRMRR_PHYS_BASE 0x1f4
57 #define MSR_PRMRR_PHYS_MASK 0x1f5
58 #define MSR_UNCORE_PRMRR_PHYS_BASE 0x2f4
59 #define MSR_UNCORE_PRMRR_PHYS_MASK 0x2f5
60 
write_smrr(struct smm_relocation_params * relo_params)61 static inline void write_smrr(struct smm_relocation_params *relo_params)
62 {
63 	printk(BIOS_DEBUG, "Writing SMRR. base = 0x%08x, mask=0x%08x\n",
64 	       relo_params->smrr_base.lo, relo_params->smrr_mask.lo);
65 	wrmsr(IA32_SMRR_PHYS_BASE, relo_params->smrr_base);
66 	wrmsr(IA32_SMRR_PHYS_MASK, relo_params->smrr_mask);
67 }
68 
write_prmrr(struct smm_relocation_params * relo_params)69 static inline void write_prmrr(struct smm_relocation_params *relo_params)
70 {
71 	printk(BIOS_DEBUG, "Writing PRMRR. base = 0x%08x, mask=0x%08x\n",
72 	       relo_params->prmrr_base.lo, relo_params->prmrr_mask.lo);
73 	wrmsr(MSR_PRMRR_PHYS_BASE, relo_params->prmrr_base);
74 	wrmsr(MSR_PRMRR_PHYS_MASK, relo_params->prmrr_mask);
75 }
76 
write_uncore_prmrr(struct smm_relocation_params * relo_params)77 static inline void write_uncore_prmrr(struct smm_relocation_params *relo_params)
78 {
79 	printk(BIOS_DEBUG,
80 	       "Writing UNCORE_PRMRR. base = 0x%08x, mask=0x%08x\n",
81 	       relo_params->uncore_prmrr_base.lo,
82 	       relo_params->uncore_prmrr_mask.lo);
83 	wrmsr(MSR_UNCORE_PRMRR_PHYS_BASE, relo_params->uncore_prmrr_base);
84 	wrmsr(MSR_UNCORE_PRMRR_PHYS_MASK, relo_params->uncore_prmrr_mask);
85 }
86 
87 #endif
88