From 6a96c18c474e6339fab93f54d52aa7dcc4b70e52 Mon Sep 17 00:00:00 2001
From: Tobias Rist <tobias.rist@joynext.com>
Date: Thu, 16 Mar 2023 21:31:15 +0900
Subject: [PATCH] rcar-gen3: plat: BL2: check loaded NS image area

Check if next NS image invades a previous loaded image.
Correct non secure image area to avoid loading a NS image to secure

Signed-off-by: Tobias Rist <tobias.rist@joynext.com>
Signed-off-by: Yoshifumi Hosoya <yoshifumi.hosoya.wj@renesas.com>
---
 drivers/renesas/rcar/io/io_rcar.c    | 46 ++++++++++++++++++++++++++--
 plat/renesas/rcar/include/rcar_def.h |  2 +-
 2 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/drivers/renesas/rcar/io/io_rcar.c b/drivers/renesas/rcar/io/io_rcar.c
index fe968b6..dc1b786 100644
--- a/drivers/renesas/rcar/io/io_rcar.c
+++ b/drivers/renesas/rcar/io/io_rcar.c
@@ -84,6 +84,18 @@ typedef struct {
 #define RCAR_COUNT_LOAD_BL33		(2U)
 #define RCAR_COUNT_LOAD_BL33X		(3U)
 
+#define CHECK_IMAGE_AREA_CNT (5U)
+#define BOOT_BL2_ADDR (0xE6304000U)
+#define BOOT_BL2_LENGTH (0x19000U)
+
+typedef struct {
+	uintptr_t dest;
+	uintptr_t length;
+} addr_loaded_t;
+
+static addr_loaded_t addr_loaded[CHECK_IMAGE_AREA_CNT] = { [0] = {BOOT_BL2_ADDR, BOOT_BL2_LENGTH} };
+static uint32_t addr_loaded_cnt = 1;
+
 static const plat_rcar_name_offset_t name_offset[] = {
 	{BL31_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(0, 0, 0)},
 
@@ -256,9 +268,9 @@ static int32_t check_load_area(uintptr_t dst, uintptr_t len)
 	uintptr_t prot_start, prot_end;
 	int32_t result = IO_SUCCESS;
 
-	dram_start = legacy ? DRAM1_BASE : DRAM_40BIT_BASE;
+	dram_start = legacy ? DRAM1_NS_BASE : DRAM_40BIT_BASE;
 
-	dram_end = legacy ? DRAM1_BASE + DRAM1_SIZE :
+	dram_end = legacy ? DRAM1_NS_BASE + DRAM1_NS_SIZE :
 	    DRAM_40BIT_BASE + DRAM_40BIT_SIZE;
 
 	prot_start = legacy ? DRAM_PROTECTED_BASE : DRAM_40BIT_PROTECTED_BASE;
@@ -287,6 +299,36 @@ done:
 	if (result == IO_FAIL)
 		ERROR("BL2: Out of range : dst=0x%lx len=0x%lx\n", dst, len);
 
+	if (addr_loaded_cnt >= CHECK_IMAGE_AREA_CNT) {
+		ERROR("BL2: max loadable non secure images reached\n");
+		result = IO_FAIL;
+	}
+	addr_loaded[addr_loaded_cnt].dest = dst;
+	addr_loaded[addr_loaded_cnt].length = len;
+	for(int n=0; n<addr_loaded_cnt; n++) {
+		/* Check if next image invades a previous loaded image
+		 *
+		 * IMAGE n: area from previous image:	dest| IMAGE n |length
+		 * IMAGE n+1: area from next image:	dst | IMAGE n |len
+		 *
+		 * 1. check:
+		 *      | IMAGE n |
+		 *           | IMAGE n+1 |
+		 * 2. check:
+		 *      | IMAGE n |
+		 *  | IMAGE n+1 |
+		 *
+		 * */
+		if (((dst > addr_loaded[n].dest) &&
+		     (dst <  addr_loaded[n].dest + addr_loaded[n].length)) ||
+		    (((dst < addr_loaded[n].dest) &&
+		      (dst + len)) > addr_loaded[n].dest)) {
+			ERROR("BL2: image is inside a previous image area.\n");
+			result = IO_FAIL;
+		}
+	}
+	addr_loaded_cnt++;
+
 	return result;
 }
 
diff --git a/plat/renesas/rcar/include/rcar_def.h b/plat/renesas/rcar/include/rcar_def.h
index 0ffbfe9..a41a994 100644
--- a/plat/renesas/rcar/include/rcar_def.h
+++ b/plat/renesas/rcar/include/rcar_def.h
@@ -31,7 +31,7 @@
 #define DRAM_LIMIT			ULL(0x0000010000000000)
 #define DRAM1_BASE			U(0x40000000)
 #define DRAM1_SIZE			U(0x80000000)
-#define DRAM1_NS_BASE			(DRAM1_BASE + U(0x10000000))
+#define DRAM1_NS_BASE			(DRAM1_BASE + U(0x08000000))
 #define DRAM1_NS_SIZE			(DRAM1_SIZE - DRAM1_NS_BASE)
 #define	DRAM_40BIT_BASE			ULL(0x0400000000)
 #define	DRAM_40BIT_SIZE			ULL(0x0400000000)
-- 
2.33.0

