@@ -704,7 +704,7 @@ static void pci_pbm_init(Object *obj)
for (i = 0; i < 32; i++) {
s->obio_irq_map[i] = ((0x1f << 6) | 0x20) + i;
}
- s->pbm_irqs = qemu_allocate_irqs(pci_apb_set_irq, s, MAX_IVEC);
+ qdev_init_gpio_in_named(DEVICE(s), pci_apb_set_irq, "pbm-irq", MAX_IVEC);
qdev_init_gpio_out_named(DEVICE(s), s->ivec_irqs, "ivec-irq", MAX_IVEC);
s->irq_request = NO_IRQ_REQUEST;
s->pci_irq_in = 0ULL;
@@ -86,6 +86,7 @@ typedef struct EbusState {
PCIDevice parent_obj;
ISABus *isa_bus;
+ qemu_irq isa_bus_irqs[ISA_NUM_IRQS];
uint64_t console_serial_base;
MemoryRegion bar0;
MemoryRegion bar1;
@@ -211,23 +212,15 @@ typedef struct ResetData {
uint64_t prom_addr;
} ResetData;
-static void isa_irq_handler(void *opaque, int n, int level)
+static void ebus_isa_irq_handler(void *opaque, int n, int level)
{
- static const int isa_irq_to_ivec[16] = {
- [1] = 0x29, /* keyboard */
- [4] = 0x2b, /* serial */
- [6] = 0x27, /* floppy */
- [7] = 0x22, /* parallel */
- [12] = 0x2a, /* mouse */
- };
- qemu_irq *irqs = opaque;
- int ivec;
-
- assert(n < ARRAY_SIZE(isa_irq_to_ivec));
- ivec = isa_irq_to_ivec[n];
- EBUS_DPRINTF("Set ISA IRQ %d level %d -> ivec 0x%x\n", n, level, ivec);
- if (ivec) {
- qemu_set_irq(irqs[ivec], level);
+ EbusState *s = EBUS(opaque);
+ qemu_irq irq = s->isa_bus_irqs[n];
+
+ /* Pass ISA bus IRQs onto their gpio equivalent */
+ EBUS_DPRINTF("Set ISA IRQ %d level %d\n", n, level);
+ if (irq) {
+ qemu_set_irq(irq, level);
}
}
@@ -235,7 +228,6 @@ static void isa_irq_handler(void *opaque, int n, int level)
static void ebus_realize(PCIDevice *pci_dev, Error **errp)
{
EbusState *s = EBUS(pci_dev);
- APBState *apb;
DeviceState *dev;
qemu_irq *isa_irq;
DriveInfo *fd[MAX_FD];
@@ -248,14 +240,11 @@ static void ebus_realize(PCIDevice *pci_dev, Error **errp)
return;
}
- apb = APB_DEVICE(object_resolve_path_type("", TYPE_APB, NULL));
- if (!apb) {
- error_setg(errp, "unable to locate APB PCI host bridge");
- return;
- }
-
- isa_irq = qemu_allocate_irqs(isa_irq_handler, apb->pbm_irqs, 16);
+ /* ISA bus */
+ isa_irq = qemu_allocate_irqs(ebus_isa_irq_handler, s, ISA_NUM_IRQS);
isa_bus_irqs(s->isa_bus, isa_irq);
+ qdev_init_gpio_out_named(DEVICE(s), s->isa_bus_irqs, "isa-irq",
+ ISA_NUM_IRQS);
/* Serial ports */
i = 0;
@@ -530,6 +519,18 @@ static void sun4uv_init(MemoryRegion *address_space_mem,
hwdef->console_serial_base);
qdev_init_nofail(DEVICE(ebus));
+ /* Wire up "well-known" ISA IRQs to APB legacy obio IRQs */
+ qdev_connect_gpio_out_named(DEVICE(ebus), "isa-irq", 7,
+ qdev_get_gpio_in_named(DEVICE(apb), "pbm-irq", OBIO_LPT_IRQ));
+ qdev_connect_gpio_out_named(DEVICE(ebus), "isa-irq", 6,
+ qdev_get_gpio_in_named(DEVICE(apb), "pbm-irq", OBIO_FDD_IRQ));
+ qdev_connect_gpio_out_named(DEVICE(ebus), "isa-irq", 1,
+ qdev_get_gpio_in_named(DEVICE(apb), "pbm-irq", OBIO_KBD_IRQ));
+ qdev_connect_gpio_out_named(DEVICE(ebus), "isa-irq", 12,
+ qdev_get_gpio_in_named(DEVICE(apb), "pbm-irq", OBIO_MSE_IRQ));
+ qdev_connect_gpio_out_named(DEVICE(ebus), "isa-irq", 4,
+ qdev_get_gpio_in_named(DEVICE(apb), "pbm-irq", OBIO_SER_IRQ));
+
pci_dev = pci_create_simple(pci_busA, PCI_DEVFN(2, 0), "VGA");
memset(&macaddr, 0, sizeof(MACAddr));
@@ -52,6 +52,13 @@ typedef struct IOMMUState {
#define MAX_IVEC 0x40
+/* OBIO IVEC IRQs */
+#define OBIO_LPT_IRQ 0x22
+#define OBIO_FDD_IRQ 0x27
+#define OBIO_KBD_IRQ 0x29
+#define OBIO_MSE_IRQ 0x2a
+#define OBIO_SER_IRQ 0x2b
+
#define TYPE_APB "pbm"
#define APB_DEVICE(obj) \
@@ -76,7 +83,6 @@ typedef struct APBState {
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[MAX_IVEC];
unsigned int irq_request;
uint32_t reset_control;