1 /*
2 * Copyright (c) 2013-2014, Google, Inc. All rights reserved
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * 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 NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #ifndef _LIB_TRUSTY_VQUEUE_H
25 #define _LIB_TRUSTY_VQUEUE_H
26
27 #include <arch/ops.h>
28 #include <kernel/event.h>
29 #include <kernel/mutex.h>
30 #include <lib/extmem/extmem.h>
31 #include <lib/trusty/uio.h>
32 #include <stdint.h>
33 #include <string.h>
34 #include <sys/types.h>
35
36 #include <virtio/virtio_ring.h>
37
38 struct vqueue;
39 typedef int (*vqueue_cb_t)(struct vqueue* vq, void* priv);
40
41 struct vqueue {
42 uint32_t id;
43
44 struct vring vring;
45 vaddr_t vring_addr;
46 size_t vring_sz;
47
48 spin_lock_t slock;
49
50 uint16_t last_avail_idx;
51
52 event_t avail_event;
53
54 /* called when the vq is kicked *from* the other side */
55 vqueue_cb_t notify_cb;
56
57 /* called when we want to kick the other side */
58 vqueue_cb_t kick_cb;
59
60 void* priv;
61 };
62
63 struct vqueue_iovs {
64 uint cnt; /* max number of iovs available */
65 uint used; /* number of iovs currently in use */
66 size_t len; /* total length of all used iovs */
67 ext_mem_obj_id_t* shared_mem_id;
68 struct iovec_kern* iovs;
69 };
70
71 struct vqueue_buf {
72 uint16_t head;
73 uint16_t padding;
74 struct vqueue_iovs in_iovs;
75 struct vqueue_iovs out_iovs;
76 };
77
78 struct vqueue_mapped_list {
79 struct bst_root list;
80 mutex_t lock;
81 bool in_direction;
82 };
83
84 int vqueue_init(struct vqueue* vq,
85 uint32_t id,
86 ext_mem_client_id_t client_id,
87 ext_mem_obj_id_t shared_mem_id,
88 uint num,
89 ulong align,
90 void* priv,
91 vqueue_cb_t notify_cb,
92 vqueue_cb_t kick_cb);
93
94 void vqueue_destroy(struct vqueue* vq);
95
96 int vqueue_get_avail_buf(struct vqueue* vq, struct vqueue_buf* iovbuf);
97
98 int vqueue_map_iovs(ext_mem_client_id_t client_id,
99 struct vqueue_iovs* vqiovs,
100 u_int flags,
101 struct vqueue_mapped_list* mapped_list);
102 void vqueue_unmap_iovs(struct vqueue_iovs* vqiovs,
103 struct vqueue_mapped_list* mapped_list);
104
105 int vqueue_unmap_memid(ext_mem_obj_id_t id,
106 struct vqueue_mapped_list* mapped_list[],
107 int list_cnt);
108
109 int vqueue_add_buf(struct vqueue* vq, struct vqueue_buf* buf, uint32_t len);
110
111 void vqueue_signal_avail(struct vqueue* vq);
112
vqueue_id(struct vqueue * vq)113 static inline uint32_t vqueue_id(struct vqueue* vq) {
114 return vq->id;
115 }
116
vqueue_notify(struct vqueue * vq)117 static inline int vqueue_notify(struct vqueue* vq) {
118 if (vq->notify_cb)
119 return vq->notify_cb(vq, vq->priv);
120 return 0;
121 }
122
vqueue_kick(struct vqueue * vq)123 static inline int vqueue_kick(struct vqueue* vq) {
124 if (vq->kick_cb)
125 return vq->kick_cb(vq, vq->priv);
126 return 0;
127 }
128
129 #endif /* _LIB_TRUSTY_VQUEUE_H */
130