refactor(qemu): move GPT setup to BL31

Some platforms such as QEMU-SBSA access the device tree located at the
bottom of the non-secure RAM from BL31.  When GPT checks are enabled at
BL2, that access generates a GPT check fault because the device tree
area is configure as non-secure RAM and the access is made from secure
EL3.

We could change the device tree memory area configuration in a way that
it is accessible from BL31, but that would require another configuration
of the GPT before going to BL33.

Since BL2 and BL31 are both running at EL3, a better solution is simply
move the GPT configuration and enabling to BL31, after the device tree
has been probed.

No change in functionality.

Change-Id: Ifa01c50164268b993d563c32e4e42140259c44e2
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
[Added changelog description]
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
diff --git a/plat/qemu/common/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c
index 0a70cc2..961f87c 100644
--- a/plat/qemu/common/qemu_bl31_setup.c
+++ b/plat/qemu/common/qemu_bl31_setup.c
@@ -11,6 +11,9 @@
 #include <lib/gpt_rme/gpt_rme.h>
 #include <lib/transfer_list.h>
 #include <plat/common/platform.h>
+#if ENABLE_RME
+#include <qemu_pas_def.h>
+#endif
 
 #include "qemu_private.h"
 
@@ -109,6 +112,54 @@
 		bl31_tl = (void *)arg3; /* saved TL address from BL2 */
 	}
 }
+
+#if ENABLE_RME
+static void bl31_plat_gpt_setup(void)
+{
+	/*
+	 * The GPT library might modify the gpt regions structure to optimize
+	 * the layout, so the array cannot be constant.
+	 */
+	pas_region_t pas_regions[] = {
+		QEMU_PAS_ROOT,
+		QEMU_PAS_SECURE,
+		QEMU_PAS_GPTS,
+		QEMU_PAS_NS0,
+		QEMU_PAS_REALM,
+		QEMU_PAS_NS1,
+	};
+
+	/*
+	 * Initialize entire protected space to GPT_GPI_ANY. With each L0 entry
+	 * covering 1GB (currently the only supported option), then covering
+	 * 256TB of RAM (48-bit PA) would require a 2MB L0 region. At the
+	 * moment we use a 8KB table, which covers 1TB of RAM (40-bit PA).
+	 */
+	if (gpt_init_l0_tables(GPCCR_PPS_1TB, PLAT_QEMU_L0_GPT_BASE,
+			       PLAT_QEMU_L0_GPT_SIZE +
+			       PLAT_QEMU_GPT_BITLOCK_SIZE) < 0) {
+		ERROR("gpt_init_l0_tables() failed!\n");
+		panic();
+	}
+
+	/* Carve out defined PAS ranges. */
+	if (gpt_init_pas_l1_tables(GPCCR_PGS_4K,
+				   PLAT_QEMU_L1_GPT_BASE,
+				   PLAT_QEMU_L1_GPT_SIZE,
+				   pas_regions,
+				   (unsigned int)(sizeof(pas_regions) /
+						  sizeof(pas_region_t))) < 0) {
+		ERROR("gpt_init_pas_l1_tables() failed!\n");
+		panic();
+	}
+
+	INFO("Enabling Granule Protection Checks\n");
+	if (gpt_enable() < 0) {
+		ERROR("gpt_enable() failed!\n");
+		panic();
+	}
+}
+#endif
 
 void bl31_plat_arch_setup(void)
 {
@@ -131,6 +182,9 @@
 	enable_mmu_el3(0);
 
 #if ENABLE_RME
+	/* Initialise and enable granule protection after MMU. */
+	bl31_plat_gpt_setup();
+
 	/*
 	 * Initialise Granule Protection library and enable GPC for the primary
 	 * processor. The tables have already been initialized by a previous BL