iPXE
dma.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2020 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 FILE_SECBOOT ( PERMITTED );
26 
27 #include <assert.h>
28 #include <errno.h>
29 #include <ipxe/dma.h>
30 
31 /** @file
32  *
33  * DMA mappings
34  *
35  */
36 
37 /******************************************************************************
38  *
39  * Flat address space DMA API
40  *
41  ******************************************************************************
42  */
43 
44 PROVIDE_DMAAPI_INLINE ( flat, dma_map );
51 PROVIDE_DMAAPI_INLINE ( flat, dma );
52 
53 /******************************************************************************
54  *
55  * Operations-based DMA API
56  *
57  ******************************************************************************
58  */
59 
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 static int dma_op_map ( struct dma_device *dma, struct dma_mapping *map,
71  void *addr, size_t len, int flags ) {
72  struct dma_operations *op = dma->op;
73 
74  if ( ! op )
75  return -ENODEV;
76  return op->map ( dma, map, addr, len, flags );
77 }
78 
79 /**
80  * Unmap buffer
81  *
82  * @v map DMA mapping
83  * @v len Used length
84  */
85 static void dma_op_unmap ( struct dma_mapping *map, size_t len ) {
86  struct dma_device *dma = map->dma;
87 
88  assert ( dma != NULL );
89  assert ( dma->op != NULL );
90  dma->op->unmap ( dma, map, len );
91 }
92 
93 /**
94  * Allocate and map DMA-coherent buffer
95  *
96  * @v dma DMA device
97  * @v map DMA mapping to fill in
98  * @v len Length of buffer
99  * @v align Physical alignment
100  * @ret addr Buffer address, or NULL on error
101  */
102 static void * dma_op_alloc ( struct dma_device *dma, struct dma_mapping *map,
103  size_t len, size_t align ) {
104  struct dma_operations *op = dma->op;
105 
106  if ( ! op )
107  return NULL;
108  return op->alloc ( dma, map, len, align );
109 }
110 
111 /**
112  * Unmap and free DMA-coherent buffer
113  *
114  * @v map DMA mapping
115  * @v addr Buffer address
116  * @v len Length of buffer
117  */
118 static void dma_op_free ( struct dma_mapping *map, void *addr, size_t len ) {
119  struct dma_device *dma = map->dma;
120 
121  assert ( dma != NULL );
122  assert ( dma->op != NULL );
123  dma->op->free ( dma, map, addr, len );
124 }
125 
126 /**
127  * Allocate and map DMA-coherent buffer from external (user) memory
128  *
129  * @v dma DMA device
130  * @v map DMA mapping to fill in
131  * @v len Length of buffer
132  * @v align Physical alignment
133  * @ret addr Buffer address, or NULL on error
134  */
135 static void * dma_op_umalloc ( struct dma_device *dma,
136  struct dma_mapping *map,
137  size_t len, size_t align ) {
138  struct dma_operations *op = dma->op;
139 
140  if ( ! op )
141  return NULL;
142  return op->umalloc ( dma, map, len, align );
143 }
144 
145 /**
146  * Unmap and free DMA-coherent buffer from external (user) memory
147  *
148  * @v map DMA mapping
149  * @v addr Buffer address
150  * @v len Length of buffer
151  */
152 static void dma_op_ufree ( struct dma_mapping *map, void *addr, size_t len ) {
153  struct dma_device *dma = map->dma;
154 
155  assert ( dma != NULL );
156  assert ( dma->op != NULL );
157  dma->op->ufree ( dma, map, addr, len );
158 }
159 
160 /**
161  * Set addressable space mask
162  *
163  * @v dma DMA device
164  * @v mask Addressable space mask
165  */
166 static void dma_op_set_mask ( struct dma_device *dma, physaddr_t mask ) {
167  struct dma_operations *op = dma->op;
168 
169  if ( op )
170  op->set_mask ( dma, mask );
171 }
172 
173 PROVIDE_DMAAPI ( op, dma_map, dma_op_map );
PROVIDE_DMAAPI_INLINE(flat, dma_map)
struct dma_device * dma
DMA device (if unmapping is required)
Definition: dma.h:42
static void * dma_op_alloc(struct dma_device *dma, struct dma_mapping *map, size_t len, size_t align)
Allocate and map DMA-coherent buffer.
Definition: dma.c:102
Error codes.
void dma_unmap(struct dma_mapping *map, size_t len)
Unmap buffer.
PROVIDE_DMAAPI(op, dma_map, dma_op_map)
DMA mappings.
void dma_set_mask(struct dma_device *dma, physaddr_t mask)
Set addressable space mask.
static int dma_op_map(struct dma_device *dma, struct dma_mapping *map, void *addr, size_t len, int flags)
Map buffer for DMA.
Definition: dma.c:70
static void dma_op_ufree(struct dma_mapping *map, void *addr, size_t len)
Unmap and free DMA-coherent buffer from external (user) memory.
Definition: dma.c:152
physaddr_t mask
Addressable space mask.
Definition: dma.h:52
void dma_free(struct dma_mapping *map, void *addr, size_t len)
Unmap and free DMA-coherent buffer.
Assertions.
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
ring len
Length.
Definition: dwmac.h:231
uint8_t flags
Flags.
Definition: ena.h:18
void * 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.
uint32_t addr
Buffer address.
Definition: dwmac.h:20
#define ENODEV
No such device.
Definition: errno.h:510
DMA operations.
Definition: dma.h:60
void dma_ufree(struct dma_mapping *map, void *addr, size_t len)
Unmap and free DMA-coherent buffer from external (user) memory.
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
FILE_SECBOOT(PERMITTED)
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
static __always_inline int struct dma_mapping * map
Definition: dma.h:184
static void * dma_op_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.c:135
static void dma_op_unmap(struct dma_mapping *map, size_t len)
Unmap buffer.
Definition: dma.c:85
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static void dma_op_free(struct dma_mapping *map, void *addr, size_t len)
Unmap and free DMA-coherent buffer.
Definition: dma.c:118
A DMA mapping.
Definition: dma.h:33
#define NULL
NULL pointer (VOID *)
Definition: Base.h:322
static void dma_op_set_mask(struct dma_device *dma, physaddr_t mask)
Set addressable space mask.
Definition: dma.c:166
physaddr_t dma(struct dma_mapping *map, void *addr)
Get DMA address from virtual address.
A DMA-capable device.
Definition: dma.h:48