1 /* 2 * Copyright (C) 2022 Huawei Technologies Co., Ltd. 3 * Licensed under the Mulan PSL v2. 4 * You can use this software according to the terms and conditions of the Mulan PSL v2. 5 * You may obtain a copy of Mulan PSL v2 at: 6 * http://license.coscl.org.cn/MulanPSL2 7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR 8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR 9 * PURPOSE. 10 * See the Mulan PSL v2 for more details. 11 */ 12 13 #ifndef TEED_PRIVATE_H 14 #define TEED_PRIVATE_H 15 16 #include <arch.h> 17 #include <context.h> 18 #include <interrupt_mgmt.h> 19 #include <platform_def.h> 20 #include <psci.h> 21 22 /* 23 * Secure Payload PM state information e.g. SP is suspended, uninitialised etc 24 * and macros to access the state information in the per-cpu 'state' flags 25 */ 26 #define TEE_PSTATE_OFF 0 27 #define TEE_PSTATE_ON 1 28 #define TEE_PSTATE_SUSPEND 2 29 #define TEE_PSTATE_SHIFT 0u 30 #define TEE_PSTATE_MASK 0x3u 31 #define get_tee_pstate(state) (((state) >> TEE_PSTATE_SHIFT) & TEE_PSTATE_MASK) 32 33 #define clr_tee_pstate(state) \ 34 do { \ 35 ((state) &= ~(TEE_PSTATE_MASK << \ 36 TEE_PSTATE_SHIFT)); \ 37 } while (0) 38 39 #define set_tee_pstate(st, pst) \ 40 do { \ 41 clr_tee_pstate(st); \ 42 (st) |= ((pst) & TEE_PSTATE_MASK) << \ 43 TEE_PSTATE_SHIFT; \ 44 } while (0) 45 46 /* smc id added for TEE */ 47 #define TEE_STD_REE_SIQ 0xb200000a 48 #define TEE_STD_CRASH 0xb200000b 49 #define TEE_ENTRY_DONE_AARCH32 0xb2000000 50 #define TEE_ON_DONE_AARCH32 0xb2000001 51 #define TEE_OFF_DONE_AARCH32 0xb2000002 52 #define TEE_SUSPEND_DONE_AARCH32 0xb2000003 53 #define TEE_RESUME_DONE_AARCH32 0xb2000004 54 #define TEE_PREEMPTED_AARCH32 0xb2000005 55 #define TEE_HANDLED_S_EL1_FIQ_AARCH32 0xb2000006 56 57 /* 58 * Function identifiers to send smc request to SP from NS and the the repsonse 59 * to NS from SP 60 */ 61 #define TEE_STD_REQUEST 0xb2000008 62 #define TEE_STD_RESPONSE 0xb2000009 63 64 #define CPU_INIT_DONE 1 65 #define CPU_IDLE_STATE 0 66 #define CPU_SUSPEND_STATE 1 67 /* 68 * This flag is used by the TEED to determine if the TEE is servicing a yielding 69 * SMC request prior to programming the next entry into the TEE e.g. if TEE 70 * execution is preempted by a non-secure interrupt and handed control to the 71 * normal world. If another request which is distinct from what the TEE was 72 * previously doing arrives, then this flag will be help the TEED to either 73 * reject the new request or service it while ensuring that the previous context 74 * is not corrupted. 75 */ 76 #define YIELD_SMC_ACTIVE_FLAG_SHIFT 2u 77 #define YIELD_SMC_ACTIVE_FLAG_MASK 1u 78 #define SMC_INACTIVE 0 79 #define SMC_ACTIVE 1 80 #define get_yield_smc_active_flag(state) \ 81 (((state) >> YIELD_SMC_ACTIVE_FLAG_SHIFT) \ 82 & YIELD_SMC_ACTIVE_FLAG_MASK) 83 84 #define set_yield_smc_active_flag(state) \ 85 do { \ 86 ((state) |= \ 87 1u << YIELD_SMC_ACTIVE_FLAG_SHIFT); \ 88 } while (0) 89 90 #define clr_yield_smc_active_flag(state) \ 91 do { \ 92 ((state) &= \ 93 ~(YIELD_SMC_ACTIVE_FLAG_MASK \ 94 << YIELD_SMC_ACTIVE_FLAG_SHIFT)); \ 95 } while (0) 96 /* 97 * This flag is used by the TEED to determine if the TEE has crashed in any way 98 * and it is impossible to continue. The flag will disable forwarding any calls 99 * to secure os system. 100 */ 101 #define INIT_CONTEXT_NOT_SAVED 0x0 102 #define INIT_CONTEXT_SAVED 0x1 103 #define INVALID_PC_ADDR 0x0 104 #define INVALID_C_RT_CTX 0x0 105 #define STD_NO_CRASH_FLAG 0x0 106 #define SECURE_WORLD_FLAG 0x0 107 #define TEE_SETUP_FAIL 0x1 108 #define STD_SMC_CRASH_FLAG_SHIFT 0x3u 109 #define STD_SMC_CRASH_FLAG_MASK 0x1u 110 #define get_std_crash_flag(state) \ 111 (((state) >> STD_SMC_CRASH_FLAG_SHIFT) & \ 112 STD_SMC_CRASH_FLAG_MASK) 113 114 #define set_std_crash_flag(state) \ 115 do { \ 116 ((state) |= \ 117 1 << STD_SMC_CRASH_FLAG_SHIFT); \ 118 } while (0) 119 120 /* Secure Payload execution state information i.e. aarch32 or aarch64 */ 121 #define TEE_AARCH32 MODE_RW_32 122 #define TEE_AARCH64 MODE_RW_64 123 124 /* The SPD should know the type of Secure Payload */ 125 #define TEE_TYPE_UP PSCI_TOS_NOT_UP_MIG_CAP 126 #define TEE_TYPE_UPM PSCI_TOS_UP_MIG_CAP 127 #define TEE_TYPE_MP PSCI_TOS_NOT_PRESENT_MP 128 129 /* 130 * Secure Payload migrate type information as known to the SPD. We assume that 131 * the SPD is dealing with an MP Secure Payload. 132 */ 133 #define TEE_MIGRATE_INFO TEE_TYPE_MP 134 135 /* 136 * Number of cpus that the present on this platform. Rely on a topology 137 * tree to determine this in the future to avoid assumptions about mpidr 138 * allocation 139 */ 140 #define TEED_CORE_COUNT PLATFORM_CORE_COUNT 141 142 /* 143 * Constants that allow assembler code to preserve callee-saved registers of the 144 * C runtime context while performing a security state switch. 145 */ 146 #define TEED_C_RT_CTX_X19 0x0 147 #define TEED_C_RT_CTX_X20 0x8 148 #define TEED_C_RT_CTX_X21 0x10 149 #define TEED_C_RT_CTX_X22 0x18 150 #define TEED_C_RT_CTX_X23 0x20 151 #define TEED_C_RT_CTX_X24 0x28 152 #define TEED_C_RT_CTX_X25 0x30 153 #define TEED_C_RT_CTX_X26 0x38 154 #define TEED_C_RT_CTX_X27 0x40 155 #define TEED_C_RT_CTX_X28 0x48 156 #define TEED_C_RT_CTX_X29 0x50 157 #define TEED_C_RT_CTX_X30 0x58 158 #define TEED_C_RT_CTX_SIZE 0x60 159 #define TEED_C_RT_CTX_ENTRIES (TEED_C_RT_CTX_SIZE >> DWORD_SHIFT) 160 161 /* 162 * Constants that allow assembler code to preserve caller-saved registers of the 163 * SP context while performing a TEE preemption. 164 * Note: These offsets have to match with the offsets for the corresponding 165 * registers in cpu_context as we are using memcpy to copy the values from 166 * cpu_context to sp_ctx. 167 */ 168 #define TEED_SP_CTX_X0 0x0 169 #define TEED_SP_CTX_X1 0x8 170 #define TEED_SP_CTX_X2 0x10 171 #define TEED_SP_CTX_X3 0x18 172 #define TEED_SP_CTX_X4 0x20 173 #define TEED_SP_CTX_X5 0x28 174 #define TEED_SP_CTX_X6 0x30 175 #define TEED_SP_CTX_X7 0x38 176 #define TEED_SP_CTX_X8 0x40 177 #define TEED_SP_CTX_X9 0x48 178 #define TEED_SP_CTX_X10 0x50 179 #define TEED_SP_CTX_X11 0x58 180 #define TEED_SP_CTX_X12 0x60 181 #define TEED_SP_CTX_X13 0x68 182 #define TEED_SP_CTX_X14 0x70 183 #define TEED_SP_CTX_X15 0x78 184 #define TEED_SP_CTX_X16 0x80 185 #define TEED_SP_CTX_X17 0x88 186 #define TEED_SP_CTX_SIZE 0x90 187 #define TEED_SP_CTX_ENTRIES (TEED_SP_CTX_SIZE >> DWORD_SHIFT) 188 189 #ifndef __ASSEMBLY__ 190 191 #include <stdint.h> 192 193 /* 194 * The number of arguments to save during a SMC call for TEE. 195 * Currently only x1 and x2 are used by TEE. 196 */ 197 #define TEE_NUM_ARGS 0x2 198 199 /* AArch64 callee saved general purpose register context structure. */ 200 DEFINE_REG_STRUCT(c_rt_regs, TEED_C_RT_CTX_ENTRIES); 201 202 /* 203 * Compile time assertion to ensure that both the compiler and linker 204 * have the same double word aligned view of the size of the C runtime 205 * register context. 206 */ 207 CASSERT(TEED_C_RT_CTX_SIZE == sizeof(c_rt_regs_t), \ 208 assert_spd_c_rt_regs_size_mismatch); 209 210 /* SEL1 Secure payload (SP) caller saved register context structure. */ 211 DEFINE_REG_STRUCT(sp_ctx_regs, TEED_SP_CTX_ENTRIES); 212 213 /* 214 * Compile time assertion to ensure that both the compiler and linker 215 * have the same double word aligned view of the size of the C runtime 216 * register context. 217 */ 218 CASSERT(TEED_SP_CTX_SIZE == sizeof(sp_ctx_regs_t), \ 219 assert_spd_sp_regs_size_mismatch); 220 221 /* 222 * Structure which helps the SPD to maintain the per-cpu state of the SP. 223 * 'spsr_el3' - temporary copy to allow S-EL1 interrupt handling when 224 * the TEE has been preempted. 225 * 'elr_el3' - temporary copy to allow S-EL1 interrupt handling when 226 * the TEE has been preempted. 227 * 'state' - collection of flags to track SP state e.g. on/off 228 * 'mpidr' - mpidr to associate a context with a cpu 229 * 'rt_context' - stack address to restore C runtime context from after 230 * returning from a synchronous entry into the SP. 231 * 'cpu_context' - space to maintain SP architectural state 232 * 'saved_tee_args' - space to store arguments for TEE arithmetic operations 233 * which will queried using the TEE_GET_ARGS SMC by TEE. 234 * 'sp_ctx' - space to save the SEL1 Secure Payload(SP) caller saved 235 * register context after it has been preempted by an EL3 236 * routed NS interrupt and when a Secure Interrupt is taken 237 * to SP. 238 */ 239 typedef struct tee_context { 240 uint64_t elr_el3; 241 uint32_t spsr_el3; 242 uint32_t state; 243 uint64_t mpidr; 244 uint64_t rt_context; 245 cpu_context_t cpu_context; 246 uint64_t saved_tee_args[TEE_NUM_ARGS]; 247 } tee_context_t; 248 249 typedef struct tee_vectors { 250 uint32_t yield_smc_entry; 251 uint32_t fast_smc_entry; 252 uint32_t cpu_on_entry; 253 uint32_t cpu_off_entry; 254 uint32_t cpu_resume_entry; 255 uint32_t cpu_suspend_entry; 256 uint32_t sel1_intr_entry; 257 uint32_t irq_return_entry; 258 uint32_t s4_resume_entry; 259 uint32_t s4_suspend_entry; 260 uint32_t system_off_entry; 261 uint32_t system_reset_entry; 262 uint32_t abort_yield_smc_entry; 263 } tee_vectors_t; 264 265 typedef struct smc_registers { 266 u_register_t x1; 267 u_register_t x2; 268 u_register_t x3; 269 u_register_t x4; 270 } smc_registers_t; 271 272 /* Helper macros to store and retrieve tee args from tee_context */ 273 #define store_tee_args(_tee_ctx, _x1, _x2) \ 274 do { \ 275 (_tee_ctx)->saved_tee_args[0] = _x1; \ 276 (_tee_ctx)->saved_tee_args[1] = _x2; \ 277 } while (0) 278 279 #define get_tee_args(_tee_ctx, _x1, _x2) \ 280 do { \ 281 _x1 = (_tee_ctx)->saved_tee_args[0]; \ 282 _x2 = (_tee_ctx)->saved_tee_args[1]; \ 283 } while (0) 284 285 /* TEED power management handlers */ 286 const spd_pm_ops_t *get_teed_pm(void); 287 288 /* Forward declarations */ 289 typedef struct tee_vectors tee_vectors_t; 290 tee_context_t* get_teed_sp_context(const uint32_t linear_id); 291 uint64_t get_teed_sp_context_size(void); 292 tee_context_t *get_teed_sp_context_ptr(void); 293 tee_context_t* get_teed_sp_init_context(void); 294 int64_t get_tee_init_context_saved(void); 295 void set_tee_init_context_saved(int64_t tee_init_context_saved); 296 uint64_t get_primary_cpu_mpidr(void); 297 void set_primary_cpu_mpidr(uint64_t primary_cpu_mpidr_in); 298 tee_vectors_t* get_tee_vectors_t(void); 299 void set_tee_vectors_t(tee_vectors_t *const tee_vectors_tmp); 300 uint64_t plat_arm_calc_core_pos(uint64_t mpidr); 301 302 #endif /* __ASSEMBLY__ */ 303 304 #endif /* TEED_PRIVATE_H */ 305