aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile12
-rw-r--r--include/common/test_helpers.h11
-rw-r--r--include/lib/tftf_lib.h11
-rw-r--r--include/runtime_services/spci_helpers.h32
-rw-r--r--include/runtime_services/spci_svc.h220
-rw-r--r--lib/aarch64/misc_helpers.S115
-rw-r--r--lib/smc/aarch64/asm_smc.S57
-rw-r--r--lib/smc/aarch64/hvc.c30
-rw-r--r--spm/README.txt11
-rw-r--r--spm/cactus/aarch64/cactus_entrypoint.S16
-rw-r--r--spm/cactus/cactus-secondary.dts67
-rw-r--r--spm/cactus/cactus.dts152
-rw-r--r--spm/cactus/cactus.ld.S25
-rw-r--r--spm/cactus/cactus.mk12
-rw-r--r--spm/cactus/cactus_def.h4
-rw-r--r--spm/cactus/cactus_main.c297
-rw-r--r--tftf/tests/runtime_services/secure_service/spci_helpers.c227
-rw-r--r--tftf/tests/runtime_services/secure_service/test_spci_direct_messaging.c107
-rw-r--r--tftf/tests/tests-spm.mk9
-rw-r--r--tftf/tests/tests-spm.xml22
-rw-r--r--tftf/tests/tests-standard.xml2
-rwxr-xr-xtools/generate_dtb/generate_dtb.sh34
-rwxr-xr-xtools/generate_json/generate_json.sh32
23 files changed, 953 insertions, 552 deletions
diff --git a/Makefile b/Makefile
index 010496d6a..dc6092ff1 100644
--- a/Makefile
+++ b/Makefile
@@ -223,6 +223,14 @@ NS_BL1U_CFLAGS += -mbranch-protection=pac-ret
NS_BL2U_CFLAGS += -mbranch-protection=pac-ret
endif
+#####################################################################################
+ifneq ($(findstring gcc,$(notdir $(LD))),)
+ PIE_LDFLAGS += -Wl,-pie -Wl,--no-dynamic-linker
+else
+ PIE_LDFLAGS += -pie --no-dynamic-linker
+endif
+
+#####################################################################################
NS_BL1U_SOURCES += ${PLAT_SOURCES} ${LIBC_SRCS}
NS_BL1U_INCLUDES += ${PLAT_INCLUDES}
NS_BL1U_CFLAGS += ${COMMON_CFLAGS}
@@ -243,9 +251,9 @@ CACTUS_MM_LDFLAGS += ${COMMON_LDFLAGS}
CACTUS_SOURCES += ${LIBC_SRCS}
CACTUS_INCLUDES += ${PLAT_INCLUDES}
-CACTUS_CFLAGS += ${COMMON_CFLAGS}
+CACTUS_CFLAGS += ${COMMON_CFLAGS} -fpie
CACTUS_ASFLAGS += ${COMMON_ASFLAGS}
-CACTUS_LDFLAGS += ${COMMON_LDFLAGS}
+CACTUS_LDFLAGS += ${COMMON_LDFLAGS} $(PIE_LDFLAGS)
IVY_SOURCES += ${LIBC_SRCS}
IVY_INCLUDES += ${PLAT_INCLUDES}
diff --git a/include/common/test_helpers.h b/include/common/test_helpers.h
index a90fd715f..5c0f090e5 100644
--- a/include/common/test_helpers.h
+++ b/include/common/test_helpers.h
@@ -147,14 +147,19 @@ typedef test_result_t (*test_function_arg_t)(void *arg);
do { \
smc_args version_smc = { SPCI_VERSION }; \
smc_ret_values smc_ret = tftf_smc(&version_smc); \
- uint32_t version = smc_ret.ret0; \
+ uint32_t version = smc_ret.ret2; \
\
- if (version == SMC_UNKNOWN) { \
+ if (smc_ret.ret0 != SPCI_SUCCESS_SMC32) { \
tftf_testcase_printf("SPM not detected.\n"); \
return TEST_RESULT_SKIPPED; \
} \
+ \
+ if ((version & SPCI_VERSION_BIT31_MASK) != 0) { \
+ tftf_testcase_printf("SPCI_VERSION bad response.\n"); \
+ return TEST_RESULT_SKIPPED; \
+ } \
\
- if (version < SPCI_VERSION_FORM(major, minor)) { \
+ if (version < MAKE_SPCI_VERSION(major, minor)) { \
tftf_testcase_printf("SPCI_VERSION returned %d.%d\n" \
"The required version is %d.%d\n", \
version >> SPCI_VERSION_MAJOR_SHIFT,\
diff --git a/include/lib/tftf_lib.h b/include/lib/tftf_lib.h
index 7f6786a0a..c3ad105b2 100644
--- a/include/lib/tftf_lib.h
+++ b/include/lib/tftf_lib.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -159,6 +159,15 @@ typedef struct {
smc_ret_values tftf_smc(const smc_args *args);
/*
+ * Trigger an HVC call.
+ */
+typedef smc_args hvc_args;
+
+typedef smc_ret_values hvc_ret_values;
+
+hvc_ret_values tftf_hvc(const hvc_args *args);
+
+/*
* Write a formatted string in the test output buffer.
* Just like the standard libc's printf() function, the string produced is under
* the control of a format string that specifies how subsequent arguments are
diff --git a/include/runtime_services/spci_helpers.h b/include/runtime_services/spci_helpers.h
index a64591e71..cfc3a5ff4 100644
--- a/include/runtime_services/spci_helpers.h
+++ b/include/runtime_services/spci_helpers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,41 +7,19 @@
#ifndef SPCI_HELPERS_H
#define SPCI_HELPERS_H
+#include <tftf_lib.h>
#include <utils_def.h>
/* This error code must be different to the ones used by SPCI */
#define SPCI_TFTF_ERROR -42
-/* Client ID used for SPCI calls */
-#define TFTF_SPCI_CLIENT_ID U(0x00007F7F)
-
#ifndef __ASSEMBLY__
#include <stdint.h>
-int spci_service_handle_open(uint16_t client_id, uint16_t *handle,
- uint32_t uuid1, uint32_t uuid2,
- uint32_t uuid3, uint32_t uuid4);
-int spci_service_handle_close(uint16_t client_id, uint16_t handle);
-
-int spci_service_request_start(u_register_t x1, u_register_t x2,
- u_register_t x3, u_register_t x4,
- u_register_t x5, u_register_t x6,
- uint16_t client_id, uint16_t handle,
- uint32_t *token);
-int spci_service_request_resume(uint16_t client_id, uint16_t handle,
- uint32_t token, u_register_t *x1,
- u_register_t *x2, u_register_t *x3);
-int spci_service_get_response(uint16_t client_id, uint16_t handle,
- uint32_t token, u_register_t *x1,
- u_register_t *x2, u_register_t *x3);
-
-int spci_service_request_blocking(u_register_t x1, u_register_t x2,
- u_register_t x3, u_register_t x4,
- u_register_t x5, u_register_t x6,
- uint16_t client_id, uint16_t handle,
- u_register_t *rx1, u_register_t *rx2,
- u_register_t *rx3);
+smc_ret_values spci_msg_send_direct_req(uint32_t source_id, uint32_t dest_id, uint32_t message);
+smc_ret_values spci_msg_send_direct_req64(uint32_t source_id, uint32_t dest_id, uint64_t message);
+smc_ret_values spci_run(uint32_t dest_id, uint32_t vcpu_id);
#endif /* __ASSEMBLY__ */
diff --git a/include/runtime_services/spci_svc.h b/include/runtime_services/spci_svc.h
index f0ea57e3b..926f52a3a 100644
--- a/include/runtime_services/spci_svc.h
+++ b/include/runtime_services/spci_svc.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,118 +7,134 @@
#ifndef SPCI_SVC_H
#define SPCI_SVC_H
+#include <lib/utils_def.h>
#include <smccc.h>
-#include <utils_def.h>
+#include <uuid.h>
-/* SPCI_VERSION helpers */
+/* SPCI error codes. */
+#define SPCI_ERROR_NOT_SUPPORTED -1
+#define SPCI_ERROR_INVALID_PARAMETER -2
+#define SPCI_ERROR_NO_MEMORY -3
+#define SPCI_ERROR_BUSY -4
+#define SPCI_ERROR_INTERRUPTED -5
+#define SPCI_ERROR_DENIED -6
+#define SPCI_ERROR_RETRY -7
+
+/* The macros below are used to identify SPCI calls from the SMC function ID */
+#define SPCI_FNUM_MIN_VALUE U(0x60)
+#define SPCI_FNUM_MAX_VALUE U(0x7f)
+#define is_spci_fid(fid) __extension__ ({ \
+ __typeof__(fid) _fid = (fid); \
+ ((GET_SMC_NUM(_fid) >= SPCI_FNUM_MIN_VALUE) && \
+ (GET_SMC_NUM(_fid) <= SPCI_FNUM_MAX_VALUE)); })
+/* SPCI_VERSION helpers */
#define SPCI_VERSION_MAJOR U(0)
#define SPCI_VERSION_MAJOR_SHIFT 16
#define SPCI_VERSION_MAJOR_MASK U(0x7FFF)
-#define SPCI_VERSION_MINOR U(1)
+#define SPCI_VERSION_MINOR U(9)
#define SPCI_VERSION_MINOR_SHIFT 0
#define SPCI_VERSION_MINOR_MASK U(0xFFFF)
-#define SPCI_VERSION_FORM(major, minor) ((((major) & SPCI_VERSION_MAJOR_MASK) \
- << SPCI_VERSION_MAJOR_SHIFT) | \
- ((minor) & SPCI_VERSION_MINOR_MASK))
-#define SPCI_VERSION_COMPILED SPCI_VERSION_FORM(SPCI_VERSION_MAJOR, \
- SPCI_VERSION_MINOR)
-
-/* Definitions to build the complete SMC ID */
-
-#define SPCI_FID_MISC_FLAG (U(0) << 27)
-#define SPCI_FID_MISC_SHIFT U(20)
-#define SPCI_FID_MISC_MASK U(0x7F)
-
-#define SPCI_FID_TUN_FLAG (U(1) << 27)
-#define SPCI_FID_TUN_SHIFT U(24)
-#define SPCI_FID_TUN_MASK U(0x7)
-
-#define OEN_SPCI_START U(0x30)
-#define OEN_SPCI_END U(0x3F)
-
-#define SPCI_SMC(spci_fid) ((OEN_SPCI_START << FUNCID_OEN_SHIFT) | \
- (U(1) << 31) | (spci_fid))
-#define SPCI_MISC_32(misc_fid) ((SMC_32 << FUNCID_CC_SHIFT) | \
- SPCI_FID_MISC_FLAG | \
- SPCI_SMC((misc_fid) << SPCI_FID_MISC_SHIFT))
-#define SPCI_MISC_64(misc_fid) ((SMC_64 << FUNCID_CC_SHIFT) | \
- SPCI_FID_MISC_FLAG | \
- SPCI_SMC((misc_fid) << SPCI_FID_MISC_SHIFT))
-#define SPCI_TUN_32(tun_fid) ((SMC_32 << FUNCID_CC_SHIFT) | \
- SPCI_FID_TUN_FLAG | \
- SPCI_SMC((tun_fid) << SPCI_FID_TUN_SHIFT))
-#define SPCI_TUN_64(tun_fid) ((SMC_64 << FUNCID_CC_SHIFT) | \
- SPCI_FID_TUN_FLAG | \
- SPCI_SMC((tun_fid) << SPCI_FID_TUN_SHIFT))
-
-/* SPCI miscellaneous functions */
-
-#define SPCI_FID_VERSION U(0x0)
-#define SPCI_FID_SERVICE_HANDLE_OPEN U(0x2)
-#define SPCI_FID_SERVICE_HANDLE_CLOSE U(0x3)
-#define SPCI_FID_SERVICE_MEM_REGISTER U(0x4)
-#define SPCI_FID_SERVICE_MEM_UNREGISTER U(0x5)
-#define SPCI_FID_SERVICE_MEM_PUBLISH U(0x6)
-#define SPCI_FID_SERVICE_REQUEST_BLOCKING U(0x7)
-#define SPCI_FID_SERVICE_REQUEST_START U(0x8)
-#define SPCI_FID_SERVICE_GET_RESPONSE U(0x9)
-#define SPCI_FID_SERVICE_RESET_CLIENT_STATE U(0xA)
-
-/* SPCI tunneling functions */
-
-#define SPCI_FID_SERVICE_TUN_REQUEST_START U(0x0)
-#define SPCI_FID_SERVICE_REQUEST_RESUME U(0x1)
-#define SPCI_FID_SERVICE_TUN_REQUEST_BLOCKING U(0x2)
-
-/* Complete SMC IDs and associated values */
-
-#define SPCI_VERSION SPCI_MISC_32(SPCI_FID_VERSION)
-
-#define SPCI_SERVICE_HANDLE_OPEN SPCI_MISC_32(SPCI_FID_SERVICE_HANDLE_OPEN)
-#define SPCI_SERVICE_HANDLE_OPEN_NOTIFY_BIT U(1)
+#define SPCI_VERSION_BIT31_MASK (1 << 31)
-#define SPCI_SERVICE_HANDLE_CLOSE SPCI_MISC_32(SPCI_FID_SERVICE_HANDLE_CLOSE)
-
-#define SPCI_SERVICE_MEM_REGISTER_AARCH32 SPCI_MISC_32(SPCI_FID_SERVICE_MEM_REGISTER)
-#define SPCI_SERVICE_MEM_REGISTER_AARCH64 SPCI_MISC_64(SPCI_FID_SERVICE_MEM_REGISTER)
-
-#define SPCI_SERVICE_MEM_UNREGISTER_AARCH32 SPCI_MISC_32(SPCI_FID_SERVICE_MEM_UNREGISTER)
-#define SPCI_SERVICE_MEM_UNREGISTER_AARCH64 SPCI_MISC_64(SPCI_FID_SERVICE_MEM_UNREGISTER)
-
-#define SPCI_SERVICE_MEM_PUBLISH_AARCH32 SPCI_MISC_32(SPCI_FID_SERVICE_MEM_PUBLISH)
-#define SPCI_SERVICE_MEM_PUBLISH_AARCH64 SPCI_MISC_64(SPCI_FID_SERVICE_MEM_PUBLISH)
-
-#define SPCI_SERVICE_REQUEST_BLOCKING_AARCH32 SPCI_MISC_32(SPCI_FID_SERVICE_REQUEST_BLOCKING)
-#define SPCI_SERVICE_REQUEST_BLOCKING_AARCH64 SPCI_MISC_64(SPCI_FID_SERVICE_REQUEST_BLOCKING)
-
-#define SPCI_SERVICE_REQUEST_START_AARCH32 SPCI_MISC_32(SPCI_FID_SERVICE_REQUEST_START)
-#define SPCI_SERVICE_REQUEST_START_AARCH64 SPCI_MISC_64(SPCI_FID_SERVICE_REQUEST_START)
-
-#define SPCI_SERVICE_GET_RESPONSE_AARCH32 SPCI_MISC_32(SPCI_FID_SERVICE_GET_RESPONSE)
-#define SPCI_SERVICE_GET_RESPONSE_AARCH64 SPCI_MISC_64(SPCI_FID_SERVICE_GET_RESPONSE)
-
-#define SPCI_SERVICE_RESET_CLIENT_STATE_AARCH32 SPCI_MISC_32(SPCI_FID_SERVICE_RESET_CLIENT_STATE)
-#define SPCI_SERVICE_RESET_CLIENT_STATE_AARCH64 SPCI_MISC_64(SPCI_FID_SERVICE_RESET_CLIENT_STATE)
-
-#define SPCI_SERVICE_TUN_REQUEST_START_AARCH32 SPCI_TUN_32(SPCI_FID_SERVICE_TUN_REQUEST_START)
-#define SPCI_SERVICE_TUN_REQUEST_START_AARCH64 SPCI_TUN_64(SPCI_FID_SERVICE_TUN_REQUEST_START)
-
-#define SPCI_SERVICE_REQUEST_RESUME_AARCH32 SPCI_TUN_32(SPCI_FID_SERVICE_REQUEST_RESUME)
-#define SPCI_SERVICE_REQUEST_RESUME_AARCH64 SPCI_TUN_64(SPCI_FID_SERVICE_REQUEST_RESUME)
+#define MAKE_SPCI_VERSION(major, minor) \
+ ((((major) & SPCI_VERSION_MAJOR_MASK) << SPCI_VERSION_MAJOR_SHIFT) | \
+ (((minor) & SPCI_VERSION_MINOR_MASK) << SPCI_VERSION_MINOR_SHIFT))
+#define SPCI_VERSION_COMPILED MAKE_SPCI_VERSION(SPCI_VERSION_MAJOR, \
+ SPCI_VERSION_MINOR)
-#define SPCI_SERVICE_TUN_REQUEST_BLOCKING_AARCH32 SPCI_TUN_32(SPCI_FID_SERVICE_TUN_REQUEST_BLOCKING)
-#define SPCI_SERVICE_TUN_REQUEST_BLOCKING_AARCH64 SPCI_TUN_64(SPCI_FID_SERVICE_TUN_REQUEST_BLOCKING)
+/* SPCI_MSG_SEND helpers */
+#define SPCI_MSG_SEND_ATTRS_BLK_SHIFT U(0)
+#define SPCI_MSG_SEND_ATTRS_BLK_MASK U(0x1)
+#define SPCI_MSG_SEND_ATTRS_BLK U(0)
+#define SPCI_MSG_SEND_ATTRS_BLK_NOT U(1)
+#define SPCI_MSG_SEND_ATTRS(blk) \
+ (((blk) & SPCI_MSG_SEND_ATTRS_BLK_MASK) \
+ << SPCI_MSG_SEND_ATTRS_BLK_SHIFT)
+
+/* Get SPCI fastcall std FID from function number */
+#define SPCI_FID(smc_cc, func_num) \
+ ((SMC_TYPE_FAST << FUNCID_TYPE_SHIFT) | \
+ ((smc_cc) << FUNCID_CC_SHIFT) | \
+ (OEN_STD_START << FUNCID_OEN_SHIFT) | \
+ ((func_num) << FUNCID_NUM_SHIFT))
+
+/* SPCI function numbers */
+#define SPCI_FNUM_ERROR U(0x60)
+#define SPCI_FNUM_SUCCESS U(0x61)
+#define SPCI_FNUM_INTERRUPT U(0x62)
+#define SPCI_FNUM_VERSION U(0x63)
+#define SPCI_FNUM_FEATURES U(0x64)
+#define SPCI_FNUM_RX_RELEASE U(0x65)
+#define SPCI_FNUM_RXTX_MAP U(0x66)
+#define SPCI_FNUM_RXTX_UNMAP U(0x67)
+#define SPCI_FNUM_PARTITION_INFO_GET U(0x68)
+#define SPCI_FNUM_ID_GET U(0x69)
+#define SPCI_FNUM_MSG_POLL U(0x6A)
+#define SPCI_FNUM_MSG_WAIT U(0x6B)
+#define SPCI_FNUM_MSG_YIELD U(0x6C)
+#define SPCI_FNUM_MSG_RUN U(0x6D)
+#define SPCI_FNUM_MSG_SEND U(0x6E)
+#define SPCI_FNUM_MSG_SEND_DIRECT_REQ U(0x6F)
+#define SPCI_FNUM_MSG_SEND_DIRECT_RESP U(0x70)
+#define SPCI_FNUM_MEM_DONATE U(0x71)
+#define SPCI_FNUM_MEM_LEND U(0x72)
+#define SPCI_FNUM_MEM_SHARE U(0x73)
+#define SPCI_FNUM_MEM_RETRIEVE_REQ U(0x74)
+#define SPCI_FNUM_MEM_RETRIEVE_RESP U(0x75)
+#define SPCI_FNUM_MEM_RELINQUISH U(0x76)
+#define SPCI_FNUM_MEM_RECLAIM U(0x77)
+
+/* SPCI SMC32 FIDs */
+#define SPCI_ERROR SPCI_FID(SMC_32, SPCI_FNUM_ERROR)
+#define SPCI_SUCCESS_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_SUCCESS)
+#define SPCI_INTERRUPT SPCI_FID(SMC_32, SPCI_FNUM_INTERRUPT)
+#define SPCI_VERSION SPCI_FID(SMC_32, SPCI_FNUM_VERSION)
+#define SPCI_FEATURES SPCI_FID(SMC_32, SPCI_FNUM_FEATURES)
+#define SPCI_RX_RELEASE SPCI_FID(SMC_32, SPCI_FNUM_RX_RELEASE)
+#define SPCI_RXTX_MAP_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_RXTX_MAP)
+#define SPCI_RXTX_UNMAP SPCI_FID(SMC_32, SPCI_FNUM_RXTX_UNMAP)
+#define SPCI_PARTITION_INFO_GET SPCI_FID(SMC_32, SPCI_FNUM_PARTITION_INFO_GET)
+#define SPCI_ID_GET SPCI_FID(SMC_32, SPCI_FNUM_ID_GET)
+#define SPCI_MSG_POLL SPCI_FID(SMC_32, SPCI_FNUM_MSG_POLL)
+#define SPCI_MSG_WAIT SPCI_FID(SMC_32, SPCI_FNUM_MSG_WAIT)
+#define SPCI_MSG_YIELD SPCI_FID(SMC_32, SPCI_FNUM_MSG_YIELD)
+#define SPCI_MSG_RUN SPCI_FID(SMC_32, SPCI_FNUM_MSG_RUN)
+#define SPCI_MSG_SEND SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND)
+#define SPCI_MSG_SEND_DIRECT_REQ_SMC32 \
+ SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND_DIRECT_REQ)
+#define SPCI_MSG_SEND_DIRECT_RESP_SMC32 \
+ SPCI_FID(SMC_32, SPCI_FNUM_MSG_SEND_DIRECT_RESP)
+#define SPCI_MEM_DONATE_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_DONATE)
+#define SPCI_MEM_LEND_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_LEND)
+#define SPCI_MEM_SHARE_SMC32 SPCI_FID(SMC_32, SPCI_FNUM_MEM_SHARE)
+#define SPCI_MEM_RETRIEVE_REQ_SMC32 \
+ SPCI_FID(SMC_32, SPCI_FNUM_MEM_RETRIEVE_REQ)
+#define SPCI_MEM_RETRIEVE_RESP SPCI_FID(SMC_32, SPCI_FNUM_MEM_RETRIEVE_RESP)
+#define SPCI_MEM_RELINQUISH SPCI_FID(SMC_32, SPCI_FNUM_MEM_RELINQUISH)
+#define SPCI_MEM_RECLAIM SPCI_FID(SMC_32, SPCI_FNUM_MEM_RECLAIM)
+
+/* SPCI SMC64 FIDs */
+#define SPCI_SUCCESS_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_SUCCESS)
+#define SPCI_RXTX_MAP_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_RXTX_MAP)
+#define SPCI_MSG_SEND_DIRECT_REQ_SMC64 \
+ SPCI_FID(SMC_64, SPCI_FNUM_MSG_SEND_DIRECT_REQ)
+#define SPCI_MSG_SEND_DIRECT_RESP_SMC64 \
+ SPCI_FID(SMC_64, SPCI_FNUM_MSG_SEND_DIRECT_RESP)
+#define SPCI_MEM_DONATE_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_DONATE)
+#define SPCI_MEM_LEND_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_LEND)
+#define SPCI_MEM_SHARE_SMC64 SPCI_FID(SMC_64, SPCI_FNUM_MEM_SHARE)
+#define SPCI_MEM_RETRIEVE_REQ_SMC64 \
+ SPCI_FID(SMC_64, SPCI_FNUM_MEM_RETRIEVE_REQ)
-/* SPCI error codes. */
+/*
+ * Reserve a special value for traffic targeted to the Hypervisor or SPM.
+ */
+#define SPCI_TARGET_INFO_MBZ U(0x0)
-#define SPCI_SUCCESS 0
-#define SPCI_NOT_SUPPORTED -1
-#define SPCI_INVALID_PARAMETER -2
-#define SPCI_NO_MEMORY -3
-#define SPCI_BUSY -4
-#define SPCI_QUEUED -5
-#define SPCI_DENIED -6
-#define SPCI_NOT_PRESENT -7
+/*
+ * Reserve a special value for MBZ parameters.
+ */
+#define SPCI_PARAM_MBZ U(0x0)
#endif /* SPCI_SVC_H */
diff --git a/lib/aarch64/misc_helpers.S b/lib/aarch64/misc_helpers.S
index 7c9da92af..b67772152 100644
--- a/lib/aarch64/misc_helpers.S
+++ b/lib/aarch64/misc_helpers.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -7,6 +7,7 @@
#include <arch.h>
#include <asm_macros.S>
#include <assert_macros.S>
+#include <lib/xlat_tables/xlat_tables_defs.h>
.globl smc
@@ -110,3 +111,115 @@ endfunc disable_mmu_icache
/* Need this label for asm_read/write_sctlr_el1_or_el2 */
dead:
b dead
+
+/* ---------------------------------------------------------------------------
+ * Helper to fixup Global Offset table (GOT) and dynamic relocations
+ * (.rela.dyn) at runtime.
+ *
+ * This function is meant to be used when the firmware is compiled with -fpie
+ * and linked with -pie options. We rely on the linker script exporting
+ * appropriate markers for start and end of the section. For GOT, we
+ * expect __GOT_START__ and __GOT_END__. Similarly for .rela.dyn, we expect
+ * __RELA_START__ and __RELA_END__.
+ *
+ * The function takes the limits of the memory to apply fixups to as
+ * arguments (which is usually the limits of the relocable BL image).
+ * x0 - the start of the fixup region
+ * x1 - the limit of the fixup region
+ * These addresses have to be page (4KB aligned).
+ * ---------------------------------------------------------------------------
+ */
+.globl fixup_gdt_reloc
+func fixup_gdt_reloc
+ mov x6, x0
+ mov x7, x1
+
+ /* Test if the limits are 4K aligned */
+#if ENABLE_ASSERTIONS
+ orr x0, x0, x1
+ tst x0, #(PAGE_SIZE - 1)
+ ASM_ASSERT(eq)
+#endif
+ /*
+ * Calculate the offset based on return address in x30.
+ * Assume that this function is called within a page at the start of
+ * fixup region.
+ */
+ and x2, x30, #~(PAGE_SIZE - 1)
+ sub x0, x2, x6 /* Diff(S) = Current Address - Compiled Address */
+
+ adrp x1, __GOT_START__
+ add x1, x1, :lo12:__GOT_START__
+ adrp x2, __GOT_END__
+ add x2, x2, :lo12:__GOT_END__
+
+ /*
+ * GOT is an array of 64_bit addresses which must be fixed up as
+ * new_addr = old_addr + Diff(S).
+ * The new_addr is the address currently the binary is executing from
+ * and old_addr is the address at compile time.
+ */
+1:
+ ldr x3, [x1]
+ /* Skip adding offset if address is < lower limit */
+ cmp x3, x6
+ b.lo 2f
+ /* Skip adding offset if address is >= upper limit */
+ cmp x3, x7
+ b.ge 2f
+ add x3, x3, x0
+ str x3, [x1]
+2:
+ add x1, x1, #8
+ cmp x1, x2
+ b.lo 1b
+
+ /* Starting dynamic relocations. Use adrp/adr to get RELA_START and END */
+ adrp x1, __RELA_START__
+ add x1, x1, :lo12:__RELA_START__
+ adrp x2, __RELA_END__
+ add x2, x2, :lo12:__RELA_END__
+ /*
+ * According to ELF-64 specification, the RELA data structure is as
+ * follows:
+ * typedef struct
+ * {
+ * Elf64_Addr r_offset;
+ * Elf64_Xword r_info;
+ * Elf64_Sxword r_addend;
+ * } Elf64_Rela;
+ *
+ * r_offset is address of reference
+ * r_info is symbol index and type of relocation (in this case
+ * 0x403 which corresponds to R_AARCH64_RELATIVE).
+ * r_addend is constant part of expression.
+ *
+ * Size of Elf64_Rela structure is 24 bytes.
+ */
+1:
+ /* Assert that the relocation type is R_AARCH64_RELATIVE */
+#if ENABLE_ASSERTIONS
+ ldr x3, [x1, #8]
+ cmp x3, #0x403
+ ASM_ASSERT(eq)
+#endif
+ ldr x3, [x1] /* r_offset */
+ add x3, x0, x3
+ ldr x4, [x1, #16] /* r_addend */
+
+ /* Skip adding offset if r_addend is < lower limit */
+ cmp x4, x6
+ b.lo 2f
+ /* Skip adding offset if r_addend entry is >= upper limit */
+ cmp x4, x7
+ b.ge 2f
+
+ add x4, x0, x4 /* Diff(S) + r_addend */
+ str x4, [x3]
+
+2: add x1, x1, #24
+ cmp x1, x2
+ b.lo 1b
+
+ ret
+endfunc fixup_gdt_reloc
diff --git a/lib/smc/aarch64/asm_smc.S b/lib/smc/aarch64/asm_smc.S
index c3044a42f..b11baa8c1 100644
--- a/lib/smc/aarch64/asm_smc.S
+++ b/lib/smc/aarch64/asm_smc.S
@@ -1,28 +1,15 @@
/*
- * Copyright (c) 2013-2019, Arm Limited. All rights reserved.
+ * Copyright (c) 2013-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <asm_macros.S>
- .globl asm_tftf_smc64
-
.section .text, "ax"
+ .macro smccc_conduit _conduit
-/* ---------------------------------------------------------------------------
- * smc_ret_values asm_tftf_smc64(uint32_t fid,
- * u_register_t arg1,
- * u_register_t arg2,
- * u_register_t arg3,
- * u_register_t arg4,
- * u_register_t arg5,
- * u_register_t arg6,
- * u_register_t arg7);
- * ---------------------------------------------------------------------------
- */
-func asm_tftf_smc64
/*
* According to the AAPCS64, x8 is the indirect result location
* register. It contains the address of the memory block that the caller
@@ -34,8 +21,8 @@ func asm_tftf_smc64
*/
str x8, [sp, #-16]!
- /* SMC arguments are already stored in x0-x7 */
- smc #0
+ /* "Conduit" arguments are already stored in x0-x7 */
+ \_conduit #0
/* Pop x8 into a caller-saved register */
ldr x9, [sp], #16
@@ -48,5 +35,41 @@ func asm_tftf_smc64
stp x2, x3, [x9, #16]
stp x4, x5, [x9, #32]
stp x6, x7, [x9, #48]
+
+ .endm
+
+/* ---------------------------------------------------------------------------
+ * smc_ret_values asm_tftf_smc64(uint32_t fid,
+ * u_register_t arg1,
+ * u_register_t arg2,
+ * u_register_t arg3,
+ * u_register_t arg4,
+ * u_register_t arg5,
+ * u_register_t arg6,
+ * u_register_t arg7);
+ * ---------------------------------------------------------------------------
+ */
+ .globl asm_tftf_smc64
+
+func asm_tftf_smc64
+ smccc_conduit smc
ret
endfunc asm_tftf_smc64
+
+/* ---------------------------------------------------------------------------
+ * hvc_ret_values asm_tftf_hvcc64(uint32_t fid,
+ * u_register_t arg1,
+ * u_register_t arg2,
+ * u_register_t arg3,
+ * u_register_t arg4,
+ * u_register_t arg5,
+ * u_register_t arg6,
+ * u_register_t arg7);
+ * ---------------------------------------------------------------------------
+ */
+ .globl asm_tftf_hvc64
+
+func asm_tftf_hvc64
+ smccc_conduit hvc
+ ret
+endfunc asm_tftf_hvc64
diff --git a/lib/smc/aarch64/hvc.c b/lib/smc/aarch64/hvc.c
new file mode 100644
index 000000000..c8338643b
--- /dev/null
+++ b/lib/smc/aarch64/hvc.c
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdint.h>
+#include <tftf.h>
+
+hvc_ret_values asm_tftf_hvc64(uint32_t fid,
+ u_register_t arg1,
+ u_register_t arg2,
+ u_register_t arg3,
+ u_register_t arg4,
+ u_register_t arg5,
+ u_register_t arg6,
+ u_register_t arg7);
+
+hvc_ret_values tftf_hvc(const hvc_args *args)
+{
+ return asm_tftf_hvc64(args->fid,
+ args->arg1,
+ args->arg2,
+ args->arg3,
+ args->arg4,
+ args->arg5,
+ args->arg6,
+ args->arg7);
+}
diff --git a/spm/README.txt b/spm/README.txt
index bff23efbe..0a25d6b7a 100644
--- a/spm/README.txt
+++ b/spm/README.txt
@@ -1,8 +1,7 @@
-This is a prototype loosely based on the SPCI Alpha and SPRT pre-alpha
-specifications. Any interface / platform API introduced for this is subject to
+This is a prototype loosely based on the SPCI Beta1 specification.
+Any interface / platform API introduced for this is subject to
change as it evolves.
-Cactus is meant to be the main test Secure Partition. It is the one meant to
-have most of the tests that a Secure Partition has to do. Ivy is meant to be
-more minimalistic. In the future, Cactus may be modified to be a S-EL1 partition
-while Ivy will remain as a S-EL0 partition.
+Cactus is meant to be the main test Secure Partition run at S-EL1.
+It is the one meant to have most of the tests that a Secure Partition
+has to do. Ivy is meant to be more minimalistic and run at S-EL0.
diff --git a/spm/cactus/aarch64/cactus_entrypoint.S b/spm/cactus/aarch64/cactus_entrypoint.S
index 214b4cfbd..4fe17e343 100644
--- a/spm/cactus/aarch64/cactus_entrypoint.S
+++ b/spm/cactus/aarch64/cactus_entrypoint.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -21,6 +21,20 @@ func cactus_entrypoint
adr x0, stacks_end
mov sp, x0
+ /* Enable I-Cache */
+ mrs x0, sctlr_el1
+ orr x0, x0, #SCTLR_I_BIT
+ msr sctlr_el1, x0
+ isb
+
+ /* Relocate symbols */
+pie_fixup:
+ ldr x0, =pie_fixup
+ and x0, x0, #~(0x1000 - 1)
+ mov x1, #CACTUS_IMAGE_SIZE
+ add x1, x1, x0
+ bl fixup_gdt_reloc
+
/* And jump to the C entrypoint. */
b cactus_main
diff --git a/spm/cactus/cactus-secondary.dts b/spm/cactus/cactus-secondary.dts
new file mode 100644
index 000000000..041cd317a
--- /dev/null
+++ b/spm/cactus/cactus-secondary.dts
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP)
+ * that has additional optional properties defined.
+ *
+ */
+
+/dts-v1/;
+
+/ {
+ compatible = "arm,spci-manifest-1.0";
+
+ /* Properties */
+ description = "Base-1";
+ spci-version = <0x00000009>; /* 31:16 - Major, 15:0 - Minor */
+ uuid = <0xd1582309 0xf02347b9 0x827c4464 0xf5578fc8>;
+ id = <2>;
+ auxiliary-id = <0xae>;
+ stream-endpoint-ids = <0 1 2 3>;
+ execution-ctx-count = <1>;
+ exception-level = <2>; /* S-EL1 */
+ execution-state = <0>; /* AARCH64 */
+ load-address = <0x7100000>;
+ entrypoint-offset = <0x00001000>;
+ xlat-granule = <0>; /* 4KiB */
+ boot-order = <0>;
+ messaging-method = <0>; /* Direct messaging only */
+ run-time-model = <0>; /* Run to completion */
+
+ /* Boot protocol */
+ gp-register-num = <0x0>;
+
+ rx_tx-info {
+ compatible = "arm,spci-manifest-rx_tx-buffer";
+
+ description = "NS RX/TX Buffer";
+ pages-count = <1>;
+ attributes = <0x0>;
+ base-address = <0x7200000>;
+ };
+
+ memory-regions {
+ compatible = "arm,spci-manifest-memory-regions";
+ test-memory {
+ description = "Test Memory";
+ pages-count = <32>; /* 128KiB with 4KiB pages */
+ base-address = <0x00000000 0x21000000>;
+ attributes = <0x0>;
+ };
+ };
+
+ device-regions {
+ compatible = "arm,spci-manifest-device-regions";
+ attributes = <0x0>;
+ test-reg {
+ reg = <0x10000008 0x00000001 1>; /* Arbitrary test address */
+ smmu-id = <1>;
+ stream-ids = <0x0 0x1>;
+ interrupts = <0x2 0x3>,
+ <0x4 0x5>;
+ };
+ };
+
+};
diff --git a/spm/cactus/cactus.dts b/spm/cactus/cactus.dts
index cf89d7fe8..78cbb56ce 100644
--- a/spm/cactus/cactus.dts
+++ b/spm/cactus/cactus.dts
@@ -1,119 +1,67 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * This file is a Partition Manifest (PM) for a minimal Secure Partition (SP)
+ * that has additional optional properties defined.
+ *
*/
-#include <sp_res_desc_def.h>
-
-#include "cactus_def.h"
-
-/* 4 KiB pages */
-#define PAGE_SIZE U(0x1000)
-
-/*
- * FVP platform layout. The defines are hardcoded here because including the
- * platform headers have too many dependencies.
- * TODO: Move this to the platform layer.
- */
-#define V2M_IOFPGA_BASE ULL(0x1c000000)
-#define V2M_IOFPGA_SIZE ULL(0x03000000)
-
-/* Aggregate of all devices in the first GB. */
-#define DEVICE0_BASE ULL(0x20000000)
-#define DEVICE0_SIZE ULL(0x0c200000)
-
/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 = <CACTUS_IMAGE_SIZE>;
- load_address = <0x00000000 CACTUS_IMAGE_BASE>;
- entrypoint = <0x00000000 CACTUS_IMAGE_BASE>;
+ compatible = "arm,spci-manifest-1.0";
+
+ /* Properties */
+ description = "Base-1";
+ spci-version = <0x00000009>; /* 31:16 - Major, 15:0 - Minor */
+ uuid = <0xb4b5671e 0x4a904fe1 0xb81ffb13 0xdae1dacb>;
+ id = <1>;
+ auxiliary-id = <0xae>;
+ stream-endpoint-ids = <0 1 2 3>;
+ execution-ctx-count = <1>;
+ exception-level = <2>; /* S-EL1 */
+ execution-state = <0>; /* AARCH64 */
+ load-address = <0x7000000>;
+ entrypoint-offset = <0x00001000>;
+ xlat-granule = <0>; /* 4KiB */
+ boot-order = <0>;
+ messaging-method = <0>; /* Direct messaging only */
+ run-time-model = <0>; /* Run to completion */
+
+ /* Boot protocol */
+ gp-register-num = <0x0>;
+
+ rx_tx-info {
+ compatible = "arm,spci-manifest-rx_tx-buffer";
+
+ description = "NS RX/TX Buffer";
+ pages-count = <1>;
+ attributes = <0x0>;
+ base-address = <0x7200000>;
};
- memory_regions {
- v2m_iofpga {
- str = "V2M IOFPGA";
- base = <0x00000000 V2M_IOFPGA_BASE>;
- size = <0x00000000 V2M_IOFPGA_SIZE>;
- attr = <RD_MEM_DEVICE>;
- };
-
- device0 {
- str = "Device 0";
- base = <0x00000000 DEVICE0_BASE>;
- size = <0x00000000 DEVICE0_SIZE>;
- attr = <RD_MEM_DEVICE>;
- };
-
- spm_buffer {
- str = "SPM buffer";
- base = <0x00000000 CACTUS_SPM_BUF_BASE>;
- size = <0x00000000 CACTUS_SPM_BUF_SIZE>;
- attr = <RD_MEM_NORMAL_SPM_SP_SHARED_MEM>;
- };
-
- ns_buffer {
- str = "NS buffer";
- base = <0x00000000 CACTUS_NS_BUF_BASE>;
- size = <0x00000000 CACTUS_NS_BUF_SIZE>;
- attr = <RD_MEM_NORMAL_CLIENT_SHARED_MEM>;
- };
-
- test_memory {
- str = "Test memory";
- base = <0x00000000 CACTUS_TEST_MEM_BASE>;
- size = <0x00000000 CACTUS_TEST_MEM_SIZE>;
- attr = <RD_MEM_NORMAL_MISCELLANEOUS>;
+ memory-regions {
+ compatible = "arm,spci-manifest-memory-regions";
+ test-memory {
+ description = "Test Memory";
+ pages-count = <32>; /* 128KiB with 4KiB pages */
+ base-address = <0x00000000 0x21000000>;
+ attributes = <0x0>;
};
};
- notifications {
- notification_0 {
- attr = <0>;
- pe = <0>;
+ device-regions {
+ compatible = "arm,spci-manifest-device-regions";
+ attributes = <0x0>;
+ test-reg {
+ reg = <0x10000008 0x00000001 1>; /* Arbitrary test address */
+ smmu-id = <1>;
+ stream-ids = <0x0 0x1>;
+ interrupts = <0x2 0x3>,
+ <0x4 0x5>;
};
};
- services {
- test_service_1 {
- uuid = <CACTUS_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>;
-
- required_uuids {
- uuid_0 = <CACTUS_SERVICE2_UUID_RD>;
- };
- };
-
- test_service_2 {
- uuid = <CACTUS_SERVICE2_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/cactus/cactus.ld.S b/spm/cactus/cactus.ld.S
index a3d8e65d0..30ad0da7b 100644
--- a/spm/cactus/cactus.ld.S
+++ b/spm/cactus/cactus.ld.S
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -32,8 +32,20 @@ SECTIONS
. = ALIGN(PAGE_SIZE);
__RODATA_START__ = .;
*(.rodata*)
+
+ /*
+ * Keep the .got section in the RO section as it is patched
+ * prior to enabling the MMU and having the .got in RO is better for
+ * security. GOT is a table of addresses so ensure 8-byte alignment.
+ */
+ . = ALIGN(8);
+ __GOT_START__ = .;
+ *(.got)
+ __GOT_END__ = .;
+
. = NEXT(PAGE_SIZE);
__RODATA_END__ = .;
+
}
.data : {
@@ -44,6 +56,17 @@ SECTIONS
__DATA_END__ = .;
}
+ /*
+ * .rela.dyn needs to come after .data for the read-elf utility to parse
+ * this section correctly. Ensure 8-byte alignment so that the fields of
+ * RELA data structure are aligned.
+ */
+ . = ALIGN(8);
+ __RELA_START__ = .;
+ .rela.dyn . : {
+ }
+ __RELA_END__ = .;
+
.bss (NOLOAD) : {
. = ALIGN(PAGE_SIZE);
__BSS_START__ = .;
diff --git a/spm/cactus/cactus.mk b/spm/cactus/cactus.mk
index d4be8c625..c0b98f400 100644
--- a/spm/cactus/cactus.mk
+++ b/spm/cactus/cactus.mk
@@ -1,14 +1,16 @@
#
-# Copyright (c) 2018-2019, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
include lib/sprt/sprt_client.mk
+include lib/xlat_tables_v2/xlat_tables.mk
CACTUS_DTB := $(BUILD_PLAT)/cactus.dtb
CACTUS_INCLUDES := \
+ -Itftf/framework/include \
-Iinclude \
-Iinclude/common \
-Iinclude/common/${ARCH} \
@@ -44,9 +46,13 @@ CACTUS_SOURCES += \
CACTUS_SOURCES += drivers/arm/pl011/${ARCH}/pl011_console.S \
lib/${ARCH}/cache_helpers.S \
lib/${ARCH}/misc_helpers.S \
+ lib/smc/${ARCH}/asm_smc.S \
+ lib/smc/${ARCH}/smc.c \
+ lib/smc/${ARCH}/hvc.c \
lib/locks/${ARCH}/spinlock.S \
lib/utils/mp_printf.c \
- ${SPRT_LIB_SOURCES}
+ ${SPRT_LIB_SOURCES} \
+ ${XLAT_TABLES_LIB_SRCS}
CACTUS_LINKERFILE := spm/cactus/cactus.ld.S
@@ -64,6 +70,8 @@ $(CACTUS_DTB) : spm/cactus/cactus.dts
@echo " DTBGEN spm/cactus/cactus.dts"
${Q}tools/generate_dtb/generate_dtb.sh \
cactus spm/cactus/cactus.dts $(BUILD_PLAT)
+ ${Q}tools/generate_json/generate_json.sh \
+ cactus $(PLAT) $(BUILD_TYPE)
@echo
@echo "Built $@ successfully"
@echo
diff --git a/spm/cactus/cactus_def.h b/spm/cactus/cactus_def.h
index 13b5dac60..e865036d8 100644
--- a/spm/cactus/cactus_def.h
+++ b/spm/cactus/cactus_def.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -14,7 +14,7 @@
*/
/* Up to 2 MiB at an arbitrary address that doesn't overlap the devices. */
-#define CACTUS_IMAGE_BASE ULL(0x80000000)
+#define CACTUS_IMAGE_BASE ULL(0x1000)
#define CACTUS_IMAGE_SIZE ULL(0x200000)
/* Memory reserved for stacks */
diff --git a/spm/cactus/cactus_main.c b/spm/cactus/cactus_main.c
index 4580f23eb..c2c8ec295 100644
--- a/spm/cactus/cactus_main.c
+++ b/spm/cactus/cactus_main.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -10,21 +10,176 @@
#include <drivers/arm/pl011.h>
#include <drivers/console.h>
#include <errno.h>
+#include <lib/aarch64/arch_helpers.h>
+#include <lib/xlat_tables/xlat_tables_v2.h>
+#include <lib/xlat_tables/xlat_mmu_helpers.h>
#include <plat_arm.h>
+#include <plat/common/platform.h>
#include <platform_def.h>
#include <sp_helpers.h>
-#include <sprt_client.h>
-#include <sprt_svc.h>
+#include <spci_svc.h>
#include <std_svc.h>
#include "cactus.h"
#include "cactus_def.h"
#include "cactus_tests.h"
+#include "tftf_lib.h"
+
+#define SPM_VM_ID_FIRST (1)
+
+#define SPM_VM_GET_COUNT (0xFF01)
+#define SPM_VCPU_GET_COUNT (0xFF02)
+#define SPM_DEBUG_LOG (0xBD000000)
+
+/* Hypervisor ID at physical SPCI instance */
+#define HYP_ID (0)
+
+/* By convention, SP IDs (as opposed to VM IDs) have bit 15 set */
+#define SP_ID(x) (x | (1 << 15))
+
+typedef unsigned short spci_vm_id_t;
+typedef unsigned short spci_vm_count_t;
+typedef unsigned short spci_vcpu_count_t;
+
/* Host machine information injected by the build system in the ELF file. */
extern const char build_message[];
extern const char version_string[];
+static spci_vcpu_count_t spm_vcpu_get_count(spci_vm_id_t vm_id)
+{
+ hvc_args args = {
+ .fid = SPM_VCPU_GET_COUNT,
+ .arg1 = vm_id
+ };
+
+ hvc_ret_values ret = tftf_hvc(&args);
+
+ return ret.ret0;
+}
+
+static spci_vm_count_t spm_vm_get_count(void)
+{
+ hvc_args args = {
+ .fid = SPM_VM_GET_COUNT
+ };
+
+ hvc_ret_values ret = tftf_hvc(&args);
+
+ return ret.ret0;
+}
+
+static void spm_debug_log(char c)
+{
+ hvc_args args = {
+ .fid = SPM_DEBUG_LOG,
+ .arg1 = c
+ };
+
+ (void)tftf_hvc(&args);
+}
+
+static smc_ret_values spci_id_get(void)
+{
+ smc_args args = {
+ .fid = SPCI_ID_GET
+ };
+
+ return tftf_smc(&args);
+}
+
+static smc_ret_values spci_msg_wait(void)
+{
+ smc_args args = {
+ .fid = SPCI_MSG_WAIT
+ };
+
+ return tftf_smc(&args);
+}
+
+/* Send response through registers using direct messaging */
+static smc_ret_values spci_msg_send_direct_resp(spci_vm_id_t sender_vm_id,
+ spci_vm_id_t target_vm_id,
+ uint32_t message)
+{
+ smc_args args = {
+ .fid = SPCI_MSG_SEND_DIRECT_RESP_SMC32,
+ .arg1 = ((uint32_t)sender_vm_id << 16) | target_vm_id,
+ .arg3 = message
+ };
+
+ return tftf_smc(&args);
+}
+
+static smc_ret_values spci_error(int32_t error_code)
+{
+ smc_args args = {
+ .fid = SPCI_ERROR,
+ .arg1 = 0,
+ .arg2 = error_code
+ };
+
+ return tftf_smc(&args);
+}
+
+/*
+ *
+ * Message loop function
+ * Notice we cannot use regular print functions because this serves to both
+ * "primary" and "secondary" VMs. Secondary VM cannot access UART directly
+ * but rather through Hafnium print hypercall.
+ *
+ */
+static void __dead2 message_loop(spci_vm_id_t vm_id)
+{
+ smc_ret_values spci_ret;
+ uint32_t sp_response;
+
+ /*
+ * This initial wait call is necessary to inform SPMD that
+ * SP initialization has completed. It blocks until receiving
+ * a direct message request.
+ */
+ spci_ret = spci_msg_wait();
+
+ for (;;) {
+
+ if (spci_ret.ret0 != SPCI_MSG_SEND_DIRECT_REQ_SMC32) {
+ spci_ret = spci_error(-1);
+ continue;
+ }
+
+ if (spci_ret.ret1 != SP_ID(vm_id)) {
+ spci_ret = spci_error(-2);
+ continue;
+ }
+
+ if (spci_ret.ret2 != HYP_ID) {
+ spci_ret = spci_error(-3);
+ continue;
+ }
+
+ /*
+ * For the sake of testing, add the vm id to the
+ * received message.
+ */
+ sp_response = spci_ret.ret3 | vm_id;
+
+ /*
+ * Send a response through direct messaging then block
+ * until receiving a new message request.
+ */
+ spci_ret = spci_msg_send_direct_resp(SP_ID(vm_id),
+ HYP_ID, sp_response);
+ }
+}
+
+static const mmap_region_t cactus_mmap[] __attribute__((used)) = {
+ /* DEVICE0 area includes UART2 necessary to console */
+ MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW),
+ {0}
+};
+
static void cactus_print_memory_layout(void)
{
NOTICE("Secure Partition memory layout:\n");
@@ -54,97 +209,81 @@ static void cactus_print_memory_layout(void)
(void *)(CACTUS_TEST_MEM_BASE + CACTUS_TEST_MEM_SIZE));
}
-static void cactus_message_handler(struct sprt_queue_entry_message *message)
+static void cactus_plat_configure_mmu(void)
{
- 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;
-
- case CACTUS_SLEEP_MS:
- sp_sleep(message->args[2]);
- 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;
- }
+ mmap_add_region(CACTUS_TEXT_START,
+ CACTUS_TEXT_START,
+ CACTUS_TEXT_END - CACTUS_TEXT_START,
+ MT_CODE);
+ mmap_add_region(CACTUS_RODATA_START,
+ CACTUS_RODATA_START,
+ CACTUS_RODATA_END - CACTUS_RODATA_START,
+ MT_RO_DATA);
+ mmap_add_region(CACTUS_DATA_START,
+ CACTUS_DATA_START,
+ CACTUS_DATA_END - CACTUS_DATA_START,
+ MT_RW_DATA);
+ mmap_add_region(CACTUS_BSS_START,
+ CACTUS_BSS_START,
+ CACTUS_BSS_END - CACTUS_BSS_START,
+ MT_RW_DATA);
- sprt_message_end(message, ret0, ret1, ret2, ret3);
+ mmap_add(cactus_mmap);
+ init_xlat_tables();
}
void __dead2 cactus_main(void)
{
+ assert(IS_IN_EL1() != 0);
+
+ /* Clear BSS */
+ memset((void *)CACTUS_BSS_START,
+ 0, CACTUS_BSS_END - CACTUS_BSS_START);
+
+ /* Configure and enable Stage-1 MMU, enable D-Cache */
+ cactus_plat_configure_mmu();
+ enable_mmu_el1(0);
+
+ /* Get current SPCI id */
+ smc_ret_values spci_id_ret = spci_id_get();
+ if (spci_id_ret.ret0 != SPCI_SUCCESS_SMC32) {
+ ERROR("SPCI_ID_GET failed.\n");
+ panic();
+ }
+
+ spci_vm_id_t spci_id = spci_id_ret.ret2 & 0xffff;
+ if (spci_id > SPM_VM_ID_FIRST) {
+ /* Indicate secondary VM start through debug log hypercall */
+ spm_debug_log('2');
+ spm_debug_log('N');
+ spm_debug_log('D');
+ spm_debug_log('\n');
+
+ /* Run straight to the message loop */
+ message_loop(spci_id);
+ }
+
+ /* Next initialization steps only performed by primary VM */
+
console_init(PL011_UART2_BASE,
PL011_UART2_CLK_IN_HZ,
PL011_BAUDRATE);
- NOTICE("Booting test Secure Partition Cactus\n");
- NOTICE("%s\n", build_message);
- NOTICE("%s\n", version_string);
- NOTICE("Running at S-EL0\n");
+ NOTICE("Booting Cactus Secure Partition\n%s\n%s\n",
+ build_message, version_string);
cactus_print_memory_layout();
- /*
- * Run some initial tests.
- *
- * These are executed when the system is still booting, just after SPM
- * has handed over to Cactus.
- */
- misc_tests();
- system_setup_tests();
- mem_attr_changes_tests();
+ NOTICE("SPCI id: %u\n", spci_id); /* Expect VM id 1 */
- /*
- * Handle secure service requests.
- */
- sprt_initialize_queues((void *)CACTUS_SPM_BUF_BASE);
+ /* Get number of VMs */
+ NOTICE("VM count: %u\n", spm_vm_get_count());
- while (1) {
- struct sprt_queue_entry_message message;
+ /* Get virtual CPU count for current VM */
+ NOTICE("vCPU count: %u\n", spm_vcpu_get_count(spci_id));
- /*
- * 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);
- }
- }
+ /* End up to message loop */
+ message_loop(spci_id);
- sprt_wait_for_messages();
- }
+ /* Not reached */
}
diff --git a/tftf/tests/runtime_services/secure_service/spci_helpers.c b/tftf/tests/runtime_services/secure_service/spci_helpers.c
index 268c26f6f..1370a3877 100644
--- a/tftf/tests/runtime_services/secure_service/spci_helpers.c
+++ b/tftf/tests/runtime_services/secure_service/spci_helpers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Arm Limited. All rights reserved.
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
@@ -8,172 +8,101 @@
#include <smccc.h>
#include <spci_helpers.h>
#include <spci_svc.h>
-#include <tftf_lib.h>
-/* Returns a SPCI error code. On success, it also returns a 16 bit handle. */
-int spci_service_handle_open(uint16_t client_id, uint16_t *handle,
- uint32_t uuid1, uint32_t uuid2,
- uint32_t uuid3, uint32_t uuid4)
-{
- int32_t ret;
-
- smc_args get_handle_smc_args = {
- SPCI_SERVICE_HANDLE_OPEN,
- uuid1, uuid2, uuid3, uuid4,
- 0, 0, /* Reserved - MBZ */
- client_id
- };
-
- smc_ret_values smc_ret = tftf_smc(&get_handle_smc_args);
-
- ret = smc_ret.ret0;
- if (ret != SPCI_SUCCESS)
- return ret;
-
- uint32_t x1 = smc_ret.ret1;
-
- if ((x1 & 0x0000FFFF) != 0) {
- tftf_testcase_printf("SPCI_SERVICE_HANDLE_OPEN returned x1 = 0x%08x\n", x1);
- return SPCI_TFTF_ERROR;
- }
-
- /* The handle is returned in the top 16 bits */
- *handle = (x1 >> 16) & 0xFFFF;
-
- return SPCI_SUCCESS;
-}
-
-/* Invokes SPCI_SERVICE_HANDLE_CLOSE. Returns a SPCI error code. */
-int spci_service_handle_close(uint16_t client_id, uint16_t handle)
+/*-----------------------------------------------------------------------------
+ * SPCI_RUN
+ *
+ * Parameters
+ * uint32 Function ID (w0): 0x8400006D
+ * uint32 Target information (w1): Information to identify target SP/VM
+ * -Bits[31:16]: ID of SP/VM.
+ * -Bits[15:0]: ID of vCPU of SP/VM to run.
+ * Other Parameter registers w2-w7/x2-x7: Reserved (MBZ)
+ *
+ * On failure, returns SPCI_ERROR in w0 and error code in w2:
+ * -INVALID_PARAMETERS: Unrecognized endpoint or vCPU ID
+ * -NOT_SUPPORTED: This function is not implemented at this SPCI instance
+ * -DENIED: Callee is not in a state to handle this request
+ * -BUSY: vCPU is busy and caller must retry later
+ * -ABORTED: vCPU or VM ran into an unexpected error and has aborted
+ */
+smc_ret_values spci_run(uint32_t dest_id, uint32_t vcpu_id)
{
- smc_args close_handle_smc_args = {
- SPCI_SERVICE_HANDLE_CLOSE,
- client_id | (handle << 16)
+ smc_args args = {
+ SPCI_MSG_RUN,
+ (dest_id << 16) | vcpu_id,
+ 0, 0, 0, 0, 0, 0
};
- smc_ret_values smc_ret = tftf_smc(&close_handle_smc_args);
-
- return (int32_t)(uint32_t)smc_ret.ret0;
+ return tftf_smc(&args);
}
-/* Returns a SPCI error code. On success, it also returns a token. */
-int spci_service_request_start(u_register_t x1, u_register_t x2,
- u_register_t x3, u_register_t x4,
- u_register_t x5, u_register_t x6,
- uint16_t client_id, uint16_t handle,
- uint32_t *token)
+/*-----------------------------------------------------------------------------
+ * SPCI_MSG_SEND_DIRECT_REQ
+ *
+ * Parameters
+ * uint32 Function ID (w0): 0x8400006F / 0xC400006F
+ * uint32 Source/Destination IDs (w1): Source and destination endpoint IDs
+ * -Bit[31:16]: Source endpoint ID
+ * -Bit[15:0]: Destination endpoint ID
+ * uint32/uint64 (w2/x2) - RFU MBZ
+ * w3-w7 - Implementation defined
+ *
+ * On failure, returns SPCI_ERROR in w0 and error code in w2:
+ * -INVALID_PARAMETERS: Invalid endpoint ID or non-zero reserved register
+ * -DENIED: Callee is not in a state to handle this request
+ * -NOT_SUPPORTED: This function is not implemented at this SPCI instance
+ * -BUSY: Message target is busy
+ * -ABORTED: Message target ran into an unexpected error and has aborted
+ */
+static smc_ret_values __spci_msg_send_direct_req32_5(uint32_t source_id,
+ uint32_t dest_id,
+ uint32_t arg0,
+ uint32_t arg1,
+ uint32_t arg2,
+ uint32_t arg3,
+ uint32_t arg4)
{
- int32_t ret;
-
- smc_args request_smc_args = {
- SPCI_SERVICE_REQUEST_START_AARCH64,
- x1, x2, x3, x4, x5, x6,
- client_id | (handle << 16)
+ smc_args args = {
+ SPCI_MSG_SEND_DIRECT_REQ_SMC32,
+ (source_id << 16) | dest_id,
+ 0,
+ arg0, arg1, arg2, arg3, arg4
};
- smc_ret_values smc_ret = tftf_smc(&request_smc_args);
-
- ret = (int32_t)(uint32_t)smc_ret.ret0;
- if (ret != SPCI_SUCCESS)
- return ret;
-
- *token = smc_ret.ret1;
-
- return SPCI_SUCCESS;
+ return tftf_smc(&args);
}
-/*
- * Returns a SPCI error code. On success, it also returns x1-x3. Any of the
- * pointers x1-x3 may be NULL in case the caller doesn't need that value.
- */
-int spci_service_request_resume(uint16_t client_id, uint16_t handle,
- uint32_t token, u_register_t *x1,
- u_register_t *x2, u_register_t *x3)
+/* Direct message send helper accepting a single 32b message argument */
+smc_ret_values spci_msg_send_direct_req(uint32_t source_id, uint32_t dest_id,
+ uint32_t message)
{
- int32_t ret;
-
- smc_args request_resume_smc = {
- SPCI_SERVICE_REQUEST_RESUME_AARCH64,
- token, 0, 0, 0, 0, 0,
- client_id | (handle << 16)
- };
-
- smc_ret_values smc_ret = tftf_smc(&request_resume_smc);
-
- ret = (int32_t)(uint32_t)smc_ret.ret0;
- if (ret != SPCI_SUCCESS)
- return ret;
-
- if (x1 != NULL)
- *x1 = smc_ret.ret1;
- if (x2 != NULL)
- *x2 = smc_ret.ret2;
- if (x3 != NULL)
- *x3 = smc_ret.ret3;
-
- return SPCI_SUCCESS;
+ return __spci_msg_send_direct_req32_5(source_id, dest_id,
+ message, 0, 0, 0, 0);
}
-/*
- * Returns a SPCI error code. On success, it also returns x1-x3. Any of the
- * pointers x1-x3 may be NULL in case the caller doesn't need that value.
- */
-int spci_service_get_response(uint16_t client_id, uint16_t handle,
- uint32_t token, u_register_t *x1,
- u_register_t *x2, u_register_t *x3)
+static smc_ret_values __spci_msg_send_direct_req64_5(uint32_t source_id,
+ uint32_t dest_id,
+ uint64_t arg0,
+ uint64_t arg1,
+ uint64_t arg2,
+ uint64_t arg3,
+ uint64_t arg4)
{
- int32_t ret;
-
- smc_args get_response_smc = {
- SPCI_SERVICE_GET_RESPONSE_AARCH64,
- token, 0, 0, 0, 0, 0,
- client_id | (handle << 16)
+ smc_args args = {
+ SPCI_MSG_SEND_DIRECT_REQ_SMC64,
+ (source_id << 16) | dest_id,
+ 0,
+ arg0, arg1, arg2, arg3, arg4
};
- smc_ret_values smc_ret = tftf_smc(&get_response_smc);
-
- ret = (int32_t)(uint32_t)smc_ret.ret0;
- if (ret != SPCI_SUCCESS)
- return ret;
-
- if (x1 != NULL)
- *x1 = smc_ret.ret1;
- if (x2 != NULL)
- *x2 = smc_ret.ret2;
- if (x3 != NULL)
- *x3 = smc_ret.ret3;
-
- return SPCI_SUCCESS;
+ return tftf_smc(&args);
}
-/* Returns a SPCI error code. On success, it also returns the returned values. */
-int spci_service_request_blocking(u_register_t x1, u_register_t x2,
- u_register_t x3, u_register_t x4,
- u_register_t x5, u_register_t x6,
- uint16_t client_id, uint16_t handle,
- u_register_t *rx1, u_register_t *rx2,
- u_register_t *rx3)
+/* Direct message send helper accepting a single 64b message argument */
+smc_ret_values spci_msg_send_direct_req64(uint32_t source_id, uint32_t dest_id,
+ uint64_t message)
{
- int32_t ret;
-
- smc_args request_smc_args = {
- SPCI_SERVICE_REQUEST_BLOCKING_AARCH64,
- x1, x2, x3, x4, x5, x6,
- client_id | (handle << 16)
- };
-
- smc_ret_values smc_ret = tftf_smc(&request_smc_args);
-
- ret = (int32_t)(uint32_t)smc_ret.ret0;
- if (ret != SPCI_SUCCESS)
- return ret;
-
- if (rx1 != NULL)
- *rx1 = smc_ret.ret1;
- if (rx2 != NULL)
- *rx2 = smc_ret.ret2;
- if (rx3 != NULL)
- *rx3 = smc_ret.ret3;
-
- return SPCI_SUCCESS;
+ return __spci_msg_send_direct_req64_5(source_id, dest_id,
+ message, 0, 0, 0, 0);
}
diff --git a/tftf/tests/runtime_services/secure_service/test_spci_direct_messaging.c b/tftf/tests/runtime_services/secure_service/test_spci_direct_messaging.c
new file mode 100644
index 000000000..7c0e97380
--- /dev/null
+++ b/tftf/tests/runtime_services/secure_service/test_spci_direct_messaging.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <arch_helpers.h>
+#include <cactus_def.h>
+#include <platform.h>
+#include <smccc.h>
+#include <spci_helpers.h>
+#include <spci_svc.h>
+#include <test_helpers.h>
+
+/* Hypervisor ID at physical SPCI instance */
+#define HYP_ID (0)
+
+/* By convention, SP IDs (as opposed to VM IDs) have bit 15 set */
+#define SP_ID(x) (x | (1 << 15))
+
+#define DIRECT_MSG_TEST_PATTERN1 (0xaaaa0000)
+#define DIRECT_MSG_TEST_PATTERN2 (0xbbbb0000)
+#define DIRECT_MSG_TEST_PATTERN3 (0xcccc0000)
+
+static test_result_t send_receive_direct_msg(unsigned int sp_id,
+ unsigned int test_pattern)
+{
+ smc_ret_values ret_values;
+
+ /* Send a message to SP through direct messaging */
+ ret_values = spci_msg_send_direct_req(HYP_ID, SP_ID(sp_id),
+ test_pattern);
+
+ /*
+ * Return responses may be SPCI_MSG_SEND_DIRECT_RESP or SPCI_INTERRUPT,
+ * but only expect the former. Expect SMC32 convention from SP.
+ */
+ if (ret_values.ret0 != SPCI_MSG_SEND_DIRECT_RESP_SMC32) {
+ tftf_testcase_printf("spci_msg_send_direct_req returned %lx\n",
+ (u_register_t)ret_values.ret0);
+ return TEST_RESULT_FAIL;
+ }
+
+ /*
+ * Message loop in SP returns initial message with the running VM id
+ * into the lower 16 bits of initial message.
+ */
+ if (ret_values.ret3 != (test_pattern | sp_id)) {
+ return TEST_RESULT_FAIL;
+ }
+
+ return TEST_RESULT_SUCCESS;
+}
+
+test_result_t test_spci_direct_messaging(void)
+{
+ smc_ret_values ret_values;
+ test_result_t result;
+
+ /**********************************************************************
+ * Verify that SPCI is there and that it has the correct version.
+ **********************************************************************/
+ SKIP_TEST_IF_SPCI_VERSION_LESS_THAN(0, 9);
+
+ /**********************************************************************
+ * Send a message to SP1 through direct messaging
+ **********************************************************************/
+ result = send_receive_direct_msg(1, DIRECT_MSG_TEST_PATTERN1);
+ if (result != TEST_RESULT_SUCCESS) {
+ return result;
+ }
+
+ /**********************************************************************
+ * Send a message to SP2 through direct messaging
+ **********************************************************************/
+ /*
+ * NOTICE: for now, the SPM does not initially run each SP sequentially
+ * on boot up so we explicitely run the SP once by invoking SPCI_RUN so
+ * it reaches spci_msg_wait in the message loop function.
+ */
+
+ /* Request running SP2 on VCPU0 */
+ ret_values = spci_run(2, 0);
+ if (ret_values.ret0 != SPCI_MSG_WAIT) {
+ tftf_testcase_printf("spci_run returned %lx\n",
+ (u_register_t)ret_values.ret0);
+ return TEST_RESULT_FAIL;
+ }
+
+ result = send_receive_direct_msg(2, DIRECT_MSG_TEST_PATTERN2);
+ if (result != TEST_RESULT_SUCCESS) {
+ return result;
+ }
+
+ /**********************************************************************
+ * Send a message to SP1 through direct messaging
+ **********************************************************************/
+ result = send_receive_direct_msg(1, DIRECT_MSG_TEST_PATTERN3);
+ if (result != TEST_RESULT_SUCCESS) {
+ return result;
+ }
+
+ /**********************************************************************
+ * All tests passed.
+ **********************************************************************/
+ return TEST_RESULT_SUCCESS;
+}
diff --git a/tftf/tests/tests-spm.mk b/tftf/tests/tests-spm.mk
index c4876879f..40c9b87d7 100644
--- a/tftf/tests/tests-spm.mk
+++ b/tftf/tests/tests-spm.mk
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -7,10 +7,5 @@
TESTS_SOURCES += \
$(addprefix tftf/tests/runtime_services/secure_service/, \
spci_helpers.c \
- test_spci_handle_open.c \
- test_spci_blocking_request.c \
- test_spci_non_blocking_request.c \
- test_spci_blocking_while_busy.c \
- test_spci_blocking_interrupt.c \
- test_spci_non_blocking_interrupt.c \
+ test_spci_direct_messaging.c \
)
diff --git a/tftf/tests/tests-spm.xml b/tftf/tests/tests-spm.xml
index 9afc6afd2..beac7dd69 100644
--- a/tftf/tests/tests-spm.xml
+++ b/tftf/tests/tests-spm.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (c) 2018, Arm Limited. All rights reserved.
+ Copyright (c) 2018-2020, Arm Limited. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
-->
@@ -11,24 +11,8 @@
<testsuite name="Secure Partition Manager"
description="Test SPM APIs">
- <testcase name="SPCI handle open and close"
- function="test_spci_handle_open" />
-
- <testcase name="SPCI non-blocking requests"
- function="test_spci_request" />
-
- <testcase name="SPCI blocking requests multicore"
- function="test_spci_blocking_request_multicore" />
- <testcase name="SPCI non-blocking requests multicore"
- function="test_spci_request_multicore" />
-
- <testcase name="SPCI blocking request while busy"
- function="test_spci_blocking_while_busy" />
-
- <testcase name="SPCI blocking request fail to preempt"
- function="test_spci_blocking_interrupt_by_ns" />
- <testcase name="SPCI non-blocking request succeed to preempt"
- function="test_spci_non_blocking_interrupt_by_ns" />
+ <testcase name="SPCI direct messaging API"
+ function="test_spci_direct_messaging" />
</testsuite>
diff --git a/tftf/tests/tests-standard.xml b/tftf/tests/tests-standard.xml
index a865981db..0bebbef67 100644
--- a/tftf/tests/tests-standard.xml
+++ b/tftf/tests/tests-standard.xml
@@ -20,6 +20,7 @@
<!ENTITY tests-cpu-extensions SYSTEM "tests-cpu-extensions.xml">
<!ENTITY tests-performance SYSTEM "tests-performance.xml">
<!ENTITY tests-smc SYSTEM "tests-smc.xml">
+ <!ENTITY tests-spm SYSTEM "tests-spm.xml">
<!ENTITY tests-pmu-leakage SYSTEM "tests-pmu-leakage.xml">
<!ENTITY tests-debugfs SYSTEM "tests-debugfs.xml">
]>
@@ -37,6 +38,7 @@
&tests-cpu-extensions;
&tests-performance;
&tests-smc;
+ &tests-spm;
&tests-pmu-leakage;
&tests-debugfs;
diff --git a/tools/generate_dtb/generate_dtb.sh b/tools/generate_dtb/generate_dtb.sh
index 84ba88090..564c2a05d 100755
--- a/tools/generate_dtb/generate_dtb.sh
+++ b/tools/generate_dtb/generate_dtb.sh
@@ -1,7 +1,7 @@
#!/bin/bash
#
-# Copyright (c) 2018, Arm Limited. All rights reserved.
+# Copyright (c) 2018-2020, Arm Limited. All rights reserved.
#
# SPDX-License-Identifier: BSD-3-Clause
#
@@ -37,37 +37,9 @@ BSS_END=$(grep __BSS_END__ $MAPFILE | awk {'print $1'})
# Inject new sections to the base DTS
-echo "\
-/ {
- memory_regions {
- text {
- str = \"Text\";
- base = <0x0 ${TEXT_START}ULL>;
- size = <0x0 (${TEXT_END}ULL - ${TEXT_START}ULL)>;
- attr = <RD_MEM_NORMAL_CODE>;
- };
- rodata {
- str = \"RO Data\";
- base = <0x0 (${RODATA_START}ULL)>;
- size = <0x0 (${RODATA_END}ULL - ${RODATA_START}ULL)>;
- attr = <RD_MEM_NORMAL_RODATA>;
- };
- rwdata {
- str = \"Data\";
- base = <0x0 ${DATA_START}ULL>;
- size = <0x0 (${DATA_END}ULL - ${DATA_START}ULL)>;
- attr = <RD_MEM_NORMAL_DATA>;
- };
- bss {
- str = \"BSS\";
- base = <0x0 ${BSS_START}ULL>;
- size = <0x0 (${BSS_END}ULL - ${BSS_START}ULL)>;
- attr = <RD_MEM_NORMAL_BSS>;
- };
- };
-};" > "$EXTRA_DTS"
+# Memory region generation discarded
-cat "$ORIGINAL_DTS" "$EXTRA_DTS" > "$COMBINED_DTS"
+cat "$ORIGINAL_DTS" > "$COMBINED_DTS"
INCLUDES="-I spm/cactus
-I spm/ivy
diff --git a/tools/generate_json/generate_json.sh b/tools/generate_json/generate_json.sh
new file mode 100755
index 000000000..8dd263032
--- /dev/null
+++ b/tools/generate_json/generate_json.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+#
+# Copyright (c) 2020, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+
+# Generate a JSON file which will be fed to TF-A as SPM_LAYOUT_FILE to package
+# Secure Partitions as part of FIP.
+
+# $1 = Secure Partition (cactus)
+# $2 = Platform (fvp)
+# $3 = Build Type
+# Output = build/plat/<Build Type>/sp_layout.json
+
+GENERATED_JSON=build/$2/$3/sp_layout.json
+
+# To demonstrate communication between SP's, two cactus S-EL1 instances used.
+# cactus-primary and cactus-secondary has same binary but different
+# partition manifest.
+if [ "$1" == "cactus" ]; then
+ echo -e "{\n\t\"$1-primary\" : {\n \
+ \t\"image\": \"$1.bin\",\n \
+ \t\"pm\": \"../../../spm/$1/$1.dts\"\n\t},\n\n\t\"$1-secondary\" : {\n \
+ \t\"image\": \"$1.bin\",\n \
+ \t\"pm\": \"../../../spm/$1/$1-secondary.dts\" \n \
+ }\n}" \
+ > "$GENERATED_JSON"
+else
+ echo -e "\nWarning: Only Cactus is supported as Secure Partition\n"
+fi