diff options
author | Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> | 2014-09-05 14:50:56 +0100 |
---|---|---|
committer | Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> | 2014-09-09 06:07:12 +0100 |
commit | de739df8e0032d441a57ec1a8f9ab8e9bf72cef0 (patch) | |
tree | 37b299e0156ae2fb15ce47d06f5bec80ecde8f8c | |
parent | 1bc0e405816c9c6bde5695af20b07a1491ce1f9f (diff) |
apb: implement PCI bus error interrupt map registers
Both OpenBSD and FreeBSD SPARC64 attempt to read the interrupt map from the
hardware and will fail if the correct ino isn't present.
Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
-rw-r--r-- | hw/pci-host/apb.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c index 762ebdd8fe..f573875baf 100644 --- a/hw/pci-host/apb.c +++ b/hw/pci-host/apb.c @@ -142,6 +142,7 @@ typedef struct APBState { IOMMUState iommu; uint32_t pci_control[16]; uint32_t pci_irq_map[8]; + uint32_t pci_err_irq_map[4]; uint32_t obio_irq_map[32]; qemu_irq *pbm_irqs; qemu_irq *ivec_irqs; @@ -437,7 +438,7 @@ static void apb_config_writel (void *opaque, hwaddr addr, pbm_check_irqs(s); } break; - case 0x1000 ... 0x1080: /* OBIO interrupt control */ + case 0x1000 ... 0x107f: /* OBIO interrupt control */ if (addr & 4) { unsigned int ino = ((addr & 0xff) >> 3); s->obio_irq_map[ino] &= PBM_PCI_IMR_MASK; @@ -515,13 +516,20 @@ static uint64_t apb_config_readl (void *opaque, val = 0; } break; - case 0x1000 ... 0x1080: /* OBIO interrupt control */ + case 0x1000 ... 0x107f: /* OBIO interrupt control */ if (addr & 4) { val = s->obio_irq_map[(addr & 0xff) >> 3]; } else { val = 0; } break; + case 0x1080 ... 0x108f: /* PCI bus error */ + if (addr & 4) { + val = s->pci_err_irq_map[(addr & 0xf) >> 3]; + } else { + val = 0; + } + break; case 0x2000 ... 0x202f: /* PCI control */ val = s->pci_control[(addr & 0x3f) >> 2]; break; @@ -753,6 +761,9 @@ static int pci_pbm_init_device(SysBusDevice *dev) for (i = 0; i < 8; i++) { s->pci_irq_map[i] = (0x1f << 6) | (i << 2); } + for (i = 0; i < 2; i++) { + s->pci_err_irq_map[i] = (0x1f << 6) | 0x30; + } for (i = 0; i < 32; i++) { s->obio_irq_map[i] = ((0x1f << 6) | 0x20) + i; } |