Cactus: Refactor handling of commands

Added helper macros to define a command handler, build a command table
in which each element is a pair of the handler and respective command
ID.
Message loop has been refactored to traverse the command table looking
for the ID, and to call the respective command handler.
Available tests have been moved to their own command handler.

Signed-off-by: J-Alves <joao.alves@arm.com>
Change-Id: I38a50a8d47b083c81c21950d98341de660891c61
diff --git a/spm/cactus/cactus_test_cmds.h b/spm/cactus/cactus_test_cmds.h
index f814ba5..d8bba95 100644
--- a/spm/cactus/cactus_test_cmds.h
+++ b/spm/cactus/cactus_test_cmds.h
@@ -9,12 +9,20 @@
 
 #include <debug.h>
 #include <ffa_helpers.h>
+#include <spm_common.h>
 
 /**
  * Success and error return to be sent over a msg response.
  */
-#define CACTUS_SUCCESS	 U(0)
-#define CACTUS_ERROR	 U(-1)
+#define CACTUS_SUCCESS		U(0)
+#define CACTUS_ERROR		U(-1)
+
+/**
+ * Error codes.
+ */
+#define CACTUS_ERROR_INVALID		U(1)
+#define CACTUS_ERROR_TEST		U(2)
+#define CACTUS_ERROR_FFA_CALL		U(3)
 
 /**
  * Get command from struct smc_ret_values.
@@ -243,7 +251,44 @@
 static inline smc_ret_values cactus_req_simd_fill_send_cmd(
 	ffa_vm_id_t source, ffa_vm_id_t dest)
 {
-	return cactus_send_cmd(source, dest, CACTUS_REQ_SIMD_FILL_CMD, 0, 0, 0, 0);
+	return cactus_send_cmd(source, dest, CACTUS_REQ_SIMD_FILL_CMD, 0, 0, 0,
+			       0);
 }
 
+/**
+ * Pairs a command id with a function call, to handle the command ID.
+ */
+struct cactus_cmd_handler {
+	const uint64_t id;
+	smc_ret_values (*fn)(const smc_ret_values *args,
+			     struct mailbox_buffers *mb);
+};
+
+/**
+ * Helper to create the name of a handler function.
+ */
+#define CACTUS_HANDLER_FN_NAME(name) cactus_##name##_handler
+
+/**
+ * Define handler's function signature.
+ */
+#define CACTUS_HANDLER_FN(name)						\
+	static smc_ret_values CACTUS_HANDLER_FN_NAME(name)(		\
+		const smc_ret_values *args, struct mailbox_buffers *mb)
+
+/**
+ * Helper to define Cactus command handler, and pair it with a command ID.
+ * It also creates a table with this information, to be traversed by
+ * 'cactus_handle_cmd' function.
+ */
+#define CACTUS_CMD_HANDLER(name, ID)					\
+	CACTUS_HANDLER_FN(name);					\
+	struct cactus_cmd_handler name __section(".cactus_handler") = {	\
+		.id = ID, .fn = CACTUS_HANDLER_FN_NAME(name),		\
+	};								\
+	CACTUS_HANDLER_FN(name)
+
+bool cactus_handle_cmd(smc_ret_values *cmd_args, smc_ret_values *ret,
+		       struct mailbox_buffers *mb);
+
 #endif