cactus: Update service handling loop

Also, add test to check SPRT version.

Change-Id: I4e47bba998b86f460df3407d147735e873fd6cf3
Signed-off-by: Antonio Nino Diaz <antonio.ninodiaz@arm.com>
diff --git a/spm/cactus/cactus.h b/spm/cactus/cactus.h
index fb8155f..2f12f5c 100644
--- a/spm/cactus/cactus.h
+++ b/spm/cactus/cactus.h
@@ -26,10 +26,4 @@
 #define CACTUS_BSS_START	((uintptr_t)&__BSS_START__)
 #define CACTUS_BSS_END		((uintptr_t)&__BSS_END__)
 
-/*
- * Once Cactus has finished its initialisation, this is the function it will
- * jump to to handle runtime services for the rest of its lifetime.
- */
-__dead2 void secure_services_loop(void);
-
 #endif /* __CACTUS_H__ */
diff --git a/spm/cactus/cactus.mk b/spm/cactus/cactus.mk
index 6f912e7..6ba0db0 100644
--- a/spm/cactus/cactus.mk
+++ b/spm/cactus/cactus.mk
@@ -4,6 +4,8 @@
 # SPDX-License-Identifier: BSD-3-Clause
 #
 
+include lib/sprt/sprt_client.mk
+
 CACTUS_INCLUDES :=					\
 	-Iinclude					\
 	-Iinclude/common				\
@@ -14,18 +16,19 @@
 	-Iinclude/lib/${ARCH}				\
 	-Iinclude/lib/stdlib				\
 	-Iinclude/lib/stdlib/sys			\
+	-Iinclude/lib/sprt				\
 	-Iinclude/lib/utils				\
 	-Iinclude/lib/xlat_tables			\
 	-Iinclude/runtime_services			\
 	-Iinclude/runtime_services/secure_el0_payloads	\
 	-Ispm/cactus					\
 	-Ispm/common					\
+	${SPRT_LIB_INCLUDES}
 
 CACTUS_SOURCES	:=					\
 	$(addprefix spm/cactus/,			\
 		aarch64/cactus_entrypoint.S		\
 		cactus_main.c				\
-		cactus_service_loop.c			\
 		cactus_tests_memory_attributes.c	\
 		cactus_tests_misc.c			\
 		cactus_tests_system_setup.c		\
@@ -53,7 +56,8 @@
 CACTUS_SOURCES	+= 	drivers/arm/pl011/${ARCH}/pl011_console.S	\
 			lib/${ARCH}/cache_helpers.S			\
 			lib/${ARCH}/misc_helpers.S			\
-			${STDLIB_SOURCES}
+			${STDLIB_SOURCES}				\
+			${SPRT_LIB_SOURCES}
 
 CACTUS_LINKERFILE	:=	spm/cactus/cactus.ld.S
 
diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c
index 889c174..bfbfa48 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -5,12 +5,15 @@
  */
 
 #include <assert.h>
+#include <cactus_def.h>
 #include <console.h>
 #include <debug.h>
+#include <errno.h>
 #include <pl011.h>
 #include <plat_arm.h>
 #include <platform_def.h>
-#include <sp_helpers.h>
+#include <sprt_client.h>
+#include <sprt_svc.h>
 #include <std_svc.h>
 
 #include "cactus.h"
@@ -50,6 +53,38 @@
 		(void *)(CACTUS_TEST_MEM_BASE + CACTUS_TEST_MEM_SIZE));
 }
 
+static void cactus_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 CACTUS_PRINT_MAGIC:
+			INFO("Cactus: Magic: 0x%x\n", CACTUS_MAGIC_NUMBER);
+			ret0 = SPRT_SUCCESS;
+			break;
+
+		case CACTUS_GET_MAGIC:
+			ret1 = CACTUS_MAGIC_NUMBER;
+			ret0 = SPRT_SUCCESS;
+			break;
+
+		default:
+			NOTICE("Cactus: Unhandled Service ID 0x%x\n",
+			       (unsigned int)message->args[1]);
+			ret0 = SPRT_NOT_SUPPORTED;
+			break;
+		}
+	} else {
+		NOTICE("Cactus: Unhandled Service type 0x%x\n",
+		       (unsigned int)message->type);
+		ret0 = SPRT_NOT_SUPPORTED;
+	}
+
+	sprt_message_end(message, ret0, ret1, ret2, ret3);
+}
+
 void __dead2 cactus_main(void)
 {
 	console_init(PL011_UART2_BASE,
@@ -76,5 +111,34 @@
 	/*
 	 * Handle secure service requests.
 	 */
-	secure_services_loop();
+	sprt_initialize_queues((void *)CACTUS_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);
+					cactus_message_handler(&message);
+				}
+			} else {
+				assert(err == 0);
+				cactus_message_handler(&message);
+			}
+		}
+
+		sprt_wait_for_messages();
+	}
 }
diff --git a/spm/cactus/cactus_service_loop.c b/spm/cactus/cactus_service_loop.c
deleted file mode 100644
index 4b202ad..0000000
--- a/spm/cactus/cactus_service_loop.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
-
-#include <assert.h>
-#include <debug.h>
-#include <sp_helpers.h>
-#include <sprt_svc.h>
-#include <spm_svc.h>
-#include <string.h>
-
-__dead2 void secure_services_loop(void)
-{
-	int32_t event_status_code;
-	svc_args svc_values = { 0 };
-
-	/*
-	 * The first time this loop is executed corresponds to when Cactus has
-	 * finished initialising its run time environment and is ready to handle
-	 * secure service requests.
-	 */
-	NOTICE("Cactus: Signal end of init to SPM\n");
-	event_status_code = SPRT_SUCCESS;
-
-	while (1) {
-		svc_values.arg0 = SPRT_REQUEST_COMPLETE_BLOCKING_AARCH64;
-		svc_values.arg1 = event_status_code;
-		int32_t event_id = sp_svc(&svc_values);
-
-		switch (event_id) {
-
-		default:
-			NOTICE("Unhandled Service ID 0x%x\n", event_id);
-			event_status_code = SPRT_NOT_SUPPORTED;
-			break;
-		}
-	}
-}
diff --git a/spm/cactus/cactus_tests_misc.c b/spm/cactus/cactus_tests_misc.c
index bb8eaa7..62d7ad3 100644
--- a/spm/cactus/cactus_tests_misc.c
+++ b/spm/cactus/cactus_tests_misc.c
@@ -9,6 +9,8 @@
 #include <errno.h>
 #include <sp_helpers.h>
 #include <spm_svc.h>
+#include <sprt_client.h>
+#include <sprt_svc.h>
 #include <types.h>
 
 #include "cactus.h"
@@ -25,15 +27,26 @@
 
 	announce_test_section_start(test_sect_desc);
 
-	const char *test_version = "SPM version check";
+	const char *test_version_spm = "SPM version check";
 
-	announce_test_start(test_version);
+	announce_test_start(test_version_spm);
 	svc_args svc_values = { SPM_VERSION_AARCH32 };
 	ret = sp_svc(&svc_values);
 	INFO("Version = 0x%x (%u.%u)\n", ret,
-	     (ret >> 16) & 0x7FFF, ret & 0xFFFF);
+	     (ret >> SPM_VERSION_MAJOR_SHIFT) & SPM_VERSION_MAJOR_MASK,
+	     ret & SPM_VERSION_MINOR_MASK);
 	expect(ret, SPM_VERSION_COMPILED);
-	announce_test_end(test_version);
+	announce_test_end(test_version_spm);
+
+	const char *test_version_sprt = "SPRT version check";
+
+	announce_test_start(test_version_sprt);
+	ret = sprt_version();
+	INFO("Version = 0x%x (%u.%u)\n", ret,
+	     (ret >> SPRT_VERSION_MAJOR_SHIFT) & SPRT_VERSION_MAJOR_MASK,
+	     ret & SPRT_VERSION_MINOR_MASK);
+	expect(ret, SPRT_VERSION_COMPILED);
+	announce_test_end(test_version_sprt);
 
 	announce_test_section_end(test_sect_desc);
 }