security/intel/txt: Add and use DPR register layout

This simplifies operations with this register's bitfields, and can also
be used by TXT-enabled platforms on the register in PCI config space.

Change-Id: I10a26bc8f4457158dd09e91d666fb29ad16a2087
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/46050
Reviewed-by: Patrick Rudolph <siro@das-labor.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/security/intel/txt/ramstage.c b/src/security/intel/txt/ramstage.c
index fb84777e..bc30da5 100644
--- a/src/security/intel/txt/ramstage.c
+++ b/src/security/intel/txt/ramstage.c
@@ -64,16 +64,14 @@
 			  TXT_PUBLIC_SPACE - TXT_PRIVATE_SPACE,
 			  BM_MEM_RESERVED);
 
-	const uint32_t txt_dev_memory = read32((void *)TXT_DPR) &
-			(TXT_DPR_TOP_ADDR_MASK << TXT_DPR_TOP_ADDR_SHIFT);
-	const uint32_t txt_dev_size =
-			(read32((void *)TXT_DPR) >> TXT_DPR_LOCK_SIZE_SHIFT) &
-			TXT_DPR_LOCK_SIZE_MASK;
+	const union dpr_register dpr = {
+		.raw = read32((void *)TXT_DPR),
+	};
+
+	const uint32_t dpr_base = dpr.top - dpr.size * MiB;
 
 	/* Chapter 5.5.6 Intel TXT Device Memory */
-	bootmem_add_range(txt_dev_memory - txt_dev_size * MiB,
-			  txt_dev_size * MiB,
-			  BM_MEM_RESERVED);
+	bootmem_add_range(dpr_base, dpr.size * MiB, BM_MEM_RESERVED);
 }
 
 static bool get_wake_error_status(void)
@@ -228,12 +226,15 @@
 	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) {
 
+	if (dpr_capable) {
 		/* Protect 3 MiB below TSEG and lock register */
-		write64((void *)TXT_DPR, (TXT_DPR_TOP_ADDR(tseg) |
-			TXT_DPR_LOCK_SIZE(3) |
-			TXT_DPR_LOCK_MASK));
+		union dpr_register dpr = {
+			.lock = 1,
+			.size = 3,
+			.top  = tseg,
+		};
+		write64((void *)TXT_DPR, dpr.raw);
 
 		// DPR TODO: implement SA_ENABLE_DPR in the intelblocks
 
diff --git a/src/security/intel/txt/txt_register.h b/src/security/intel/txt/txt_register.h
index bd546b5..bbf0a7e 100644
--- a/src/security/intel/txt/txt_register.h
+++ b/src/security/intel/txt/txt_register.h
@@ -91,15 +91,6 @@
 #define TXT_BIOSACM_ERRORCODE (TXT_BASE + 0x328)
 
 #define TXT_DPR (TXT_BASE + 0x330)
-#define  TXT_DPR_LOCK_SHIFT		0
-#define  TXT_DPR_LOCK_SIZE_SHIFT	4
-#define  TXT_DPR_LOCK_SIZE_MASK		0xff
-#define  TXT_DPR_TOP_ADDR_SHIFT		20
-#define  TXT_DPR_TOP_ADDR_MASK		0xfff
-
-#define  TXT_DPR_LOCK_MASK	(1 << TXT_DPR_LOCK_SHIFT)
-#define  TXT_DPR_LOCK_SIZE(x)	((x) << TXT_DPR_LOCK_SIZE_SHIFT)
-#define  TXT_DPR_TOP_ADDR(x)	((x) << TXT_DPR_TOP_ADDR_SHIFT)
 
 #define TXT_ACM_KEY_HASH (TXT_BASE + 0x400)
 #define  TXT_ACM_KEY_HASH_LEN 0x4
@@ -160,6 +151,20 @@
 /* MSRs */
 #define IA32_MCG_STATUS 0x17a
 
+/* DPR register layout, either in PCI config space or TXT MMIO space */
+union dpr_register {
+	struct {
+		uint32_t lock :  1; /* [ 0.. 0] */
+		uint32_t prs  :  1; /* [ 1.. 1] and only present on PCI config */
+		uint32_t epm  :  1; /* [ 2.. 2] and only present on PCI config */
+		uint32_t      :  1;
+		uint32_t size :  8; /* [11.. 4] */
+		uint32_t      :  8;
+		uint32_t top  : 12; /* [31..20] */
+	};
+	uint32_t raw;
+};
+
 typedef enum {
 	CHIPSET_ACM = 2,
 } acm_module_type;