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