diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2012-10-29 14:31:47 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-10-29 14:31:47 -0500 |
commit | 233926fafa6c4a0fb666e1469524d66dd3b47ddd (patch) | |
tree | 2dbe1506ee13fbc7d2d56b317f596114d0f849bb /hw/msi.c | |
parent | b308c82cbda44e138ef990af64d44a5613c16092 (diff) | |
parent | 523a59f596a3e62f5a28eb171adba35e71310040 (diff) |
Merge remote-tracking branch 'mst/tags/for_anthony' into staging
virtio,pci infrastructure
This includes infrastructure patches that don't do much by themselves
but should help vfio and q35 make progress.
Also included is rework of virtio-net to use iovec APIs
for vector access - helpful to make it more secure
and in preparation for a new feature that will allow
arbitrary s/g layout for guests.
Also included is a pci bridge bugfix by Avi.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
* mst/tags/for_anthony: (25 commits)
pci: avoid destroying bridge address space windows in a transaction
virtio-net: enable mrg buf header in tap on linux
virtio-net: test peer header support at init time
virtio-net: minor code simplification
virtio-net: simplify rx code
virtio-net: switch tx to safe iov functions
virtio-net: first s/g is always at start of buf
virtio-net: refactor receive_hdr
virtio-net: use safe iov operations for rx
virtio-net: avoid sg copy
iov: add iov_cpy
virtio-net: track host/guest header length
pcie: Convert PCIExpressHost to use the QOM.
pcie: pass pcie window size to pcie_host_mmcfg_update()
pci: Add class 0xc05 as 'SMBus'
pci: introduce pci_swizzle_map_irq_fn() for standardized interrupt pin swizzle
pci_ids: add intel 82801BA pci-to-pci bridge id
pci: pci capability must be in PCI space
pci: make each capability DWORD aligned
qemu: enable PV EOI for qemu 1.3
...
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw/msi.c')
-rw-r--r-- | hw/msi.c | 45 |
1 files changed, 29 insertions, 16 deletions
@@ -122,6 +122,31 @@ void msi_set_message(PCIDevice *dev, MSIMessage msg) pci_set_word(dev->config + msi_data_off(dev, msi64bit), msg.data); } +MSIMessage msi_get_message(PCIDevice *dev, unsigned int vector) +{ + uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev)); + bool msi64bit = flags & PCI_MSI_FLAGS_64BIT; + unsigned int nr_vectors = msi_nr_vectors(flags); + MSIMessage msg; + + assert(vector < nr_vectors); + + if (msi64bit) { + msg.address = pci_get_quad(dev->config + msi_address_lo_off(dev)); + } else { + msg.address = pci_get_long(dev->config + msi_address_lo_off(dev)); + } + + /* upper bit 31:16 is zero */ + msg.data = pci_get_word(dev->config + msi_data_off(dev, msi64bit)); + if (nr_vectors > 1) { + msg.data &= ~(nr_vectors - 1); + msg.data |= vector; + } + + return msg; +} + bool msi_enabled(const PCIDevice *dev) { return msi_present(dev) && @@ -249,8 +274,7 @@ void msi_notify(PCIDevice *dev, unsigned int vector) uint16_t flags = pci_get_word(dev->config + msi_flags_off(dev)); bool msi64bit = flags & PCI_MSI_FLAGS_64BIT; unsigned int nr_vectors = msi_nr_vectors(flags); - uint64_t address; - uint32_t data; + MSIMessage msg; assert(vector < nr_vectors); if (msi_is_masked(dev, vector)) { @@ -261,24 +285,13 @@ void msi_notify(PCIDevice *dev, unsigned int vector) return; } - if (msi64bit) { - address = pci_get_quad(dev->config + msi_address_lo_off(dev)); - } else { - address = pci_get_long(dev->config + msi_address_lo_off(dev)); - } - - /* upper bit 31:16 is zero */ - data = pci_get_word(dev->config + msi_data_off(dev, msi64bit)); - if (nr_vectors > 1) { - data &= ~(nr_vectors - 1); - data |= vector; - } + msg = msi_get_message(dev, vector); MSI_DEV_PRINTF(dev, "notify vector 0x%x" " address: 0x%"PRIx64" data: 0x%"PRIx32"\n", - vector, address, data); - stl_le_phys(address, data); + vector, msg.address, msg.data); + stl_le_phys(msg.address, msg.data); } /* Normally called by pci_default_write_config(). */ |