1 /* 2 * Copyright (c) 2017-2021, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef SPM_MM_SVC_H 8 #define SPM_MM_SVC_H 9 10 #include <lib/utils_def.h> 11 12 /* 13 * The MM_VERSION_XXX definitions are used when responding to the 14 * MM_VERSION_AARCH32 service request. The version returned is different between 15 * this request and the SPM_MM_VERSION_AARCH32 request - both have been retained 16 * for compatibility. 17 */ 18 #define MM_VERSION_MAJOR U(1) 19 #define MM_VERSION_MAJOR_SHIFT 16 20 #define MM_VERSION_MAJOR_MASK U(0x7FFF) 21 #define MM_VERSION_MINOR U(0) 22 #define MM_VERSION_MINOR_SHIFT 0 23 #define MM_VERSION_MINOR_MASK U(0xFFFF) 24 #define MM_VERSION_FORM(major, minor) ((major << MM_VERSION_MAJOR_SHIFT) | \ 25 (minor)) 26 #define MM_VERSION_COMPILED MM_VERSION_FORM(MM_VERSION_MAJOR, \ 27 MM_VERSION_MINOR) 28 29 #define SPM_MM_VERSION_MAJOR U(0) 30 #define SPM_MM_VERSION_MAJOR_SHIFT 16 31 #define SPM_MM_VERSION_MAJOR_MASK U(0x7FFF) 32 #define SPM_MM_VERSION_MINOR U(1) 33 #define SPM_MM_VERSION_MINOR_SHIFT 0 34 #define SPM_MM_VERSION_MINOR_MASK U(0xFFFF) 35 #define SPM_MM_VERSION_FORM(major, minor) ((major << \ 36 SPM_MM_VERSION_MAJOR_SHIFT) | \ 37 (minor)) 38 #define SPM_MM_VERSION_COMPILED SPM_MM_VERSION_FORM(SPM_MM_VERSION_MAJOR, \ 39 SPM_MM_VERSION_MINOR) 40 41 /* These macros are used to identify SPM-MM calls using the SMC function ID */ 42 #define SPM_MM_FID_MASK U(0xffff) 43 #define SPM_MM_FID_MIN_VALUE U(0x40) 44 #define SPM_MM_FID_MAX_VALUE U(0x7f) 45 #define is_spm_mm_fid(_fid) \ 46 ((((_fid) & SPM_MM_FID_MASK) >= SPM_MM_FID_MIN_VALUE) && \ 47 (((_fid) & SPM_MM_FID_MASK) <= SPM_MM_FID_MAX_VALUE)) 48 49 /* 50 * SMC IDs defined in [1] for accessing MM services from the Non-secure world. 51 * These FIDs occupy the range 0x40 - 0x5f. 52 * [1] DEN0060A_ARM_MM_Interface_Specification.pdf 53 */ 54 #define MM_VERSION_AARCH32 U(0x84000040) 55 #define MM_COMMUNICATE_AARCH64 U(0xC4000041) 56 #define MM_COMMUNICATE_AARCH32 U(0x84000041) 57 58 /* 59 * SMC IDs defined for accessing services implemented by the Secure Partition 60 * Manager from the Secure Partition(s). These services enable a partition to 61 * handle delegated events and request privileged operations from the manager. 62 * They occupy the range 0x60-0x7f. 63 */ 64 #define SPM_MM_VERSION_AARCH32 U(0x84000060) 65 #define MM_SP_EVENT_COMPLETE_AARCH64 U(0xC4000061) 66 #define MM_SP_MEMORY_ATTRIBUTES_GET_AARCH64 U(0xC4000064) 67 #define MM_SP_MEMORY_ATTRIBUTES_SET_AARCH64 U(0xC4000065) 68 69 #ifndef __ASSEMBLER__ 70 71 #include <stdint.h> 72 #include <lib/spinlock.h> 73 #include <lib/xlat_tables/xlat_tables_v2.h> 74 #include <lib/utils_def.h> 75 76 /* 77 * SMC IDs defined in [1] for accessing MM services from the Non-secure world. 78 * These FIDs occupy the range 0x40 - 0x5f. 79 * [1] DEN0060A_ARM_MM_Interface_Specification.pdf 80 */ 81 #define MM_INTERFACE_ID_AARCH64 U(0xC4000041) 82 #define MM_INTERFACE_ID_AARCH32 U(0x84000041) 83 84 /* 85 * Macros used by SP_MEMORY_ATTRIBUTES_SET_AARCH64. 86 */ 87 88 #define SP_MEMORY_ATTRIBUTES_ACCESS_NOACCESS U(0) 89 #define SP_MEMORY_ATTRIBUTES_ACCESS_RW U(1) 90 /* Value U(2) is reserved. */ 91 #define SP_MEMORY_ATTRIBUTES_ACCESS_RO U(3) 92 #define SP_MEMORY_ATTRIBUTES_ACCESS_MASK U(3) 93 #define SP_MEMORY_ATTRIBUTES_ACCESS_SHIFT U(0) 94 95 #define SP_MEMORY_ATTRIBUTES_EXEC (U(0) << 2) 96 #define SP_MEMORY_ATTRIBUTES_NON_EXEC (U(1) << 2) 97 98 99 /* SPM error codes. */ 100 #define SPM_SUCCESS 0 101 #define SPM_NOT_SUPPORTED -1 102 #define SPM_INVALID_PARAMETER -2 103 #define SPM_DENIED -3 104 #define SPM_NO_MEMORY -5 105 106 typedef enum sp_state { 107 SP_STATE_RESET = 0, 108 SP_STATE_IDLE, 109 SP_STATE_BUSY 110 } sp_state_t; 111 112 typedef struct sp_context { 113 uint64_t c_rt_ctx; 114 cpu_context_t cpu_ctx; 115 xlat_ctx_t *xlat_ctx_handle; 116 uint64_t sp_stack_base; 117 uint64_t sp_pcpu_stack_size; 118 119 sp_state_t state; 120 spinlock_t state_lock; 121 } sp_context_t; 122 123 /* Setup Function for different SP types. */ 124 void spm_sp_common_setup(sp_context_t *sp_ctx); 125 void spm_el0_sp_setup(sp_context_t *sp_ctx); 126 void spm_el1_sp_setup(sp_context_t *sp_ctx); 127 128 int32_t spm_memory_attributes_get_smc_handler(sp_context_t *sp_ctx, 129 uintptr_t base_va); 130 int spm_memory_attributes_set_smc_handler(sp_context_t *sp_ctx, 131 u_register_t page_address, 132 u_register_t pages_count, 133 u_register_t smc_attributes); 134 135 void sp_state_set(sp_context_t *sp_ptr, sp_state_t state); 136 void sp_state_wait_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to); 137 int sp_state_try_switch(sp_context_t *sp_ptr, sp_state_t from, sp_state_t to); 138 uint64_t spm_sp_synchronous_entry(sp_context_t *ctx); 139 __dead2 void spm_sp_synchronous_exit(sp_context_t *ctx, uint64_t rc); 140 141 int32_t spm_mm_setup(void); 142 143 uint64_t spm_mm_smc_handler(uint32_t smc_fid, 144 uint64_t x1, 145 uint64_t x2, 146 uint64_t x3, 147 uint64_t x4, 148 void *cookie, 149 void *handle, 150 uint64_t flags); 151 152 /* Helper to enter a secure partition */ 153 uint64_t spm_mm_sp_call(uint32_t smc_fid, 154 uint64_t x1, 155 uint64_t x2, 156 uint64_t x3); 157 158 #endif /* __ASSEMBLER__ */ 159 160 #endif /* SPM_MM_SVC_H */ 161