blob: abd766735556b6d4a263a03c38c558348e5b3c1a [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
80void setup_smm_descriptor(void *smbase, void *base_smbase, int32_t apic_id,
81 int32_t entry32_off)
82{
83 struct descriptor gdtr;
84 void *smbase_processor;
85 //msr_t smbase_msr;
86
87 TXT_PROCESSOR_SMM_DESCRIPTOR *psd;
88
89 smbase_processor = (void *) SMM_DEFAULT_BASE;//we are here
90 psd = smbase + SMM_PSD_OFFSET;
91
92 printk(BIOS_DEBUG,
93 "STM: Smm Descriptor setup: Smbase: %p Smbase_processor: %p Psd: %p\n",
94 smbase,
95 smbase_processor,
96 psd);
97
98 memset(psd, 0, sizeof(TXT_PROCESSOR_SMM_DESCRIPTOR));
99
100 memcpy(&psd->signature, TXT_PROCESSOR_SMM_DESCRIPTOR_SIGNATURE, 8);
101 psd->smm_descriptor_ver_major =
102 TXT_PROCESSOR_SMM_DESCRIPTOR_VERSION_MAJOR;
103 psd->smm_descriptor_ver_minor =
104 TXT_PROCESSOR_SMM_DESCRIPTOR_VERSION_MINOR;
105 psd->smm_smi_handler_rip =
106 (uint64_t)((uintptr_t)base_smbase + SMM_ENTRY_OFFSET +
107 entry32_off);
108 psd->local_apic_id = apic_id;
109 psd->size = sizeof(TXT_PROCESSOR_SMM_DESCRIPTOR);
110 psd->acpi_rsdp = 0;
111 psd->bios_hw_resource_requirements_ptr =
112 (uint64_t)((uintptr_t)get_stm_resource());
113 psd->smm_cs = ROM_CODE_SEG;
114 psd->smm_ds = ROM_DATA_SEG;
115 psd->smm_ss = ROM_DATA_SEG;
116 psd->smm_other_segment = ROM_DATA_SEG;
117 psd->smm_tr = SMM_TASK_STATE_SEG;
118
Eugene Myersae438be2020-01-21 17:01:47 -0500119 // At this point the coreboot smm_stub is relative to the default
120 // smbase and not the one for the smi handler in tseg. So we have
121 // to adjust the gdtr.base
122
123 read_gdtr(&gdtr);
124
125 gdtr.base -= (uintptr_t) smbase_processor;
126 gdtr.base += (uintptr_t) base_smbase;
127
128 psd->smm_gdt_ptr = gdtr.base;
129 psd->smm_gdt_size = gdtr.limit + 1; // the stm will subtract, so add
130 printk(BIOS_DEBUG, "STM: Smm Descriptor setup complete - Smbase: %p Psd: %p\n",
131 smbase, psd);
132}
133
134extern uint8_t *stm_resource_heap;
135
136#define FXSAVE_SIZE 512
137
138static int stm_load_status = 0;
139
Eugene D Myersf213f172020-04-15 19:11:52 -0400140void stm_setup(uintptr_t mseg, int cpu, uintptr_t smbase,
Eugene Myersae438be2020-01-21 17:01:47 -0500141 uintptr_t base_smbase, uint32_t offset32)
142{
143 msr_t InitMseg;
144 msr_t MsegChk;
Eugene Myers5544f622020-02-12 13:31:30 -0500145 msr_t vmx_basic;
146
Eugene Myersae438be2020-01-21 17:01:47 -0500147 uintptr_t addr_calc; // used to calculate the stm resource heap area
148
Eugene D Myersf213f172020-04-15 19:11:52 -0400149 printk(BIOS_DEBUG, "STM: set up for cpu %d\n", cpu);
Eugene Myers5544f622020-02-12 13:31:30 -0500150
151 vmx_basic = rdmsr(IA32_VMX_BASIC_MSR);
152
153 // Does this processor support an STM?
154 if ((vmx_basic.hi & VMX_BASIC_HI_DUAL_MONITOR) != VMX_BASIC_HI_DUAL_MONITOR) {
155 printk(BIOS_WARNING, "STM: not supported on CPU %d\n", cpu);
156 return;
157 }
158
Eugene Myersae438be2020-01-21 17:01:47 -0500159 if (cpu == 0) {
160
161 // need to create the BIOS resource list once
162 // first calculate the location in SMRAM
Eugene D Myers076605b2020-04-15 18:28:10 -0400163 addr_calc = mseg - CONFIG_BIOS_RESOURCE_LIST_SIZE;
Eugene Myersae438be2020-01-21 17:01:47 -0500164 stm_resource_heap = (uint8_t *) addr_calc;
165 printk(BIOS_DEBUG, "STM: stm_resource_heap located at %p\n",
166 stm_resource_heap);
167 //setup the the list
168 add_resources_cmd();
169
170 stm_load_status = load_stm_image(mseg);
171 }
172
173 if (stm_load_status == 0) {
174 // enable STM for this cpu
175 InitMseg.lo = mseg | IA32_SMM_MONITOR_VALID;
176 InitMseg.hi = 0;
177
178 wrmsr(IA32_SMM_MONITOR_CTL_MSR, InitMseg);
179
180 MsegChk = rdmsr(IA32_SMM_MONITOR_CTL_MSR);
181
182 printk(BIOS_DEBUG, "STM: MSEG Initialized (%d) 0x%08x 0x%08x\n",
183 cpu, MsegChk.hi, MsegChk.lo);
184
185 // setup the descriptor for this cpu
186 setup_smm_descriptor((void *)smbase, (void *) base_smbase,
187 cpu, offset32);
188 } else {
189 printk(BIOS_DEBUG,
190 "STM: Error in STM load, STM not enabled: %d\n",
191 cpu);
192 }
193}