This helper will also be used by the upcoming config notifier.
Signed-off-by: Jan Kiszka <[email protected]>
---
hw/msi.c | 43 +++++++++++++++++++++++++------------------
1 files changed, 25 insertions(+), 18 deletions(-)
diff --git a/hw/msi.c b/hw/msi.c
index 2b7b6e3..3c7ebc3 100644
--- a/hw/msi.c
+++ b/hw/msi.c
@@ -113,6 +113,25 @@ bool msi_enabled(const PCIDevice *dev)
PCI_MSI_FLAGS_ENABLE);
}
+static void msi_message_from_vector(PCIDevice *dev, uint16_t msi_flags,
+ unsigned vector, MSIMessage *msg)
+{
+ bool msi64bit = msi_flags & PCI_MSI_FLAGS_64BIT;
+ unsigned int nr_vectors = msi_nr_vectors(msi_flags);
+
+ msg->address = pci_get_long(dev->config + msi_address_lo_off(dev));
+ if (msi64bit) {
+ msg->address |= (uint64_t)pci_get_long(dev->config +
+ msi_address_hi_off(dev)) << 32;
+ }
+
+ msg->data = pci_get_word(dev->config + msi_data_off(dev, msi64bit));
+ if (nr_vectors > 1) {
+ msg->data &= ~(nr_vectors - 1);
+ msg->data |= vector;
+ }
+}
+
static void kvm_msi_message_from_vector(PCIDevice *dev, unsigned vector,
KVMMsiMessage *kmm)
{
@@ -339,11 +358,10 @@ 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 < msi_nr_vectors(flags));
- assert(vector < nr_vectors);
if (msi_is_masked(dev, vector)) {
assert(flags & PCI_MSI_FLAGS_MASKBIT);
pci_long_test_and_set_mask(
@@ -357,24 +375,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;
- }
+ msi_message_from_vector(dev, flags, vector, &msg);
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(). */
--
1.7.3.4
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html