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