hw/core/irq.c: Use upstream version. Change-Id: I628d463245995db72be21f08b3c38680c58e2070
diff --git a/arch_init.c b/arch_init.c index cfd0fad..07edec9 100644 --- a/arch_init.c +++ b/arch_init.c
@@ -29,6 +29,7 @@ #include <sys/mman.h> #endif #include "config.h" +#include "hw/irq.h" #include "monitor/monitor.h" #include "sysemu/sysemu.h" #include "sysemu/arch_init.h"
diff --git a/hw/core/irq.c b/hw/core/irq.c index c43fe48..03c8cb3 100644 --- a/hw/core/irq.c +++ b/hw/core/irq.c
@@ -38,30 +38,59 @@ irq->handler(irq->opaque, irq->n, level); } -qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n) +qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler, + void *opaque, int n) { qemu_irq *s; struct IRQState *p; int i; - s = (qemu_irq *)g_malloc0(sizeof(qemu_irq) * n); - p = (struct IRQState *)g_malloc0(sizeof(struct IRQState) * n); - for (i = 0; i < n; i++) { - p->handler = handler; - p->opaque = opaque; - p->n = i; + if (!old) { + n_old = 0; + } + s = old ? g_renew(qemu_irq, old, n + n_old) : g_new(qemu_irq, n); + p = old ? g_renew(struct IRQState, s[0], n + n_old) : + g_new(struct IRQState, n); + for (i = 0; i < n + n_old; i++) { + if (i >= n_old) { + p->handler = handler; + p->opaque = opaque; + p->n = i; + } s[i] = p; p++; } return s; } +qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n) +{ + return qemu_extend_irqs(NULL, 0, handler, opaque, n); +} + +qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n) +{ + struct IRQState *irq; + + irq = g_new(struct IRQState, 1); + irq->handler = handler; + irq->opaque = opaque; + irq->n = n; + + return irq; +} + void qemu_free_irqs(qemu_irq *s) { g_free(s[0]); g_free(s); } +void qemu_free_irq(qemu_irq irq) +{ + g_free(irq); +} + static void qemu_notirq(void *opaque, int line, int level) { struct IRQState *irq = opaque; @@ -75,3 +104,49 @@ qemu_irq_raise(irq); return qemu_allocate_irqs(qemu_notirq, irq, 1)[0]; } + +static void qemu_splitirq(void *opaque, int line, int level) +{ + struct IRQState **irq = opaque; + irq[0]->handler(irq[0]->opaque, irq[0]->n, level); + irq[1]->handler(irq[1]->opaque, irq[1]->n, level); +} + +qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2) +{ + qemu_irq *s = g_malloc0(2 * sizeof(qemu_irq)); + s[0] = irq1; + s[1] = irq2; + return qemu_allocate_irqs(qemu_splitirq, s, 1)[0]; +} + +static void proxy_irq_handler(void *opaque, int n, int level) +{ + qemu_irq **target = opaque; + + if (*target) { + qemu_set_irq((*target)[n], level); + } +} + +qemu_irq *qemu_irq_proxy(qemu_irq **target, int n) +{ + return qemu_allocate_irqs(proxy_irq_handler, target, n); +} + +void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n) +{ + int i; + qemu_irq *old_irqs = qemu_allocate_irqs(NULL, NULL, n); + for (i = 0; i < n; i++) { + *old_irqs[i] = *gpio_in[i]; + gpio_in[i]->handler = handler; + gpio_in[i]->opaque = old_irqs; + } +} + +void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, int n) +{ + qemu_irq *old_irqs = *gpio_out; + *gpio_out = qemu_allocate_irqs(handler, old_irqs, n); +}
diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c index e77ed8a..533935c 100644 --- a/hw/intc/i8259.c +++ b/hw/intc/i8259.c
@@ -23,6 +23,7 @@ */ #include "hw/hw.h" #include "hw/i386/pc.h" +#include "hw/irq.h" #include "hw/isa/isa.h" #include "monitor/monitor.h" #include "hw/android/goldfish/device.h" @@ -61,7 +62,7 @@ qemu_irq parent_irq; void *irq_request_opaque; /* IOAPIC callback support */ - SetIRQFunc *alt_irq_func; + qemu_irq_handler alt_irq_func; void *alt_irq_opaque; }; @@ -563,7 +564,7 @@ return qemu_allocate_irqs(i8259_set_irq, s, GFD_MAX_IRQ); } -void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func, +void pic_set_alt_irq_func(PicState2 *s, qemu_irq_handler alt_irq_func, void *alt_irq_opaque) { s->alt_irq_func = alt_irq_func;
diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 80ab1f4..eef15f7 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c
@@ -38,7 +38,7 @@ pci_map_irq_fn map_irq; uint32_t config_reg; /* XXX: suppress */ /* low level pic */ - SetIRQFunc *low_set_irq; + qemu_irq_handler low_set_irq; qemu_irq *irq_opaque; PCIDevice *devices[256]; PCIDevice *parent_dev;
diff --git a/include/hw/android/goldfish/device.h b/include/hw/android/goldfish/device.h index 40b614e..a62e810 100644 --- a/include/hw/android/goldfish/device.h +++ b/include/hw/android/goldfish/device.h
@@ -14,6 +14,7 @@ #include "config.h" #include "exec/cpu-common.h" +#include "hw/irq.h" struct goldfish_device { struct goldfish_device *next;
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index 4d0e4c6..196bf51 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h
@@ -4,6 +4,7 @@ #include "cpu.h" #include "qemu-common.h" #include "exec/hwaddr.h" +#include "hw/irq.h" /* PC-style peripherals (also used by other machines). */ @@ -34,7 +35,7 @@ void pic_set_irq(int irq, int level); void pic_set_irq_new(void *opaque, int irq, int level); qemu_irq *i8259_init(qemu_irq parent_irq); -void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func, +void pic_set_alt_irq_func(PicState2 *s, qemu_irq_handler alt_irq_func, void *alt_irq_opaque); int pic_read_irq(PicState2 *s); void pic_update_irq(PicState2 *s);
diff --git a/include/hw/irq.h b/include/hw/irq.h index 5daae44..d08bc02 100644 --- a/include/hw/irq.h +++ b/include/hw/irq.h
@@ -3,9 +3,9 @@ /* Generic IRQ/GPIO pin infrastructure. */ -/* FIXME: Rmove one of these. */ +typedef struct IRQState *qemu_irq; + typedef void (*qemu_irq_handler)(void *opaque, int n, int level); -typedef void SetIRQFunc(void *opaque, int irq_num, int level); void qemu_set_irq(qemu_irq irq, int level); @@ -25,11 +25,40 @@ qemu_set_irq(irq, 0); } -/* Returns an array of N IRQs. */ +/* Returns an array of N IRQs. Each IRQ is assigned the argument handler and + * opaque data. + */ qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n); + +/* + * Allocates a single IRQ. The irq is assigned with a handler, an opaque + * data and the interrupt number. + */ +qemu_irq qemu_allocate_irq(qemu_irq_handler handler, void *opaque, int n); + +/* Extends an Array of IRQs. Old IRQs have their handlers and opaque data + * preserved. New IRQs are assigned the argument handler and opaque data. + */ +qemu_irq *qemu_extend_irqs(qemu_irq *old, int n_old, qemu_irq_handler handler, + void *opaque, int n); + void qemu_free_irqs(qemu_irq *s); +void qemu_free_irq(qemu_irq irq); /* Returns a new IRQ with opposite polarity. */ qemu_irq qemu_irq_invert(qemu_irq irq); +/* Returns a new IRQ which feeds into both the passed IRQs */ +qemu_irq qemu_irq_split(qemu_irq irq1, qemu_irq irq2); + +/* Returns a new IRQ set which connects 1:1 to another IRQ set, which + * may be set later. + */ +qemu_irq *qemu_irq_proxy(qemu_irq **target, int n); + +/* For internal use in qtest. Similar to qemu_irq_split, but operating + on an existing vector of qemu_irq. */ +void qemu_irq_intercept_in(qemu_irq *gpio_in, qemu_irq_handler handler, int n); +void qemu_irq_intercept_out(qemu_irq **gpio_out, qemu_irq_handler handler, int n); + #endif
diff --git a/qemu-char.c b/qemu-char.c index 73ba896..e9463d4 100644 --- a/qemu-char.c +++ b/qemu-char.c
@@ -30,6 +30,7 @@ #include "qemu/timer.h" #include "sysemu/char.h" #include "block/block.h" +#include "hw/irq.h" #include "hw/msmouse.h" #include "qapi/qmp/types.h"