feat(spmd): update SPMC init flow to use EL3 implementation

Allow the SPMD to initialise an SPMC implementation at EL3 directly
rather than at a lower EL.
This includes removing the requirement to parse an SPMC manifest to
obtain information about the SPMC implementation, in this case since the
SPMD and SPMC reside in the same EL we can hardcode the required
information directly.

Signed-off-by: Marc Bonnici <marc.bonnici@arm.com>
Change-Id: I66d1e1b3ec2d0abbfc28b011a32445ee890a331d
diff --git a/include/services/spmc_svc.h b/include/services/spmc_svc.h
index 9dbe045..8ee61e9 100644
--- a/include/services/spmc_svc.h
+++ b/include/services/spmc_svc.h
@@ -12,8 +12,10 @@
 
 #include <lib/utils_def.h>
 #include <services/ffa_svc.h>
+#include <services/spm_core_manifest.h>
 
 int spmc_setup(void);
+void spmc_populate_attrs(spmc_manifest_attribute_t *spmc_attrs);
 void *spmc_get_config_addr(void);
 
 void spmc_set_config_addr(uintptr_t soc_fw_config);
diff --git a/services/std_svc/spm/el3_spmc/spmc_main.c b/services/std_svc/spm/el3_spmc/spmc_main.c
index 80d7a4c..ddfae95 100644
--- a/services/std_svc/spm/el3_spmc/spmc_main.c
+++ b/services/std_svc/spm/el3_spmc/spmc_main.c
@@ -383,6 +383,17 @@
 }
 
 /*******************************************************************************
+ * Initialize SPMC attributes for the SPMD.
+ ******************************************************************************/
+void spmc_populate_attrs(spmc_manifest_attribute_t *spmc_attrs)
+{
+	spmc_attrs->major_version = FFA_VERSION_MAJOR;
+	spmc_attrs->minor_version = FFA_VERSION_MINOR;
+	spmc_attrs->exec_state = MODE_RW_64;
+	spmc_attrs->spmc_id = FFA_SPMC_ID;
+}
+
+/*******************************************************************************
  * Initialize contexts of all Secure Partitions.
  ******************************************************************************/
 int32_t spmc_setup(void)
diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c
index 27a8382..448e12d 100644
--- a/services/std_svc/spmd/spmd_main.c
+++ b/services/std_svc/spmd/spmd_main.c
@@ -24,6 +24,7 @@
 #include <plat/common/platform.h>
 #include <platform_def.h>
 #include <services/ffa_svc.h>
+#include <services/spmc_svc.h>
 #include <services/spmd_svc.h>
 #include <smccc_helpers.h>
 #include "spmd_private.h"
@@ -34,7 +35,8 @@
 static spmd_spm_core_context_t spm_core_context[PLATFORM_CORE_COUNT];
 
 /*******************************************************************************
- * SPM Core attribute information read from its manifest.
+ * SPM Core attribute information is read from its manifest if the SPMC is not
+ * at EL3. Else, it is populated from the SPMC directly.
  ******************************************************************************/
 static spmc_manifest_attribute_t spmc_attrs;
 
@@ -385,8 +387,23 @@
  ******************************************************************************/
 int spmd_setup(void)
 {
-	void *spmc_manifest;
 	int rc;
+	void *spmc_manifest;
+
+	/*
+	 * If the SPMC is at EL3, then just initialise it directly. The
+	 * shenanigans of when it is at a lower EL are not needed.
+	 */
+	if (is_spmc_at_el3()) {
+		/* Allow the SPMC to populate its attributes directly. */
+		spmc_populate_attrs(&spmc_attrs);
+
+		rc = spmc_setup();
+		if (rc != 0) {
+			ERROR("SPMC initialisation failed 0x%x.\n", rc);
+		}
+		return rc;
+	}
 
 	spmc_ep_info = bl31_plat_get_next_image_ep_info(SECURE);
 	if (spmc_ep_info == NULL) {