diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2012-06-27 14:50:44 +1000 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-06-27 16:33:25 -0500 |
commit | ad0ebb91cd8b5fdc4a583b03645677771f420a46 (patch) | |
tree | 4449fc0cf864869480c95b79c661c0e0ec254c1a /hw/spapr_vio.h | |
parent | e5332e6334f375600b0c15f5c3540c1b72af7067 (diff) | |
download | qemu-ad0ebb91cd8b5fdc4a583b03645677771f420a46.zip |
pseries: Convert sPAPR TCEs to use generic IOMMU infrastructure
The pseries platform already contains an IOMMU implementation, since it is
essential for the platform's paravirtualized VIO devices. This IOMMU
support is currently built into the implementation of the VIO "bus" and
the various VIO devices.
This patch converts this code to make use of the new common IOMMU
infrastructure.
We don't yet handle synchronization of map/unmap callbacks vs. invalidations,
this will require some complex interaction with the kernel and is not a
major concern at this stage.
Cc: Alex Graf <agraf@suse.de>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw/spapr_vio.h')
-rw-r--r-- | hw/spapr_vio.h | 73 |
1 files changed, 37 insertions, 36 deletions
diff --git a/hw/spapr_vio.h b/hw/spapr_vio.h index 2adad77d02..6f9a498ccd 100644 --- a/hw/spapr_vio.h +++ b/hw/spapr_vio.h @@ -21,16 +21,7 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/>. */ -#define SPAPR_VIO_TCE_PAGE_SHIFT 12 -#define SPAPR_VIO_TCE_PAGE_SIZE (1ULL << SPAPR_VIO_TCE_PAGE_SHIFT) -#define SPAPR_VIO_TCE_PAGE_MASK (SPAPR_VIO_TCE_PAGE_SIZE - 1) - -enum VIOsPAPR_TCEAccess { - SPAPR_TCE_FAULT = 0, - SPAPR_TCE_RO = 1, - SPAPR_TCE_WO = 2, - SPAPR_TCE_RW = 3, -}; +#include "dma.h" #define TYPE_VIO_SPAPR_DEVICE "vio-spapr-device" #define VIO_SPAPR_DEVICE(obj) \ @@ -45,10 +36,6 @@ enum VIOsPAPR_TCEAccess { struct VIOsPAPRDevice; -typedef struct VIOsPAPR_RTCE { - uint64_t tce; -} VIOsPAPR_RTCE; - typedef struct VIOsPAPR_CRQ { uint64_t qladdr; uint32_t qsize; @@ -64,6 +51,7 @@ typedef struct VIOsPAPRDeviceClass { const char *dt_name, *dt_type, *dt_compatible; target_ulong signal_mask; + uint32_t rtce_window_size; int (*init)(VIOsPAPRDevice *dev); void (*reset)(VIOsPAPRDevice *dev); int (*devnode)(VIOsPAPRDevice *dev, void *fdt, int node_off); @@ -73,20 +61,15 @@ struct VIOsPAPRDevice { DeviceState qdev; uint32_t reg; uint32_t flags; -#define VIO_PAPR_FLAG_DMA_BYPASS 0x1 qemu_irq qirq; uint32_t vio_irq_num; target_ulong signal_state; - uint32_t rtce_window_size; - VIOsPAPR_RTCE *rtce_table; - int kvmtce_fd; VIOsPAPR_CRQ crq; + DMAContext *dma; }; -#define DEFINE_SPAPR_PROPERTIES(type, field, default_dma_window) \ - DEFINE_PROP_UINT32("reg", type, field.reg, -1), \ - DEFINE_PROP_UINT32("dma-window", type, field.rtce_window_size, \ - default_dma_window) +#define DEFINE_SPAPR_PROPERTIES(type, field) \ + DEFINE_PROP_UINT32("reg", type, field.reg, -1) struct VIOsPAPRBus { BusState bus; @@ -102,20 +85,38 @@ extern int spapr_populate_chosen_stdout(void *fdt, VIOsPAPRBus *bus); extern int spapr_vio_signal(VIOsPAPRDevice *dev, target_ulong mode); -int spapr_vio_check_tces(VIOsPAPRDevice *dev, target_ulong ioba, - target_ulong len, - enum VIOsPAPR_TCEAccess access); - -int spapr_tce_dma_read(VIOsPAPRDevice *dev, uint64_t taddr, - void *buf, uint32_t size); -int spapr_tce_dma_write(VIOsPAPRDevice *dev, uint64_t taddr, - const void *buf, uint32_t size); -int spapr_tce_dma_zero(VIOsPAPRDevice *dev, uint64_t taddr, uint32_t size); -void stb_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint8_t val); -void sth_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint16_t val); -void stw_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint32_t val); -void stq_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint64_t val); -uint64_t ldq_tce(VIOsPAPRDevice *dev, uint64_t taddr); +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); +} + +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) ? + 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) ? + 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) ? + 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))) int spapr_vio_send_crq(VIOsPAPRDevice *dev, uint8_t *crq); |