fix(rcar3-drivers): 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

Move GZ compressed payload at 32 * compressed payload size offset,
so it is loaded in non-secure area and can be decompressed into
non-secure area too. It is unlikely that the up to 2 MiB compressed
BL33 blob would decompress to payload larger than 64 MiB .

Signed-off-by: Tobias Rist <tobias.rist@joynext.com>
Signed-off-by: Yoshifumi Hosoya <yoshifumi.hosoya.wj@renesas.com>
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org> # Fix for compressed BL33
Change-Id: I52fd556aab50687e4791e5dbc45d425f802c8757
diff --git a/drivers/renesas/common/io/io_rcar.c b/drivers/renesas/common/io/io_rcar.c
index 0c49ec9..80f32aa 100644
--- a/drivers/renesas/common/io/io_rcar.c
+++ b/drivers/renesas/common/io/io_rcar.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -84,6 +84,29 @@
 #define RCAR_COUNT_LOAD_BL33		(2U)
 #define RCAR_COUNT_LOAD_BL33X		(3U)
 
+#define CHECK_IMAGE_AREA_CNT (7U)
+#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},
+	[1] = {BL31_BASE, RCAR_TRUSTED_SRAM_SIZE},
+#ifndef SPD_NONE
+	[2] = {BL32_BASE, BL32_SIZE}
+#endif
+};
+
+#ifndef SPD_NONE
+static uint32_t addr_loaded_cnt = 3;
+#else
+static uint32_t addr_loaded_cnt = 2;
+#endif
+
 static const plat_rcar_name_offset_t name_offset[] = {
 	{BL31_IMAGE_ID, 0U, RCAR_ATTR_SET_ALL(0, 0, 0)},
 
@@ -281,10 +304,11 @@
 	uintptr_t dram_start, dram_end;
 	uintptr_t prot_start, prot_end;
 	int32_t result = IO_SUCCESS;
+	int n;
 
-	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;
@@ -301,13 +325,54 @@
 	if (dst >= prot_start && dst < prot_end) {
 		ERROR("BL2: dst address is on the protected area.\n");
 		result = IO_FAIL;
+		goto done;
 	}
 
 	if (len > prot_start || (dst < prot_start && dst > prot_start - len)) {
 		ERROR("BL2: %s[%d] loaded data is on the protected area.\n",
 			__func__, __LINE__);
 		result = IO_FAIL;
+		goto done;
+	}
+
+	if (addr_loaded_cnt >= CHECK_IMAGE_AREA_CNT) {
+		ERROR("BL2: max loadable non secure images reached\n");
+		result = IO_FAIL;
+		goto done;
 	}
+
+	addr_loaded[addr_loaded_cnt].dest = dst;
+	addr_loaded[addr_loaded_cnt].length = len;
+	for (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 |
+		 * 3. check:
+		 *      | IMAGE n |
+		 *  |    IMAGE n+1    |
+		 */
+		if (((dst >= addr_loaded[n].dest) &&
+		     (dst <= addr_loaded[n].dest + addr_loaded[n].length)) ||
+		    ((dst + len >= addr_loaded[n].dest) &&
+		     (dst + len <= addr_loaded[n].dest + addr_loaded[n].length)) ||
+		    ((dst <= addr_loaded[n].dest) &&
+		     (dst + len >= addr_loaded[n].dest + addr_loaded[n].length))) {
+			ERROR("BL2: next image overlap a previous image area.\n");
+			result = IO_FAIL;
+			goto done;
+		}
+	}
+	addr_loaded_cnt++;
+
 done:
 	if (result == IO_FAIL) {
 		ERROR("BL2: Out of range : dst=0x%lx len=0x%lx\n", dst, len);
diff --git a/plat/renesas/common/include/platform_def.h b/plat/renesas/common/include/platform_def.h
index ab071ec..8178f3a 100644
--- a/plat/renesas/common/include/platform_def.h
+++ b/plat/renesas/common/include/platform_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -144,7 +144,8 @@
  ******************************************************************************/
 #ifndef SPD_NONE
 #define BL32_BASE		U(0x44100000)
-#define BL32_LIMIT		(BL32_BASE + U(0x200000))
+#define BL32_SIZE		U(0x200000)
+#define BL32_LIMIT		(BL32_BASE + BL32_SIZE)
 #endif
 
 /*******************************************************************************
@@ -152,7 +153,8 @@
  ******************************************************************************/
 #define BL33_BASE		DRAM1_NS_BASE
 #define BL33_COMP_SIZE		U(0x200000)
-#define BL33_COMP_BASE		(BL33_BASE - BL33_COMP_SIZE)
+#define BL33_DECOMP_SIZE	(BL33_COMP_SIZE * 32)
+#define BL33_COMP_BASE		(BL33_BASE + BL33_DECOMP_SIZE)
 
 /*******************************************************************************
  * Platform specific page table and MMU setup constants
diff --git a/plat/renesas/common/include/rcar_def.h b/plat/renesas/common/include/rcar_def.h
index 2cd26ed..f1c2553 100644
--- a/plat/renesas/common/include/rcar_def.h
+++ b/plat/renesas/common/include/rcar_def.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2021, Renesas Electronics Corporation. All rights reserved.
+ * Copyright (c) 2015-2023, Renesas Electronics Corporation. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -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)