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 
26 #include <assert.h>
27 #include <errno.h>
28 #include <ipxe/dma.h>
29 
30 /** @file
31  *
32  * DMA mappings
33  *
34  */
35 
36 /******************************************************************************
37  *
38  * Flat address space DMA API
39  *
40  ******************************************************************************
41  */
42 
43 PROVIDE_DMAAPI_INLINE ( flat, dma_map );
50 PROVIDE_DMAAPI_INLINE ( flat, dma );
51 
52 /******************************************************************************
53  *
54  * Operations-based DMA API
55  *
56  ******************************************************************************
57  */
58 
59 /**
60  * Map buffer for DMA
61  *
62  * @v dma DMA device
63  * @v map DMA mapping to fill in
64  * @v addr Buffer address
65  * @v len Length of buffer
66  * @v flags Mapping flags
67  * @ret rc Return status code
68  */
69 static int dma_op_map ( struct dma_device *dma, struct dma_mapping *map,
70  void *addr, size_t len, int flags ) {
71  struct dma_operations *op = dma->op;
72 
73  if ( ! op )
74  return -ENODEV;
75  return op->map ( dma, map, addr, len, flags );
76 }
77 
78 /**
79  * Unmap buffer
80  *
81  * @v map DMA mapping
82  * @v len Used length
83  */
84 static void dma_op_unmap ( struct dma_mapping *map, size_t len ) {
85  struct dma_device *dma = map->dma;
86 
87  assert ( dma != NULL );
88  assert ( dma->op != NULL );
89  dma->op->unmap ( dma, map, len );
90 }
91 
92 /**
93  * Allocate and map DMA-coherent buffer
94  *
95  * @v dma DMA device
96  * @v map DMA mapping to fill in
97  * @v len Length of buffer
98  * @v align Physical alignment
99  * @ret addr Buffer address, or NULL on error
100  */
101 static void * dma_op_alloc ( struct dma_device *dma, struct dma_mapping *map,
102  size_t len, size_t align ) {
103  struct dma_operations *op = dma->op;
104 
105  if ( ! op )
106  return NULL;
107  return op->alloc ( dma, map, len, align );
108 }
109 
110 /**
111  * Unmap and free DMA-coherent buffer
112  *
113  * @v map DMA mapping
114  * @v addr Buffer address
115  * @v len Length of buffer
116  */
117 static void dma_op_free ( struct dma_mapping *map, void *addr, size_t len ) {
118  struct dma_device *dma = map->dma;
119 
120  assert ( dma != NULL );
121  assert ( dma->op != NULL );
122  dma->op->free ( dma, map, addr, len );
123 }
124 
125 /**
126  * Allocate and map DMA-coherent buffer from external (user) memory
127  *
128  * @v dma DMA device
129  * @v map DMA mapping to fill in
130  * @v len Length of buffer
131  * @v align Physical alignment
132  * @ret addr Buffer address, or NULL on error
133  */
134 static void * dma_op_umalloc ( struct dma_device *dma,
135  struct dma_mapping *map,
136  size_t len, size_t align ) {
137  struct dma_operations *op = dma->op;
138 
139  if ( ! op )
140  return NULL;
141  return op->umalloc ( dma, map, len, align );
142 }
143 
144 /**
145  * Unmap and free DMA-coherent buffer from external (user) memory
146  *
147  * @v map DMA mapping
148  * @v addr Buffer address
149  * @v len Length of buffer
150  */
151 static void dma_op_ufree ( struct dma_mapping *map, void *addr, size_t len ) {
152  struct dma_device *dma = map->dma;
153 
154  assert ( dma != NULL );
155  assert ( dma->op != NULL );
156  dma->op->ufree ( dma, map, addr, len );
157 }
158 
159 /**
160  * Set addressable space mask
161  *
162  * @v dma DMA device
163  * @v mask Addressable space mask
164  */
165 static void dma_op_set_mask ( struct dma_device *dma, physaddr_t mask ) {
166  struct dma_operations *op = dma->op;
167 
168  if ( op )
169  op->set_mask ( dma, mask );
170 }
171 
172 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:41
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:101
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:69
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:151
physaddr_t mask
Addressable space mask.
Definition: dma.h:51
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:509
DMA operations.
Definition: dma.h:59
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
static uint16_t struct vmbus_xfer_pages_operations * op
Definition: netvsc.h:327
static __always_inline int struct dma_mapping * map
Definition: dma.h:183
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:134
static void dma_op_unmap(struct dma_mapping *map, size_t len)
Unmap buffer.
Definition: dma.c:84
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:117
A DMA mapping.
Definition: dma.h:32
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
static void dma_op_set_mask(struct dma_device *dma, physaddr_t mask)
Set addressable space mask.
Definition: dma.c:165
physaddr_t dma(struct dma_mapping *map, void *addr)
Get DMA address from virtual address.
A DMA-capable device.
Definition: dma.h:47