blob: ce7cbd126aa1d4239460aabdecaf795706648bc7 [file] [log] [blame]
/*
* 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 <trusty/sysdeps.h>
/*
* 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_ */