Angel Pons submitted this change.

View Change

Approvals: build bot (Jenkins): Verified Arthur Heymans: Looks good to me, approved
sec/intel/txt: Add support for running SCLEAN in romstage

SCLEAN has specific requirements and needs to run in early romstage,
since the DRAM would be locked when SCLEAN needs to be executed.

Change-Id: I77b237342e0c98eda974f87944f1948d197714db
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/46607
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
---
M src/security/intel/txt/Makefile.inc
A src/security/intel/txt/getsec_sclean.S
M src/security/intel/txt/txt_getsec.h
3 files changed, 186 insertions(+), 0 deletions(-)

diff --git a/src/security/intel/txt/Makefile.inc b/src/security/intel/txt/Makefile.inc
index 712ab58..762256f 100644
--- a/src/security/intel/txt/Makefile.inc
+++ b/src/security/intel/txt/Makefile.inc
@@ -1,5 +1,7 @@
ifeq ($(CONFIG_INTEL_TXT),y)

+romstage-y += getsec_sclean.S
+
romstage-y += common.c
romstage-$(CONFIG_INTEL_TXT_LOGGING) += logging.c

diff --git a/src/security/intel/txt/getsec_sclean.S b/src/security/intel/txt/getsec_sclean.S
new file mode 100644
index 0000000..e240a2f
--- /dev/null
+++ b/src/security/intel/txt/getsec_sclean.S
@@ -0,0 +1,181 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#include <cpu/x86/cr.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/msr.h>
+
+#include "getsec_mtrr_setup.inc"
+
+#define MTRR_HIGH_MASK $((1 << (CONFIG_CPU_ADDR_BITS - 32)) - 1)
+
+#define NO_EVICT_MODE 0x2e0
+
+.align 4
+.text
+
+/*
+ * void getsec_sclean(const uint32_t acm_base, const uint32_t acm_size);
+ */
+.global getsec_sclean
+getsec_sclean:
+ /*
+ * At this point, it is certain that the BIOS ACM will be run.
+ * This requires tearing down CAR, which cannot be undone.
+ *
+ * From here onwards, the only way out is to reset the system.
+ */
+
+ /* Enable SMXE, SSE and debug extensions */
+ movl %cr4, %eax
+ orl $(CR4_OSFXSR | CR4_DE | CR4_SMXE), %eax
+ movl %eax, %cr4
+
+ /*
+ * Save arguments into SSE registers. We need to tear down CAR
+ * before launching the BIOS ACM, which will destroy the stack.
+ */
+ movd 4(%esp), %xmm2 /* acm_base */
+ movd 8(%esp), %xmm3 /* acm_size */
+
+ /* Disable cache */
+ movl %cr0, %eax
+ orl $(CR0_CD | CR0_NE), %eax
+ andl $(~(CR0_NW)), %eax
+ movl %eax, %cr0
+
+ /* Invalidate the cache */
+ invd
+
+ /* Disable MTRRs */
+ movl $(MTRR_DEF_TYPE_MSR), %ecx
+ xorl %eax, %eax
+ xorl %edx, %edx
+ wrmsr
+
+ /* Disable NEM, needs to be done in two steps */
+ movl $NO_EVICT_MODE, %ecx
+ rdmsr
+ andl $~2, %eax /* Clear NEM Run bit */
+ wrmsr
+ andl $~1, %eax /* Clear NEM Setup bit */
+ wrmsr
+
+ /* Invalidate the cache, again */
+ invd
+
+ /*
+ * Clear variable MTRRs
+ * Chapter 2.2.5.1
+ * Intel TXT Software Development Guide (Document: 315168-015)
+ */
+ movl $(MTRR_CAP_MSR), %ecx
+ rdmsr
+ andl $(0xff), %eax
+ movl %eax, %ebx
+
+ xorl %eax, %eax
+ xorl %edx, %edx
+
+ jmp cond_clear_var_mtrrs
+
+body_clear_var_mtrrs:
+
+ decl %ebx
+ movl %ebx, %ecx
+ shll %ecx
+ addl $(MTRR_PHYS_BASE(0)), %ecx
+ wrmsr
+ incl %ecx /* MTRR_PHYS_MASK */
+ wrmsr
+
+cond_clear_var_mtrrs:
+
+ cmpl $0, %ebx
+ jnz body_clear_var_mtrrs
+
+ /*
+ * Setup BIOS ACM as WB
+ * Chapter A.1.1
+ * Intel TXT Software Development Guide (Document: 315168-015)
+ */
+
+ /* Determine size of AC module */
+ movd %xmm2, %eax /* acm_base */
+ movd %xmm3, %ebx /* acm_size */
+
+ /* Round up to page size */
+ addl $(0xfff), %ebx
+ andl $(~0xfff), %ebx /* Aligned to a page (4 KiB) */
+
+ /* Use SSE registers to store local variables */
+ movd %eax, %xmm0
+ movd %ebx, %xmm1
+
+ /*
+ * Important note: The MTRRs must cache less than a page (4 KiB)
+ * of unused memory after the BIOS ACM. Not doing so on Haswell
+ * will cause a TXT reset with Class Code 5, Major Error Code 2.
+ *
+ * The caller must have checked that there are enough variable
+ * MTRRs to cache the ACM size prior to invoking this routine.
+ */
+ SET_UP_MTRRS_FOR_BIOS_ACM
+
+ /* Enable variable MTRRs */
+ movl $MTRR_DEF_TYPE_MSR, %ecx
+ rdmsr
+ orl $MTRR_DEF_TYPE_EN, %eax
+ wrmsr
+
+ /* Enable cache - CR0_NW is and stays clear */
+ movl %cr0, %eax
+ andl $~(CR0_CD), %eax
+ movl %eax, %cr0
+
+ /*
+ * Get function arguments.
+ * It's important to pass the exact ACM size as it's used by getsec to verify
+ * the integrity of ACM. Unlike the size for MTRR programming, which needs to
+ * be power of two.
+ *
+ * Note: Do not forget that CAR has been torn down, so the stack doesn't exist.
+ */
+ movl $2, %eax /* GETSEC[ENTERACCS] */
+ movd %xmm2, %ebx /* acm_base */
+ movd %xmm3, %ecx /* acm_size */
+ movl $0, %edx /* reserved, must be zero */
+ movl $0, %edi /* must be zero */
+ movl $0, %esi /* SCLEAN */
+
+ getsec
+
+ /*
+ * The platform state after SCLEAN is undefined. The only sane
+ * thing to do afterwards is to reset the platform. Note that
+ * the BIOS ACM should already reset the platform, so this code
+ * may not always be reached, but keep it here just to be sure.
+ */
+#if 1
+ movw $0xcf8, %dx
+ movl $0x8000F8AC, %eax
+ outl %eax, %dx
+
+ movw $0xcfc, %dx
+ inl %dx, %eax
+ andl $~(1 << 20), %eax
+ outl %eax, %dx
+#endif
+
+ movw $0xcf9, %dx
+ movb $0, %al
+ outb %al, %dx
+
+ movw $0xcf9, %dx
+ movb $0x0e, %al
+ outb %al, %dx
+
+ cli
+
+ hlt
+
+ ret
diff --git a/src/security/intel/txt/txt_getsec.h b/src/security/intel/txt/txt_getsec.h
index 78171a7..f949c7d 100644
--- a/src/security/intel/txt/txt_getsec.h
+++ b/src/security/intel/txt/txt_getsec.h
@@ -20,4 +20,7 @@
const uint32_t acm_base,
const uint32_t acm_size);

+void getsec_sclean(const uint32_t acm_base,
+ const uint32_t acm_size);
+
#endif /* SECURITY_INTEL_TXT_REGISTER_H_ */

To view, visit change 46607. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I77b237342e0c98eda974f87944f1948d197714db
Gerrit-Change-Number: 46607
Gerrit-PatchSet: 7
Gerrit-Owner: Angel Pons <th3fanbus@gmail.com>
Gerrit-Reviewer: Angel Pons <th3fanbus@gmail.com>
Gerrit-Reviewer: Arthur Heymans <arthur@aheymans.xyz>
Gerrit-Reviewer: Christian Walter <christian.walter@9elements.com>
Gerrit-Reviewer: Martin Roth <martinroth@google.com>
Gerrit-Reviewer: Patrick Georgi <pgeorgi@google.com>
Gerrit-Reviewer: Patrick Rudolph <patrick.rudolph@9elements.com>
Gerrit-Reviewer: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
Gerrit-Reviewer: build bot (Jenkins) <no-reply@coreboot.org>
Gerrit-CC: Patrick Rudolph <siro@das-labor.org>
Gerrit-CC: Paul Menzel <paulepanter@users.sourceforge.net>
Gerrit-MessageType: merged