amd/stoneyridge: Put stage cache into TSEG

Add a function to allow an external region to be located in TSEG.
Select the option to use memory outside of cbmem.  Increase the size
reserved in TSEG.

Change-Id: Ic1073af04475d862753136c9e14e2b2dde31fe66
Signed-off-by: Marshall Dawson <marshalldawson3rd@gmail.com>
Reviewed-on: https://review.coreboot.org/23519
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
diff --git a/src/soc/amd/stoneyridge/ramtop.c b/src/soc/amd/stoneyridge/ramtop.c
index e676465..24386ed 100644
--- a/src/soc/amd/stoneyridge/ramtop.c
+++ b/src/soc/amd/stoneyridge/ramtop.c
@@ -20,7 +20,9 @@
 #include <arch/io.h>
 #include <cpu/x86/msr.h>
 #include <cpu/amd/mtrr.h>
+#include <cpu/amd/amdfam15.h>
 #include <cbmem.h>
+#include <stage_cache.h>
 #include <soc/northbridge.h>
 #include <soc/southbridge.h>
 
@@ -56,12 +58,43 @@
 	return CONFIG_SMM_TSEG_SIZE;
 }
 
+void stage_cache_external_region(void **base, size_t *size)
+{
+	if (smm_subregion(SMM_SUBREGION_CACHE, base, size)) {
+		printk(BIOS_ERR, "ERROR: No cache SMM subregion.\n");
+		*base = NULL;
+		*size = 0;
+	}
+}
+
 void smm_region_info(void **start, size_t *size)
 {
 	*start = (void *)smm_region_start();
 	*size = smm_region_size();
 }
 
+/*
+ * For data stored in TSEG, ensure TValid is clear so R/W access can reach
+ * the DRAM when not in SMM.
+ */
+static void clear_tvalid(void)
+{
+	msr_t hwcr = rdmsr(HWCR_MSR);
+	msr_t mask = rdmsr(MSR_SMM_MASK);
+	int tvalid = !!(mask.lo & SMM_TSEG_VALID);
+
+	if (hwcr.lo & SMM_LOCK) {
+		if (!tvalid) /* not valid but locked means still accessible */
+			return;
+
+		printk(BIOS_ERR, "Error: can't clear TValid, already locked\n");
+		return;
+	}
+
+	mask.lo &= ~SMM_TSEG_VALID;
+	wrmsr(MSR_SMM_MASK, mask);
+}
+
 int smm_subregion(int sub, void **start, size_t *size)
 {
 	uintptr_t sub_base;
@@ -82,6 +115,7 @@
 		/* External cache is in the middle of TSEG. */
 		sub_base += sub_size - cache_size;
 		sub_size = cache_size;
+		clear_tvalid();
 		break;
 	default:
 		return -1;