MA-11015 Support Trusty OS on imx8qm/qxp

The Trusty OS binary will be installed into
container.img and loaded into  0x84000000.

Due Trusty OS addresss is in 0xfe000000 which
ROM cannot reach, so use ATF to copy it into
the target address.
Mapped the BL32 code into MMU due the Trusty
SPD need to check the code status and decide
the CPU executing mode.

To reserve and protect the memory for secure
world, modify the partition code to keep
BL32 spaces in secure_part.

Signed-off-by: Haoran.Wang <elven.wang@nxp.com>
Reviewed-by: Ye Li <ye.li@nxp.com>
(cherry picked from commit d305ece47bf3e90b5008bf5932583ee2a772650b)
diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c
index 881c3c6..092d20a 100644
--- a/plat/imx/imx8qm/imx8qm_bl31_setup.c
+++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c
@@ -23,6 +23,9 @@
 #include <sec_rsrc.h>
 #include <stdbool.h>
 #include <xlat_tables.h>
+#include <string.h>
+
+#define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
 
 IMPORT_SYM(unsigned long, __COHERENT_RAM_START__, BL31_COHERENT_RAM_START);
 IMPORT_SYM(unsigned long, __COHERENT_RAM_END__, BL31_COHERENT_RAM_END);
@@ -154,10 +157,15 @@
 {
 	sc_rm_pt_t secure_part, os_part;
 	sc_rm_mr_t mr, mr_record = 64;
-	sc_faddr_t start, end;
+	sc_faddr_t start, end, reg_end;
 	bool owned, owned2;
 	sc_err_t err;
 	int i;
+#ifdef SPD_trusty
+	sc_rm_mr_t mr_tee = 64;
+	bool mr_tee_atf_same = false;
+	sc_faddr_t reg_start;
+#endif
 
 	err = sc_rm_get_partition(ipc_handle, &secure_part);
 
@@ -185,44 +193,110 @@
 		owned = sc_rm_is_memreg_owned(ipc_handle, mr);
 		if (owned) {
 			err = sc_rm_get_memreg_info(ipc_handle, mr, &start, &end);
-			if (err)
+			if (err) {
 				ERROR("Memreg get info failed, %u\n", mr);
-			NOTICE("Memreg %u 0x%llx -- 0x%llx\n", mr, start, end);
-			if (BL31_BASE >= start && (BL31_LIMIT - 1) <= end) {
-				mr_record = mr; /* Record the mr for ATF running */
 			} else {
-				err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
-				if (err)
-					ERROR("Memreg assign failed, 0x%llx -- 0x%llx, \
-						err %d\n", start, end, err);
+				NOTICE("Memreg %u 0x%llx -- 0x%llx\n", mr, start, end);
+
+				if (BL31_BASE >= start && (BL31_LIMIT - 1) <= end) {
+					mr_record = mr; /* Record the mr for ATF running */
+				}
+#ifdef SPD_trusty
+				else if (BL32_BASE >= start && (BL32_LIMIT -1) <= end) {
+					mr_tee = mr;
+				}
+#endif
+				else {
+					err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
+					if (err)
+						ERROR("Memreg assign failed, 0x%llx -- 0x%llx, err %d\n", start, end, err);
+				}
 			}
 		}
 	}
 
+#ifdef SPD_trusty
+	if (mr_tee != 64) {
+		err = sc_rm_get_memreg_info(ipc_handle, mr_tee, &start, &end);
+		if (err) {
+			ERROR("Memreg get info failed, %u\n", mr_tee);
+		} else {
+			if ((BL32_LIMIT - 1) < end) {
+				err = sc_rm_memreg_alloc(ipc_handle, &mr, BL32_LIMIT , end);
+				if (err) {
+					ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n", (sc_faddr_t)BL32_LIMIT, end);
+				} else {
+					err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
+					if (err)
+						ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n", (sc_faddr_t)BL32_LIMIT, end);
+				}
+			}
+
+			if (start < (BL32_BASE - 1)) {
+				err = sc_rm_memreg_alloc(ipc_handle, &mr, start, BL32_BASE - 1);
+				if (err) {
+					ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n", start, (sc_faddr_t)BL32_BASE - 1);
+				} else {
+					err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
+					if (err)
+						ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n", start, (sc_faddr_t)BL32_BASE - 1);
+				}
+			}
+		}
+	}
+#endif
 	if (mr_record != 64) {
 		err = sc_rm_get_memreg_info(ipc_handle, mr_record, &start, &end);
-		if (err)
-			ERROR("Memreg get info failed, %u\n", mr_record);
-		if ((BL31_LIMIT - 1) < end) {
-			err = sc_rm_memreg_alloc(ipc_handle, &mr, BL31_LIMIT, end);
-			if (err)
-				ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
-					(sc_faddr_t)BL31_LIMIT, end);
-			err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
-			if (err)
-				ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
-					(sc_faddr_t)BL31_LIMIT, end);
-		}
 
-		if (start < (BL31_BASE - 1)) {
-			err = sc_rm_memreg_alloc(ipc_handle, &mr, start, BL31_BASE - 1);
-			if (err)
-				ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
-					start, (sc_faddr_t)BL31_BASE - 1);
-			err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
+#ifdef SPD_trusty
+		if (BL32_BASE >= start && (BL32_LIMIT - 1) <= end)
+			mr_tee_atf_same = true;
+#endif
+		reg_end = end;
+
+		if (err) {
+			ERROR("Memreg get info failed, %u\n", mr_record);
+		} else {
+			if ((BL31_LIMIT - 1) < end) {
+#ifdef SPD_trusty
+				if ((end > BL32_BASE) && mr_tee_atf_same)
+					reg_end = BL32_BASE - 1;
+#endif
+				err = sc_rm_memreg_alloc(ipc_handle, &mr, BL31_LIMIT, reg_end);
+				if (err) {
+					ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n", (sc_faddr_t)BL31_LIMIT, reg_end);
+				} else {
+					err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
+					if (err)
+						ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n", (sc_faddr_t)BL31_LIMIT, reg_end);
+				}
+			}
+#ifdef SPD_trusty
+			if (mr_tee_atf_same) {
+				if ((BL32_LIMIT - 1) < end) {
+					reg_start = BL32_LIMIT;
+					err = sc_rm_memreg_alloc(ipc_handle, &mr, reg_start, end);
+					if (err) {
+						ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n", reg_start, reg_end);
+					} else {
+						err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
+						if (err)
+							ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n", reg_start, reg_end);
+					}
+				}
+			}
+#endif
+
+			if (start < (BL31_BASE - 1)) {
+				err = sc_rm_memreg_alloc(ipc_handle, &mr, start, BL31_BASE - 1);
 				if (err)
-					ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
+					ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
 						start, (sc_faddr_t)BL31_BASE - 1);
+				err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
+					if (err)
+						ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
+							start, (sc_faddr_t)BL31_BASE - 1);
+			}
 		}
 	}
 
@@ -330,6 +404,15 @@
 
 	bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET;
 	bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
+#ifdef SPD_trusty
+	SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
+	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+	bl32_image_ep_info.pc = BL32_BASE;
+	bl32_image_ep_info.spsr = 0;
+	memcpy((void*)BL32_BASE,(void*) PLAT_TEE_IMAGE_OFFSET, BL32_SIZE);
+	bl32_image_ep_info.args.arg0 = BL32_SIZE;
+	bl32_image_ep_info.args.arg1 = BL32_BASE;
+#endif
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
 
 	/* init the first cluster's cci slave interface */
@@ -354,6 +437,10 @@
 		MT_RW | MT_MEMORY | MT_SECURE);
 	mmap_add(imx_mmap);
 
+#ifdef SPD_trusty
+	mmap_add_region(BL32_BASE, BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW);
+#endif
+
 #if USE_COHERENT_MEM
 	mmap_add_region(coh_start, coh_start, coh_size,
 			MT_DEVICE | MT_RW | MT_SECURE);
@@ -390,3 +477,12 @@
 {
 	return;
 }
+
+#ifdef SPD_trusty
+void plat_trusty_set_boot_args(aapcs64_params_t *args)
+{
+	args->arg0 = BL32_SIZE;
+	args->arg1 = BL32_BASE;
+	args->arg2 = TRUSTY_PARAMS_LEN_BYTES;
+}
+#endif
diff --git a/plat/imx/imx8qm/include/platform_def.h b/plat/imx/imx8qm/include/platform_def.h
index d5eba60..e9eb99f 100644
--- a/plat/imx/imx8qm/include/platform_def.h
+++ b/plat/imx/imx8qm/include/platform_def.h
@@ -40,6 +40,13 @@
 #define BL31_BASE			0x80000000
 #define BL31_LIMIT			0x80020000
 
+#ifdef SPD_trusty
+#define BL32_BASE			0xfe000000
+#define BL32_SIZE			0x00200000
+#define BL32_LIMIT			0x100000000
+#define PLAT_TEE_IMAGE_OFFSET		0x84000000
+#endif
+
 #define PLAT_GICD_BASE			0x51a00000
 #define PLAT_GICD_SIZE			0x10000
 #define PLAT_GICR_BASE			0x51b00000
@@ -78,7 +85,11 @@
 #define SC_CONSOLE			0
 
 #define DEBUG_CONSOLE			0
+#ifdef SPD_trusty
+#define DEBUG_CONSOLE_A53		1
+#else
 #define DEBUG_CONSOLE_A53		0
+#endif
 #define PLAT_IMX8QM			1
 
 #endif /* PLATFORM_DEF_H */
diff --git a/plat/imx/imx8qx/imx8qx_bl31_setup.c b/plat/imx/imx8qx/imx8qx_bl31_setup.c
index ad2a1b6..0782978 100644
--- a/plat/imx/imx8qx/imx8qx_bl31_setup.c
+++ b/plat/imx/imx8qx/imx8qx_bl31_setup.c
@@ -23,6 +23,9 @@
 #include <sec_rsrc.h>
 #include <stdbool.h>
 #include <xlat_tables.h>
+#include <string.h>
+
+#define TRUSTY_PARAMS_LEN_BYTES      (4096*2)
 
 IMPORT_SYM(unsigned long, __COHERENT_RAM_START__, BL31_COHERENT_RAM_START);
 IMPORT_SYM(unsigned long, __COHERENT_RAM_END__, BL31_COHERENT_RAM_END);
@@ -149,10 +152,15 @@
 {
 	sc_rm_pt_t secure_part, os_part;
 	sc_rm_mr_t mr, mr_record = 64;
-	sc_faddr_t start, end;
+	sc_faddr_t start, end, reg_end;
 	sc_err_t err;
 	bool owned;
 	int i;
+#ifdef SPD_trusty
+	sc_rm_mr_t mr_tee = 64;
+	bool mr_tee_atf_same = false;
+	sc_faddr_t reg_start;
+#endif
 
 	err = sc_rm_get_partition(ipc_handle, &secure_part);
 	if (err)
@@ -185,45 +193,109 @@
 		owned = sc_rm_is_memreg_owned(ipc_handle, mr);
 		if (owned) {
 			err = sc_rm_get_memreg_info(ipc_handle, mr, &start, &end);
-			if (err)
+			if (err) {
 				ERROR("Memreg get info failed, %u\n", mr);
-
-			NOTICE("Memreg %u 0x%llx -- 0x%llx\n", mr, start, end);
-			if (BL31_BASE >= start && (BL31_LIMIT - 1) <= end) {
-				mr_record = mr; /* Record the mr for ATF running */
 			} else {
-				err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
-				if (err)
-					ERROR("Memreg assign failed, 0x%llx -- 0x%llx, \
-						err %d\n", start, end, err);
+				NOTICE("Memreg %u 0x%llx -- 0x%llx\n", mr, start, end);
+
+				if (BL31_BASE >= start && (BL31_LIMIT - 1) <= end) {
+					mr_record = mr; /* Record the mr for ATF running */
+				}
+#ifdef SPD_trusty
+				else if (BL32_BASE >= start && (BL32_LIMIT -1) <= end) {
+					mr_tee = mr;
+				}
+#endif
+				else {
+					err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
+					if (err)
+						ERROR("Memreg assign failed, 0x%llx -- 0x%llx, err %d\n", start, end, err);
+				}
 			}
 		}
 	}
 
+#ifdef SPD_trusty
+	if (mr_tee != 64) {
+		err = sc_rm_get_memreg_info(ipc_handle, mr_tee, &start, &end);
+		if (err) {
+			ERROR("Memreg get info failed, %u\n", mr_tee);
+		} else {
+			if ((BL32_LIMIT - 1) < end) {
+				err = sc_rm_memreg_alloc(ipc_handle, &mr, BL32_LIMIT , end);
+				if (err) {
+					ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n", (sc_faddr_t)BL32_LIMIT, end);
+				} else {
+					err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
+					if (err)
+						ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n", (sc_faddr_t)BL32_LIMIT, end);
+				}
+			}
+
+			if (start < (BL32_BASE - 1)) {
+				err = sc_rm_memreg_alloc(ipc_handle, &mr, start, BL32_BASE - 1);
+				if (err) {
+					ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n", start, (sc_faddr_t)BL32_BASE - 1);
+				} else {
+					err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
+					if (err)
+						ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n", start, (sc_faddr_t)BL32_BASE - 1);
+				}
+			}
+		}
+	}
+#endif
 	if (mr_record != 64) {
 		err = sc_rm_get_memreg_info(ipc_handle, mr_record, &start, &end);
-		if (err)
-			ERROR("Memreg get info failed, %u\n", mr_record);
-		if ((BL31_LIMIT - 1) < end) {
-			err = sc_rm_memreg_alloc(ipc_handle, &mr, BL31_LIMIT, end);
-			if (err)
-				ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
-					(sc_faddr_t)BL31_LIMIT, end);
-			err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
-			if (err)
-				ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
-					(sc_faddr_t)BL31_LIMIT, end);
-		}
 
-		if (start < (BL31_BASE - 1)) {
-			err = sc_rm_memreg_alloc(ipc_handle, &mr, start, BL31_BASE - 1);
-			if (err)
-				ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
-					start, (sc_faddr_t)BL31_BASE - 1);
-			err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
-			if (err)
-				ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
-					start, (sc_faddr_t)BL31_BASE - 1);
+#ifdef SPD_trusty
+		if (BL32_BASE >= start && (BL32_LIMIT - 1) <= end)
+			mr_tee_atf_same = true;
+#endif
+		reg_end = end;
+		if (err) {
+			ERROR("Memreg get info failed, %u\n", mr_record);
+		} else {
+			if ((BL31_LIMIT - 1) < end) {
+#ifdef SPD_trusty
+				if ((end > BL32_BASE) && mr_tee_atf_same)
+					reg_end = BL32_BASE - 1;
+#endif
+				err = sc_rm_memreg_alloc(ipc_handle, &mr, BL31_LIMIT, reg_end);
+				if (err) {
+					ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n", (sc_faddr_t)BL31_LIMIT, reg_end);
+				} else {
+					err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
+					if (err)
+						ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n", (sc_faddr_t)BL31_LIMIT, reg_end);
+				}
+			}
+#ifdef SPD_trusty
+			if (mr_tee_atf_same) {
+				if ((BL32_LIMIT - 1) < end) {
+					reg_start = BL32_LIMIT;
+					err = sc_rm_memreg_alloc(ipc_handle, &mr, reg_start, end);
+					if (err) {
+						ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n", reg_start, reg_end);
+					} else {
+						err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
+					if (err)
+						ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n", reg_start, reg_end);
+					}
+				}
+			}
+#endif
+
+			if (start < (BL31_BASE - 1)) {
+				err = sc_rm_memreg_alloc(ipc_handle, &mr, start, BL31_BASE - 1);
+				if (err)
+					ERROR("sc_rm_memreg_alloc failed, 0x%llx -- 0x%llx\n",
+						start, (sc_faddr_t)BL31_BASE - 1);
+				err = sc_rm_assign_memreg(ipc_handle, os_part, mr);
+				if (err)
+					ERROR("Memreg assign failed, 0x%llx -- 0x%llx\n",
+						start, (sc_faddr_t)BL31_BASE - 1);
+			}
 		}
 	}
 
@@ -308,6 +380,15 @@
 
 	bl33_image_ep_info.pc = PLAT_NS_IMAGE_OFFSET;
 	bl33_image_ep_info.spsr = get_spsr_for_bl33_entry();
+#ifdef SPD_trusty
+	SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0);
+	SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE);
+	bl32_image_ep_info.pc = BL32_BASE;
+	bl32_image_ep_info.spsr = 0;
+	memcpy((void*)BL32_BASE,(void*) PLAT_TEE_IMAGE_OFFSET, BL32_SIZE);
+	bl32_image_ep_info.args.arg0 = BL32_SIZE;
+	bl32_image_ep_info.args.arg1 = BL32_BASE;
+#endif
 	SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE);
 }
 
@@ -328,6 +409,10 @@
 		MT_RW | MT_MEMORY | MT_SECURE);
 	mmap_add(imx_mmap);
 
+#ifdef SPD_trusty
+	mmap_add_region(BL32_BASE, BL32_BASE, BL32_SIZE, MT_MEMORY | MT_RW);
+#endif
+
 #if USE_COHERENT_MEM
 	mmap_add_region(coh_start, coh_start, coh_size,
 			MT_DEVICE | MT_RW | MT_SECURE);
@@ -362,3 +447,11 @@
 {
 	return;
 }
+#ifdef SPD_trusty
+void plat_trusty_set_boot_args(aapcs64_params_t *args)
+{
+	args->arg0 = BL32_SIZE;
+	args->arg1 = BL32_BASE;
+	args->arg2 = TRUSTY_PARAMS_LEN_BYTES;
+}
+#endif
diff --git a/plat/imx/imx8qx/include/platform_def.h b/plat/imx/imx8qx/include/platform_def.h
index 6f1b446..c81b12f 100644
--- a/plat/imx/imx8qx/include/platform_def.h
+++ b/plat/imx/imx8qx/include/platform_def.h
@@ -36,11 +36,18 @@
 #define BL31_BASE			0x80000000
 #define BL31_LIMIT			0x80020000
 
+#ifdef SPD_trusty
+#define BL32_BASE			0xfe000000
+#define BL32_SIZE			0x00200000
+#define BL32_LIMIT			0x100000000
+#define PLAT_TEE_IMAGE_OFFSET		0x84000000
+#endif
+
 #define PLAT_VIRT_ADDR_SPACE_SIZE	(1ull << 32)
 #define PLAT_PHY_ADDR_SPACE_SIZE	(1ull << 32)
 
 #define MAX_XLAT_TABLES			8
-#define MAX_MMAP_REGIONS		8
+#define MAX_MMAP_REGIONS		9
 
 #define PLAT_GICD_BASE			0x51a00000
 #define PLAT_GICD_SIZE			0x10000
@@ -73,7 +80,13 @@
 #define SC_CONSOLE			0
 
 #define DEBUG_CONSOLE			0
+
+#ifdef SPD_trusty
+#define DEBUG_CONSOLE_A35		1
+#else
 #define DEBUG_CONSOLE_A35		0
+#endif
+
 #define PLAT_IMX8QX			1
 
 #endif /* PLATFORM_DEF_H */