iommu: Add universal DMA helper functions
[qemu-kvm.git] / dma.h
blob8912dfcb6e9703669372b6ebf7321cc50e9c8b17
1 /*
2 * DMA helper functions
4 * Copyright (c) 2009 Red Hat
6 * This work is licensed under the terms of the GNU General Public License
7 * (GNU GPL), version 2 or later.
8 */
10 #ifndef DMA_H
11 #define DMA_H
13 #include <stdio.h>
14 #include "hw/hw.h"
15 #include "block.h"
17 typedef struct DMAContext DMAContext;
18 typedef struct ScatterGatherEntry ScatterGatherEntry;
20 typedef enum {
21 DMA_DIRECTION_TO_DEVICE = 0,
22 DMA_DIRECTION_FROM_DEVICE = 1,
23 } DMADirection;
25 struct QEMUSGList {
26 ScatterGatherEntry *sg;
27 int nsg;
28 int nalloc;
29 size_t size;
32 #if defined(TARGET_PHYS_ADDR_BITS)
33 typedef target_phys_addr_t dma_addr_t;
35 #define DMA_ADDR_BITS TARGET_PHYS_ADDR_BITS
36 #define DMA_ADDR_FMT TARGET_FMT_plx
38 /* Checks that the given range of addresses is valid for DMA. This is
39 * useful for certain cases, but usually you should just use
40 * dma_memory_{read,write}() and check for errors */
41 static inline bool dma_memory_valid(DMAContext *dma, dma_addr_t addr,
42 dma_addr_t len, DMADirection dir)
44 /* Stub version, with no iommu we assume all bus addresses are valid */
45 return true;
48 static inline int dma_memory_rw(DMAContext *dma, dma_addr_t addr,
49 void *buf, dma_addr_t len, DMADirection dir)
51 /* Stub version when we have no iommu support */
52 cpu_physical_memory_rw(addr, buf, (target_phys_addr_t)len,
53 dir == DMA_DIRECTION_FROM_DEVICE);
54 return 0;
57 static inline int dma_memory_read(DMAContext *dma, dma_addr_t addr,
58 void *buf, dma_addr_t len)
60 return dma_memory_rw(dma, addr, buf, len, DMA_DIRECTION_TO_DEVICE);
63 static inline int dma_memory_write(DMAContext *dma, dma_addr_t addr,
64 const void *buf, dma_addr_t len)
66 return dma_memory_rw(dma, addr, (void *)buf, len,
67 DMA_DIRECTION_FROM_DEVICE);
70 int dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c, dma_addr_t len);
72 static inline void *dma_memory_map(DMAContext *dma,
73 dma_addr_t addr, dma_addr_t *len,
74 DMADirection dir)
76 target_phys_addr_t xlen = *len;
77 void *p;
79 p = cpu_physical_memory_map(addr, &xlen,
80 dir == DMA_DIRECTION_FROM_DEVICE);
81 *len = xlen;
82 return p;
85 static inline void dma_memory_unmap(DMAContext *dma,
86 void *buffer, dma_addr_t len,
87 DMADirection dir, dma_addr_t access_len)
89 return cpu_physical_memory_unmap(buffer, (target_phys_addr_t)len,
90 dir == DMA_DIRECTION_FROM_DEVICE,
91 access_len);
94 #define DEFINE_LDST_DMA(_lname, _sname, _bits, _end) \
95 static inline uint##_bits##_t ld##_lname##_##_end##_dma(DMAContext *dma, \
96 dma_addr_t addr) \
97 { \
98 uint##_bits##_t val; \
99 dma_memory_read(dma, addr, &val, (_bits) / 8); \
100 return _end##_bits##_to_cpu(val); \
102 static inline void st##_sname##_##_end##_dma(DMAContext *dma, \
103 dma_addr_t addr, \
104 uint##_bits##_t val) \
106 val = cpu_to_##_end##_bits(val); \
107 dma_memory_write(dma, addr, &val, (_bits) / 8); \
110 static inline uint8_t ldub_dma(DMAContext *dma, dma_addr_t addr)
112 uint8_t val;
114 dma_memory_read(dma, addr, &val, 1);
115 return val;
118 static inline void stb_dma(DMAContext *dma, dma_addr_t addr, uint8_t val)
120 dma_memory_write(dma, addr, &val, 1);
123 DEFINE_LDST_DMA(uw, w, 16, le);
124 DEFINE_LDST_DMA(l, l, 32, le);
125 DEFINE_LDST_DMA(q, q, 64, le);
126 DEFINE_LDST_DMA(uw, w, 16, be);
127 DEFINE_LDST_DMA(l, l, 32, be);
128 DEFINE_LDST_DMA(q, q, 64, be);
130 #undef DEFINE_LDST_DMA
132 struct ScatterGatherEntry {
133 dma_addr_t base;
134 dma_addr_t len;
137 void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint);
138 void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len);
139 void qemu_sglist_destroy(QEMUSGList *qsg);
140 #endif
142 typedef BlockDriverAIOCB *DMAIOFunc(BlockDriverState *bs, int64_t sector_num,
143 QEMUIOVector *iov, int nb_sectors,
144 BlockDriverCompletionFunc *cb, void *opaque);
146 BlockDriverAIOCB *dma_bdrv_io(BlockDriverState *bs,
147 QEMUSGList *sg, uint64_t sector_num,
148 DMAIOFunc *io_func, BlockDriverCompletionFunc *cb,
149 void *opaque, DMADirection dir);
150 BlockDriverAIOCB *dma_bdrv_read(BlockDriverState *bs,
151 QEMUSGList *sg, uint64_t sector,
152 BlockDriverCompletionFunc *cb, void *opaque);
153 BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
154 QEMUSGList *sg, uint64_t sector,
155 BlockDriverCompletionFunc *cb, void *opaque);
156 uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg);
157 uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg);
159 void dma_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie,
160 QEMUSGList *sg, enum BlockAcctType type);
162 #endif