test(ivy): S-EL0 partition using VHE

Starting from [1], Cactus remains the sample S-EL1 partition.
Ivy remains the sample "S-EL0 partition" either using the shim at S-EL1
(as of today), or leveraging Hafnium VHE (reason for this change).
The same code base is re-used by adding the IVY_SHIM toggle. IVY_SHIM=1
is default using the shim, or 0 to use VHE (and strip the shim out).
Using svc helper from spm/common/aarch64/sp_arch_helpers.S

We must modify generate_json.sh so it only adds the partition
information to the layout file for the sp given in arg1. This allows
the ability for sp's to pass flags to the script such as IVY_SHIM which
is used to vary the dts file included for ivy.

Typical build command for a VHE-enabled Ivy partition:
make CROSS_COMPILE=aarch64-none-elf- PLAT=fvp DEBUG=1 TESTS=spm
    ARM_ARCH_MINOR=5 BRANCH_PROTECTION=1 IVY_SHIM=0 ivy -j8

The intent is to create a dedicated tftf_config build config for the
VHE-enabled build in the CI.

[1] https://trustedfirmware-a-tests.readthedocs.io/en/latest/getting_started/build.html#cactus-and-ivy

Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
Signed-off-by: Daniel Boulby <daniel.boulby@arm.com>
Change-Id: I34125b375b043c61c44ede558802d8ae757bd51f
diff --git a/spm/cactus/cactus.mk b/spm/cactus/cactus.mk
index 8970b29..74baee5 100644
--- a/spm/cactus/cactus.mk
+++ b/spm/cactus/cactus.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -91,7 +91,7 @@
 $(CACTUS_DTB) : $(CACTUS_DTS)
 	@echo "  DTBGEN  $@"
 	${Q}tools/generate_dtb/generate_dtb.sh \
-		cactus ${CACTUS_DTS} $(BUILD_PLAT)
+		cactus ${CACTUS_DTS} $(BUILD_PLAT) $(CACTUS_DTB)
 	${Q}tools/generate_json/generate_json.sh \
 		cactus $(BUILD_PLAT)
 	@echo
diff --git a/spm/ivy/app/aarch64/ivy_entrypoint.S b/spm/ivy/app/aarch64/ivy_entrypoint.S
index d981d6a..062225c 100644
--- a/spm/ivy/app/aarch64/ivy_entrypoint.S
+++ b/spm/ivy/app/aarch64/ivy_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -15,12 +15,63 @@
 	.fill	IVY_STACKS_SIZE
 stacks_end:
 
+/* Call FFA_MEM_PERM_SET_32 to set the permissions of a given memory region. */
+.macro ffa_mem_perm_set start:req end:req perm:req
+	adrp x29, \start
+	add x29, x29, :lo12:\start
+
+	adrp x30, \end
+	add x30, x30, :lo12:\end
+
+	/* x30 = end - start */
+	sub x30, x30, x29
+	/* x28 = x30 >> 12 (number of pages) */
+	mov x28, #12
+	lsrv x28, x30, x28
+
+	/* 0x84000089 is function identifier for FFA_MEM_PERM_SET_32 */
+	mov w0, #0x89
+	movk w0, 0x8400, lsl #16
+	mov x1, x29 /* Base VA */
+	mov x2, x28 /* Page count */
+	mov w3, #\perm /* Memory permissions */
+	svc #0
+
+	/* 0x84000061 is function identifier for FFA_SUCCESS_32 */
+	mov w1, #0x61
+	movk w1, #0x8400, lsl #16
+	cmp w1, w0
+	b.ne .
+.endm
+
 func ivy_entrypoint
 
 	/* Setup the stack pointer. */
 	adr	x0, stacks_end
 	mov	sp, x0
 
+#if IVY_SHIM == 0
+	/* RODATA+DATA+BSS marked RW so relocations can succeed. */
+	ffa_mem_perm_set __RODATA_START__ __BSS_END__ 5
+
+	/* Relocate symbols */
+ivy_pie_fixup:
+	mov	x0, #0x1000
+	mov	x1, #IVY_IMAGE_SIZE
+	add	x1, x1, x0
+	bl	fixup_gdt_reloc
+
+	/* Clear S-EL0 partition BSS */
+	adrp	x0, __BSS_START__
+	adrp	x2, __BSS_END__
+	sub	x2, x2, x0
+	mov	x1, xzr
+	bl	memset
+
+	/* Then mark RODATA as RO */
+	ffa_mem_perm_set __RODATA_START__ __RODATA_END__ 7
+#endif /* IVY_SHIM == 0 */
+
 	/* And jump to the C entrypoint. */
 	b	ivy_main
 
diff --git a/spm/ivy/app/ivy_main.c b/spm/ivy/app/ivy_main.c
index 777ef82..232ab2e 100644
--- a/spm/ivy/app/ivy_main.c
+++ b/spm/ivy/app/ivy_main.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -21,14 +21,20 @@
 {
 	u_register_t ret;
 	svc_args args;
+	ffa_id_t my_id;
 
 	set_putc_impl(SVC_CALL_AS_STDOUT);
 
-	args = (svc_args) {.fid = FFA_ID_GET};
+	/* Get FF-A id. */
+	args = (svc_args){.fid = FFA_ID_GET};
 	ret = sp_svc(&args);
+	if (ret != FFA_SUCCESS_SMC32) {
+		ERROR("Cannot get FF-A id.\n");
+		panic();
+	}
+	my_id = (ffa_id_t)args.arg2;
 
-	NOTICE("Booting Secure Partition (ID: %x)\n",
-		(unsigned int)args.arg2);
+	NOTICE("Booting Secure Partition (ID: %x)\n", my_id);
 	NOTICE("%s\n", build_message);
 	NOTICE("%s\n", version_string);
 
@@ -37,6 +43,8 @@
 	ret = sp_svc(&args);
 
 	while (1) {
+		ffa_id_t req_sender = (ffa_id_t)(args.arg1 >> 16);
+
 		if (ret != FFA_MSG_SEND_DIRECT_REQ_SMC32) {
 			ERROR("unknown FF-A request %lx\n", ret);
 			goto init;
@@ -44,8 +52,10 @@
 
 		VERBOSE("Received request: %lx\n", args.arg3);
 
+
 		args.fid = FFA_MSG_SEND_DIRECT_RESP_SMC32;
-		args.arg1 = 0x80020000;
+		args.arg1 = ((u_register_t)my_id) << 16 |
+			    (u_register_t)req_sender;
 		args.arg2 = 0;
 		args.arg3 = 0;
 
diff --git a/spm/ivy/app/plat/arm/fvp/fdts/ivy.dts b/spm/ivy/app/plat/arm/fvp/fdts/ivy-sel0.dts
similarity index 69%
copy from spm/ivy/app/plat/arm/fvp/fdts/ivy.dts
copy to spm/ivy/app/plat/arm/fvp/fdts/ivy-sel0.dts
index d368076..76a5e3c 100644
--- a/spm/ivy/app/plat/arm/fvp/fdts/ivy.dts
+++ b/spm/ivy/app/plat/arm/fvp/fdts/ivy-sel0.dts
@@ -1,10 +1,10 @@
 /*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
  * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP)
- * that has additional optional properties defined.
+ * running in S-EL0 on top of Hafnium with VHE enabled (no S-EL1 shim included).
  */
 
 
@@ -14,18 +14,16 @@
 	compatible = "arm,ffa-manifest-1.0";
 
 	/* Properties */
-	description = "ivy-1";
+	description = "ivy-sel0-fvp";
 	ffa-version = <0x00010001>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <0xd883baea 0xaf4eafba 0xfdf74481 0xa744e5cb>;
 	execution-ctx-count = <1>;
-	exception-level = <2>; /* S-EL1 */
+	exception-level = <1>; /* S-EL0 */
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0x7600000>;
 	entrypoint-offset = <0x00004000>;
-	xlat-granule = <0>; /* 4KiB */
 	boot-order = <0>;
 	messaging-method = <3>; /* Direct messaging only */
-	run-time-model = <1>; /* SP pre-emptible */
 
 	/* Boot protocol */
 	gp-register-num = <0x0>;
diff --git a/spm/ivy/app/plat/arm/fvp/fdts/ivy.dts b/spm/ivy/app/plat/arm/fvp/fdts/ivy-sel1.dts
similarity index 73%
rename from spm/ivy/app/plat/arm/fvp/fdts/ivy.dts
rename to spm/ivy/app/plat/arm/fvp/fdts/ivy-sel1.dts
index d368076..62f59b9 100644
--- a/spm/ivy/app/plat/arm/fvp/fdts/ivy.dts
+++ b/spm/ivy/app/plat/arm/fvp/fdts/ivy-sel1.dts
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
  * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP)
- * that has additional optional properties defined.
+ * intended to run at S-EL0 utilising a shim to run at S-EL1 on a
+ * non VHE enabled hafnium.
  */
 
 
@@ -14,7 +15,7 @@
 	compatible = "arm,ffa-manifest-1.0";
 
 	/* Properties */
-	description = "ivy-1";
+	description = "ivy-sel1-fvp";
 	ffa-version = <0x00010001>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <0xd883baea 0xaf4eafba 0xfdf74481 0xa744e5cb>;
 	execution-ctx-count = <1>;
@@ -22,10 +23,8 @@
 	execution-state = <0>; /* AARCH64 */
 	load-address = <0x7600000>;
 	entrypoint-offset = <0x00004000>;
-	xlat-granule = <0>; /* 4KiB */
 	boot-order = <0>;
 	messaging-method = <3>; /* Direct messaging only */
-	run-time-model = <1>; /* SP pre-emptible */
 
 	/* Boot protocol */
 	gp-register-num = <0x0>;
diff --git a/spm/ivy/app/plat/arm/fvp/platform.mk b/spm/ivy/app/plat/arm/fvp/platform.mk
index 1e9a43b..3b9be33 100644
--- a/spm/ivy/app/plat/arm/fvp/platform.mk
+++ b/spm/ivy/app/plat/arm/fvp/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,7 +9,11 @@
 PLAT_INCLUDES		+= -I${FVP_IVY_BASE}/include/
 
 # Add the FDT source
-IVY_DTS		= ${FVP_IVY_BASE}/fdts/ivy.dts
+ifeq ($(IVY_SHIM),0)
+IVY_DTS		= ${FVP_IVY_BASE}/fdts/ivy-sel0.dts
+else
+IVY_DTS		= ${FVP_IVY_BASE}/fdts/ivy-sel1.dts
+endif
 
 # List of FDTS to copy
-FDTS_CP_LIST		= ${FVP_IVY_BASE}/fdts/ivy.dts
+FDTS_CP_LIST		=  $(IVY_DTS)
diff --git a/spm/ivy/app/plat/arm/fvp/fdts/ivy.dts b/spm/ivy/app/plat/arm/tc0/fdts/ivy-sel0.dts
similarity index 65%
copy from spm/ivy/app/plat/arm/fvp/fdts/ivy.dts
copy to spm/ivy/app/plat/arm/tc0/fdts/ivy-sel0.dts
index d368076..93e7da3 100644
--- a/spm/ivy/app/plat/arm/fvp/fdts/ivy.dts
+++ b/spm/ivy/app/plat/arm/tc0/fdts/ivy-sel0.dts
@@ -1,31 +1,28 @@
 /*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
  * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP)
- * that has additional optional properties defined.
+ * running in S-EL0 on top of Hafnium with VHE enabled (no S-EL1 shim included).
  */
 
-
 /dts-v1/;
 
 / {
 	compatible = "arm,ffa-manifest-1.0";
 
 	/* Properties */
-	description = "ivy-1";
+	description = "ivy-sel0-tc0";
 	ffa-version = <0x00010001>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <0xd883baea 0xaf4eafba 0xfdf74481 0xa744e5cb>;
 	execution-ctx-count = <1>;
-	exception-level = <2>; /* S-EL1 */
+	exception-level = <1>; /* S-EL0 */
 	execution-state = <0>; /* AARCH64 */
-	load-address = <0x7600000>;
+	load-address = <0xfe280000>;
 	entrypoint-offset = <0x00004000>;
-	xlat-granule = <0>; /* 4KiB */
 	boot-order = <0>;
 	messaging-method = <3>; /* Direct messaging only */
-	run-time-model = <1>; /* SP pre-emptible */
 
 	/* Boot protocol */
 	gp-register-num = <0x0>;
diff --git a/spm/ivy/app/plat/arm/fvp/fdts/ivy.dts b/spm/ivy/app/plat/arm/tc0/fdts/ivy-sel1.dts
similarity index 70%
copy from spm/ivy/app/plat/arm/fvp/fdts/ivy.dts
copy to spm/ivy/app/plat/arm/tc0/fdts/ivy-sel1.dts
index d368076..1d4df60 100644
--- a/spm/ivy/app/plat/arm/fvp/fdts/ivy.dts
+++ b/spm/ivy/app/plat/arm/tc0/fdts/ivy-sel1.dts
@@ -1,31 +1,29 @@
 /*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2020-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
  * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP)
- * that has additional optional properties defined.
+ * intended to run at S-EL0 utilising a shim to run at S-EL1 on a
+ * non VHE enabled hadnium.
  */
 
-
 /dts-v1/;
 
 / {
 	compatible = "arm,ffa-manifest-1.0";
 
 	/* Properties */
-	description = "ivy-1";
+	description = "ivy-sel1-tc0";
 	ffa-version = <0x00010001>; /* 31:16 - Major, 15:0 - Minor */
 	uuid = <0xd883baea 0xaf4eafba 0xfdf74481 0xa744e5cb>;
 	execution-ctx-count = <1>;
 	exception-level = <2>; /* S-EL1 */
 	execution-state = <0>; /* AARCH64 */
-	load-address = <0x7600000>;
+	load-address = <0xfe280000>;
 	entrypoint-offset = <0x00004000>;
-	xlat-granule = <0>; /* 4KiB */
 	boot-order = <0>;
 	messaging-method = <3>; /* Direct messaging only */
-	run-time-model = <1>; /* SP pre-emptible */
 
 	/* Boot protocol */
 	gp-register-num = <0x0>;
diff --git a/spm/ivy/app/plat/arm/tc0/fdts/ivy.dts b/spm/ivy/app/plat/arm/tc0/fdts/ivy.dts
deleted file mode 100644
index 405dca7..0000000
--- a/spm/ivy/app/plat/arm/tc0/fdts/ivy.dts
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2020-2021, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP)
- * that has additional optional properties defined.
- */
-
-
-/dts-v1/;
-
-/ {
-	compatible = "arm,ffa-manifest-1.0";
-
-	/* Properties */
-	description = "ivy-1";
-	ffa-version = <0x00010001>; /* 31:16 - Major, 15:0 - Minor */
-	uuid = <0xd883baea 0xaf4eafba 0xfdf74481 0xa744e5cb>;
-	id = <1>;
-	auxiliary-id = <0xae>;
-	stream-endpoint-ids = <0 1 2 3>;
-	execution-ctx-count = <1>;
-	exception-level = <2>; /* S-EL1 */
-	execution-state = <0>; /* AARCH64 */
-	load-address = <0xfe600000>;
-	entrypoint-offset = <0x00004000>;
-	xlat-granule = <0>; /* 4KiB */
-	boot-order = <0>;
-	messaging-method = <3>; /* Direct messaging only */
-	run-time-model = <1>; /* SP pre-emptible */
-
-	/* Boot protocol */
-	gp-register-num = <0x0>;
-};
diff --git a/spm/ivy/app/plat/arm/tc0/platform.mk b/spm/ivy/app/plat/arm/tc0/platform.mk
index 10342d2..72b1521 100644
--- a/spm/ivy/app/plat/arm/tc0/platform.mk
+++ b/spm/ivy/app/plat/arm/tc0/platform.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2021, Arm Limited. All rights reserved.
+# Copyright (c) 2021-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -9,7 +9,11 @@
 PLAT_INCLUDES		+= -I${TC0_IVY_BASE}/include/
 
 # Add the FDT source
-IVY_DTS		= ${TC0_IVY_BASE}/fdts/ivy.dts
+ifeq ($(IVY_SHIM),0)
+IVY_DTS		= ${TC0_IVY_BASE}/fdts/ivy-sel0.dts
+else
+IVY_DTS		= ${TC0_IVY_BASE}/fdts/ivy-sel1.dts
+endif
 
 # List of FDTS to copy
-FDTS_CP_LIST		= ${TC0_IVY_BASE}/fdts/ivy.dts
+FDTS_CP_LIST		=  $(IVY_DTS)
diff --git a/spm/ivy/ivy.ld.S b/spm/ivy/ivy.ld.S
index 0e47c21..b21201b 100644
--- a/spm/ivy/ivy.ld.S
+++ b/spm/ivy/ivy.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2022, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -10,7 +10,13 @@
 
 OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
 OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
+
+#if IVY_SHIM == 1
 ENTRY(shim_entrypoint)
+#else
+ENTRY(ivy_entrypoint)
+#endif
+
 
 SECTIONS
 {
@@ -19,7 +25,7 @@
     ASSERT(. == ALIGN(PAGE_SIZE),
            "TEXT_START address is not aligned to PAGE_SIZE.")
 
-    /*----------------- START S-EL1 SHIM ----------------*/
+#if IVY_SHIM == 1
 
     .shim_text : {
         __SHIM_TEXT_START__ = .;
@@ -59,7 +65,7 @@
         __SHIM_BSS_END__ = .;
     }
 
-    /*----------------- END S-EL1 SHIM ----------------*/
+#endif
 
     .text : {
         __TEXT_START__ = .;
diff --git a/spm/ivy/ivy.mk b/spm/ivy/ivy.mk
index f58422f..9531f9b 100644
--- a/spm/ivy/ivy.mk
+++ b/spm/ivy/ivy.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -13,7 +13,13 @@
 	include ${IVY_PLAT_PATH}/platform.mk
 endif
 
-IVY_DTB		:= build/${PLAT}/debug/ivy.dtb
+IVY_SHIM	:= 1
+
+ifeq (${IVY_SHIM},1)
+	IVY_DTB		:= $(BUILD_PLAT)/ivy-sel1.dtb
+else
+	IVY_DTB		:= $(BUILD_PLAT)/ivy-sel0.dtb
+endif
 
 IVY_INCLUDES :=					\
 	-Itftf/framework/include			\
@@ -35,11 +41,6 @@
 		aarch64/ivy_entrypoint.S		\
 		ivy_main.c				\
 	)						\
-	$(addprefix spm/ivy/shim/,			\
-		aarch64/spm_shim_entrypoint.S		\
-		aarch64/spm_shim_exceptions.S		\
-		shim_main.c				\
-	)						\
 	$(addprefix spm/common/,			\
 		aarch64/sp_arch_helpers.S		\
 		sp_debug.c				\
@@ -47,6 +48,15 @@
 		spm_helpers.c				\
 	)						\
 
+ifeq ($(IVY_SHIM),1)
+IVY_SOURCES	+=					\
+	$(addprefix spm/ivy/shim/,			\
+		aarch64/spm_shim_entrypoint.S		\
+		aarch64/spm_shim_exceptions.S		\
+		shim_main.c				\
+	)
+endif
+
 # TODO: Remove dependency on TFTF files.
 IVY_SOURCES	+=					\
 	tftf/framework/debug.c				\
@@ -75,14 +85,15 @@
 $(eval $(call add_define,IVY_DEFINES,ENABLE_PAUTH))
 $(eval $(call add_define,IVY_DEFINES,LOG_LEVEL))
 $(eval $(call add_define,IVY_DEFINES,PLAT_${PLAT}))
+$(eval $(call add_define,IVY_DEFINES,IVY_SHIM))
 
 $(IVY_DTB) : $(BUILD_PLAT)/ivy $(BUILD_PLAT)/ivy/ivy.elf
 $(IVY_DTB) : $(IVY_DTS)
 	@echo "  DTBGEN  $@"
 	${Q}tools/generate_dtb/generate_dtb.sh \
-		ivy ${IVY_DTS} $(BUILD_PLAT)
+		ivy ${IVY_DTS} $(BUILD_PLAT) $(IVY_DTB)
 	${Q}tools/generate_json/generate_json.sh \
-		ivy $(BUILD_PLAT)
+		ivy $(BUILD_PLAT) $(IVY_SHIM)
 	@echo
 	@echo "Built $@ successfully"
 	@echo
diff --git a/spm/quark/quark.mk b/spm/quark/quark.mk
index 0fe1646..fb2851d 100644
--- a/spm/quark/quark.mk
+++ b/spm/quark/quark.mk
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -63,7 +63,7 @@
 $(QUARK_DTB) : spm/quark/quark.dts
 	@echo "  DTBGEN  spm/quark/quark.dts"
 	${Q}tools/generate_dtb/generate_dtb.sh \
-		quark spm/quark/quark.dts $(BUILD_PLAT)
+		quark spm/quark/quark.dts $(BUILD_PLAT) $(QUARK_DTB)
 	@echo
 	@echo "Built $@ successfully"
 	@echo
diff --git a/tools/generate_dtb/generate_dtb.sh b/tools/generate_dtb/generate_dtb.sh
index 564c2a0..f4a4271 100755
--- a/tools/generate_dtb/generate_dtb.sh
+++ b/tools/generate_dtb/generate_dtb.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 
 #
-# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -12,13 +12,14 @@
 # $1 = image_name (lowercase)
 # $2 = path/to/file.dts
 # $3 = build/$PLAT/$BUILD_TYPE/
+# $4 = path to store the dtb generated by this script
 
 ORIGINAL_DTS=$2
 MAPFILE="$3/$1/$1.map"
 EXTRA_DTS="$3/$1/$1_extra.dts"
 COMBINED_DTS="$3/$1/$1_combined.dts"
 PREPROCESSED_DTS="$3/$1/$1_preprocessed.dts"
-GENERATED_DTB="$3/$1.dtb"
+GENERATED_DTB=$4
 
 # Look for the start and end of the sections that are only known in the elf file
 # after compiling the partition.
diff --git a/tools/generate_json/generate_json.sh b/tools/generate_json/generate_json.sh
index d1b861f..0485862 100755
--- a/tools/generate_json/generate_json.sh
+++ b/tools/generate_json/generate_json.sh
@@ -1,26 +1,52 @@
 #!/bin/bash
 
 #
-# Copyright (c) 2020-2021, Arm Limited. All rights reserved.
+# Copyright (c) 2020-2022, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 # Generate a JSON file which will be fed to TF-A as SPM_LAYOUT_FILE to package
 # Secure Partitions as part of FIP.
+# Note the script will append the partition to the existing layout file.
+# If you wish to only generate a layout file with this partition first run
+# "make realclean" to remove the existing file.
 
-# $1 = Secure Partition (cactus)
+# $1 = Secure Partition
 # $2 = Platform built path
+# $3 = Ivy Shim present
 # Output = $2/sp_layout.json
 
 GENERATED_JSON=$2/sp_layout.json
+primary_dts="$1.dts"
+
+# Remove closing bracket and add comma if the dts is already present.
+if [ ! -f "$GENERATED_JSON" ]; then
+	echo -e "{\n" >> "$GENERATED_JSON"
+else
+	if [ "$1" == "ivy" ]; then
+		if [ "$3" == "1" ]; then
+			primary_dts="ivy-sel1.dts"
+		else
+			primary_dts="ivy-sel0.dts"
+		fi
+	fi
+
+	if [ $(grep "$primary_dts" "$GENERATED_JSON" | wc -l) -eq "0" ]; then
+		sed -i '$d' "$GENERATED_JSON"
+		sed -i '$ s/$/,/' "$GENERATED_JSON"
+		echo -e "\n" >> "$GENERATED_JSON"
+	else
+		exit 0
+	fi
+fi
 
 # To demonstrate communication between SP's, two cactus S-EL1 instances used.
 # To also test mapping of the RXTX region a third cactus S-EL1 instance is used.
 # cactus-primary, cactus-secondary and cactus-tertiary have same binary but
 # different partition manifests.
 if [ "$1" == "cactus" ]; then
-	echo -e "{\n\t\"$1-primary\" : {\n \
+	echo -e "\t\"$1-primary\" : {\n \
 	\t\"image\": {\n \
 	\t\t\"file\": \"$1.bin\",\n \
 	\t\t\"offset\":\"0x2000\"\n\
@@ -35,12 +61,15 @@
 	\t\"owner\": \"Plat\"\n\t},\n\n\t\"$1-tertiary\" : {\n \
 	\t\"image\": \"$1.bin\",\n \
 	\t\"pm\": \"$1-tertiary.dts\",\n \
-	\t\"owner\": \"Plat\"\n\t},\n\n\t\"ivy\" : {\n \
+	\t\"owner\": \"Plat\"\n\t}" \
+	>> "$GENERATED_JSON"
+elif [ "$1" == "ivy" ]; then
+	echo -e "\t\"ivy\" : {\n \
 	\t\"image\": \"ivy.bin\",\n \
-	\t\"pm\": \"ivy.dts\", \n \
-	\t\"owner\": \"Plat\"\n \
-	}\n}" \
-	> "$GENERATED_JSON"
+	\t\"pm\": \"$primary_dts\",\n \
+	\t\"owner\": \"Plat\"\n\t}" >> "$GENERATED_JSON"
 else
-	echo -e "\nWarning: Only Cactus is supported as Secure Partition\n"
+	echo -e "\nWarning: Secure Partition not supported\n"
 fi
+
+echo -e "}" >> "$GENERATED_JSON"