mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 23:33:54 -06:00
dma: eliminate DMAContext
The DMAContext is a simple pointer to an AddressSpace that is now always already available. Make everyone hold the address space directly, and clean up the DMA API to use the AddressSpace directly. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
96478592a9
commit
df32fd1c9f
23 changed files with 117 additions and 148 deletions
|
@ -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;
|
||||
|
@ -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;
|
||||
|
|
|
@ -64,7 +64,6 @@ struct VIOsPAPRDevice {
|
|||
target_ulong signal_state;
|
||||
VIOsPAPR_CRQ crq;
|
||||
AddressSpace as;
|
||||
DMAContext dma;
|
||||
sPAPRTCETable *tcet;
|
||||
};
|
||||
|
||||
|
@ -93,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);
|
||||
|
||||
|
|
|
@ -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,16 +46,7 @@ typedef uint64_t dma_addr_t;
|
|||
#define DMA_ADDR_BITS 64
|
||||
#define DMA_ADDR_FMT "%" PRIx64
|
||||
|
||||
struct DMAContext {
|
||||
AddressSpace *as;
|
||||
};
|
||||
|
||||
/* 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
|
||||
|
@ -83,105 +74,105 @@ static inline void dma_barrier(DMAContext *dma, DMADirection dir)
|
|||
/* 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 */
|
||||
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)
|
||||
{
|
||||
return address_space_access_valid(dma->as, addr, len,
|
||||
return address_space_access_valid(as, addr, len,
|
||||
dir == DMA_DIRECTION_FROM_DEVICE);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return address_space_rw(dma->as, addr, buf, len, dir == DMA_DIRECTION_FROM_DEVICE);
|
||||
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 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);
|
||||
|
||||
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)
|
||||
{
|
||||
hwaddr xlen = *len;
|
||||
void *p;
|
||||
|
||||
p = address_space_map(dma->as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE);
|
||||
p = address_space_map(as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE);
|
||||
*len = xlen;
|
||||
return p;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
address_space_unmap(dma->as, buffer, (hwaddr)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);
|
||||
|
@ -193,14 +184,12 @@ DEFINE_LDST_DMA(q, q, 64, be);
|
|||
|
||||
#undef DEFINE_LDST_DMA
|
||||
|
||||
void dma_context_init(DMAContext *dma, AddressSpace *as);
|
||||
|
||||
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue