DeviceQueue: Direct Solarflare queue implementation
[barrelfish] / include / devif / queue_interface.h
1 /*
2  * Copyright (c) 2016 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, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
8  */
9 #ifndef QUEUE_INTERFACE_H_
10 #define QUEUE_INTERFACE_H_ 1
11
12
13 #include <barrelfish/barrelfish.h>
14
15 #define MAX_DEVICE_NAME 256
16
17 #define ENDPOINT_TYPE_FORWARD 0x1
18 #define ENDPOINT_TYPE_BLOCK 0x3
19 #define ENDPOINT_TYPE_DEVICE 0x4
20 #define ENDPOINT_TYPE_DIRECT 0x5
21
22 // the user side of the queue
23 #define ENDPOINT_TYPE_USER 0xF
24 // only internal?
25 #define ENDPOINT_TYPE_FORWARD_TX 0x11
26
27
28 #define DEVQ_BUF_FLAG_TX 0x1
29 #define DEVQ_BUF_FLAG_RX 0x2
30
31
32 typedef uint32_t regionid_t;
33 typedef uint32_t bufferid_t;
34
35 struct devq;
36
37 struct devq_buf{
38     regionid_t rid; // 4
39     bufferid_t bid; // 8
40     lpaddr_t addr; // 16
41     size_t len; // 24
42     uint64_t flags; // 32
43 };
44
45 /*
46  * ===========================================================================
47  * Backend function definitions
48  * ===========================================================================
49  */
50
51 // These functions must be implemented by the driver which is using the library
52
53  /**
54   * @brief Setup function called on the device side
55   *
56   * @param features         Return pointer to the features of the device
57   * @param default_qsize    Return pointer to the default hardware device 
58   *                         queue size
59   * @param default_bufsize  Return pointer to the default buffer size used by the
60   *                         device
61   * @param reconnect        Return pointer to a bool that inicates if the other 
62   *                         other endpoint has to reconnect to another serivce
63   *                         (i.e. reconnect from device_manager to queue_manager)
64   * @param name             String of the service to reconnect to
65   *
66   * @returns error on failure or SYS_ERR_OK on success
67   */
68 typedef errval_t (*devq_setup_t)(uint64_t *features, uint32_t* default_qsize, 
69                                  uint32_t* default_bufsize, bool* reconnect, char* name);
70
71  /**
72   * @brief Create function that initializes the queue on the device side, or 
73   *        for direct queues get all the necessary state so that direct function calls
74   *        to the hardware registers can be used. To set this state up, 
75   *        communication to other services might be necessary (e.g. device_manager).
76   *        The pointer to the device specific state can be aquired by devq_get_state()
77   *        
78   * @param q         The device queue to create the device state from
79   * @param flags     Flags that inidicate which features the queue should have
80   *                  enabled
81   *
82   * @returns error on failure or SYS_ERR_OK on success
83   */
84 typedef errval_t (*devq_create_t)(struct devq *q, uint64_t flags);
85  /**
86   * @brief Destroy function that cleans up all the resouces used by the queue.
87   *        Similar to create, for direct endpoint types further communication
88   *        is necessary in this function
89   *        
90   * @param q         The device queue to destroy
91   *
92   * @returns error on failure or SYS_ERR_OK on success
93   */
94 typedef errval_t (*devq_destroy_t)(struct devq *q);
95    
96  /**
97   * @brief Notifies the device of new descriptors in the queue. 
98   *        On a notificaton, the device can dequeue num_slots descritpors
99   *        from the queue. NOTE: Does nothing for direct queues since there
100   *        is no other endpoint to notify! (i.e. it is the same process)
101   *        
102   * @param q         The device queue to destroy
103   *
104   * @returns error on failure or SYS_ERR_OK on success
105   */
106 typedef errval_t (*devq_notify_t) (struct devq *q, uint8_t num_slots);
107
108  /**
109   * @brief Registers a memory region. For direct queues this function 
110   *        Has to handle the communication to the device driver since
111   *        there might also be a need to set up some local state for the
112   *        direct queue that is device specific
113   *        
114   * @param q         The device queue handle
115   * @param cap       The capability of the memory region
116   * @param reigon_id The region id
117   *
118   * @returns error on failure or SYS_ERR_OK on success
119   */
120 typedef errval_t (*devq_register_t)(struct devq *q, struct capref cap,
121                                     regionid_t region_id);
122
123  /**
124   * @brief Deregisters a memory region. (Similar communication constraints 
125   *        as register)
126   *        
127   * @param q         The device queue handle
128   * @param reigon_id The region id
129   *
130   * @returns error on failure or SYS_ERR_OK on success
131   */
132 typedef errval_t (*devq_deregister_t)(struct devq *q, regionid_t region_id);
133
134  /**
135   * @brief handles a control message to the device (Similar communication 
136   *        constraints as register)
137   *        
138   * @param q         The device queue handle
139   * @param request   The request type
140   * @param value     The value to the request
141   *
142   * @returns error on failure or SYS_ERR_OK on success
143   */
144 typedef errval_t (*devq_control_t)(struct devq *q, uint64_t request,
145                                    uint64_t value);
146
147
148  /**
149   * @brief Directly enqueues something into a hardware queue. Only used by
150   *        direct endpoints
151   *        
152   * @param q            The device queue handle
153   * @param region_id    The region id of the buffer
154   * @param buffer_id    The buffer id of the buffer
155   * @param base         The base address of the buffer
156   * @param length       The length of the buffer
157   * @param misc_flags   Misc flags
158   *
159   * @returns error on failure or SYS_ERR_OK on success
160   */
161 typedef errval_t (*devq_enqueue_t)(struct devq *q, regionid_t region_id,
162                                    bufferid_t buffer_id, lpaddr_t base, size_t length,
163                                    uint64_t misc_flags);
164
165  /**
166   * @brief Directly dequeus something from a hardware queue. Only used by
167   *        direct endpoints
168   *        
169   * @param q            The device queue handle
170   * @param region_id    The region id of the buffer
171   * @param buffer_id    The buffer id of the buffer
172   * @param base         The base address of the buffer
173   * @param length       The length of the buffer
174   * @param misc_flags   Misc flags
175   *
176   * @returns error on failure if the queue is empty or SYS_ERR_OK on success
177   */
178 typedef errval_t (*devq_dequeue_t)(struct devq *q, regionid_t* region_id,
179                                    bufferid_t* buffer_id, lpaddr_t* base, size_t* length,
180                                    uint64_t* misc_flags);
181
182 // The functions that the device driver has to export
183 struct devq_func_pointer {
184     devq_setup_t setup;
185     devq_create_t create;
186     devq_destroy_t destroy;
187     devq_register_t reg;
188     devq_deregister_t dereg;
189     devq_control_t ctrl;
190     devq_notify_t notify;
191     devq_enqueue_t enq;
192     devq_dequeue_t deq;
193 };
194
195 // The devif device state
196 struct endpoint_state {
197     // device type
198     uint8_t endpoint_type;
199     // name of the endpoint
200     char device_name[MAX_DEVICE_NAME];
201     // features of the endpoint
202     uint64_t features;
203     // setup function pointer
204     struct devq_func_pointer f;
205     // bool to check export
206     bool export_done;
207     // binding
208     struct devif_ctrl_binding* ctrl;
209     struct devif_data_binding* data;
210 };
211
212  /*
213  * ===========================================================================
214  * Device queue interface export (for devices)
215  * ===========================================================================
216  */
217  /**
218   * @brief exports the devq interface so others (client side) can connect
219   *
220   * @param s             An endpoint state containing all the information
221   *                      of a device including function pointers
222   *
223   * @returns error on failure or SYS_ERR_OK on success
224   */
225
226 errval_t devq_driver_export(struct endpoint_state* s);
227
228 /* ===========================================================================
229  * Device queue creation and destruction
230  * ===========================================================================
231  */
232
233  /**
234   * @brief creates a queue 
235   *
236   * @param q             Return pointer to the devq (handle)
237   * @param end           Endpoint state containing the function pointers
238   * @param device_name   Device name of the device to which this queue belongs
239   *                      (Driver itself is running in a separate process)
240   * @param device_type   The type of the device
241   * @param flags         Anything you can think of that makes sense for the device
242   *                      and its driver?
243   *
244   * @returns error on failure or SYS_ERR_OK on success
245   */
246
247 errval_t devq_create(struct devq **q,
248                      struct endpoint_state* end,
249                      char* device_name,
250                      uint64_t flags);
251
252  /**
253   * @brief destroys the device queue
254   *
255   * @param q           The queue state to free (and the device queue to be 
256                        shut down in the driver)
257   *
258   * @returns error on failure or SYS_ERR_OK on success
259   */
260 errval_t devq_destroy(struct devq *q);
261
262
263 /*
264  * ===========================================================================
265  * Device specific state
266  * ===========================================================================
267  */
268
269 /**
270  * @brief allocate device specific state of size bytes
271  *
272  * @param q           The device queue to allocate the state for
273  * @param bytes       Size of the state to allocate
274  *
275  */
276 void devq_allocate_state(struct devq *q, size_t bytes);
277
278 /**
279  * @brief get the device specific state for a queue
280  *
281  * @param q           The device queue to get the state for
282  *
283  * @returns void pointer to the defice specific state
284  */
285 void* devq_get_state(struct devq *q);
286
287 /*
288  * ===========================================================================
289  * Datapath functions
290  * ===========================================================================
291  */
292 /*
293  *
294  * @brief enqueue a buffer into the device queue
295  *
296  * @param q             The device queue to call the operation on
297  * @param region_id     Id of the memory region the buffer belongs to
298  * @param base          Physical address of the start of the enqueued buffer
299  * @param lenght        Lenght of the enqueued buffer
300  * @param misc_flags    Any other argument that makes sense to the device queue
301  * @param buffer_id     Return pointer to buffer id of the enqueued buffer 
302  *                      buffer_id is assigned by the interface
303  *
304  * @returns error on failure or SYS_ERR_OK on success
305  *
306  */
307 errval_t devq_enqueue(struct devq *q,
308                       regionid_t region_id,
309                       lpaddr_t base,
310                       size_t length,
311                       uint64_t misc_flags,
312                       bufferid_t* buffer_id);
313
314 /**
315  * @brief dequeue a buffer from the device queue
316  *
317  * @param q             The device queue to call the operation on
318  * @param region_id     Return pointer to the id of the memory 
319  *                      region the buffer belongs to
320  * @param base          Return pointer to the physical address of 
321  *                      the of the buffer
322  * @param lenght        Return pointer to the lenght of the dequeue buffer
323  * @param buffer_id     Reutrn pointer to the buffer id of the dequeued buffer 
324  * @param misc_flags    Return value from other endpoint
325  *
326  * @returns error on failure or SYS_ERR_OK on success
327  *
328  */
329
330 errval_t devq_dequeue(struct devq *q,
331                       regionid_t* region_id,
332                       lpaddr_t* base,
333                       size_t* length,
334                       bufferid_t* buffer_id,
335                       uint64_t* misc_flags);
336
337 /*
338  * ===========================================================================
339  * Control Path
340  * ===========================================================================
341  */
342
343 /**
344  * @brief Add a memory region that can be used as buffers to 
345  *        the device queue
346  *
347  * @param q              The device queue to call the operation on
348  * @param cap            A Capability for some memory
349  * @param region_id      Return pointer to a region id that is assigned
350  *                       to the memory
351  *
352  * @returns error on failure or SYS_ERR_OK on success
353  *
354  */
355 errval_t devq_register(struct devq *q,
356                        struct capref cap,
357                        regionid_t* region_id);
358
359 /**
360  * @brief Remove a memory region 
361  *
362  * @param q              The device queue to call the operation on
363  * @param region_id      The region id to remove from the device 
364  *                       queues memory
365  * @param cap            The capability to the removed memory
366  *
367  * @returns error on failure or SYS_ERR_OK on success
368  *
369  */
370 errval_t devq_deregister(struct devq *q,
371                          regionid_t region_id,
372                          struct capref* cap);
373
374 /**
375  * @brief Send a notification about new buffers on the queue
376  *
377  * @param q      The device queue to call the operation on
378  *
379  * @returns error on failure or SYS_ERR_OK on success
380  *
381  */
382 errval_t devq_notify(struct devq *q);
383
384 /**
385  * @brief Enforce coherency between of the buffers in the queue
386  *        by either flushing the cache or invalidating it
387  *
388  * @param q      The device queue to call the operation on
389  *
390  * @returns error on failure or SYS_ERR_OK on success
391  *
392  */
393 errval_t devq_prepare(struct devq *q);
394
395 /**
396  * @brief Send a control message to the device queue
397  *
398  * @param q          The device queue to call the operation on
399  * @param request    The type of the control message*
400  * @param value      The value for the request
401  *
402  * @returns error on failure or SYS_ERR_OK on success
403  *
404  */
405 errval_t devq_control(struct devq *q,
406                       uint64_t request,
407                       uint64_t value);
408
409
410 errval_t devq_event_loop(struct endpoint_state* s);   
411 #endif /* QUEUE_INTERFACE_H_ */