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 );
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  physaddr_t 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  */
83 static void dma_op_unmap ( struct dma_mapping *map ) {
84  struct dma_device *dma = map->dma;
85 
86  assert ( dma != NULL );
87  assert ( dma->op != NULL );
88  dma->op->unmap ( dma, map );
89 }
90 
91 /**
92  * Allocate and map DMA-coherent buffer
93  *
94  * @v dma DMA device
95  * @v map DMA mapping to fill in
96  * @v len Length of buffer
97  * @v align Physical alignment
98  * @ret addr Buffer address, or NULL on error
99  */
100 static void * dma_op_alloc ( struct dma_device *dma, struct dma_mapping *map,
101  size_t len, size_t align ) {
102  struct dma_operations *op = dma->op;
103 
104  if ( ! op )
105  return NULL;
106  return op->alloc ( dma, map, len, align );
107 }
108 
109 /**
110  * Unmap and free DMA-coherent buffer
111  *
112  * @v map DMA mapping
113  * @v addr Buffer address
114  * @v len Length of buffer
115  */
116 static void dma_op_free ( struct dma_mapping *map, void *addr, size_t len ) {
117  struct dma_device *dma = map->dma;
118 
119  assert ( dma != NULL );
120  assert ( dma->op != NULL );
121  dma->op->free ( dma, map, addr, len );
122 }
123 
124 /**
125  * Allocate and map DMA-coherent buffer from external (user) memory
126  *
127  * @v dma DMA device
128  * @v map DMA mapping to fill in
129  * @v len Length of buffer
130  * @v align Physical alignment
131  * @ret addr Buffer address, or NULL on error
132  */
134  struct dma_mapping *map,
135  size_t len, size_t align ) {
136  struct dma_operations *op = dma->op;
137 
138  if ( ! op )
139  return UNULL;
140  return op->umalloc ( dma, map, len, align );
141 }
142 
143 /**
144  * Unmap and free DMA-coherent buffer from external (user) memory
145  *
146  * @v map DMA mapping
147  * @v addr Buffer address
148  * @v len Length of buffer
149  */
150 static void dma_op_ufree ( struct dma_mapping *map, userptr_t addr,
151  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 );
static __always_inline void struct dma_mapping size_t size_t align
Definition: dma.h:222
DMA mappings.
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:100
Error codes.
physaddr_t dma_phys(struct dma_mapping *map, physaddr_t addr)
Get DMA address from physical address.
PROVIDE_DMAAPI(op, dma_map, dma_op_map)
static void dma_op_unmap(struct dma_mapping *map)
Unmap buffer.
Definition: dma.c:83
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)
void dma_unmap(struct dma_mapping *map)
Unmap buffer.
static int dma_op_map(struct dma_device *dma, struct dma_mapping *map, physaddr_t addr, size_t len, int flags)
Map buffer for DMA.
Definition: dma.c:69
void dma_set_mask(struct dma_device *dma, physaddr_t mask)
Set addressable space mask.
#define ENODEV
No such device.
Definition: errno.h:509
u32 addr
Definition: sky2.h:8
DMA operations.
Definition: dma.h:59
static void dma_op_ufree(struct dma_mapping *map, userptr_t addr, size_t len)
Unmap and free DMA-coherent buffer from external (user) memory.
Definition: dma.c:150
static __always_inline int struct dma_mapping * map
Definition: dma.h:181
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
void dma_ufree(struct dma_mapping *map, userptr_t addr, size_t len)
Unmap and free DMA-coherent buffer from external (user) memory.
#define UNULL
Equivalent of NULL for user pointers.
Definition: uaccess.h:36
uint32_t len
Length.
Definition: ena.h:14
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
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.
static userptr_t 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:133
static __always_inline physaddr_t dma(struct dma_mapping *map, void *addr)
Get DMA address from virtual address.
Definition: dma.h:436
static void dma_op_free(struct dma_mapping *map, void *addr, size_t len)
Unmap and free DMA-coherent buffer.
Definition: dma.c:116
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
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