feat(qemu): setup memory map for RME

Reserve some space in DRAM for RMM, and some space in SRAM for the GPT
tables. Create the page table mappings.

Change-Id: I3822e7e505e86eb0fa15b1b5b6298e4122b17181
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
diff --git a/plat/qemu/common/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c
index eb7da46..5ad553e 100644
--- a/plat/qemu/common/qemu_bl2_setup.c
+++ b/plat/qemu/common/qemu_bl2_setup.c
@@ -11,6 +11,7 @@
 
 #include <platform_def.h>
 
+#include <arch_features.h>
 #include <arch_helpers.h>
 #include <common/bl_common.h>
 #include <common/debug.h>
@@ -101,6 +102,18 @@
 		return;
 	}
 
+#if ENABLE_RME
+	if (fdt_add_reserved_memory(fdt, "rmm", REALM_DRAM_BASE,
+				    REALM_DRAM_SIZE)) {
+		ERROR("Failed to reserve RMM memory in Device Tree\n");
+		return;
+	}
+
+	INFO("Reserved RMM memory [0x%lx, 0x%lx] in Device tree\n",
+	     (uintptr_t)REALM_DRAM_BASE,
+	     (uintptr_t)REALM_DRAM_BASE + REALM_DRAM_SIZE - 1);
+#endif
+
 	ret = fdt_pack(fdt);
 	if (ret < 0)
 		ERROR("Failed to pack Device Tree at %p: error %d\n", fdt, ret);
@@ -146,16 +159,28 @@
 #if USE_COHERENT_MEM
 		MAP_BL_COHERENT_RAM,
 #endif
+#if ENABLE_RME
+		MAP_RMM_DRAM,
+		MAP_GPT_L0_REGION,
+		MAP_GPT_L1_REGION,
+#endif
 		{0}
 	};
 
 	setup_page_tables(bl_regions, plat_qemu_get_mmap());
 
+#if ENABLE_RME
+	/* BL2 runs in EL3 when RME enabled. */
+	assert(get_armv9_2_feat_rme_support() != 0U);
+	enable_mmu_el3(0);
+#else /* ENABLE_RME */
+
 #ifdef __aarch64__
 	enable_mmu_el1(0);
 #else
 	enable_mmu_svc_mon(0);
 #endif
+#endif /* ENABLE_RME */
 }
 
 /*******************************************************************************
diff --git a/plat/qemu/common/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c
index f309efd..0fe3993 100644
--- a/plat/qemu/common/qemu_bl31_setup.c
+++ b/plat/qemu/common/qemu_bl31_setup.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2023, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -97,6 +97,11 @@
 #if USE_COHERENT_MEM
 		MAP_BL_COHERENT_RAM,
 #endif
+#if ENABLE_RME
+		MAP_GPT_L0_REGION,
+		MAP_GPT_L1_REGION,
+		MAP_RMM_SHARED_MEM,
+#endif
 		{0}
 	};
 
diff --git a/plat/qemu/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h
index e7e30bc..4e0b50a 100644
--- a/plat/qemu/qemu/include/platform_def.h
+++ b/plat/qemu/qemu/include/platform_def.h
@@ -171,7 +171,8 @@
 #define BL32_SRAM_BASE			BL_RAM_BASE
 #define BL32_SRAM_LIMIT			BL31_BASE
 #define BL32_DRAM_BASE			SEC_DRAM_BASE
-#define BL32_DRAM_LIMIT			(SEC_DRAM_BASE + SEC_DRAM_SIZE)
+#define BL32_DRAM_LIMIT			(SEC_DRAM_BASE + SEC_DRAM_SIZE - \
+					 RME_GPT_DRAM_SIZE)
 
 #define SEC_SRAM_ID			0
 #define SEC_DRAM_ID			1
@@ -199,7 +200,7 @@
 
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ULL << 32)
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ULL << 32)
-#define MAX_MMAP_REGIONS		(11 + MAX_MMAP_REGIONS_SPMC)
+#define MAX_MMAP_REGIONS		(13 + MAX_MMAP_REGIONS_SPMC)
 #define MAX_XLAT_TABLES			(6 + MAX_XLAT_TABLES_SPMC)
 #define MAX_IO_DEVICES			4
 #define MAX_IO_HANDLES			4
@@ -338,4 +339,72 @@
 #define MAX_MMAP_REGIONS_SPMC		0
 #define MAX_XLAT_TABLES_SPMC		0
 #endif
+
+#if ENABLE_RME
+
+/*
+ * Reserve some space at the end of secure DRAM for the Granule Protection
+ * Tables
+ */
+#define PLAT_QEMU_L0_GPT_BASE		(PLAT_QEMU_L1_GPT_BASE -	\
+					 PLAT_QEMU_L0_GPT_SIZE)
+#define PLAT_QEMU_L0_GPT_SIZE		(2 * PAGE_SIZE)
+
+#define PLAT_QEMU_L1_GPT_BASE		(SEC_DRAM_BASE + SEC_DRAM_SIZE - \
+					 PLAT_QEMU_L1_GPT_SIZE)
+#define PLAT_QEMU_L1_GPT_END		(PLAT_QEMU_L1_GPT_BASE +	\
+					 PLAT_QEMU_L1_GPT_SIZE - 1U)
+#define PLAT_QEMU_L1_GPT_SIZE		UL(0x00100000)	/* 1MB */
+
+#define RME_GPT_DRAM_BASE		PLAT_QEMU_L0_GPT_BASE
+#define RME_GPT_DRAM_SIZE		(PLAT_QEMU_L1_GPT_SIZE +	\
+					 PLAT_QEMU_L0_GPT_SIZE)
+
+#ifndef __ASSEMBLER__
+/* L0 table greater than 4KB must be naturally aligned */
+CASSERT((PLAT_QEMU_L0_GPT_BASE & (PLAT_QEMU_L0_GPT_SIZE - 1)) == 0,
+	assert_l0_gpt_naturally_aligned);
+#endif
+
+/* Reserved some DRAM space for RMM (24MB) */
+#define REALM_DRAM_BASE			(NS_DRAM0_BASE + PLAT_QEMU_DT_MAX_SIZE)
+#define REALM_DRAM_SIZE			0x01800000
+
+#define PLAT_QEMU_RMM_SIZE		(REALM_DRAM_SIZE - RMM_SHARED_SIZE)
+#define PLAT_QEMU_RMM_SHARED_SIZE	(PAGE_SIZE)	/* 4KB */
+
+#define RMM_BASE			(REALM_DRAM_BASE)
+#define RMM_LIMIT			(RMM_BASE + PLAT_QEMU_RMM_SIZE)
+#define RMM_SHARED_BASE			(RMM_LIMIT)
+#define RMM_SHARED_SIZE			PLAT_QEMU_RMM_SHARED_SIZE
+
+#define MAP_GPT_L0_REGION	MAP_REGION_FLAT(			\
+					PLAT_QEMU_L0_GPT_BASE,		\
+					PLAT_QEMU_L0_GPT_SIZE,		\
+					MT_MEMORY | MT_RW | EL3_PAS)
+
+#define MAP_GPT_L1_REGION	MAP_REGION_FLAT(			\
+					PLAT_QEMU_L1_GPT_BASE,		\
+					PLAT_QEMU_L1_GPT_SIZE,		\
+					MT_MEMORY | MT_RW | EL3_PAS)
+/*
+ * We add the RMM_SHARED size to RMM mapping to map the region as a block.
+ * Else we end up requiring more pagetables in BL2 for ROMLIB build.
+ */
+#define MAP_RMM_DRAM		MAP_REGION_FLAT(			\
+					RMM_BASE,			\
+					(PLAT_QEMU_RMM_SIZE +		\
+					 RMM_SHARED_SIZE),		\
+					MT_MEMORY | MT_RW | MT_REALM)
+
+#define MAP_RMM_SHARED_MEM	MAP_REGION_FLAT(			\
+					RMM_SHARED_BASE,		\
+					RMM_SHARED_SIZE,		\
+					MT_MEMORY | MT_RW | MT_REALM)
+#else /* !ENABLE_RME */
+
+#define RME_GPT_DRAM_SIZE		0
+
+#endif /* ENABLE_RME */
+
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/qemu/qemu/include/qemu_pas_def.h b/plat/qemu/qemu/include/qemu_pas_def.h
new file mode 100644
index 0000000..c108920
--- /dev/null
+++ b/plat/qemu/qemu/include/qemu_pas_def.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2024, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+#ifndef QEMU_PAS_DEF_H
+#define QEMU_PAS_DEF_H
+
+#include <lib/gpt_rme/gpt_rme.h>
+#include "platform_def.h"
+
+/*****************************************************************************
+ * PAS regions used to initialize the Granule Protection Table (GPT)
+ ****************************************************************************/
+
+/*
+ * The PA space is initially mapped in the GPT as follows:
+ *
+ * ===========================================================================
+ * Base Addr   | Size    |L? GPT|PAS   |Content          |Comment
+ * ===========================================================================
+ *             | 1GB     |L0 GPT|ANY   |Flash            |
+ *    00000000 |         |      |      |IO               |
+ * ---------------------------------------------------------------------------
+ *       224MB | 1KB     |L0 GPT|ANY   |Secure RAM (EL3) |
+ *    0e000000 |         |      |      |  (shared)       |
+ * ---------------------------------------------------------------------------
+ *             | 1MB-1KB |L1 GPT|ROOT  |Secure RAM (EL3) |
+ *    0e001000 |         |      |      |                 |
+ * ---------------------------------------------------------------------------
+ *       225MB | 14MB    |L1 GPT|SECURE|Secure RAM       |
+ *    0e100000 |         |      |      |  (EL2, EL1)     |
+ * ---------------------------------------------------------------------------
+ *             | 1MB+8KB |L1 GPT|ROOT  |L0 and L1 GPTs   |
+ *    0eefe000 |         |      |      |                 |
+ * ---------------------------------------------------------------------------
+ *       240MB | 800MB   |L0 GPT|ANY   |IO               |
+ *    0f000000 |         |      |      |                 |
+ * ---------------------------------------------------------------------------
+ *         1GB | 1MB     |L1 GPT|NS    |DRAM             |
+ *    40000000 |         |      |      | (device tree)   |
+ * ---------------------------------------------------------------------------
+ *     1GB+1MB | 24MB    |L1 GPT|REALM |DRAM (RMM)       |
+ *    40100000 |         |      |      |                 |
+ * ---------------------------------------------------------------------------
+ *    1GB+25MB | 3GB     |L1 GPT|NS    |DRAM (kernel)    | Limit set by
+ *    41900000 |         |      |      |                 |  NS_DRAM0_SIZE
+ * ---------------------------------------------------------------------------
+ *       256GB | 512+GB  |L0 GPT|ANY   |IO               | Floating. Higher
+ * 40000000000 |         |      |      |                 |  when RAM>256GB
+ * ----------------------------------------------------------------------------
+ */
+
+/* EL3 SRAM */
+#define QEMU_PAS_ROOT_BASE		BL_RAM_BASE
+#define QEMU_PAS_ROOT_SIZE		BL_RAM_SIZE
+
+/* Secure DRAM */
+#define QEMU_PAS_SEC_BASE		SEC_DRAM_BASE
+#define QEMU_PAS_SEC_SIZE		(SEC_DRAM_SIZE - RME_GPT_DRAM_SIZE)
+
+/* GPTs */
+#define QEMU_PAS_GPT_BASE		RME_GPT_DRAM_BASE
+#define QEMU_PAS_GPT_SIZE		RME_GPT_DRAM_SIZE
+
+/* RMM */
+#define QEMU_PAS_RMM_BASE		RMM_BASE
+#define QEMU_PAS_RMM_SIZE		PLAT_QEMU_RMM_SIZE
+
+/* Shared area between EL3 and RMM */
+#define QEMU_PAS_RMM_SHARED_BASE	RMM_SHARED_BASE
+#define QEMU_PAS_RMM_SHARED_SIZE	RMM_SHARED_SIZE
+
+#define QEMU_PAS_NS0_BASE		NS_DRAM0_BASE
+#define QEMU_PAS_NS0_SIZE		PLAT_QEMU_DT_MAX_SIZE
+#define QEMU_PAS_NS1_BASE		(REALM_DRAM_BASE + REALM_DRAM_SIZE)
+#define QEMU_PAS_NS1_SIZE		(NS_DRAM0_SIZE - \
+					 (QEMU_PAS_NS0_SIZE + REALM_DRAM_SIZE))
+
+#define QEMU_PAS_ROOT			GPT_MAP_REGION_GRANULE(QEMU_PAS_ROOT_BASE, \
+							       QEMU_PAS_ROOT_SIZE, \
+							       GPT_GPI_ROOT)
+
+#define QEMU_PAS_SECURE			GPT_MAP_REGION_GRANULE(QEMU_PAS_SEC_BASE, \
+							       QEMU_PAS_SEC_SIZE, \
+							       GPT_GPI_SECURE)
+
+#define QEMU_PAS_GPTS			GPT_MAP_REGION_GRANULE(QEMU_PAS_GPT_BASE, \
+							       QEMU_PAS_GPT_SIZE, \
+							       GPT_GPI_ROOT)
+
+#define QEMU_PAS_NS0			GPT_MAP_REGION_GRANULE(QEMU_PAS_NS0_BASE, \
+							       QEMU_PAS_NS0_SIZE, \
+							       GPT_GPI_NS)
+
+#define QEMU_PAS_NS1			GPT_MAP_REGION_GRANULE(QEMU_PAS_NS1_BASE, \
+							       QEMU_PAS_NS1_SIZE, \
+							       GPT_GPI_NS)
+
+#define QEMU_PAS_REALM			GPT_MAP_REGION_GRANULE(QEMU_PAS_RMM_BASE, \
+							       QEMU_PAS_RMM_SIZE + \
+							       QEMU_PAS_RMM_SHARED_SIZE, \
+							       GPT_GPI_REALM)
+
+/* GPT Configuration options */
+#define PLATFORM_L0GPTSZ		GPCCR_L0GPTSZ_30BITS
+
+#endif /* QEMU_PAS_DEF_H */
diff --git a/plat/qemu/qemu/platform.mk b/plat/qemu/qemu/platform.mk
index e902c12..436e425 100644
--- a/plat/qemu/qemu/platform.mk
+++ b/plat/qemu/qemu/platform.mk
@@ -204,6 +204,10 @@
 BL32_RAM_LOCATION	:=	tdram
 ifeq (${BL32_RAM_LOCATION}, tsram)
   BL32_RAM_LOCATION_ID = SEC_SRAM_ID
+  ifeq (${ENABLE_RME},1)
+	# Avoid overlap between BL2 and BL32 to ease GPT partition
+	$(error "With RME, BL32 must use secure DRAM")
+  endif
 else ifeq (${BL32_RAM_LOCATION}, tdram)
   BL32_RAM_LOCATION_ID = SEC_DRAM_ID
 else