hikey: configure 4 MB of secure DRAM for OP-TEE Secure Data Path

Update the memory firewall configuration to reserve 4 MB of secure RAM
for use by the kernel and OP-TEE as the Secure Data Path pool.
Note that this address range (0x3E800000 - 0x3EC00000) falls in the
range already set aside by UEFI (which reserves the upper 32 MB of the
1GB DRAM for OP-TEE [1]) and was previously unused.

[1] https://github.com/96boards-hikey/edk2/blob/hikey/HisiPkg/HiKeyPkg/Library/HiKeyLib/HiKeyMem.c#L44
Signed-off-by: Jerome Forissier <jerome.forissier@linaro.org>
diff --git a/plat/hikey/hikey_def.h b/plat/hikey/hikey_def.h
index 2007633..d81b6d7 100644
--- a/plat/hikey/hikey_def.h
+++ b/plat/hikey/hikey_def.h
@@ -46,13 +46,19 @@
 #define PLAT_TRUSTED_DRAM_ID	1
 
 /*
- * DRAM at 0x0000_0000 is divided in two regions:
- *   - Secure DRAM (default is the top 16MB)
+ * DRAM (1 GB) at 0x0000_0000 is divided in several regions:
+ *   - Secure DRAM (default is the top 16MB) used by OP-TEE
+ *   - Non-secure DRAM used by OP-TEE (shared memory and padding) (4MB)
+ *   - Secure DRAM (4MB aligned on 4MB) for OP-TEE's "Secure Data Path" feature
  *   - Non-Secure DRAM (remaining DRAM starting at DRAM_BASE)
  */
 #define DRAM_SEC_SIZE			0x01000000
 #define DRAM_SEC_BASE			(DRAM_BASE + DRAM_SIZE - DRAM_SEC_SIZE)
 
+#define DRAM_SDP_SIZE			0x00400000
+#define DRAM_SDP_BASE			(DRAM_SEC_BASE - 0x400000 /* align */ - \
+					 DRAM_SDP_SIZE)
+
 #define DRAM_NS_BASE			DRAM_BASE
 #define DRAM_NS_SIZE			(DRAM_SIZE - DRAM_SEC_SIZE)
 
diff --git a/plat/hikey/plat_security.c b/plat/hikey/plat_security.c
index b2cd602..dc439c7 100644
--- a/plat/hikey/plat_security.c
+++ b/plat/hikey/plat_security.c
@@ -90,13 +90,17 @@
  * region_size must be a power of 2 and at least 64KB
  * region_base must be region_size aligned
  */
-static void sec_protect(uint32_t region_base, uint32_t region_size)
+static void sec_protect(uint32_t region_base, uint32_t region_size,
+			int region)
 {
 	volatile struct int_en_reg *int_en_reg ;
 	volatile struct rgn_map_reg *rgn_map_reg;
 	volatile struct rgn_attr_reg *rgn_attr_reg;
 	uint32_t i = 0;
 
+	if (region < 1 || region > 15) {
+		ERROR("Secure region number is invalid\n");
+	}
 	if (!is_power_of_two(region_size) || region_size < 0x10000) {
 		ERROR("Secure region size is not a power of 2 >= 64KB\n");
 		return;
@@ -113,8 +117,8 @@
 	int_en_reg->in_en = 0x1;
 
 	for (i = 0; i < PORTNUM_MAX; i++) {
-		rgn_map_reg = get_rgn_map_reg(MDDRC_SECURITY_BASE, 1, i);
-		rgn_attr_reg = get_rgn_attr_reg(MDDRC_SECURITY_BASE, 1, i);
+		rgn_map_reg = get_rgn_map_reg(MDDRC_SECURITY_BASE, region, i);
+		rgn_attr_reg = get_rgn_attr_reg(MDDRC_SECURITY_BASE, region, i);
 		rgn_map_reg->rgn_base_addr = region_base >> 16;
 		rgn_attr_reg->subrgn_disable = 0x0;
 		rgn_attr_reg->sp = (i == 3) ? 0xC : 0x0;
@@ -128,5 +132,6 @@
  ******************************************************************************/
 void plat_security_setup(void)
 {
-	sec_protect(DRAM_SEC_BASE, DRAM_SEC_SIZE);
+	sec_protect(DRAM_SEC_BASE, DRAM_SEC_SIZE, 1);
+	sec_protect(DRAM_SDP_BASE, DRAM_SDP_SIZE, 2);
 }