blob: e5b3cf1d74cc5389f45ae5ebf4803b1132a4ca87 [file] [log] [blame]
Patrick Georgi593124d2020-05-10 19:44:08 +02001/* SPDX-License-Identifier: BSD-2-Clause */
Eugene Myersae438be2020-01-21 17:01:47 -05002
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
Eugene Myersae438be2020-01-21 17:01:47 -050010#include <cbfs.h>
11#include <console/console.h>
Angel Pons002e5e02020-07-20 23:10:21 +020012#include <stdbool.h>
Eugene Myersae438be2020-01-21 17:01:47 -050013#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 */
21int 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
Julius Werner834b3ec2020-03-04 16:52:08 -080038 stm_image_size = cbfs_load("stm.bin", mseg_base, stm_buffer_size);
Eugene Myersae438be2020-01-21 17:01:47 -050039 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
70struct descriptor {
71 uint16_t limit;
72 uintptr_t base;
73} __attribute__((packed));
74
Eugene Myersae438be2020-01-21 17:01:47 -050075static void read_gdtr(struct descriptor *gdtr)
76{
77 __asm__ __volatile__("sgdt %0" : "=m"(*gdtr));
78}
79
Eugene Myersa5141922022-02-07 16:27:26 -050080void setup_smm_descriptor(void *smbase, int32_t apic_id, int32_t entry32_off)
Eugene Myersae438be2020-01-21 17:01:47 -050081{
82 struct descriptor gdtr;
83 void *smbase_processor;
84 //msr_t smbase_msr;
85
86 TXT_PROCESSOR_SMM_DESCRIPTOR *psd;
87
Elyes Haouasb538d712022-11-18 15:03:07 +010088 smbase_processor = (void *)SMM_DEFAULT_BASE;//we are here
Eugene Myersae438be2020-01-21 17:01:47 -050089 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 =
Eugene Myersa5141922022-02-07 16:27:26 -0500105 (uint64_t)((uintptr_t)smbase + SMM_ENTRY_OFFSET +
Eugene Myersae438be2020-01-21 17:01:47 -0500106 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
Eugene Myersae438be2020-01-21 17:01:47 -0500118 // 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
Elyes Haouasb538d712022-11-18 15:03:07 +0100124 gdtr.base -= (uintptr_t)smbase_processor;
125 gdtr.base += (uintptr_t)smbase;
Eugene Myersae438be2020-01-21 17:01:47 -0500126
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
133extern uint8_t *stm_resource_heap;
134
135#define FXSAVE_SIZE 512
136
137static int stm_load_status = 0;
138
Eugene D Myersf213f172020-04-15 19:11:52 -0400139void stm_setup(uintptr_t mseg, int cpu, uintptr_t smbase,
Eugene Myersae438be2020-01-21 17:01:47 -0500140 uintptr_t base_smbase, uint32_t offset32)
141{
142 msr_t InitMseg;
143 msr_t MsegChk;
Eugene Myers5544f622020-02-12 13:31:30 -0500144 msr_t vmx_basic;
145
Eugene Myersae438be2020-01-21 17:01:47 -0500146 uintptr_t addr_calc; // used to calculate the stm resource heap area
147
Eugene D Myersf213f172020-04-15 19:11:52 -0400148 printk(BIOS_DEBUG, "STM: set up for cpu %d\n", cpu);
Eugene Myers5544f622020-02-12 13:31:30 -0500149
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
Eugene Myersb2c681f2022-02-07 16:45:22 -0500158 // 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;
Elyes Haouasb538d712022-11-18 15:03:07 +0100162 stm_resource_heap = (uint8_t *)addr_calc;
Eugene Myersb2c681f2022-02-07 16:45:22 -0500163
Eugene Myersae438be2020-01-21 17:01:47 -0500164 if (cpu == 0) {
165
166 // need to create the BIOS resource list once
Eugene Myersae438be2020-01-21 17:01:47 -0500167 printk(BIOS_DEBUG, "STM: stm_resource_heap located at %p\n",
168 stm_resource_heap);
Elyes HAOUAS5edd51f2021-01-16 15:01:13 +0100169 //setup the list
Eugene Myersae438be2020-01-21 17:01:47 -0500170 add_resources_cmd();
171
172 stm_load_status = load_stm_image(mseg);
173 }
174
175 if (stm_load_status == 0) {
176 // enable STM for this cpu
177 InitMseg.lo = mseg | IA32_SMM_MONITOR_VALID;
178 InitMseg.hi = 0;
179
180 wrmsr(IA32_SMM_MONITOR_CTL_MSR, InitMseg);
181
182 MsegChk = rdmsr(IA32_SMM_MONITOR_CTL_MSR);
183
184 printk(BIOS_DEBUG, "STM: MSEG Initialized (%d) 0x%08x 0x%08x\n",
185 cpu, MsegChk.hi, MsegChk.lo);
186
187 // setup the descriptor for this cpu
Eugene Myersa5141922022-02-07 16:27:26 -0500188 setup_smm_descriptor((void *)smbase, cpu, offset32);
189
Eugene Myersae438be2020-01-21 17:01:47 -0500190 } else {
191 printk(BIOS_DEBUG,
192 "STM: Error in STM load, STM not enabled: %d\n",
193 cpu);
194 }
195}