xref: /aosp_15_r20/external/coreboot/src/security/intel/stm/StmPlatformSmm.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: BSD-2-Clause */
2 
3 #include <security/intel/stm/StmApi.h>
4 #include <security/intel/stm/SmmStm.h>
5 #include <security/intel/stm/StmPlatformResource.h>
6 #include <security/tpm/tspi.h>
7 #include <cpu/x86/smm.h>
8 #include <cpu/x86/msr.h>
9 
10 #include <cbfs.h>
11 #include <console/console.h>
12 #include <stdbool.h>
13 #include <stdint.h>
14 #include <arch/rom_segs.h>
15 
16 /*
17  * Load STM image to MSEG
18  *
19  * @retval SUCCESS           STM is loaded to MSEG
20  */
load_stm_image(uintptr_t mseg)21 int load_stm_image(uintptr_t mseg)
22 {
23 	int status;
24 	void *mseg_base;
25 	uint32_t stm_buffer_size;
26 	uint32_t stm_image_size;
27 	bool stm_status;
28 
29 	STM_HEADER *stm_header;
30 
31 	// Extract STM image from FV
32 	mseg_base = (void *)mseg;
33 	stm_buffer_size = CONFIG_MSEG_SIZE;
34 	stm_image_size = 0;
35 
36 	memset((void *)mseg_base, 0, CONFIG_MSEG_SIZE); // clear the mseg
37 
38 	stm_image_size = cbfs_load("stm.bin", mseg_base, stm_buffer_size);
39 	printk(BIOS_DEBUG, "STM:loaded into mseg: 0x%p size: %u\n", mseg_base,
40 	       stm_image_size);
41 	/* status is number of bytes loaded */
42 	stm_status = stm_check_stm_image(mseg_base, stm_image_size);
43 
44 	if (!stm_status) {
45 		printk(BIOS_DEBUG, "STM: Error in STM image\n");
46 		return -1;
47 	}
48 
49 	stm_header = mseg_base;
50 
51 	stm_gen_4g_pagetable_x64((uint32_t)mseg_base
52 				 + stm_header->hw_stm_hdr.cr3_offset);
53 
54 	// Debug stuff
55 	printk(BIOS_DEBUG,
56 	       "STM: Header-Revision %d Features 0x%08x Cr3Offset 0x%08x\n",
57 	       stm_header->hw_stm_hdr.stm_header_revision,
58 	       stm_header->hw_stm_hdr.monitor_features,
59 	       stm_header->hw_stm_hdr.cr3_offset);
60 	printk(BIOS_DEBUG,
61 	       "STM: Header-StaticImageSize: %d  Cr3Location: 0x%08x\n",
62 	       stm_header->sw_stm_hdr.static_image_size,
63 	       ((uint32_t)mseg_base + stm_header->hw_stm_hdr.cr3_offset));
64 
65 	status = 0; // always return good for now
66 
67 	return status;
68 }
69 
70 struct descriptor {
71 	uint16_t limit;
72 	uintptr_t base;
73 } __packed;
74 
read_gdtr(struct descriptor * gdtr)75 static void read_gdtr(struct descriptor *gdtr)
76 {
77 	__asm__ __volatile__("sgdt %0" : "=m"(*gdtr));
78 }
79 
setup_smm_descriptor(void * smbase,int32_t apic_id,int32_t entry32_off)80 void setup_smm_descriptor(void *smbase, int32_t apic_id, int32_t entry32_off)
81 {
82 	struct descriptor gdtr;
83 	void *smbase_processor;
84 	//msr_t smbase_msr;
85 
86 	TXT_PROCESSOR_SMM_DESCRIPTOR *psd;
87 
88 	smbase_processor =  (void *)SMM_DEFAULT_BASE;//we are here
89 	psd = smbase + SMM_PSD_OFFSET;
90 
91 	printk(BIOS_DEBUG,
92 	"STM: Smm Descriptor setup: Smbase: %p Smbase_processor: %p Psd: %p\n",
93 		smbase,
94 		smbase_processor,
95 		psd);
96 
97 	memset(psd, 0, sizeof(TXT_PROCESSOR_SMM_DESCRIPTOR));
98 
99 	memcpy(&psd->signature, TXT_PROCESSOR_SMM_DESCRIPTOR_SIGNATURE, 8);
100 	psd->smm_descriptor_ver_major =
101 		TXT_PROCESSOR_SMM_DESCRIPTOR_VERSION_MAJOR;
102 	psd->smm_descriptor_ver_minor =
103 		TXT_PROCESSOR_SMM_DESCRIPTOR_VERSION_MINOR;
104 	psd->smm_smi_handler_rip =
105 		(uint64_t)((uintptr_t)smbase + SMM_ENTRY_OFFSET +
106 		entry32_off);
107 	psd->local_apic_id = apic_id;
108 	psd->size = sizeof(TXT_PROCESSOR_SMM_DESCRIPTOR);
109 	psd->acpi_rsdp = 0;
110 	psd->bios_hw_resource_requirements_ptr =
111 		(uint64_t)((uintptr_t)get_stm_resource());
112 	psd->smm_cs = ROM_CODE_SEG;
113 	psd->smm_ds = ROM_DATA_SEG;
114 	psd->smm_ss = ROM_DATA_SEG;
115 	psd->smm_other_segment = ROM_DATA_SEG;
116 	psd->smm_tr = SMM_TASK_STATE_SEG;
117 
118 	// At this point the coreboot smm_stub is relative to the default
119 	// smbase and not the one for the smi handler in tseg.  So we have
120 	// to adjust the gdtr.base
121 
122 	read_gdtr(&gdtr);
123 
124 	gdtr.base -= (uintptr_t)smbase_processor;
125 	gdtr.base += (uintptr_t)smbase;
126 
127 	psd->smm_gdt_ptr = gdtr.base;
128 	psd->smm_gdt_size = gdtr.limit + 1; // the stm will subtract, so add
129 	printk(BIOS_DEBUG, "STM: Smm Descriptor setup complete - Smbase: %p Psd: %p\n",
130 		smbase, psd);
131 }
132 
133 extern uint8_t *stm_resource_heap;
134 
135 #define FXSAVE_SIZE 512
136 
137 static int stm_load_status = 0;
138 
stm_setup(uintptr_t mseg,int cpu,uintptr_t smbase,uintptr_t base_smbase,uint32_t offset32)139 void stm_setup(uintptr_t mseg, int cpu, uintptr_t smbase,
140 			uintptr_t base_smbase, uint32_t offset32)
141 {
142 	msr_t InitMseg;
143 	msr_t MsegChk;
144 	msr_t vmx_basic;
145 
146 	uintptr_t addr_calc;  // used to calculate the stm resource heap area
147 
148 	printk(BIOS_DEBUG, "STM: set up for cpu %d\n", cpu);
149 
150 	vmx_basic = rdmsr(IA32_VMX_BASIC_MSR);
151 
152 	// Does this processor support an STM?
153 	if ((vmx_basic.hi & VMX_BASIC_HI_DUAL_MONITOR) != VMX_BASIC_HI_DUAL_MONITOR) {
154 		printk(BIOS_WARNING, "STM: not supported on CPU %d\n", cpu);
155 		return;
156 	}
157 
158 	// This code moved here because paralled SMM set can cause
159 	// some processor to receive a bad value
160 	// calculate the location in SMRAM
161 	addr_calc = mseg - CONFIG_BIOS_RESOURCE_LIST_SIZE;
162 	stm_resource_heap = (uint8_t *)addr_calc;
163 
164 	if (cpu == 0) {
165 		// need to create the BIOS resource list once
166 		printk(BIOS_DEBUG, "STM: stm_resource_heap located at %p\n",
167 				stm_resource_heap);
168 		//setup the list
169 		add_resources_cmd();
170 
171 		stm_load_status = load_stm_image(mseg);
172 	}
173 
174 	if (stm_load_status == 0) {
175 		// enable STM for this cpu
176 		InitMseg.lo = mseg | IA32_SMM_MONITOR_VALID;
177 		InitMseg.hi = 0;
178 
179 		wrmsr(IA32_SMM_MONITOR_CTL_MSR, InitMseg);
180 
181 		MsegChk = rdmsr(IA32_SMM_MONITOR_CTL_MSR);
182 
183 		printk(BIOS_DEBUG, "STM: MSEG Initialized (%d) 0x%08x 0x%08x\n",
184 			cpu, MsegChk.hi, MsegChk.lo);
185 
186 		// setup the descriptor for this cpu
187 		setup_smm_descriptor((void *)smbase, cpu, offset32);
188 
189 	} else {
190 		printk(BIOS_DEBUG,
191 			"STM: Error in STM load, STM not enabled: %d\n",
192 			cpu);
193 	}
194 }
195