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" 185e5a94b6SBenoî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 { 91*5c9eb028SPeter Maydell return (bool)address_space_rw(as, addr, MEMTXATTRS_UNSPECIFIED, 92*5c9eb028SPeter Maydell buf, len, dir == DMA_DIRECTION_FROM_DEVICE); 939c17d615SPaolo Bonzini } 949c17d615SPaolo Bonzini 95df32fd1cSPaolo Bonzini static inline int dma_memory_read_relaxed(AddressSpace *as, dma_addr_t addr, 969c17d615SPaolo Bonzini void *buf, dma_addr_t len) 979c17d615SPaolo Bonzini { 98df32fd1cSPaolo Bonzini return dma_memory_rw_relaxed(as, addr, buf, len, DMA_DIRECTION_TO_DEVICE); 999c17d615SPaolo Bonzini } 1009c17d615SPaolo Bonzini 101df32fd1cSPaolo Bonzini static inline int dma_memory_write_relaxed(AddressSpace *as, dma_addr_t addr, 1029c17d615SPaolo Bonzini const void *buf, dma_addr_t len) 1039c17d615SPaolo Bonzini { 104df32fd1cSPaolo Bonzini return dma_memory_rw_relaxed(as, addr, (void *)buf, len, 1059c17d615SPaolo Bonzini DMA_DIRECTION_FROM_DEVICE); 1069c17d615SPaolo Bonzini } 1079c17d615SPaolo Bonzini 108df32fd1cSPaolo Bonzini static inline int dma_memory_rw(AddressSpace *as, dma_addr_t addr, 1099c17d615SPaolo Bonzini void *buf, dma_addr_t len, 1109c17d615SPaolo Bonzini DMADirection dir) 1119c17d615SPaolo Bonzini { 112df32fd1cSPaolo Bonzini dma_barrier(as, dir); 1139c17d615SPaolo Bonzini 114df32fd1cSPaolo Bonzini return dma_memory_rw_relaxed(as, addr, buf, len, dir); 1159c17d615SPaolo Bonzini } 1169c17d615SPaolo Bonzini 117df32fd1cSPaolo Bonzini static inline int dma_memory_read(AddressSpace *as, dma_addr_t addr, 1189c17d615SPaolo Bonzini void *buf, dma_addr_t len) 1199c17d615SPaolo Bonzini { 120df32fd1cSPaolo Bonzini return dma_memory_rw(as, addr, buf, len, DMA_DIRECTION_TO_DEVICE); 1219c17d615SPaolo Bonzini } 1229c17d615SPaolo Bonzini 123df32fd1cSPaolo Bonzini static inline int dma_memory_write(AddressSpace *as, dma_addr_t addr, 1249c17d615SPaolo Bonzini const void *buf, dma_addr_t len) 1259c17d615SPaolo Bonzini { 126df32fd1cSPaolo Bonzini return dma_memory_rw(as, addr, (void *)buf, len, 1279c17d615SPaolo Bonzini DMA_DIRECTION_FROM_DEVICE); 1289c17d615SPaolo Bonzini } 1299c17d615SPaolo Bonzini 130df32fd1cSPaolo Bonzini int dma_memory_set(AddressSpace *as, dma_addr_t addr, uint8_t c, dma_addr_t len); 1319c17d615SPaolo Bonzini 132df32fd1cSPaolo Bonzini static inline void *dma_memory_map(AddressSpace *as, 1339c17d615SPaolo Bonzini dma_addr_t addr, dma_addr_t *len, 1349c17d615SPaolo Bonzini DMADirection dir) 1359c17d615SPaolo Bonzini { 1369c17d615SPaolo Bonzini hwaddr xlen = *len; 1379c17d615SPaolo Bonzini void *p; 1389c17d615SPaolo Bonzini 139df32fd1cSPaolo Bonzini p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE); 1409c17d615SPaolo Bonzini *len = xlen; 1419c17d615SPaolo Bonzini return p; 1429c17d615SPaolo Bonzini } 1439c17d615SPaolo Bonzini 144df32fd1cSPaolo Bonzini static inline void dma_memory_unmap(AddressSpace *as, 1459c17d615SPaolo Bonzini void *buffer, dma_addr_t len, 1469c17d615SPaolo Bonzini DMADirection dir, dma_addr_t access_len) 1479c17d615SPaolo Bonzini { 148df32fd1cSPaolo Bonzini address_space_unmap(as, buffer, (hwaddr)len, 1499c17d615SPaolo Bonzini dir == DMA_DIRECTION_FROM_DEVICE, access_len); 1509c17d615SPaolo Bonzini } 1519c17d615SPaolo Bonzini 1529c17d615SPaolo Bonzini #define DEFINE_LDST_DMA(_lname, _sname, _bits, _end) \ 153df32fd1cSPaolo Bonzini static inline uint##_bits##_t ld##_lname##_##_end##_dma(AddressSpace *as, \ 1549c17d615SPaolo Bonzini dma_addr_t addr) \ 1559c17d615SPaolo Bonzini { \ 1569c17d615SPaolo Bonzini uint##_bits##_t val; \ 157df32fd1cSPaolo Bonzini dma_memory_read(as, addr, &val, (_bits) / 8); \ 1589c17d615SPaolo Bonzini return _end##_bits##_to_cpu(val); \ 1599c17d615SPaolo Bonzini } \ 160df32fd1cSPaolo Bonzini static inline void st##_sname##_##_end##_dma(AddressSpace *as, \ 1619c17d615SPaolo Bonzini dma_addr_t addr, \ 1629c17d615SPaolo Bonzini uint##_bits##_t val) \ 1639c17d615SPaolo Bonzini { \ 1649c17d615SPaolo Bonzini val = cpu_to_##_end##_bits(val); \ 165df32fd1cSPaolo Bonzini dma_memory_write(as, addr, &val, (_bits) / 8); \ 1669c17d615SPaolo Bonzini } 1679c17d615SPaolo Bonzini 168df32fd1cSPaolo Bonzini static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr) 1699c17d615SPaolo Bonzini { 1709c17d615SPaolo Bonzini uint8_t val; 1719c17d615SPaolo Bonzini 172df32fd1cSPaolo Bonzini dma_memory_read(as, addr, &val, 1); 1739c17d615SPaolo Bonzini return val; 1749c17d615SPaolo Bonzini } 1759c17d615SPaolo Bonzini 176df32fd1cSPaolo Bonzini static inline void stb_dma(AddressSpace *as, dma_addr_t addr, uint8_t val) 1779c17d615SPaolo Bonzini { 178df32fd1cSPaolo Bonzini dma_memory_write(as, addr, &val, 1); 1799c17d615SPaolo Bonzini } 1809c17d615SPaolo Bonzini 1819c17d615SPaolo Bonzini DEFINE_LDST_DMA(uw, w, 16, le); 1829c17d615SPaolo Bonzini DEFINE_LDST_DMA(l, l, 32, le); 1839c17d615SPaolo Bonzini DEFINE_LDST_DMA(q, q, 64, le); 1849c17d615SPaolo Bonzini DEFINE_LDST_DMA(uw, w, 16, be); 1859c17d615SPaolo Bonzini DEFINE_LDST_DMA(l, l, 32, be); 1869c17d615SPaolo Bonzini DEFINE_LDST_DMA(q, q, 64, be); 1879c17d615SPaolo Bonzini 1889c17d615SPaolo Bonzini #undef DEFINE_LDST_DMA 1899c17d615SPaolo Bonzini 1909c17d615SPaolo Bonzini struct ScatterGatherEntry { 1919c17d615SPaolo Bonzini dma_addr_t base; 1929c17d615SPaolo Bonzini dma_addr_t len; 1939c17d615SPaolo Bonzini }; 1949c17d615SPaolo Bonzini 195f487b677SPaolo Bonzini void qemu_sglist_init(QEMUSGList *qsg, DeviceState *dev, int alloc_hint, 196f487b677SPaolo Bonzini AddressSpace *as); 1979c17d615SPaolo Bonzini void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len); 1989c17d615SPaolo Bonzini void qemu_sglist_destroy(QEMUSGList *qsg); 1999c17d615SPaolo Bonzini #endif 2009c17d615SPaolo Bonzini 2014be74634SMarkus Armbruster typedef BlockAIOCB *DMAIOFunc(BlockBackend *blk, int64_t sector_num, 2029c17d615SPaolo Bonzini QEMUIOVector *iov, int nb_sectors, 203097310b5SMarkus Armbruster BlockCompletionFunc *cb, void *opaque); 2049c17d615SPaolo Bonzini 2054be74634SMarkus Armbruster BlockAIOCB *dma_blk_io(BlockBackend *blk, 2069c17d615SPaolo Bonzini QEMUSGList *sg, uint64_t sector_num, 207097310b5SMarkus Armbruster DMAIOFunc *io_func, BlockCompletionFunc *cb, 2089c17d615SPaolo Bonzini void *opaque, DMADirection dir); 2094be74634SMarkus Armbruster BlockAIOCB *dma_blk_read(BlockBackend *blk, 2109c17d615SPaolo Bonzini QEMUSGList *sg, uint64_t sector, 211097310b5SMarkus Armbruster BlockCompletionFunc *cb, void *opaque); 2124be74634SMarkus Armbruster BlockAIOCB *dma_blk_write(BlockBackend *blk, 2139c17d615SPaolo Bonzini QEMUSGList *sg, uint64_t sector, 214097310b5SMarkus Armbruster BlockCompletionFunc *cb, void *opaque); 2159c17d615SPaolo Bonzini uint64_t dma_buf_read(uint8_t *ptr, int32_t len, QEMUSGList *sg); 2169c17d615SPaolo Bonzini uint64_t dma_buf_write(uint8_t *ptr, int32_t len, QEMUSGList *sg); 2179c17d615SPaolo Bonzini 2184be74634SMarkus Armbruster void dma_acct_start(BlockBackend *blk, BlockAcctCookie *cookie, 2199c17d615SPaolo Bonzini QEMUSGList *sg, enum BlockAcctType type); 2209c17d615SPaolo Bonzini 2219c17d615SPaolo Bonzini #endif 222