aboutsummaryrefslogtreecommitdiff
path: root/src/security/intel/txt/common.c
diff options
context:
space:
mode:
authorAngel Pons <th3fanbus@gmail.com>2020-08-28 02:02:00 +0200
committerAngel Pons <th3fanbus@gmail.com>2020-11-04 23:53:51 +0000
commit6c49f40b6e6342b7acb47cb0a57fa10269e3d4c9 (patch)
tree76063a89a7e8248c7f757201f2cf2f8a2fcef228 /src/security/intel/txt/common.c
parent35597435d023150d847ec11019cb19cba29397bf (diff)
haswell: Add Intel TXT support in romstage
Provide necessary romstage hooks to allow unblocking the memory with SCLEAN. Note that this is slow, and took four minutes with 4 GiB of RAM. Tested on Asrock B85M Pro4 with tboot. When Linux has tboot support compiled in, booting as well as S3 suspend and resume are functional. However, SINIT will TXT reset when the iGPU is enabled, and using a dGPU will result in DMAR-related problems as soon as the IOMMU is enabled. However, SCLEAN seems to hang sometimes. This may be because the AP initialization that reference code does before SCLEAN is missing, but the ACM is still able to unblock the memory. Considering that SCLEAN is critical to recover an otherwise-bricked platform but is hardly ever necessary, prefer having a partially-working solution over none at all. Change-Id: I60beb7d79a30f460bbd5d94e4cba0244318c124e Signed-off-by: Angel Pons <th3fanbus@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/46608 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Diffstat (limited to 'src/security/intel/txt/common.c')
-rw-r--r--src/security/intel/txt/common.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/src/security/intel/txt/common.c b/src/security/intel/txt/common.c
index 88e2b5dddb..4dd4ad3ddf 100644
--- a/src/security/intel/txt/common.c
+++ b/src/security/intel/txt/common.c
@@ -290,6 +290,48 @@ static void *intel_txt_prepare_bios_acm(struct region_device *acm, size_t *acm_l
return acm_data;
}
+#define MCU_BASE_ADDR (TXT_BASE + 0x278)
+#define BIOACM_ADDR (TXT_BASE + 0x27c)
+#define APINIT_ADDR (TXT_BASE + 0x290)
+#define SEMAPHORE (TXT_BASE + 0x294)
+
+/* Returns on failure, resets the computer on success */
+void intel_txt_run_sclean(void)
+{
+ struct region_device acm;
+ size_t acm_len;
+
+ void *acm_data = intel_txt_prepare_bios_acm(&acm, &acm_len);
+
+ if (!acm_data)
+ return;
+
+ /* FIXME: Do we need to program these two? */
+ //write32((void *)MCU_BASE_ADDR, 0xffe1a990);
+ //write32((void *)APINIT_ADDR, 0xfffffff0);
+
+ write32((void *)BIOACM_ADDR, (uintptr_t)acm_data);
+ write32((void *)SEMAPHORE, 0);
+
+ /*
+ * The time SCLEAN will take depends on the installed RAM size.
+ * On Haswell with 8 GiB of DDR3, it takes five or ten minutes. (rough estimate)
+ */
+ printk(BIOS_ALERT, "TEE-TXT: Invoking SCLEAN. This can take several minutes.\n");
+
+ /*
+ * Invoke the BIOS ACM. If successful, the system will reset with memory unlocked.
+ */
+ getsec_sclean((uintptr_t)acm_data, acm_len);
+
+ /*
+ * However, if this function returns, the BIOS ACM could not be invoked. This is bad.
+ */
+ printk(BIOS_CRIT, "TEE-TXT: getsec_sclean could not launch the BIOS ACM.\n");
+
+ rdev_munmap(&acm, acm_data);
+}
+
/*
* Test all bits for TXT execution.
*