Merge pull request #1413 from grandpaul/paulliu-rpi3-0

rpi3: BL32 optee support
diff --git a/docs/plat/rpi3.rst b/docs/plat/rpi3.rst
index 659ed7f..554c9a1 100644
--- a/docs/plat/rpi3.rst
+++ b/docs/plat/rpi3.rst
@@ -122,7 +122,7 @@
     0x10000000 +-----------------+
                |   Secure SRAM   | BL2, BL31
     0x10100000 +-----------------+
-               |   Secure DRAM   |
+               |   Secure DRAM   | BL32 (Secure payload)
     0x10300000 +-----------------+
                | Non-secure DRAM | BL33
     0x11000000 +-----------------+
@@ -237,6 +237,12 @@
   in AArch64 mode. If set to 1, it will jump to BL33 in Hypervisor in AArch32
   mode.
 
+- ``BL32``: This port can load and run OP-TEE. The OP-TEE image is optional.
+  Please use the code from `here <https://github.com/OP-TEE/optee_os>`__.
+  Build the Trusted Firmware with option ``BL32=tee-header_v2.bin
+  BL32_EXTRA1=tee-pager_v2.bin  BL32_EXTRA2=tee-pageable_v2.bin``
+  to put the binaries into the FIP.
+
 The following is not currently supported:
 
 - AArch32 for TF-A itself.
diff --git a/plat/rpi3/aarch64/rpi3_bl2_mem_params_desc.c b/plat/rpi3/aarch64/rpi3_bl2_mem_params_desc.c
index e3acfe9..6a3c1d6 100644
--- a/plat/rpi3/aarch64/rpi3_bl2_mem_params_desc.c
+++ b/plat/rpi3/aarch64/rpi3_bl2_mem_params_desc.c
@@ -99,6 +99,10 @@
 		SET_STATIC_PARAM_HEAD(image_info, PARAM_EP,
 				      VERSION_2, image_info_t,
 				      IMAGE_ATTRIB_SKIP_LOADING),
+#ifdef SPD_opteed
+		.image_info.image_base = RPI3_OPTEE_PAGEABLE_LOAD_BASE,
+		.image_info.image_max_size = RPI3_OPTEE_PAGEABLE_LOAD_SIZE,
+#endif
 		.next_handoff_image_id = INVALID_IMAGE_ID,
 	},
 # endif /* BL32_BASE */
diff --git a/plat/rpi3/include/platform_def.h b/plat/rpi3/include/platform_def.h
index 5e2f1da..ebd77cd 100644
--- a/plat/rpi3/include/platform_def.h
+++ b/plat/rpi3/include/platform_def.h
@@ -181,6 +181,13 @@
 #define BL32_DRAM_BASE			SEC_DRAM0_BASE
 #define BL32_DRAM_LIMIT			(SEC_DRAM0_BASE + SEC_DRAM0_SIZE)
 
+#ifdef SPD_opteed
+/* Load pageable part of OP-TEE at end of allocated DRAM space for BL32 */
+#define RPI3_OPTEE_PAGEABLE_LOAD_SIZE	0x080000 /* 512KB */
+#define RPI3_OPTEE_PAGEABLE_LOAD_BASE	(BL32_DRAM_LIMIT - \
+					 RPI3_OPTEE_PAGEABLE_LOAD_SIZE)
+#endif
+
 #define SEC_SRAM_ID			0
 #define SEC_DRAM_ID			1
 
diff --git a/plat/rpi3/platform.mk b/plat/rpi3/platform.mk
index 2cb7a15..2aaf406 100644
--- a/plat/rpi3/platform.mk
+++ b/plat/rpi3/platform.mk
@@ -120,3 +120,17 @@
 ifeq (${ARCH},aarch32)
   $(error Error: AArch32 not supported on rpi3)
 endif
+
+ifeq (${SPD},opteed)
+BL2_SOURCES	+=							\
+		lib/optee/optee_utils.c
+endif
+
+# Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images
+# in the FIP if the platform requires.
+ifneq ($(BL32_EXTRA1),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA1,--tos-fw-extra1))
+endif
+ifneq ($(BL32_EXTRA2),)
+$(eval $(call TOOL_ADD_IMG,BL32_EXTRA2,--tos-fw-extra2))
+endif
diff --git a/plat/rpi3/rpi3_bl2_setup.c b/plat/rpi3/rpi3_bl2_setup.c
index f286caf..13e8c01 100644
--- a/plat/rpi3/rpi3_bl2_setup.c
+++ b/plat/rpi3/rpi3_bl2_setup.c
@@ -9,6 +9,7 @@
 #include <bl_common.h>
 #include <debug.h>
 #include <desc_image_load.h>
+#include <optee_utils.h>
 #include <platform_def.h>
 #include <xlat_mmu_helpers.h>
 #include <xlat_tables_defs.h>
@@ -67,11 +68,28 @@
 {
 	int err = 0;
 	bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id);
+#ifdef SPD_opteed
+	bl_mem_params_node_t *pager_mem_params = NULL;
+	bl_mem_params_node_t *paged_mem_params = NULL;
+#endif
 
 	assert(bl_mem_params != NULL);
 
 	switch (image_id) {
 	case BL32_IMAGE_ID:
+#ifdef SPD_opteed
+		pager_mem_params = get_bl_mem_params_node(BL32_EXTRA1_IMAGE_ID);
+		assert(pager_mem_params);
+
+		paged_mem_params = get_bl_mem_params_node(BL32_EXTRA2_IMAGE_ID);
+		assert(paged_mem_params);
+
+		err = parse_optee_header(&bl_mem_params->ep_info,
+				&pager_mem_params->image_info,
+				&paged_mem_params->image_info);
+		if (err != 0)
+			WARN("OPTEE header parse error.\n");
+#endif
 		bl_mem_params->ep_info.spsr = rpi3_get_spsr_for_bl32_entry();
 		break;
 
diff --git a/plat/rpi3/rpi3_common.c b/plat/rpi3/rpi3_common.c
index 03914a6..65f5e7a 100644
--- a/plat/rpi3/rpi3_common.c
+++ b/plat/rpi3/rpi3_common.c
@@ -34,6 +34,13 @@
 #define MAP_BL32_MEM	MAP_REGION_FLAT(BL32_MEM_BASE, BL32_MEM_SIZE,	\
 					MT_MEMORY | MT_RW | MT_SECURE)
 
+#ifdef SPD_opteed
+#define MAP_OPTEE_PAGEABLE	MAP_REGION_FLAT(		\
+				RPI3_OPTEE_PAGEABLE_LOAD_BASE,	\
+				RPI3_OPTEE_PAGEABLE_LOAD_SIZE,	\
+				MT_MEMORY | MT_RW | MT_SECURE)
+#endif
+
 /*
  * Table of regions for various BL stages to map using the MMU.
  */
@@ -42,6 +49,9 @@
 	MAP_SHARED_RAM,
 	MAP_DEVICE0,
 	MAP_FIP,
+#ifdef SPD_opteed
+	MAP_OPTEE_PAGEABLE,
+#endif
 	{0}
 };
 #endif
@@ -190,3 +200,13 @@
 {
 	return INTR_TYPE_INVAL;
 }
+
+uint32_t plat_interrupt_type_to_line(uint32_t type,
+				     uint32_t security_state)
+{
+	/* It is not expected to receive an interrupt route to EL3.
+	 * Hence panic() to flag error.
+	 */
+	ERROR("Interrupt not expected to be routed to EL3");
+	panic();
+}
diff --git a/plat/rpi3/rpi3_io_storage.c b/plat/rpi3/rpi3_io_storage.c
index 7ac45ef..e090b2b 100644
--- a/plat/rpi3/rpi3_io_storage.c
+++ b/plat/rpi3/rpi3_io_storage.c
@@ -54,6 +54,14 @@
 	.uuid = UUID_SECURE_PAYLOAD_BL32,
 };
 
+static const io_uuid_spec_t bl32_extra1_uuid_spec = {
+	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1,
+};
+
+static const io_uuid_spec_t bl32_extra2_uuid_spec = {
+	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2,
+};
+
 static const io_uuid_spec_t bl33_uuid_spec = {
 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33,
 };
@@ -123,6 +131,21 @@
 		(uintptr_t)&bl32_uuid_spec,
 		open_fip
 	},
+	[BL32_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl32_uuid_spec,
+		open_fip
+	},
+	[BL32_EXTRA1_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl32_extra1_uuid_spec,
+		open_fip
+	},
+	[BL32_EXTRA2_IMAGE_ID] = {
+		&fip_dev_handle,
+		(uintptr_t)&bl32_extra2_uuid_spec,
+		open_fip
+	},
 	[BL33_IMAGE_ID] = {
 		&fip_dev_handle,
 		(uintptr_t)&bl33_uuid_spec,