1/* 2 * Copyright (c) 2014 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, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#ifndef LIB_DMA_REQUEST_H 11#define LIB_DMA_REQUEST_H 12 13#include <dma/dma_channel.h> 14 15struct dma_request; 16 17/// callback to be called when the request is finished 18typedef void (*dma_req_cb_t)(errval_t, 19 dma_req_id_t, 20 void *); 21 22/** 23 * enumeration of the possible request types 24 */ 25typedef enum dma_req_type 26{ 27 DMA_REQ_TYPE_INVALID = 0, ///< invalid request 28 DMA_REQ_TYPE_MEM_REGISTER, ///< 29 DMA_REQ_TYPE_MEM_REMOVE, ///< 30 DMA_REQ_TYPE_NOP, ///< NULL / NOP request 31 DMA_REQ_TYPE_MEMCPY, ///< Memcpy request 32 DMA_REQ_TYPE_MEMSET, ///< Memset request 33 DMA_REQ_TYPE_STATUS, 34 DMA_REQ_TYPE_GENERAL, 35 DMA_REQ_TYPE_KEYNON, 36 DMA_REQ_TYPE_KEY, 37 38} dma_req_type_t; 39 40/** 41 * enumeration of the request states 42 */ 43typedef enum dma_req_st 44{ 45 DMA_REQ_ST_INVALID, ///< request is invalid 46 DMA_REQ_ST_PREPARED, ///< request is prepared 47 DMA_REQ_ST_SUBMITTED, ///< request is submitted to hardware 48 DMA_REQ_ST_DONE, ///< request has been executed 49 DMA_REQ_ST_ERR ///< request execution failed 50} dma_req_st_t; 51 52/** 53 * specifies the DMA request setup fields 54 */ 55struct dma_req_setup 56{ 57 dma_req_type_t type; ///< specifies the request type 58 dma_req_cb_t done_cb; ///< callback for executed request 59 void *cb_arg; ///< argument for the callback 60 union 61 { 62 struct 63 { 64 lpaddr_t src; ///< source physical address 65 lpaddr_t dst; ///< destination physical address 66 size_t bytes; ///< size of the transfer in bytes 67 uint8_t ctrl_intr :1; ///< do an interrupt upon completion 68 uint8_t ctrl_fence :1; ///< do a mem fence upon completion 69 } memcpy; ///< memcpy request 70 71 struct 72 { 73 lpaddr_t dst; ///< source physical address 74 uint64_t val; ///< value to set 75 size_t bytes; ///< size of the transfer in bytes 76 uint8_t ctrl_intr :1; ///< do an interrupt upon completion 77 uint8_t ctrl_fence :1; ///< do a mem fence upon completion 78 } memset; ///< memcpy request 79 struct { 80 81 } nop; 82 83 struct { 84 85 } status; 86 struct { 87 88 } general; 89 struct { 90 91 } keynon; 92 struct { 93 94 } key; 95 96 } args; ///< request setup arguments 97 98}; 99 100/* 101 * ---------------------------------------------------------------------------- 102 * Getter / Setter Functions 103 * ---------------------------------------------------------------------------- 104 */ 105 106/** 107 * \brief returns the state of a DMA request 108 * 109 * \param req DMA request 110 * 111 * \returns DMA request state 112 */ 113dma_req_st_t dma_request_get_state(struct dma_request *req); 114 115/** 116 * \brief returns the ID of a DMA request 117 * 118 * \param req DMA request 119 * 120 * \returns DMA request ID 121 */ 122dma_req_id_t dma_request_get_id(struct dma_request *req); 123 124 125/** 126 * \brief returns the next DMA request of the given request 127 * 128 * \param req DMA request 129 * 130 * \returns DMA request if there was one 131 * NULL if the request is at the end of the chain 132 */ 133struct dma_request *dma_request_get_next(struct dma_request *req); 134 135/* 136 * ---------------------------------------------------------------------------- 137 * Memory Registration 138 * ---------------------------------------------------------------------------- 139 */ 140 141/** 142 * \brief registers a memory region for future use 143 * 144 * \param frame the memory frame to register 145 * 146 * \returns SYS_ERR_OK on succes 147 * errval on error 148 */ 149errval_t dma_register_memory(struct dma_device *dev, 150 struct capref frame); 151 152/** 153 * \brief deregisters a previously registered memory region 154 * 155 * \param frame the memory frame to register 156 * 157 * \returns SYS_ERR_OK on succes 158 * errval on error 159 */ 160errval_t dma_request_deregister_memory(struct dma_device *dev, 161 struct capref frame); 162 163/* 164 * ---------------------------------------------------------------------------- 165 * Request Execution 166 * ---------------------------------------------------------------------------- 167 */ 168 169/** 170 * \brief issues a new DMA memcpy request based on the setup information 171 * 172 * \param chan DMA channel 173 * \param setup DMA request setup information 174 * \param id returns the DMA request ID 175 * 176 * \returns SYS_ERR_OK on success 177 * errval on error 178 */ 179errval_t dma_request_memcpy_chan(struct dma_channel *chan, 180 struct dma_req_setup *setup, 181 dma_req_id_t *id); 182 183/** 184 * \brief issues a new DMA memcpy request based on the setup information 185 * 186 * \param dev DMA device 187 * \param setup DMA request setup information 188 * \param id returns the DMA request ID 189 * 190 * \returns SYS_ERR_OK on success 191 * errval on error 192 */ 193errval_t dma_request_memcpy(struct dma_device *dev, 194 struct dma_req_setup *setup, 195 dma_req_id_t *id); 196/** 197 * \brief issues a new DMA memcpy request based on the setup information 198 * 199 * \param chan DMA channel 200 * \param setup DMA request setup information 201 * \param id returns the DMA request ID 202 * 203 * \returns SYS_ERR_OK on success 204 * errval on error 205 */ 206errval_t dma_request_memset_chan(struct dma_channel *chan, 207 struct dma_req_setup *setup, 208 dma_req_id_t *id); 209 210/** 211 * \brief issues a new DMA memcpy request based on the setup information 212 * 213 * \param dev DMA device 214 * \param setup DMA request setup information 215 * \param id returns the DMA request ID 216 * 217 * \returns SYS_ERR_OK on success 218 * errval on error 219 */ 220errval_t dma_request_memset(struct dma_device *dev, 221 struct dma_req_setup *setup, 222 dma_req_id_t *id); 223 224/* 225 * ---------------------------------------------------------------------------- 226 * Helper Functions 227 * ---------------------------------------------------------------------------- 228 */ 229 230/** 231 * \brief builds the DMA request ID for a request counter value on a give channel 232 * 233 * \param chan the DMA channel 234 * \param req request counter value 235 * 236 * \return DMA request ID 237 */ 238static inline dma_req_id_t dma_request_id_build(struct dma_channel *chan, 239 uint64_t req) 240{ 241 dma_req_id_t id = (dma_req_id_t)dma_channel_get_id(chan); 242 id <<= 48; 243 id |= (0x0000FFFFFFFFFFFFULL & req); 244 return id; 245} 246 247/** 248 * \brief obtains the DMA channel ID from the request ID 249 * 250 * \param id the DMA request ID 251 * 252 * \return DMA channel ID 253 */ 254static inline dma_chan_id_t dma_request_id_get_channel_id(dma_req_id_t id) 255{ 256 return (dma_chan_id_t)((id >> 48) & 0xFFFF); 257} 258 259/** 260 * \brief obtains the DMA device ID from the request ID 261 * 262 * \param id the DMA request ID 263 * 264 * \return DMA device ID 265 */ 266static inline dma_chan_id_t dma_request_id_get_device_id(dma_req_id_t id) 267{ 268 return dma_channel_id_get_device_id(dma_request_id_get_channel_id(id)); 269} 270 271 272#endif /* LIB_DMA_REQUEST_H */ 273