SPM: S-EL0 partitions support build for TC0

Add support for building Ivy for the TC0 platform. To do this
extend the Ivy build system to support building for multiple
platforms.

Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
Change-Id: I47298f00ba91f498826dd3ddd690309df01cc13e
diff --git a/spm/common/sp_debug.c b/spm/common/sp_debug.c
index 64ea9c5..396253b 100644
--- a/spm/common/sp_debug.c
+++ b/spm/common/sp_debug.c
@@ -7,6 +7,7 @@
 #include <drivers/arm/pl011.h>
 #include <drivers/console.h>
 #include <sp_debug.h>
+#include <sp_helpers.h>
 #include <spm_helpers.h>
 
 static int (*putc_impl)(int);
@@ -18,6 +19,18 @@
 	return c;
 }
 
+static int putc_svccall(int c)
+{
+	/* TODO svc call */
+	svc_args args = {
+		.fid = SPM_DEBUG_LOG,
+		.arg1 = c
+	};
+	sp_svc(&args);
+
+	return c;
+}
+
 static int putc_uart(int c)
 {
 	console_pl011_putc(c);
@@ -33,6 +46,10 @@
 		putc_impl = putc_hypcall;
 		return;
 
+	case SVC_CALL_AS_STDOUT:
+		putc_impl = putc_svccall;
+		return;
+
 	case PL011_AS_STDOUT:
 	default:
 		break;
diff --git a/spm/common/sp_debug.h b/spm/common/sp_debug.h
index 8b0bec7..e35c602 100644
--- a/spm/common/sp_debug.h
+++ b/spm/common/sp_debug.h
@@ -7,6 +7,7 @@
 enum stdout_route {
 	PL011_AS_STDOUT = 0,
 	HVC_CALL_AS_STDOUT,
+	SVC_CALL_AS_STDOUT,
 };
 
 void set_putc_impl(enum stdout_route);
diff --git a/spm/ivy/app/ivy_main.c b/spm/ivy/app/ivy_main.c
index f51fcb5..28f93ab 100644
--- a/spm/ivy/app/ivy_main.c
+++ b/spm/ivy/app/ivy_main.c
@@ -8,8 +8,7 @@
 #include <debug.h>
 #include <errno.h>
 #include <ffa_helpers.h>
-#include <ivy_def.h>
-#include <platform_def.h>
+#include <sp_debug.h>
 #include <sp_helpers.h>
 
 #include "ivy.h"
@@ -23,6 +22,8 @@
 	u_register_t ret;
 	svc_args args;
 
+	set_putc_impl(SVC_CALL_AS_STDOUT);
+
 	NOTICE("Entering S-EL0 Secure Partition\n");
 	NOTICE("%s\n", build_message);
 	NOTICE("%s\n", version_string);
@@ -30,16 +31,20 @@
 init:
 	args = (svc_args){.fid = FFA_MSG_WAIT};
 	ret = sp_svc(&args);
+
 	while (1) {
 		if (ret != FFA_MSG_SEND_DIRECT_REQ_SMC32) {
 			ERROR("unknown FF-A request %lx\n", ret);
 			goto init;
 		}
+
 		VERBOSE("Received request: %lx\n", args.arg3);
+
 		args.fid = FFA_MSG_SEND_DIRECT_RESP_SMC32;
 		args.arg1 = 0x80020000;
 		args.arg2 = 0;
 		args.arg3 = 0;
+
 		ret = sp_svc(&args);
 	}
 }
diff --git a/spm/ivy/app/ivy.dts b/spm/ivy/app/plat/arm/fvp/fdts/ivy.dts
similarity index 100%
rename from spm/ivy/app/ivy.dts
rename to spm/ivy/app/plat/arm/fvp/fdts/ivy.dts
diff --git a/spm/ivy/app/plat/arm/fvp/include/ivy_platform_def.h b/spm/ivy/app/plat/arm/fvp/include/ivy_platform_def.h
new file mode 100644
index 0000000..3658c83
--- /dev/null
+++ b/spm/ivy/app/plat/arm/fvp/include/ivy_platform_def.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#ifndef CACTUS_PLATFORM_DEF_H
+#define CACTUS_PLATFORM_DEF_H
+
+#define PLAT_ARM_DEVICE0_BASE		DEVICE0_BASE
+#define PLAT_ARM_DEVICE0_SIZE		DEVICE0_SIZE
+
+#define CACTUS_PL011_UART_BASE		PL011_UART2_BASE
+#define CACTUS_PL011_UART_CLK_IN_HZ	PL011_UART2_CLK_IN_HZ
+
+#define PLAT_CACTUS_RX_BASE		ULL(0x7300000)
+
+#define CACTUS_PRIMARY_EC_COUNT		(8U)
+#define CACTUS_SECONDARY_EC_COUNT	(8U)
+#define CACTUS_TERTIARY_EC_COUNT	(8U)
+
+#endif /* CACTUS_PLATFORM_DEF_H */
diff --git a/spm/ivy/app/plat/arm/fvp/platform.mk b/spm/ivy/app/plat/arm/fvp/platform.mk
new file mode 100644
index 0000000..1e9a43b
--- /dev/null
+++ b/spm/ivy/app/plat/arm/fvp/platform.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+FVP_IVY_BASE		= spm/ivy/app/plat/arm/fvp
+
+PLAT_INCLUDES		+= -I${FVP_IVY_BASE}/include/
+
+# Add the FDT source
+IVY_DTS		= ${FVP_IVY_BASE}/fdts/ivy.dts
+
+# List of FDTS to copy
+FDTS_CP_LIST		= ${FVP_IVY_BASE}/fdts/ivy.dts
diff --git a/spm/ivy/app/plat/arm/tc0/fdts/ivy.dts b/spm/ivy/app/plat/arm/tc0/fdts/ivy.dts
new file mode 100644
index 0000000..2a22e20
--- /dev/null
+++ b/spm/ivy/app/plat/arm/tc0/fdts/ivy.dts
@@ -0,0 +1,35 @@
+/*
+ * 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 = <0x00010000>; /* 31:16 - Major, 15:0 - Minor */
+	uuid = <0xeaba83d8 0xbaaf4eaf 0x8144f7fd 0xcbe544a7>;
+	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 = <0xfe280000>;
+	entrypoint-offset = <0x00001000>;
+	xlat-granule = <0>; /* 4KiB */
+	boot-order = <0>;
+	messaging-method = <0>; /* 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/include/ivy_platform_def.h b/spm/ivy/app/plat/arm/tc0/include/ivy_platform_def.h
new file mode 100644
index 0000000..3658c83
--- /dev/null
+++ b/spm/ivy/app/plat/arm/tc0/include/ivy_platform_def.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <platform_def.h>
+
+#ifndef CACTUS_PLATFORM_DEF_H
+#define CACTUS_PLATFORM_DEF_H
+
+#define PLAT_ARM_DEVICE0_BASE		DEVICE0_BASE
+#define PLAT_ARM_DEVICE0_SIZE		DEVICE0_SIZE
+
+#define CACTUS_PL011_UART_BASE		PL011_UART2_BASE
+#define CACTUS_PL011_UART_CLK_IN_HZ	PL011_UART2_CLK_IN_HZ
+
+#define PLAT_CACTUS_RX_BASE		ULL(0x7300000)
+
+#define CACTUS_PRIMARY_EC_COUNT		(8U)
+#define CACTUS_SECONDARY_EC_COUNT	(8U)
+#define CACTUS_TERTIARY_EC_COUNT	(8U)
+
+#endif /* CACTUS_PLATFORM_DEF_H */
diff --git a/spm/ivy/app/plat/arm/tc0/platform.mk b/spm/ivy/app/plat/arm/tc0/platform.mk
new file mode 100644
index 0000000..10342d2
--- /dev/null
+++ b/spm/ivy/app/plat/arm/tc0/platform.mk
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2021, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+TC0_IVY_BASE		= spm/ivy/app/plat/arm/tc0
+
+PLAT_INCLUDES		+= -I${TC0_IVY_BASE}/include/
+
+# Add the FDT source
+IVY_DTS		= ${TC0_IVY_BASE}/fdts/ivy.dts
+
+# List of FDTS to copy
+FDTS_CP_LIST		= ${TC0_IVY_BASE}/fdts/ivy.dts
diff --git a/spm/ivy/ivy.mk b/spm/ivy/ivy.mk
index 7230a45..d184097 100644
--- a/spm/ivy/ivy.mk
+++ b/spm/ivy/ivy.mk
@@ -7,7 +7,13 @@
 include branch_protection.mk
 include lib/xlat_tables_v2/xlat_tables.mk
 
-IVY_DTB		:= $(BUILD_PLAT)/ivy.dtb
+# Include ivy platform Makefile
+IVY_PLAT_PATH	:= $(shell find spm/ivy/app/plat -wholename '*/${PLAT}')
+ifneq (${IVY_PLAT_PATH},)
+	include ${IVY_PLAT_PATH}/platform.mk
+endif
+
+IVY_DTB		:= build/${PLAT}/debug/ivy.dtb
 
 IVY_INCLUDES :=					\
 	-Itftf/framework/include			\
@@ -74,12 +80,31 @@
 $(eval $(call add_define,IVY_DEFINES,PLAT_${PLAT}))
 
 $(IVY_DTB) : $(BUILD_PLAT)/ivy $(BUILD_PLAT)/ivy/ivy.elf
-$(IVY_DTB) : spm/ivy/app/ivy.dts
-	@echo "  DTBGEN  spm/ivy/app/ivy.dts"
+$(IVY_DTB) : $(IVY_DTS)
+	@echo "  DTBGEN  $@"
 	${Q}tools/generate_dtb/generate_dtb.sh \
-		ivy spm/ivy/app/ivy.dts $(BUILD_PLAT)
+		ivy ${IVY_DTS} $(BUILD_PLAT)
+	${Q}tools/generate_json/generate_json.sh \
+		ivy $(BUILD_PLAT)
 	@echo
 	@echo "Built $@ successfully"
 	@echo
 
 ivy: $(IVY_DTB)
+
+# FDTS_CP copies flattened device tree sources
+#   $(1) = output directory
+#   $(2) = flattened device tree source file to copy
+define FDTS_CP
+        $(eval FDTS := $(addprefix $(1)/,$(notdir $(2))))
+FDTS_LIST += $(FDTS)
+$(FDTS): $(2) $(IVY_DTB)
+	@echo "  CP      $$<"
+	${Q}cp $$< $$@
+endef
+
+ifdef FDTS_CP_LIST
+        $(eval files := $(filter %.dts,$(FDTS_CP_LIST)))
+        $(eval $(foreach file,$(files),$(call FDTS_CP,$(BUILD_PLAT),$(file))))
+ivy: $(FDTS_LIST)
+endif