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