Revision df32fd1c include/sysemu/dma.h
b/include/sysemu/dma.h | ||
---|---|---|
12 | 12 |
|
13 | 13 |
#include <stdio.h> |
14 | 14 |
#include "exec/memory.h" |
15 |
#include "exec/address-spaces.h" |
|
15 | 16 |
#include "hw/hw.h" |
16 | 17 |
#include "block/block.h" |
17 | 18 |
#include "sysemu/kvm.h" |
18 | 19 |
|
19 |
typedef struct DMAContext DMAContext; |
|
20 | 20 |
typedef struct ScatterGatherEntry ScatterGatherEntry; |
21 | 21 |
|
22 | 22 |
typedef enum { |
... | ... | |
29 | 29 |
int nsg; |
30 | 30 |
int nalloc; |
31 | 31 |
size_t size; |
32 |
DMAContext *dma;
|
|
32 |
AddressSpace *as;
|
|
33 | 33 |
}; |
34 | 34 |
|
35 | 35 |
#ifndef CONFIG_USER_ONLY |
... | ... | |
46 | 46 |
#define DMA_ADDR_BITS 64 |
47 | 47 |
#define DMA_ADDR_FMT "%" PRIx64 |
48 | 48 |
|
49 |
struct DMAContext { |
|
50 |
AddressSpace *as; |
|
51 |
}; |
|
52 |
|
|
53 |
/* A global DMA context corresponding to the address_space_memory |
|
54 |
* AddressSpace, for sysbus devices which do DMA. |
|
55 |
*/ |
|
56 |
extern DMAContext dma_context_memory; |
|
57 |
|
|
58 |
static inline void dma_barrier(DMAContext *dma, DMADirection dir) |
|
49 |
static inline void dma_barrier(AddressSpace *as, DMADirection dir) |
|
59 | 50 |
{ |
60 | 51 |
/* |
61 | 52 |
* This is called before DMA read and write operations |
... | ... | |
83 | 74 |
/* Checks that the given range of addresses is valid for DMA. This is |
84 | 75 |
* useful for certain cases, but usually you should just use |
85 | 76 |
* dma_memory_{read,write}() and check for errors */ |
86 |
static inline bool dma_memory_valid(DMAContext *dma,
|
|
77 |
static inline bool dma_memory_valid(AddressSpace *as,
|
|
87 | 78 |
dma_addr_t addr, dma_addr_t len, |
88 | 79 |
DMADirection dir) |
89 | 80 |
{ |
90 |
return address_space_access_valid(dma->as, addr, len,
|
|
81 |
return address_space_access_valid(as, addr, len, |
|
91 | 82 |
dir == DMA_DIRECTION_FROM_DEVICE); |
92 | 83 |
} |
93 | 84 |
|
94 |
static inline int dma_memory_rw_relaxed(DMAContext *dma, dma_addr_t addr,
|
|
85 |
static inline int dma_memory_rw_relaxed(AddressSpace *as, dma_addr_t addr,
|
|
95 | 86 |
void *buf, dma_addr_t len, |
96 | 87 |
DMADirection dir) |
97 | 88 |
{ |
98 |
return address_space_rw(dma->as, addr, buf, len, dir == DMA_DIRECTION_FROM_DEVICE);
|
|
89 |
return address_space_rw(as, addr, buf, len, dir == DMA_DIRECTION_FROM_DEVICE); |
|
99 | 90 |
} |
100 | 91 |
|
101 |
static inline int dma_memory_read_relaxed(DMAContext *dma, dma_addr_t addr,
|
|
92 |
static inline int dma_memory_read_relaxed(AddressSpace *as, dma_addr_t addr,
|
|
102 | 93 |
void *buf, dma_addr_t len) |
103 | 94 |
{ |
104 |
return dma_memory_rw_relaxed(dma, addr, buf, len, DMA_DIRECTION_TO_DEVICE);
|
|
95 |
return dma_memory_rw_relaxed(as, addr, buf, len, DMA_DIRECTION_TO_DEVICE);
|
|
105 | 96 |
} |
106 | 97 |
|
107 |
static inline int dma_memory_write_relaxed(DMAContext *dma, dma_addr_t addr,
|
|
98 |
static inline int dma_memory_write_relaxed(AddressSpace *as, dma_addr_t addr,
|
|
108 | 99 |
const void *buf, dma_addr_t len) |
109 | 100 |
{ |
110 |
return dma_memory_rw_relaxed(dma, addr, (void *)buf, len,
|
|
101 |
return dma_memory_rw_relaxed(as, addr, (void *)buf, len,
|
|
111 | 102 |
DMA_DIRECTION_FROM_DEVICE); |
112 | 103 |
} |
113 | 104 |
|
114 |
static inline int dma_memory_rw(DMAContext *dma, dma_addr_t addr,
|
|
105 |
static inline int dma_memory_rw(AddressSpace *as, dma_addr_t addr,
|
|
115 | 106 |
void *buf, dma_addr_t len, |
116 | 107 |
DMADirection dir) |
117 | 108 |
{ |
118 |
dma_barrier(dma, dir);
|
|
109 |
dma_barrier(as, dir);
|
|
119 | 110 |
|
120 |
return dma_memory_rw_relaxed(dma, addr, buf, len, dir);
|
|
111 |
return dma_memory_rw_relaxed(as, addr, buf, len, dir);
|
|
121 | 112 |
} |
122 | 113 |
|
123 |
static inline int dma_memory_read(DMAContext *dma, dma_addr_t addr,
|
|
114 |
static inline int dma_memory_read(AddressSpace *as, dma_addr_t addr,
|
|
124 | 115 |
void *buf, dma_addr_t len) |
125 | 116 |
{ |
126 |
return dma_memory_rw(dma, addr, buf, len, DMA_DIRECTION_TO_DEVICE);
|
|
117 |
return dma_memory_rw(as, addr, buf, len, DMA_DIRECTION_TO_DEVICE);
|
|
127 | 118 |
} |
128 | 119 |
|
129 |
static inline int dma_memory_write(DMAContext *dma, dma_addr_t addr,
|
|
120 |
static inline int dma_memory_write(AddressSpace *as, dma_addr_t addr,
|
|
130 | 121 |
const void *buf, dma_addr_t len) |
131 | 122 |
{ |
132 |
return dma_memory_rw(dma, addr, (void *)buf, len,
|
|
123 |
return dma_memory_rw(as, addr, (void *)buf, len,
|
|
133 | 124 |
DMA_DIRECTION_FROM_DEVICE); |
134 | 125 |
} |
135 | 126 |
|
136 |
int dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c, dma_addr_t len);
|
|
127 |
int dma_memory_set(AddressSpace *as, dma_addr_t addr, uint8_t c, dma_addr_t len);
|
|
137 | 128 |
|
138 |
static inline void *dma_memory_map(DMAContext *dma,
|
|
129 |
static inline void *dma_memory_map(AddressSpace *as,
|
|
139 | 130 |
dma_addr_t addr, dma_addr_t *len, |
140 | 131 |
DMADirection dir) |
141 | 132 |
{ |
142 | 133 |
hwaddr xlen = *len; |
143 | 134 |
void *p; |
144 | 135 |
|
145 |
p = address_space_map(dma->as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE);
|
|
136 |
p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE); |
|
146 | 137 |
*len = xlen; |
147 | 138 |
return p; |
148 | 139 |
} |
149 | 140 |
|
150 |
static inline void dma_memory_unmap(DMAContext *dma,
|
|
141 |
static inline void dma_memory_unmap(AddressSpace *as,
|
|
151 | 142 |
void *buffer, dma_addr_t len, |
152 | 143 |
DMADirection dir, dma_addr_t access_len) |
153 | 144 |
{ |
154 |
address_space_unmap(dma->as, buffer, (hwaddr)len,
|
|
145 |
address_space_unmap(as, buffer, (hwaddr)len, |
|
155 | 146 |
dir == DMA_DIRECTION_FROM_DEVICE, access_len); |
156 | 147 |
} |
157 | 148 |
|
158 | 149 |
#define DEFINE_LDST_DMA(_lname, _sname, _bits, _end) \ |
159 |
static inline uint##_bits##_t ld##_lname##_##_end##_dma(DMAContext *dma, \
|
|
150 |
static inline uint##_bits##_t ld##_lname##_##_end##_dma(AddressSpace *as, \
|
|
160 | 151 |
dma_addr_t addr) \ |
161 | 152 |
{ \ |
162 | 153 |
uint##_bits##_t val; \ |
163 |
dma_memory_read(dma, addr, &val, (_bits) / 8); \
|
|
154 |
dma_memory_read(as, addr, &val, (_bits) / 8); \
|
|
164 | 155 |
return _end##_bits##_to_cpu(val); \ |
165 | 156 |
} \ |
166 |
static inline void st##_sname##_##_end##_dma(DMAContext *dma, \
|
|
157 |
static inline void st##_sname##_##_end##_dma(AddressSpace *as, \
|
|
167 | 158 |
dma_addr_t addr, \ |
168 | 159 |
uint##_bits##_t val) \ |
169 | 160 |
{ \ |
170 | 161 |
val = cpu_to_##_end##_bits(val); \ |
171 |
dma_memory_write(dma, addr, &val, (_bits) / 8); \
|
|
162 |
dma_memory_write(as, addr, &val, (_bits) / 8); \
|
|
172 | 163 |
} |
173 | 164 |
|
174 |
static inline uint8_t ldub_dma(DMAContext *dma, dma_addr_t addr)
|
|
165 |
static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr)
|
|
175 | 166 |
{ |
176 | 167 |
uint8_t val; |
177 | 168 |
|
178 |
dma_memory_read(dma, addr, &val, 1);
|
|
169 |
dma_memory_read(as, addr, &val, 1);
|
|
179 | 170 |
return val; |
180 | 171 |
} |
181 | 172 |
|
182 |
static inline void stb_dma(DMAContext *dma, dma_addr_t addr, uint8_t val)
|
|
173 |
static inline void stb_dma(AddressSpace *as, dma_addr_t addr, uint8_t val)
|
|
183 | 174 |
{ |
184 |
dma_memory_write(dma, addr, &val, 1);
|
|
175 |
dma_memory_write(as, addr, &val, 1);
|
|
185 | 176 |
} |
186 | 177 |
|
187 | 178 |
DEFINE_LDST_DMA(uw, w, 16, le); |
... | ... | |
193 | 184 |
|
194 | 185 |
#undef DEFINE_LDST_DMA |
195 | 186 |
|
196 |
void dma_context_init(DMAContext *dma, AddressSpace *as); |
|
197 |
|
|
198 | 187 |
struct ScatterGatherEntry { |
199 | 188 |
dma_addr_t base; |
200 | 189 |
dma_addr_t len; |
201 | 190 |
}; |
202 | 191 |
|
203 |
void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint, DMAContext *dma);
|
|
192 |
void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint, AddressSpace *as);
|
|
204 | 193 |
void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len); |
205 | 194 |
void qemu_sglist_destroy(QEMUSGList *qsg); |
206 | 195 |
#endif |
Also available in: Unified diff