/* * Copyright (C) 2016 The Android Open Source Project * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, copy, * modify, merge, publish, distribute, sublicense, and/or sell copies * of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef TRUSTY_TRUSTY_IPC_H_ #define TRUSTY_TRUSTY_IPC_H_ #include /* * handle_t is an opaque 32 bit value that is used to reference an * Trusty IPC channel */ typedef uint32_t handle_t; #define INVALID_IPC_HANDLE 0 /* * Error codes returned by Trusty IPC device function calls */ enum trusty_err { TRUSTY_ERR_NONE = 0, TRUSTY_ERR_GENERIC = -1, TRUSTY_ERR_NOT_SUPPORTED = -2, TRUSTY_ERR_NO_MEMORY = -3, TRUSTY_ERR_INVALID_ARGS = -4, TRUSTY_ERR_SECOS_ERR = -5, TRUSTY_ERR_MSG_TOO_BIG = -6, TRUSTY_ERR_NO_MSG = -7, TRUSTY_ERR_CHANNEL_CLOSED = -8, TRUSTY_ERR_SEND_BLOCKED = -9, }; /* * Return codes for successful Trusty IPC events (failures return trusty_err) */ enum trusty_event_result { TRUSTY_EVENT_HANDLED = 1, TRUSTY_EVENT_NONE = 2 }; /* * Combination of these values are used for the event field * of trusty_ipc_event structure. */ enum trusty_ipc_event_type { IPC_HANDLE_POLL_NONE = 0x0, IPC_HANDLE_POLL_READY = 0x1, IPC_HANDLE_POLL_ERROR = 0x2, IPC_HANDLE_POLL_HUP = 0x4, IPC_HANDLE_POLL_MSG = 0x8, IPC_HANDLE_POLL_SEND_UNBLOCKED = 0x10, }; struct trusty_dev; struct trusty_ipc_chan; /* * Trusty IPC event * * @event: event type * @handle: handle this event is related to * @cookie: cookie associated with handle */ struct trusty_ipc_event { uint32_t event; uint32_t handle; uint64_t cookie; }; struct trusty_ipc_iovec { void *base; size_t len; }; /* * Trusty IPC device * * @buf_vaddr: virtual address of shared buffer associated with device * @buf_size: size of shared buffer * @buf_ns: physical address info of shared buffer * @tdev: trusty device */ struct trusty_ipc_dev { void *buf_vaddr; size_t buf_size; struct ns_mem_page_info buf_ns; struct trusty_dev *tdev; }; /* * Trusty IPC event handlers. */ struct trusty_ipc_ops { int (*on_raw_event)(struct trusty_ipc_chan *chan, struct trusty_ipc_event *evt); int (*on_connect_complete)(struct trusty_ipc_chan *chan); int (*on_send_unblocked)(struct trusty_ipc_chan *chan); int (*on_message)(struct trusty_ipc_chan *chan); int (*on_disconnect)(struct trusty_ipc_chan *chan); }; /* * Trusty IPC channel. * * @ops_ctx: refers to additional data that may be used by trusty_ipc_ops * @handle: identifier for channel * @complete: completion status of last event on channel * @dev: Trusty IPC device used by channel, initialized with trusty_ipc_dev_create * @ops: callbacks for Trusty events */ struct trusty_ipc_chan { void *ops_ctx; handle_t handle; volatile int complete; struct trusty_ipc_dev *dev; struct trusty_ipc_ops *ops; }; /* * Creates new Trusty IPC device on @tdev. Allocates shared buffer, and calls * trusty_dev_init_ipc to register with secure side. Returns a trusty_err. * * @ipc_dev: new Trusty IPC device to be initialized * @tdev: associated Trusty device * @shared_buf_size: size of shared buffer to be allocated */ int trusty_ipc_dev_create(struct trusty_ipc_dev **ipc_dev, struct trusty_dev *tdev, size_t shared_buf_size); /* * Shutdown @dev. Frees shared buffer, and calls trusty_dev_shutdown_ipc * to shutdown on the secure side. */ void trusty_ipc_dev_shutdown(struct trusty_ipc_dev *dev); /* * Calls into secure OS to initiate a new connection to a Trusty IPC service. * Returns handle for the new channel, a trusty_err on error. * * @dev: Trusty IPC device initialized with trusty_ipc_dev_create * @port: name of port to connect to on secure side * @cookie: cookie associated with new channel. */ int trusty_ipc_dev_connect(struct trusty_ipc_dev *dev, const char *port, uint64_t cookie); /* * Calls into secure OS to close connection to Trusty IPC service. * Returns a trusty_err. * * @dev: Trusty IPC device * @chan: handle for connection, opened with trusty_ipc_dev_connect */ int trusty_ipc_dev_close(struct trusty_ipc_dev *dev, handle_t chan); /* * Calls into secure OS to receive pending event. Returns a trusty_err. * * @dev: Trusty IPC device * @chan: handle for connection * @event: pointer to output event struct */ int trusty_ipc_dev_get_event(struct trusty_ipc_dev *dev, handle_t chan, struct trusty_ipc_event *event); /* * Calls into secure OS to send message to channel. Returns a trusty_err. * * @dev: Trusty IPC device * @chan: handle for connection * @iovs: contains messages to be sent * @iovs_cnt: number of iovecs to be sent */ int trusty_ipc_dev_send(struct trusty_ipc_dev *dev, handle_t chan, const struct trusty_ipc_iovec *iovs, size_t iovs_cnt); /* * Calls into secure OS to receive message on channel. Returns number of bytes * received on success, trusty_err on failure. * * @dev: Trusty IPC device * @chan: handle for connection * @iovs: contains received messages * @iovs_cnt: number of iovecs received */ int trusty_ipc_dev_recv(struct trusty_ipc_dev *dev, handle_t chan, const struct trusty_ipc_iovec *iovs, size_t iovs_cnt); void trusty_ipc_dev_idle(struct trusty_ipc_dev *dev); /* * Initializes @chan with default values and @dev. */ void trusty_ipc_chan_init(struct trusty_ipc_chan *chan, struct trusty_ipc_dev *dev); /* * Calls trusty_ipc_dev_connect to get a handle for channel. * Returns a trusty_err. * * @chan: channel to initialize with new handle * @port: name of port to connect to on secure side * @wait: flag to wait for connect to complete by polling for * IPC_HANDLE_POLL_READY event */ int trusty_ipc_connect(struct trusty_ipc_chan *chan, const char *port, bool wait); /* * Calls trusty_ipc_dev_close and invalidates @chan. Returns a trusty_err. */ int trusty_ipc_close(struct trusty_ipc_chan *chan); /* * Calls trusty_ipc_dev_get_event to poll @dev for events. Handles * events by calling appropriate callbacks. Returns nonnegative on success. */ int trusty_ipc_poll_for_event(struct trusty_ipc_dev *dev); /* * Calls trusty_ipc_dev_send to send a message. Returns a trusty_err. * * @chan: handle for connection * @iovs: contains messages to be sent * @iovs_cnt: number of iovecs to be sent * @wait: flag to wait for send to complete */ int trusty_ipc_send(struct trusty_ipc_chan *chan, const struct trusty_ipc_iovec *iovs, size_t iovs_cnt, bool wait); /* * Calls trusty_ipc_dev_recv to receive a message. Return number of bytes * received on success, trusty_err on failure. * * @chan: handle for connection * @iovs: contains received messages * @iovs_cnt: number of iovecs received * @wait: flag to wait for a message to receive */ int trusty_ipc_recv(struct trusty_ipc_chan *chan, const struct trusty_ipc_iovec *iovs, size_t iovs_cnt, bool wait); #endif /* TRUSTY_TRUSTY_IPC_H_ */