diff --git a/include/services/spm_core_manifest.h b/include/services/spm_core_manifest.h index 7874882..71e6cfb 100644 --- a/include/services/spm_core_manifest.h +++ b/include/services/spm_core_manifest.h @@ -43,6 +43,11 @@ */ uint32_t binary_size; + /* + * ID of the SPMD (mandatory) + */ + uint16_t spmc_id; + } spmc_manifest_sect_attribute_t; #endif /* SPMC_MANIFEST_H */ diff --git a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts index c94a209..db3fb55 100644 --- a/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts +++ b/plat/arm/board/fvp/fdts/fvp_spmc_manifest.dts @@ -9,6 +9,7 @@ compatible = "spci-core-manifest-1.0"; attribute { + spmc_id = <0x8000>; maj_ver = <0x0>; min_ver = <0x9>; exec_state = <0x0>; diff --git a/plat/common/plat_spmd_manifest.c b/plat/common/plat_spmd_manifest.c index 9c3dc71..f0aa27c 100644 --- a/plat/common/plat_spmd_manifest.c +++ b/plat/common/plat_spmd_manifest.c @@ -37,6 +37,12 @@ return -ENOENT; } + rc = fdtw_read_cells(fdt, node, "spmc_id", 1, &attr->spmc_id); + if (rc) { + ERROR("Missing SPMC ID in manifest.\n"); + return -ENOENT; + } + rc = fdtw_read_cells(fdt, node, "exec_state", 1, &attr->exec_state); if (rc) NOTICE("Execution state not specified in SPM core manifest.\n"); @@ -55,6 +61,7 @@ VERBOSE("SPM core manifest attribute section:\n"); VERBOSE(" version: %x.%x\n", attr->major_version, attr->minor_version); + VERBOSE(" spmc_id: %x\n", attr->spmc_id); VERBOSE(" binary_size: 0x%x\n", attr->binary_size); VERBOSE(" load_address: 0x%llx\n", attr->load_address); VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint); diff --git a/services/std_svc/spmd/spmd_main.c b/services/std_svc/spmd/spmd_main.c index 2cdf4f5..a3e1a2d 100644 --- a/services/std_svc/spmd/spmd_main.c +++ b/services/std_svc/spmd/spmd_main.c @@ -162,6 +162,16 @@ INFO("SPM core run time EL%x.\n", SPMD_SPM_AT_SEL2 ? MODE_EL2 : MODE_EL1); + /* Validate the SPMC ID, Ensure high bit is set */ + if (!(spmc_attrs.spmc_id >> SPMC_SECURE_ID_SHIFT) & + SPMC_SECURE_ID_MASK) { + WARN("Invalid ID (0x%x) for SPMC.\n", + spmc_attrs.spmc_id); + return 1; + } + + INFO("SPMC ID %x.\n", spmc_attrs.spmc_id); + /* Validate the SPM core execution state */ if ((spmc_attrs.exec_state != MODE_RW_64) && (spmc_attrs.exec_state != MODE_RW_32)) { @@ -436,6 +446,26 @@ break; /* not reached */ + case SPCI_ID_GET: + /* + * Returns the ID of the calling SPCI component. + */ + if (!secure_origin) { + SMC_RET8(handle, SPCI_SUCCESS_SMC32, + SPCI_TARGET_INFO_MBZ, SPCI_NS_ENDPOINT_ID, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ); + } else { + SMC_RET8(handle, SPCI_SUCCESS_SMC32, + SPCI_TARGET_INFO_MBZ, spmc_attrs.spmc_id, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ, SPCI_PARAM_MBZ, + SPCI_PARAM_MBZ); + } + + break; /* not reached */ + case SPCI_RX_RELEASE: case SPCI_RXTX_MAP_SMC32: case SPCI_RXTX_MAP_SMC64: diff --git a/services/std_svc/spmd/spmd_private.h b/services/std_svc/spmd/spmd_private.h index 61b479a..0ad35c7 100644 --- a/services/std_svc/spmd/spmd_private.h +++ b/services/std_svc/spmd/spmd_private.h @@ -55,6 +55,15 @@ } spmd_spm_core_context_t; /* + * Reserve ID for NS physical SPCI Endpoint. + */ +#define SPCI_NS_ENDPOINT_ID U(0) + +/* Mask and shift to check valid secure SPCI Endpoint ID. */ +#define SPMC_SECURE_ID_MASK 0x1 +#define SPMC_SECURE_ID_SHIFT 15 + +/* * Data structure used by the SPM dispatcher (SPMD) in EL3 to track sequence of * SPCI calls from lower ELs. *