1 /* 2 * Copyright (c) 2015, Linaro Limited 3 * 4 * This software is licensed under the terms of the GNU General Public 5 * License version 2, as published by the Free Software Foundation, and 6 * may be copied, distributed, and modified under those terms. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU General Public License for more details. 12 * 13 */ 14 15 #ifndef OPTEE_PRIVATE_H 16 #define OPTEE_PRIVATE_H 17 18 #include <linux/arm-smccc.h> 19 #include <linux/semaphore.h> 20 #include <linux/tee_drv.h> 21 #include <linux/types.h> 22 #include "optee_msg.h" 23 24 #define OPTEE_MAX_ARG_SIZE 1024 25 26 /* Some Global Platform error codes used in this driver */ 27 #define TEEC_SUCCESS 0x00000000 28 #define TEEC_ERROR_BAD_PARAMETERS 0xFFFF0006 29 #define TEEC_ERROR_COMMUNICATION 0xFFFF000E 30 #define TEEC_ERROR_OUT_OF_MEMORY 0xFFFF000C 31 32 #define TEEC_ORIGIN_COMMS 0x00000002 33 34 typedef void (optee_invoke_fn)(unsigned long, unsigned long, unsigned long, 35 unsigned long, unsigned long, unsigned long, 36 unsigned long, unsigned long, 37 struct arm_smccc_res *); 38 39 struct optee_call_queue { 40 /* Serializes access to this struct */ 41 struct mutex mutex; 42 struct list_head waiters; 43 }; 44 45 struct optee_wait_queue { 46 /* Serializes access to this struct */ 47 struct mutex mu; 48 struct list_head db; 49 }; 50 51 /** 52 * struct optee_supp - supplicant synchronization struct 53 * @ctx the context of current connected supplicant. 54 * if !NULL the supplicant device is available for use, 55 * else busy 56 * @ctx_mutex: held while accessing @ctx 57 * @func: supplicant function id to call 58 * @ret: call return value 59 * @num_params: number of elements in @param 60 * @param: parameters for @func 61 * @req_posted: if true, a request has been posted to the supplicant 62 * @supp_next_send: if true, next step is for supplicant to send response 63 * @thrd_mutex: held by the thread doing a request to supplicant 64 * @supp_mutex: held by supplicant while operating on this struct 65 * @data_to_supp: supplicant is waiting on this for next request 66 * @data_from_supp: requesting thread is waiting on this to get the result 67 */ 68 struct optee_supp { 69 struct tee_context *ctx; 70 /* Serializes access of ctx */ 71 struct mutex ctx_mutex; 72 73 u32 func; 74 u32 ret; 75 size_t num_params; 76 struct tee_param *param; 77 78 bool req_posted; 79 bool supp_next_send; 80 /* Serializes access to this struct for requesting thread */ 81 struct mutex thrd_mutex; 82 /* Serializes access to this struct for supplicant threads */ 83 struct mutex supp_mutex; 84 struct completion data_to_supp; 85 struct completion data_from_supp; 86 }; 87 88 /** 89 * struct optee - main service struct 90 * @supp_teedev: supplicant device 91 * @teedev: client device 92 * @invoke_fn: function to issue smc or hvc 93 * @call_queue: queue of threads waiting to call @invoke_fn 94 * @wait_queue: queue of threads from secure world waiting for a 95 * secure world sync object 96 * @supp: supplicant synchronization struct for RPC to supplicant 97 * @pool: shared memory pool 98 * @memremaped_shm virtual address of memory in shared memory pool 99 */ 100 struct optee { 101 struct tee_device *supp_teedev; 102 struct tee_device *teedev; 103 optee_invoke_fn *invoke_fn; 104 struct optee_call_queue call_queue; 105 struct optee_wait_queue wait_queue; 106 struct optee_supp supp; 107 struct tee_shm_pool *pool; 108 void *memremaped_shm; 109 }; 110 111 struct optee_session { 112 struct list_head list_node; 113 u32 session_id; 114 }; 115 116 struct optee_context_data { 117 /* Serializes access to this struct */ 118 struct mutex mutex; 119 struct list_head sess_list; 120 }; 121 122 struct optee_rpc_param { 123 u32 a0; 124 u32 a1; 125 u32 a2; 126 u32 a3; 127 u32 a4; 128 u32 a5; 129 u32 a6; 130 u32 a7; 131 }; 132 133 void optee_handle_rpc(struct tee_context *ctx, struct optee_rpc_param *param); 134 135 void optee_wait_queue_init(struct optee_wait_queue *wq); 136 void optee_wait_queue_exit(struct optee_wait_queue *wq); 137 138 u32 optee_supp_thrd_req(struct tee_context *ctx, u32 func, size_t num_params, 139 struct tee_param *param); 140 141 int optee_supp_read(struct tee_context *ctx, void __user *buf, size_t len); 142 int optee_supp_write(struct tee_context *ctx, void __user *buf, size_t len); 143 void optee_supp_init(struct optee_supp *supp); 144 void optee_supp_uninit(struct optee_supp *supp); 145 146 int optee_supp_recv(struct tee_context *ctx, u32 *func, u32 *num_params, 147 struct tee_param *param); 148 int optee_supp_send(struct tee_context *ctx, u32 ret, u32 num_params, 149 struct tee_param *param); 150 151 u32 optee_do_call_with_arg(struct tee_context *ctx, phys_addr_t parg); 152 int optee_open_session(struct tee_context *ctx, 153 struct tee_ioctl_open_session_arg *arg, 154 struct tee_param *param); 155 int optee_close_session(struct tee_context *ctx, u32 session); 156 int optee_invoke_func(struct tee_context *ctx, struct tee_ioctl_invoke_arg *arg, 157 struct tee_param *param); 158 int optee_cancel_req(struct tee_context *ctx, u32 cancel_id, u32 session); 159 160 void optee_enable_shm_cache(struct optee *optee); 161 void optee_disable_shm_cache(struct optee *optee); 162 163 int optee_from_msg_param(struct tee_param *params, size_t num_params, 164 const struct optee_msg_param *msg_params); 165 int optee_to_msg_param(struct optee_msg_param *msg_params, size_t num_params, 166 const struct tee_param *params); 167 168 /* 169 * Small helpers 170 */ 171 172 static inline void *reg_pair_to_ptr(u32 reg0, u32 reg1) 173 { 174 return (void *)(unsigned long)(((u64)reg0 << 32) | reg1); 175 } 176 177 static inline void reg_pair_from_64(u32 *reg0, u32 *reg1, u64 val) 178 { 179 *reg0 = val >> 32; 180 *reg1 = val; 181 } 182 183 #endif /*OPTEE_PRIVATE_H*/ 184