quark: Introduce Quark Secure Partition

Test partition designed to have a virtual address space as small as
possible in order to test the extension ARMv8.4-TTST. This Secure
Partition doesn't have print capabilities. The only service it provides
is one that returns a magic number to verify that it has been loaded.

Change-Id: I431f6c65f2926d486836d12ddfefe05e83b0c47f
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
diff --git a/Makefile b/Makefile
index e699def..bd179b9 100644
--- a/Makefile
+++ b/Makefile
@@ -117,6 +117,7 @@
 include spm/cactus_mm/cactus_mm.mk
 include spm/cactus/cactus.mk
 include spm/ivy/ivy.mk
+include spm/quark/quark.mk
 
 ################################################################################
 # Include libc
@@ -256,6 +257,12 @@
 IVY_ASFLAGS		+= ${COMMON_ASFLAGS}
 IVY_LDFLAGS		+= ${COMMON_LDFLAGS}
 
+QUARK_SOURCES		+= ${LIBC_SRCS}
+QUARK_INCLUDES		+= ${PLAT_INCLUDES}
+QUARK_CFLAGS		+= ${COMMON_CFLAGS}
+QUARK_ASFLAGS		+= ${COMMON_ASFLAGS}
+QUARK_LDFLAGS		+= ${COMMON_LDFLAGS}
+
 .PHONY: locate-checkpatch
 locate-checkpatch:
 ifndef CHECKPATCH
@@ -332,6 +339,11 @@
 ivy:
 	@echo "ERROR: $@ is supported only on AArch64 FVP."
 	@exit 1
+
+.PHONY: quark
+quark:
+	@echo "ERROR: $@ is supported only on AArch64 FVP."
+	@exit 1
 endif
 
 MAKE_DEP = -Wp,-MD,$(DEP) -MT $$@
@@ -460,6 +472,7 @@
   $(eval $(call MAKE_IMG,cactus_mm))
   $(eval $(call MAKE_IMG,cactus))
   $(eval $(call MAKE_IMG,ivy))
+  $(eval $(call MAKE_IMG,quark))
 endif
 
 # The EL3 test payload is only supported in AArch64. It has an independent build
@@ -481,7 +494,7 @@
 
 .PHONY: help
 help:
-	@echo "usage: ${MAKE} PLAT=<${PLATFORMS}> <all|tftf|ns_bl1u|ns_bl2u|cactus|ivy|el3_payload|distclean|clean|checkcodebase|checkpatch>"
+	@echo "usage: ${MAKE} PLAT=<${PLATFORMS}> <all|tftf|ns_bl1u|ns_bl2u|cactus|ivy|quark|el3_payload|distclean|clean|checkcodebase|checkpatch>"
 	@echo ""
 	@echo "PLAT is used to specify which platform you wish to build."
 	@echo "If no platform is specified, PLAT defaults to: ${DEFAULT_PLAT}"
@@ -495,6 +508,7 @@
 	@echo "  cactus         Build the Cactus image (Test S-EL0 payload) and resource description."
 	@echo "  cactus_mm      Build the Cactus-MM image (Test S-EL0 payload)."
 	@echo "  ivy            Build the Ivy image (Test S-EL0 payload) and resource description."
+	@echo "  quark          Build the Quark image (Test S-EL0 payload) and resource description."
 	@echo "  el3_payload    Build the EL3 test payload"
 	@echo "  checkcodebase  Check the coding style of the entire source tree"
 	@echo "  checkpatch     Check the coding style on changes in the current"
diff --git a/docs/user-guide.rst b/docs/user-guide.rst
index 4c03ea2..ef12c90 100644
--- a/docs/user-guide.rst
+++ b/docs/user-guide.rst
@@ -103,6 +103,7 @@
       -  ``build/<platform>/<build-type>/cactus_mm.bin``
       -  ``build/<platform>/<build-type>/cactus.bin``
       -  ``build/<platform>/<build-type>/ivy.bin``
+      -  ``build/<platform>/<build-type>/quark.bin``
 
       where ``<platform>`` is the name of the chosen platform and ``<build-type>``
       is either ``debug`` or ``release``. The actual number of images might differ
diff --git a/spm/quark/aarch64/quark_entrypoint.S b/spm/quark/aarch64/quark_entrypoint.S
new file mode 100644
index 0000000..9cbed97
--- /dev/null
+++ b/spm/quark/aarch64/quark_entrypoint.S
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <quark_def.h>
+#include <platform_def.h>
+
+	.globl	quark_entrypoint
+
+.section .bss.stacks
+	.balign CACHE_WRITEBACK_GRANULE
+	.fill	QUARK_STACKS_SIZE
+stacks_end:
+
+func quark_entrypoint
+
+	/* Setup the stack pointer. */
+	adr	x0, stacks_end
+	mov	sp, x0
+
+	/* And jump to the C entrypoint. */
+	b	quark_main
+
+endfunc quark_entrypoint
diff --git a/spm/quark/quark.dts b/spm/quark/quark.dts
new file mode 100644
index 0000000..a8fb4a7
--- /dev/null
+++ b/spm/quark/quark.dts
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <sp_res_desc_def.h>
+
+#include "quark_def.h"
+
+/* 4 KiB pages */
+#define PAGE_SIZE			U(0x1000)
+
+/dts-v1/;
+
+/ {
+	compatible = "arm,sp_rd";
+
+	attribute {
+		version = <0x00000001>;
+		sp_type = <RD_ATTR_TYPE_UP_MIGRATABLE>;
+		pe_mpidr = <0>; /* Unused */
+		runtime_el = <RD_ATTR_RUNTIME_SEL0>;
+		exec_type = <RD_ATTR_RUNTIME>;
+		panic_policy = <RD_ATTR_PANIC_ONESHOT>;
+		xlat_granule = <RD_ATTR_XLAT_GRANULE_4KB>;
+		binary_size = <QUARK_IMAGE_SIZE>;
+		load_address = <0x00000000 QUARK_IMAGE_BASE>;
+		entrypoint = <0x00000000 QUARK_IMAGE_BASE>;
+	};
+
+	memory_regions {
+		spm_buffer {
+			str = "SPM buffer";
+			base = <0x00000000 QUARK_SPM_BUF_BASE>;
+			size = <0x00000000 QUARK_SPM_BUF_SIZE>;
+			attr = <RD_MEM_NORMAL_SPM_SP_SHARED_MEM>;
+		};
+	};
+
+	notifications {
+		notification_0 {
+			attr = <0>;
+			pe = <0>;
+		};
+	};
+
+	services {
+		test_service_1 {
+			uuid = <QUARK_SERVICE1_UUID_RD>;
+
+			accessibility = <(RD_SERV_ACCESS_SECURE |
+					  RD_SERV_ACCESS_EL3 |
+					  RD_SERV_ACCESS_NORMAL)>;
+			request_type = <(RD_SERV_SUPPORT_BLOCKING |
+					 RD_SERV_SUPPORT_NON_BLOCKING)>;
+			connection_quota = <10>;
+			sec_mem_size = <0>;
+			interrupt_num = <0>;
+		};
+	};
+};
diff --git a/spm/quark/quark.h b/spm/quark/quark.h
new file mode 100644
index 0000000..2b4fd39
--- /dev/null
+++ b/spm/quark/quark.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QUARK_H
+#define QUARK_H
+
+#include <stdint.h>
+
+/* Linker symbols used to figure out the memory layout of Quark. */
+extern uintptr_t __TEXT_START__, __TEXT_END__;
+#define QUARK_TEXT_START	((uintptr_t)&__TEXT_START__)
+#define QUARK_TEXT_END		((uintptr_t)&__TEXT_END__)
+
+extern uintptr_t __RODATA_START__, __RODATA_END__;
+#define QUARK_RODATA_START	((uintptr_t)&__RODATA_START__)
+#define QUARK_RODATA_END	((uintptr_t)&__RODATA_END__)
+
+extern uintptr_t __DATA_START__, __DATA_END__;
+#define QUARK_DATA_START	((uintptr_t)&__DATA_START__)
+#define QUARK_DATA_END		((uintptr_t)&__DATA_END__)
+
+extern uintptr_t __BSS_START__, __BSS_END__;
+#define QUARK_BSS_START	((uintptr_t)&__BSS_START__)
+#define QUARK_BSS_END		((uintptr_t)&__BSS_END__)
+
+#endif /* QUARK_H */
diff --git a/spm/quark/quark.ld.S b/spm/quark/quark.ld.S
new file mode 100644
index 0000000..8f51edb
--- /dev/null
+++ b/spm/quark/quark.ld.S
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <quark_def.h>
+#include <platform_def.h>
+#include <xlat_tables_defs.h>
+
+OUTPUT_FORMAT(PLATFORM_LINKER_FORMAT)
+OUTPUT_ARCH(PLATFORM_LINKER_ARCH)
+ENTRY(quark_entrypoint)
+
+SECTIONS
+{
+    . = QUARK_IMAGE_BASE;
+
+    ASSERT(. == ALIGN(PAGE_SIZE),
+           "TEXT_START address is not aligned to PAGE_SIZE.")
+
+    .text : {
+        __TEXT_START__ = .;
+        *quark_entrypoint.o(.text*)
+        *(.text*)
+        *(.vectors)
+        . = NEXT(PAGE_SIZE);
+        __TEXT_END__ = .;
+    }
+
+    .rodata : {
+        . = ALIGN(PAGE_SIZE);
+        __RODATA_START__ = .;
+        *(.rodata*)
+        . = NEXT(PAGE_SIZE);
+        __RODATA_END__ = .;
+    }
+
+    .data : {
+        . = ALIGN(PAGE_SIZE);
+        __DATA_START__ = .;
+        *(.data*)
+        . = NEXT(PAGE_SIZE);
+        __DATA_END__ = .;
+    }
+
+    .bss (NOLOAD) : {
+        . = ALIGN(PAGE_SIZE);
+        __BSS_START__ = .;
+        *(SORT_BY_ALIGNMENT(.bss*))
+        *(COMMON)
+        . = NEXT(PAGE_SIZE);
+        __BSS_END__ = .;
+    }
+}
diff --git a/spm/quark/quark.mk b/spm/quark/quark.mk
new file mode 100644
index 0000000..554d334
--- /dev/null
+++ b/spm/quark/quark.mk
@@ -0,0 +1,64 @@
+#
+# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+include lib/sprt/sprt_client.mk
+
+QUARK_DTB		:= $(BUILD_PLAT)/quark.dtb
+
+QUARK_INCLUDES :=					\
+	-Iinclude					\
+	-Iinclude/common				\
+	-Iinclude/common/${ARCH}			\
+	-Iinclude/lib					\
+	-Iinclude/lib/${ARCH}				\
+	-Iinclude/lib/sprt				\
+	-Iinclude/lib/utils				\
+	-Iinclude/lib/xlat_tables			\
+	-Iinclude/runtime_services			\
+	-Iinclude/runtime_services/secure_el0_payloads	\
+	-Ispm/quark					\
+	-Ispm/common					\
+	${SPRT_LIB_INCLUDES}
+
+QUARK_SOURCES	:=					\
+	$(addprefix spm/quark/,				\
+		aarch64/quark_entrypoint.S		\
+		quark_main.c				\
+	)						\
+	$(addprefix spm/common/,			\
+		aarch64/sp_arch_helpers.S		\
+		sp_helpers.c				\
+	)						\
+
+# TODO: Remove dependency on TFTF files.
+QUARK_SOURCES	+=					\
+	tftf/framework/debug.c				\
+	tftf/framework/${ARCH}/asm_debug.S
+
+QUARK_SOURCES	+= 	drivers/console/${ARCH}/dummy_console.S		\
+			lib/locks/${ARCH}/spinlock.S			\
+			lib/utils/mp_printf.c				\
+			${SPRT_LIB_SOURCES}
+
+QUARK_LINKERFILE	:=	spm/quark/quark.ld.S
+
+QUARK_DEFINES	:=
+
+$(eval $(call add_define,QUARK_DEFINES,DEBUG))
+$(eval $(call add_define,QUARK_DEFINES,ENABLE_ASSERTIONS))
+$(eval $(call add_define,QUARK_DEFINES,PLAT_${PLAT}))
+$(eval $(call add_define,QUARK_DEFINES,AARCH64))
+
+$(QUARK_DTB) : $(BUILD_PLAT)/quark $(BUILD_PLAT)/quark/quark.elf
+$(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)
+	@echo
+	@echo "Built $@ successfully"
+	@echo
+
+quark: $(QUARK_DTB) $(AUTOGEN_DIR)/tests_list.h
diff --git a/spm/quark/quark_def.h b/spm/quark/quark_def.h
new file mode 100644
index 0000000..7a0ec15
--- /dev/null
+++ b/spm/quark/quark_def.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef QUARK_DEF_H
+#define QUARK_DEF_H
+
+#include <utils_def.h>
+
+/*
+ * Layout of the Secure Partition image.
+ */
+
+/* The base address is 0 to reduce the address space size */
+#define QUARK_IMAGE_BASE		ULL(0x00000000)
+#define QUARK_IMAGE_SIZE		ULL(0x10000)
+
+/* Memory reserved for stacks */
+#define QUARK_STACKS_SIZE		ULL(0x1000)
+
+/* Memory shared between EL3 and S-EL0 (64 KiB). */
+#define QUARK_SPM_BUF_BASE		(QUARK_IMAGE_BASE + QUARK_IMAGE_SIZE)
+#define QUARK_SPM_BUF_SIZE		ULL(0x10000)
+
+/*
+ * UUIDs of Secure Services provided by Quark
+ */
+
+/* Mass (MeV/c^2): Up, down, charm, strange */
+#define QUARK_SERVICE1_UUID	U(0x23), U(0x48), U(0x1275), U(0x95)
+
+#define QUARK_SERVICE1_UUID_RD	U(0x23) U(0x48) U(0x1275) U(0x95)
+
+/*
+ * Service IDs
+ */
+/* Return a magic number unique to QUARK */
+#define QUARK_GET_MAGIC		U(2002)
+
+/* Mass (MeV/c^2): Top */
+#define QUARK_MAGIC_NUMBER	U(0x173210)
+
+#endif /* QUARK_DEF_H */
diff --git a/spm/quark/quark_main.c b/spm/quark/quark_main.c
new file mode 100644
index 0000000..145560b
--- /dev/null
+++ b/spm/quark/quark_main.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <assert.h>
+#include <cdefs.h>
+#include <errno.h>
+#include <quark_def.h>
+#include <sprt_client.h>
+#include <sprt_svc.h>
+#include <utils_def.h>
+
+#include "quark.h"
+#include "quark_def.h"
+
+/* NOTE: This partition doesn't have text output capabilities */
+
+static void quark_message_handler(struct sprt_queue_entry_message *message)
+{
+	u_register_t ret0 = 0U, ret1 = 0U, ret2 = 0U, ret3 = 0U;
+
+	if (message->type == SPRT_MSG_TYPE_SERVICE_REQUEST) {
+		switch (message->args[1]) {
+
+		case QUARK_GET_MAGIC:
+			ret1 = QUARK_MAGIC_NUMBER;
+			ret0 = SPRT_SUCCESS;
+			break;
+
+		default:
+			ret0 = SPRT_NOT_SUPPORTED;
+			break;
+		}
+	} else {
+		ret0 = SPRT_NOT_SUPPORTED;
+	}
+
+	sprt_message_end(message, ret0, ret1, ret2, ret3);
+}
+
+void __dead2 quark_main(void)
+{
+	/*
+	 * Handle secure service requests.
+	 */
+	sprt_initialize_queues((void *)QUARK_SPM_BUF_BASE);
+
+	while (1) {
+		struct sprt_queue_entry_message message;
+
+		/*
+		 * Try to fetch a message from the blocking requests queue. If
+		 * it is empty, try to fetch from the non-blocking requests
+		 * queue. Repeat until both of them are empty.
+		 */
+		while (1) {
+			int err = sprt_get_next_message(&message,
+					SPRT_QUEUE_NUM_BLOCKING);
+			if (err == -ENOENT) {
+				err = sprt_get_next_message(&message,
+						SPRT_QUEUE_NUM_NON_BLOCKING);
+				if (err == -ENOENT) {
+					break;
+				} else {
+					assert(err == 0);
+					quark_message_handler(&message);
+				}
+			} else {
+				assert(err == 0);
+				quark_message_handler(&message);
+			}
+		}
+
+		sprt_wait_for_messages();
+	}
+}
diff --git a/tftf/framework/framework.mk b/tftf/framework/framework.mk
index d51a246..00bb84a 100644
--- a/tftf/framework/framework.mk
+++ b/tftf/framework/framework.mk
@@ -25,7 +25,8 @@
 	-Iinclude/runtime_services/secure_el0_payloads	\
 	-Iinclude/runtime_services/secure_el1_payloads	\
 	-Ispm/cactus					\
-	-Ispm/ivy
+	-Ispm/ivy					\
+	-Ispm/quark
 
 FRAMEWORK_SOURCES	:=	${AUTOGEN_DIR}/tests_list.c
 
diff --git a/tools/generate_dtb/generate_dtb.sh b/tools/generate_dtb/generate_dtb.sh
index efcc67e..20a08d0 100755
--- a/tools/generate_dtb/generate_dtb.sh
+++ b/tools/generate_dtb/generate_dtb.sh
@@ -71,6 +71,7 @@
 
 INCLUDES="-I spm/cactus
 	  -I spm/ivy
+	  -I spm/quark
 	  -I spm/include
 	  -I include/lib"