diff options
-rw-r--r-- | hw/openpic.c | 34 | ||||
-rw-r--r-- | hw/openpic.h | 3 |
2 files changed, 19 insertions, 18 deletions
diff --git a/hw/openpic.c b/hw/openpic.c index 2a3b56af49..d709e36b52 100644 --- a/hw/openpic.c +++ b/hw/openpic.c @@ -207,6 +207,9 @@ typedef struct openpic_t { PCIDevice pci_dev; MemoryRegion mem; + /* Behavior control */ + uint32_t flags; + /* Sub-regions */ MemoryRegion sub_io_mem[7]; @@ -234,9 +237,10 @@ typedef struct openpic_t { int irq_ipi0; int irq_tim0; void (*reset) (void *); - void (*irq_raise) (struct openpic_t *, int, IRQ_src_t *); } openpic_t; +static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src); + static inline void IRQ_setbit (IRQ_queue_t *q, int n_IRQ) { set_bit(q->queue, n_IRQ); @@ -321,7 +325,7 @@ static void IRQ_local_pipe (openpic_t *opp, int n_CPU, int n_IRQ) return; } DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", n_CPU, n_IRQ); - opp->irq_raise(opp, n_CPU, src); + openpic_irq_raise(opp, n_CPU, src); } /* update pic state because registers for n_IRQ have changed value */ @@ -753,7 +757,7 @@ static void openpic_cpu_write_internal(void *opaque, hwaddr addr, IPVP_PRIORITY(src->ipvp) > dst->servicing.priority)) { DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n", idx, n_IRQ); - opp->irq_raise(opp, idx, src); + openpic_irq_raise(opp, idx, src); } break; default: @@ -996,7 +1000,13 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id) static void openpic_irq_raise(openpic_t *opp, int n_CPU, IRQ_src_t *src) { - qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]); + int n_ci = IDR_CI0 - n_CPU; + + if ((opp->flags & OPENPIC_FLAG_IDE_CRIT) && test_bit(&src->ide, n_ci)) { + qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_CINT]); + } else { + qemu_irq_raise(opp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]); + } } qemu_irq *openpic_init (MemoryRegion **pmem, int nb_cpus, @@ -1059,7 +1069,6 @@ qemu_irq *openpic_init (MemoryRegion **pmem, int nb_cpus, openpic_save, openpic_load, opp); qemu_register_reset(openpic_reset, opp); - opp->irq_raise = openpic_irq_raise; opp->reset = openpic_reset; if (pmem) @@ -1068,18 +1077,6 @@ qemu_irq *openpic_init (MemoryRegion **pmem, int nb_cpus, return qemu_allocate_irqs(openpic_set_irq, opp, opp->max_irq); } -static void mpic_irq_raise(openpic_t *mpp, int n_CPU, IRQ_src_t *src) -{ - int n_ci = IDR_CI0 - n_CPU; - - if(test_bit(&src->ide, n_ci)) { - qemu_irq_raise(mpp->dst[n_CPU].irqs[OPENPIC_OUTPUT_CINT]); - } - else { - qemu_irq_raise(mpp->dst[n_CPU].irqs[OPENPIC_OUTPUT_INT]); - } -} - static void mpic_reset (void *opaque) { openpic_t *mpp = (openpic_t *)opaque; @@ -1265,7 +1262,8 @@ qemu_irq *mpic_init (MemoryRegion *address_space, hwaddr base, mpp->dst[i].irqs = irqs[i]; mpp->irq_out = irq_out; - mpp->irq_raise = mpic_irq_raise; + /* Enable critical interrupt support */ + mpp->flags |= OPENPIC_FLAG_IDE_CRIT; mpp->reset = mpic_reset; register_savevm(NULL, "mpic", 0, 2, openpic_save, openpic_load, mpp); diff --git a/hw/openpic.h b/hw/openpic.h index f50a1e42bd..1232d1039c 100644 --- a/hw/openpic.h +++ b/hw/openpic.h @@ -11,6 +11,9 @@ enum { OPENPIC_OUTPUT_NB, }; +/* OpenPIC capability flags */ +#define OPENPIC_FLAG_IDE_CRIT (1 << 0) + qemu_irq *openpic_init (MemoryRegion **pmem, int nb_cpus, qemu_irq **irqs, qemu_irq irq_out); qemu_irq *mpic_init (MemoryRegion *address_space, hwaddr base, |