iPXE
dma.h
Go to the documentation of this file.
1 #ifndef _IPXE_DMA_H
2 #define _IPXE_DMA_H
3 
4 /** @file
5  *
6  * DMA mappings
7  *
8  */
9 
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11 
12 #include <stdint.h>
13 #include <ipxe/api.h>
14 #include <ipxe/io.h>
15 #include <ipxe/malloc.h>
16 #include <ipxe/umalloc.h>
17 #include <config/ioapi.h>
18 
19 #ifdef DMAAPI_OP
20 #define DMAAPI_PREFIX_op
21 #else
22 #define DMAAPI_PREFIX_op __op_
23 #endif
24 
25 #ifdef DMAAPI_FLAT
26 #define DMAAPI_PREFIX_flat
27 #else
28 #define DMAAPI_PREFIX_flat __flat_
29 #endif
30 
31 /** A DMA mapping */
32 struct dma_mapping {
33  /** Address offset
34  *
35  * This is the value that must be added to a physical address
36  * within the mapping in order to produce the corresponding
37  * device-side DMA address.
38  */
40  /** DMA device (if unmapping is required) */
41  struct dma_device *dma;
42  /** Platform mapping token */
43  void *token;
44 };
45 
46 /** A DMA-capable device */
47 struct dma_device {
48  /** DMA operations */
49  struct dma_operations *op;
50  /** Addressable space mask */
52  /** Total number of mappings (for debugging) */
53  unsigned int mapped;
54  /** Total number of allocations (for debugging) */
55  unsigned int allocated;
56 };
57 
58 /** DMA operations */
60  /**
61  * Map buffer for DMA
62  *
63  * @v dma DMA device
64  * @v map DMA mapping to fill in
65  * @v addr Buffer address
66  * @v len Length of buffer
67  * @v flags Mapping flags
68  * @ret rc Return status code
69  */
70  int ( * map ) ( struct dma_device *dma, struct dma_mapping *map,
71  physaddr_t addr, size_t len, int flags );
72  /**
73  * Unmap buffer
74  *
75  * @v dma DMA device
76  * @v map DMA mapping
77  */
78  void ( * unmap ) ( struct dma_device *dma, struct dma_mapping *map );
79  /**
80  * Allocate and map DMA-coherent buffer
81  *
82  * @v dma DMA device
83  * @v map DMA mapping to fill in
84  * @v len Length of buffer
85  * @v align Physical alignment
86  * @ret addr Buffer address, or NULL on error
87  */
88  void * ( * alloc ) ( struct dma_device *dma, struct dma_mapping *map,
89  size_t len, size_t align );
90  /**
91  * Unmap and free DMA-coherent buffer
92  *
93  * @v dma DMA device
94  * @v map DMA mapping
95  * @v addr Buffer address
96  * @v len Length of buffer
97  */
98  void ( * free ) ( struct dma_device *dma, struct dma_mapping *map,
99  void *addr, size_t len );
100  /**
101  * Allocate and map DMA-coherent buffer from external (user) memory
102  *
103  * @v dma DMA device
104  * @v map DMA mapping to fill in
105  * @v len Length of buffer
106  * @v align Physical alignment
107  * @ret addr Buffer address, or NULL on error
108  */
109  userptr_t ( * umalloc ) ( struct dma_device *dma,
110  struct dma_mapping *map,
111  size_t len, size_t align );
112  /**
113  * Unmap and free DMA-coherent buffer from external (user) memory
114  *
115  * @v dma DMA device
116  * @v map DMA mapping
117  * @v addr Buffer address
118  * @v len Length of buffer
119  */
120  void ( * ufree ) ( struct dma_device *dma, struct dma_mapping *map,
121  userptr_t addr, size_t len );
122  /**
123  * Set addressable space mask
124  *
125  * @v dma DMA device
126  * @v mask Addressable space mask
127  */
128  void ( * set_mask ) ( struct dma_device *dma, physaddr_t mask );
129 };
130 
131 /** Device will read data from host memory */
132 #define DMA_TX 0x01
133 
134 /** Device will write data to host memory */
135 #define DMA_RX 0x02
136 
137 /** Device will both read data from and write data to host memory */
138 #define DMA_BI ( DMA_TX | DMA_RX )
139 
140 /**
141  * Calculate static inline DMA I/O API function name
142  *
143  * @v _prefix Subsystem prefix
144  * @v _api_func API function
145  * @ret _subsys_func Subsystem API function
146  */
147 #define DMAAPI_INLINE( _subsys, _api_func ) \
148  SINGLE_API_INLINE ( DMAAPI_PREFIX_ ## _subsys, _api_func )
149 
150 /**
151  * Provide a DMA I/O API implementation
152  *
153  * @v _prefix Subsystem prefix
154  * @v _api_func API function
155  * @v _func Implementing function
156  */
157 #define PROVIDE_DMAAPI( _subsys, _api_func, _func ) \
158  PROVIDE_SINGLE_API ( DMAAPI_PREFIX_ ## _subsys, _api_func, _func )
159 
160 /**
161  * Provide a static inline DMA I/O API implementation
162  *
163  * @v _prefix Subsystem prefix
164  * @v _api_func API function
165  */
166 #define PROVIDE_DMAAPI_INLINE( _subsys, _api_func ) \
167  PROVIDE_SINGLE_API_INLINE ( DMAAPI_PREFIX_ ## _subsys, _api_func )
168 
169 /**
170  * Map buffer for DMA
171  *
172  * @v dma DMA device
173  * @v map DMA mapping to fill in
174  * @v addr Buffer address
175  * @v len Length of buffer
176  * @v flags Mapping flags
177  * @ret rc Return status code
178  */
179 static inline __always_inline int
180 DMAAPI_INLINE ( flat, dma_map ) ( struct dma_device *dma,
181  struct dma_mapping *map,
183  size_t len __unused, int flags __unused ) {
184 
185  /* Increment mapping count (for debugging) */
186  if ( DBG_LOG ) {
187  map->dma = dma;
188  dma->mapped++;
189  }
190 
191  return 0;
192 }
193 
194 /**
195  * Unmap buffer
196  *
197  * @v map DMA mapping
198  */
199 static inline __always_inline void
200 DMAAPI_INLINE ( flat, dma_unmap ) ( struct dma_mapping *map ) {
201 
202  /* Decrement mapping count (for debugging) */
203  if ( DBG_LOG ) {
204  assert ( map->dma != NULL );
205  map->dma->mapped--;
206  map->dma = NULL;
207  }
208 }
209 
210 /**
211  * Allocate and map DMA-coherent buffer
212  *
213  * @v dma DMA device
214  * @v map DMA mapping to fill in
215  * @v len Length of buffer
216  * @v align Physical alignment
217  * @ret addr Buffer address, or NULL on error
218  */
219 static inline __always_inline void *
220 DMAAPI_INLINE ( flat, dma_alloc ) ( struct dma_device *dma,
221  struct dma_mapping *map,
222  size_t len, size_t align ) {
223  void *addr;
224 
225  /* Allocate buffer */
227 
228  /* Increment mapping count (for debugging) */
229  if ( DBG_LOG && addr ) {
230  map->dma = dma;
231  dma->mapped++;
232  }
233 
234  return addr;
235 }
236 
237 /**
238  * Unmap and free DMA-coherent buffer
239  *
240  * @v map DMA mapping
241  * @v addr Buffer address
242  * @v len Length of buffer
243  */
244 static inline __always_inline void
245 DMAAPI_INLINE ( flat, dma_free ) ( struct dma_mapping *map,
246  void *addr, size_t len ) {
247 
248  /* Free buffer */
249  free_phys ( addr, len );
250 
251  /* Decrement mapping count (for debugging) */
252  if ( DBG_LOG ) {
253  assert ( map->dma != NULL );
254  map->dma->mapped--;
255  map->dma = NULL;
256  }
257 }
258 
259 /**
260  * Allocate and map DMA-coherent buffer from external (user) memory
261  *
262  * @v dma DMA device
263  * @v map DMA mapping to fill in
264  * @v len Length of buffer
265  * @v align Physical alignment
266  * @ret addr Buffer address, or NULL on error
267  */
268 static inline __always_inline userptr_t
269 DMAAPI_INLINE ( flat, dma_umalloc ) ( struct dma_device *dma,
270  struct dma_mapping *map,
271  size_t len, size_t align __unused ) {
272  userptr_t addr;
273 
274  /* Allocate buffer */
275  addr = umalloc ( len );
276 
277  /* Increment mapping count (for debugging) */
278  if ( DBG_LOG && addr ) {
279  map->dma = dma;
280  dma->mapped++;
281  }
282 
283  return addr;
284 }
285 
286 /**
287  * Unmap and free DMA-coherent buffer from external (user) memory
288  *
289  * @v map DMA mapping
290  * @v addr Buffer address
291  * @v len Length of buffer
292  */
293 static inline __always_inline void
294 DMAAPI_INLINE ( flat, dma_ufree ) ( struct dma_mapping *map,
295  userptr_t addr, size_t len __unused ) {
296 
297  /* Free buffer */
298  ufree ( addr );
299 
300  /* Decrement mapping count (for debugging) */
301  if ( DBG_LOG ) {
302  assert ( map->dma != NULL );
303  map->dma->mapped--;
304  map->dma = NULL;
305  }
306 }
307 
308 /**
309  * Set addressable space mask
310  *
311  * @v dma DMA device
312  * @v mask Addressable space mask
313  */
314 static inline __always_inline void
315 DMAAPI_INLINE ( flat, dma_set_mask ) ( struct dma_device *dma __unused,
317 
318  /* Nothing to do */
319 }
320 
321 /**
322  * Get DMA address from physical address
323  *
324  * @v map DMA mapping
325  * @v addr Physical address within the mapped region
326  * @ret addr Device-side DMA address
327  */
328 static inline __always_inline physaddr_t
329 DMAAPI_INLINE ( flat, dma_phys ) ( struct dma_mapping *map __unused,
330  physaddr_t addr ) {
331 
332  /* Use physical address as device address */
333  return addr;
334 }
335 
336 /**
337  * Get DMA address from physical address
338  *
339  * @v map DMA mapping
340  * @v addr Physical address within the mapped region
341  * @ret addr Device-side DMA address
342  */
343 static inline __always_inline physaddr_t
345 
346  /* Adjust physical address using mapping offset */
347  return ( addr + map->offset );
348 }
349 
350 /**
351  * Map buffer for DMA
352  *
353  * @v dma DMA device
354  * @v map DMA mapping to fill in
355  * @v addr Buffer address
356  * @v len Length of buffer
357  * @v flags Mapping flags
358  * @ret rc Return status code
359  */
360 int dma_map ( struct dma_device *dma, struct dma_mapping *map,
361  physaddr_t addr, size_t len, int flags );
362 
363 /**
364  * Unmap buffer
365  *
366  * @v map DMA mapping
367  */
368 void dma_unmap ( struct dma_mapping *map );
369 
370 /**
371  * Allocate and map DMA-coherent buffer
372  *
373  * @v dma DMA device
374  * @v map DMA mapping to fill in
375  * @v len Length of buffer
376  * @v align Physical alignment
377  * @ret addr Buffer address, or NULL on error
378  */
379 void * dma_alloc ( struct dma_device *dma, struct dma_mapping *map,
380  size_t len, size_t align );
381 
382 /**
383  * Unmap and free DMA-coherent buffer
384  *
385  * @v map DMA mapping
386  * @v addr Buffer address
387  * @v len Length of buffer
388  */
389 void dma_free ( struct dma_mapping *map, void *addr, size_t len );
390 
391 /**
392  * Allocate and map DMA-coherent buffer from external (user) memory
393  *
394  * @v dma DMA device
395  * @v map DMA mapping to fill in
396  * @v len Length of buffer
397  * @v align Physical alignment
398  * @ret addr Buffer address, or NULL on error
399  */
401  size_t len, size_t align );
402 
403 /**
404  * Unmap and free DMA-coherent buffer from external (user) memory
405  *
406  * @v map DMA mapping
407  * @v addr Buffer address
408  * @v len Length of buffer
409  */
410 void dma_ufree ( struct dma_mapping *map, userptr_t addr, size_t len );
411 
412 /**
413  * Set addressable space mask
414  *
415  * @v dma DMA device
416  * @v mask Addressable space mask
417  */
418 void dma_set_mask ( struct dma_device *dma, physaddr_t mask );
419 
420 /**
421  * Get DMA address from physical address
422  *
423  * @v map DMA mapping
424  * @v addr Physical address within the mapped region
425  * @ret addr Device-side DMA address
426  */
428 
429 /**
430  * Get DMA address from virtual address
431  *
432  * @v map DMA mapping
433  * @v addr Virtual address within the mapped region
434  * @ret addr Device-side DMA address
435  */
436 static inline __always_inline physaddr_t dma ( struct dma_mapping *map,
437  void *addr ) {
438 
439  /* Get DMA address from corresponding physical address */
440  return dma_phys ( map, virt_to_phys ( addr ) );
441 }
442 
443 /**
444  * Check if DMA unmapping is required
445  *
446  * @v map DMA mapping
447  * @v unmap Unmapping is required
448  */
449 static inline __always_inline int dma_mapped ( struct dma_mapping *map ) {
450 
451  /* Unmapping is required if a DMA device was recorded */
452  return ( map->dma != NULL );
453 }
454 
455 /**
456  * Initialise DMA device
457  *
458  * @v dma DMA device
459  * @v op DMA operations
460  */
461 static inline __always_inline void dma_init ( struct dma_device *dma,
462  struct dma_operations *op ) {
463 
464  /* Set operations table */
465  dma->op = op;
466 }
467 
468 /**
469  * Set 64-bit addressable space mask
470  *
471  * @v dma DMA device
472  */
473 static inline __always_inline void
475 
476  /* Set mask to maximum physical address */
477  dma_set_mask ( dma, ~( ( physaddr_t ) 0 ) );
478 }
479 
480 #endif /* _IPXE_DMA_H */
int(* map)(struct dma_device *dma, struct dma_mapping *map, physaddr_t addr, size_t len, int flags)
Map buffer for DMA.
Definition: dma.h:70
static __always_inline void struct dma_mapping size_t size_t align
Definition: dma.h:222
iPXE I/O API
iPXE internal APIs
struct dma_device * dma
DMA device (if unmapping is required)
Definition: dma.h:41
static __always_inline void dma_init(struct dma_device *dma, struct dma_operations *op)
Initialise DMA device.
Definition: dma.h:461
physaddr_t dma_phys(struct dma_mapping *map, physaddr_t addr)
Get DMA address from physical address.
struct dma_operations * op
DMA operations.
Definition: dma.h:49
static __always_inline void dma_set_mask_64bit(struct dma_device *dma)
Set 64-bit addressable space mask.
Definition: dma.h:474
static void *__malloc malloc_phys(size_t size, size_t phys_align)
Allocate memory with specified physical alignment.
Definition: malloc.h:62
void(* unmap)(struct dma_device *dma, struct dma_mapping *map)
Unmap buffer.
Definition: dma.h:78
static __always_inline unsigned long virt_to_phys(volatile const void *addr)
Convert virtual address to a physical address.
Definition: uaccess.h:287
static __always_inline int struct dma_mapping physaddr_t addr __unused
Definition: dma.h:181
Dynamic memory allocation.
physaddr_t mask
Addressable space mask.
Definition: dma.h:51
static __always_inline void struct dma_mapping size_t len
Definition: dma.h:221
static __always_inline int dma_mapped(struct dma_mapping *map)
Check if DMA unmapping is required.
Definition: dma.h:449
void dma_free(struct dma_mapping *map, void *addr, size_t len)
Unmap and free DMA-coherent buffer.
addr
Definition: dma.h:226
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define DMAAPI_INLINE(_subsys, _api_func)
Calculate static inline DMA I/O API function name.
Definition: dma.h:147
void dma_unmap(struct dma_mapping *map)
Unmap buffer.
physaddr_t offset
Address offset.
Definition: dma.h:39
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
void dma_set_mask(struct dma_device *dma, physaddr_t mask)
Set addressable space mask.
void(* set_mask)(struct dma_device *dma, physaddr_t mask)
Set addressable space mask.
Definition: dma.h:128
#define __always_inline
Declare a function to be always inline.
Definition: compiler.h:611
User memory allocation.
DMA operations.
Definition: dma.h:59
static __always_inline int struct dma_mapping * map
Definition: dma.h:181
unsigned int mapped
Total number of mappings (for debugging)
Definition: dma.h:53
void * dma_alloc(struct dma_device *dma, struct dma_mapping *map, size_t len, size_t align)
Allocate and map DMA-coherent buffer.
unsigned long physaddr_t
Definition: stdint.h:20
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
unsigned int allocated
Total number of allocations (for debugging)
Definition: dma.h:55
I/O API configuration.
void dma_ufree(struct dma_mapping *map, userptr_t addr, size_t len)
Unmap and free DMA-coherent buffer from external (user) memory.
static __always_inline void ufree(userptr_t userptr)
Free external memory.
Definition: umalloc.h:65
static __always_inline userptr_t umalloc(size_t size)
Allocate external memory.
Definition: umalloc.h:54
void * token
Platform mapping token.
Definition: dma.h:43
userptr_t(* umalloc)(struct dma_device *dma, struct dma_mapping *map, size_t len, size_t align)
Allocate and map DMA-coherent buffer from external (user) memory.
Definition: dma.h:109
static void free_phys(void *ptr, size_t size)
Free memory allocated with malloc_phys()
Definition: malloc.h:77
userptr_t dma_umalloc(struct dma_device *dma, struct dma_mapping *map, size_t len, size_t align)
Allocate and map DMA-coherent buffer from external (user) memory.
void(* ufree)(struct dma_device *dma, struct dma_mapping *map, userptr_t addr, size_t len)
Unmap and free DMA-coherent buffer from external (user) memory.
Definition: dma.h:120
void(* free)(struct dma_device *dma, struct dma_mapping *map, void *addr, size_t len)
Unmap and free DMA-coherent buffer.
Definition: dma.h:98
static __always_inline physaddr_t dma(struct dma_mapping *map, void *addr)
Get DMA address from virtual address.
Definition: dma.h:436
#define DBG_LOG
Definition: compiler.h:317
A DMA mapping.
Definition: dma.h:32
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33
A DMA-capable device.
Definition: dma.h:47
uint8_t flags
Flags.
Definition: ena.h:18