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);
}