summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/northbridge/intel/haswell/memmap.c10
-rw-r--r--src/security/intel/txt/ramstage.c41
-rw-r--r--src/security/intel/txt/txt_platform.h12
-rw-r--r--src/soc/intel/common/block/systemagent/systemagent_early.c7
4 files changed, 60 insertions, 10 deletions
diff --git a/src/northbridge/intel/haswell/memmap.c b/src/northbridge/intel/haswell/memmap.c
index ac36e25999..02d120b119 100644
--- a/src/northbridge/intel/haswell/memmap.c
+++ b/src/northbridge/intel/haswell/memmap.c
@@ -9,6 +9,7 @@
#include <cpu/x86/smm.h>
#include <device/pci_ops.h>
#include <cbmem.h>
+#include <security/intel/txt/txt_platform.h>
#include <security/intel/txt/txt_register.h>
#include "haswell.h"
@@ -23,6 +24,11 @@ static size_t northbridge_get_tseg_size(void)
return CONFIG_SMM_TSEG_SIZE;
}
+union dpr_register txt_get_chipset_dpr(void)
+{
+ return (union dpr_register) { .raw = pci_read_config32(HOST_BRIDGE, DPR) };
+}
+
/*
* Return the topmost memory address below 4 GiB available for general
* use, from software's view of memory. Do not confuse this with TOLUD,
@@ -39,9 +45,7 @@ static uintptr_t top_of_low_usable_memory(void)
*/
uintptr_t tolum = northbridge_get_tseg_base();
- const union dpr_register dpr = {
- .raw = pci_read_config32(HOST_BRIDGE, DPR),
- };
+ const union dpr_register dpr = txt_get_chipset_dpr();
/* Subtract DMA Protected Range size if enabled */
if (dpr.epm)
diff --git a/src/security/intel/txt/ramstage.c b/src/security/intel/txt/ramstage.c
index 263bc9daa6..f532a2fbd8 100644
--- a/src/security/intel/txt/ramstage.c
+++ b/src/security/intel/txt/ramstage.c
@@ -13,6 +13,7 @@
#include <types.h>
#include "txt.h"
+#include "txt_platform.h"
#include "txt_register.h"
#include "txt_getsec.h"
@@ -233,16 +234,42 @@ static void lockdown_intel_txt(void *unused)
printk(BIOS_INFO, "TEE-TXT: DPR capable %x\n", dpr_capable);
if (dpr_capable) {
- /* Protect 3 MiB below TSEG and lock register */
- union dpr_register dpr = {
- .lock = 1,
- .size = 3,
- .top = tseg_base / MiB,
- };
- write64((void *)TXT_DPR, dpr.raw);
+ /* 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 < 3) {
+ 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));
}
diff --git a/src/security/intel/txt/txt_platform.h b/src/security/intel/txt/txt_platform.h
new file mode 100644
index 0000000000..8881cab331
--- /dev/null
+++ b/src/security/intel/txt/txt_platform.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __SECURITY_INTEL_TXT_PLATFORM_H__
+#define __SECURITY_INTEL_TXT_PLATFORM_H__
+
+#include <types.h>
+#include "txt_register.h"
+
+/* Prototypes to be defined in chipset code */
+union dpr_register txt_get_chipset_dpr(void);
+
+#endif /* __SECURITY_INTEL_TXT_PLATFORM_H__ */
diff --git a/src/soc/intel/common/block/systemagent/systemagent_early.c b/src/soc/intel/common/block/systemagent/systemagent_early.c
index ffb6404aa2..53d6077e5f 100644
--- a/src/soc/intel/common/block/systemagent/systemagent_early.c
+++ b/src/soc/intel/common/block/systemagent/systemagent_early.c
@@ -7,6 +7,8 @@
#include <device/device.h>
#include <device/pci.h>
#include <intelblocks/systemagent.h>
+#include <security/intel/txt/txt_platform.h>
+#include <security/intel/txt/txt_register.h>
#include <soc/iomap.h>
#include <soc/pci_devs.h>
#include <soc/systemagent.h>
@@ -145,3 +147,8 @@ size_t sa_get_tseg_size(void)
{
return sa_get_gsm_base() - sa_get_tseg_base();
}
+
+union dpr_register txt_get_chipset_dpr(void)
+{
+ return (union dpr_register) { .raw = pci_read_config32(SA_DEV_ROOT, DPR) };
+}