sec/intel/txt/ramstage.c: Extract heap init into a function

Heap initialization is self-contained, so place it into a separate
function. Also, do it after the MSEG registers have been written, so
that all register writes are grouped together. This has no impact.

Change-Id: Id108f4cfcd2896d881d9ba267888f7ed5dd984fa
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/46494
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
This commit is contained in:
Angel Pons 2020-10-16 01:07:18 +02:00
parent 08de7d6bbd
commit 8f7e2a3add
1 changed files with 101 additions and 96 deletions

View File

@ -194,103 +194,8 @@ static void push_sinit_heap(u8 **heap_ptr, void *data, size_t data_length)
} }
} }
/** static void txt_initialize_heap(void)
* Finalize the TXT device.
*
* - Lock TXT register.
* - Protect TSEG using DMA protected regions.
* - Setup TXT regions.
* - Place SINIT ACM in TXT_SINIT memory segment.
* - Fill TXT BIOSDATA region.
*/
static void lockdown_intel_txt(void *unused)
{ {
const uint64_t status = read64((void *)TXT_SPAD);
uintptr_t tseg_base;
size_t tseg_size;
smm_region(&tseg_base, &tseg_size);
if (status & ACMSTS_TXT_DISABLED)
return;
printk(BIOS_INFO, "TEE-TXT: Locking TEE...\n");
/* Lock TXT config, unlocks TXT_HEAP_BASE */
if (intel_txt_run_bios_acm(ACMINPUT_LOCK_CONFIG) < 0) {
printk(BIOS_ERR, "TEE-TXT: Failed to lock registers.\n");
printk(BIOS_ERR, "TEE-TXT: SINIT won't be supported.\n");
return;
}
/*
* Document Number: 558294
* Chapter 5.5.6.1 DMA Protection Memory Region
*/
const u8 dpr_capable = !!(read64((void *)TXT_CAPABILITIES) &
TXT_CAPABILITIES_DPR);
printk(BIOS_INFO, "TEE-TXT: DPR capable %x\n", dpr_capable);
if (dpr_capable) {
/* Verify the DPR settings on the MCH and mirror them to TXT public space */
union dpr_register dpr = txt_get_chipset_dpr();
printk(BIOS_DEBUG, "TEE-TXT: MCH DPR 0x%08x\n", dpr.raw);
printk(BIOS_DEBUG, "TEE-TXT: MCH DPR base @ 0x%08x size %u MiB\n",
(dpr.top - dpr.size) * MiB, dpr.size);
// DPR TODO: implement SA_ENABLE_DPR in the intelblocks
if (!dpr.lock) {
printk(BIOS_ERR, "TEE-TXT: MCH DPR not locked.\n");
return;
}
if (!dpr.epm || !dpr.prs) {
printk(BIOS_ERR, "TEE-TXT: MCH DPR protection not active.\n");
return;
}
if (dpr.size < CONFIG_INTEL_TXT_DPR_SIZE) {
printk(BIOS_ERR, "TEE-TXT: MCH DPR configured size is too small.\n");
return;
}
if (dpr.top * MiB != tseg_base) {
printk(BIOS_ERR, "TEE-TXT: MCH DPR top does not equal TSEG base.\n");
return;
}
/* Clear reserved bits */
dpr.prs = 0;
dpr.epm = 0;
write64((void *)TXT_DPR, dpr.raw);
printk(BIOS_INFO, "TEE-TXT: TXT.DPR 0x%08x\n",
read32((void *)TXT_DPR));
}
/*
* Document Number: 558294
* Chapter 5.5.6.3 Intel TXT Heap Memory Region
*/
write64((void *)TXT_HEAP_SIZE, 0xE0000);
write64((void *)TXT_HEAP_BASE,
ALIGN_DOWN(tseg_base - read64((void *)TXT_HEAP_SIZE), 4096));
/*
* Document Number: 558294
* Chapter 5.5.6.2 SINIT Memory Region
*/
write64((void *)TXT_SINIT_SIZE, 0x20000);
write64((void *)TXT_SINIT_BASE,
ALIGN_DOWN(read64((void *)TXT_HEAP_BASE) -
read64((void *)TXT_SINIT_SIZE), 4096));
/* /*
* BIOS Data Format * BIOS Data Format
* Chapter C.2 * Chapter C.2
@ -392,6 +297,104 @@ static void lockdown_intel_txt(void *unused)
/* SinitMLEData */ /* SinitMLEData */
/* FIXME: Does firmware need to write this? */ /* FIXME: Does firmware need to write this? */
push_sinit_heap(&heap_struct, NULL, 0); push_sinit_heap(&heap_struct, NULL, 0);
}
/**
* Finalize the TXT device.
*
* - Lock TXT register.
* - Protect TSEG using DMA protected regions.
* - Setup TXT regions.
* - Place SINIT ACM in TXT_SINIT memory segment.
* - Fill TXT BIOSDATA region.
*/
static void lockdown_intel_txt(void *unused)
{
const uint64_t status = read64((void *)TXT_SPAD);
uintptr_t tseg_base;
size_t tseg_size;
smm_region(&tseg_base, &tseg_size);
if (status & ACMSTS_TXT_DISABLED)
return;
printk(BIOS_INFO, "TEE-TXT: Locking TEE...\n");
/* Lock TXT config, unlocks TXT_HEAP_BASE */
if (intel_txt_run_bios_acm(ACMINPUT_LOCK_CONFIG) < 0) {
printk(BIOS_ERR, "TEE-TXT: Failed to lock registers.\n");
printk(BIOS_ERR, "TEE-TXT: SINIT won't be supported.\n");
return;
}
/*
* Document Number: 558294
* Chapter 5.5.6.1 DMA Protection Memory Region
*/
const u8 dpr_capable = !!(read64((void *)TXT_CAPABILITIES) &
TXT_CAPABILITIES_DPR);
printk(BIOS_INFO, "TEE-TXT: DPR capable %x\n", dpr_capable);
if (dpr_capable) {
/* Verify the DPR settings on the MCH and mirror them to TXT public space */
union dpr_register dpr = txt_get_chipset_dpr();
printk(BIOS_DEBUG, "TEE-TXT: MCH DPR 0x%08x\n", dpr.raw);
printk(BIOS_DEBUG, "TEE-TXT: MCH DPR base @ 0x%08x size %u MiB\n",
(dpr.top - dpr.size) * MiB, dpr.size);
// DPR TODO: implement SA_ENABLE_DPR in the intelblocks
if (!dpr.lock) {
printk(BIOS_ERR, "TEE-TXT: MCH DPR not locked.\n");
return;
}
if (!dpr.epm || !dpr.prs) {
printk(BIOS_ERR, "TEE-TXT: MCH DPR protection not active.\n");
return;
}
if (dpr.size < CONFIG_INTEL_TXT_DPR_SIZE) {
printk(BIOS_ERR, "TEE-TXT: MCH DPR configured size is too small.\n");
return;
}
if (dpr.top * MiB != tseg_base) {
printk(BIOS_ERR, "TEE-TXT: MCH DPR top does not equal TSEG base.\n");
return;
}
/* Clear reserved bits */
dpr.prs = 0;
dpr.epm = 0;
write64((void *)TXT_DPR, dpr.raw);
printk(BIOS_INFO, "TEE-TXT: TXT.DPR 0x%08x\n",
read32((void *)TXT_DPR));
}
/*
* Document Number: 558294
* Chapter 5.5.6.3 Intel TXT Heap Memory Region
*/
write64((void *)TXT_HEAP_SIZE, 0xE0000);
write64((void *)TXT_HEAP_BASE,
ALIGN_DOWN(tseg_base - read64((void *)TXT_HEAP_SIZE), 4096));
/*
* Document Number: 558294
* Chapter 5.5.6.2 SINIT Memory Region
*/
write64((void *)TXT_SINIT_SIZE, 0x20000);
write64((void *)TXT_SINIT_BASE,
ALIGN_DOWN(read64((void *)TXT_HEAP_BASE) -
read64((void *)TXT_SINIT_SIZE), 4096));
/* /*
* FIXME: Server-TXT capable platforms need to install an STM in SMM and set up MSEG. * FIXME: Server-TXT capable platforms need to install an STM in SMM and set up MSEG.
@ -404,6 +407,8 @@ static void lockdown_intel_txt(void *unused)
write64((void *)TXT_MSEG_SIZE, 0); write64((void *)TXT_MSEG_SIZE, 0);
write64((void *)TXT_MSEG_BASE, 0); write64((void *)TXT_MSEG_BASE, 0);
txt_initialize_heap();
if (CONFIG(INTEL_TXT_LOGGING)) if (CONFIG(INTEL_TXT_LOGGING))
txt_dump_regions(); txt_dump_regions();
} }