xref: /qemu/include/sysemu/dma.h (revision 5e5a94b6)
19c17d615SPaolo Bonzini /*
29c17d615SPaolo Bonzini  * DMA helper functions
39c17d615SPaolo Bonzini  *
49c17d615SPaolo Bonzini  * Copyright (c) 2009 Red Hat
59c17d615SPaolo Bonzini  *
69c17d615SPaolo Bonzini  * This work is licensed under the terms of the GNU General Public License
79c17d615SPaolo Bonzini  * (GNU GPL), version 2 or later.
89c17d615SPaolo Bonzini  */
99c17d615SPaolo Bonzini 
109c17d615SPaolo Bonzini #ifndef DMA_H
119c17d615SPaolo Bonzini #define DMA_H
129c17d615SPaolo Bonzini 
139c17d615SPaolo Bonzini #include <stdio.h>
149c17d615SPaolo Bonzini #include "exec/memory.h"
15df32fd1cSPaolo Bonzini #include "exec/address-spaces.h"
169c17d615SPaolo Bonzini #include "hw/hw.h"
179c17d615SPaolo Bonzini #include "block/block.h"
18*5e5a94b6SBenoît Canet #include "block/accounting.h"
199c17d615SPaolo Bonzini #include "sysemu/kvm.h"
209c17d615SPaolo Bonzini 
219c17d615SPaolo Bonzini typedef struct ScatterGatherEntry ScatterGatherEntry;
229c17d615SPaolo Bonzini 
239c17d615SPaolo Bonzini typedef enum {
249c17d615SPaolo Bonzini     DMA_DIRECTION_TO_DEVICE = 0,
259c17d615SPaolo Bonzini     DMA_DIRECTION_FROM_DEVICE = 1,
269c17d615SPaolo Bonzini } DMADirection;
279c17d615SPaolo Bonzini 
289c17d615SPaolo Bonzini struct QEMUSGList {
299c17d615SPaolo Bonzini     ScatterGatherEntry *sg;
309c17d615SPaolo Bonzini     int nsg;
319c17d615SPaolo Bonzini     int nalloc;
329c17d615SPaolo Bonzini     size_t size;
33f487b677SPaolo Bonzini     DeviceState *dev;
34df32fd1cSPaolo Bonzini     AddressSpace *as;
359c17d615SPaolo Bonzini };
369c17d615SPaolo Bonzini 
379c17d615SPaolo Bonzini #ifndef CONFIG_USER_ONLY
389c17d615SPaolo Bonzini 
399c17d615SPaolo Bonzini /*
409c17d615SPaolo Bonzini  * When an IOMMU is present, bus addresses become distinct from
419c17d615SPaolo Bonzini  * CPU/memory physical addresses and may be a different size.  Because
429c17d615SPaolo Bonzini  * the IOVA size depends more on the bus than on the platform, we more
439c17d615SPaolo Bonzini  * or less have to treat these as 64-bit always to cover all (or at
449c17d615SPaolo Bonzini  * least most) cases.
459c17d615SPaolo Bonzini  */
469c17d615SPaolo Bonzini typedef uint64_t dma_addr_t;
479c17d615SPaolo Bonzini 
489c17d615SPaolo Bonzini #define DMA_ADDR_BITS 64
499c17d615SPaolo Bonzini #define DMA_ADDR_FMT "%" PRIx64
509c17d615SPaolo Bonzini 
51df32fd1cSPaolo Bonzini static inline void dma_barrier(AddressSpace *as, DMADirection dir)
529c17d615SPaolo Bonzini {
539c17d615SPaolo Bonzini     /*
549c17d615SPaolo Bonzini      * This is called before DMA read and write operations
559c17d615SPaolo Bonzini      * unless the _relaxed form is used and is responsible
569c17d615SPaolo Bonzini      * for providing some sane ordering of accesses vs
579c17d615SPaolo Bonzini      * concurrently running VCPUs.
589c17d615SPaolo Bonzini      *
599c17d615SPaolo Bonzini      * Users of map(), unmap() or lower level st/ld_*
609c17d615SPaolo Bonzini      * operations are responsible for providing their own
619c17d615SPaolo Bonzini      * ordering via barriers.
629c17d615SPaolo Bonzini      *
639c17d615SPaolo Bonzini      * This primitive implementation does a simple smp_mb()
649c17d615SPaolo Bonzini      * before each operation which provides pretty much full
659c17d615SPaolo Bonzini      * ordering.
669c17d615SPaolo Bonzini      *
679c17d615SPaolo Bonzini      * A smarter implementation can be devised if needed to
689c17d615SPaolo Bonzini      * use lighter barriers based on the direction of the
699c17d615SPaolo Bonzini      * transfer, the DMA context, etc...
709c17d615SPaolo Bonzini      */
719c17d615SPaolo Bonzini     if (kvm_enabled()) {
729c17d615SPaolo Bonzini         smp_mb();
739c17d615SPaolo Bonzini     }
749c17d615SPaolo Bonzini }
759c17d615SPaolo Bonzini 
769c17d615SPaolo Bonzini /* Checks that the given range of addresses is valid for DMA.  This is
779c17d615SPaolo Bonzini  * useful for certain cases, but usually you should just use
789c17d615SPaolo Bonzini  * dma_memory_{read,write}() and check for errors */
79df32fd1cSPaolo Bonzini static inline bool dma_memory_valid(AddressSpace *as,
809c17d615SPaolo Bonzini                                     dma_addr_t addr, dma_addr_t len,
819c17d615SPaolo Bonzini                                     DMADirection dir)
829c17d615SPaolo Bonzini {
83df32fd1cSPaolo Bonzini     return address_space_access_valid(as, addr, len,
8451644ab7SPaolo Bonzini                                       dir == DMA_DIRECTION_FROM_DEVICE);
859c17d615SPaolo Bonzini }
869c17d615SPaolo Bonzini 
87df32fd1cSPaolo Bonzini static inline int dma_memory_rw_relaxed(AddressSpace *as, dma_addr_t addr,
889c17d615SPaolo Bonzini                                         void *buf, dma_addr_t len,
899c17d615SPaolo Bonzini                                         DMADirection dir)
909c17d615SPaolo Bonzini {
91df32fd1cSPaolo Bonzini     return address_space_rw(as, addr, buf, len, dir == DMA_DIRECTION_FROM_DEVICE);
929c17d615SPaolo Bonzini }
939c17d615SPaolo Bonzini 
94df32fd1cSPaolo Bonzini static inline int dma_memory_read_relaxed(AddressSpace *as, dma_addr_t addr,
959c17d615SPaolo Bonzini                                           void *buf, dma_addr_t len)
969c17d615SPaolo Bonzini {
97df32fd1cSPaolo Bonzini     return dma_memory_rw_relaxed(as, addr, buf, len, DMA_DIRECTION_TO_DEVICE);
989c17d615SPaolo Bonzini }
999c17d615SPaolo Bonzini 
100df32fd1cSPaolo Bonzini static inline int dma_memory_write_relaxed(AddressSpace *as, dma_addr_t addr,
1019c17d615SPaolo Bonzini                                            const void *buf, dma_addr_t len)
1029c17d615SPaolo Bonzini {
103df32fd1cSPaolo Bonzini     return dma_memory_rw_relaxed(as, addr, (void *)buf, len,
1049c17d615SPaolo Bonzini                                  DMA_DIRECTION_FROM_DEVICE);
1059c17d615SPaolo Bonzini }
1069c17d615SPaolo Bonzini 
107df32fd1cSPaolo Bonzini static inline int dma_memory_rw(AddressSpace *as, dma_addr_t addr,
1089c17d615SPaolo Bonzini                                 void *buf, dma_addr_t len,
1099c17d615SPaolo Bonzini                                 DMADirection dir)
1109c17d615SPaolo Bonzini {
111df32fd1cSPaolo Bonzini     dma_barrier(as, dir);
1129c17d615SPaolo Bonzini 
113df32fd1cSPaolo Bonzini     return dma_memory_rw_relaxed(as, addr, buf, len, dir);
1149c17d615SPaolo Bonzini }
1159c17d615SPaolo Bonzini 
116df32fd1cSPaolo Bonzini static inline int dma_memory_read(AddressSpace *as, dma_addr_t addr,
1179c17d615SPaolo Bonzini                                   void *buf, dma_addr_t len)
1189c17d615SPaolo Bonzini {
119df32fd1cSPaolo Bonzini     return dma_memory_rw(as, addr, buf, len, DMA_DIRECTION_TO_DEVICE);
1209c17d615SPaolo Bonzini }
1219c17d615SPaolo Bonzini 
122df32fd1cSPaolo Bonzini static inline int dma_memory_write(AddressSpace *as, dma_addr_t addr,
1239c17d615SPaolo Bonzini                                    const void *buf, dma_addr_t len)
1249c17d615SPaolo Bonzini {
125df32fd1cSPaolo Bonzini     return dma_memory_rw(as, addr, (void *)buf, len,
1269c17d615SPaolo Bonzini                          DMA_DIRECTION_FROM_DEVICE);
1279c17d615SPaolo Bonzini }
1289c17d615SPaolo Bonzini 
129df32fd1cSPaolo Bonzini int dma_memory_set(AddressSpace *as, dma_addr_t addr, uint8_t c, dma_addr_t len);
1309c17d615SPaolo Bonzini 
131df32fd1cSPaolo Bonzini static inline void *dma_memory_map(AddressSpace *as,
1329c17d615SPaolo Bonzini                                    dma_addr_t addr, dma_addr_t *len,
1339c17d615SPaolo Bonzini                                    DMADirection dir)
1349c17d615SPaolo Bonzini {
1359c17d615SPaolo Bonzini     hwaddr xlen = *len;
1369c17d615SPaolo Bonzini     void *p;
1379c17d615SPaolo Bonzini 
138df32fd1cSPaolo Bonzini     p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE);
1399c17d615SPaolo Bonzini     *len = xlen;
1409c17d615SPaolo Bonzini     return p;
1419c17d615SPaolo Bonzini }
1429c17d615SPaolo Bonzini 
143df32fd1cSPaolo Bonzini static inline void dma_memory_unmap(AddressSpace *as,
1449c17d615SPaolo Bonzini                                     void *buffer, dma_addr_t len,
1459c17d615SPaolo Bonzini                                     DMADirection dir, dma_addr_t access_len)
1469c17d615SPaolo Bonzini {
147df32fd1cSPaolo Bonzini     address_space_unmap(as, buffer, (hwaddr)len,
1489c17d615SPaolo Bonzini                         dir == DMA_DIRECTION_FROM_DEVICE, access_len);
1499c17d615SPaolo Bonzini }
1509c17d615SPaolo Bonzini 
1519c17d615SPaolo Bonzini #define DEFINE_LDST_DMA(_lname, _sname, _bits, _end) \
152df32fd1cSPaolo Bonzini     static inline uint##_bits##_t ld##_lname##_##_end##_dma(AddressSpace *as, \
1539c17d615SPaolo Bonzini                                                             dma_addr_t addr) \
1549c17d615SPaolo Bonzini     {                                                                   \
1559c17d615SPaolo Bonzini         uint##_bits##_t val;                                            \
156df32fd1cSPaolo Bonzini         dma_memory_read(as, addr, &val, (_bits) / 8);                   \
1579c17d615SPaolo Bonzini         return _end##_bits##_to_cpu(val);                               \
1589c17d615SPaolo Bonzini     }                                                                   \
159df32fd1cSPaolo Bonzini     static inline void st##_sname##_##_end##_dma(AddressSpace *as,      \
1609c17d615SPaolo Bonzini                                                  dma_addr_t addr,       \
1619c17d615SPaolo Bonzini                                                  uint##_bits##_t val)   \
1629c17d615SPaolo Bonzini     {                                                                   \
1639c17d615SPaolo Bonzini         val = cpu_to_##_end##_bits(val);                                \
164df32fd1cSPaolo Bonzini         dma_memory_write(as, addr, &val, (_bits) / 8);                  \
1659c17d615SPaolo Bonzini     }
1669c17d615SPaolo Bonzini 
167df32fd1cSPaolo Bonzini static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr)
1689c17d615SPaolo Bonzini {
1699c17d615SPaolo Bonzini     uint8_t val;
1709c17d615SPaolo Bonzini 
171df32fd1cSPaolo Bonzini     dma_memory_read(as, addr, &val, 1);
1729c17d615SPaolo Bonzini     return val;
1739c17d615SPaolo Bonzini }
1749c17d615SPaolo Bonzini 
175df32fd1cSPaolo Bonzini static inline void stb_dma(AddressSpace *as, dma_addr_t addr, uint8_t val)
1769c17d615SPaolo Bonzini {
177df32fd1cSPaolo Bonzini     dma_memory_write(as, addr, &val, 1);
1789c17d615SPaolo Bonzini }
1799c17d615SPaolo Bonzini 
1809c17d615SPaolo Bonzini DEFINE_LDST_DMA(uw, w, 16, le);
1819c17d615SPaolo Bonzini DEFINE_LDST_DMA(l, l, 32, le);
1829c17d615SPaolo Bonzini DEFINE_LDST_DMA(q, q, 64, le);
1839c17d615SPaolo Bonzini DEFINE_LDST_DMA(uw, w, 16, be);
1849c17d615SPaolo Bonzini DEFINE_LDST_DMA(l, l, 32, be);
1859c17d615SPaolo Bonzini DEFINE_LDST_DMA(q, q, 64, be);
1869c17d615SPaolo Bonzini 
1879c17d615SPaolo Bonzini #undef DEFINE_LDST_DMA
1889c17d615SPaolo Bonzini 
1899c17d615SPaolo Bonzini struct ScatterGatherEntry {
1909c17d615SPaolo Bonzini     dma_addr_t base;
1919c17d615SPaolo Bonzini     dma_addr_t len;
1929c17d615SPaolo Bonzini };
1939c17d615SPaolo Bonzini 
194f487b677SPaolo Bonzini void qemu_sglist_init(QEMUSGList *qsg, DeviceState *dev, int alloc_hint,
195f487b677SPaolo Bonzini                       AddressSpace *as);
1969c17d615SPaolo Bonzini void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len);
1979c17d615SPaolo Bonzini void qemu_sglist_destroy(QEMUSGList *qsg);
1989c17d615SPaolo Bonzini #endif
1999c17d615SPaolo Bonzini 
2009c17d615SPaolo Bonzini typedef BlockDriverAIOCB *DMAIOFunc(BlockDriverState *bs, int64_t sector_num,
2019c17d615SPaolo Bonzini                                  QEMUIOVector *iov, int nb_sectors,
2029c17d615SPaolo Bonzini                                  BlockDriverCompletionFunc *cb, void *opaque);
2039c17d615SPaolo Bonzini 
2049c17d615SPaolo Bonzini BlockDriverAIOCB *dma_bdrv_io(BlockDriverState *bs,
2059c17d615SPaolo Bonzini                               QEMUSGList *sg, uint64_t sector_num,
2069c17d615SPaolo Bonzini                               DMAIOFunc *io_func, BlockDriverCompletionFunc *cb,
2079c17d615SPaolo Bonzini                               void *opaque, DMADirection dir);
2089c17d615SPaolo Bonzini BlockDriverAIOCB *dma_bdrv_read(BlockDriverState *bs,
2099c17d615SPaolo Bonzini                                 QEMUSGList *sg, uint64_t sector,
2109c17d615SPaolo Bonzini                                 BlockDriverCompletionFunc *cb, void *opaque);
2119c17d615SPaolo Bonzini BlockDriverAIOCB *dma_bdrv_write(BlockDriverState *bs,
2129c17d615SPaolo Bonzini                                  QEMUSGList *sg, uint64_t sector,
2139c17d615SPaolo Bonzini                                  BlockDriverCompletionFunc *cb, void *opaque);
2149c17d615SPaolo Bonzini uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg);
2159c17d615SPaolo Bonzini uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg);
2169c17d615SPaolo Bonzini 
2179c17d615SPaolo Bonzini void dma_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie,
2189c17d615SPaolo Bonzini                     QEMUSGList *sg, enum BlockAcctType type);
2199c17d615SPaolo Bonzini 
2209c17d615SPaolo Bonzini #endif
221