SPM: Add shim layer to Ivy partition and enable PIE

Add a shim layer that runs at S-EL1 to the Ivy partition.
Also enable Ivy to be built with PIE.

Signed-off-by: Ruari Phipps <ruari.phipps@arm.com>
Signed-off-by: Daniel Boulby <daniel.boulby@arm.com>
Change-Id: I821a8ac99d07200aec93ca29d182f8ab6716616c
diff --git a/Makefile b/Makefile
index 8eba940..69d55be 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2021, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
@@ -289,9 +289,9 @@
 
 IVY_SOURCES		+= ${LIBC_SRCS}
 IVY_INCLUDES		+= ${PLAT_INCLUDES}
-IVY_CFLAGS		+= ${COMMON_CFLAGS}
+IVY_CFLAGS		+= ${COMMON_CFLAGS} -fpie
 IVY_ASFLAGS		+= ${COMMON_ASFLAGS}
-IVY_LDFLAGS		+= ${COMMON_LDFLAGS}
+IVY_LDFLAGS		+= ${COMMON_LDFLAGS} $(PIE_LDFLAGS)
 
 QUARK_SOURCES		+= ${LIBC_SRCS}
 QUARK_INCLUDES		+= ${PLAT_INCLUDES}
diff --git a/include/common/aarch64/asm_macros.S b/include/common/aarch64/asm_macros.S
index d829133..8a69c38 100644
--- a/include/common/aarch64/asm_macros.S
+++ b/include/common/aarch64/asm_macros.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -79,6 +79,15 @@
 	.endm
 
 	/*
+	 * Create a vector entry that just spins making the exception unrecoverable.
+	 */
+	.macro vector_entry_spin name
+	vector_entry \name
+	b \name
+	end_vector_entry \name
+	.endm
+
+	/*
 	 * This macro calculates the base address of an MP stack using the
 	 * platform_get_core_pos() index, the name of the stack storage and
 	 * the size of each stack
diff --git a/lib/aarch64/exception_stubs.S b/lib/aarch64/exception_stubs.S
index 1d243de..b186e82 100644
--- a/lib/aarch64/exception_stubs.S
+++ b/lib/aarch64/exception_stubs.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -12,11 +12,6 @@
  * Simplistic exceptions vector table.
  * All entries spin, which means all types of exceptions are unrecoverable.
  */
-	.macro vector_entry_spin name
-	vector_entry \name
-	b \name
-	end_vector_entry \name
-	.endm
 
 vector_base exception_stubs
 vector_entry_spin sync_exception_sp_el0
diff --git a/plat/arm/fvp/platform.mk b/plat/arm/fvp/platform.mk
index 42779c7..4f8c4bd 100644
--- a/plat/arm/fvp/platform.mk
+++ b/plat/arm/fvp/platform.mk
@@ -83,6 +83,7 @@
 			plat/arm/fvp/plat_setup.c
 
 CACTUS_SOURCES	+=	plat/arm/fvp/${ARCH}/plat_helpers.S
+IVY_SOURCES	+=	plat/arm/fvp/${ARCH}/plat_helpers.S
 
 # Firmware update is implemented on FVP.
 FIRMWARE_UPDATE := 1
diff --git a/plat/arm/tc0/platform.mk b/plat/arm/tc0/platform.mk
index faf0d19..1cfe9ee 100644
--- a/plat/arm/tc0/platform.mk
+++ b/plat/arm/tc0/platform.mk
@@ -32,6 +32,7 @@
 			plat/arm/tc0/tc0_topology.c
 
 CACTUS_SOURCES	+=	plat/arm/tc0/${ARCH}/plat_helpers.S
+IVY_SOURCES	+=	plat/arm/tc0/${ARCH}/plat_helpers.S
 
 PLAT_TESTS_SKIP_LIST	:=	plat/arm/tc0/tests_to_skip.txt
 
diff --git a/spm/ivy/aarch64/ivy_entrypoint.S b/spm/ivy/aarch64/ivy_entrypoint.S
index c6cb8b3..f79a577 100644
--- a/spm/ivy/aarch64/ivy_entrypoint.S
+++ b/spm/ivy/aarch64/ivy_entrypoint.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -20,6 +20,23 @@
 	/* Setup the stack pointer. */
 	adr	x0, stacks_end
 	mov	sp, x0
+	adr	x0, spm_shim_exceptions_ptr
+	msr	vbar_el1, x0
+
+	/* Enable I-Cache */
+	mrs	x0, sctlr_el1
+	orr	x0, x0, #SCTLR_I_BIT
+	msr	sctlr_el1, x0
+	isb
+
+	/* Relocate symbols */
+pie_fixup:
+	ldr	x0, =pie_fixup
+	and	x0, x0, #~(0x1000 - 1)
+	mov	x1, #IVY_IMAGE_SIZE
+	add	x1, x1, x0
+	bl	fixup_gdt_reloc
+
 
 	/* And jump to the C entrypoint. */
 	b	ivy_main
diff --git a/spm/ivy/aarch64/spm_shim_exceptions.S b/spm/ivy/aarch64/spm_shim_exceptions.S
new file mode 100644
index 0000000..07527e6
--- /dev/null
+++ b/spm/ivy/aarch64/spm_shim_exceptions.S
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch.h>
+#include <asm_macros.S>
+
+/* -----------------------------------------------------------------------------
+ * Very simple stackless exception handlers used by the spm shim layer.
+ * -----------------------------------------------------------------------------
+ */
+	.globl	spm_shim_exceptions_ptr
+
+vector_base spm_shim_exceptions_ptr
+
+	/* -----------------------------------------------------
+	 * Current EL with SP0 : 0x0 - 0x200
+	 * -----------------------------------------------------
+	 */
+vector_entry_spin sync_exception_sp_el0
+
+vector_entry_spin irq_sp_el0
+
+vector_entry_spin fiq_ep_el0
+
+vector_entry_spin serror_ep_el0
+
+	/* -----------------------------------------------------
+	 * Current EL with SPx: 0x200 - 0x400
+	 * -----------------------------------------------------
+	 */
+vector_entry_spin sync_exception_sp_elx
+
+vector_entry_spin irq_sp_elx
+
+vector_entry_spin fiq_sp_elx
+
+vector_entry_spin serror_sp_elx
+
+	/* -----------------------------------------------------
+	 * Lower EL using AArch64 : 0x400 - 0x600. No exceptions
+	 * are handled since secure_partition does not implement
+	 * a lower EL
+	 * -----------------------------------------------------
+	 */
+vector_entry sync_exception_aarch64
+	msr	tpidr_el1, x30
+	mrs	x30, esr_el1
+	ubfx	x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH
+
+	cmp	x30, #EC_AARCH64_SVC
+	b.eq 	do_smc
+
+	cmp	x30, #EC_AARCH32_SVC
+	b.eq	do_smc
+
+	cmp	x30, #EC_AARCH64_SYS
+	b.eq	handle_sys_trap
+
+	/* Fail in all the other cases */
+	b	panic
+
+	/* ---------------------------------------------
+	 * Tell SPM that we are done initialising
+	 * ---------------------------------------------
+	 */
+do_smc:
+	mrs	x30, tpidr_el1
+	smc	#0
+	eret
+
+	/* AArch64 system instructions trap are handled as a panic for now */
+handle_sys_trap:
+panic:
+	b	panic
+end_vector_entry sync_exception_aarch64
+
+vector_entry_spin irq_aarch64
+
+vector_entry_spin fiq_aarch64
+
+vector_entry_spin serror_aarch64
+
+	/* -----------------------------------------------------
+	 * Lower EL using AArch32 : 0x600 - 0x800
+	 * -----------------------------------------------------
+	 */
+vector_entry_spin sync_exception_aarch32
+
+vector_entry_spin irq_aarch32
+
+vector_entry_spin fiq_aarch32
+
+vector_entry_spin serror_aarch32
diff --git a/spm/ivy/ivy.ld.S b/spm/ivy/ivy.ld.S
index 634db15..a247ee4 100644
--- a/spm/ivy/ivy.ld.S
+++ b/spm/ivy/ivy.ld.S
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  */
@@ -32,6 +32,16 @@
         . = ALIGN(PAGE_SIZE);
         __RODATA_START__ = .;
         *(.rodata*)
+        /*
+         * Keep the .got section in the RO section as it is patched
+         * prior to enabling the MMU, so having it in RO is better for
+         * security. GOT is a table of addresses so ensure 8-byte alignment.
+         */
+        . = ALIGN(8);
+        __GOT_START__ = .;
+        *(.got)
+        __GOT_END__ = .;
+
         . = NEXT(PAGE_SIZE);
         __RODATA_END__ = .;
     }
@@ -44,6 +54,18 @@
         __DATA_END__ = .;
     }
 
+    /*
+     * .rela.dyn needs to come after .data for the read-elf utility
+     * to parse this section correctly. Ensure 8-byte alignment so
+     * that the fields of RELA data structure are aligned.
+     */
+    . = ALIGN(8);
+    __RELA_START__ = .;
+    .rela.dyn . : {
+    }
+    __RELA_END__ = .;
+
+
     .bss (NOLOAD) : {
         . = ALIGN(PAGE_SIZE);
         __BSS_START__ = .;
diff --git a/spm/ivy/ivy.mk b/spm/ivy/ivy.mk
index a500049..87eea43 100644
--- a/spm/ivy/ivy.mk
+++ b/spm/ivy/ivy.mk
@@ -1,15 +1,17 @@
 #
-# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2021, Arm Limited. All rights reserved.
 #
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
 include branch_protection.mk
 include lib/sprt/sprt_client.mk
+include lib/xlat_tables_v2/xlat_tables.mk
 
 IVY_DTB		:= $(BUILD_PLAT)/ivy.dtb
 
 IVY_INCLUDES :=					\
+	-Itftf/framework/include			\
 	-Iinclude					\
 	-Iinclude/common				\
 	-Iinclude/common/${ARCH}			\
@@ -21,12 +23,12 @@
 	-Iinclude/runtime_services			\
 	-Iinclude/runtime_services/secure_el0_payloads	\
 	-Ispm/ivy					\
-	-Ispm/common					\
-	${SPRT_LIB_INCLUDES}
+	-Ispm/common
 
 IVY_SOURCES	:=					\
 	$(addprefix spm/ivy/,			\
 		aarch64/ivy_entrypoint.S		\
+		aarch64/spm_shim_exceptions.S		\
 		ivy_main.c				\
 	)						\
 	$(addprefix spm/common/,			\
@@ -37,7 +39,8 @@
 # TODO: Remove dependency on TFTF files.
 IVY_SOURCES	+=					\
 	tftf/framework/debug.c				\
-	tftf/framework/${ARCH}/asm_debug.S
+	tftf/framework/${ARCH}/asm_debug.S		\
+	tftf/tests/runtime_services/secure_service/ffa_helpers.c
 
 IVY_SOURCES	+= 	drivers/arm/pl011/${ARCH}/pl011_console.S	\
 			drivers/console/console.c			\
@@ -45,7 +48,8 @@
 			lib/${ARCH}/misc_helpers.S			\
 			lib/locks/${ARCH}/spinlock.S			\
 			lib/utils/mp_printf.c				\
-			${SPRT_LIB_SOURCES}
+			${SPRT_LIB_SOURCES}				\
+			${XLAT_TABLES_LIB_SRCS}
 
 IVY_LINKERFILE	:=	spm/ivy/ivy.ld.S