diff --git a/Makefile b/Makefile index ff7c5b7..4bbe715 100644 --- a/Makefile +++ b/Makefile @@ -571,14 +571,6 @@ endif endif -# The SPCI-based SPM implementation and the MM-based SPM implementation cannot -# be enabled at the same time. -ifeq ($(ENABLE_SPM),1) - ifeq ($(SPM_MM),1) - $(error Use only one of the ENABLE_SPM and SPM_MM flags) - endif -endif - ################################################################################ # Process platform overrideable behaviour ################################################################################ @@ -719,7 +711,6 @@ $(eval $(call assert_boolean,ENABLE_PSCI_STAT)) $(eval $(call assert_boolean,ENABLE_RUNTIME_INSTRUMENTATION)) $(eval $(call assert_boolean,ENABLE_SPE_FOR_LOWER_ELS)) -$(eval $(call assert_boolean,ENABLE_SPM)) $(eval $(call assert_boolean,ENABLE_SVE_FOR_NS)) $(eval $(call assert_boolean,ERROR_DEPRECATED)) $(eval $(call assert_boolean,FAULT_INJECTION_SUPPORT)) @@ -784,7 +775,6 @@ $(eval $(call add_define,ENABLE_PSCI_STAT)) $(eval $(call add_define,ENABLE_RUNTIME_INSTRUMENTATION)) $(eval $(call add_define,ENABLE_SPE_FOR_LOWER_ELS)) -$(eval $(call add_define,ENABLE_SPM)) $(eval $(call add_define,ENABLE_SVE_FOR_NS)) $(eval $(call add_define,ERROR_DEPRECATED)) $(eval $(call add_define,FAULT_INJECTION_SUPPORT)) diff --git a/bl31/bl31.ld.S b/bl31/bl31.ld.S index a4be3b2..a598e59 100644 --- a/bl31/bl31.ld.S +++ b/bl31/bl31.ld.S @@ -142,7 +142,7 @@ ASSERT(__CPU_OPS_END__ > __CPU_OPS_START__, "cpu_ops not defined for this platform.") -#if ENABLE_SPM || SPM_MM +#if SPM_MM #ifndef SPM_SHIM_EXCEPTIONS_VMA #define SPM_SHIM_EXCEPTIONS_VMA RAM #endif diff --git a/bl31/bl31.mk b/bl31/bl31.mk index 7ff054a..33d414d 100644 --- a/bl31/bl31.mk +++ b/bl31/bl31.mk @@ -5,16 +5,11 @@ # ################################################################################ -# Include Makefile for either of the supported SPM implementations +# Include Makefile for the SPM-MM implementation ################################################################################ -ifeq (${ENABLE_SPM},1) - $(info Including SPM (SPCI) makefile) - include services/std_svc/spm/spm.mk -endif - ifeq (${SPM_MM},1) ifeq (${EL3_EXCEPTION_HANDLING},0) - $(error EL3_EXCEPTION_HANDLING must be 1 for SPM support) + $(error EL3_EXCEPTION_HANDLING must be 1 for SPM-MM support) else $(info Including SPM Management Mode (MM) makefile) include services/std_svc/spm_mm/spm.mk diff --git a/docs/getting_started/build-options.rst b/docs/getting_started/build-options.rst index 87ce94e..87429f2 100644 --- a/docs/getting_started/build-options.rst +++ b/docs/getting_started/build-options.rst @@ -235,11 +235,6 @@ The default is 1 but is automatically disabled when the target architecture is AArch32. -- ``ENABLE_SPM`` : Boolean option to enable the SPCI-based Secure Partition - Manager (SPM) implementation. - Refer to the :ref:`Secure Partition Manager` guide for more details about - this feature. Default is 0. - - ``ENABLE_SVE_FOR_NS``: Boolean option to enable Scalable Vector Extension (SVE) for the Non-secure world only. SVE is an optional architectural feature for AArch64. Note that when SVE is enabled for the Non-secure world, access diff --git a/include/lib/sprt/sprt_common.h b/include/lib/sprt/sprt_common.h deleted file mode 100644 index 27d5027..0000000 --- a/include/lib/sprt/sprt_common.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2018, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SPRT_COMMON_H -#define SPRT_COMMON_H - -#define SPRT_MAX_MSG_ARGS 6 - -/* - * Message types supported. - */ -#define SPRT_MSG_TYPE_SERVICE_HANDLE_OPEN 1 -#define SPRT_MSG_TYPE_SERVICE_HANDLE_CLOSE 2 -/* TODO: Add other types of SPRT messages. */ -#define SPRT_MSG_TYPE_SERVICE_TUN_REQUEST 10 - -/* - * Struct that defines the layout of the fields corresponding to a request in - * shared memory. - */ -struct __attribute__((__packed__)) sprt_queue_entry_message { - uint32_t type; /* Type of message (result of an SPCI call). */ - uint16_t client_id; /* SPCI client ID */ - uint16_t service_handle;/* SPCI service handle */ - uint32_t session_id; /* Optional SPCI session ID */ - uint32_t token; /* SPCI request token */ - uint64_t args[SPRT_MAX_MSG_ARGS]; -}; - -#define SPRT_QUEUE_ENTRY_MSG_SIZE (sizeof(struct sprt_queue_entry_message)) - -#define SPRT_QUEUE_NUM_BLOCKING 0 -#define SPRT_QUEUE_NUM_NON_BLOCKING 1 - -#endif /* SPRT_COMMON_H */ diff --git a/include/lib/sprt/sprt_host.h b/include/lib/sprt/sprt_host.h deleted file mode 100644 index f888141..0000000 --- a/include/lib/sprt/sprt_host.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2018, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#ifndef SPRT_HOST_H -#define SPRT_HOST_H - -#include - -#include "sprt_common.h" - -/* - * Initialize the specified buffer to be used by SPM. - */ -void sprt_initialize_queues(void *buffer_base, size_t buffer_size); - -/* - * Push a message to the queue number `queue_num` in a buffer that has been - * initialized by `sprt_initialize_queues`. - */ -int sprt_push_message(void *buffer_base, - const struct sprt_queue_entry_message *message, - int queue_num); - -#endif /* SPRT_HOST_H */ diff --git a/include/plat/arm/common/arm_def.h b/include/plat/arm/common/arm_def.h index 8095bed..72e2e8e 100644 --- a/include/plat/arm/common/arm_def.h +++ b/include/plat/arm/common/arm_def.h @@ -457,7 +457,7 @@ * Trusted DRAM (if available) or the DRAM region secured by the TrustZone * controller. */ -# if ENABLE_SPM +# if SPM_MM # define TSP_SEC_MEM_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000)) # define TSP_SEC_MEM_SIZE (ARM_AP_TZC_DRAM1_SIZE - ULL(0x200000)) # define BL32_BASE (ARM_AP_TZC_DRAM1_BASE + ULL(0x200000)) @@ -500,9 +500,9 @@ * SPD and no SPM, as they are the only ones that can be used as BL32. */ #if defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME -# if defined(SPD_none) && !ENABLE_SPM && !SPM_MM +# if defined(SPD_none) && !SPM_MM # undef BL32_BASE -# endif /* defined(SPD_none) && !ENABLE_SPM && !SPM_MM*/ +# endif /* defined(SPD_none) && !SPM_MM*/ #endif /* defined(__aarch64__) && !JUNO_AARCH32_EL3_RUNTIME */ /******************************************************************************* diff --git a/include/plat/arm/common/arm_spm_def.h b/include/plat/arm/common/arm_spm_def.h index 16c806b..c43583d 100644 --- a/include/plat/arm/common/arm_spm_def.h +++ b/include/plat/arm/common/arm_spm_def.h @@ -10,31 +10,6 @@ #include /* - * Reserve 4 MiB for binaries of Secure Partitions and Resource Description - * blobs. - */ -#define PLAT_SP_PACKAGE_BASE BL32_BASE -#define PLAT_SP_PACKAGE_SIZE ULL(0x400000) - -#define PLAT_MAP_SP_PACKAGE_MEM_RO MAP_REGION_FLAT( \ - PLAT_SP_PACKAGE_BASE, \ - PLAT_SP_PACKAGE_SIZE, \ - MT_MEMORY | MT_RO | MT_SECURE) -#define PLAT_MAP_SP_PACKAGE_MEM_RW MAP_REGION_FLAT( \ - PLAT_SP_PACKAGE_BASE, \ - PLAT_SP_PACKAGE_SIZE, \ - MT_MEMORY | MT_RW | MT_SECURE) - -/* - * The rest of the memory reserved for BL32 is free for SPM to use it as memory - * pool to allocate memory regions requested in the resource description. - */ -#define PLAT_SPM_HEAP_BASE (PLAT_SP_PACKAGE_BASE + PLAT_SP_PACKAGE_SIZE) -#define PLAT_SPM_HEAP_SIZE (BL32_LIMIT - BL32_BASE - PLAT_SP_PACKAGE_SIZE) - -#if SPM_MM - -/* * If BL31 is placed in DRAM, place the Secure Partition in DRAM right after the * region used by BL31. If BL31 it is placed in SRAM, put the Secure Partition * at the base of DRAM. @@ -121,23 +96,8 @@ /* Total number of memory regions with distinct properties */ #define ARM_SP_IMAGE_NUM_MEM_REGIONS 6 -#endif /* SPM_MM */ - /* Cookies passed to the Secure Partition at boot. Not used by ARM platforms. */ #define PLAT_SPM_COOKIE_0 ULL(0) #define PLAT_SPM_COOKIE_1 ULL(0) -/* - * Max number of elements supported by SPM in this platform. The defines below - * are used to allocate memory at compile time for different arrays in SPM. - */ -#define PLAT_SPM_MAX_PARTITIONS U(2) - -#define PLAT_SPM_MEM_REGIONS_MAX U(80) -#define PLAT_SPM_NOTIFICATIONS_MAX U(30) -#define PLAT_SPM_SERVICES_MAX U(30) - -#define PLAT_SPCI_HANDLES_MAX_NUM U(20) -#define PLAT_SPM_RESPONSES_MAX U(30) - #endif /* ARM_SPM_DEF_H */ diff --git a/include/services/sp_res_desc.h b/include/services/sp_res_desc.h deleted file mode 100644 index b8be72e..0000000 --- a/include/services/sp_res_desc.h +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2018, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SPM_RES_DESC_H -#define SPM_RES_DESC_H - -#include - -#include - -/******************************************************************************* - * Attribute Section - ******************************************************************************/ - -struct sp_rd_sect_attribute { - /* - * Version of the resource description. - */ - uint16_t version; - - /* - * Type of the Secure Partition: - * - bit[0]: SP Type - * - b'0: UP SP - * - b'1: MP SP - * If UP SP: - * - bit[1]: Type of UP SP - * - b'0: Migratable UP SP - * - b'1: Pinned UP SP - */ - uint16_t sp_type; - - /* - * If this is a Pinned UP SP, PE on which the Pinned UP SP will run. - */ - uint32_t pe_mpidr; - - /* - * Run-Time Exception Level: - * - 0: SEL0 SP - * - 1: SEL1 SP - */ - uint8_t runtime_el; - - /* - * Type of Execution: - * - 0: Init-time only - * - 1: Run-time Execution - */ - uint8_t exec_type; - - /* - * Expected behavior upon failure: - * - 0: Restartable - * - 1: One-Shot - */ - uint8_t panic_policy; - - /* - * Translation Granule to use in the SP translation regime: - * - 0: 4KB - * - 1: 16KB - * - 2: 64KB - */ - uint8_t xlat_granule; - - /* - * Size of the SP binary in bytes. - */ - uint32_t binary_size; - - /* - * - If SP is NOT PIE: - * - VA Address where the SP expects to be loaded. - * - If SP is PIE: - * - Ignored. - */ - uint64_t load_address; - - /* - * Initial execution address. This is a VA as the SP sees it. - */ - uint64_t entrypoint; -}; - -/******************************************************************************* - * Memory Region Section - ******************************************************************************/ - -struct sp_rd_sect_mem_region { - /* - * Name of a Memory region, including null terminator. Reserved names: - * - "Client Shared Memory Region": - * Memory region where memory shared by clients shall be mapped. - * - "Queue Memory Region": - * Memory region shared with SPM for SP queue management. - */ - char name[RD_MEM_REGION_NAME_LEN]; - - /* - * Memory Attributes: - * - bits[3:0]: Type of memory - * - 0: Device - * - 1: Code - * - 2: Data - * - 3: BSS - * - 4: Read-only Data - * - 5: SPM-to-SP Shared Memory Region - * - 6: Client Shared Memory Region - * - 7: Miscellaneous - * - If memory is { SPM-to-SP shared Memory, Client Shared Memory, - * Miscellaneous } - * - bits[4]: Position Independent - * - b'0: Position Dependent - * - b'1: Position Independent - */ - uint32_t attr; - - /* - * Base address of the memory region. - */ - uint64_t base; - - /* - * Size of the memory region. - */ - uint64_t size; - - /* - * Pointer to next memory region (or NULL if this is the last one). - */ - struct sp_rd_sect_mem_region *next; -}; - -/******************************************************************************* - * Notification Section - ******************************************************************************/ - -struct sp_rd_sect_notification { - /* - * Notification attributes: - * - bit[31]: Notification Type - * - b'0: Platform Notification - * - b'1: Interrupt - * If Notification Type == Platform Notification - * - bits[15:0]: Implementation-defined Notification ID - * If Notification Type == Interrupt - * - bits[15:0]: IRQ number - * - bits[23:16]: Interrupt Priority - * - bit[24]: Trigger Type - * - b'0: Edge Triggered - * - b'1: Level Triggered - * - bit[25]: Trigger Level - * - b'0: Falling or Low - * - b'1: Rising or High - */ - uint32_t attr; - - /* - * Processing Element. - * If Notification Type == Interrupt && IRQ number is { SGI, LPI } - * - PE ID to which IRQ will be forwarded - */ - uint32_t pe; - - /* - * Pointer to next notification (or NULL if this is the last one). - */ - struct sp_rd_sect_notification *next; -}; - -/******************************************************************************* - * Service Description Section - ******************************************************************************/ - -struct sp_rd_sect_service { - /* - * Service identifier. - */ - uint32_t uuid[4]; - - /* - * Accessibility Options: - * - bit[0]: Accessibility by secure-world clients - * - b'0: Not Accessible - * - b'1: Accessible - * - bit[1]: Accessible by EL3 - * - b'0: Not Accessible - * - b'1: Accessible - * - bit[2]: Accessible by normal-world clients - * - b'0: Not Accessible - * - b'1: Accessible - */ - uint8_t accessibility; - - /* - * Request type supported: - * - bit[0]: Blocking request - * - b'0: Not Enable - * - b'1: Enable - * - bit[1]: Non-blocking request - * - b'0: Not Enable - * - b'1: Enable - */ - uint8_t request_type; - - /* - * Maximum number of client connections that the service can support. - */ - uint16_t connection_quota; - - /* - * If the service requires secure world memory to be shared with its - * clients: - * - Maximum amount of secure world memory in bytes to reserve from the - * secure world memory pool for the service. - */ - uint32_t secure_mem_size; - - /* - * Interrupt number used to notify the SP for the service. - * - Should also be enabled in the Notification Section. - */ - uint32_t interrupt_num; - - /* - * Pointer to next service (or NULL if this is the last one). - */ - struct sp_rd_sect_service *next; -}; - -/******************************************************************************* - * Complete resource description struct - ******************************************************************************/ - -struct sp_res_desc { - - /* Attribute Section */ - struct sp_rd_sect_attribute attribute; - - /* System Resource Section */ - struct sp_rd_sect_mem_region *mem_region; - - struct sp_rd_sect_notification *notification; - - /* Service Section */ - struct sp_rd_sect_service *service; -}; - -#endif /* SPM_RES_DESC_H */ diff --git a/include/services/sp_res_desc_def.h b/include/services/sp_res_desc_def.h deleted file mode 100644 index 5a3c50d..0000000 --- a/include/services/sp_res_desc_def.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (c) 2018, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SPM_RES_DESC_DEFS_H -#define SPM_RES_DESC_DEFS_H - -#include - -/******************************************************************************* - * Attribute Section - ******************************************************************************/ - -#define RD_ATTR_TYPE_UP_MIGRATABLE U(0) -#define RD_ATTR_TYPE_UP_PINNED U(2) -#define RD_ATTR_TYPE_MP U(1) - -#define RD_ATTR_RUNTIME_SEL0 U(0) -#define RD_ATTR_RUNTIME_SEL1 U(1) - -#define RD_ATTR_INIT_ONLY U(0) -#define RD_ATTR_RUNTIME U(1) - -#define RD_ATTR_PANIC_RESTART U(0) -#define RD_ATTR_PANIC_ONESHOT U(1) - -#define RD_ATTR_XLAT_GRANULE_4KB U(0) -#define RD_ATTR_XLAT_GRANULE_16KB U(1) -#define RD_ATTR_XLAT_GRANULE_64KB U(2) - -/******************************************************************************* - * Memory Region Section - ******************************************************************************/ - -#define RD_MEM_REGION_NAME_LEN U(32) - -#define RD_MEM_DEVICE U(0) -#define RD_MEM_NORMAL_CODE U(1) -#define RD_MEM_NORMAL_DATA U(2) -#define RD_MEM_NORMAL_BSS U(3) -#define RD_MEM_NORMAL_RODATA U(4) -#define RD_MEM_NORMAL_SPM_SP_SHARED_MEM U(5) -#define RD_MEM_NORMAL_CLIENT_SHARED_MEM U(6) -#define RD_MEM_NORMAL_MISCELLANEOUS U(7) - -#define RD_MEM_MASK U(15) - -#define RD_MEM_IS_PIE (U(1) << 4) - -/******************************************************************************* - * Notification Section - ******************************************************************************/ - -#define RD_NOTIF_TYPE_PLATFORM (U(0) << 31) -#define RD_NOTIF_TYPE_INTERRUPT (U(1) << 31) - -#define RD_NOTIF_PLAT_ID_MASK U(0xFFFF) -#define RD_NOTIF_PLAT_ID_SHIFT U(0) - -#define RD_NOTIF_PLATFORM(id) \ - (RD_NOTIF_TYPE_PLATFORM \ - | (((id) & RD_NOTIF_PLAT_ID_MASK) << RD_NOTIF_PLAT_ID_SHIFT)) - -#define RD_NOTIF_IRQ_NUM_MASK U(0xFFFF) -#define RD_NOTIF_IRQ_NUM_SHIFT U(0) -#define RD_NOTIF_IRQ_PRIO_MASK U(0xFF) -#define RD_NOTIF_IRQ_PRIO_SHIFT U(16) - -#define RD_NOTIF_IRQ_EDGE_FALLING U(0) -#define RD_NOTIF_IRQ_EDGE_RISING U(2) -#define RD_NOTIF_IRQ_LEVEL_LOW U(1) -#define RD_NOTIF_IRQ_LEVEL_HIGH U(3) -#define RD_NOTIF_IRQ_TRIGGER_SHIFT U(24) - -#define RD_NOTIF_IRQ(num, prio, trig) \ - (RD_NOTIF_TYPE_IRQ \ - | (((num) & RD_NOTIF_IRQ_NUM_MASK) << RD_NOTIF_IRQ_NUM_SHIFT) \ - | (((prio) & RD_NOTIF_IRQ_PRIO_MASK) << RD_NOTIF_IRQ_PRIO_SHIFT) \ - | (((trig) << RD_NOTIF_IRQ_TRIGGER_SHIFT))) - -/******************************************************************************* - * Service Description Section - ******************************************************************************/ - -#define RD_SERV_ACCESS_SECURE (U(1) << 0) -#define RD_SERV_ACCESS_EL3 (U(1) << 1) -#define RD_SERV_ACCESS_NORMAL (U(1) << 2) - -#define RD_SERV_SUPPORT_BLOCKING (U(1) << 0) -#define RD_SERV_SUPPORT_NON_BLOCKING (U(1) << 0) - -#endif /* SPM_RES_DESC_DEFS_H */ diff --git a/include/services/spci_svc.h b/include/services/spci_svc.h deleted file mode 100644 index 1d02bfa..0000000 --- a/include/services/spci_svc.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SPCI_SVC_H -#define SPCI_SVC_H - -#include -#include - -/* 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_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_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 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 error codes. */ - -#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 - -#endif /* SPCI_SVC_H */ diff --git a/include/services/spm_svc.h b/include/services/spm_svc.h index a3723a0..c8dbe5d 100644 --- a/include/services/spm_svc.h +++ b/include/services/spm_svc.h @@ -7,8 +7,6 @@ #ifndef SPM_SVC_H #define SPM_SVC_H -#if SPM_MM - #include #define SPM_VERSION_MAJOR U(0) @@ -61,16 +59,12 @@ #define SPM_DENIED -3 #define SPM_NO_MEMORY -5 -#endif /* SPM_MM */ - #ifndef __ASSEMBLER__ #include int32_t spm_setup(void); -#if SPM_MM - uint64_t spm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, @@ -83,8 +77,6 @@ /* Helper to enter a Secure Partition */ uint64_t spm_sp_call(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3); -#endif /* SPM_MM */ - #endif /* __ASSEMBLER__ */ #endif /* SPM_SVC_H */ diff --git a/include/services/sprt_svc.h b/include/services/sprt_svc.h deleted file mode 100644 index 2421ea2..0000000 --- a/include/services/sprt_svc.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SPRT_SVC_H -#define SPRT_SVC_H - -#include -#include - -/* SPRT_VERSION helpers */ - -#define SPRT_VERSION_MAJOR U(0) -#define SPRT_VERSION_MAJOR_SHIFT 16 -#define SPRT_VERSION_MAJOR_MASK U(0x7FFF) -#define SPRT_VERSION_MINOR U(1) -#define SPRT_VERSION_MINOR_SHIFT 0 -#define SPRT_VERSION_MINOR_MASK U(0xFFFF) -#define SPRT_VERSION_FORM(major, minor) ((((major) & SPRT_VERSION_MAJOR_MASK) \ - << SPRT_VERSION_MAJOR_SHIFT) | \ - ((minor) & SPRT_VERSION_MINOR_MASK)) -#define SPRT_VERSION_COMPILED SPRT_VERSION_FORM(SPRT_VERSION_MAJOR, \ - SPRT_VERSION_MINOR) - -/* SPRT function IDs */ - -#define SPRT_FID_VERSION U(0x0) -#define SPRT_FID_PUT_RESPONSE U(0x1) -#define SPRT_FID_YIELD U(0x5) -#define SPRT_FID_PANIC U(0x7) -#define SPRT_FID_MEMORY_PERM_ATTR_GET U(0xB) -#define SPRT_FID_MEMORY_PERM_ATTR_SET U(0xC) - -#define SPRT_FID_MASK U(0xFF) - -/* Definitions to build the complete SMC ID */ - -#define OEN_SPRT_START U(0x20) -#define OEN_SPRT_END U(0x2F) - -#define SPRT_SMC_64(sprt_fid) ((OEN_SPRT_START << FUNCID_OEN_SHIFT) | \ - (U(1) << 31) | ((sprt_fid) & SPRT_FID_MASK) | \ - (SMC_64 << FUNCID_CC_SHIFT)) -#define SPRT_SMC_32(sprt_fid) ((OEN_SPRT_START << FUNCID_OEN_SHIFT) | \ - (U(1) << 31) | ((sprt_fid) & SPRT_FID_MASK) | \ - (SMC_32 << FUNCID_CC_SHIFT)) - -/* Complete SMC IDs */ - -#define SPRT_VERSION SPRT_SMC_32(SPRT_FID_VERSION) -#define SPRT_PUT_RESPONSE_AARCH64 SPRT_SMC_64(SPRT_FID_PUT_RESPONSE) -#define SPRT_YIELD_AARCH64 SPRT_SMC_64(SPRT_FID_YIELD) -#define SPRT_PANIC_AARCH64 SPRT_SMC_64(SPRT_FID_PANIC) -#define SPRT_MEMORY_PERM_ATTR_GET_AARCH64 SPRT_SMC_64(SPRT_FID_MEMORY_PERM_ATTR_GET) -#define SPRT_MEMORY_PERM_ATTR_SET_AARCH64 SPRT_SMC_64(SPRT_FID_MEMORY_PERM_ATTR_SET) - -/* Defines used by SPRT_MEMORY_PERM_ATTR_{GET,SET}_AARCH64 */ - -#define SPRT_MEMORY_PERM_ATTR_RO U(0) -#define SPRT_MEMORY_PERM_ATTR_RW U(1) -#define SPRT_MEMORY_PERM_ATTR_RO_EXEC U(2) -/* U(3) is reserved */ -#define SPRT_MEMORY_PERM_ATTR_MASK U(3) -#define SPRT_MEMORY_PERM_ATTR_SHIFT 3 - -/* SPRT error codes. */ - -#define SPRT_SUCCESS 0 -#define SPRT_NOT_SUPPORTED -1 -#define SPRT_INVALID_PARAMETER -2 - -#endif /* SPRT_SVC_H */ diff --git a/lib/sprt/sprt_host.c b/lib/sprt/sprt_host.c deleted file mode 100644 index c4d436e..0000000 --- a/lib/sprt/sprt_host.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2018, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include - -#include "sprt_common.h" -#include "sprt_queue.h" - -void sprt_initialize_queues(void *buffer_base, size_t buffer_size) -{ - /* Initialize queue for blocking messages */ - - void *blocking_base = buffer_base; - uint32_t blocking_num = 4U; - size_t blocking_size = SPRT_QUEUE_HEADER_SIZE + - SPRT_QUEUE_ENTRY_MSG_SIZE * blocking_num; - - sprt_queue_init(blocking_base, blocking_num, SPRT_QUEUE_ENTRY_MSG_SIZE); - - /* Initialize queue for non-blocking messages */ - - void *non_blocking_base = (void *)((uintptr_t)blocking_base + blocking_size); - size_t non_blocking_size = buffer_size - blocking_size; - uint32_t non_blocking_num = (non_blocking_size - SPRT_QUEUE_HEADER_SIZE) / - SPRT_QUEUE_ENTRY_MSG_SIZE; - - sprt_queue_init(non_blocking_base, non_blocking_num, SPRT_QUEUE_ENTRY_MSG_SIZE); -} - -int sprt_push_message(void *buffer_base, - const struct sprt_queue_entry_message *message, - int queue_num) -{ - struct sprt_queue *q = buffer_base; - - while (queue_num-- > 0) { - uintptr_t next_addr = (uintptr_t)q + sizeof(struct sprt_queue) + - q->entry_num * q->entry_size; - q = (struct sprt_queue *) next_addr; - } - - return sprt_queue_push(q, message); -} diff --git a/lib/sprt/sprt_host.mk b/lib/sprt/sprt_host.mk deleted file mode 100644 index abcfe5e..0000000 --- a/lib/sprt/sprt_host.mk +++ /dev/null @@ -1,11 +0,0 @@ -# -# Copyright (c) 2018, Arm Limited. All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause -# - -SPRT_LIB_SOURCES := $(addprefix lib/sprt/, \ - sprt_host.c \ - sprt_queue.c) - -SPRT_LIB_INCLUDES := -Iinclude/lib/sprt/ diff --git a/lib/sprt/sprt_queue.c b/lib/sprt/sprt_queue.c deleted file mode 100644 index 2bd4139..0000000 --- a/lib/sprt/sprt_queue.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (c) 2018, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - -#include "sprt_queue.h" - -void sprt_queue_init(void *queue_base, uint32_t entry_num, uint32_t entry_size) -{ - assert(queue_base != NULL); - assert(entry_size > 0U); - assert(entry_num > 0U); - - struct sprt_queue *queue = (struct sprt_queue *)queue_base; - - queue->entry_num = entry_num; - queue->entry_size = entry_size; - queue->idx_write = 0U; - queue->idx_read = 0U; - - memset(queue->data, 0, entry_num * entry_size); -} - -int sprt_queue_is_empty(void *queue_base) -{ - assert(queue_base != NULL); - - struct sprt_queue *queue = (struct sprt_queue *)queue_base; - - return (queue->idx_write == queue->idx_read); -} - -int sprt_queue_is_full(void *queue_base) -{ - assert(queue_base != NULL); - - struct sprt_queue *queue = (struct sprt_queue *)queue_base; - - uint32_t idx_next_write = (queue->idx_write + 1) % queue->entry_num; - - return (idx_next_write == queue->idx_read); -} - -int sprt_queue_push(void *queue_base, const void *entry) -{ - assert(entry != NULL); - assert(queue_base != NULL); - - if (sprt_queue_is_full(queue_base) != 0) { - return -ENOMEM; - } - - struct sprt_queue *queue = (struct sprt_queue *)queue_base; - - uint8_t *dst_entry = &queue->data[queue->entry_size * queue->idx_write]; - - memcpy(dst_entry, entry, queue->entry_size); - - /* - * Make sure that the message data is visible before increasing the - * counter of available messages. - */ - __asm__ volatile("dmb st" ::: "memory"); - - queue->idx_write = (queue->idx_write + 1) % queue->entry_num; - - __asm__ volatile("dmb st" ::: "memory"); - - return 0; -} - -int sprt_queue_pop(void *queue_base, void *entry) -{ - assert(entry != NULL); - assert(queue_base != NULL); - - if (sprt_queue_is_empty(queue_base) != 0) { - return -ENOENT; - } - - struct sprt_queue *queue = (struct sprt_queue *)queue_base; - - uint8_t *src_entry = &queue->data[queue->entry_size * queue->idx_read]; - - memcpy(entry, src_entry, queue->entry_size); - - /* - * Make sure that the message data is visible before increasing the - * counter of read messages. - */ - __asm__ volatile("dmb st" ::: "memory"); - - queue->idx_read = (queue->idx_read + 1) % queue->entry_num; - - __asm__ volatile("dmb st" ::: "memory"); - - return 0; -} diff --git a/lib/sprt/sprt_queue.h b/lib/sprt/sprt_queue.h deleted file mode 100644 index 4ea1bc2..0000000 --- a/lib/sprt/sprt_queue.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2018, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SPRT_QUEUE_H -#define SPRT_QUEUE_H - -#include - -/* Struct that defines a queue. Not to be used directly. */ -struct __attribute__((__packed__)) sprt_queue { - uint32_t entry_num; /* Number of entries */ - uint32_t entry_size; /* Size of an entry */ - uint32_t idx_write; /* Index of first empty entry */ - uint32_t idx_read; /* Index of first entry to read */ - uint8_t data[0]; /* Start of data */ -}; - -#define SPRT_QUEUE_HEADER_SIZE (sizeof(struct sprt_queue)) - -/* - * Initializes a memory region to be used as a queue of the given number of - * entries with the specified size. - */ -void sprt_queue_init(void *queue_base, uint32_t entry_num, uint32_t entry_size); - -/* Returns 1 if the queue is empty, 0 otherwise */ -int sprt_queue_is_empty(void *queue_base); - -/* Returns 1 if the queue is full, 0 otherwise */ -int sprt_queue_is_full(void *queue_base); - -/* - * Pushes a new entry intro the queue. Returns 0 on success, -ENOMEM if the - * queue is full. - */ -int sprt_queue_push(void *queue_base, const void *entry); - -/* - * Pops an entry from the queue. Returns 0 on success, -ENOENT if the queue is - * empty. - */ -int sprt_queue_pop(void *queue_base, void *entry); - -#endif /* SPRT_QUEUE_H */ diff --git a/make_helpers/defaults.mk b/make_helpers/defaults.mk index ac5d959..1e31236 100644 --- a/make_helpers/defaults.mk +++ b/make_helpers/defaults.mk @@ -178,9 +178,6 @@ # SPD choice SPD := none -# Enable the SPCI-based Secure Partition Manager implementation -ENABLE_SPM := 0 - # Enable the Management Mode (MM)-based Secure Partition Manager implementation SPM_MM := 0 diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index fca4d01..0b1b321 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -99,9 +99,6 @@ #if SPM_MM ARM_SP_IMAGE_MMAP, #endif -#if ENABLE_SPM - PLAT_MAP_SP_PACKAGE_MEM_RW, -#endif #if ARM_BL31_IN_DRAM ARM_MAP_BL31_SEC_DRAM, #endif @@ -130,9 +127,6 @@ #if SPM_MM ARM_SPM_BUF_EL3_MMAP, #endif -#if ENABLE_SPM - PLAT_MAP_SP_PACKAGE_MEM_RO, -#endif {0} }; diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 1a251b8..fa855cf 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -61,7 +61,7 @@ * plat_arm_mmap array defined for each BL stage. */ #if defined(IMAGE_BL31) -# if ENABLE_SPM || SPM_MM +# if SPM_MM # define PLAT_ARM_MMAP_ENTRIES 9 # define MAX_XLAT_TABLES 9 # define PLAT_SP_IMAGE_MMAP_REGIONS 30 @@ -116,11 +116,7 @@ * calculated using the current BL31 PROGBITS debug size plus the sizes of * BL2 and BL1-RW */ -#if ENABLE_SPM -#define PLAT_ARM_MAX_BL31_SIZE UL(0x60000) -#else #define PLAT_ARM_MAX_BL31_SIZE UL(0x3B000) -#endif #ifndef __aarch64__ /* diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 446969c..55ad1c7 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -281,9 +281,6 @@ ifeq (${RESET_TO_BL31},1) BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 endif - ifeq (${ENABLE_SPM},1) - BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 - endif ifeq (${SPD},trusty) BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 endif diff --git a/plat/arm/common/aarch64/arm_ehf.c b/plat/arm/common/aarch64/arm_ehf.c index 5144afc..69ebd79 100644 --- a/plat/arm/common/aarch64/arm_ehf.c +++ b/plat/arm/common/aarch64/arm_ehf.c @@ -24,7 +24,7 @@ /* Normal priority SDEI */ EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_NORMAL_PRI), #endif -#if ENABLE_SPM || SPM_MM +#if SPM_MM EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SP_PRI), #endif }; diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index a60e349..9d4f05e 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -248,14 +248,6 @@ lib/extensions/pauth/pauth_helpers.S endif -# SPM uses libfdt in Arm platforms -ifeq (${ENABLE_SPM},1) -BL31_SOURCES += common/fdt_wrappers.c \ - plat/common/plat_spm_rd.c \ - plat/common/plat_spm_sp.c \ - ${LIBFDT_SRCS} -endif - ifneq (${TRUSTED_BOARD_BOOT},0) # Include common TBB sources diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h index a42c759..e214573 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -28,7 +28,7 @@ * plat_arm_mmap array defined for each BL stage. */ #if defined(IMAGE_BL31) -# if ENABLE_SPM || SPM_MM +# if SPM_MM # define PLAT_ARM_MMAP_ENTRIES 9 # define MAX_XLAT_TABLES 7 # define PLAT_SP_IMAGE_MMAP_REGIONS 7 @@ -101,7 +101,7 @@ #elif defined(IMAGE_BL2U) # define PLATFORM_STACK_SIZE 0x400 #elif defined(IMAGE_BL31) -# if ENABLE_SPM || SPM_MM +# if SPM_MM # define PLATFORM_STACK_SIZE 0x500 # else # define PLATFORM_STACK_SIZE 0x400 diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk index b736b0b..7160111 100644 --- a/plat/arm/css/sgi/sgi-common.mk +++ b/plat/arm/css/sgi/sgi-common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -10,8 +10,6 @@ RAS_EXTENSION := 0 -ENABLE_SPM := 0 - SDEI_SUPPORT := 0 EL3_EXCEPTION_HANDLING := 0 diff --git a/plat/common/plat_spm_rd.c b/plat/common/plat_spm_rd.c deleted file mode 100644 index ebd3e6d..0000000 --- a/plat/common/plat_spm_rd.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include - -/******************************************************************************* - * Resource pool - ******************************************************************************/ -static struct sp_rd_sect_mem_region rd_mem_regions[PLAT_SPM_MEM_REGIONS_MAX]; -static OBJECT_POOL_ARRAY(rd_mem_regions_pool, rd_mem_regions); - -static struct sp_rd_sect_notification rd_notifs[PLAT_SPM_NOTIFICATIONS_MAX]; -static OBJECT_POOL_ARRAY(rd_notifs_pool, rd_notifs); - -static struct sp_rd_sect_service rd_services[PLAT_SPM_SERVICES_MAX]; -static OBJECT_POOL_ARRAY(rd_services_pool, rd_services); - -/******************************************************************************* - * Attribute section handler - ******************************************************************************/ -static void rd_parse_attribute(struct sp_rd_sect_attribute *attr, - const void *fdt, int node) -{ - int rc = 0; - - /* The minimum size that can be read from the DTB is 32-bit. */ - uint32_t version, sp_type, runtime_el, exec_type; - uint32_t panic_policy, xlat_granule; - - rc |= fdtw_read_cells(fdt, node, "version", 1, &version); - - if (version != 1) { - ERROR("Unsupported resource description version: 0x%x\n", - version); - panic(); - } - - rc |= fdtw_read_cells(fdt, node, "sp_type", 1, &sp_type); - rc |= fdtw_read_cells(fdt, node, "pe_mpidr", 1, &attr->pe_mpidr); - rc |= fdtw_read_cells(fdt, node, "runtime_el", 1, &runtime_el); - rc |= fdtw_read_cells(fdt, node, "exec_type", 1, &exec_type); - rc |= fdtw_read_cells(fdt, node, "panic_policy", 1, &panic_policy); - rc |= fdtw_read_cells(fdt, node, "xlat_granule", 1, &xlat_granule); - rc |= fdtw_read_cells(fdt, node, "binary_size", 1, &attr->binary_size); - rc |= fdtw_read_cells(fdt, node, "load_address", 2, &attr->load_address); - rc |= fdtw_read_cells(fdt, node, "entrypoint", 2, &attr->entrypoint); - - attr->version = version; - attr->sp_type = sp_type; - attr->runtime_el = runtime_el; - attr->exec_type = exec_type; - attr->panic_policy = panic_policy; - attr->xlat_granule = xlat_granule; - - VERBOSE(" Attribute Section:\n"); - VERBOSE(" version: 0x%x\n", version); - VERBOSE(" sp_type: 0x%x\n", sp_type); - VERBOSE(" pe_mpidr: 0x%x\n", attr->pe_mpidr); - VERBOSE(" runtime_el: 0x%x\n", runtime_el); - VERBOSE(" exec_type: 0x%x\n", exec_type); - VERBOSE(" panic_policy: 0x%x\n", panic_policy); - VERBOSE(" xlat_granule: 0x%x\n", xlat_granule); - VERBOSE(" binary_size: 0x%x\n", attr->binary_size); - VERBOSE(" load_address: 0x%llx\n", attr->load_address); - VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint); - - if (rc) { - ERROR("Failed to read attribute node elements.\n"); - panic(); - } -} - -/******************************************************************************* - * Memory regions section handlers - ******************************************************************************/ -static void rd_parse_memory_region(struct sp_rd_sect_mem_region *rdmem, - const void *fdt, int node) -{ - int rc = 0; - char name[RD_MEM_REGION_NAME_LEN]; - - rc |= fdtw_read_string(fdt, node, "str", (char *)&name, sizeof(name)); - rc |= fdtw_read_cells(fdt, node, "attr", 1, &rdmem->attr); - rc |= fdtw_read_cells(fdt, node, "base", 2, &rdmem->base); - rc |= fdtw_read_cells(fdt, node, "size", 2, &rdmem->size); - - size_t len = strlcpy(rdmem->name, name, RD_MEM_REGION_NAME_LEN); - - if (len >= RD_MEM_REGION_NAME_LEN) { - WARN("Memory region name truncated: '%s'\n", name); - } - - VERBOSE(" Memory Region:\n"); - VERBOSE(" name: '%s'\n", rdmem->name); - VERBOSE(" attr: 0x%x\n", rdmem->attr); - VERBOSE(" base: 0x%llx\n", rdmem->base); - VERBOSE(" size: 0x%llx\n", rdmem->size); - - if (rc) { - ERROR("Failed to read mem_region node elements.\n"); - panic(); - } -} - -static void rd_parse_memory_regions(struct sp_res_desc *rd, const void *fdt, - int node) -{ - int child; - struct sp_rd_sect_mem_region *rdmem, *old_rdmem; - - fdt_for_each_subnode(child, fdt, node) { - rdmem = pool_alloc(&rd_mem_regions_pool); - - /* Add element to the start of the list */ - old_rdmem = rd->mem_region; - rd->mem_region = rdmem; - rdmem->next = old_rdmem; - - rd_parse_memory_region(rdmem, fdt, child); - } - - if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) { - ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node); - panic(); - } -} - -/******************************************************************************* - * Notifications section handlers - ******************************************************************************/ -static void rd_parse_notification(struct sp_rd_sect_notification *rdnot, - const void *fdt, int node) -{ - int rc = 0; - - rc |= fdtw_read_cells(fdt, node, "attr", 1, &rdnot->attr); - rc |= fdtw_read_cells(fdt, node, "pe", 1, &rdnot->pe); - - VERBOSE(" Notification:\n"); - VERBOSE(" attr: 0x%x\n", rdnot->attr); - VERBOSE(" pe: 0x%x\n", rdnot->pe); - - if (rc) { - ERROR("Failed to read notification node elements.\n"); - panic(); - } -} - -static void rd_parse_notifications(struct sp_res_desc *rd, const void *fdt, int node) -{ - int child; - struct sp_rd_sect_notification *rdnot, *old_rdnot; - - fdt_for_each_subnode(child, fdt, node) { - rdnot = pool_alloc(&rd_notifs_pool); - - /* Add element to the start of the list */ - old_rdnot = rd->notification; - rd->notification = rdnot; - rdnot->next = old_rdnot; - - rd_parse_notification(rdnot, fdt, child); - } - - if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) { - ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, child); - panic(); - } -} - -/******************************************************************************* - * Services section handlers - ******************************************************************************/ -static void rd_parse_service(struct sp_rd_sect_service *rdsvc, const void *fdt, - int node) -{ - int rc = 0; - - /* The minimum size that can be read from the DTB is 32-bit. */ - uint32_t accessibility, request_type, connection_quota; - - rc |= fdtw_read_array(fdt, node, "uuid", 4, &rdsvc->uuid); - rc |= fdtw_read_cells(fdt, node, "accessibility", 1, &accessibility); - rc |= fdtw_read_cells(fdt, node, "request_type", 1, &request_type); - rc |= fdtw_read_cells(fdt, node, "connection_quota", 1, &connection_quota); - rc |= fdtw_read_cells(fdt, node, "sec_mem_size", 1, &rdsvc->secure_mem_size); - rc |= fdtw_read_cells(fdt, node, "interrupt_num", 1, &rdsvc->interrupt_num); - - rdsvc->accessibility = accessibility; - rdsvc->request_type = request_type; - rdsvc->connection_quota = connection_quota; - - VERBOSE(" Service:\n"); - VERBOSE(" uuid: 0x%08x 0x%08x 0x%08x 0x%08x\n", rdsvc->uuid[0], - rdsvc->uuid[1], rdsvc->uuid[2], rdsvc->uuid[3]); - VERBOSE(" accessibility: 0x%x\n", accessibility); - VERBOSE(" request_type: 0x%x\n", request_type); - VERBOSE(" connection_quota: 0x%x\n", connection_quota); - VERBOSE(" secure_memory_size: 0x%x\n", rdsvc->secure_mem_size); - VERBOSE(" interrupt_num: 0x%x\n", rdsvc->interrupt_num); - - if (rc) { - ERROR("Failed to read attribute node elements.\n"); - panic(); - } -} - -static void rd_parse_services(struct sp_res_desc *rd, const void *fdt, int node) -{ - int child; - struct sp_rd_sect_service *rdsvc, *old_rdsvc; - - fdt_for_each_subnode(child, fdt, node) { - rdsvc = pool_alloc(&rd_services_pool); - - /* Add element to the start of the list */ - old_rdsvc = rd->service; - rd->service = rdsvc; - rdsvc->next = old_rdsvc; - - rd_parse_service(rdsvc, fdt, child); - } - - if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) { - ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node); - panic(); - } -} - -/******************************************************************************* - * Root node handler - ******************************************************************************/ -static void rd_parse_root(struct sp_res_desc *rd, const void *fdt, int root) -{ - int node; - char *str; - - str = "attribute"; - node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str)); - if (node < 0) { - ERROR("Root node doesn't contain subnode '%s'\n", str); - panic(); - } else { - rd_parse_attribute(&rd->attribute, fdt, node); - } - - str = "memory_regions"; - node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str)); - if (node < 0) { - ERROR("Root node doesn't contain subnode '%s'\n", str); - panic(); - } else { - rd_parse_memory_regions(rd, fdt, node); - } - - str = "notifications"; - node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str)); - if (node < 0) { - WARN("Root node doesn't contain subnode '%s'\n", str); - } else { - rd_parse_notifications(rd, fdt, node); - } - - str = "services"; - node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str)); - if (node < 0) { - WARN("Root node doesn't contain subnode '%s'\n", str); - } else { - rd_parse_services(rd, fdt, node); - } -} - -/******************************************************************************* - * Platform handler to load resource descriptor blobs into the active Secure - * Partition context. - ******************************************************************************/ -int plat_spm_sp_rd_load(struct sp_res_desc *rd, const void *ptr, size_t size) -{ - int rc; - int root_node; - - assert(rd != NULL); - assert(ptr != NULL); - - INFO("Reading RD blob at address %p\n", ptr); - - rc = fdt_check_header(ptr); - if (rc != 0) { - ERROR("Wrong format for resource descriptor blob (%d).\n", rc); - return -1; - } - - root_node = fdt_node_offset_by_compatible(ptr, -1, "arm,sp_rd"); - if (root_node < 0) { - ERROR("Unrecognized resource descriptor blob (%d)\n", rc); - return -1; - } - - rd_parse_root(rd, ptr, root_node); - - return 0; -} diff --git a/plat/common/plat_spm_sp.c b/plat/common/plat_spm_sp.c deleted file mode 100644 index bc3d6a0..0000000 --- a/plat/common/plat_spm_sp.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include - -#include - -#include -#include -#include - -static unsigned int sp_next; - -/******************************************************************************* - * Platform handler get the address of a Secure Partition and its resource - * description blob. It iterates through all SPs detected by the platform. If - * there is information for another SP, it returns 0. If there are no more SPs, - * it returns -1. - ******************************************************************************/ -int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size, - void **rd_base, size_t *rd_size) -{ - assert((sp_base != NULL) && (sp_size != NULL)); - assert((rd_base != NULL) && (rd_base != NULL)); - - const uint64_t *pkg_base = (uint64_t *)PLAT_SP_PACKAGE_BASE; - - struct sp_pkg_header *pkg_header = (struct sp_pkg_header *)pkg_base; - - if (sp_next == 0) { - if (pkg_header->version != 0x1) { - ERROR("SP package has an unsupported version 0x%llx\n", - pkg_header->version); - panic(); - } - } - - if (sp_next >= pkg_header->number_of_sp) { - /* No more partitions in the package */ - return -1; - } - - const struct sp_pkg_entry *entry_list = - (const struct sp_pkg_entry *)((uintptr_t)pkg_base - + sizeof(struct sp_pkg_header)); - - const struct sp_pkg_entry *entry = &(entry_list[sp_next]); - - uint64_t sp_offset = entry->sp_offset; - uint64_t rd_offset = entry->rd_offset; - - uintptr_t pkg_sp_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + sp_offset); - uintptr_t pkg_rd_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + rd_offset); - - uint64_t pkg_sp_size = entry->sp_size; - uint64_t pkg_rd_size = entry->rd_size; - - uintptr_t pkg_end = (uintptr_t)PLAT_SP_PACKAGE_BASE - + (uintptr_t)PLAT_SP_PACKAGE_SIZE - 1U; - - /* - * Check for overflows. The package header isn't trusted, so assert() - * can't be used here. - */ - - uintptr_t pkg_sp_end = pkg_sp_base + pkg_sp_size - 1U; - uintptr_t pkg_rd_end = pkg_rd_base + pkg_rd_size - 1U; - - if ((pkg_sp_end > pkg_end) || (pkg_sp_end < pkg_sp_base)) { - ERROR("Invalid Secure Partition size (0x%llx)\n", pkg_sp_size); - panic(); - } - - if ((pkg_rd_end > pkg_end) || (pkg_rd_end < pkg_rd_base)) { - ERROR("Invalid Resource Description blob size (0x%llx)\n", - pkg_rd_size); - panic(); - } - - /* Return location of the binaries. */ - - *sp_base = (void *)pkg_sp_base; - *sp_size = pkg_sp_size; - *rd_base = (void *)pkg_rd_base; - *rd_size = pkg_rd_size; - - sp_next++; - - return 0; -} diff --git a/plat/nvidia/tegra/scat/bl31.scat b/plat/nvidia/tegra/scat/bl31.scat index ff7719a..2d6d2b3 100644 --- a/plat/nvidia/tegra/scat/bl31.scat +++ b/plat/nvidia/tegra/scat/bl31.scat @@ -95,7 +95,7 @@ /* cpu_ops must always be defined */ ScatterAssert(ImageLength(__CPU_OPS__) > 0) -#if ENABLE_SPM || SPM_MM +#if SPM_MM LR_SPM +0 { /* diff --git a/services/std_svc/spm/README.rst b/services/std_svc/spm/README.rst deleted file mode 100644 index 63406a3..0000000 --- a/services/std_svc/spm/README.rst +++ /dev/null @@ -1,3 +0,0 @@ -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 -change as it evolves. diff --git a/services/std_svc/spm/aarch64/spm_helpers.S b/services/std_svc/spm/aarch64/spm_helpers.S deleted file mode 100644 index aa35811..0000000 --- a/services/std_svc/spm/aarch64/spm_helpers.S +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include "../spm_private.h" - - .global spm_secure_partition_enter - .global spm_secure_partition_exit - - /* --------------------------------------------------------------------- - * This function is called with SP_EL0 as stack. Here we stash our EL3 - * callee-saved registers on to the stack as a part of saving the C - * runtime and enter the secure payload. - * 'x0' contains a pointer to the memory where the address of the C - * runtime context is to be saved. - * --------------------------------------------------------------------- - */ -func spm_secure_partition_enter - /* Make space for the registers that we're going to save */ - mov x3, sp - str x3, [x0, #0] - sub sp, sp, #SP_C_RT_CTX_SIZE - - /* Save callee-saved registers on to the stack */ - stp x19, x20, [sp, #SP_C_RT_CTX_X19] - stp x21, x22, [sp, #SP_C_RT_CTX_X21] - stp x23, x24, [sp, #SP_C_RT_CTX_X23] - stp x25, x26, [sp, #SP_C_RT_CTX_X25] - stp x27, x28, [sp, #SP_C_RT_CTX_X27] - stp x29, x30, [sp, #SP_C_RT_CTX_X29] - - /* --------------------------------------------------------------------- - * Everything is setup now. el3_exit() will use the secure context to - * restore to the general purpose and EL3 system registers to ERET - * into the secure payload. - * --------------------------------------------------------------------- - */ - b el3_exit -endfunc spm_secure_partition_enter - - /* --------------------------------------------------------------------- - * This function is called with 'x0' pointing to a C runtime context - * saved in spm_secure_partition_enter(). - * It restores the saved registers and jumps to that runtime with 'x0' - * as the new SP register. This destroys the C runtime context that had - * been built on the stack below the saved context by the caller. Later - * the second parameter 'x1' is passed as a return value to the caller. - * --------------------------------------------------------------------- - */ -func spm_secure_partition_exit - /* Restore the previous stack */ - mov sp, x0 - - /* Restore callee-saved registers on to the stack */ - ldp x19, x20, [x0, #(SP_C_RT_CTX_X19 - SP_C_RT_CTX_SIZE)] - ldp x21, x22, [x0, #(SP_C_RT_CTX_X21 - SP_C_RT_CTX_SIZE)] - ldp x23, x24, [x0, #(SP_C_RT_CTX_X23 - SP_C_RT_CTX_SIZE)] - ldp x25, x26, [x0, #(SP_C_RT_CTX_X25 - SP_C_RT_CTX_SIZE)] - ldp x27, x28, [x0, #(SP_C_RT_CTX_X27 - SP_C_RT_CTX_SIZE)] - ldp x29, x30, [x0, #(SP_C_RT_CTX_X29 - SP_C_RT_CTX_SIZE)] - - /* --------------------------------------------------------------------- - * This should take us back to the instruction after the call to the - * last spm_secure_partition_enter().* Place the second parameter to x0 - * so that the caller will see it as a return value from the original - * entry call. - * --------------------------------------------------------------------- - */ - mov x0, x1 - ret -endfunc spm_secure_partition_exit diff --git a/services/std_svc/spm/aarch64/spm_shim_exceptions.S b/services/std_svc/spm/aarch64/spm_shim_exceptions.S deleted file mode 100644 index dab6150..0000000 --- a/services/std_svc/spm/aarch64/spm_shim_exceptions.S +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - -/* ----------------------------------------------------------------------------- - * Very simple stackless exception handlers used by the spm shim layer. - * ----------------------------------------------------------------------------- - */ - .globl spm_shim_exceptions_ptr - -vector_base spm_shim_exceptions_ptr, .spm_shim_exceptions - - /* ----------------------------------------------------- - * Current EL with SP0 : 0x0 - 0x200 - * ----------------------------------------------------- - */ -vector_entry SynchronousExceptionSP0, .spm_shim_exceptions - b . -end_vector_entry SynchronousExceptionSP0 - -vector_entry IrqSP0, .spm_shim_exceptions - b . -end_vector_entry IrqSP0 - -vector_entry FiqSP0, .spm_shim_exceptions - b . -end_vector_entry FiqSP0 - -vector_entry SErrorSP0, .spm_shim_exceptions - b . -end_vector_entry SErrorSP0 - - /* ----------------------------------------------------- - * Current EL with SPx: 0x200 - 0x400 - * ----------------------------------------------------- - */ -vector_entry SynchronousExceptionSPx, .spm_shim_exceptions - b . -end_vector_entry SynchronousExceptionSPx - -vector_entry IrqSPx, .spm_shim_exceptions - b . -end_vector_entry IrqSPx - -vector_entry FiqSPx, .spm_shim_exceptions - b . -end_vector_entry FiqSPx - -vector_entry SErrorSPx, .spm_shim_exceptions - b . -end_vector_entry SErrorSPx - - /* ----------------------------------------------------- - * Lower EL using AArch64 : 0x400 - 0x600. No exceptions - * are handled since secure_partition does not implement - * a lower EL - * ----------------------------------------------------- - */ -vector_entry SynchronousExceptionA64, .spm_shim_exceptions - msr tpidr_el1, x30 - mrs x30, esr_el1 - ubfx x30, x30, #ESR_EC_SHIFT, #ESR_EC_LENGTH - - cmp x30, #EC_AARCH64_SVC - b.eq do_smc - - cmp x30, #EC_AARCH32_SVC - b.eq do_smc - - cmp x30, #EC_AARCH64_SYS - b.eq handle_sys_trap - - /* Fail in all the other cases */ - b panic - - /* --------------------------------------------- - * Tell SPM that we are done initialising - * --------------------------------------------- - */ -do_smc: - mrs x30, tpidr_el1 - smc #0 - eret - - /* AArch64 system instructions trap are handled as a panic for now */ -handle_sys_trap: -panic: - b panic -end_vector_entry SynchronousExceptionA64 - -vector_entry IrqA64, .spm_shim_exceptions - b . -end_vector_entry IrqA64 - -vector_entry FiqA64, .spm_shim_exceptions - b . -end_vector_entry FiqA64 - -vector_entry SErrorA64, .spm_shim_exceptions - b . -end_vector_entry SErrorA64 - - /* ----------------------------------------------------- - * Lower EL using AArch32 : 0x600 - 0x800 - * ----------------------------------------------------- - */ -vector_entry SynchronousExceptionA32, .spm_shim_exceptions - b . -end_vector_entry SynchronousExceptionA32 - -vector_entry IrqA32, .spm_shim_exceptions - b . -end_vector_entry IrqA32 - -vector_entry FiqA32, .spm_shim_exceptions - b . -end_vector_entry FiqA32 - -vector_entry SErrorA32, .spm_shim_exceptions - b . -end_vector_entry SErrorA32 diff --git a/services/std_svc/spm/spci.c b/services/std_svc/spm/spci.c deleted file mode 100644 index 2e12a6c..0000000 --- a/services/std_svc/spm/spci.c +++ /dev/null @@ -1,769 +0,0 @@ -/* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "spm_private.h" - -/******************************************************************************* - * Macros to print UUIDs. - ******************************************************************************/ -#define PRINT_UUID_FORMAT "%08x-%08x-%08x-%08x" -#define PRINT_UUID_ARGS(x) x[0], x[1], x[2], x[3] - -/******************************************************************************* - * Array of structs that contains information about all handles of Secure - * Services that are currently open. - ******************************************************************************/ -typedef enum spci_handle_status { - HANDLE_STATUS_CLOSED = 0, - HANDLE_STATUS_OPEN, -} spci_handle_status_t; - -typedef struct spci_handle { - /* 16-bit value used as reference in all SPCI calls */ - uint16_t handle; - - /* Client ID of the client that requested the handle */ - uint16_t client_id; - - /* Current status of the handle */ - spci_handle_status_t status; - - /* - * Context of the Secure Partition that provides the Secure Service - * referenced by this handle. - */ - sp_context_t *sp_ctx; - - /* - * The same handle might be used for multiple requests, keep a reference - * counter of them. - */ - unsigned int num_active_requests; -} spci_handle_t; - -static spci_handle_t spci_handles[PLAT_SPCI_HANDLES_MAX_NUM]; -static spinlock_t spci_handles_lock; - -/* - * Given a handle and a client ID, return the element of the spci_handles - * array that contains the information of the handle. It can only return open - * handles. It returns NULL if it couldn't find the element in the array. - */ -static spci_handle_t *spci_handle_info_get(uint16_t handle, uint16_t client_id) -{ - size_t i; - - for (i = 0; i < ARRAY_SIZE(spci_handles); i++) { - spci_handle_t *h = &(spci_handles[i]); - - /* Only check for open handles */ - if (h->status == HANDLE_STATUS_CLOSED) { - continue; - } - - /* Check if either the handle or the client ID are different */ - if ((h->handle != handle) || (h->client_id != client_id)) { - continue; - } - - return h; - } - - return NULL; -} - -/* - * Returns a unique value for a handle. This function must be called while - * spci_handles_lock is locked. It returns 0 on success, -1 on error. - */ -static int spci_create_handle_value(uint16_t *handle) -{ - /* - * Trivial implementation that relies on the fact that any handle will - * be closed before 2^16 more handles have been opened. - */ - static uint16_t handle_count; - - *handle = handle_count; - - handle_count++; - - return 0; -} - -/******************************************************************************* - * Returns a unique token for a Secure Service request. - ******************************************************************************/ -static uint32_t spci_create_token_value(void) -{ - /* - * Trivial implementation that relies on the fact that any response will - * be read before 2^32 more service requests have been done. - */ - static uint32_t token_count; - - return token_count++; -} - -/******************************************************************************* - * This function looks for a Secure Partition that has a Secure Service - * identified by the given UUID. It returns a handle that the client can use to - * access the service, and an SPCI_*** error code. - ******************************************************************************/ -static uint64_t spci_service_handle_open_poll(void *handle, u_register_t x1, - u_register_t x2, u_register_t x3, u_register_t x4, - u_register_t x5, u_register_t x6, u_register_t x7) -{ - unsigned int i; - sp_context_t *sp_ptr; - uint16_t service_handle; - - /* Bits 31:16 of w7 are reserved (MBZ). */ - assert((x7 & 0xFFFF0000U) == 0); - - uint16_t client_id = x7 & 0x0000FFFFU; - uint32_t uuid[4] = { x1, x2, x3, x4 }; - - /* Get pointer to the Secure Partition that handles this service */ - sp_ptr = spm_sp_get_by_uuid(&uuid); - if (sp_ptr == NULL) { - WARN("SPCI: Service requested by client 0x%04x not found\n", - client_id); - WARN("SPCI: UUID: " PRINT_UUID_FORMAT "\n", - PRINT_UUID_ARGS(uuid)); - - SMC_RET2(handle, SPCI_NOT_PRESENT, 0); - } - - /* Get lock of the array of handles */ - spin_lock(&spci_handles_lock); - - /* - * We need to record the client ID and Secure Partition that correspond - * to this handle. Look for the first free entry in the array. - */ - for (i = 0; i < PLAT_SPCI_HANDLES_MAX_NUM; i++) { - if (spci_handles[i].status == HANDLE_STATUS_CLOSED) { - break; - } - } - - if (i == PLAT_SPCI_HANDLES_MAX_NUM) { - spin_unlock(&spci_handles_lock); - - WARN("SPCI: Can't open more handles. Client 0x%04x\n", - client_id); - WARN("SPCI: UUID: " PRINT_UUID_FORMAT "\n", - PRINT_UUID_ARGS(uuid)); - - SMC_RET2(handle, SPCI_NO_MEMORY, 0); - } - - /* Create new handle value */ - if (spci_create_handle_value(&service_handle) != 0) { - spin_unlock(&spci_handles_lock); - - WARN("SPCI: Can't create a new handle value. Client 0x%04x\n", - client_id); - WARN("SPCI: UUID: " PRINT_UUID_FORMAT "\n", - PRINT_UUID_ARGS(uuid)); - - SMC_RET2(handle, SPCI_NO_MEMORY, 0); - } - - /* Save all information about this handle */ - spci_handles[i].status = HANDLE_STATUS_OPEN; - spci_handles[i].client_id = client_id; - spci_handles[i].handle = service_handle; - spci_handles[i].num_active_requests = 0U; - spci_handles[i].sp_ctx = sp_ptr; - - /* Release lock of the array of handles */ - spin_unlock(&spci_handles_lock); - - VERBOSE("SPCI: Service handle request by client 0x%04x: 0x%04x\n", - client_id, service_handle); - VERBOSE("SPCI: UUID: " PRINT_UUID_FORMAT "\n", PRINT_UUID_ARGS(uuid)); - - /* The handle is returned in the top 16 bits of x1 */ - SMC_RET2(handle, SPCI_SUCCESS, ((uint32_t)service_handle) << 16); -} - -/******************************************************************************* - * This function closes a handle that a specific client uses to access a Secure - * Service. It returns a SPCI_*** error code. - ******************************************************************************/ -static uint64_t spci_service_handle_close(void *handle, u_register_t x1) -{ - spci_handle_t *handle_info; - uint16_t client_id = x1 & 0x0000FFFFU; - uint16_t service_handle = (x1 >> 16) & 0x0000FFFFU; - - spin_lock(&spci_handles_lock); - - handle_info = spci_handle_info_get(service_handle, client_id); - - if (handle_info == NULL) { - spin_unlock(&spci_handles_lock); - - WARN("SPCI: Tried to close invalid handle 0x%04x by client 0x%04x\n", - service_handle, client_id); - - SMC_RET1(handle, SPCI_INVALID_PARAMETER); - } - - if (handle_info->status != HANDLE_STATUS_OPEN) { - spin_unlock(&spci_handles_lock); - - WARN("SPCI: Tried to close handle 0x%04x by client 0x%04x in status %d\n", - service_handle, client_id, handle_info->status); - - SMC_RET1(handle, SPCI_INVALID_PARAMETER); - } - - if (handle_info->num_active_requests != 0U) { - spin_unlock(&spci_handles_lock); - - /* A handle can't be closed if there are requests left */ - WARN("SPCI: Tried to close handle 0x%04x by client 0x%04x with %d requests left\n", - service_handle, client_id, - handle_info->num_active_requests); - - SMC_RET1(handle, SPCI_BUSY); - } - - memset(handle_info, 0, sizeof(spci_handle_t)); - - handle_info->status = HANDLE_STATUS_CLOSED; - - spin_unlock(&spci_handles_lock); - - VERBOSE("SPCI: Closed handle 0x%04x by client 0x%04x.\n", - service_handle, client_id); - - SMC_RET1(handle, SPCI_SUCCESS); -} - -/******************************************************************************* - * This function requests a Secure Service from a given handle and client ID. - ******************************************************************************/ -static uint64_t spci_service_request_blocking(void *handle, - uint32_t smc_fid, u_register_t x1, u_register_t x2, - u_register_t x3, u_register_t x4, u_register_t x5, - u_register_t x6, u_register_t x7) -{ - spci_handle_t *handle_info; - sp_context_t *sp_ctx; - cpu_context_t *cpu_ctx; - uint32_t rx0; - u_register_t rx1, rx2, rx3; - uint16_t request_handle, client_id; - - /* Get handle array lock */ - spin_lock(&spci_handles_lock); - - /* Get pointer to struct of this open handle and client ID. */ - request_handle = (x7 >> 16U) & 0x0000FFFFU; - client_id = x7 & 0x0000FFFFU; - - handle_info = spci_handle_info_get(request_handle, client_id); - if (handle_info == NULL) { - spin_unlock(&spci_handles_lock); - - WARN("SPCI_SERVICE_TUN_REQUEST_BLOCKING: Not found.\n"); - WARN(" Handle 0x%04x. Client ID 0x%04x\n", request_handle, - client_id); - - SMC_RET1(handle, SPCI_BUSY); - } - - /* Get pointer to the Secure Partition that handles the service */ - sp_ctx = handle_info->sp_ctx; - assert(sp_ctx != NULL); - cpu_ctx = &(sp_ctx->cpu_ctx); - - /* Blocking requests are only allowed if the queue is empty */ - if (handle_info->num_active_requests > 0) { - spin_unlock(&spci_handles_lock); - - SMC_RET1(handle, SPCI_BUSY); - } - - if (spm_sp_request_increase_if_zero(sp_ctx) == -1) { - spin_unlock(&spci_handles_lock); - - SMC_RET1(handle, SPCI_BUSY); - } - - /* Prevent this handle from being closed */ - handle_info->num_active_requests += 1; - - /* Release handle lock */ - spin_unlock(&spci_handles_lock); - - /* Save the Normal world context */ - cm_el1_sysregs_context_save(NON_SECURE); - - /* Wait until the Secure Partition is idle and set it to busy. */ - sp_state_wait_switch(sp_ctx, SP_STATE_IDLE, SP_STATE_BUSY); - - /* Pass arguments to the Secure Partition */ - struct sprt_queue_entry_message message = { - .type = SPRT_MSG_TYPE_SERVICE_TUN_REQUEST, - .client_id = client_id, - .service_handle = request_handle, - .session_id = x6, - .token = 0, /* No token needed for blocking requests */ - .args = {smc_fid, x1, x2, x3, x4, x5} - }; - - spin_lock(&(sp_ctx->spm_sp_buffer_lock)); - int rc = sprt_push_message((void *)sp_ctx->spm_sp_buffer_base, &message, - SPRT_QUEUE_NUM_BLOCKING); - spin_unlock(&(sp_ctx->spm_sp_buffer_lock)); - if (rc != 0) { - /* - * This shouldn't happen, blocking requests can only be made if - * the request queue is empty. - */ - assert(rc == -ENOMEM); - ERROR("SPCI_SERVICE_TUN_REQUEST_BLOCKING: Queue is full.\n"); - panic(); - } - - /* Jump to the Secure Partition. */ - rx0 = spm_sp_synchronous_entry(sp_ctx, 0); - - /* Verify returned value */ - if (rx0 != SPRT_PUT_RESPONSE_AARCH64) { - ERROR("SPM: %s: Unexpected x0 value 0x%x\n", __func__, rx0); - panic(); - } - - rx1 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X3); - rx2 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X4); - rx3 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X5); - - /* Flag Secure Partition as idle. */ - assert(sp_ctx->state == SP_STATE_BUSY); - sp_state_set(sp_ctx, SP_STATE_IDLE); - - /* Decrease count of requests. */ - spin_lock(&spci_handles_lock); - handle_info->num_active_requests -= 1; - spin_unlock(&spci_handles_lock); - spm_sp_request_decrease(sp_ctx); - - /* Restore non-secure state */ - cm_el1_sysregs_context_restore(NON_SECURE); - cm_set_next_eret_context(NON_SECURE); - - SMC_RET4(handle, SPCI_SUCCESS, rx1, rx2, rx3); -} - -/******************************************************************************* - * This function handles the returned values from the Secure Partition. - ******************************************************************************/ -static void spci_handle_returned_values(const cpu_context_t *cpu_ctx, - uint64_t ret) -{ - if (ret == SPRT_PUT_RESPONSE_AARCH64) { - uint32_t token; - uint64_t x3, x4, x5, x6; - - token = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X1); - x3 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X3); - x4 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X4); - x5 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X5); - x6 = read_ctx_reg(get_gpregs_ctx(cpu_ctx), CTX_GPREG_X6); - - uint16_t client_id = x6 & 0xFFFFU; - uint16_t service_handle = x6 >> 16; - - int rc = spm_response_add(client_id, service_handle, token, - x3, x4, x5); - if (rc != 0) { - /* - * This is error fatal because we can't return to the SP - * from this SMC. The SP has crashed. - */ - panic(); - } - } else if ((ret != SPRT_YIELD_AARCH64) && - (ret != SPM_SECURE_PARTITION_PREEMPTED)) { - ERROR("SPM: %s: Unexpected x0 value 0x%llx\n", __func__, ret); - panic(); - } -} - -/******************************************************************************* - * This function requests a Secure Service from a given handle and client ID. - ******************************************************************************/ -static uint64_t spci_service_request_start(void *handle, - uint32_t smc_fid, u_register_t x1, u_register_t x2, - u_register_t x3, u_register_t x4, u_register_t x5, - u_register_t x6, u_register_t x7) -{ - spci_handle_t *handle_info; - sp_context_t *sp_ctx; - cpu_context_t *cpu_ctx; - uint16_t request_handle, client_id; - uint32_t token; - - /* Get handle array lock */ - spin_lock(&spci_handles_lock); - - /* Get pointer to struct of this open handle and client ID. */ - request_handle = (x7 >> 16U) & 0x0000FFFFU; - client_id = x7 & 0x0000FFFFU; - - handle_info = spci_handle_info_get(request_handle, client_id); - if (handle_info == NULL) { - spin_unlock(&spci_handles_lock); - - WARN("SPCI_SERVICE_TUN_REQUEST_START: Not found.\n" - " Handle 0x%04x. Client ID 0x%04x\n", request_handle, - client_id); - - SMC_RET1(handle, SPCI_INVALID_PARAMETER); - } - - /* Get pointer to the Secure Partition that handles the service */ - sp_ctx = handle_info->sp_ctx; - assert(sp_ctx != NULL); - cpu_ctx = &(sp_ctx->cpu_ctx); - - /* Prevent this handle from being closed */ - handle_info->num_active_requests += 1; - - spm_sp_request_increase(sp_ctx); - - /* Create new token for this request */ - token = spci_create_token_value(); - - /* Release handle lock */ - spin_unlock(&spci_handles_lock); - - /* Pass arguments to the Secure Partition */ - struct sprt_queue_entry_message message = { - .type = SPRT_MSG_TYPE_SERVICE_TUN_REQUEST, - .client_id = client_id, - .service_handle = request_handle, - .session_id = x6, - .token = token, - .args = {smc_fid, x1, x2, x3, x4, x5} - }; - - spin_lock(&(sp_ctx->spm_sp_buffer_lock)); - int rc = sprt_push_message((void *)sp_ctx->spm_sp_buffer_base, &message, - SPRT_QUEUE_NUM_NON_BLOCKING); - spin_unlock(&(sp_ctx->spm_sp_buffer_lock)); - if (rc != 0) { - WARN("SPCI_SERVICE_TUN_REQUEST_START: SPRT queue full.\n" - " Handle 0x%04x. Client ID 0x%04x\n", request_handle, - client_id); - SMC_RET1(handle, SPCI_NO_MEMORY); - } - - /* Try to enter the partition. If it's not possible, simply return. */ - if (sp_state_try_switch(sp_ctx, SP_STATE_IDLE, SP_STATE_BUSY) != 0) { - SMC_RET2(handle, SPCI_SUCCESS, token); - } - - /* Save the Normal world context */ - cm_el1_sysregs_context_save(NON_SECURE); - - /* - * This request is non-blocking and needs to be interruptible by - * non-secure interrupts. Enable their routing to EL3 during the - * processing of the Secure Partition's service on this core. - */ - - /* Jump to the Secure Partition. */ - uint64_t ret = spm_sp_synchronous_entry(sp_ctx, 1); - - /* Handle returned values */ - spci_handle_returned_values(cpu_ctx, ret); - - /* Flag Secure Partition as idle. */ - assert(sp_ctx->state == SP_STATE_BUSY); - sp_state_set(sp_ctx, SP_STATE_IDLE); - - /* Restore non-secure state */ - cm_el1_sysregs_context_restore(NON_SECURE); - cm_set_next_eret_context(NON_SECURE); - - SMC_RET2(handle, SPCI_SUCCESS, token); -} - -/******************************************************************************* - * This function returns the response of a Secure Service given a handle, a - * client ID and a token. If not available, it will schedule a Secure Partition - * and give it CPU time. - ******************************************************************************/ -static uint64_t spci_service_request_resume(void *handle, u_register_t x1, - u_register_t x7) -{ - int rc; - u_register_t rx1 = 0, rx2 = 0, rx3 = 0; - spci_handle_t *handle_info; - sp_context_t *sp_ctx; - cpu_context_t *cpu_ctx; - uint32_t token = (uint32_t) x1; - uint16_t client_id = x7 & 0x0000FFFF; - uint16_t service_handle = (x7 >> 16) & 0x0000FFFF; - - /* Get pointer to struct of this open handle and client ID. */ - spin_lock(&spci_handles_lock); - - handle_info = spci_handle_info_get(service_handle, client_id); - if (handle_info == NULL) { - spin_unlock(&spci_handles_lock); - WARN("SPCI_SERVICE_REQUEST_RESUME: Not found.\n" - "Handle 0x%04x. Client ID 0x%04x, Token 0x%08x.\n", - client_id, service_handle, token); - - SMC_RET1(handle, SPCI_INVALID_PARAMETER); - } - - /* Get pointer to the Secure Partition that handles the service */ - sp_ctx = handle_info->sp_ctx; - assert(sp_ctx != NULL); - cpu_ctx = &(sp_ctx->cpu_ctx); - - spin_unlock(&spci_handles_lock); - - /* Look for a valid response in the global queue */ - rc = spm_response_get(client_id, service_handle, token, - &rx1, &rx2, &rx3); - if (rc == 0) { - /* Decrease request count */ - spin_lock(&spci_handles_lock); - handle_info->num_active_requests -= 1; - spin_unlock(&spci_handles_lock); - spm_sp_request_decrease(sp_ctx); - - SMC_RET4(handle, SPCI_SUCCESS, rx1, rx2, rx3); - } - - /* Try to enter the partition. If it's not possible, simply return. */ - if (sp_state_try_switch(sp_ctx, SP_STATE_IDLE, SP_STATE_BUSY) != 0) { - SMC_RET1(handle, SPCI_QUEUED); - } - - /* Save the Normal world context */ - cm_el1_sysregs_context_save(NON_SECURE); - - /* - * This request is non-blocking and needs to be interruptible by - * non-secure interrupts. Enable their routing to EL3 during the - * processing of the Secure Partition's service on this core. - */ - - /* Jump to the Secure Partition. */ - uint64_t ret = spm_sp_synchronous_entry(sp_ctx, 1); - - /* Handle returned values */ - spci_handle_returned_values(cpu_ctx, ret); - - /* Flag Secure Partition as idle. */ - assert(sp_ctx->state == SP_STATE_BUSY); - sp_state_set(sp_ctx, SP_STATE_IDLE); - - /* Restore non-secure state */ - cm_el1_sysregs_context_restore(NON_SECURE); - cm_set_next_eret_context(NON_SECURE); - - /* Look for a valid response in the global queue */ - rc = spm_response_get(client_id, service_handle, token, - &rx1, &rx2, &rx3); - if (rc != 0) { - SMC_RET1(handle, SPCI_QUEUED); - } - - /* Decrease request count */ - spin_lock(&spci_handles_lock); - handle_info->num_active_requests -= 1; - spin_unlock(&spci_handles_lock); - spm_sp_request_decrease(sp_ctx); - - /* Return response */ - SMC_RET4(handle, SPCI_SUCCESS, rx1, rx2, rx3); -} - -/******************************************************************************* - * This function returns the response of a Secure Service given a handle, a - * client ID and a token. - ******************************************************************************/ -static uint64_t spci_service_get_response(void *handle, u_register_t x1, - u_register_t x7) - -{ - int rc; - u_register_t rx1 = 0, rx2 = 0, rx3 = 0; - spci_handle_t *handle_info; - uint32_t token = (uint32_t) x1; - uint16_t client_id = x7 & 0x0000FFFF; - uint16_t service_handle = (x7 >> 16) & 0x0000FFFF; - - /* Get pointer to struct of this open handle and client ID. */ - - spin_lock(&spci_handles_lock); - - handle_info = spci_handle_info_get(service_handle, client_id); - if (handle_info == NULL) { - spin_unlock(&spci_handles_lock); - WARN("SPCI_SERVICE_GET_RESPONSE: Not found.\n" - "Handle 0x%04x. Client ID 0x%04x, Token 0x%08x.\n", - client_id, service_handle, token); - - SMC_RET1(handle, SPCI_INVALID_PARAMETER); - } - - spin_unlock(&spci_handles_lock); - - /* Look for a valid response in the global queue */ - rc = spm_response_get(client_id, service_handle, token, - &rx1, &rx2, &rx3); - - if (rc != 0) { - SMC_RET1(handle, SPCI_QUEUED); - } - - /* Decrease request count */ - spin_lock(&spci_handles_lock); - handle_info->num_active_requests -= 1; - sp_context_t *sp_ctx; - sp_ctx = handle_info->sp_ctx; - spin_unlock(&spci_handles_lock); - spm_sp_request_decrease(sp_ctx); - - /* Return response */ - SMC_RET4(handle, SPCI_SUCCESS, rx1, rx2, rx3); -} - -/******************************************************************************* - * This function handles all SMCs in the range reserved for SPCI. - ******************************************************************************/ -static uintptr_t spci_smc_handler(uint32_t smc_fid, u_register_t x1, - u_register_t x2, u_register_t x3, - u_register_t x4, void *cookie, void *handle, - u_register_t flags) -{ - uint32_t spci_fid; - - /* SPCI only supported from the Non-secure world for now */ - if (is_caller_non_secure(flags) == SMC_FROM_SECURE) { - SMC_RET1(handle, SMC_UNK); - } - - if ((smc_fid & SPCI_FID_TUN_FLAG) == 0) { - - /* Miscellaneous calls */ - - spci_fid = (smc_fid >> SPCI_FID_MISC_SHIFT) & SPCI_FID_MISC_MASK; - - switch (spci_fid) { - - case SPCI_FID_VERSION: - SMC_RET1(handle, SPCI_VERSION_COMPILED); - - case SPCI_FID_SERVICE_HANDLE_OPEN: - { - if ((smc_fid & SPCI_SERVICE_HANDLE_OPEN_NOTIFY_BIT) != 0) { - /* Not supported for now */ - WARN("SPCI_SERVICE_HANDLE_OPEN_NOTIFY not supported.\n"); - SMC_RET1(handle, SPCI_INVALID_PARAMETER); - } - - uint64_t x5 = SMC_GET_GP(handle, CTX_GPREG_X5); - uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6); - uint64_t x7 = SMC_GET_GP(handle, CTX_GPREG_X7); - - return spci_service_handle_open_poll(handle, x1, x2, x3, - x4, x5, x6, x7); - } - case SPCI_FID_SERVICE_HANDLE_CLOSE: - return spci_service_handle_close(handle, x1); - - case SPCI_FID_SERVICE_REQUEST_BLOCKING: - { - uint64_t x5 = SMC_GET_GP(handle, CTX_GPREG_X5); - uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6); - uint64_t x7 = SMC_GET_GP(handle, CTX_GPREG_X7); - - return spci_service_request_blocking(handle, - smc_fid, x1, x2, x3, x4, x5, x6, x7); - } - - case SPCI_FID_SERVICE_REQUEST_START: - { - uint64_t x5 = SMC_GET_GP(handle, CTX_GPREG_X5); - uint64_t x6 = SMC_GET_GP(handle, CTX_GPREG_X6); - uint64_t x7 = SMC_GET_GP(handle, CTX_GPREG_X7); - - return spci_service_request_start(handle, - smc_fid, x1, x2, x3, x4, x5, x6, x7); - } - - case SPCI_FID_SERVICE_GET_RESPONSE: - { - uint64_t x7 = SMC_GET_GP(handle, CTX_GPREG_X7); - - return spci_service_get_response(handle, x1, x7); - } - - default: - break; - } - - } else { - - /* Tunneled calls */ - - spci_fid = (smc_fid >> SPCI_FID_TUN_SHIFT) & SPCI_FID_TUN_MASK; - - switch (spci_fid) { - - case SPCI_FID_SERVICE_REQUEST_RESUME: - { - uint64_t x7 = SMC_GET_GP(handle, CTX_GPREG_X7); - - return spci_service_request_resume(handle, x1, x7); - } - - default: - break; - } - } - - WARN("SPCI: Unsupported call 0x%08x\n", smc_fid); - SMC_RET1(handle, SPCI_NOT_SUPPORTED); -} - -DECLARE_RT_SVC( - spci_handler, - OEN_SPCI_START, - OEN_SPCI_END, - SMC_TYPE_FAST, - NULL, - spci_smc_handler -); diff --git a/services/std_svc/spm/spm.mk b/services/std_svc/spm/spm.mk deleted file mode 100644 index 448aba4..0000000 --- a/services/std_svc/spm/spm.mk +++ /dev/null @@ -1,30 +0,0 @@ -# -# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause -# - -ifneq (${SPD},none) - $(error "Error: SPD and SPM are incompatible build options.") -endif -ifneq (${ARCH},aarch64) - $(error "Error: SPM is only supported on aarch64.") -endif - -include lib/sprt/sprt_host.mk - -SPM_SOURCES := $(addprefix services/std_svc/spm/, \ - ${ARCH}/spm_helpers.S \ - ${ARCH}/spm_shim_exceptions.S \ - spci.c \ - spm_buffers.c \ - spm_main.c \ - spm_setup.c \ - spm_xlat.c \ - sprt.c) \ - ${SPRT_LIB_SOURCES} - -INCLUDES += ${SPRT_LIB_INCLUDES} - -# Let the top-level Makefile know that we intend to include a BL32 image -NEED_BL32 := yes diff --git a/services/std_svc/spm/spm_buffers.c b/services/std_svc/spm/spm_buffers.c deleted file mode 100644 index 79398ba..0000000 --- a/services/std_svc/spm/spm_buffers.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include - -#include "./spm_private.h" - -/******************************************************************************* - * Secure Service response global array. All the responses to the requests done - * to the Secure Partition are stored here. They are removed from the array as - * soon as their value is read. - ******************************************************************************/ -struct sprt_response { - int is_valid; - uint32_t token; - uint16_t client_id, handle; - u_register_t x1, x2, x3; -}; - -static struct sprt_response responses[PLAT_SPM_RESPONSES_MAX]; - -static spinlock_t responses_lock; - -/* Add response to the global response buffer. Returns 0 on success else -1. */ -int spm_response_add(uint16_t client_id, uint16_t handle, uint32_t token, - u_register_t x1, u_register_t x2, u_register_t x3) -{ - spin_lock(&responses_lock); - - /* Make sure that there isn't any other response with the same token. */ - for (unsigned int i = 0U; i < ARRAY_SIZE(responses); i++) { - struct sprt_response *resp = &(responses[i]); - - if ((resp->is_valid == 1) && (resp->token == token)) { - spin_unlock(&responses_lock); - - return -1; - } - } - - for (unsigned int i = 0U; i < ARRAY_SIZE(responses); i++) { - struct sprt_response *resp = &(responses[i]); - - if (resp->is_valid == 0) { - resp->token = token; - resp->client_id = client_id; - resp->handle = handle; - resp->x1 = x1; - resp->x2 = x2; - resp->x3 = x3; - - dmbish(); - - resp->is_valid = 1; - - spin_unlock(&responses_lock); - - return 0; - } - } - - spin_unlock(&responses_lock); - - return -1; -} - -/* - * Returns a response from the requests array and removes it from it. Returns 0 - * on success, -1 if it wasn't found. - */ -int spm_response_get(uint16_t client_id, uint16_t handle, uint32_t token, - u_register_t *x1, u_register_t *x2, u_register_t *x3) -{ - spin_lock(&responses_lock); - - for (unsigned int i = 0U; i < ARRAY_SIZE(responses); i++) { - struct sprt_response *resp = &(responses[i]); - - /* Ignore invalid entries */ - if (resp->is_valid == 0) { - continue; - } - - /* Make sure that all the information matches the stored one */ - if ((resp->token != token) || (resp->client_id != client_id) || - (resp->handle != handle)) { - continue; - } - - *x1 = resp->x1; - *x2 = resp->x2; - *x3 = resp->x3; - - dmbish(); - - resp->is_valid = 0; - - spin_unlock(&responses_lock); - - return 0; - } - - spin_unlock(&responses_lock); - - return -1; -} diff --git a/services/std_svc/spm/spm_main.c b/services/std_svc/spm/spm_main.c deleted file mode 100644 index 3a63f1c..0000000 --- a/services/std_svc/spm/spm_main.c +++ /dev/null @@ -1,359 +0,0 @@ -/* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "spm_private.h" - -/******************************************************************************* - * Secure Partition context information. - ******************************************************************************/ -sp_context_t sp_ctx_array[PLAT_SPM_MAX_PARTITIONS]; - -/* Last Secure Partition last used by the CPU */ -sp_context_t *cpu_sp_ctx[PLATFORM_CORE_COUNT]; - -void spm_cpu_set_sp_ctx(unsigned int linear_id, sp_context_t *sp_ctx) -{ - assert(linear_id < PLATFORM_CORE_COUNT); - - cpu_sp_ctx[linear_id] = sp_ctx; -} - -sp_context_t *spm_cpu_get_sp_ctx(unsigned int linear_id) -{ - assert(linear_id < PLATFORM_CORE_COUNT); - - return cpu_sp_ctx[linear_id]; -} - -/******************************************************************************* - * Functions to keep track of how many requests a Secure Partition has received - * and hasn't finished. - ******************************************************************************/ -void spm_sp_request_increase(sp_context_t *sp_ctx) -{ - spin_lock(&(sp_ctx->request_count_lock)); - sp_ctx->request_count++; - spin_unlock(&(sp_ctx->request_count_lock)); -} - -void spm_sp_request_decrease(sp_context_t *sp_ctx) -{ - spin_lock(&(sp_ctx->request_count_lock)); - sp_ctx->request_count--; - spin_unlock(&(sp_ctx->request_count_lock)); -} - -/* Returns 0 if it was originally 0, -1 otherwise. */ -int spm_sp_request_increase_if_zero(sp_context_t *sp_ctx) -{ - int ret = -1; - - spin_lock(&(sp_ctx->request_count_lock)); - if (sp_ctx->request_count == 0U) { - sp_ctx->request_count++; - ret = 0U; - } - spin_unlock(&(sp_ctx->request_count_lock)); - - return ret; -} - -/******************************************************************************* - * This function returns a pointer to the context of the Secure Partition that - * handles the service specified by an UUID. It returns NULL if the UUID wasn't - * found. - ******************************************************************************/ -sp_context_t *spm_sp_get_by_uuid(const uint32_t (*svc_uuid)[4]) -{ - unsigned int i; - - for (i = 0U; i < PLAT_SPM_MAX_PARTITIONS; i++) { - - sp_context_t *sp_ctx = &sp_ctx_array[i]; - - if (sp_ctx->is_present == 0) { - continue; - } - - struct sp_rd_sect_service *rdsvc; - - for (rdsvc = sp_ctx->rd.service; rdsvc != NULL; - rdsvc = rdsvc->next) { - uint32_t *rd_uuid = (uint32_t *)(rdsvc->uuid); - - if (memcmp(rd_uuid, svc_uuid, sizeof(*svc_uuid)) == 0) { - return sp_ctx; - } - } - } - - return NULL; -} - -/******************************************************************************* - * Set state of a Secure Partition context. - ******************************************************************************/ -void sp_state_set(sp_context_t *sp_ptr, sp_state_t state) -{ - spin_lock(&(sp_ptr->state_lock)); - sp_ptr->state = state; - spin_unlock(&(sp_ptr->state_lock)); -} - -/******************************************************************************* - * Wait until the state of a Secure Partition is the specified one and change it - * to the desired state. - ******************************************************************************/ -void sp_state_wait_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to) -{ - int success = 0; - - while (success == 0) { - spin_lock(&(sp_ptr->state_lock)); - - if (sp_ptr->state == from) { - sp_ptr->state = to; - - success = 1; - } - - spin_unlock(&(sp_ptr->state_lock)); - } -} - -/******************************************************************************* - * Check if the state of a Secure Partition is the specified one and, if so, - * change it to the desired state. Returns 0 on success, -1 on error. - ******************************************************************************/ -int sp_state_try_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to) -{ - int ret = -1; - - spin_lock(&(sp_ptr->state_lock)); - - if (sp_ptr->state == from) { - sp_ptr->state = to; - - ret = 0; - } - - spin_unlock(&(sp_ptr->state_lock)); - - return ret; -} - -/******************************************************************************* - * This function takes an SP context pointer and performs a synchronous entry - * into it. - ******************************************************************************/ -uint64_t spm_sp_synchronous_entry(sp_context_t *sp_ctx, int can_preempt) -{ - uint64_t rc; - unsigned int linear_id = plat_my_core_pos(); - - assert(sp_ctx != NULL); - - /* Assign the context of the SP to this CPU */ - spm_cpu_set_sp_ctx(linear_id, sp_ctx); - cm_set_context(&(sp_ctx->cpu_ctx), SECURE); - - /* Restore the context assigned above */ - cm_el1_sysregs_context_restore(SECURE); - cm_set_next_eret_context(SECURE); - - /* Invalidate TLBs at EL1. */ - tlbivmalle1(); - dsbish(); - - if (can_preempt == 1) { - enable_intr_rm_local(INTR_TYPE_NS, SECURE); - } else { - disable_intr_rm_local(INTR_TYPE_NS, SECURE); - } - - /* Enter Secure Partition */ - rc = spm_secure_partition_enter(&sp_ctx->c_rt_ctx); - - /* Save secure state */ - cm_el1_sysregs_context_save(SECURE); - - return rc; -} - -/******************************************************************************* - * This function returns to the place where spm_sp_synchronous_entry() was - * called originally. - ******************************************************************************/ -__dead2 void spm_sp_synchronous_exit(uint64_t rc) -{ - /* Get context of the SP in use by this CPU. */ - unsigned int linear_id = plat_my_core_pos(); - sp_context_t *ctx = spm_cpu_get_sp_ctx(linear_id); - - /* - * The SPM must have initiated the original request through a - * synchronous entry into the secure partition. Jump back to the - * original C runtime context with the value of rc in x0; - */ - spm_secure_partition_exit(ctx->c_rt_ctx, rc); - - panic(); -} - -/******************************************************************************* - * This function is the handler registered for Non secure interrupts by the SPM. - * It validates the interrupt and upon success arranges entry into the normal - * world for handling the interrupt. - ******************************************************************************/ -static uint64_t spm_ns_interrupt_handler(uint32_t id, uint32_t flags, - void *handle, void *cookie) -{ - /* Check the security state when the exception was generated */ - assert(get_interrupt_src_ss(flags) == SECURE); - - spm_sp_synchronous_exit(SPM_SECURE_PARTITION_PREEMPTED); -} - -/******************************************************************************* - * Jump to each Secure Partition for the first time. - ******************************************************************************/ -static int32_t spm_init(void) -{ - uint64_t rc = 0; - sp_context_t *ctx; - - for (unsigned int i = 0U; i < PLAT_SPM_MAX_PARTITIONS; i++) { - - ctx = &sp_ctx_array[i]; - - if (ctx->is_present == 0) { - continue; - } - - INFO("Secure Partition %u init...\n", i); - - ctx->state = SP_STATE_RESET; - - rc = spm_sp_synchronous_entry(ctx, 0); - if (rc != SPRT_YIELD_AARCH64) { - ERROR("Unexpected return value 0x%llx\n", rc); - panic(); - } - - ctx->state = SP_STATE_IDLE; - - INFO("Secure Partition %u initialized.\n", i); - } - - return rc; -} - -/******************************************************************************* - * Initialize contexts of all Secure Partitions. - ******************************************************************************/ -int32_t spm_setup(void) -{ - int rc; - sp_context_t *ctx; - void *sp_base, *rd_base; - size_t sp_size, rd_size; - uint64_t flags = 0U; - - /* Disable MMU at EL1 (initialized by BL2) */ - disable_mmu_icache_el1(); - - /* - * Non-blocking services can be interrupted by Non-secure interrupts. - * Register an interrupt handler for NS interrupts when generated while - * the CPU is in secure state. They are routed to EL3. - */ - set_interrupt_rm_flag(flags, SECURE); - - uint64_t rc_int = register_interrupt_type_handler(INTR_TYPE_NS, - spm_ns_interrupt_handler, flags); - if (rc_int) { - ERROR("SPM: Failed to register NS interrupt handler with rc = %llx\n", - rc_int); - panic(); - } - - /* Setup shim layer */ - spm_exceptions_xlat_init_context(); - - /* - * Setup all Secure Partitions. - */ - unsigned int i = 0U; - - while (1) { - rc = plat_spm_sp_get_next_address(&sp_base, &sp_size, - &rd_base, &rd_size); - if (rc < 0) { - /* Reached the end of the package. */ - break; - } - - if (i >= PLAT_SPM_MAX_PARTITIONS) { - ERROR("Too many partitions in the package.\n"); - panic(); - } - - ctx = &sp_ctx_array[i]; - - assert(ctx->is_present == 0); - - /* Initialize context of the SP */ - INFO("Secure Partition %u context setup start...\n", i); - - /* Save location of the image in physical memory */ - ctx->image_base = (uintptr_t)sp_base; - ctx->image_size = sp_size; - - rc = plat_spm_sp_rd_load(&ctx->rd, rd_base, rd_size); - if (rc < 0) { - ERROR("Error while loading RD blob.\n"); - panic(); - } - - spm_sp_setup(ctx); - - ctx->is_present = 1; - - INFO("Secure Partition %u setup done.\n", i); - - i++; - } - - if (i == 0U) { - ERROR("No present partitions in the package.\n"); - panic(); - } - - /* Register init function for deferred init. */ - bl31_register_bl32_init(&spm_init); - - return 0; -} diff --git a/services/std_svc/spm/spm_private.h b/services/std_svc/spm/spm_private.h deleted file mode 100644 index efc91cb..0000000 --- a/services/std_svc/spm/spm_private.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SPM_PRIVATE_H -#define SPM_PRIVATE_H - -#include - -/******************************************************************************* - * Constants that allow assembler code to preserve callee-saved registers of the - * C runtime context while performing a security state switch. - ******************************************************************************/ -#define SP_C_RT_CTX_X19 0x0 -#define SP_C_RT_CTX_X20 0x8 -#define SP_C_RT_CTX_X21 0x10 -#define SP_C_RT_CTX_X22 0x18 -#define SP_C_RT_CTX_X23 0x20 -#define SP_C_RT_CTX_X24 0x28 -#define SP_C_RT_CTX_X25 0x30 -#define SP_C_RT_CTX_X26 0x38 -#define SP_C_RT_CTX_X27 0x40 -#define SP_C_RT_CTX_X28 0x48 -#define SP_C_RT_CTX_X29 0x50 -#define SP_C_RT_CTX_X30 0x58 - -#define SP_C_RT_CTX_SIZE 0x60 -#define SP_C_RT_CTX_ENTRIES (SP_C_RT_CTX_SIZE >> DWORD_SHIFT) - -/* Value returned by spm_sp_synchronous_entry() when a partition is preempted */ -#define SPM_SECURE_PARTITION_PREEMPTED U(0x1234) - -#ifndef __ASSEMBLER__ - -#include - -#include -#include -#include - -typedef enum sp_state { - SP_STATE_RESET = 0, - SP_STATE_IDLE, - SP_STATE_BUSY -} sp_state_t; - -typedef struct sp_context { - /* 1 if the partition is present, 0 otherwise */ - int is_present; - - /* Location of the image in physical memory */ - unsigned long long image_base; - size_t image_size; - - uint64_t c_rt_ctx; - cpu_context_t cpu_ctx; - struct sp_res_desc rd; - - /* Translation tables context */ - xlat_ctx_t *xlat_ctx_handle; - spinlock_t xlat_ctx_lock; - - sp_state_t state; - spinlock_t state_lock; - - unsigned int request_count; - spinlock_t request_count_lock; - - /* Base and size of the shared SPM<->SP buffer */ - uintptr_t spm_sp_buffer_base; - size_t spm_sp_buffer_size; - spinlock_t spm_sp_buffer_lock; -} sp_context_t; - -/* Functions used to enter/exit a Secure Partition synchronously */ -uint64_t spm_sp_synchronous_entry(sp_context_t *sp_ctx, int can_preempt); -__dead2 void spm_sp_synchronous_exit(uint64_t rc); - -/* Assembly helpers */ -uint64_t spm_secure_partition_enter(uint64_t *c_rt_ctx); -void __dead2 spm_secure_partition_exit(uint64_t c_rt_ctx, uint64_t ret); - -/* Secure Partition setup */ -void spm_sp_setup(sp_context_t *sp_ctx); - -/* Secure Partition state management helpers */ -void sp_state_set(sp_context_t *sp_ptr, sp_state_t state); -void sp_state_wait_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to); -int sp_state_try_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to); - -/* Functions to keep track of the number of active requests per SP */ -void spm_sp_request_increase(sp_context_t *sp_ctx); -void spm_sp_request_decrease(sp_context_t *sp_ctx); -int spm_sp_request_increase_if_zero(sp_context_t *sp_ctx); - -/* Functions related to the shim layer translation tables */ -void spm_exceptions_xlat_init_context(void); -uint64_t *spm_exceptions_xlat_get_base_table(void); - -/* Functions related to the translation tables management */ -void spm_sp_xlat_context_alloc(sp_context_t *sp_ctx); -void sp_map_memory_regions(sp_context_t *sp_ctx); - -/* Functions to handle Secure Partition contexts */ -void spm_cpu_set_sp_ctx(unsigned int linear_id, sp_context_t *sp_ctx); -sp_context_t *spm_cpu_get_sp_ctx(unsigned int linear_id); -sp_context_t *spm_sp_get_by_uuid(const uint32_t (*svc_uuid)[4]); - -/* Functions to manipulate response and requests buffers */ -int spm_response_add(uint16_t client_id, uint16_t handle, uint32_t token, - u_register_t x1, u_register_t x2, u_register_t x3); -int spm_response_get(uint16_t client_id, uint16_t handle, uint32_t token, - u_register_t *x1, u_register_t *x2, u_register_t *x3); - -#endif /* __ASSEMBLER__ */ - -#endif /* SPM_PRIVATE_H */ diff --git a/services/std_svc/spm/spm_setup.c b/services/std_svc/spm/spm_setup.c deleted file mode 100644 index 2ed44d1..0000000 --- a/services/std_svc/spm/spm_setup.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "spm_private.h" -#include "spm_shim_private.h" - -/* Setup context of the Secure Partition */ -void spm_sp_setup(sp_context_t *sp_ctx) -{ - cpu_context_t *ctx = &(sp_ctx->cpu_ctx); - - /* - * Initialize CPU context - * ---------------------- - */ - - entry_point_info_t ep_info = {0}; - - SET_PARAM_HEAD(&ep_info, PARAM_EP, VERSION_1, SECURE | EP_ST_ENABLE); - - /* Setup entrypoint and SPSR */ - ep_info.pc = sp_ctx->rd.attribute.entrypoint; - ep_info.spsr = SPSR_64(MODE_EL0, MODE_SP_EL0, DISABLE_ALL_EXCEPTIONS); - - /* - * X0: Unused (MBZ). - * X1: Unused (MBZ). - * X2: cookie value (Implementation Defined) - * X3: cookie value (Implementation Defined) - * X4 to X7 = 0 - */ - ep_info.args.arg0 = 0; - ep_info.args.arg1 = 0; - ep_info.args.arg2 = PLAT_SPM_COOKIE_0; - ep_info.args.arg3 = PLAT_SPM_COOKIE_1; - - cm_setup_context(ctx, &ep_info); - - /* - * Setup translation tables - * ------------------------ - */ - - /* Assign translation tables context. */ - spm_sp_xlat_context_alloc(sp_ctx); - - sp_map_memory_regions(sp_ctx); - - /* - * MMU-related registers - * --------------------- - */ - xlat_ctx_t *xlat_ctx = sp_ctx->xlat_ctx_handle; - - uint64_t mmu_cfg_params[MMU_CFG_PARAM_MAX]; - - setup_mmu_cfg((uint64_t *)&mmu_cfg_params, 0, xlat_ctx->base_table, - xlat_ctx->pa_max_address, xlat_ctx->va_max_address, - EL1_EL0_REGIME); - - write_ctx_reg(get_sysregs_ctx(ctx), CTX_MAIR_EL1, - mmu_cfg_params[MMU_CFG_MAIR]); - - /* Enable translations using TTBR1_EL1 */ - int t1sz = 64 - __builtin_ctzll(SPM_SHIM_XLAT_VIRT_ADDR_SPACE_SIZE); - mmu_cfg_params[MMU_CFG_TCR] &= ~TCR_EPD1_BIT; - mmu_cfg_params[MMU_CFG_TCR] |= - ((uint64_t)t1sz << TCR_T1SZ_SHIFT) | - TCR_SH1_INNER_SHAREABLE | - TCR_RGN1_OUTER_WBA | TCR_RGN1_INNER_WBA | - TCR_TG1_4K; - - write_ctx_reg(get_sysregs_ctx(ctx), CTX_TCR_EL1, - mmu_cfg_params[MMU_CFG_TCR]); - - write_ctx_reg(get_sysregs_ctx(ctx), CTX_TTBR0_EL1, - mmu_cfg_params[MMU_CFG_TTBR0]); - - write_ctx_reg(get_sysregs_ctx(ctx), CTX_TTBR1_EL1, - (uint64_t)spm_exceptions_xlat_get_base_table()); - - /* Setup SCTLR_EL1 */ - u_register_t sctlr_el1 = read_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1); - - sctlr_el1 |= - /*SCTLR_EL1_RES1 |*/ - /* Don't trap DC CVAU, DC CIVAC, DC CVAC, DC CVAP, or IC IVAU */ - SCTLR_UCI_BIT | - /* RW regions at xlat regime EL1&0 are forced to be XN. */ - SCTLR_WXN_BIT | - /* Don't trap to EL1 execution of WFI or WFE at EL0. */ - SCTLR_NTWI_BIT | SCTLR_NTWE_BIT | - /* Don't trap to EL1 accesses to CTR_EL0 from EL0. */ - SCTLR_UCT_BIT | - /* Don't trap to EL1 execution of DZ ZVA at EL0. */ - SCTLR_DZE_BIT | - /* Enable SP Alignment check for EL0 */ - SCTLR_SA0_BIT | - /* Allow cacheable data and instr. accesses to normal memory. */ - SCTLR_C_BIT | SCTLR_I_BIT | - /* Alignment fault checking enabled when at EL1 and EL0. */ - SCTLR_A_BIT | - /* Enable MMU. */ - SCTLR_M_BIT - ; - - sctlr_el1 &= ~( - /* Explicit data accesses at EL0 are little-endian. */ - SCTLR_E0E_BIT | - /* Accesses to DAIF from EL0 are trapped to EL1. */ - SCTLR_UMA_BIT - ); - - write_ctx_reg(get_sysregs_ctx(ctx), CTX_SCTLR_EL1, sctlr_el1); - - /* - * Setup other system registers - * ---------------------------- - */ - - /* - * Shim exception vector base address. It is mapped at the start of the - * address space accessed by TTBR1_EL1, which means that the base - * address of the exception vectors depends on the size of the address - * space specified in TCR_EL1.T1SZ. - */ - write_ctx_reg(get_sysregs_ctx(ctx), CTX_VBAR_EL1, - UINT64_MAX - (SPM_SHIM_XLAT_VIRT_ADDR_SPACE_SIZE - 1ULL)); - - /* - * FPEN: Allow the Secure Partition to access FP/SIMD registers. - * Note that SPM will not do any saving/restoring of these registers on - * behalf of the SP. This falls under the SP's responsibility. - * TTA: Enable access to trace registers. - * ZEN (v8.2): Trap SVE instructions and access to SVE registers. - */ - write_ctx_reg(get_sysregs_ctx(ctx), CTX_CPACR_EL1, - CPACR_EL1_FPEN(CPACR_EL1_FP_TRAP_NONE)); - - /* - * Prepare shared buffers - * ---------------------- - */ - - /* Initialize SPRT queues */ - sprt_initialize_queues((void *)sp_ctx->spm_sp_buffer_base, - sp_ctx->spm_sp_buffer_size); -} diff --git a/services/std_svc/spm/spm_shim_private.h b/services/std_svc/spm/spm_shim_private.h deleted file mode 100644 index fc510b1..0000000 --- a/services/std_svc/spm/spm_shim_private.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef SPM_SHIM_PRIVATE_H -#define SPM_SHIM_PRIVATE_H - -#include - -#include - -/* Assembly source */ -IMPORT_SYM(uintptr_t, spm_shim_exceptions_ptr, SPM_SHIM_EXCEPTIONS_PTR); - -/* Linker symbols */ -IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_START__, SPM_SHIM_EXCEPTIONS_START); -IMPORT_SYM(uintptr_t, __SPM_SHIM_EXCEPTIONS_END__, SPM_SHIM_EXCEPTIONS_END); - -/* Definitions */ - -#define SPM_SHIM_EXCEPTIONS_SIZE \ - (SPM_SHIM_EXCEPTIONS_END - SPM_SHIM_EXCEPTIONS_START) - -/* - * Use the smallest virtual address space size allowed in ARMv8.0 for - * compatibility. - */ -#define SPM_SHIM_XLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 25) -#define SPM_SHIM_MMAP_REGIONS 1 -#define SPM_SHIM_XLAT_TABLES 1 - -#endif /* SPM_SHIM_PRIVATE_H */ diff --git a/services/std_svc/spm/spm_xlat.c b/services/std_svc/spm/spm_xlat.c deleted file mode 100644 index 5d5bc51..0000000 --- a/services/std_svc/spm/spm_xlat.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -#include "spm_private.h" -#include "spm_shim_private.h" - -/******************************************************************************* - * Instantiation of translation table context - ******************************************************************************/ - -/* Place translation tables by default along with the ones used by BL31. */ -#ifndef PLAT_SP_IMAGE_XLAT_SECTION_NAME -#define PLAT_SP_IMAGE_XLAT_SECTION_NAME "xlat_table" -#endif - -/* - * Allocate elements of the translation contexts for the Secure Partitions. - */ - -/* Allocate an array of mmap_region per partition. */ -static struct mmap_region sp_mmap_regions[PLAT_SP_IMAGE_MMAP_REGIONS + 1] - [PLAT_SPM_MAX_PARTITIONS]; -static OBJECT_POOL(sp_mmap_regions_pool, sp_mmap_regions, - sizeof(mmap_region_t) * (PLAT_SP_IMAGE_MMAP_REGIONS + 1), - PLAT_SPM_MAX_PARTITIONS); - -/* Allocate individual translation tables. */ -static uint64_t sp_xlat_tables[XLAT_TABLE_ENTRIES] - [(PLAT_SP_IMAGE_MAX_XLAT_TABLES + 1) * PLAT_SPM_MAX_PARTITIONS] - __aligned(XLAT_TABLE_SIZE) __section(PLAT_SP_IMAGE_XLAT_SECTION_NAME); -static OBJECT_POOL(sp_xlat_tables_pool, sp_xlat_tables, - XLAT_TABLE_ENTRIES * sizeof(uint64_t), - (PLAT_SP_IMAGE_MAX_XLAT_TABLES + 1) * PLAT_SPM_MAX_PARTITIONS); - -/* Allocate arrays. */ -static int sp_xlat_mapped_regions[PLAT_SP_IMAGE_MAX_XLAT_TABLES] - [PLAT_SPM_MAX_PARTITIONS]; -static OBJECT_POOL(sp_xlat_mapped_regions_pool, sp_xlat_mapped_regions, - sizeof(int) * PLAT_SP_IMAGE_MAX_XLAT_TABLES, PLAT_SPM_MAX_PARTITIONS); - -/* Allocate individual contexts. */ -static xlat_ctx_t sp_xlat_ctx[PLAT_SPM_MAX_PARTITIONS]; -static OBJECT_POOL(sp_xlat_ctx_pool, sp_xlat_ctx, sizeof(xlat_ctx_t), - PLAT_SPM_MAX_PARTITIONS); - -/* Get handle of Secure Partition translation context */ -void spm_sp_xlat_context_alloc(sp_context_t *sp_ctx) -{ - /* Allocate xlat context elements */ - - xlat_ctx_t *ctx = pool_alloc(&sp_xlat_ctx_pool); - - struct mmap_region *mmap = pool_alloc(&sp_mmap_regions_pool); - - uint64_t *base_table = pool_alloc(&sp_xlat_tables_pool); - uint64_t **tables = pool_alloc_n(&sp_xlat_tables_pool, - PLAT_SP_IMAGE_MAX_XLAT_TABLES); - - int *mapped_regions = pool_alloc(&sp_xlat_mapped_regions_pool); - - /* Calculate the size of the virtual address space needed */ - - uintptr_t va_size = 0U; - struct sp_rd_sect_mem_region *rdmem; - - for (rdmem = sp_ctx->rd.mem_region; rdmem != NULL; rdmem = rdmem->next) { - uintptr_t end_va = (uintptr_t)rdmem->base + - (uintptr_t)rdmem->size; - - if (end_va > va_size) - va_size = end_va; - } - - if (va_size == 0U) { - ERROR("No regions in resource description.\n"); - panic(); - } - - /* - * Get the power of two that is greater or equal to the top VA. The - * values of base and size in the resource description are 32-bit wide - * so the values will never overflow when using a uintptr_t. - */ - if (!IS_POWER_OF_TWO(va_size)) { - va_size = 1ULL << - ((sizeof(va_size) * 8) - __builtin_clzll(va_size)); - } - - if (va_size > PLAT_VIRT_ADDR_SPACE_SIZE) { - ERROR("Resource description requested too much virtual memory.\n"); - panic(); - } - - uintptr_t min_va_size; - - /* The following sizes are only valid for 4KB pages */ - assert(PAGE_SIZE == (4U * 1024U)); - - if (is_armv8_4_ttst_present()) { - VERBOSE("Using ARMv8.4-TTST\n"); - min_va_size = 1ULL << (64 - TCR_TxSZ_MAX_TTST); - } else { - min_va_size = 1ULL << (64 - TCR_TxSZ_MAX); - } - - if (va_size < min_va_size) { - va_size = min_va_size; - } - - /* Initialize xlat context */ - - xlat_setup_dynamic_ctx(ctx, PLAT_PHY_ADDR_SPACE_SIZE - 1ULL, - va_size - 1ULL, mmap, - PLAT_SP_IMAGE_MMAP_REGIONS, tables, - PLAT_SP_IMAGE_MAX_XLAT_TABLES, base_table, - EL1_EL0_REGIME, mapped_regions); - - sp_ctx->xlat_ctx_handle = ctx; -}; - -/******************************************************************************* - * Translation table context used for S-EL1 exception vectors - ******************************************************************************/ - -REGISTER_XLAT_CONTEXT2(spm_sel1, SPM_SHIM_MMAP_REGIONS, SPM_SHIM_XLAT_TABLES, - SPM_SHIM_XLAT_VIRT_ADDR_SPACE_SIZE, PLAT_PHY_ADDR_SPACE_SIZE, - EL1_EL0_REGIME, PLAT_SP_IMAGE_XLAT_SECTION_NAME); - -void spm_exceptions_xlat_init_context(void) -{ - /* This region contains the exception vectors used at S-EL1. */ - mmap_region_t sel1_exception_vectors = - MAP_REGION(SPM_SHIM_EXCEPTIONS_PTR, - 0x0UL, - SPM_SHIM_EXCEPTIONS_SIZE, - MT_CODE | MT_SECURE | MT_PRIVILEGED); - - mmap_add_region_ctx(&spm_sel1_xlat_ctx, - &sel1_exception_vectors); - - init_xlat_tables_ctx(&spm_sel1_xlat_ctx); -} - -uint64_t *spm_exceptions_xlat_get_base_table(void) -{ - return spm_sel1_xlat_ctx.base_table; -} - -/******************************************************************************* - * Functions to allocate memory for regions. - ******************************************************************************/ - -/* - * The region with base PLAT_SPM_HEAP_BASE and size PLAT_SPM_HEAP_SIZE is - * reserved for SPM to use as heap to allocate memory regions of Secure - * Partitions. This is only done at boot. - */ -static OBJECT_POOL(spm_heap_mem, (void *)PLAT_SPM_HEAP_BASE, 1U, - PLAT_SPM_HEAP_SIZE); - -static uintptr_t spm_alloc_heap(size_t size) -{ - return (uintptr_t)pool_alloc_n(&spm_heap_mem, size); -} - -/******************************************************************************* - * Functions to map memory regions described in the resource description. - ******************************************************************************/ -static unsigned int rdmem_attr_to_mmap_attr(uint32_t attr) -{ - unsigned int index = attr & RD_MEM_MASK; - - const unsigned int mmap_attr_arr[8] = { - MT_DEVICE | MT_RW | MT_SECURE, /* RD_MEM_DEVICE */ - MT_CODE | MT_SECURE, /* RD_MEM_NORMAL_CODE */ - MT_MEMORY | MT_RW | MT_SECURE, /* RD_MEM_NORMAL_DATA */ - MT_MEMORY | MT_RW | MT_SECURE, /* RD_MEM_NORMAL_BSS */ - MT_RO_DATA | MT_SECURE, /* RD_MEM_NORMAL_RODATA */ - MT_MEMORY | MT_RW | MT_SECURE, /* RD_MEM_NORMAL_SPM_SP_SHARED_MEM */ - MT_MEMORY | MT_RW | MT_SECURE, /* RD_MEM_NORMAL_CLIENT_SHARED_MEM */ - MT_MEMORY | MT_RW | MT_SECURE /* RD_MEM_NORMAL_MISCELLANEOUS */ - }; - - if (index >= ARRAY_SIZE(mmap_attr_arr)) { - ERROR("Unsupported RD memory attributes 0x%x\n", attr); - panic(); - } - - return mmap_attr_arr[index]; -} - -/* - * The data provided in the resource description structure is not directly - * compatible with a mmap_region structure. This function handles the conversion - * and maps it. - */ -static void map_rdmem(sp_context_t *sp_ctx, struct sp_rd_sect_mem_region *rdmem) -{ - int rc; - mmap_region_t mmap; - - /* Location of the SP image */ - uintptr_t sp_size = sp_ctx->image_size; - uintptr_t sp_base_va = sp_ctx->rd.attribute.load_address; - unsigned long long sp_base_pa = sp_ctx->image_base; - - /* Location of the memory region to map */ - size_t rd_size = rdmem->size; - uintptr_t rd_base_va = rdmem->base; - unsigned long long rd_base_pa; - - unsigned int memtype = rdmem->attr & RD_MEM_MASK; - - if (rd_size == 0U) { - VERBOSE("Memory region '%s' is empty. Ignored.\n", rdmem->name); - return; - } - - VERBOSE("Adding memory region '%s'\n", rdmem->name); - - mmap.granularity = REGION_DEFAULT_GRANULARITY; - - /* Check if the RD region is inside of the SP image or not */ - int is_outside = (rd_base_va + rd_size <= sp_base_va) || - (sp_base_va + sp_size <= rd_base_va); - - /* Set to 1 if it is needed to zero this region */ - int zero_region = 0; - - switch (memtype) { - case RD_MEM_DEVICE: - /* Device regions are mapped 1:1 */ - rd_base_pa = rd_base_va; - break; - - case RD_MEM_NORMAL_CODE: - case RD_MEM_NORMAL_RODATA: - { - if (is_outside == 1) { - ERROR("Code and rodata sections must be fully contained in the image."); - panic(); - } - - /* Get offset into the image */ - rd_base_pa = sp_base_pa + rd_base_va - sp_base_va; - break; - } - case RD_MEM_NORMAL_DATA: - { - if (is_outside == 1) { - ERROR("Data sections must be fully contained in the image."); - panic(); - } - - rd_base_pa = spm_alloc_heap(rd_size); - - /* Get offset into the image */ - void *img_pa = (void *)(sp_base_pa + rd_base_va - sp_base_va); - - VERBOSE(" Copying data from %p to 0x%llx\n", img_pa, rd_base_pa); - - /* Map destination */ - rc = mmap_add_dynamic_region(rd_base_pa, rd_base_pa, - rd_size, MT_MEMORY | MT_RW | MT_SECURE); - if (rc != 0) { - ERROR("Unable to map data region at EL3: %d\n", rc); - panic(); - } - - /* Copy original data to destination */ - memcpy((void *)rd_base_pa, img_pa, rd_size); - - /* Unmap destination region */ - rc = mmap_remove_dynamic_region(rd_base_pa, rd_size); - if (rc != 0) { - ERROR("Unable to remove data region at EL3: %d\n", rc); - panic(); - } - - break; - } - case RD_MEM_NORMAL_MISCELLANEOUS: - /* Allow SPM to change the attributes of the region. */ - mmap.granularity = PAGE_SIZE; - rd_base_pa = spm_alloc_heap(rd_size); - zero_region = 1; - break; - - case RD_MEM_NORMAL_SPM_SP_SHARED_MEM: - if ((sp_ctx->spm_sp_buffer_base != 0) || - (sp_ctx->spm_sp_buffer_size != 0)) { - ERROR("A partition must have only one SPM<->SP buffer.\n"); - panic(); - } - rd_base_pa = spm_alloc_heap(rd_size); - zero_region = 1; - /* Save location of this buffer, it is needed by SPM */ - sp_ctx->spm_sp_buffer_base = rd_base_pa; - sp_ctx->spm_sp_buffer_size = rd_size; - break; - - case RD_MEM_NORMAL_CLIENT_SHARED_MEM: - /* Fallthrough */ - case RD_MEM_NORMAL_BSS: - rd_base_pa = spm_alloc_heap(rd_size); - zero_region = 1; - break; - - default: - panic(); - } - - mmap.base_pa = rd_base_pa; - mmap.base_va = rd_base_va; - mmap.size = rd_size; - - /* Only S-EL0 mappings supported for now */ - mmap.attr = rdmem_attr_to_mmap_attr(rdmem->attr) | MT_USER; - - VERBOSE(" VA: 0x%lx PA: 0x%llx (0x%lx, attr: 0x%x)\n", - mmap.base_va, mmap.base_pa, mmap.size, mmap.attr); - - /* Map region in the context of the Secure Partition */ - mmap_add_region_ctx(sp_ctx->xlat_ctx_handle, &mmap); - - if (zero_region == 1) { - VERBOSE(" Zeroing region...\n"); - - rc = mmap_add_dynamic_region(mmap.base_pa, mmap.base_pa, - mmap.size, MT_MEMORY | MT_RW | MT_SECURE); - if (rc != 0) { - ERROR("Unable to map memory at EL3 to zero: %d\n", - rc); - panic(); - } - - zeromem((void *)mmap.base_pa, mmap.size); - - /* - * Unmap destination region unless it is the SPM<->SP buffer, - * which must be used by SPM. - */ - if (memtype != RD_MEM_NORMAL_SPM_SP_SHARED_MEM) { - rc = mmap_remove_dynamic_region(rd_base_pa, rd_size); - if (rc != 0) { - ERROR("Unable to remove region at EL3: %d\n", rc); - panic(); - } - } - } -} - -void sp_map_memory_regions(sp_context_t *sp_ctx) -{ - struct sp_rd_sect_mem_region *rdmem; - - for (rdmem = sp_ctx->rd.mem_region; rdmem != NULL; rdmem = rdmem->next) { - map_rdmem(sp_ctx, rdmem); - } - - init_xlat_tables_ctx(sp_ctx->xlat_ctx_handle); -} diff --git a/services/std_svc/spm/sprt.c b/services/std_svc/spm/sprt.c deleted file mode 100644 index 20ad2af..0000000 --- a/services/std_svc/spm/sprt.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "spm_private.h" - -/******************************************************************************* - * Functions to manipulate memory regions - ******************************************************************************/ - -/* - * Attributes are encoded using a different format in the SMC interface than in - * the Trusted Firmware, where the mmap_attr_t enum type is used. This function - * converts an attributes value from the SMC format to the mmap_attr_t format by - * setting MT_RW/MT_RO, MT_USER/MT_PRIVILEGED and MT_EXECUTE/MT_EXECUTE_NEVER. - * The other fields are left as 0 because they are ignored by the function - * xlat_change_mem_attributes_ctx(). - */ -static unsigned int smc_attr_to_mmap_attr(unsigned int attributes) -{ - unsigned int perm = attributes & SPRT_MEMORY_PERM_ATTR_MASK; - - if (perm == SPRT_MEMORY_PERM_ATTR_RW) { - return MT_RW | MT_EXECUTE_NEVER | MT_USER; - } else if (perm == SPRT_MEMORY_PERM_ATTR_RO) { - return MT_RO | MT_EXECUTE_NEVER | MT_USER; - } else if (perm == SPRT_MEMORY_PERM_ATTR_RO_EXEC) { - return MT_RO | MT_USER; - } else { - return UINT_MAX; - } -} - -/* - * This function converts attributes from the Trusted Firmware format into the - * SMC interface format. - */ -static unsigned int mmap_attr_to_smc_attr(unsigned int attr) -{ - unsigned int perm; - - /* No access from EL0. */ - if ((attr & MT_USER) == 0U) - return UINT_MAX; - - if ((attr & MT_RW) != 0) { - assert(MT_TYPE(attr) != MT_DEVICE); - perm = SPRT_MEMORY_PERM_ATTR_RW; - } else { - if ((attr & MT_EXECUTE_NEVER) != 0U) { - perm = SPRT_MEMORY_PERM_ATTR_RO; - } else { - perm = SPRT_MEMORY_PERM_ATTR_RO_EXEC; - } - } - - return perm << SPRT_MEMORY_PERM_ATTR_SHIFT; -} - -static int32_t sprt_memory_perm_attr_get(sp_context_t *sp_ctx, uintptr_t base_va) -{ - uint32_t attributes; - - spin_lock(&(sp_ctx->xlat_ctx_lock)); - - int ret = xlat_get_mem_attributes_ctx(sp_ctx->xlat_ctx_handle, - base_va, &attributes); - - spin_unlock(&(sp_ctx->xlat_ctx_lock)); - - /* Convert error codes of xlat_get_mem_attributes_ctx() into SPM. */ - assert((ret == 0) || (ret == -EINVAL)); - - if (ret != 0) - return SPRT_INVALID_PARAMETER; - - unsigned int perm = mmap_attr_to_smc_attr(attributes); - - if (perm == UINT_MAX) - return SPRT_INVALID_PARAMETER; - - return SPRT_SUCCESS | perm; -} - -static int32_t sprt_memory_perm_attr_set(sp_context_t *sp_ctx, - u_register_t page_address, u_register_t pages_count, - u_register_t smc_attributes) -{ - int ret; - uintptr_t base_va = (uintptr_t) page_address; - size_t size = pages_count * PAGE_SIZE; - - VERBOSE(" Start address : 0x%lx\n", base_va); - VERBOSE(" Number of pages: %i (%zi bytes)\n", (int) pages_count, size); - VERBOSE(" Attributes : 0x%lx\n", smc_attributes); - - uint32_t mmap_attr = smc_attr_to_mmap_attr(smc_attributes); - - if (mmap_attr == UINT_MAX) { - WARN("%s: Invalid memory attributes: 0x%lx\n", __func__, - smc_attributes); - return SPRT_INVALID_PARAMETER; - } - - /* - * Perform some checks before actually trying to change the memory - * attributes. - */ - - spin_lock(&(sp_ctx->xlat_ctx_lock)); - - uint32_t attributes; - - ret = xlat_get_mem_attributes_ctx(sp_ctx->xlat_ctx_handle, - base_va, &attributes); - - if (ret != 0) { - spin_unlock(&(sp_ctx->xlat_ctx_lock)); - return SPRT_INVALID_PARAMETER; - } - - if ((attributes & MT_USER) == 0U) { - /* Prohibit changing attributes of S-EL1 regions */ - spin_unlock(&(sp_ctx->xlat_ctx_lock)); - return SPRT_INVALID_PARAMETER; - } - - ret = xlat_change_mem_attributes_ctx(sp_ctx->xlat_ctx_handle, - base_va, size, mmap_attr); - - spin_unlock(&(sp_ctx->xlat_ctx_lock)); - - /* Convert error codes of xlat_change_mem_attributes_ctx() into SPM. */ - assert((ret == 0) || (ret == -EINVAL)); - - return (ret == 0) ? SPRT_SUCCESS : SPRT_INVALID_PARAMETER; -} - -/******************************************************************************* - * This function handles all SMCs in the range reserved for SPRT. - ******************************************************************************/ -static uintptr_t sprt_smc_handler(uint32_t smc_fid, u_register_t x1, - u_register_t x2, u_register_t x3, - u_register_t x4, void *cookie, void *handle, - u_register_t flags) -{ - /* SPRT only supported from the Secure world */ - if (is_caller_non_secure(flags) == SMC_FROM_NON_SECURE) { - SMC_RET1(handle, SMC_UNK); - } - - assert(handle == cm_get_context(SECURE)); - - /* - * Only S-EL0 partitions are supported for now. Make the next ERET into - * the partition jump directly to S-EL0 instead of S-EL1. - */ - cm_set_elr_spsr_el3(SECURE, read_elr_el1(), read_spsr_el1()); - - switch (smc_fid) { - case SPRT_VERSION: - SMC_RET1(handle, SPRT_VERSION_COMPILED); - - case SPRT_PUT_RESPONSE_AARCH64: - spm_sp_synchronous_exit(SPRT_PUT_RESPONSE_AARCH64); - - case SPRT_YIELD_AARCH64: - spm_sp_synchronous_exit(SPRT_YIELD_AARCH64); - - case SPRT_MEMORY_PERM_ATTR_GET_AARCH64: - { - /* Get context of the SP in use by this CPU. */ - unsigned int linear_id = plat_my_core_pos(); - sp_context_t *sp_ctx = spm_cpu_get_sp_ctx(linear_id); - - SMC_RET1(handle, sprt_memory_perm_attr_get(sp_ctx, x1)); - } - - case SPRT_MEMORY_PERM_ATTR_SET_AARCH64: - { - /* Get context of the SP in use by this CPU. */ - unsigned int linear_id = plat_my_core_pos(); - sp_context_t *sp_ctx = spm_cpu_get_sp_ctx(linear_id); - - SMC_RET1(handle, sprt_memory_perm_attr_set(sp_ctx, x1, x2, x3)); - } - - default: - break; - } - - WARN("SPRT: Unsupported call 0x%08x\n", smc_fid); - SMC_RET1(handle, SPRT_NOT_SUPPORTED); -} - -DECLARE_RT_SVC( - sprt_handler, - OEN_SPRT_START, - OEN_SPRT_END, - SMC_TYPE_FAST, - NULL, - sprt_smc_handler -); diff --git a/services/std_svc/std_svc_setup.c b/services/std_svc/std_svc_setup.c index 1219b34..7a95c5b 100644 --- a/services/std_svc/std_svc_setup.c +++ b/services/std_svc/std_svc_setup.c @@ -45,7 +45,7 @@ ret = 1; } -#if ENABLE_SPM || SPM_MM +#if SPM_MM if (spm_setup() != 0) { ret = 1; }