blob: 8a266a4230d0f6de1ef8b775d7aed435870b2339 [file] [log] [blame]
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +01001/* SPDX-License-Identifier: GPL-2.0-only */
2
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +01003#include <acpi/acpi.h>
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +01004#include <bootmem.h>
Angel Pons52082be2020-10-05 12:34:29 +02005#include <bootstate.h>
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +01006#include <cbfs.h>
Angel Pons52082be2020-10-05 12:34:29 +02007#include <console/console.h>
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +01008#include <cpu/intel/common/common.h>
Angel Pons11334722020-10-05 16:34:03 +02009#include <cpu/x86/smm.h>
Elyes Haouas8823ba12022-12-05 08:48:50 +010010#include <device/mmio.h>
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +010011#include <device/pci_ops.h>
Arthur Heymansee55d712021-05-12 16:22:05 +020012#include <security/intel/cbnt/cbnt.h>
Angel Pons52082be2020-10-05 12:34:29 +020013#include <types.h>
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +010014
15#include "txt.h"
Angel Ponsffbb4b22020-10-15 23:25:58 +020016#include "txt_platform.h"
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +010017#include "txt_register.h"
18#include "txt_getsec.h"
19
20/* FIXME: Seems to work only on some platforms */
21static void log_ibb_measurements(void)
22{
23 const uint64_t mseg_size = read64((void *)TXT_MSEG_SIZE);
24 uint64_t mseg_base = read64((void *)TXT_MSEG_BASE);
25
26 if (!mseg_size || !mseg_base || mseg_size <= mseg_base)
27 return;
28 /*
29 * MSEG SIZE and MSEG BASE might contain random values.
30 * Assume below 4GiB and 8byte aligned.
31 */
32 if (mseg_base & ~0xfffffff8ULL || mseg_size & ~0xfffffff8ULL)
33 return;
34
35 printk(BIOS_INFO, "TEE-TXT: IBB Hash 0x");
36 for (; mseg_base < mseg_size; mseg_base++)
37 printk(BIOS_INFO, "%02X", read8((void *)(uintptr_t)mseg_base));
38
39 printk(BIOS_INFO, "\n");
40}
41
42void bootmem_platform_add_ranges(void)
43{
44 uint64_t status = read64((void *)TXT_SPAD);
45
46 if (status & ACMSTS_TXT_DISABLED)
47 return;
48
49 /* Chapter 5.5.5 Intel TXT reserved memory */
50 bootmem_add_range(TXT_RESERVED_SPACE,
51 TXT_RESERVED_SPACE_SIZE,
52 BM_MEM_RESERVED);
53
54 /* Intel TPM decode memory */
55 bootmem_add_range(TXT_TPM_DECODE_AREA,
56 TXT_RESERVED_SPACE - TXT_TPM_DECODE_AREA,
57 BM_MEM_RESERVED);
58
59 /* Intel TXT public space memory */
60 bootmem_add_range(TXT_PUBLIC_SPACE,
61 TXT_TPM_DECODE_AREA - TXT_PUBLIC_SPACE,
62 BM_MEM_RESERVED);
63
64 /* Intel TXT private space memory */
65 bootmem_add_range(TXT_PRIVATE_SPACE,
66 TXT_PUBLIC_SPACE - TXT_PRIVATE_SPACE,
67 BM_MEM_RESERVED);
68
Angel Pons463e44b2020-10-05 13:58:16 +020069 const union dpr_register dpr = {
70 .raw = read32((void *)TXT_DPR),
71 };
72
73 const uint32_t dpr_base = dpr.top - dpr.size * MiB;
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +010074
75 /* Chapter 5.5.6 Intel TXT Device Memory */
Angel Pons463e44b2020-10-05 13:58:16 +020076 bootmem_add_range(dpr_base, dpr.size * MiB, BM_MEM_RESERVED);
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +010077}
78
79static bool get_wake_error_status(void)
80{
81 const uint8_t error = read8((void *)TXT_ESTS);
82 return !!(error & TXT_ESTS_WAKE_ERROR_STS);
83}
84
85static void check_secrets_txt(void *unused)
86{
87 uint64_t status = read64((void *)TXT_SPAD);
88
89 if (status & ACMSTS_TXT_DISABLED)
90 return;
91
Arthur Heymansbccb6912020-11-24 17:37:11 +010092 /*
93 * Check if secrets bit needs to be reset. Only platforms that support
94 * CONFIG(PLATFORM_HAS_DRAM_CLEAR) will be able to run this code.
95 * On some platforms FSP-M takes care of the DRAM clearing.
96 * Assume all memory really was cleared.
97 *
98 * TXT will issue a platform reset to come up sober.
99 */
100 if (intel_txt_memory_has_secrets()) {
101 printk(BIOS_INFO, "TEE-TXT: Wiping TEE...\n");
102 intel_txt_run_bios_acm(ACMINPUT_CLEAR_SECRETS);
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100103
Arthur Heymansbccb6912020-11-24 17:37:11 +0100104 /* Should never reach this point ... */
105 intel_txt_log_acm_error(read32((void *)TXT_BIOSACM_ERRORCODE));
106 die("Waiting for platform reset...\n");
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100107 }
108}
109
110BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_ENTRY, check_secrets_txt, NULL);
111
112/**
113 * Log TXT startup errors, check all bits for TXT, run BIOSACM using
114 * GETSEC[ENTERACCS].
115 *
116 * If a "TXT reset" is detected or "memory had secrets" is set, then do nothing as
117 * 1. Running ACMs will cause a TXT-RESET
118 * 2. Memory will be scrubbed in BS_DEV_INIT
119 * 3. TXT-RESET will be issued by code above later
120 *
121 */
122static void init_intel_txt(void *unused)
123{
124 const uint64_t status = read64((void *)TXT_SPAD);
125
126 if (status & ACMSTS_TXT_DISABLED)
127 return;
128
129 printk(BIOS_INFO, "TEE-TXT: Initializing TEE...\n");
130
131 intel_txt_log_spad();
132
Arthur Heymansee55d712021-05-12 16:22:05 +0200133 if (CONFIG(INTEL_CBNT_LOGGING))
134 intel_cbnt_log_registers();
135
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100136 if (CONFIG(INTEL_TXT_LOGGING)) {
137 intel_txt_log_bios_acm_error();
138 txt_dump_chipset_info();
139 }
140
141 printk(BIOS_INFO, "TEE-TXT: Validate TEE...\n");
142
143 if (intel_txt_prepare_txt_env()) {
144 printk(BIOS_ERR, "TEE-TXT: Failed to prepare TXT environment\n");
145 return;
146 }
147
148 /* Check for fatal ACM error and TXT reset */
149 if (get_wake_error_status()) {
150 /* Can't run ACMs with TXT_ESTS_WAKE_ERROR_STS set */
151 printk(BIOS_ERR, "TEE-TXT: Fatal BIOS ACM error reported\n");
152 return;
153 }
154
Angel Pons8a285fd82020-10-16 10:49:12 +0200155 if (CONFIG(INTEL_TXT_TEST_BIOS_ACM_CALLING_CODE)) {
156 printk(BIOS_INFO, "TEE-TXT: Testing BIOS ACM calling code...\n");
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100157
Angel Pons8a285fd82020-10-16 10:49:12 +0200158 /*
159 * Test BIOS ACM code.
160 * ACM should do nothing on reserved functions, and return an error code
161 * in TXT_BIOSACM_ERRORCODE. Tests showed that this is not true.
162 * Use special function "NOP" that does 'nothing'.
163 */
164 if (intel_txt_run_bios_acm(ACMINPUT_NOP) < 0) {
165 printk(BIOS_ERR,
166 "TEE-TXT: Error calling BIOS ACM with NOP function.\n");
167 return;
168 }
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100169 }
170
171 if (status & (ACMSTS_BIOS_TRUSTED | ACMSTS_IBB_MEASURED)) {
Angel Ponse70a3f82020-10-16 10:58:57 +0200172 printk(BIOS_INFO, "TEE-TXT: Logging IBB measurements...\n");
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100173 log_ibb_measurements();
Angel Ponse70a3f82020-10-16 10:58:57 +0200174 }
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100175
Angel Ponse70a3f82020-10-16 10:58:57 +0200176 int s3resume = acpi_is_wakeup_s3();
Arthur Heymans66dbd9c2021-01-06 14:12:47 +0100177 if (!s3resume && !CONFIG(INTEL_CBNT_SUPPORT)) {
Angel Ponse70a3f82020-10-16 10:58:57 +0200178 printk(BIOS_INFO, "TEE-TXT: Scheck...\n");
179 if (intel_txt_run_bios_acm(ACMINPUT_SCHECK) < 0) {
180 printk(BIOS_ERR, "TEE-TXT: Error calling BIOS ACM.\n");
181 return;
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100182 }
183 }
184}
185
186BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_EXIT, init_intel_txt, NULL);
187
188static void push_sinit_heap(u8 **heap_ptr, void *data, size_t data_length)
189{
190 /* Push size */
191 const uint64_t tmp = data_length + 8;
192 memcpy(*heap_ptr, &tmp, 8);
193 *heap_ptr += 8;
194
195 if (data_length) {
196 /* Push data */
197 memcpy(*heap_ptr, data, data_length);
198 *heap_ptr += data_length;
199 }
200}
201
Michał Żygowskieffe39b2021-11-21 13:07:17 +0100202static void txt_heap_fill_common_bdr(struct txt_biosdataregion *bdr)
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100203{
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100204 /* TPM2.0 requires version 6 of BDT */
Michał Żygowskieffe39b2021-11-21 13:07:17 +0100205 bdr->version = CONFIG_INTEL_TXT_BDR_VERSION;
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100206
Michał Żygowskieffe39b2021-11-21 13:07:17 +0100207 bdr->no_logical_procs = dev_count_cpu();
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100208
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100209 /* The following have been removed from BIOS Data Table in version 6 */
Julius Werner77639e42021-02-05 16:51:25 -0800210 size_t policy_len;
211 void *policy_data = cbfs_map(CONFIG_INTEL_TXT_CBFS_BIOS_POLICY, &policy_len);
212 if (policy_data) {
213 /* Point to FIT Type 9 entry in flash */
Michał Żygowskieffe39b2021-11-21 13:07:17 +0100214 bdr->lcp_pd_base = (uintptr_t)policy_data;
215 bdr->lcp_pd_size = (uint64_t)policy_len;
Julius Werner77639e42021-02-05 16:51:25 -0800216 cbfs_unmap(policy_data);
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100217 } else {
218 printk(BIOS_ERR, "TEE-TXT: Couldn't locate LCP PD Policy in CBFS.\n");
219 }
220
Michał Żygowskieffe39b2021-11-21 13:07:17 +0100221 bdr->support_acpi_ppi = 0;
222 bdr->platform_type = 0;
223}
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100224
Michał Żygowskieffe39b2021-11-21 13:07:17 +0100225static void txt_heap_fill_bios_spec(struct txt_bios_spec_ver_element *spec)
226{
Angel Pons08de7d62020-10-16 01:01:14 +0200227 /* Fill in the version of the used TXT BIOS Specification */
Michał Żygowskieffe39b2021-11-21 13:07:17 +0100228 spec->header.type = HEAP_EXTDATA_TYPE_BIOS_SPEC_VER;
229 spec->header.size = sizeof(*spec);
230 spec->ver_major = 2;
231 spec->ver_minor = 1;
232 spec->ver_revision = 0;
233}
234
235static void txt_heap_push_bdr_for_two_acms(u8 **heap_struct)
236{
237 /*
238 * BIOS Data Format
239 * Chapter C.2
240 * Intel TXT Software Development Guide (Document: 315168-015)
241 */
242 /* Structure format for two present ACMs */
243 struct {
244 struct txt_biosdataregion bdr;
245 struct txt_bios_spec_ver_element spec;
246 struct txt_heap_acm_element2 heap_acm;
247 struct txt_extended_data_element_header end;
248 } __packed data = {0};
249
250 txt_heap_fill_common_bdr(&data.bdr);
251 txt_heap_fill_bios_spec(&data.spec);
252
253 void *sinit_base = (void *)(uintptr_t)read64((void *)TXT_SINIT_BASE);
254 data.bdr.bios_sinit_size = cbfs_load(CONFIG_INTEL_TXT_CBFS_SINIT_ACM,
255 sinit_base,
256 read64((void *)TXT_SINIT_SIZE));
Angel Pons08de7d62020-10-16 01:01:14 +0200257
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100258 /* Extended elements - ACM addresses */
259 data.heap_acm.header.type = HEAP_EXTDATA_TYPE_ACM;
Michał Żygowskieffe39b2021-11-21 13:07:17 +0100260 data.heap_acm.num_acms = 2;
261 data.heap_acm.acm_addrs[1] = (uintptr_t)sinit_base;
262
263 printk(BIOS_INFO, "TEE-TXT: Placing SINIT ACM in memory.\n");
264 if (CONFIG(INTEL_TXT_LOGGING))
265 txt_dump_acm_info(sinit_base);
266
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100267 data.heap_acm.acm_addrs[0] =
Julius Werner834b3ec2020-03-04 16:52:08 -0800268 (uintptr_t)cbfs_map(CONFIG_INTEL_TXT_CBFS_BIOS_ACM, NULL);
Michał Żygowskieffe39b2021-11-21 13:07:17 +0100269
270 data.heap_acm.header.size = sizeof(data.heap_acm);
271
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100272 /* Extended elements - End marker */
273 data.end.type = HEAP_EXTDATA_TYPE_END;
274 data.end.size = sizeof(data.end);
275
Michał Żygowskieffe39b2021-11-21 13:07:17 +0100276 /* BiosData */
277 push_sinit_heap(heap_struct, &data, sizeof(data));
278}
279
280static void txt_heap_push_bdr_for_one_acm(u8 **heap_struct)
281{
282 /*
283 * BIOS Data Format
284 * Chapter C.2
285 * Intel TXT Software Development Guide (Document: 315168-015)
286 */
287 /* Structure format for one present ACM */
288 struct {
289 struct txt_biosdataregion bdr;
290 struct txt_bios_spec_ver_element spec;
291 struct txt_heap_acm_element1 heap_acm;
292 struct txt_extended_data_element_header end;
293 } __packed data = {0};
294
295 txt_heap_fill_common_bdr(&data.bdr);
296 txt_heap_fill_bios_spec(&data.spec);
297
298 void *sinit_base = (void *)(uintptr_t)read64((void *)TXT_SINIT_BASE);
299 /* Clear SINIT ACM memory */
300 memset(sinit_base, 0, read64((void *)TXT_SINIT_SIZE));
301
302 /* Extended elements - ACM addresses */
303 data.heap_acm.header.type = HEAP_EXTDATA_TYPE_ACM;
304 data.heap_acm.acm_addrs[0] =
305 (uintptr_t)cbfs_map(CONFIG_INTEL_TXT_CBFS_BIOS_ACM, NULL);
306 data.heap_acm.num_acms = 1;
307
308 data.heap_acm.header.size = sizeof(data.heap_acm);
309
310 /* Extended elements - End marker */
311 data.end.type = HEAP_EXTDATA_TYPE_END;
312 data.end.size = sizeof(data.end);
313
314 /* BiosData */
315 push_sinit_heap(heap_struct, &data, sizeof(data));
316}
317
318static void txt_initialize_heap(void)
319{
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100320 /* Fill TXT.HEAP.BASE with 4 subregions */
321 u8 *heap_struct = (void *)((uintptr_t)read64((void *)TXT_HEAP_BASE));
322
Michał Żygowskieffe39b2021-11-21 13:07:17 +0100323 /*
324 * Since we may have either BIOS ACM or both BIOS and SINIT ACMs in
325 * CBFS, the size of txt_heap_acm_element will be different. We cannot
326 * always hardcode the number of ACM addresses for two ACMs. If we
327 * include BIOS ACM only, the BDR parsing will fail in TBoot due to
328 * invalid sizeof BDR. Check if SINIT ACM is present in CBFS and push
329 * properly formatted BDR region onto the TXT heap.
330 */
331 if (cbfs_file_exists(CONFIG_INTEL_TXT_CBFS_SINIT_ACM))
332 txt_heap_push_bdr_for_two_acms(&heap_struct);
333 else
334 txt_heap_push_bdr_for_one_acm(&heap_struct);
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100335
336 /* OsMLEData */
337 /* FIXME: Does firmware need to write this? */
338 push_sinit_heap(&heap_struct, NULL, 0);
339
340 /* OsSinitData */
341 /* FIXME: Does firmware need to write this? */
342 push_sinit_heap(&heap_struct, NULL, 0);
343
344 /* SinitMLEData */
345 /* FIXME: Does firmware need to write this? */
346 push_sinit_heap(&heap_struct, NULL, 0);
Angel Pons8f7e2a32020-10-16 01:07:18 +0200347}
348
Arthur Heymansfc6cc712021-02-02 19:00:49 +0100349__weak bool skip_intel_txt_lockdown(void)
350{
351 return false;
352}
353
Angel Pons8f7e2a32020-10-16 01:07:18 +0200354/**
355 * Finalize the TXT device.
356 *
357 * - Lock TXT register.
358 * - Protect TSEG using DMA protected regions.
359 * - Setup TXT regions.
360 * - Place SINIT ACM in TXT_SINIT memory segment.
361 * - Fill TXT BIOSDATA region.
362 */
363static void lockdown_intel_txt(void *unused)
364{
Arthur Heymansfc6cc712021-02-02 19:00:49 +0100365 if (skip_intel_txt_lockdown())
366 return;
367
Angel Pons8f7e2a32020-10-16 01:07:18 +0200368 const uint64_t status = read64((void *)TXT_SPAD);
369
Angel Pons6c4028d2020-10-16 11:52:40 +0200370 uint32_t txt_feature_flags = 0;
Angel Pons8f7e2a32020-10-16 01:07:18 +0200371 uintptr_t tseg_base;
372 size_t tseg_size;
373
374 smm_region(&tseg_base, &tseg_size);
375
376 if (status & ACMSTS_TXT_DISABLED)
377 return;
378
Angel Pons6c4028d2020-10-16 11:52:40 +0200379 /*
380 * Document Number: 558294
381 * Chapter 5.4.3 Detection of Intel TXT Capability
382 */
Angel Pons8f7e2a32020-10-16 01:07:18 +0200383
Angel Pons6c4028d2020-10-16 11:52:40 +0200384 if (!getsec_parameter(NULL, NULL, NULL, NULL, NULL, &txt_feature_flags))
Angel Pons8f7e2a32020-10-16 01:07:18 +0200385 return;
Angel Pons6c4028d2020-10-16 11:52:40 +0200386
387 /* LockConfig only exists on Intel TXT for Servers */
388 if (txt_feature_flags & GETSEC_PARAMS_TXT_EXT_CRTM_SUPPORT) {
389 printk(BIOS_INFO, "TEE-TXT: Locking TEE...\n");
390
391 /* Lock TXT config, unlocks TXT_HEAP_BASE */
392 if (intel_txt_run_bios_acm(ACMINPUT_LOCK_CONFIG) < 0) {
393 printk(BIOS_ERR, "TEE-TXT: Failed to lock registers.\n");
394 printk(BIOS_ERR, "TEE-TXT: SINIT won't be supported.\n");
395 return;
396 }
Angel Pons8f7e2a32020-10-16 01:07:18 +0200397 }
398
399 /*
400 * Document Number: 558294
401 * Chapter 5.5.6.1 DMA Protection Memory Region
402 */
403
404 const u8 dpr_capable = !!(read64((void *)TXT_CAPABILITIES) &
405 TXT_CAPABILITIES_DPR);
406 printk(BIOS_INFO, "TEE-TXT: DPR capable %x\n", dpr_capable);
407
408 if (dpr_capable) {
409 /* Verify the DPR settings on the MCH and mirror them to TXT public space */
410 union dpr_register dpr = txt_get_chipset_dpr();
411
412 printk(BIOS_DEBUG, "TEE-TXT: MCH DPR 0x%08x\n", dpr.raw);
413
414 printk(BIOS_DEBUG, "TEE-TXT: MCH DPR base @ 0x%08x size %u MiB\n",
415 (dpr.top - dpr.size) * MiB, dpr.size);
416
417 // DPR TODO: implement SA_ENABLE_DPR in the intelblocks
418
419 if (!dpr.lock) {
420 printk(BIOS_ERR, "TEE-TXT: MCH DPR not locked.\n");
421 return;
422 }
423
424 if (!dpr.epm || !dpr.prs) {
425 printk(BIOS_ERR, "TEE-TXT: MCH DPR protection not active.\n");
426 return;
427 }
428
Arthur Heymans9059a892020-10-23 11:08:41 +0200429 _Static_assert(CONFIG_INTEL_TXT_HEAP_SIZE + CONFIG_INTEL_TXT_SINIT_SIZE
430 < CONFIG_INTEL_TXT_DPR_SIZE * MiB, "TXT Heap and Sinit must fit DPR");
431
Angel Pons8f7e2a32020-10-16 01:07:18 +0200432 if (dpr.size < CONFIG_INTEL_TXT_DPR_SIZE) {
433 printk(BIOS_ERR, "TEE-TXT: MCH DPR configured size is too small.\n");
434 return;
435 }
436
437 if (dpr.top * MiB != tseg_base) {
438 printk(BIOS_ERR, "TEE-TXT: MCH DPR top does not equal TSEG base.\n");
439 return;
440 }
441
442 /* Clear reserved bits */
443 dpr.prs = 0;
444 dpr.epm = 0;
445
446 write64((void *)TXT_DPR, dpr.raw);
447
448 printk(BIOS_INFO, "TEE-TXT: TXT.DPR 0x%08x\n",
449 read32((void *)TXT_DPR));
450 }
451
452 /*
453 * Document Number: 558294
454 * Chapter 5.5.6.3 Intel TXT Heap Memory Region
455 */
Arthur Heymans9059a892020-10-23 11:08:41 +0200456 write64((void *)TXT_HEAP_SIZE, CONFIG_INTEL_TXT_HEAP_SIZE);
Angel Pons8f7e2a32020-10-16 01:07:18 +0200457 write64((void *)TXT_HEAP_BASE,
458 ALIGN_DOWN(tseg_base - read64((void *)TXT_HEAP_SIZE), 4096));
459
460 /*
461 * Document Number: 558294
462 * Chapter 5.5.6.2 SINIT Memory Region
463 */
Arthur Heymans9059a892020-10-23 11:08:41 +0200464 write64((void *)TXT_SINIT_SIZE, CONFIG_INTEL_TXT_SINIT_SIZE);
Angel Pons8f7e2a32020-10-16 01:07:18 +0200465 write64((void *)TXT_SINIT_BASE,
466 ALIGN_DOWN(read64((void *)TXT_HEAP_BASE) -
467 read64((void *)TXT_SINIT_SIZE), 4096));
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100468
469 /*
470 * FIXME: Server-TXT capable platforms need to install an STM in SMM and set up MSEG.
471 */
472
473 /**
474 * Chapter 5.10.1 SMM in the Intel TXT for Servers Environment
475 * Disable MSEG.
476 */
477 write64((void *)TXT_MSEG_SIZE, 0);
478 write64((void *)TXT_MSEG_BASE, 0);
479
Angel Ponsc0376952020-10-16 01:12:00 +0200480 /* Only initialize the heap on regular boots */
481 if (!acpi_is_wakeup_s3())
482 txt_initialize_heap();
Angel Pons8f7e2a32020-10-16 01:07:18 +0200483
Philipp Deppenwiese5f9f7762018-11-20 14:22:15 +0100484 if (CONFIG(INTEL_TXT_LOGGING))
485 txt_dump_regions();
486}
487
488BOOT_STATE_INIT_ENTRY(BS_POST_DEVICE, BS_ON_EXIT, lockdown_intel_txt, NULL);