[coreboot-gerrit] Patch set updated for coreboot: 5560a56 tegra132: Add Trust Zone register access

Marc Jones (marc.jones@se-eng.com) gerrit at coreboot.org
Fri Mar 13 00:14:48 CET 2015


Marc Jones (marc.jones at se-eng.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/8648

-gerrit

commit 5560a5653d476b64164809102c323411fd1c8870
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Mon Jul 21 14:24:42 2014 -0500

    tegra132: Add Trust Zone register access
    
    The Trust Zone carveout registers are only accessible using
    a secure access mode. The AVP runs as non-secure all the time.
    In EL3 the CPU is in secure mode, but when the MMU is enabled
    the page tables dictate if accesses to certain regions are
    secure or not. However, ramstage is currently being loaded
    into non-secure memory and the page tables will live in
    non-secure memory as well. Therefore, handle all these
    cases by providing global state which mirrors the TZ
    register.
    
    BUG=chrome-os-partner:30782
    BRANCH=None
    TEST=Built and ran through ramstage with the MMU enabled
         Resources are read and set accordingly.
    
    Original-Change-Id: Ib76b2641497a29ef2adb75934b2df55ecf0b3e78
    Original-Signed-off-by: Aaron Durbin <adurbin at chromium.org>
    Original-Reviewed-on: https://chromium-review.googlesource.com/209061
    Original-Reviewed-by: Furquan Shaikh <furquan at chromium.org>
    Original-Commit-Queue: Furquan Shaikh <furquan at chromium.org>
    (cherry picked from commit 0bcbdc56978f6ebe3e7d1b74ed2fd861e03bb562)
    Signed-off-by: Marc Jones <marc.jones at se-eng.com>
    
    Change-Id: I9c1beed443a48870ba190427e87caf90caf4ff6b
---
 src/soc/nvidia/tegra132/addressmap.c             | 55 ++++++++++++++++--------
 src/soc/nvidia/tegra132/include/soc/addressmap.h |  9 ++++
 src/soc/nvidia/tegra132/ramstage.c               | 23 +---------
 src/soc/nvidia/tegra132/romstage.c               | 11 +++++
 4 files changed, 58 insertions(+), 40 deletions(-)

diff --git a/src/soc/nvidia/tegra132/addressmap.c b/src/soc/nvidia/tegra132/addressmap.c
index 7dbab55..6537187 100644
--- a/src/soc/nvidia/tegra132/addressmap.c
+++ b/src/soc/nvidia/tegra132/addressmap.c
@@ -27,6 +27,9 @@
 #include "mc.h"
 #include "sdram.h"
 
+static uintptr_t tz_base_mib;
+static const size_t tz_size_mib = CONFIG_TRUSTZONE_CARVEOUT_SIZE_MB;
+
 /* returns total amount of DRAM (in MB) from memory controller registers */
 int sdram_size_mb(void)
 {
@@ -71,13 +74,8 @@ void carveout_range(int id, uintptr_t *base_mib, size_t *size_mib)
 
 	switch (id) {
 	case CARVEOUT_TZ:
-		/* AVP does not have access to the TZ carveout registers. */
-		if (context_avp())
-			return;
-		carveout_from_regs(base_mib, size_mib,
-					read32(&mc->security_cfg0),
-					0,
-					read32(&mc->security_cfg1));
+		*base_mib = tz_base_mib;
+		*size_mib = tz_size_mib;
 		break;
 	case CARVEOUT_SEC:
 		carveout_from_regs(base_mib, size_mib,
@@ -102,7 +100,8 @@ void carveout_range(int id, uintptr_t *base_mib, size_t *size_mib)
 	}
 }
 
-static void memory_in_range(uintptr_t *base_mib, uintptr_t *end_mib)
+static void memory_in_range(uintptr_t *base_mib, uintptr_t *end_mib,
+				int ignore_tz)
 {
 	uintptr_t base;
 	uintptr_t end;
@@ -128,6 +127,9 @@ static void memory_in_range(uintptr_t *base_mib, uintptr_t *end_mib)
 		uintptr_t carveout_end;
 		size_t carveout_size;
 
+		if (i == CARVEOUT_TZ && ignore_tz)
+			continue;
+
 		carveout_range(i, &carveout_base, &carveout_size);
 
 		if (carveout_size == 0)
@@ -155,14 +157,14 @@ void memory_in_range_below_4gb(uintptr_t *base_mib, uintptr_t *end_mib)
 {
 	*base_mib = 0;
 	*end_mib = 4096;
-	memory_in_range(base_mib, end_mib);
+	memory_in_range(base_mib, end_mib, 0);
 }
 
 void memory_in_range_above_4gb(uintptr_t *base_mib, uintptr_t *end_mib)
 {
 	*base_mib = 4096;
 	*end_mib = ~0UL;
-	memory_in_range(base_mib, end_mib);
+	memory_in_range(base_mib, end_mib, 0);
 }
 
 uintptr_t framebuffer_attributes(size_t *size_mib)
@@ -173,16 +175,33 @@ uintptr_t framebuffer_attributes(size_t *size_mib)
 	/* Place the framebuffer just below the 32-bit addressable limit. */
 	memory_in_range_below_4gb(&begin, &end);
 
-	/*
-	 * Need to take into account that the Trust Zone region is not able to
-	 * be read by the AVP. The Trust Zone region will live just below the
-	 * rest of the carveout regions.
-	 */
-	if (context_avp())
-		end -= CONFIG_TRUSTZONE_CARVEOUT_SIZE_MB;
-
 	*size_mib = FB_SIZE_MB;
 	end -= *size_mib;
 
 	return end;
 }
+
+void trustzone_region_init(void)
+{
+	struct tegra_mc_regs * const mc = (void *)(uintptr_t)TEGRA_MC_BASE;
+	uintptr_t end = 4096;
+
+	/* Already has been initialized. */
+	if (tz_size_mib != 0 && tz_base_mib != 0)
+		return;
+
+	/*
+	 * Get memory layout below 4GiB ignoring the TZ carveout because
+	 * that's the one to initialize.
+	 */
+	memory_in_range(&tz_base_mib, &end, 1);
+	tz_base_mib = end - tz_size_mib;
+
+	/* AVP cannot set the TZ registers proper as it is always non-secure. */
+	if (context_avp())
+		return;
+
+	/* Set the carveout region. */
+	write32(tz_base_mib << 20, &mc->security_cfg0);
+	write32(tz_size_mib, &mc->security_cfg1);
+}
diff --git a/src/soc/nvidia/tegra132/include/soc/addressmap.h b/src/soc/nvidia/tegra132/include/soc/addressmap.h
index 3d0fc59..52e4d54 100644
--- a/src/soc/nvidia/tegra132/include/soc/addressmap.h
+++ b/src/soc/nvidia/tegra132/include/soc/addressmap.h
@@ -99,6 +99,15 @@ enum {
 /* Provided the careout id, obtain the base and size in 1MiB units. */
 void carveout_range(int id, uintptr_t *base_mib, size_t *size_mib);
 
+/*
+ * There are complications accessing the Trust Zone carveout region. The
+ * AVP cannot access these registers and the CPU can't access this register
+ * as a non-secure access. When the page tables live in non-secure memory
+ * these registers cannot be accessed either. Thus, this function handles
+ * both the AVP case and non-secured access case by keeping global state.
+ */
+void trustzone_region_init(void);
+
 /* Return pointer and size in 1MiB units. */
 uintptr_t framebuffer_attributes(size_t *size_mib);
 
diff --git a/src/soc/nvidia/tegra132/ramstage.c b/src/soc/nvidia/tegra132/ramstage.c
index ad553d4..b3b4db2 100644
--- a/src/soc/nvidia/tegra132/ramstage.c
+++ b/src/soc/nvidia/tegra132/ramstage.c
@@ -17,34 +17,13 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <arch/io.h>
 #include <arch/stages.h>
 #include <soc/addressmap.h>
-#include "mc.h"
 #include "mmu_operations.h"
 
 void arm64_soc_init(void)
 {
-	struct tegra_mc_regs * const mc = (void *)(uintptr_t)TEGRA_MC_BASE;
-	const size_t tz_size_mib = CONFIG_TRUSTZONE_CARVEOUT_SIZE_MB;
-	uintptr_t base;
-	uintptr_t end;
-
-	if (!tz_size_mib)
-		return;
-
-	/*
-	 * Ramstage is when the arm64 first gets running. It also is the
-	 * only entity that the capabilities to program the Trust Zone region.
-	 * Therefore configure the region early. Also, the TZ region can only
-	 * live in 32-bit space.
-	 */
-	memory_in_range_below_4gb(&base, &end);
-
-	/* Place the TZ area just below current carveout regions. */
-	end -= tz_size_mib;
-	write32(end << 20, &mc->security_cfg0);
-	write32(tz_size_mib, &mc->security_cfg1);
+	trustzone_region_init();
 
 	tegra132_mmu_init();
 }
diff --git a/src/soc/nvidia/tegra132/romstage.c b/src/soc/nvidia/tegra132/romstage.c
index 2a1bd46..4b1c843 100644
--- a/src/soc/nvidia/tegra132/romstage.c
+++ b/src/soc/nvidia/tegra132/romstage.c
@@ -24,6 +24,7 @@
 #include <console/console.h>
 #include <arch/exception.h>
 
+#include <soc/addressmap.h>
 #include <soc/sdram_configs.h>
 #include "sdram.h"
 #include "ccplex.h"
@@ -45,6 +46,16 @@ void romstage(void)
 	sdram_init(get_sdram_config());
 	printk(BIOS_INFO, "T132 romstage: sdram_init done\n");
 #endif
+
+	/*
+	 * Trust Zone needs to be initialized after the DRAM initialization
+	 * because carveout registers are programmed during DRAM init.
+	 * cbmem_initialize() is dependent on the Trust Zone region
+	 * initalization because CBMEM lives right below the Trust Zone which
+	 * needs to be properly identified.
+	 */
+	trustzone_region_init();
+
 	cbmem_initialize();
 
 	ccplex_cpu_prepare();



More information about the coreboot-gerrit mailing list