From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org, anthony@codemonkey.ws,
yamahata@valinux.co.jp, paul@codesourcery.com,
quintela@redhat.com
Subject: [Qemu-devel] [PATCHv2 3/3] pci: interrupt disable bit support
Date: Thu, 26 Nov 2009 17:48:47 +0200 [thread overview]
Message-ID: <20091126154847.GD2694@redhat.com> (raw)
In-Reply-To: <cover.1259249330.git.mst@redhat.com>
Interrupt disable bit is mandatory in PCI spec.
Implement it to make devices spec compliant.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
hw/pci.c | 29 +++++++++++++++++++++++++++--
hw/pci.h | 1 +
2 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/hw/pci.c b/hw/pci.c
index f83ea93..6542c20 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -520,7 +520,8 @@ static void pci_init_wmask(PCIDevice *dev)
dev->wmask[PCI_CACHE_LINE_SIZE] = 0xff;
dev->wmask[PCI_INTERRUPT_LINE] = 0xff;
pci_set_word(dev->wmask + PCI_COMMAND,
- PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
+ PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
+ PCI_COMMAND_INTX_DISABLE);
memset(dev->wmask + PCI_CONFIG_HEADER_SIZE, 0xff,
config_size - PCI_CONFIG_HEADER_SIZE);
@@ -940,6 +941,25 @@ static void pci_update_mappings(PCIDevice *d)
}
}
+static inline int pci_irq_disabled(PCIDevice *d)
+{
+ return pci_get_word(d->config + PCI_COMMAND) & PCI_COMMAND_INTX_DISABLE;
+}
+
+/* Called after interrupt disabled field update in config space,
+ * assert/deassert interrupts if necessary.
+ * Gets original interrupt disable bit value (before update). */
+static void pci_update_irq_disabled(PCIDevice *d, int was_irq_disabled)
+{
+ int i, disabled = pci_irq_disabled(d);
+ if (disabled == was_irq_disabled)
+ return;
+ for (i = 0; i < PCI_NUM_PINS; ++i) {
+ int state = pci_irq_state(d, i);
+ pci_change_irq_level(d, i, disabled ? -state : state);
+ }
+}
+
uint32_t pci_default_read_config(PCIDevice *d,
uint32_t address, int len)
{
@@ -952,7 +972,7 @@ uint32_t pci_default_read_config(PCIDevice *d,
void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
{
- int i;
+ int i, was_irq_disabled = pci_irq_disabled(d);
uint32_t config_size = pci_config_size(d);
for (i = 0; i < l && addr + i < config_size; val >>= 8, ++i) {
@@ -964,6 +984,9 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val, int l)
ranges_overlap(addr, l, PCI_ROM_ADDRESS1, 4) ||
range_covers_byte(addr, l, PCI_COMMAND))
pci_update_mappings(d);
+
+ if (range_covers_byte(addr, l, PCI_COMMAND))
+ pci_update_irq_disabled(d, was_irq_disabled);
}
/***********************************************************/
@@ -981,6 +1004,8 @@ static void pci_set_irq(void *opaque, int irq_num, int level)
pci_set_irq_state(pci_dev, irq_num, level);
pci_update_irq_status(pci_dev);
+ if (pci_irq_disabled(pci_dev))
+ return;
pci_change_irq_level(pci_dev, irq_num, change);
}
diff --git a/hw/pci.h b/hw/pci.h
index dc9b860..d279e3f 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -101,6 +101,7 @@ typedef struct PCIIORegion {
#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
#define PCI_COMMAND_MASTER 0x4 /* Enable bus master */
+#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
#define PCI_STATUS 0x06 /* 16 bits */
#define PCI_STATUS_INTERRUPT 0x08
#define PCI_REVISION_ID 0x08 /* 8 bits */
--
1.6.5.2.143.g8cc62
prev parent reply other threads:[~2009-11-26 15:51 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <cover.1259249330.git.mst@redhat.com>
2009-11-26 15:48 ` [Qemu-devel] [PATCHv2 1/3] pci: prepare irq code for interrupt state Michael S. Tsirkin
2009-11-26 18:54 ` [Qemu-devel] " Juan Quintela
2009-11-29 11:02 ` Michael S. Tsirkin
2009-11-26 15:48 ` [Qemu-devel] [PATCHv2 2/3] pci: interrupt status bit implementation Michael S. Tsirkin
2009-11-26 15:48 ` Michael S. Tsirkin [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20091126154847.GD2694@redhat.com \
--to=mst@redhat.com \
--cc=anthony@codemonkey.ws \
--cc=paul@codesourcery.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
--cc=yamahata@valinux.co.jp \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.