diff options
-rw-r--r-- | Makefile | 12 | ||||
-rw-r--r-- | include/common/test_helpers.h | 11 | ||||
-rw-r--r-- | include/lib/tftf_lib.h | 11 | ||||
-rw-r--r-- | include/runtime_services/spci_helpers.h | 32 | ||||
-rw-r--r-- | include/runtime_services/spci_svc.h | 220 | ||||
-rw-r--r-- | lib/aarch64/misc_helpers.S | 115 | ||||
-rw-r--r-- | lib/smc/aarch64/asm_smc.S | 57 | ||||
-rw-r--r-- | lib/smc/aarch64/hvc.c | 30 | ||||
-rw-r--r-- | spm/README.txt | 11 | ||||
-rw-r--r-- | spm/cactus/aarch64/cactus_entrypoint.S | 16 | ||||
-rw-r--r-- | spm/cactus/cactus-secondary.dts | 67 | ||||
-rw-r--r-- | spm/cactus/cactus.dts | 152 | ||||
-rw-r--r-- | spm/cactus/cactus.ld.S | 25 | ||||
-rw-r--r-- | spm/cactus/cactus.mk | 12 | ||||
-rw-r--r-- | spm/cactus/cactus_def.h | 4 | ||||
-rw-r--r-- | spm/cactus/cactus_main.c | 297 | ||||
-rw-r--r-- | tftf/tests/runtime_services/secure_service/spci_helpers.c | 227 | ||||
-rw-r--r-- | tftf/tests/runtime_services/secure_service/test_spci_direct_messaging.c | 107 | ||||
-rw-r--r-- | tftf/tests/tests-spm.mk | 9 | ||||
-rw-r--r-- | tftf/tests/tests-spm.xml | 22 | ||||
-rw-r--r-- | tftf/tests/tests-standard.xml | 2 | ||||
-rwxr-xr-x | tools/generate_dtb/generate_dtb.sh | 34 | ||||
-rwxr-xr-x | tools/generate_json/generate_json.sh | 32 |
23 files changed, 953 insertions, 552 deletions
@@ -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 |