1/*
2 * Copyright (c) 2018, ETH Zurich.
3 * All rights reserved.
4 *
5 * This file is distributed under the terms in the attached LICENSE file.
6 * If you do not find this file, copies can be found by writing to:
7 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH8092 Zurich.
8 * Attn: Systems Group.
9 */
10
11#ifndef DRIVERKIT_IOMMU_H
12#define DRIVERKIT_IOMMU_H 1
13
14#include <barrelfish/types.h>
15#include <errors/errno.h>
16
17/* forward declaration of the iommu client state */
18struct iommu_client;
19
20
21/**
22 * @brief initializes the IOMMU client library with the IOMMU endpoint
23 *
24 * @param ep the IOMMU endpoint
25 * @param cl returns a pointer ot the iommu client
26 *
27 * @return SYS_ERR_OK on success, errval on failure
28 *
29 * This function initializes the connection, allocates the root vnode etc.
30 */
31errval_t driverkit_iommu_client_init_cl(struct capref ep, struct iommu_client **cl);
32errval_t driverkit_iommu_client_init(struct capref ep);
33
34
35/**
36 * @brief connects to the IOMMU service
37 *
38 * @param ep the IOMMU endpoint
39 * @param cl returns a pointer ot the iommu client
40 *
41 * @return SYS_ERR_OK on success, errval on failure
42 *
43 * This just initializes the connecton to the IOMMU
44 */
45errval_t driverkit_iommu_client_connect_cl(struct capref ep,
46                                           struct iommu_client **cl);
47errval_t driverkit_iommu_client_connect(struct capref ep);
48
49
50/**
51 * @brief tears down a connection to the IOMMU service
52 *
53 * @param cl the iommu client
54 *
55 * @return SYS_ERR_OK on success, errval on failure
56 */
57errval_t driverkit_iommu_client_disconnect_cl(struct iommu_client *cl);
58errval_t driverkit_iommu_client_disconnect(void);
59
60
61/**
62 * @brief checks if there is an IOMMU present
63 *
64 * @param the pointer ot the IOMMU client state
65 *
66 * @return True if there is an IOMMU present
67 *         False if there is no IOMMU present
68 */
69bool driverkit_iommu_present(struct iommu_client *cl);
70
71
72/**
73 * @brief sets the default iommu client to be used
74 *
75 * @param cl    the iommu client should be taken as default
76 *
77 * @return SYS_ERR_OK on success, errval on failure
78 */
79errval_t driverkit_iommu_set_default_client(struct iommu_client *cl);
80
81
82/**
83 * @brief returns the default iommu client
84 *
85 * @return pointer to the default iommu state
86 */
87struct iommu_client *driverkit_iommu_get_default_client(void);
88
89
90/*
91 * ============================================================================
92 * Low-level interface
93 * ============================================================================
94 */
95
96
97/**
98 * @brief sets the root table pointer of the IOMMU
99 *
100 * @param rootvnode the root page table (vnode)
101 *
102 * @return SYS_ERR_OK on success, errval on failure
103 */
104errval_t driverkit_iommu_set_root_vnode(struct iommu_client *cl,
105                                        struct capref rootvnode);
106
107
108/**
109 * @brief obtains the capability type for the root level vnode
110 *
111 * @return
112 */
113enum objtype driverkit_iommu_get_root_vnode_type(struct iommu_client *cl);
114
115
116/**
117 * @brief obtains the maximu supported page size
118 *
119 * @return
120 */
121size_t driverkit_iommu_get_max_pagesize(struct iommu_client *cl);
122
123/**
124 * @brief obtains the model node id of the  protected device
125 *
126 * @return the model node id
127 */
128int32_t driverkit_iommu_get_nodeid(struct iommu_client *cl);
129
130
131/**
132 * @brief maps a vnode or a frame cap into a vnode cap
133 *
134 * @param cl    the iommu client
135 * @param dst   destination vnode to map into
136 * @param src   the source capability to be mapped
137 * @param slot  the slot to map into
138 * @param attr  attributes for the mapping
139 * @param off   offset into the frame
140 * @param count number of page-table entries to be mapped
141 *
142 * @return SYS_ERR_OK on success, errval on failure
143 */
144errval_t driverkit_iommu_map(struct iommu_client *cl, struct capref dst,
145                             struct capref src, uint16_t slot, uint64_t attr,
146                             uint64_t off, uint64_t count);
147
148
149/**
150 * @brief unmaps a slot in a vnode
151 *
152 * @param cl    the iommu client
153 * @param dst   the vnode containing the mapping
154 * @param slot  the slot to be unmapped
155 *
156 * @return SYS_ERR_OK on success, errval on failure
157 */
158errval_t driverkit_iommu_unmap(struct iommu_client *cl, struct capref dst,
159                               uint16_t slot);
160
161
162/**
163 * @brief changes the flags of the mapping
164 *
165 * @param cl    the iommu client
166 * @param dest  the destination vnode to change the mapping
167 * @param slot  the slot to change the mapping
168 * @param attrs the new attributes to set
169 *
170 * @return SYS_ERR_OK on success, erval on failure
171 */
172errval_t driverkit_iommu_modify(struct iommu_client *cl, struct capref dest,
173                                uint16_t slot, uint64_t attrs);
174
175
176/*
177 * ============================================================================
178 * High-level VSpace Management Interface
179 * ============================================================================
180 */
181
182
183///< represents a device address
184typedef genpaddr_t dmem_daddr_t;
185
186/**
187 * @brief represents a region of device memory
188 *
189 * this region is intended to be used between the device and the driver.
190 */
191struct dmem
192{
193    ///< address as seen by the device
194    dmem_daddr_t            devaddr;
195
196    ///< address as seen by the driver
197    lvaddr_t                vbase;
198
199    ///< capability referring to the memory resource
200    struct capref           mem;
201
202    ///< size of the memory region in bytes
203    gensize_t               size;
204
205    ///< iommu client state
206    struct iommu_client    *cl;
207};
208
209
210/**
211 * @brief maps a frame in the device and driver space
212 *
213 * @param frame the frame to be mapped
214 * @param flags attributes for the mapping
215 * @param dmem  the device memory struct
216 *
217 * @return SYS_ERR_OK on success, errval on failure
218 */
219errval_t driverkit_iommu_vspace_map_fixed_cl(struct iommu_client *cl, struct capref frame,
220                                             vregion_flags_t flags, struct dmem *dmem);
221errval_t driverkit_iommu_vspace_map_cl(struct iommu_client *cl, struct capref frame,
222                                       vregion_flags_t flags, struct dmem *dmem);
223errval_t driverkit_iommu_vspace_map(struct capref frame, vregion_flags_t flags,
224                                    struct dmem *dmem);
225
226
227/**
228 * @brief unmaps a previoiusly mapped device memory region
229 *
230 * @param dmem  the device memory region
231 *
232 * @return SYS_ERR_OK on succes, errval on failure
233 */
234errval_t driverkit_iommu_vspace_unmap(struct dmem *dmem);
235
236
237/**
238 * @brief modifies an existing mapping
239 *
240 * @param dmem  the device mem region
241 * @param flags new attributes for the mapping
242 *
243 * @return SYS_ERR_OK on success, errval on failure
244 */
245errval_t driverkit_iommu_vspace_modify_flags(struct dmem *dmem,
246                                             vregion_flags_t flags);
247
248
249/**
250 * @brief allocates and maps a region of memory
251 *
252 * @param cl    the iommu client
253 * @param bytes bytes to be allocated
254 * @param mem   returned dmem
255 *
256 * @return SYS_ERR_OK on success, errval on failure
257 */
258errval_t driverkit_iommu_mmap_cl(struct iommu_client *cl, size_t bytes,
259                                 vregion_flags_t flags, struct dmem *mem);
260errval_t driverkit_iommu_mmap(size_t bytes, vregion_flags_t flags,
261                              struct dmem *mem);
262
263errval_t driverkit_iommu_munmap(struct dmem *mem);
264
265/**
266 * @brief represents an iommu vspace management policy
267 */
268typedef enum {
269    IOMMU_VSPACE_POLICY_MIRROR,
270    IOMMU_VSPACE_POLICY_SHARED,
271    IOMMU_VSPACE_POLICY_INDEPENDENT
272} iommu_vspace_policy_t;
273
274
275/**
276 * @brief sets the iommu vspace managemet policy
277 *
278 * @param cl     the iommu client to set the policy for
279 * @param policy the new policy
280 *
281 * @return SYS_ERR_OK on success, errval on failure
282 */
283errval_t driverkit_iommu_vspace_set_policy(struct iommu_client *cl,
284                                           iommu_vspace_policy_t policy);
285
286
287/**
288 * @brief sets the default iommu vspace managemet policy
289 *
290 * @param policy the new policy
291 *
292 * @return SYS_ERR_OK on success, errval on failure
293 */
294errval_t driverkit_iommu_vspace_set_default_policy(iommu_vspace_policy_t policy);
295
296
297/*
298 * ============================================================================
299 * Memory Allocation
300 * ============================================================================
301 */
302
303
304/**
305 * @brief allocates a vnode for the iommu
306 *
307 * @param cl        the iommu client
308 * @param type      vnode type to be allocated
309 * @param retvnode  returned capability to the vnode
310 *
311 * @return SYS_ERR_OK on success, errval on failure
312 */
313errval_t driverkit_iommu_alloc_vnode_cl(struct iommu_client *cl,
314                                        enum objtype type,
315                                        struct capref *retvnode);
316errval_t driverkit_iommu_alloc_vnode(enum objtype type, struct capref *retvnode);
317
318
319/**
320 * @brief allocates a frame to be mapped accessible by the device and the driver
321 *
322 * @param cl        the iommu client
323 * @param bytes     number of bytes to allocate
324 * @param retframe  returned frame capability
325 *
326 * @return SYS_ERR_OK on success, errval on failure
327 */
328errval_t driverkit_iommu_alloc_frame(struct iommu_client *cl, size_t bytes,
329                                     struct capref *retframe);
330
331
332
333
334/*
335 * ============================================================================
336 * IOMMU aware heap style memory allocation
337 * ============================================================================
338 */
339
340
341/**
342 * @brief allocates memory on the device heap
343 *
344 * @param bytes number of bytes to allocate
345 *
346 * @return pointer to the allocate region
347 *
348 * the returned pointer is valid on the CPU and the device
349 * This does not work with the IOMMU_VSPACE_POLICY_INDEPENDENT.
350 */
351void *driverkit_iommu_malloc(size_t bytes);
352
353
354/**
355 * @brief allocates and zeroesa a region on the device heap
356 * @param blocks    number of blocks to be allocated
357 * @param bytes     size of a block
358 *
359 * @return pointer to the allocated regoin
360 *
361 * the returned pointer is valid on the CPU and the device
362 * This does not work with the IOMMU_VSPACE_POLICY_INDEPENDENT.
363 */
364void *driverkit_iommu_calloc(size_t blocks, size_t bytes);
365
366
367/**
368 * @brief frees a region on the devic heap
369 *
370 * @param ptr pointer ot the region to be freed
371 *
372 * the returned pointer is valid on the CPU and the device
373 * This does not work with the IOMMU_VSPACE_POLICY_INDEPENDENT.
374 */
375void driverkit_iommu_free(void *ptr);
376
377
378
379
380
381
382
383
384/**
385 * @brief creates a new protection domain
386 *
387 * @return SYS_ERR_OK on success, errval on failure
388 */
389static inline errval_t driverkit_iommu_create_domain(struct capref rootpt, struct capref dev)
390{
391    USER_PANIC("DEPRECATED!");
392    return LIB_ERR_NOT_IMPLEMENTED;
393}
394/**
395 * @brief deletes a previously created protection domain
396 *
397 * @return SYS_ERR_OK on success, errval on failure
398 */
399static inline errval_t driverkit_iommu_delete_domain(struct capref rootpt)
400{
401    USER_PANIC("DEPRECATED!");
402    return LIB_ERR_NOT_IMPLEMENTED;
403}
404
405
406/**
407 * @brief adds a device to a protection domain
408 *
409 * @return SYS_ERR_OK on success, errval on failure
410 */
411static inline errval_t driverkit_iommu_add_device(struct capref rootpt, struct capref dev)
412{
413    USER_PANIC("DEPRECATED!");
414    return LIB_ERR_NOT_IMPLEMENTED;
415}
416/**
417 * @brief removes a device from a protection domain
418 *
419 * @return SYS_ERR_OK on success, errval on failure
420 */
421static inline errval_t driverkit_iommu_remove_device(struct capref rootpt, struct capref dev)
422{
423    USER_PANIC("DEPRECATED!");
424    return LIB_ERR_NOT_IMPLEMENTED;
425}
426
427
428static inline errval_t driverkit_iommu_client_init2(void)
429{
430    USER_PANIC("DEPRECATED!");
431    return LIB_ERR_NOT_IMPLEMENTED;
432}
433
434#endif // DRIVERKIT_IOMMU_H
435