1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Permission is hereby granted, free of charge, to any person 5 * obtaining a copy of this software and associated documentation 6 * files (the "Software"), to deal in the Software without 7 * restriction, including without limitation the rights to use, copy, 8 * modify, merge, publish, distribute, sublicense, and/or sell copies 9 * of the Software, and to permit persons to whom the Software is 10 * furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be 13 * included in all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 * SOFTWARE. 23 */ 24 25 #ifndef TRUSTY_TRUSTY_IPC_H_ 26 #define TRUSTY_TRUSTY_IPC_H_ 27 28 #include <trusty/sysdeps.h> 29 #include <trusty/trusty_dev.h> 30 31 /* 32 * handle_t is an opaque 32 bit value that is used to reference an 33 * Trusty IPC channel 34 */ 35 typedef uint32_t handle_t; 36 37 #define INVALID_IPC_HANDLE 0 38 39 /* 40 * Error codes returned by Trusty IPC device function calls 41 */ 42 enum trusty_err { 43 TRUSTY_ERR_NONE = 0, 44 TRUSTY_ERR_GENERIC = -1, 45 TRUSTY_ERR_NOT_SUPPORTED = -2, 46 TRUSTY_ERR_NO_MEMORY = -3, 47 TRUSTY_ERR_INVALID_ARGS = -4, 48 TRUSTY_ERR_SECOS_ERR = -5, 49 TRUSTY_ERR_MSG_TOO_BIG = -6, 50 TRUSTY_ERR_NO_MSG = -7, 51 TRUSTY_ERR_CHANNEL_CLOSED = -8, 52 TRUSTY_ERR_SEND_BLOCKED = -9, 53 }; 54 /* 55 * Return codes for successful Trusty IPC events (failures return trusty_err) 56 */ 57 enum trusty_event_result { 58 TRUSTY_EVENT_HANDLED = 1, 59 TRUSTY_EVENT_NONE = 2, 60 }; 61 62 /* 63 * Combination of these values are used for the event field 64 * of trusty_ipc_event structure. 65 */ 66 enum trusty_ipc_event_type { 67 IPC_HANDLE_POLL_NONE = 0x0, 68 IPC_HANDLE_POLL_READY = 0x1, 69 IPC_HANDLE_POLL_ERROR = 0x2, 70 IPC_HANDLE_POLL_HUP = 0x4, 71 IPC_HANDLE_POLL_MSG = 0x8, 72 IPC_HANDLE_POLL_SEND_UNBLOCKED = 0x10, 73 }; 74 75 struct trusty_dev; 76 struct trusty_ipc_chan; 77 78 /* 79 * Trusty IPC event 80 * 81 * @event: event type 82 * @handle: handle this event is related to 83 * @cookie: cookie associated with handle 84 */ 85 struct trusty_ipc_event { 86 uint32_t event; 87 uint32_t handle; 88 uint64_t cookie; 89 }; 90 91 struct trusty_ipc_iovec { 92 void* base; 93 size_t len; 94 }; 95 96 /* 97 * Trusty IPC device 98 * 99 * @buf_vaddr: virtual address of shared buffer associated with device 100 * @buf_size: size of shared buffer 101 * @buf_ns: physical address info of shared buffer 102 * @tdev: trusty device 103 */ 104 struct trusty_ipc_dev { 105 void* buf_vaddr; 106 size_t buf_size; 107 trusty_shared_mem_id_t buf_id; 108 struct ns_mem_page_info buf_ns; 109 struct trusty_dev* tdev; 110 }; 111 112 /* 113 * Trusty IPC event handlers. 114 */ 115 struct trusty_ipc_ops { 116 int (*on_raw_event)(struct trusty_ipc_chan* chan, 117 struct trusty_ipc_event* evt); 118 int (*on_connect_complete)(struct trusty_ipc_chan* chan); 119 int (*on_send_unblocked)(struct trusty_ipc_chan* chan); 120 int (*on_message)(struct trusty_ipc_chan* chan); 121 int (*on_disconnect)(struct trusty_ipc_chan* chan); 122 }; 123 124 /* 125 * Trusty IPC channel. 126 * 127 * @ops_ctx: refers to additional data that may be used by trusty_ipc_ops 128 * @handle: identifier for channel 129 * @complete: completion status of last event on channel 130 * @dev: Trusty IPC device used by channel, initialized with 131 trusty_ipc_dev_create 132 * @ops: callbacks for Trusty events 133 */ 134 struct trusty_ipc_chan { 135 void* ops_ctx; 136 handle_t handle; 137 volatile int complete; 138 struct trusty_ipc_dev* dev; 139 struct trusty_ipc_ops* ops; 140 }; 141 142 /* 143 * Creates new Trusty IPC device on @tdev. Allocates shared buffer, and calls 144 * trusty_dev_init_ipc to register with secure side. Returns a trusty_err. 145 * 146 * @ipc_dev: new Trusty IPC device to be initialized 147 * @tdev: associated Trusty device 148 * @shared_buf_size: size of shared buffer to be allocated 149 */ 150 int trusty_ipc_dev_create(struct trusty_ipc_dev** ipc_dev, 151 struct trusty_dev* tdev, 152 size_t shared_buf_size); 153 /* 154 * Shutdown @dev. Frees shared buffer, and calls trusty_dev_shutdown_ipc 155 * to shutdown on the secure side. 156 */ 157 void trusty_ipc_dev_shutdown(struct trusty_ipc_dev* dev); 158 159 /* 160 * Calls into secure OS to initiate a new connection to a Trusty IPC service. 161 * Returns handle for the new channel, a trusty_err on error. 162 * 163 * @dev: Trusty IPC device initialized with trusty_ipc_dev_create 164 * @port: name of port to connect to on secure side 165 * @cookie: cookie associated with new channel. 166 */ 167 int trusty_ipc_dev_connect(struct trusty_ipc_dev* dev, 168 const char* port, 169 uint64_t cookie); 170 /* 171 * Calls into secure OS to close connection to Trusty IPC service. 172 * Returns a trusty_err. 173 * 174 * @dev: Trusty IPC device 175 * @chan: handle for connection, opened with trusty_ipc_dev_connect 176 */ 177 int trusty_ipc_dev_close(struct trusty_ipc_dev* dev, handle_t chan); 178 179 /* 180 * Calls into secure OS to check if there is a pending event. Returns a bool. 181 * 182 * @dev: Trusty IPC device 183 * @chan: handle for connection. Must be 0 which indicates any connection. 184 */ 185 bool trusty_ipc_dev_has_event(struct trusty_ipc_dev* dev, handle_t chan); 186 187 /* 188 * Calls into secure OS to receive pending event. Returns a trusty_err. 189 * 190 * @dev: Trusty IPC device 191 * @chan: handle for connection 192 * @event: pointer to output event struct 193 */ 194 int trusty_ipc_dev_get_event(struct trusty_ipc_dev* dev, 195 handle_t chan, 196 struct trusty_ipc_event* event); 197 /* 198 * Calls into secure OS to send message to channel. Returns a trusty_err. 199 * 200 * @dev: Trusty IPC device 201 * @chan: handle for connection 202 * @iovs: contains messages to be sent 203 * @iovs_cnt: number of iovecs to be sent 204 */ 205 int trusty_ipc_dev_send(struct trusty_ipc_dev* dev, 206 handle_t chan, 207 const struct trusty_ipc_iovec* iovs, 208 size_t iovs_cnt); 209 /* 210 * Calls into secure OS to receive message on channel. Returns number of bytes 211 * received on success, trusty_err on failure. 212 * 213 * @dev: Trusty IPC device 214 * @chan: handle for connection 215 * @iovs: contains received messages 216 * @iovs_cnt: number of iovecs received 217 */ 218 int trusty_ipc_dev_recv(struct trusty_ipc_dev* dev, 219 handle_t chan, 220 const struct trusty_ipc_iovec* iovs, 221 size_t iovs_cnt); 222 223 void trusty_ipc_dev_idle(struct trusty_ipc_dev* dev, bool event_poll); 224 225 /* 226 * Initializes @chan with default values and @dev. 227 */ 228 void trusty_ipc_chan_init(struct trusty_ipc_chan* chan, 229 struct trusty_ipc_dev* dev); 230 /* 231 * Calls trusty_ipc_dev_connect to get a handle for channel. 232 * Returns a trusty_err. 233 * 234 * @chan: channel to initialize with new handle 235 * @port: name of port to connect to on secure side 236 * @wait: flag to wait for connect to complete by polling for 237 * IPC_HANDLE_POLL_READY event 238 */ 239 int trusty_ipc_connect(struct trusty_ipc_chan* chan, 240 const char* port, 241 bool wait); 242 /* 243 * Calls trusty_ipc_dev_close and invalidates @chan. Returns a trusty_err. 244 */ 245 int trusty_ipc_close(struct trusty_ipc_chan* chan); 246 /* 247 * Calls trusty_ipc_dev_get_event to poll @dev for events. Handles 248 * events by calling appropriate callbacks. Returns nonnegative on success. 249 */ 250 int trusty_ipc_poll_for_event(struct trusty_ipc_dev* dev); 251 /* 252 * Calls trusty_ipc_dev_send to send a message. Returns a trusty_err. 253 * 254 * @chan: handle for connection 255 * @iovs: contains messages to be sent 256 * @iovs_cnt: number of iovecs to be sent 257 * @wait: flag to wait for send to complete 258 */ 259 int trusty_ipc_send(struct trusty_ipc_chan* chan, 260 const struct trusty_ipc_iovec* iovs, 261 size_t iovs_cnt, 262 bool wait); 263 /* 264 * Calls trusty_ipc_dev_recv to receive a message. Return number of bytes 265 * received on success, trusty_err on failure. 266 * 267 * @chan: handle for connection 268 * @iovs: contains received messages 269 * @iovs_cnt: number of iovecs received 270 * @wait: flag to wait for a message to receive 271 */ 272 int trusty_ipc_recv(struct trusty_ipc_chan* chan, 273 const struct trusty_ipc_iovec* iovs, 274 size_t iovs_cnt, 275 bool wait); 276 277 #endif /* TRUSTY_TRUSTY_IPC_H_ */ 278