diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/exec/cputlb.h | 4 | ||||
| -rw-r--r-- | include/exec/memory-internal.h | 15 | ||||
| -rw-r--r-- | include/exec/memory.h | 114 | ||||
| -rw-r--r-- | include/hw/pci-host/spapr.h | 3 | ||||
| -rw-r--r-- | include/hw/pci/pci.h | 21 | ||||
| -rw-r--r-- | include/hw/pci/pci_bus.h | 4 | ||||
| -rw-r--r-- | include/hw/ppc/spapr.h | 12 | ||||
| -rw-r--r-- | include/hw/ppc/spapr_vio.h | 21 | ||||
| -rw-r--r-- | include/qemu/int128.h | 19 | ||||
| -rw-r--r-- | include/sysemu/dma.h | 144 |
10 files changed, 197 insertions, 160 deletions
diff --git a/include/exec/cputlb.h b/include/exec/cputlb.h index e8216602d0..e21cb60442 100644 --- a/include/exec/cputlb.h +++ b/include/exec/cputlb.h @@ -32,6 +32,10 @@ extern int tlb_flush_count; /* exec.c */ void tb_flush_jmp_cache(CPUArchState *env, target_ulong addr); + +MemoryRegionSection * +address_space_translate_for_iotlb(AddressSpace *as, hwaddr addr, hwaddr *xlat, + hwaddr *plen); hwaddr memory_region_section_get_iotlb(CPUArchState *env, MemoryRegionSection *section, target_ulong vaddr, diff --git a/include/exec/memory-internal.h b/include/exec/memory-internal.h index 799c02a63c..26689fe252 100644 --- a/include/exec/memory-internal.h +++ b/include/exec/memory-internal.h @@ -22,24 +22,9 @@ #ifndef CONFIG_USER_ONLY #include "hw/xen/xen.h" -typedef struct PhysPageEntry PhysPageEntry; - -struct PhysPageEntry { - uint16_t is_leaf : 1; - /* index into phys_sections (is_leaf) or phys_map_nodes (!is_leaf) */ - uint16_t ptr : 15; -}; typedef struct AddressSpaceDispatch AddressSpaceDispatch; -struct AddressSpaceDispatch { - /* This is a multi-level map on the physical address space. - * The bottom level has pointers to MemoryRegionSections. - */ - PhysPageEntry phys_map; - MemoryListener listener; -}; - void address_space_init_dispatch(AddressSpace *as); void address_space_destroy_dispatch(AddressSpace *as); diff --git a/include/exec/memory.h b/include/exec/memory.h index d53a6a1b88..3598c4f914 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -25,6 +25,7 @@ #include "exec/iorange.h" #include "exec/ioport.h" #include "qemu/int128.h" +#include "qemu/notify.h" #define MAX_PHYS_ADDR_SPACE_BITS 62 #define MAX_PHYS_ADDR (((hwaddr)1 << MAX_PHYS_ADDR_SPACE_BITS) - 1) @@ -53,6 +54,24 @@ struct MemoryRegionIORange { hwaddr offset; }; +typedef struct IOMMUTLBEntry IOMMUTLBEntry; + +/* See address_space_translate: bit 0 is read, bit 1 is write. */ +typedef enum { + IOMMU_NONE = 0, + IOMMU_RO = 1, + IOMMU_WO = 2, + IOMMU_RW = 3, +} IOMMUAccessFlags; + +struct IOMMUTLBEntry { + AddressSpace *target_as; + hwaddr iova; + hwaddr translated_addr; + hwaddr addr_mask; /* 0xfff = 4k translation */ + IOMMUAccessFlags perm; +}; + /* * Memory region callbacks */ @@ -115,12 +134,20 @@ struct MemoryRegionOps { const MemoryRegionMmio old_mmio; }; +typedef struct MemoryRegionIOMMUOps MemoryRegionIOMMUOps; + +struct MemoryRegionIOMMUOps { + /* Return a TLB entry that contains a given address. */ + IOMMUTLBEntry (*translate)(MemoryRegion *iommu, hwaddr addr); +}; + typedef struct CoalescedMemoryRange CoalescedMemoryRange; typedef struct MemoryRegionIoeventfd MemoryRegionIoeventfd; struct MemoryRegion { /* All fields are private - violators will be prosecuted */ const MemoryRegionOps *ops; + const MemoryRegionIOMMUOps *iommu_ops; void *opaque; MemoryRegion *parent; Int128 size; @@ -147,6 +174,7 @@ struct MemoryRegion { uint8_t dirty_log_mask; unsigned ioeventfd_nb; MemoryRegionIoeventfd *ioeventfds; + NotifierList iommu_notify; }; struct MemoryRegionPortio { @@ -164,7 +192,7 @@ struct MemoryRegionPortio { */ struct AddressSpace { /* All fields are private. */ - const char *name; + char *name; MemoryRegion *root; struct FlatView *current_map; int ioeventfd_nb; @@ -188,7 +216,7 @@ struct MemoryRegionSection { MemoryRegion *mr; AddressSpace *address_space; hwaddr offset_within_region; - uint64_t size; + Int128 size; hwaddr offset_within_address_space; bool readonly; }; @@ -332,6 +360,24 @@ void memory_region_init_rom_device(MemoryRegion *mr, void memory_region_init_reservation(MemoryRegion *mr, const char *name, uint64_t size); + +/** + * memory_region_init_iommu: Initialize a memory region that translates + * addresses + * + * An IOMMU region translates addresses and forwards accesses to a target + * memory region. + * + * @mr: the #MemoryRegion to be initialized + * @ops: a function that translates addresses into the @target region + * @name: used for debugging; not visible to the user or ABI + * @size: size of the region. + */ +void memory_region_init_iommu(MemoryRegion *mr, + const MemoryRegionIOMMUOps *ops, + const char *name, + uint64_t size); + /** * memory_region_destroy: Destroy a memory region and reclaim all resources. * @@ -371,6 +417,45 @@ static inline bool memory_region_is_romd(MemoryRegion *mr) } /** + * memory_region_is_iommu: check whether a memory region is an iommu + * + * Returns %true is a memory region is an iommu. + * + * @mr: the memory region being queried + */ +bool memory_region_is_iommu(MemoryRegion *mr); + +/** + * memory_region_notify_iommu: notify a change in an IOMMU translation entry. + * + * @mr: the memory region that was changed + * @entry: the new entry in the IOMMU translation table. The entry + * replaces all old entries for the same virtual I/O address range. + * Deleted entries have .@perm == 0. + */ +void memory_region_notify_iommu(MemoryRegion *mr, + IOMMUTLBEntry entry); + +/** + * memory_region_register_iommu_notifier: register a notifier for changes to + * IOMMU translation entries. + * + * @mr: the memory region to observe + * @n: the notifier to be added; the notifier receives a pointer to an + * #IOMMUTLBEntry as the opaque value; the pointer ceases to be + * valid on exit from the notifier. + */ +void memory_region_register_iommu_notifier(MemoryRegion *mr, Notifier *n); + +/** + * memory_region_unregister_iommu_notifier: unregister a notifier for + * changes to IOMMU translation entries. + * + * @n: the notifier to be removed. + */ +void memory_region_unregister_iommu_notifier(Notifier *n); + +/** * memory_region_name: get a memory region's name * * Returns the string that was used to initialize the memory region. @@ -807,8 +892,10 @@ void mtree_info(fprintf_function mon_printf, void *f); * * @as: an uninitialized #AddressSpace * @root: a #MemoryRegion that routes addesses for the address space + * @name: an address space name. The name is only used for debugging + * output. */ -void address_space_init(AddressSpace *as, MemoryRegion *root); +void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name); /** @@ -825,7 +912,8 @@ void address_space_destroy(AddressSpace *as); /** * address_space_rw: read from or write to an address space. * - * Return true if the operation hit any unassigned memory. + * Return true if the operation hit any unassigned memory or encountered an + * IOMMU fault. * * @as: #AddressSpace to be accessed * @addr: address within that address space @@ -838,7 +926,8 @@ bool address_space_rw(AddressSpace *as, hwaddr addr, uint8_t *buf, /** * address_space_write: write to address space. * - * Return true if the operation hit any unassigned memory. + * Return true if the operation hit any unassigned memory or encountered an + * IOMMU fault. * * @as: #AddressSpace to be accessed * @addr: address within that address space @@ -850,7 +939,8 @@ bool address_space_write(AddressSpace *as, hwaddr addr, /** * address_space_read: read from an address space. * - * Return true if the operation hit any unassigned memory. + * Return true if the operation hit any unassigned memory or encountered an + * IOMMU fault. * * @as: #AddressSpace to be accessed * @addr: address within that address space @@ -859,7 +949,7 @@ bool address_space_write(AddressSpace *as, hwaddr addr, bool address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int len); /* address_space_translate: translate an address range into an address space - * into a MemoryRegionSection and an address range into that section + * into a MemoryRegion and an address range into that section * * @as: #AddressSpace to be accessed * @addr: address within that address space @@ -868,14 +958,16 @@ bool address_space_read(AddressSpace *as, hwaddr addr, uint8_t *buf, int len); * @len: pointer to length * @is_write: indicates the transfer direction */ -MemoryRegionSection *address_space_translate(AddressSpace *as, hwaddr addr, - hwaddr *xlat, hwaddr *len, - bool is_write); +MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, + hwaddr *xlat, hwaddr *len, + bool is_write); /* address_space_access_valid: check for validity of accessing an address * space range * - * Check whether memory is assigned to the given address space range. + * Check whether memory is assigned to the given address space range, and + * access is permitted by any IOMMU regions that are active for the address + * space. * * For now, addr and len should be aligned to a page size. This limitation * will be lifted in the future. diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h index b21080cd58..1e23dbfb4a 100644 --- a/include/hw/pci-host/spapr.h +++ b/include/hw/pci-host/spapr.h @@ -49,7 +49,8 @@ typedef struct sPAPRPHBState { uint32_t dma_liobn; uint64_t dma_window_start; uint64_t dma_window_size; - DMAContext *dma; + sPAPRTCETable *tcet; + AddressSpace iommu_as; struct { uint32_t irq; diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index 8d075ab5a3..6ef1f97393 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -242,7 +242,6 @@ struct PCIDevice { PCIIORegion io_regions[PCI_NUM_REGIONS]; AddressSpace bus_master_as; MemoryRegion bus_master_enable_region; - DMAContext *dma; /* do not access the following fields */ PCIConfigReadFunc *config_read; @@ -401,9 +400,9 @@ int pci_read_devaddr(Monitor *mon, const char *addr, int *domp, int *busp, void pci_device_deassert_intx(PCIDevice *dev); -typedef DMAContext *(*PCIDMAContextFunc)(PCIBus *, void *, int); +typedef AddressSpace *(*PCIIOMMUFunc)(PCIBus *, void *, int); -void pci_setup_iommu(PCIBus *bus, PCIDMAContextFunc fn, void *opaque); +void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque); static inline void pci_set_byte(uint8_t *config, uint8_t val) @@ -639,15 +638,15 @@ static inline uint32_t pci_config_size(const PCIDevice *d) } /* DMA access functions */ -static inline DMAContext *pci_dma_context(PCIDevice *dev) +static inline AddressSpace *pci_get_address_space(PCIDevice *dev) { - return dev->dma; + return &dev->bus_master_as; } static inline int pci_dma_rw(PCIDevice *dev, dma_addr_t addr, void *buf, dma_addr_t len, DMADirection dir) { - dma_memory_rw(pci_dma_context(dev), addr, buf, len, dir); + dma_memory_rw(pci_get_address_space(dev), addr, buf, len, dir); return 0; } @@ -667,12 +666,12 @@ static inline int pci_dma_write(PCIDevice *dev, dma_addr_t addr, static inline uint##_bits##_t ld##_l##_pci_dma(PCIDevice *dev, \ dma_addr_t addr) \ { \ - return ld##_l##_dma(pci_dma_context(dev), addr); \ + return ld##_l##_dma(pci_get_address_space(dev), addr); \ } \ static inline void st##_s##_pci_dma(PCIDevice *dev, \ dma_addr_t addr, uint##_bits##_t val) \ { \ - st##_s##_dma(pci_dma_context(dev), addr, val); \ + st##_s##_dma(pci_get_address_space(dev), addr, val); \ } PCI_DMA_DEFINE_LDST(ub, b, 8); @@ -690,20 +689,20 @@ static inline void *pci_dma_map(PCIDevice *dev, dma_addr_t addr, { void *buf; - buf = dma_memory_map(pci_dma_context(dev), addr, plen, dir); + buf = dma_memory_map(pci_get_address_space(dev), addr, plen, dir); return buf; } static inline void pci_dma_unmap(PCIDevice *dev, void *buffer, dma_addr_t len, DMADirection dir, dma_addr_t access_len) { - dma_memory_unmap(pci_dma_context(dev), buffer, len, dir, access_len); + dma_memory_unmap(pci_get_address_space(dev), buffer, len, dir, access_len); } static inline void pci_dma_sglist_init(QEMUSGList *qsg, PCIDevice *dev, int alloc_hint) { - qemu_sglist_init(qsg, alloc_hint, pci_dma_context(dev)); + qemu_sglist_init(qsg, alloc_hint, pci_get_address_space(dev)); } extern const VMStateDescription vmstate_pci_device; diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h index 6ee443cf88..66762f6d5e 100644 --- a/include/hw/pci/pci_bus.h +++ b/include/hw/pci/pci_bus.h @@ -10,8 +10,8 @@ struct PCIBus { BusState qbus; - PCIDMAContextFunc dma_context_fn; - void *dma_context_opaque; + PCIIOMMUFunc iommu_fn; + void *iommu_opaque; uint8_t devfn_min; pci_set_irq_fn set_irq; pci_map_irq_fn map_irq; diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h index 864bee9d00..a83720ee65 100644 --- a/include/hw/ppc/spapr.h +++ b/include/hw/ppc/spapr.h @@ -342,17 +342,19 @@ typedef struct sPAPRTCE { #define RTAS_ERROR_LOG_MAX 2048 +typedef struct sPAPRTCETable sPAPRTCETable; void spapr_iommu_init(void); void spapr_events_init(sPAPREnvironment *spapr); void spapr_events_fdt_skel(void *fdt, uint32_t epow_irq); -DMAContext *spapr_tce_new_dma_context(uint32_t liobn, size_t window_size); -void spapr_tce_free(DMAContext *dma); -void spapr_tce_reset(DMAContext *dma); -void spapr_tce_set_bypass(DMAContext *dma, bool bypass); +sPAPRTCETable *spapr_tce_new_table(uint32_t liobn, size_t window_size); +MemoryRegion *spapr_tce_get_iommu(sPAPRTCETable *tcet); +void spapr_tce_free(sPAPRTCETable *tcet); +void spapr_tce_reset(sPAPRTCETable *tcet); +void spapr_tce_set_bypass(sPAPRTCETable *tcet, bool bypass); int spapr_dma_dt(void *fdt, int node_off, const char *propname, uint32_t liobn, uint64_t window, uint32_t size); int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, - DMAContext *dma); + sPAPRTCETable *tcet); #endif /* !defined (__HW_SPAPR_H__) */ diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h index f98ec0a2e5..36093270e6 100644 --- a/include/hw/ppc/spapr_vio.h +++ b/include/hw/ppc/spapr_vio.h @@ -63,7 +63,8 @@ struct VIOsPAPRDevice { uint32_t irq; target_ulong signal_state; VIOsPAPR_CRQ crq; - DMAContext *dma; + AddressSpace as; + sPAPRTCETable *tcet; }; #define DEFINE_SPAPR_PROPERTIES(type, field) \ @@ -91,35 +92,35 @@ static inline qemu_irq spapr_vio_qirq(VIOsPAPRDevice *dev) static inline bool spapr_vio_dma_valid(VIOsPAPRDevice *dev, uint64_t taddr, uint32_t size, DMADirection dir) { - return dma_memory_valid(dev->dma, taddr, size, dir); + return dma_memory_valid(&dev->as, taddr, size, dir); } static inline int spapr_vio_dma_read(VIOsPAPRDevice *dev, uint64_t taddr, void *buf, uint32_t size) { - return (dma_memory_read(dev->dma, taddr, buf, size) != 0) ? + return (dma_memory_read(&dev->as, taddr, buf, size) != 0) ? H_DEST_PARM : H_SUCCESS; } static inline int spapr_vio_dma_write(VIOsPAPRDevice *dev, uint64_t taddr, const void *buf, uint32_t size) { - return (dma_memory_write(dev->dma, taddr, buf, size) != 0) ? + return (dma_memory_write(&dev->as, taddr, buf, size) != 0) ? H_DEST_PARM : H_SUCCESS; } static inline int spapr_vio_dma_set(VIOsPAPRDevice *dev, uint64_t taddr, uint8_t c, uint32_t size) { - return (dma_memory_set(dev->dma, taddr, c, size) != 0) ? + return (dma_memory_set(&dev->as, taddr, c, size) != 0) ? H_DEST_PARM : H_SUCCESS; } -#define vio_stb(_dev, _addr, _val) (stb_dma((_dev)->dma, (_addr), (_val))) -#define vio_sth(_dev, _addr, _val) (stw_be_dma((_dev)->dma, (_addr), (_val))) -#define vio_stl(_dev, _addr, _val) (stl_be_dma((_dev)->dma, (_addr), (_val))) -#define vio_stq(_dev, _addr, _val) (stq_be_dma((_dev)->dma, (_addr), (_val))) -#define vio_ldq(_dev, _addr) (ldq_be_dma((_dev)->dma, (_addr))) +#define vio_stb(_dev, _addr, _val) (stb_dma(&(_dev)->as, (_addr), (_val))) +#define vio_sth(_dev, _addr, _val) (stw_be_dma(&(_dev)->as, (_addr), (_val))) +#define vio_stl(_dev, _addr, _val) (stl_be_dma(&(_dev)->as, (_addr), (_val))) +#define vio_stq(_dev, _addr, _val) (stq_be_dma(&(_dev)->as, (_addr), (_val))) +#define vio_ldq(_dev, _addr) (ldq_be_dma(&(_dev)->as, (_addr))) int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq); diff --git a/include/qemu/int128.h b/include/qemu/int128.h index b3864b6cd4..bfe7678a04 100644 --- a/include/qemu/int128.h +++ b/include/qemu/int128.h @@ -34,6 +34,25 @@ static inline Int128 int128_2_64(void) return (Int128) { 0, 1 }; } +static inline Int128 int128_and(Int128 a, Int128 b) +{ + return (Int128) { a.lo & b.lo, a.hi & b.hi }; +} + +static inline Int128 int128_rshift(Int128 a, int n) +{ + int64_t h; + if (!n) { + return a; + } + h = a.hi >> (n & 63); + if (n >= 64) { + return (Int128) { h, h >> 63 }; + } else { + return (Int128) { (a.lo >> n) | (a.hi << (64 - n)), h }; + } +} + static inline Int128 int128_add(Int128 a, Int128 b) { Int128 r = { a.lo + b.lo, a.hi + b.hi }; diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h index 02e0dcdfeb..031d1f5fb3 100644 --- a/include/sysemu/dma.h +++ b/include/sysemu/dma.h @@ -12,11 +12,11 @@ #include <stdio.h> #include "exec/memory.h" +#include "exec/address-spaces.h" #include "hw/hw.h" #include "block/block.h" #include "sysemu/kvm.h" -typedef struct DMAContext DMAContext; typedef struct ScatterGatherEntry ScatterGatherEntry; typedef enum { @@ -29,7 +29,7 @@ struct QEMUSGList { int nsg; int nalloc; size_t size; - DMAContext *dma; + AddressSpace *as; }; #ifndef CONFIG_USER_ONLY @@ -46,34 +46,7 @@ typedef uint64_t dma_addr_t; #define DMA_ADDR_BITS 64 #define DMA_ADDR_FMT "%" PRIx64 -typedef int DMATranslateFunc(DMAContext *dma, - dma_addr_t addr, - hwaddr *paddr, - hwaddr *len, - DMADirection dir); -typedef void* DMAMapFunc(DMAContext *dma, - dma_addr_t addr, - dma_addr_t *len, - DMADirection dir); -typedef void DMAUnmapFunc(DMAContext *dma, - void *buffer, - dma_addr_t len, - DMADirection dir, - dma_addr_t access_len); - -struct DMAContext { - AddressSpace *as; - DMATranslateFunc *translate; - DMAMapFunc *map; - DMAUnmapFunc *unmap; -}; - -/* A global DMA context corresponding to the address_space_memory - * AddressSpace, for sysbus devices which do DMA. - */ -extern DMAContext dma_context_memory; - -static inline void dma_barrier(DMAContext *dma, DMADirection dir) +static inline void dma_barrier(AddressSpace *as, DMADirection dir) { /* * This is called before DMA read and write operations @@ -98,144 +71,108 @@ static inline void dma_barrier(DMAContext *dma, DMADirection dir) } } -static inline bool dma_has_iommu(DMAContext *dma) -{ - return dma && dma->translate; -} - /* Checks that the given range of addresses is valid for DMA. This is * useful for certain cases, but usually you should just use * dma_memory_{read,write}() and check for errors */ -bool iommu_dma_memory_valid(DMAContext *dma, dma_addr_t addr, dma_addr_t len, - DMADirection dir); -static inline bool dma_memory_valid(DMAContext *dma, +static inline bool dma_memory_valid(AddressSpace *as, dma_addr_t addr, dma_addr_t len, DMADirection dir) { - if (!dma_has_iommu(dma)) { - return address_space_access_valid(dma->as, addr, len, - dir == DMA_DIRECTION_FROM_DEVICE); - } else { - return iommu_dma_memory_valid(dma, addr, len, dir); - } + return address_space_access_valid(as, addr, len, + dir == DMA_DIRECTION_FROM_DEVICE); } -int iommu_dma_memory_rw(DMAContext *dma, dma_addr_t addr, - void *buf, dma_addr_t len, DMADirection dir); -static inline int dma_memory_rw_relaxed(DMAContext *dma, dma_addr_t addr, +static inline int dma_memory_rw_relaxed(AddressSpace *as, dma_addr_t addr, void *buf, dma_addr_t len, DMADirection dir) { - if (!dma_has_iommu(dma)) { - /* Fast-path for no IOMMU */ - address_space_rw(dma->as, addr, buf, len, dir == DMA_DIRECTION_FROM_DEVICE); - return 0; - } else { - return iommu_dma_memory_rw(dma, addr, buf, len, dir); - } + return address_space_rw(as, addr, buf, len, dir == DMA_DIRECTION_FROM_DEVICE); } -static inline int dma_memory_read_relaxed(DMAContext *dma, dma_addr_t addr, +static inline int dma_memory_read_relaxed(AddressSpace *as, dma_addr_t addr, void *buf, dma_addr_t len) { - return dma_memory_rw_relaxed(dma, addr, buf, len, DMA_DIRECTION_TO_DEVICE); + return dma_memory_rw_relaxed(as, addr, buf, len, DMA_DIRECTION_TO_DEVICE); } -static inline int dma_memory_write_relaxed(DMAContext *dma, dma_addr_t addr, +static inline int dma_memory_write_relaxed(AddressSpace *as, dma_addr_t addr, const void *buf, dma_addr_t len) { - return dma_memory_rw_relaxed(dma, addr, (void *)buf, len, + return dma_memory_rw_relaxed(as, addr, (void *)buf, len, DMA_DIRECTION_FROM_DEVICE); } -static inline int dma_memory_rw(DMAContext *dma, dma_addr_t addr, +static inline int dma_memory_rw(AddressSpace *as, dma_addr_t addr, void *buf, dma_addr_t len, DMADirection dir) { - dma_barrier(dma, dir); + dma_barrier(as, dir); - return dma_memory_rw_relaxed(dma, addr, buf, len, dir); + return dma_memory_rw_relaxed(as, addr, buf, len, dir); } -static inline int dma_memory_read(DMAContext *dma, dma_addr_t addr, +static inline int dma_memory_read(AddressSpace *as, dma_addr_t addr, void *buf, dma_addr_t len) { - return dma_memory_rw(dma, addr, buf, len, DMA_DIRECTION_TO_DEVICE); + return dma_memory_rw(as, addr, buf, len, DMA_DIRECTION_TO_DEVICE); } -static inline int dma_memory_write(DMAContext *dma, dma_addr_t addr, +static inline int dma_memory_write(AddressSpace *as, dma_addr_t addr, const void *buf, dma_addr_t len) { - return dma_memory_rw(dma, addr, (void *)buf, len, + return dma_memory_rw(as, addr, (void *)buf, len, DMA_DIRECTION_FROM_DEVICE); } -int iommu_dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c, - dma_addr_t len); - -int dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c, dma_addr_t len); +int dma_memory_set(AddressSpace *as, dma_addr_t addr, uint8_t c, dma_addr_t len); -void *iommu_dma_memory_map(DMAContext *dma, - dma_addr_t addr, dma_addr_t *len, - DMADirection dir); -static inline void *dma_memory_map(DMAContext *dma, +static inline void *dma_memory_map(AddressSpace *as, dma_addr_t addr, dma_addr_t *len, DMADirection dir) { - if (!dma_has_iommu(dma)) { - hwaddr xlen = *len; - void *p; - - p = address_space_map(dma->as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE); - *len = xlen; - return p; - } else { - return iommu_dma_memory_map(dma, addr, len, dir); - } + hwaddr xlen = *len; + void *p; + + p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE); + *len = xlen; + return p; } -void iommu_dma_memory_unmap(DMAContext *dma, - void *buffer, dma_addr_t len, - DMADirection dir, dma_addr_t access_len); -static inline void dma_memory_unmap(DMAContext *dma, +static inline void dma_memory_unmap(AddressSpace *as, void *buffer, dma_addr_t len, DMADirection dir, dma_addr_t access_len) { - if (!dma_has_iommu(dma)) { - address_space_unmap(dma->as, buffer, (hwaddr)len, - dir == DMA_DIRECTION_FROM_DEVICE, access_len); - } else { - iommu_dma_memory_unmap(dma, buffer, len, dir, access_len); - } + address_space_unmap(as, buffer, (hwaddr)len, + dir == DMA_DIRECTION_FROM_DEVICE, access_len); } #define DEFINE_LDST_DMA(_lname, _sname, _bits, _end) \ - static inline uint##_bits##_t ld##_lname##_##_end##_dma(DMAContext *dma, \ + static inline uint##_bits##_t ld##_lname##_##_end##_dma(AddressSpace *as, \ dma_addr_t addr) \ { \ uint##_bits##_t val; \ - dma_memory_read(dma, addr, &val, (_bits) / 8); \ + dma_memory_read(as, addr, &val, (_bits) / 8); \ return _end##_bits##_to_cpu(val); \ } \ - static inline void st##_sname##_##_end##_dma(DMAContext *dma, \ + static inline void st##_sname##_##_end##_dma(AddressSpace *as, \ dma_addr_t addr, \ uint##_bits##_t val) \ { \ val = cpu_to_##_end##_bits(val); \ - dma_memory_write(dma, addr, &val, (_bits) / 8); \ + dma_memory_write(as, addr, &val, (_bits) / 8); \ } -static inline uint8_t ldub_dma(DMAContext *dma, dma_addr_t addr) +static inline uint8_t ldub_dma(AddressSpace *as, dma_addr_t addr) { uint8_t val; - dma_memory_read(dma, addr, &val, 1); + dma_memory_read(as, addr, &val, 1); return val; } -static inline void stb_dma(DMAContext *dma, dma_addr_t addr, uint8_t val) +static inline void stb_dma(AddressSpace *as, dma_addr_t addr, uint8_t val) { - dma_memory_write(dma, addr, &val, 1); + dma_memory_write(as, addr, &val, 1); } DEFINE_LDST_DMA(uw, w, 16, le); @@ -247,15 +184,12 @@ DEFINE_LDST_DMA(q, q, 64, be); #undef DEFINE_LDST_DMA -void dma_context_init(DMAContext *dma, AddressSpace *as, DMATranslateFunc translate, - DMAMapFunc map, DMAUnmapFunc unmap); - struct ScatterGatherEntry { dma_addr_t base; dma_addr_t len; }; -void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint, DMAContext *dma); +void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint, AddressSpace *as); void qemu_sglist_add(QEMUSGList *qsg, dma_addr_t base, dma_addr_t len); void qemu_sglist_destroy(QEMUSGList *qsg); #endif |