aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/acpi.c2
-rw-r--r--hw/adlib.c2
-rw-r--r--hw/apb_pci.c6
-rw-r--r--hw/arm_gic.c20
-rw-r--r--hw/arm_pic.c43
-rw-r--r--hw/arm_pic.h6
-rw-r--r--hw/arm_timer.c37
-rw-r--r--hw/cs4231.c3
-rw-r--r--hw/cuda.c12
-rw-r--r--hw/eepro100.c4
-rw-r--r--hw/es1370.c4
-rw-r--r--hw/fdc.c10
-rw-r--r--hw/grackle_pci.c6
-rw-r--r--hw/gt64xxx.c6
-rw-r--r--hw/heathrow_pic.c10
-rw-r--r--hw/i8254.c6
-rw-r--r--hw/i8259.c27
-rw-r--r--hw/ide.c42
-rw-r--r--hw/integratorcp.c55
-rw-r--r--hw/irq.c57
-rw-r--r--hw/irq.h21
-rw-r--r--hw/lsi53c895a.c2
-rw-r--r--hw/m48t59.c12
-rw-r--r--hw/m48t59.h2
-rw-r--r--hw/mc146818rtc.c12
-rw-r--r--hw/mips_int.c13
-rw-r--r--hw/mips_malta.c32
-rw-r--r--hw/mips_r4k.c24
-rw-r--r--hw/mips_timer.c4
-rw-r--r--hw/ne2000.c25
-rw-r--r--hw/openpic.c10
-rw-r--r--hw/parallel.c8
-rw-r--r--hw/pc.c46
-rw-r--r--hw/pci.c9
-rw-r--r--hw/pckbd.c19
-rw-r--r--hw/pcnet.c24
-rw-r--r--hw/pcspk.c2
-rw-r--r--hw/piix_pci.c10
-rw-r--r--hw/pl011.c8
-rw-r--r--hw/pl050.c8
-rw-r--r--hw/pl080.c10
-rw-r--r--hw/pl110.c6
-rw-r--r--hw/pl181.c8
-rw-r--r--hw/pl190.c18
-rw-r--r--hw/ppc.c14
-rw-r--r--hw/ppc_chrp.c32
-rw-r--r--hw/ppc_prep.c27
-rw-r--r--hw/prep_pci.c8
-rw-r--r--hw/realview.c28
-rw-r--r--hw/rtl8139.c2
-rw-r--r--hw/sb16.c24
-rw-r--r--hw/serial.c20
-rw-r--r--hw/shix.c5
-rw-r--r--hw/slavio_intctl.c8
-rw-r--r--hw/slavio_misc.c22
-rw-r--r--hw/slavio_serial.c25
-rw-r--r--hw/slavio_timer.c3
-rw-r--r--hw/smc91c111.c8
-rw-r--r--hw/sparc32_dma.c39
-rw-r--r--hw/sun4m.c32
-rw-r--r--hw/sun4u.c20
-rw-r--r--hw/unin_pci.c6
-rw-r--r--hw/usb-ohci.c19
-rw-r--r--hw/usb-uhci.c2
-rw-r--r--hw/usb.h2
-rw-r--r--hw/versatile_pci.c6
-rw-r--r--hw/versatilepb.c46
67 files changed, 529 insertions, 560 deletions
diff --git a/hw/acpi.c b/hw/acpi.c
index 78c4feabbf..e78e56d628 100644
--- a/hw/acpi.c
+++ b/hw/acpi.c
@@ -92,7 +92,7 @@ static void pm_update_sci(PIIX4PMState *s)
pmsts = get_pmsts(s);
sci_level = (((pmsts & s->pmen) &
(RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0);
- pci_set_irq(&s->dev, 0, sci_level);
+ qemu_set_irq(s->dev.irq[0], sci_level);
/* schedule a timer interruption if needed */
if ((s->pmen & TMROF_EN) && !(pmsts & TMROF_EN)) {
expire_time = muldiv64(s->tmr_overflow_time, ticks_per_sec, PM_FREQ);
diff --git a/hw/adlib.c b/hw/adlib.c
index b47bc3eece..805365e709 100644
--- a/hw/adlib.c
+++ b/hw/adlib.c
@@ -267,7 +267,7 @@ static void Adlib_fini (AdlibState *s)
AUD_remove_card (&s->card);
}
-int Adlib_init (AudioState *audio)
+int Adlib_init (AudioState *audio, qemu_irq *pic)
{
AdlibState *s = &glob_adlib;
audsettings_t as;
diff --git a/hw/apb_pci.c b/hw/apb_pci.c
index a5fe9b989e..627fd9bc07 100644
--- a/hw/apb_pci.c
+++ b/hw/apb_pci.c
@@ -200,14 +200,14 @@ static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
return bus_offset + irq_num;
}
-static void pci_apb_set_irq(void *pic, int irq_num, int level)
+static void pci_apb_set_irq(qemu_irq *pic, int irq_num, int level)
{
/* PCI IRQ map onto the first 32 INO. */
- pic_set_irq_new(pic, irq_num, level);
+ qemu_set_irq(pic[irq_num], level);
}
PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
- void *pic)
+ qemu_irq *pic)
{
APBState *s;
PCIDevice *d;
diff --git a/hw/arm_gic.c b/hw/arm_gic.c
index 2901f3466e..eee5b7c727 100644
--- a/hw/arm_gic.c
+++ b/hw/arm_gic.c
@@ -60,10 +60,8 @@ typedef struct gic_irq_state
typedef struct gic_state
{
- arm_pic_handler handler;
uint32_t base;
- void *parent;
- int parent_irq;
+ qemu_irq parent_irq;
int enabled;
int cpu_enabled;
@@ -88,7 +86,7 @@ static void gic_update(gic_state *s)
s->current_pending = 1023;
if (!s->enabled || !s->cpu_enabled) {
- pic_set_irq_new(s->parent, s->parent_irq, 0);
+ qemu_irq_lower(s->parent_irq);
return;
}
best_prio = 0x100;
@@ -102,12 +100,12 @@ static void gic_update(gic_state *s)
}
}
if (best_prio > s->priority_mask) {
- pic_set_irq_new(s->parent, s->parent_irq, 0);
+ qemu_irq_lower(s->parent_irq);
} else {
s->current_pending = best_irq;
if (best_prio < s->running_priority) {
DPRINTF("Raised pending IRQ %d\n", best_irq);
- pic_set_irq_new(s->parent, s->parent_irq, 1);
+ qemu_irq_raise(s->parent_irq);
}
}
}
@@ -150,7 +148,7 @@ static uint32_t gic_acknowledge_irq(gic_state *s)
DPRINTF("ACK no pending IRQ\n");
return 1023;
}
- pic_set_irq_new(s->parent, s->parent_irq, 0);
+ qemu_irq_lower(s->parent_irq);
s->last_active[new_irq] = s->running_irq;
/* For level triggered interrupts we clear the pending bit while
the interrupt is active. */
@@ -520,16 +518,16 @@ static void gic_reset(gic_state *s)
s->cpu_enabled = 0;
}
-void *arm_gic_init(uint32_t base, void *parent, int parent_irq)
+qemu_irq *arm_gic_init(uint32_t base, qemu_irq parent_irq)
{
gic_state *s;
+ qemu_irq *qi;
int iomemtype;
s = (gic_state *)qemu_mallocz(sizeof(gic_state));
if (!s)
return NULL;
- s->handler = gic_set_irq;
- s->parent = parent;
+ qi = qemu_allocate_irqs(gic_set_irq, s, GIC_NIRQ);
s->parent_irq = parent_irq;
if (base != 0xffffffff) {
iomemtype = cpu_register_io_memory(0, gic_cpu_readfn,
@@ -543,5 +541,5 @@ void *arm_gic_init(uint32_t base, void *parent, int parent_irq)
s->base = 0;
}
gic_reset(s);
- return s;
+ return qi;
}
diff --git a/hw/arm_pic.c b/hw/arm_pic.c
index fbc2d67d0a..dcc1198e40 100644
--- a/hw/arm_pic.c
+++ b/hw/arm_pic.c
@@ -11,11 +11,6 @@
#include "arm_pic.h"
/* Stub functions for hardware that doesn't exist. */
-void pic_set_irq(int irq, int level)
-{
- cpu_abort(cpu_single_env, "pic_set_irq");
-}
-
void pic_info(void)
{
}
@@ -25,49 +20,29 @@ void irq_info(void)
}
-void pic_set_irq_new(void *opaque, int irq, int level)
-{
- arm_pic_handler *p = (arm_pic_handler *)opaque;
- /* Call the real handler. */
- (*p)(opaque, irq, level);
-}
-
-/* Model the IRQ/FIQ CPU interrupt lines as a two input interrupt controller.
- Input 0 is IRQ and input 1 is FIQ. */
-typedef struct
-{
- arm_pic_handler handler;
- CPUState *cpu_env;
-} arm_pic_cpu_state;
-
+/* Input 0 is IRQ and input 1 is FIQ. */
static void arm_pic_cpu_handler(void *opaque, int irq, int level)
{
- arm_pic_cpu_state *s = (arm_pic_cpu_state *)opaque;
+ CPUState *env = (CPUState *)opaque;
switch (irq) {
case ARM_PIC_CPU_IRQ:
if (level)
- cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
+ cpu_interrupt(env, CPU_INTERRUPT_HARD);
else
- cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
+ cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
break;
case ARM_PIC_CPU_FIQ:
if (level)
- cpu_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
+ cpu_interrupt(env, CPU_INTERRUPT_FIQ);
else
- cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ);
+ cpu_reset_interrupt(env, CPU_INTERRUPT_FIQ);
break;
default:
- cpu_abort(s->cpu_env, "arm_pic_cpu_handler: Bad interrput line %d\n",
- irq);
+ cpu_abort(env, "arm_pic_cpu_handler: Bad interrput line %d\n", irq);
}
}
-void *arm_pic_init_cpu(CPUState *env)
+qemu_irq *arm_pic_init_cpu(CPUState *env)
{
- arm_pic_cpu_state *s;
-
- s = (arm_pic_cpu_state *)malloc(sizeof(arm_pic_cpu_state));
- s->handler = arm_pic_cpu_handler;
- s->cpu_env = env;
- return s;
+ return qemu_allocate_irqs(arm_pic_cpu_handler, env, 2);
}
diff --git a/hw/arm_pic.h b/hw/arm_pic.h
index b29914985a..6c5ed1758b 100644
--- a/hw/arm_pic.h
+++ b/hw/arm_pic.h
@@ -14,14 +14,10 @@
#ifndef ARM_INTERRUPT_H
#define ARM_INTERRUPT_H 1
-/* The first element of an individual PIC state structures should
- be a pointer to the handler routine. */
-typedef void (*arm_pic_handler)(void *opaque, int irq, int level);
-
/* The CPU is also modeled as an interrupt controller. */
#define ARM_PIC_CPU_IRQ 0
#define ARM_PIC_CPU_FIQ 1
-void *arm_pic_init_cpu(CPUState *env);
+qemu_irq *arm_pic_init_cpu(CPUState *env);
#endif /* !ARM_INTERRUPT_H */
diff --git a/hw/arm_timer.c b/hw/arm_timer.c
index 068d0a0f7a..3c6c0d2394 100644
--- a/hw/arm_timer.c
+++ b/hw/arm_timer.c
@@ -32,8 +32,7 @@ typedef struct {
int raw_freq;
int freq;
int int_level;
- void *pic;
- int irq;
+ qemu_irq irq;
} arm_timer_state;
/* Calculate the new expiry time of the given timer. */
@@ -85,9 +84,9 @@ static void arm_timer_update(arm_timer_state *s, int64_t now)
}
/* Update interrupts. */
if (s->int_level && (s->control & TIMER_CTRL_IE)) {
- pic_set_irq_new(s->pic, s->irq, 1);
+ qemu_irq_raise(s->irq);
} else {
- pic_set_irq_new(s->pic, s->irq, 0);
+ qemu_irq_lower(s->irq);
}
next = now;
@@ -215,12 +214,11 @@ static void arm_timer_tick(void *opaque)
arm_timer_update((arm_timer_state *)opaque, now);
}
-static void *arm_timer_init(uint32_t freq, void *pic, int irq)
+static void *arm_timer_init(uint32_t freq, qemu_irq irq)
{
arm_timer_state *s;
s = (arm_timer_state *)qemu_mallocz(sizeof(arm_timer_state));
- s->pic = pic;
s->irq = irq;
s->raw_freq = s->freq = 1000000;
s->control = TIMER_CTRL_IE;
@@ -237,22 +235,19 @@ static void *arm_timer_init(uint32_t freq, void *pic, int irq)
Integrator/CP timer modules. */
typedef struct {
- /* Include a pseudo-PIC device to merge the two interrupt sources. */
- arm_pic_handler handler;
void *timer[2];
int level[2];
uint32_t base;
- /* The output PIC device. */
- void *pic;
- int irq;
+ qemu_irq irq;
} sp804_state;
+/* Merge the IRQs from the two component devices. */
static void sp804_set_irq(void *opaque, int irq, int level)
{
sp804_state *s = (sp804_state *)opaque;
s->level[irq] = level;
- pic_set_irq_new(s->pic, s->irq, s->level[0] || s->level[1]);
+ qemu_set_irq(s->irq, s->level[0] || s->level[1]);
}
static uint32_t sp804_read(void *opaque, target_phys_addr_t offset)
@@ -293,20 +288,20 @@ static CPUWriteMemoryFunc *sp804_writefn[] = {
sp804_write
};
-void sp804_init(uint32_t base, void *pic, int irq)
+void sp804_init(uint32_t base, qemu_irq irq)
{
int iomemtype;
sp804_state *s;
+ qemu_irq *qi;
s = (sp804_state *)qemu_mallocz(sizeof(sp804_state));
- s->handler = sp804_set_irq;
+ qi = qemu_allocate_irqs(sp804_set_irq, s, 2);
s->base = base;
- s->pic = pic;
s->irq = irq;
/* ??? The timers are actually configurable between 32kHz and 1MHz, but
we don't implement that. */
- s->timer[0] = arm_timer_init(1000000, s, 0);
- s->timer[1] = arm_timer_init(1000000, s, 1);
+ s->timer[0] = arm_timer_init(1000000, qi[0]);
+ s->timer[1] = arm_timer_init(1000000, qi[1]);
iomemtype = cpu_register_io_memory(0, sp804_readfn,
sp804_writefn, s);
cpu_register_physical_memory(base, 0x00000fff, iomemtype);
@@ -362,7 +357,7 @@ static CPUWriteMemoryFunc *icp_pit_writefn[] = {
icp_pit_write
};
-void icp_pit_init(uint32_t base, void *pic, int irq)
+void icp_pit_init(uint32_t base, qemu_irq *pic, int irq)
{
int iomemtype;
icp_pit_state *s;
@@ -370,10 +365,10 @@ void icp_pit_init(uint32_t base, void *pic, int irq)
s = (icp_pit_state *)qemu_mallocz(sizeof(icp_pit_state));
s->base = base;
/* Timer 0 runs at the system clock speed (40MHz). */
- s->timer[0] = arm_timer_init(40000000, pic, irq);
+ s->timer[0] = arm_timer_init(40000000, pic[irq]);
/* The other two timers run at 1MHz. */
- s->timer[1] = arm_timer_init(1000000, pic, irq + 1);
- s->timer[2] = arm_timer_init(1000000, pic, irq + 2);
+ s->timer[1] = arm_timer_init(1000000, pic[irq + 1]);
+ s->timer[2] = arm_timer_init(1000000, pic[irq + 2]);
iomemtype = cpu_register_io_memory(0, icp_pit_readfn,
icp_pit_writefn, s);
diff --git a/hw/cs4231.c b/hw/cs4231.c
index a154685569..6df881d41b 100644
--- a/hw/cs4231.c
+++ b/hw/cs4231.c
@@ -47,9 +47,6 @@ typedef struct CSState {
#ifdef DEBUG_CS
#define DPRINTF(fmt, args...) \
do { printf("CS: " fmt , ##args); } while (0)
-#define pic_set_irq_new(intctl, irq, level) \
- do { printf("CS: set_irq(%d): %d\n", (irq), (level)); \
- pic_set_irq_new((intctl), (irq),(level));} while (0)
#else
#define DPRINTF(fmt, args...)
#endif
diff --git a/hw/cuda.c b/hw/cuda.c
index f3c2b56010..c290450785 100644
--- a/hw/cuda.c
+++ b/hw/cuda.c
@@ -124,9 +124,7 @@ typedef struct CUDAState {
int data_in_index;
int data_out_index;
- SetIRQFunc *set_irq;
- int irq;
- void *irq_opaque;
+ qemu_irq irq;
uint8_t autopoll;
uint8_t data_in[128];
uint8_t data_out[16];
@@ -145,9 +143,9 @@ static void cuda_timer_update(CUDAState *s, CUDATimer *ti,
static void cuda_update_irq(CUDAState *s)
{
if (s->ifr & s->ier & (SR_INT | T1_INT)) {
- s->set_irq(s->irq_opaque, s->irq, 1);
+ qemu_irq_raise(s->irq);
} else {
- s->set_irq(s->irq_opaque, s->irq, 0);
+ qemu_irq_lower(s->irq);
}
}
@@ -630,13 +628,11 @@ static CPUReadMemoryFunc *cuda_read[] = {
&cuda_readl,
};
-int cuda_init(SetIRQFunc *set_irq, void *irq_opaque, int irq)
+int cuda_init(qemu_irq irq)
{
CUDAState *s = &cuda_state;
int cuda_mem_index;
- s->set_irq = set_irq;
- s->irq_opaque = irq_opaque;
s->irq = irq;
s->timers[0].index = 0;
diff --git a/hw/eepro100.c b/hw/eepro100.c
index ea18b890d0..bb570675a8 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -326,7 +326,7 @@ static void disable_interrupt(EEPRO100State * s)
{
if (s->int_stat) {
logout("interrupt disabled\n");
- pci_set_irq(s->pci_dev, 0, 0);
+ qemu_irq_lower(s->pci_dev->irq[0]);
s->int_stat = 0;
}
}
@@ -335,7 +335,7 @@ static void enable_interrupt(EEPRO100State * s)
{
if (!s->int_stat) {
logout("interrupt enabled\n");
- pci_set_irq(s->pci_dev, 0, 1);
+ qemu_irq_raise(s->pci_dev->irq[0]);
s->int_stat = 1;
}
}
diff --git a/hw/es1370.c b/hw/es1370.c
index 0d2d861166..d607a94852 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -324,7 +324,7 @@ static void es1370_update_status (ES1370State *s, uint32_t new_status)
else {
s->status = new_status & ~STAT_INTR;
}
- pci_set_irq (s->pci_dev, 0, !!level);
+ qemu_set_irq(s->pci_dev->irq[0], !!level);
}
static void es1370_reset (ES1370State *s)
@@ -350,7 +350,7 @@ static void es1370_reset (ES1370State *s)
s->dac_voice[i] = NULL;
}
}
- pci_set_irq (s->pci_dev, 0, 0);
+ qemu_irq_lower(s->pci_dev->irq[0]);
}
static void es1370_maybe_lower_irq (ES1370State *s, uint32_t sctl)
diff --git a/hw/fdc.c b/hw/fdc.c
index 0012834f44..a12eb0af5d 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -368,7 +368,7 @@ struct fdctrl_t {
/* Controller's identification */
uint8_t version;
/* HW */
- int irq_lvl;
+ qemu_irq irq;
int dma_chann;
uint32_t io_base;
/* Controller state */
@@ -485,7 +485,7 @@ static CPUWriteMemoryFunc *fdctrl_mem_write[3] = {
fdctrl_write_mem,
};
-fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
+fdctrl_t *fdctrl_init (qemu_irq irq, int dma_chann, int mem_mapped,
uint32_t io_base,
BlockDriverState **fds)
{
@@ -501,7 +501,7 @@ fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
fdctrl_result_timer, fdctrl);
fdctrl->version = 0x90; /* Intel 82078 controller */
- fdctrl->irq_lvl = irq_lvl;
+ fdctrl->irq = irq;
fdctrl->dma_chann = dma_chann;
fdctrl->io_base = io_base;
fdctrl->config = 0x60; /* Implicit seek, polling & FIFO enabled */
@@ -542,7 +542,7 @@ int fdctrl_get_drive_type(fdctrl_t *fdctrl, int drive_num)
static void fdctrl_reset_irq (fdctrl_t *fdctrl)
{
FLOPPY_DPRINTF("Reset interrupt\n");
- pic_set_irq(fdctrl->irq_lvl, 0);
+ qemu_set_irq(fdctrl->irq, 0);
fdctrl->state &= ~FD_CTRL_INTR;
}
@@ -557,7 +557,7 @@ static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status)
}
#endif
if (~(fdctrl->state & FD_CTRL_INTR)) {
- pic_set_irq(fdctrl->irq_lvl, 1);
+ qemu_set_irq(fdctrl->irq, 1);
fdctrl->state |= FD_CTRL_INTR;
}
FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", status);
diff --git a/hw/grackle_pci.c b/hw/grackle_pci.c
index 4004f9942f..74d4efccc7 100644
--- a/hw/grackle_pci.c
+++ b/hw/grackle_pci.c
@@ -80,12 +80,12 @@ static int pci_grackle_map_irq(PCIDevice *pci_dev, int irq_num)
return (irq_num + (pci_dev->devfn >> 3)) & 3;
}
-static void pci_grackle_set_irq(void *pic, int irq_num, int level)
+static void pci_grackle_set_irq(qemu_irq *pic, int irq_num, int level)
{
- heathrow_pic_set_irq(pic, irq_num + 8, level);
+ qemu_set_irq(pic[irq_num + 8], level);
}
-PCIBus *pci_grackle_init(uint32_t base, void *pic)
+PCIBus *pci_grackle_init(uint32_t base, qemu_irq *pic)
{
GrackleState *s;
PCIDevice *d;
diff --git a/hw/gt64xxx.c b/hw/gt64xxx.c
index 9d6bb44eb9..3300d40be0 100644
--- a/hw/gt64xxx.c
+++ b/hw/gt64xxx.c
@@ -520,7 +520,7 @@ static int pci_gt64120_map_irq(PCIDevice *pci_dev, int irq_num)
extern PCIDevice *piix4_dev;
static int pci_irq_levels[4];
-static void pci_gt64120_set_irq(void *pic, int irq_num, int level)
+static void pci_gt64120_set_irq(qemu_irq *pic, int irq_num, int level)
{
int i, pic_irq, pic_level;
@@ -537,7 +537,7 @@ static void pci_gt64120_set_irq(void *pic, int irq_num, int level)
if (pic_irq == piix4_dev->config[0x60 + i])
pic_level |= pci_irq_levels[i];
}
- pic_set_irq(pic_irq, pic_level);
+ qemu_set_irq(pic[pic_irq], pic_level);
}
}
@@ -608,7 +608,7 @@ void gt64120_reset(void *opaque)
gt64120_pci_mapping(s);
}
-PCIBus *pci_gt64120_init(void *pic)
+PCIBus *pci_gt64120_init(qemu_irq *pic)
{
GT64120State *s;
PCIDevice *d;
diff --git a/hw/heathrow_pic.c b/hw/heathrow_pic.c
index 4980cef467..c0edaea778 100644
--- a/hw/heathrow_pic.c
+++ b/hw/heathrow_pic.c
@@ -32,9 +32,9 @@ typedef struct HeathrowPIC {
uint32_t level_triggered;
} HeathrowPIC;
-struct HeathrowPICS {
+typedef struct HeathrowPICS {
HeathrowPIC pics[2];
-};
+} HeathrowPICS;
static inline int check_irq(HeathrowPIC *pic)
{
@@ -130,7 +130,7 @@ static CPUReadMemoryFunc *pic_read[] = {
};
-void heathrow_pic_set_irq(void *opaque, int num, int level)
+static void heathrow_pic_set_irq(void *opaque, int num, int level)
{
HeathrowPICS *s = opaque;
HeathrowPIC *pic;
@@ -156,7 +156,7 @@ void heathrow_pic_set_irq(void *opaque, int num, int level)
heathrow_pic_update(s);
}
-HeathrowPICS *heathrow_pic_init(int *pmem_index)
+qemu_irq *heathrow_pic_init(int *pmem_index)
{
HeathrowPICS *s;
@@ -164,5 +164,5 @@ HeathrowPICS *heathrow_pic_init(int *pmem_index)
s->pics[0].level_triggered = 0;
s->pics[1].level_triggered = 0x1ff00000;
*pmem_index = cpu_register_io_memory(0, pic_read, pic_write, s);
- return s;
+ return qemu_allocate_irqs(heathrow_pic_set_irq, s, 64);
}
diff --git a/hw/i8254.c b/hw/i8254.c
index a4097632eb..f0b41d75c9 100644
--- a/hw/i8254.c
+++ b/hw/i8254.c
@@ -47,7 +47,7 @@ typedef struct PITChannelState {
/* irq handling */
int64_t next_transition_time;
QEMUTimer *irq_timer;
- int irq;
+ qemu_irq irq;
} PITChannelState;
struct PITState {
@@ -366,7 +366,7 @@ static void pit_irq_timer_update(PITChannelState *s, int64_t current_time)
return;
expire_time = pit_get_next_transition_time(s, current_time);
irq_level = pit_get_out1(s, current_time);
- pic_set_irq(s->irq, irq_level);
+ qemu_set_irq(s->irq, irq_level);
#ifdef DEBUG_PIT
printf("irq_level=%d next_delay=%f\n",
irq_level,
@@ -460,7 +460,7 @@ static void pit_reset(void *opaque)
}
}
-PITState *pit_init(int base, int irq)
+PITState *pit_init(int base, qemu_irq irq)
{
PITState *pit = &pit_state;
PITChannelState *s;
diff --git a/hw/i8259.c b/hw/i8259.c
index 631e4113bc..4b25df3b9c 100644
--- a/hw/i8259.c
+++ b/hw/i8259.c
@@ -54,7 +54,7 @@ struct PicState2 {
/* 0 is master pic, 1 is slave pic */
/* XXX: better separation between the two pics */
PicState pics[2];
- IRQRequestFunc *irq_request;
+ qemu_irq parent_irq;
void *irq_request_opaque;
/* IOAPIC callback support */
SetIRQFunc *alt_irq_func;
@@ -160,13 +160,13 @@ void pic_update_irq(PicState2 *s)
}
printf("pic: cpu_interrupt\n");
#endif
- s->irq_request(s->irq_request_opaque, 1);
+ qemu_irq_raise(s->parent_irq);
}
/* all targets should do this rather than acking the IRQ in the cpu */
#if defined(TARGET_MIPS)
else {
- s->irq_request(s->irq_request_opaque, 0);
+ qemu_irq_lower(s->parent_irq);
}
#endif
}
@@ -175,14 +175,14 @@ void pic_update_irq(PicState2 *s)
int64_t irq_time[16];
#endif
-void pic_set_irq_new(void *opaque, int irq, int level)
+void i8259_set_irq(void *opaque, int irq, int level)
{
PicState2 *s = opaque;
#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
if (level != irq_level[irq]) {
#if defined(DEBUG_PIC)
- printf("pic_set_irq: irq=%d level=%d\n", irq, level);
+ printf("i8259_set_irq: irq=%d level=%d\n", irq, level);
#endif
irq_level[irq] = level;
#ifdef DEBUG_IRQ_COUNT
@@ -203,12 +203,6 @@ void pic_set_irq_new(void *opaque, int irq, int level)
pic_update_irq(s);
}
-/* obsolete function */
-void pic_set_irq(int irq, int level)
-{
- pic_set_irq_new(isa_pic, irq, level);
-}
-
/* acknowledge interrupt 'irq' */
static inline void pic_intack(PicState *s, int irq)
{
@@ -297,7 +291,7 @@ static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val)
/* init */
pic_reset(s);
/* deassert a pending interrupt */
- s->pics_state->irq_request(s->pics_state->irq_request_opaque, 0);
+ qemu_irq_lower(s->pics_state->parent_irq);
s->init_state = 1;
s->init4 = val & 1;
s->single_mode = val & 2;
@@ -546,9 +540,10 @@ void irq_info(void)
#endif
}
-PicState2 *pic_init(IRQRequestFunc *irq_request, void *irq_request_opaque)
+qemu_irq *i8259_init(qemu_irq parent_irq)
{
PicState2 *s;
+
s = qemu_mallocz(sizeof(PicState2));
if (!s)
return NULL;
@@ -556,11 +551,11 @@ PicState2 *pic_init(IRQRequestFunc *irq_request, void *irq_request_opaque)
pic_init1(0xa0, 0x4d1, &s->pics[1]);
s->pics[0].elcr_mask = 0xf8;
s->pics[1].elcr_mask = 0xde;
- s->irq_request = irq_request;
- s->irq_request_opaque = irq_request_opaque;
+ s->parent_irq = parent_irq;
s->pics[0].pics_state = s;
s->pics[1].pics_state = s;
- return s;
+ isa_pic = s;
+ return qemu_allocate_irqs(i8259_set_irq, s, 16);
}
void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
diff --git a/hw/ide.c b/hw/ide.c
index e608cc5745..ffee8dde9d 100644
--- a/hw/ide.c
+++ b/hw/ide.c
@@ -300,9 +300,7 @@ typedef struct IDEState {
int mult_sectors;
int identify_set;
uint16_t identify_data[256];
- SetIRQFunc *set_irq;
- void *irq_opaque;
- int irq;
+ qemu_irq irq;
PCIDevice *pci_dev;
struct BMDMAState *bmdma;
int drive_serial;
@@ -575,7 +573,7 @@ static inline void ide_set_irq(IDEState *s)
if (bm) {
bm->status |= BM_STATUS_INT;
}
- s->set_irq(s->irq_opaque, s->irq, 1);
+ qemu_irq_raise(s->irq);
}
}
@@ -1889,7 +1887,7 @@ static uint32_t ide_ioport_read(void *opaque, uint32_t addr1)
ret = 0;
else
ret = s->status;
- s->set_irq(s->irq_opaque, s->irq, 0);
+ qemu_irq_lower(s->irq);
break;
}
#ifdef DEBUG_IDE
@@ -2084,7 +2082,7 @@ static int guess_disk_lchs(IDEState *s,
static void ide_init2(IDEState *ide_state,
BlockDriverState *hd0, BlockDriverState *hd1,
- SetIRQFunc *set_irq, void *irq_opaque, int irq)
+ qemu_irq irq)
{
IDEState *s;
static int drive_serial = 1;
@@ -2155,8 +2153,6 @@ static void ide_init2(IDEState *ide_state,
}
}
s->drive_serial = drive_serial++;
- s->set_irq = set_irq;
- s->irq_opaque = irq_opaque;
s->irq = irq;
s->sector_write_timer = qemu_new_timer(vm_clock,
ide_sector_write_timer_cb, s);
@@ -2183,7 +2179,7 @@ static void ide_init_ioport(IDEState *ide_state, int iobase, int iobase2)
/***********************************************************/
/* ISA IDE definitions */
-void isa_ide_init(int iobase, int iobase2, int irq,
+void isa_ide_init(int iobase, int iobase2, qemu_irq irq,
BlockDriverState *hd0, BlockDriverState *hd1)
{
IDEState *ide_state;
@@ -2192,7 +2188,7 @@ void isa_ide_init(int iobase, int iobase2, int irq,
if (!ide_state)
return;
- ide_init2(ide_state, hd0, hd1, pic_set_irq_new, isa_pic, irq);
+ ide_init2(ide_state, hd0, hd1, irq);
ide_init_ioport(ide_state, iobase, iobase2);
}
@@ -2399,7 +2395,7 @@ static void cmd646_update_irq(PCIIDEState *d)
!(d->dev.config[MRDMODE] & MRDMODE_BLK_CH0)) ||
((d->dev.config[MRDMODE] & MRDMODE_INTR_CH1) &&
!(d->dev.config[MRDMODE] & MRDMODE_BLK_CH1));
- pci_set_irq((PCIDevice *)d, 0, pci_level);
+ qemu_set_irq(d->dev.irq[0], pci_level);
}
/* the PCI irq level is the logical OR of the two channels */
@@ -2423,6 +2419,7 @@ void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
PCIIDEState *d;
uint8_t *pci_conf;
int i;
+ qemu_irq *irq;
d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE",
sizeof(PCIIDEState),
@@ -2462,10 +2459,10 @@ void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
for(i = 0; i < 4; i++)
d->ide_if[i].pci_dev = (PCIDevice *)d;
- ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
- cmd646_set_irq, d, 0);
- ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
- cmd646_set_irq, d, 1);
+
+ irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
+ ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], irq[0]);
+ ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], irq[1]);
}
static void pci_ide_save(QEMUFile* f, void *opaque)
@@ -2592,7 +2589,8 @@ static void piix3_reset(PCIIDEState *d)
/* hd_table must contain 4 block drivers */
/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */
-void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn)
+void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
+ qemu_irq *pic)
{
PCIIDEState *d;
uint8_t *pci_conf;
@@ -2619,10 +2617,8 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn)
pci_register_io_region((PCIDevice *)d, 4, 0x10,
PCI_ADDRESS_SPACE_IO, bmdma_map);
- ide_init2(&d->ide_if[0], hd_table[0], hd_table[1],
- pic_set_irq_new, isa_pic, 14);
- ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
- pic_set_irq_new, isa_pic, 15);
+ ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]);
+ ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]);
ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
ide_init_ioport(&d->ide_if[2], 0x170, 0x376);
@@ -2741,15 +2737,13 @@ static CPUReadMemoryFunc *pmac_ide_read[] = {
/* hd_table must contain 4 block drivers */
/* PowerMac uses memory mapped registers, not I/O. Return the memory
I/O index to access the ide. */
-int pmac_ide_init (BlockDriverState **hd_table,
- SetIRQFunc *set_irq, void *irq_opaque, int irq)
+int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq)
{
IDEState *ide_if;
int pmac_ide_memory;
ide_if = qemu_mallocz(sizeof(IDEState) * 2);
- ide_init2(&ide_if[0], hd_table[0], hd_table[1],
- set_irq, irq_opaque, irq);
+ ide_init2(&ide_if[0], hd_table[0], hd_table[1], irq);
pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
pmac_ide_write, &ide_if[0]);
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index 1d8b722cfd..34c3b8112e 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -267,28 +267,22 @@ static void integratorcm_init(int memsz, uint32_t flash_offset)
typedef struct icp_pic_state
{
- arm_pic_handler handler;
uint32_t base;
uint32_t level;
uint32_t irq_enabled;
uint32_t fiq_enabled;
- void *parent;
- int parent_irq;
- int parent_fiq;
+ qemu_irq parent_irq;
+ qemu_irq parent_fiq;
} icp_pic_state;
static void icp_pic_update(icp_pic_state *s)
{
uint32_t flags;
- if (s->parent_irq != -1) {
- flags = (s->level & s->irq_enabled);
- pic_set_irq_new(s->parent, s->parent_irq, flags != 0);
- }
- if (s->parent_fiq != -1) {
- flags = (s->level & s->fiq_enabled);
- pic_set_irq_new(s->parent, s->parent_fiq, flags != 0);
- }
+ flags = (s->level & s->irq_enabled);
+ qemu_set_irq(s->parent_irq, flags != 0);
+ flags = (s->level & s->fiq_enabled);
+ qemu_set_irq(s->parent_fiq, flags != 0);
}
static void icp_pic_set_irq(void *opaque, int irq, int level)
@@ -345,11 +339,11 @@ static void icp_pic_write(void *opaque, target_phys_addr_t offset,
break;
case 4: /* INT_SOFTSET */
if (value & 1)
- pic_set_irq_new(s, 0, 1);
+ icp_pic_set_irq(s, 0, 1);
break;
case 5: /* INT_SOFTCLR */
if (value & 1)
- pic_set_irq_new(s, 0, 0);
+ icp_pic_set_irq(s, 0, 0);
break;
case 10: /* FRQ_ENABLESET */
s->fiq_enabled |= value;
@@ -380,25 +374,25 @@ static CPUWriteMemoryFunc *icp_pic_writefn[] = {
icp_pic_write
};
-static icp_pic_state *icp_pic_init(uint32_t base, void *parent,
- int parent_irq, int parent_fiq)
+static qemu_irq *icp_pic_init(uint32_t base,
+ qemu_irq parent_irq, qemu_irq parent_fiq)
{
icp_pic_state *s;
int iomemtype;
+ qemu_irq *qi;
s = (icp_pic_state *)qemu_mallocz(sizeof(icp_pic_state));
if (!s)
return NULL;
- s->handler = icp_pic_set_irq;
+ qi = qemu_allocate_irqs(icp_pic_set_irq, s, 32);
s->base = base;
- s->parent = parent;
s->parent_irq = parent_irq;
s->parent_fiq = parent_fiq;
iomemtype = cpu_register_io_memory(0, icp_pic_readfn,
icp_pic_writefn, s);
cpu_register_physical_memory(base, 0x007fffff, iomemtype);
/* ??? Save/restore. */
- return s;
+ return qi;
}
/* CP control registers. */
@@ -475,8 +469,8 @@ static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device,
{
CPUState *env;
uint32_t bios_offset;
- icp_pic_state *pic;
- void *cpu_pic;
+ qemu_irq *pic;
+ qemu_irq *cpu_pic;
env = cpu_init();
if (!cpu_model)
@@ -492,25 +486,26 @@ static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device,
integratorcm_init(ram_size >> 20, bios_offset);
cpu_pic = arm_pic_init_cpu(env);
- pic = icp_pic_init(0x14000000, cpu_pic, ARM_PIC_CPU_IRQ, ARM_PIC_CPU_FIQ);
- icp_pic_init(0xca000000, pic, 26, -1);
+ pic = icp_pic_init(0x14000000, cpu_pic[ARM_PIC_CPU_IRQ],
+ cpu_pic[ARM_PIC_CPU_FIQ]);
+ icp_pic_init(0xca000000, pic[26], NULL);
icp_pit_init(0x13000000, pic, 5);
- pl011_init(0x16000000, pic, 1, serial_hds[0]);
- pl011_init(0x17000000, pic, 2, serial_hds[1]);
+ pl011_init(0x16000000, pic[1], serial_hds[0]);
+ pl011_init(0x17000000, pic[2], serial_hds[1]);
icp_control_init(0xcb000000);
- pl050_init(0x18000000, pic, 3, 0);
- pl050_init(0x19000000, pic, 4, 1);
- pl181_init(0x1c000000, sd_bdrv, pic, 23, 24);
+ pl050_init(0x18000000, pic[3], 0);
+ pl050_init(0x19000000, pic[4], 1);
+ pl181_init(0x1c000000, sd_bdrv, pic[23], pic[24]);
if (nd_table[0].vlan) {
if (nd_table[0].model == NULL
|| strcmp(nd_table[0].model, "smc91c111") == 0) {
- smc91c111_init(&nd_table[0], 0xc8000000, pic, 27);
+ smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
} else {
fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
exit (1);
}
}
- pl110_init(ds, 0xc0000000, pic, 22, 0);
+ pl110_init(ds, 0xc0000000, pic[22], 0);
arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline,
initrd_filename, 0x113);
diff --git a/hw/irq.c b/hw/irq.c
new file mode 100644
index 0000000000..4bc8d80de9
--- /dev/null
+++ b/hw/irq.c
@@ -0,0 +1,57 @@
+/*
+ * QEMU IRQ/GPIO common code.
+ *
+ * Copyright (c) 2007 CodeSourcery.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+
+struct IRQState {
+ qemu_irq_handler handler;
+ void *opaque;
+ int n;
+};
+
+void qemu_set_irq(qemu_irq irq, int level)
+{
+ if (!irq)
+ return;
+
+ irq->handler(irq->opaque, irq->n, level);
+}
+
+qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n)
+{
+ qemu_irq *s;
+ struct IRQState *p;
+ int i;
+
+ s = (qemu_irq *)qemu_mallocz(sizeof(qemu_irq) * n);
+ p = (struct IRQState *)qemu_mallocz(sizeof(struct IRQState) * n);
+ for (i = 0; i < n; i++) {
+ p->handler = handler;
+ p->opaque = opaque;
+ p->n = i;
+ s[i] = p;
+ p++;
+ }
+ return s;
+}
+
diff --git a/hw/irq.h b/hw/irq.h
new file mode 100644
index 0000000000..652fd6abeb
--- /dev/null
+++ b/hw/irq.h
@@ -0,0 +1,21 @@
+/* Generic IRQ/GPIO pin infrastructure. */
+
+typedef void (*qemu_irq_handler)(void *opaque, int n, int level);
+
+typedef struct IRQState *qemu_irq;
+
+void qemu_set_irq(qemu_irq irq, int level);
+
+static inline void qemu_irq_raise(qemu_irq irq)
+{
+ qemu_set_irq(irq, 1);
+}
+
+static inline void qemu_irq_lower(qemu_irq irq)
+{
+ qemu_set_irq(irq, 0);
+}
+
+/* Returns an array of N IRQs. */
+qemu_irq *qemu_allocate_irqs(qemu_irq_handler handler, void *opaque, int n);
+
diff --git a/hw/lsi53c895a.c b/hw/lsi53c895a.c
index 193ff12204..88806a60a4 100644
--- a/hw/lsi53c895a.c
+++ b/hw/lsi53c895a.c
@@ -374,7 +374,7 @@ static void lsi_update_irq(LSIState *s)
level, s->dstat, s->sist1, s->sist0);
last_level = level;
}
- pci_set_irq(&s->pci_dev, 0, level);
+ qemu_set_irq(s->pci_dev.irq[0], level);
}
/* Stop SCRIPTS execution and raise a SCSI interrupt. */
diff --git a/hw/m48t59.c b/hw/m48t59.c
index daa1c524db..1c61401c52 100644
--- a/hw/m48t59.c
+++ b/hw/m48t59.c
@@ -41,7 +41,7 @@ struct m48t59_t {
/* Model parameters */
int type; // 8 = m48t08, 59 = m48t59
/* Hardware parameters */
- int IRQ;
+ qemu_irq IRQ;
int mem_index;
uint32_t mem_base;
uint32_t io_base;
@@ -100,7 +100,7 @@ static void alarm_cb (void *opaque)
uint64_t next_time;
m48t59_t *NVRAM = opaque;
- pic_set_irq(NVRAM->IRQ, 1);
+ qemu_set_irq(NVRAM->IRQ, 1);
if ((NVRAM->buffer[0x1FF5] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF4] & 0x80) == 0 &&
(NVRAM->buffer[0x1FF3] & 0x80) == 0 &&
@@ -137,7 +137,7 @@ static void alarm_cb (void *opaque)
next_time = 1 + mktime(&tm_now);
}
qemu_mod_timer(NVRAM->alrm_timer, next_time * 1000);
- pic_set_irq(NVRAM->IRQ, 0);
+ qemu_set_irq(NVRAM->IRQ, 0);
}
@@ -173,8 +173,8 @@ static void watchdog_cb (void *opaque)
/* May it be a hw CPU Reset instead ? */
qemu_system_reset_request();
} else {
- pic_set_irq(NVRAM->IRQ, 1);
- pic_set_irq(NVRAM->IRQ, 0);
+ qemu_set_irq(NVRAM->IRQ, 1);
+ qemu_set_irq(NVRAM->IRQ, 0);
}
}
@@ -576,7 +576,7 @@ static CPUReadMemoryFunc *nvram_read[] = {
};
/* Initialisation routine */
-m48t59_t *m48t59_init (int IRQ, target_ulong mem_base,
+m48t59_t *m48t59_init (qemu_irq IRQ, target_ulong mem_base,
uint32_t io_base, uint16_t size,
int type)
{
diff --git a/hw/m48t59.h b/hw/m48t59.h
index af22dc1123..df383e91c3 100644
--- a/hw/m48t59.h
+++ b/hw/m48t59.h
@@ -6,7 +6,7 @@ typedef struct m48t59_t m48t59_t;
void m48t59_write (m48t59_t *NVRAM, uint32_t addr, uint32_t val);
uint32_t m48t59_read (m48t59_t *NVRAM, uint32_t addr);
void m48t59_toggle_lock (m48t59_t *NVRAM, int lock);
-m48t59_t *m48t59_init (int IRQ, target_ulong mem_base,
+m48t59_t *m48t59_init (qemu_irq IRQ, target_ulong mem_base,
uint32_t io_base, uint16_t size,
int type);
diff --git a/hw/mc146818rtc.c b/hw/mc146818rtc.c
index bad4cbd864..8b9357459d 100644
--- a/hw/mc146818rtc.c
+++ b/hw/mc146818rtc.c
@@ -54,7 +54,7 @@ struct RTCState {
uint8_t cmos_data[128];
uint8_t cmos_index;
struct tm current_tm;
- int irq;
+ qemu_irq irq;
/* periodic timer */
QEMUTimer *periodic_timer;
int64_t next_periodic_time;
@@ -95,7 +95,7 @@ static void rtc_periodic_timer(void *opaque)
rtc_timer_update(s, s->next_periodic_time);
s->cmos_data[RTC_REG_C] |= 0xc0;
- pic_set_irq(s->irq, 1);
+ qemu_irq_raise(s->irq);
}
static void cmos_ioport_write(void *opaque, uint32_t addr, uint32_t data)
@@ -314,14 +314,14 @@ static void rtc_update_second2(void *opaque)
s->cmos_data[RTC_HOURS_ALARM] == s->current_tm.tm_hour)) {
s->cmos_data[RTC_REG_C] |= 0xa0;
- pic_set_irq(s->irq, 1);
+ qemu_irq_raise(s->irq);
}
}
/* update ended interrupt */
if (s->cmos_data[RTC_REG_B] & REG_B_UIE) {
s->cmos_data[RTC_REG_C] |= 0x90;
- pic_set_irq(s->irq, 1);
+ qemu_irq_raise(s->irq);
}
/* clear update in progress bit */
@@ -353,7 +353,7 @@ static uint32_t cmos_ioport_read(void *opaque, uint32_t addr)
break;
case RTC_REG_C:
ret = s->cmos_data[s->cmos_index];
- pic_set_irq(s->irq, 0);
+ qemu_irq_lower(s->irq);
s->cmos_data[RTC_REG_C] = 0x00;
break;
default:
@@ -453,7 +453,7 @@ static int rtc_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
-RTCState *rtc_init(int base, int irq)
+RTCState *rtc_init(int base, qemu_irq irq)
{
RTCState *s;
diff --git a/hw/mips_int.c b/hw/mips_int.c
index ed489f1a16..f4e22dcf85 100644
--- a/hw/mips_int.c
+++ b/hw/mips_int.c
@@ -17,7 +17,7 @@ void cpu_mips_update_irq(CPUState *env)
cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
}
-void cpu_mips_irq_request(void *opaque, int irq, int level)
+static void cpu_mips_irq_request(void *opaque, int irq, int level)
{
CPUState *env = (CPUState *)opaque;
@@ -31,3 +31,14 @@ void cpu_mips_irq_request(void *opaque, int irq, int level)
}
cpu_mips_update_irq(env);
}
+
+void cpu_mips_irq_init_cpu(CPUState *env)
+{
+ qemu_irq *qi;
+ int i;
+
+ qi = qemu_allocate_irqs(cpu_mips_irq_request, env, 8);
+ for (i = 0; i < 8; i++) {
+ env->irq[i] = qi[i];
+ }
+}
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 97707c1166..6102ecb9a4 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -60,12 +60,6 @@ typedef struct {
static PITState *pit;
-/* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
-static void pic_irq_request(void *opaque, int level)
-{
- cpu_mips_irq_request(opaque, 2, level);
-}
-
/* Malta FPGA */
static void malta_fpga_update_display(void *opaque)
{
@@ -451,8 +445,7 @@ MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, CPUState *env)
uart_chr = qemu_chr_open("vc");
qemu_chr_printf(uart_chr, "CBUS UART\r\n");
- s->uart = serial_mm_init(&cpu_mips_irq_request, env, base, 3, 2,
- uart_chr, 0);
+ s->uart = serial_mm_init(base, 3, env->irq[2], uart_chr, 0);
malta_fpga_reset(s);
qemu_register_reset(malta_fpga_reset, s);
@@ -676,6 +669,7 @@ void mips_malta_init (int ram_size, int vga_ram_size, int boot_device,
MaltaFPGAState *malta_fpga;
int ret;
mips_def_t *def;
+ qemu_irq *i8259;
/* init CPUs */
if (cpu_model == NULL) {
@@ -729,6 +723,7 @@ void mips_malta_init (int ram_size, int vga_ram_size, int boot_device,
stl_raw(phys_ram_base + bios_offset + 0x10, 0x00000420);
/* Init internal devices */
+ cpu_mips_irq_init_cpu(env);
cpu_mips_clock_init(env);
cpu_mips_irqctrl_init();
@@ -736,31 +731,32 @@ void mips_malta_init (int ram_size, int vga_ram_size, int boot_device,
malta_fpga = malta_fpga_init(0x1f000000LL, env);
/* Interrupt controller */
- isa_pic = pic_init(pic_irq_request, env);
+ /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
+ i8259 = i8259_init(env->irq[2]);
/* Northbridge */
- pci_bus = pci_gt64120_init(isa_pic);
+ pci_bus = pci_gt64120_init(i8259);
/* Southbridge */
piix4_init(pci_bus, 80);
- pci_piix3_ide_init(pci_bus, bs_table, 81);
+ pci_piix3_ide_init(pci_bus, bs_table, 81, i8259);
usb_uhci_init(pci_bus, 82);
piix4_pm_init(pci_bus, 83);
- pit = pit_init(0x40, 0);
+ pit = pit_init(0x40, i8259[0]);
DMA_init(0);
/* Super I/O */
- kbd_init();
- rtc_state = rtc_init(0x70, 8);
+ i8042_init(i8259[1], i8259[12], 0x60);
+ rtc_state = rtc_init(0x70, i8259[8]);
if (serial_hds[0])
- serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
+ serial_init(0x3f8, i8259[4], serial_hds[0]);
if (serial_hds[1])
- serial_init(&pic_set_irq_new, isa_pic, 0x2f8, 3, serial_hds[1]);
+ serial_init(0x2f8, i8259[3], serial_hds[1]);
if (parallel_hds[0])
- parallel_init(0x378, 7, parallel_hds[0]);
+ parallel_init(0x378, i8259[7], parallel_hds[0]);
/* XXX: The floppy controller does not work correctly, something is
probably wrong.
- floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); */
+ floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd_table); */
/* Sound card */
#ifdef HAS_AUDIO
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 8fbddf3c34..f6af322fdc 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -35,11 +35,6 @@ extern FILE *logfile;
static PITState *pit; /* PIT i8254 */
/*i8254 PIT is attached to the IRQ0 at PIC i8259 */
-/*The PIC is attached to the MIPS CPU INT0 pin */
-static void pic_irq_request(void *opaque, int level)
-{
- cpu_mips_irq_request(opaque, 2, level);
-}
static void mips_qemu_writel (void *opaque, target_phys_addr_t addr,
uint32_t val)
@@ -152,6 +147,7 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device,
RTCState *rtc_state;
int i;
mips_def_t *def;
+ qemu_irq *i8259;
/* init CPUs */
if (cpu_model == NULL) {
@@ -203,22 +199,24 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device,
}
/* Init CPU internal devices */
+ cpu_mips_irq_init_cpu(env);
cpu_mips_clock_init(env);
cpu_mips_irqctrl_init();
- rtc_state = rtc_init(0x70, 8);
+ /* The PIC is attached to the MIPS CPU INT0 pin */
+ i8259 = i8259_init(env->irq[2]);
+
+ rtc_state = rtc_init(0x70, i8259[8]);
/* Register 64 KB of ISA IO space at 0x14000000 */
isa_mmio_init(0x14000000, 0x00010000);
isa_mem_base = 0x10000000;
- isa_pic = pic_init(pic_irq_request, env);
- pit = pit_init(0x40, 0);
+ pit = pit_init(0x40, i8259[0]);
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
if (serial_hds[i]) {
- serial_init(&pic_set_irq_new, isa_pic,
- serial_io[i], serial_irq[i], serial_hds[i]);
+ serial_init(serial_io[i], i8259[serial_irq[i]], serial_hds[i]);
}
}
@@ -228,7 +226,7 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device,
if (nd_table[0].vlan) {
if (nd_table[0].model == NULL
|| strcmp(nd_table[0].model, "ne2k_isa") == 0) {
- isa_ne2000_init(0x300, 9, &nd_table[0]);
+ isa_ne2000_init(0x300, i8259[9], &nd_table[0]);
} else {
fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
exit (1);
@@ -236,10 +234,10 @@ void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device,
}
for(i = 0; i < 2; i++)
- isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
+ isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]],
bs_table[2 * i], bs_table[2 * i + 1]);
- kbd_init();
+ i8042_init(i8259[1], i8259[12], 0x60);
ds1225y_init(0x9000, "nvram");
}
diff --git a/hw/mips_timer.c b/hw/mips_timer.c
index 9128cbff7d..bd89e5dee1 100644
--- a/hw/mips_timer.c
+++ b/hw/mips_timer.c
@@ -63,7 +63,7 @@ void cpu_mips_store_compare (CPUState *env, uint32_t value)
cpu_mips_update_count(env, cpu_mips_get_count(env));
if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR))
env->CP0_Cause &= ~(1 << CP0Ca_TI);
- cpu_mips_irq_request(env, 7, 0);
+ qemu_irq_lower(env->irq[7]);
}
static void mips_timer_cb (void *opaque)
@@ -79,7 +79,7 @@ static void mips_timer_cb (void *opaque)
cpu_mips_update_count(env, cpu_mips_get_count(env));
if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR))
env->CP0_Cause |= 1 << CP0Ca_TI;
- cpu_mips_irq_request(env, 7, 1);
+ qemu_irq_raise(env->irq[7]);
}
void cpu_mips_clock_init (CPUState *env)
diff --git a/hw/ne2000.c b/hw/ne2000.c
index df3f3b54a2..1830ab5482 100644
--- a/hw/ne2000.c
+++ b/hw/ne2000.c
@@ -136,7 +136,7 @@ typedef struct NE2000State {
uint8_t phys[6]; /* mac address */
uint8_t curpag;
uint8_t mult[8]; /* multicast mask array */
- int irq;
+ qemu_irq irq;
PCIDevice *pci_dev;
VLANClientState *vc;
uint8_t macaddr[6];
@@ -164,16 +164,10 @@ static void ne2000_update_irq(NE2000State *s)
int isr;
isr = (s->isr & s->imr) & 0x7f;
#if defined(DEBUG_NE2000)
- printf("NE2000: Set IRQ line %d to %d (%02x %02x)\n",
- s->irq, isr ? 1 : 0, s->isr, s->imr);
+ printf("NE2000: Set IRQ to %d (%02x %02x)\n",
+ isr ? 1 : 0, s->isr, s->imr);
#endif
- if (s->irq == 16) {
- /* PCI irq */
- pci_set_irq(s->pci_dev, 0, (isr != 0));
- } else {
- /* ISA irq */
- pic_set_irq(s->irq, (isr != 0));
- }
+ qemu_set_irq(s->irq, (isr != 0));
}
#define POLYNOMIAL 0x04c11db6
@@ -647,6 +641,7 @@ static uint32_t ne2000_reset_ioport_read(void *opaque, uint32_t addr)
static void ne2000_save(QEMUFile* f,void* opaque)
{
NE2000State* s=(NE2000State*)opaque;
+ int tmp;
if (s->pci_dev)
pci_device_save(s->pci_dev, f);
@@ -669,7 +664,8 @@ static void ne2000_save(QEMUFile* f,void* opaque)
qemu_put_buffer(f, s->phys, 6);
qemu_put_8s(f, &s->curpag);
qemu_put_buffer(f, s->mult, 8);
- qemu_put_be32s(f, &s->irq);
+ tmp = 0;
+ qemu_put_be32s(f, &tmp); /* ignored, was irq */
qemu_put_buffer(f, s->mem, NE2000_MEM_SIZE);
}
@@ -677,6 +673,7 @@ static int ne2000_load(QEMUFile* f,void* opaque,int version_id)
{
NE2000State* s=(NE2000State*)opaque;
int ret;
+ int tmp;
if (version_id > 3)
return -EINVAL;
@@ -709,13 +706,13 @@ static int ne2000_load(QEMUFile* f,void* opaque,int version_id)
qemu_get_buffer(f, s->phys, 6);
qemu_get_8s(f, &s->curpag);
qemu_get_buffer(f, s->mult, 8);
- qemu_get_be32s(f, &s->irq);
+ qemu_get_be32s(f, &tmp); /* ignored */
qemu_get_buffer(f, s->mem, NE2000_MEM_SIZE);
return 0;
}
-void isa_ne2000_init(int base, int irq, NICInfo *nd)
+void isa_ne2000_init(int base, qemu_irq irq, NICInfo *nd)
{
NE2000State *s;
@@ -804,7 +801,7 @@ void pci_ne2000_init(PCIBus *bus, NICInfo *nd, int devfn)
pci_register_io_region(&d->dev, 0, 0x100,
PCI_ADDRESS_SPACE_IO, ne2000_map);
s = &d->ne2000;
- s->irq = 16; // PCI interrupt
+ s->irq = d->dev.irq[0];
s->pci_dev = (PCIDevice *)d;
memcpy(s->macaddr, nd->macaddr, 6);
ne2000_reset(s);
diff --git a/hw/openpic.c b/hw/openpic.c
index 1d91665114..3481f2d525 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -162,7 +162,7 @@ typedef struct IRQ_dst_t {
CPUState *env;
} IRQ_dst_t;
-struct openpic_t {
+typedef struct openpic_t {
PCIDevice pci_dev;
SetIRQFunc *set_irq;
int mem_index;
@@ -196,7 +196,7 @@ struct openpic_t {
uint32_t mbr; /* Mailbox register */
} mailboxes[MAX_MAILBOXES];
#endif
-};
+} openpic_t;
static inline void IRQ_setbit (IRQ_queue_t *q, int n_IRQ)
{
@@ -321,7 +321,7 @@ static void openpic_update_irq(openpic_t *opp, int n_IRQ)
}
}
-void openpic_set_irq(void *opaque, int n_IRQ, int level)
+static void openpic_set_irq(void *opaque, int n_IRQ, int level)
{
openpic_t *opp = opaque;
IRQ_src_t *src;
@@ -964,7 +964,7 @@ static void openpic_map(PCIDevice *pci_dev, int region_num,
#endif
}
-openpic_t *openpic_init (PCIBus *bus, SetIRQFunc *set_irq,
+qemu_irq *openpic_init (PCIBus *bus, SetIRQFunc *set_irq,
int *pmem_index, int nb_cpus, CPUState **envp)
{
openpic_t *opp;
@@ -1024,5 +1024,5 @@ openpic_t *openpic_init (PCIBus *bus, SetIRQFunc *set_irq,
openpic_reset(opp);
if (pmem_index)
*pmem_index = opp->mem_index;
- return opp;
+ return qemu_allocate_irqs(openpic_set_irq, opp, MAX_IRQ);
}
diff --git a/hw/parallel.c b/hw/parallel.c
index d751d7a3ae..c927ddd965 100644
--- a/hw/parallel.c
+++ b/hw/parallel.c
@@ -65,7 +65,7 @@ struct ParallelState {
uint8_t datar;
uint8_t status;
uint8_t control;
- int irq;
+ qemu_irq irq;
int irq_pending;
CharDriverState *chr;
int hw_driver;
@@ -76,9 +76,9 @@ struct ParallelState {
static void parallel_update_irq(ParallelState *s)
{
if (s->irq_pending)
- pic_set_irq(s->irq, 1);
+ qemu_irq_raise(s->irq);
else
- pic_set_irq(s->irq, 0);
+ qemu_irq_lower(s->irq);
}
static void
@@ -401,7 +401,7 @@ static uint32_t parallel_ioport_ecp_read(void *opaque, uint32_t addr)
}
/* If fd is zero, it means that the parallel device uses the console */
-ParallelState *parallel_init(int base, int irq, CharDriverState *chr)
+ParallelState *parallel_init(int base, qemu_irq irq, CharDriverState *chr)
{
ParallelState *s;
uint8_t dummy;
diff --git a/hw/pc.c b/hw/pc.c
index 332bb1c687..e8dca4de02 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -49,15 +49,16 @@ static void ioport80_write(void *opaque, uint32_t addr, uint32_t data)
}
/* MSDOS compatibility mode FPU exception support */
+static qemu_irq ferr_irq;
/* XXX: add IGNNE support */
void cpu_set_ferr(CPUX86State *s)
{
- pic_set_irq(13, 1);
+ qemu_irq_raise(ferr_irq);
}
static void ioportF0_write(void *opaque, uint32_t addr, uint32_t data)
{
- pic_set_irq(13, 0);
+ qemu_irq_lower(ferr_irq);
}
/* TSC handling */
@@ -101,7 +102,7 @@ int cpu_get_pic_interrupt(CPUState *env)
return intno;
}
-static void pic_irq_request(void *opaque, int level)
+static void pic_irq_request(void *opaque, int irq, int level)
{
CPUState *env = opaque;
if (level)
@@ -403,7 +404,7 @@ static int parallel_io[MAX_PARALLEL_PORTS] = { 0x378, 0x278, 0x3bc };
static int parallel_irq[MAX_PARALLEL_PORTS] = { 7, 7, 7 };
#ifdef HAS_AUDIO
-static void audio_init (PCIBus *pci_bus)
+static void audio_init (PCIBus *pci_bus, qemu_irq *pic)
{
struct soundhw *c;
int audio_enabled = 0;
@@ -420,7 +421,7 @@ static void audio_init (PCIBus *pci_bus)
for (c = soundhw; c->name; ++c) {
if (c->enabled) {
if (c->isa) {
- c->init.init_isa (s);
+ c->init.init_isa (s, pic);
}
else {
if (pci_bus) {
@@ -434,13 +435,13 @@ static void audio_init (PCIBus *pci_bus)
}
#endif
-static void pc_init_ne2k_isa(NICInfo *nd)
+static void pc_init_ne2k_isa(NICInfo *nd, qemu_irq *pic)
{
static int nb_ne2k = 0;
if (nb_ne2k == NE2000_NB_MAX)
return;
- isa_ne2000_init(ne2000_io[nb_ne2k], ne2000_irq[nb_ne2k], nd);
+ isa_ne2000_init(ne2000_io[nb_ne2k], pic[ne2000_irq[nb_ne2k]], nd);
nb_ne2k++;
}
@@ -460,6 +461,8 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
int piix3_devfn = -1;
CPUState *env;
NICInfo *nd;
+ qemu_irq *cpu_irq;
+ qemu_irq *i8259;
linux_boot = (kernel_filename != NULL);
@@ -643,8 +646,12 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
stw_raw(phys_ram_base + KERNEL_PARAMS_ADDR + 0x210, 0x01);
}
+ cpu_irq = qemu_allocate_irqs(pic_irq_request, first_cpu, 1);
+ i8259 = i8259_init(cpu_irq[0]);
+ ferr_irq = i8259[13];
+
if (pci_enabled) {
- pci_bus = i440fx_init(&i440fx_state);
+ pci_bus = i440fx_init(&i440fx_state, i8259);
piix3_devfn = piix3_init(pci_bus, -1);
} else {
pci_bus = NULL;
@@ -680,7 +687,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
}
}
- rtc_state = rtc_init(0x70, 8);
+ rtc_state = rtc_init(0x70, i8259[8]);
register_ioport_read(0x92, 1, 1, ioport92_read, NULL);
register_ioport_write(0x92, 1, 1, ioport92_write, NULL);
@@ -688,8 +695,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
if (pci_enabled) {
ioapic = ioapic_init();
}
- isa_pic = pic_init(pic_irq_request, first_cpu);
- pit = pit_init(0x40, 0);
+ pit = pit_init(0x40, i8259[0]);
pcspk_init(pit);
if (pci_enabled) {
pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic);
@@ -697,14 +703,14 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
if (serial_hds[i]) {
- serial_init(&pic_set_irq_new, isa_pic,
- serial_io[i], serial_irq[i], serial_hds[i]);
+ serial_init(serial_io[i], i8259[serial_irq[i]], serial_hds[i]);
}
}
for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
if (parallel_hds[i]) {
- parallel_init(parallel_io[i], parallel_irq[i], parallel_hds[i]);
+ parallel_init(parallel_io[i], i8259[parallel_irq[i]],
+ parallel_hds[i]);
}
}
@@ -718,7 +724,7 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
}
}
if (strcmp(nd->model, "ne2k_isa") == 0) {
- pc_init_ne2k_isa(nd);
+ pc_init_ne2k_isa(nd, i8259);
} else if (pci_enabled) {
pci_nic_init(pci_bus, nd, -1);
} else {
@@ -728,21 +734,21 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
}
if (pci_enabled) {
- pci_piix3_ide_init(pci_bus, bs_table, piix3_devfn + 1);
+ pci_piix3_ide_init(pci_bus, bs_table, piix3_devfn + 1, i8259);
} else {
for(i = 0; i < 2; i++) {
- isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
+ isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]],
bs_table[2 * i], bs_table[2 * i + 1]);
}
}
- kbd_init();
+ i8042_init(i8259[1], i8259[12], 0x60);
DMA_init(0);
#ifdef HAS_AUDIO
- audio_init(pci_enabled ? pci_bus : NULL);
+ audio_init(pci_enabled ? pci_bus : NULL, i8259);
#endif
- floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
+ floppy_controller = fdctrl_init(i8259[6], 2, 0, 0x3f0, fd_table);
cmos_init(ram_size, boot_device, bs_table);
diff --git a/hw/pci.c b/hw/pci.c
index 4d9eb03299..b5dcbdafd3 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -33,7 +33,7 @@ struct PCIBus {
uint32_t config_reg; /* XXX: suppress */
/* low level pic */
SetIRQFunc *low_set_irq;
- void *irq_opaque;
+ qemu_irq *irq_opaque;
PCIDevice *devices[256];
PCIDevice *parent_dev;
PCIBus *next;
@@ -43,13 +43,14 @@ struct PCIBus {
};
static void pci_update_mappings(PCIDevice *d);
+static void pci_set_irq(void *opaque, int irq_num, int level);
target_phys_addr_t pci_mem_base;
static int pci_irq_index;
static PCIBus *first_bus;
PCIBus *pci_register_bus(pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
- void *pic, int devfn_min, int nirq)
+ qemu_irq *pic, int devfn_min, int nirq)
{
PCIBus *bus;
bus = qemu_mallocz(sizeof(PCIBus) + (nirq * sizeof(int)));
@@ -129,6 +130,7 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
pci_dev->config_write = config_write;
pci_dev->irq_index = pci_irq_index++;
bus->devices[devfn] = pci_dev;
+ pci_dev->irq = qemu_allocate_irqs(pci_set_irq, pci_dev, 4);
return pci_dev;
}
@@ -433,8 +435,9 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
/* generic PCI irq support */
/* 0 <= irq_num <= 3. level must be 0 or 1 */
-void pci_set_irq(PCIDevice *pci_dev, int irq_num, int level)
+static void pci_set_irq(void *opaque, int irq_num, int level)
{
+ PCIDevice *pci_dev = (PCIDevice *)opaque;
PCIBus *bus;
int change;
diff --git a/hw/pckbd.c b/hw/pckbd.c
index 0ace3c0c9c..a6f9d09caf 100644
--- a/hw/pckbd.c
+++ b/hw/pckbd.c
@@ -122,8 +122,8 @@ typedef struct KBDState {
void *kbd;
void *mouse;
- int irq_kbd;
- int irq_mouse;
+ qemu_irq irq_kbd;
+ qemu_irq irq_mouse;
} KBDState;
KBDState kbd_state;
@@ -151,8 +151,8 @@ static void kbd_update_irq(KBDState *s)
irq_kbd_level = 1;
}
}
- pic_set_irq(s->irq_kbd, irq_kbd_level);
- pic_set_irq(s->irq_mouse, irq_mouse_level);
+ qemu_set_irq(s->irq_kbd, irq_kbd_level);
+ qemu_set_irq(s->irq_mouse, irq_mouse_level);
}
static void kbd_update_kbd_irq(void *opaque, int level)
@@ -356,12 +356,12 @@ static int kbd_load(QEMUFile* f, void* opaque, int version_id)
return 0;
}
-void i8042_init(int kbd_irq_lvl, int mouse_irq_lvl, uint32_t io_base)
+void i8042_init(qemu_irq kbd_irq, qemu_irq mouse_irq, uint32_t io_base)
{
KBDState *s = &kbd_state;
- s->irq_kbd = kbd_irq_lvl;
- s->irq_mouse = mouse_irq_lvl;
+ s->irq_kbd = kbd_irq;
+ s->irq_mouse = mouse_irq;
kbd_reset(s);
register_savevm("pckbd", 0, 3, kbd_save, kbd_load, s);
@@ -377,8 +377,3 @@ void i8042_init(int kbd_irq_lvl, int mouse_irq_lvl, uint32_t io_base)
#endif
qemu_register_reset(kbd_reset, s);
}
-
-void kbd_init(void)
-{
- return i8042_init(1, 12, 0x60);
-}
diff --git a/hw/pcnet.c b/hw/pcnet.c
index 71b8cf2a9b..f2130d7b40 100644
--- a/hw/pcnet.c
+++ b/hw/pcnet.c
@@ -69,7 +69,7 @@ struct PCNetState_st {
int xmit_pos, recv_pos;
uint8_t buffer[4096];
int tx_busy;
- void (*set_irq_cb)(void *s, int isr);
+ qemu_irq irq;
void (*phys_mem_read)(void *dma_opaque, target_phys_addr_t addr,
uint8_t *buf, int len, int do_bswap);
void (*phys_mem_write)(void *dma_opaque, target_phys_addr_t addr,
@@ -823,7 +823,7 @@ static void pcnet_update_irq(PCNetState *s)
printf("pcnet: INTA=%d\n", isr);
#endif
}
- s->set_irq_cb(s, isr);
+ qemu_set_irq(s->irq, isr);
s->isr = isr;
}
@@ -1940,13 +1940,6 @@ static void pcnet_mmio_map(PCIDevice *pci_dev, int region_num,
cpu_register_physical_memory(addr, PCNET_PNPMMIO_SIZE, d->mmio_index);
}
-static void pcnet_pci_set_irq_cb(void *opaque, int isr)
-{
- PCNetState *s = opaque;
-
- pci_set_irq(&s->dev, 0, isr);
-}
-
static void pci_physical_memory_write(void *dma_opaque, target_phys_addr_t addr,
uint8_t *buf, int len, int do_bswap)
{
@@ -2001,7 +1994,7 @@ void pci_pcnet_init(PCIBus *bus, NICInfo *nd, int devfn)
pci_register_io_region((PCIDevice *)d, 1, PCNET_PNPMMIO_SIZE,
PCI_ADDRESS_SPACE_MEM, pcnet_mmio_map);
- d->set_irq_cb = pcnet_pci_set_irq_cb;
+ d->irq = d->dev.irq[0];
d->phys_mem_read = pci_physical_memory_read;
d->phys_mem_write = pci_physical_memory_write;
d->pci_dev = &d->dev;
@@ -2025,14 +2018,7 @@ static CPUWriteMemoryFunc *lance_mem_write[3] = {
(CPUWriteMemoryFunc *)&pcnet_ioport_writew,
};
-static void pcnet_sparc_set_irq_cb(void *opaque, int isr)
-{
- PCNetState *s = opaque;
-
- ledma_set_irq(s->dma_opaque, isr);
-}
-
-void *lance_init(NICInfo *nd, uint32_t leaddr, void *dma_opaque)
+void *lance_init(NICInfo *nd, uint32_t leaddr, void *dma_opaque, qemu_irq irq)
{
PCNetState *d;
int lance_io_memory;
@@ -2047,7 +2033,7 @@ void *lance_init(NICInfo *nd, uint32_t leaddr, void *dma_opaque)
d->dma_opaque = dma_opaque;
cpu_register_physical_memory(leaddr, 4, lance_io_memory);
- d->set_irq_cb = pcnet_sparc_set_irq_cb;
+ d->irq = irq;
d->phys_mem_read = ledma_memory_read;
d->phys_mem_write = ledma_memory_write;
diff --git a/hw/pcspk.c b/hw/pcspk.c
index 0d52b31b45..2cbeff3771 100644
--- a/hw/pcspk.c
+++ b/hw/pcspk.c
@@ -92,7 +92,7 @@ static void pcspk_callback(void *opaque, int free)
}
}
-int pcspk_audio_init(AudioState *audio)
+int pcspk_audio_init(AudioState *audio, qemu_irq *pic)
{
PCSpkState *s = &pcspk_state;
audsettings_t as = {PCSPK_SAMPLE_RATE, 1, AUD_FMT_U8, 0};
diff --git a/hw/piix_pci.c b/hw/piix_pci.c
index 1b16652bc0..095698c9de 100644
--- a/hw/piix_pci.c
+++ b/hw/piix_pci.c
@@ -40,7 +40,7 @@ static uint32_t i440fx_addr_readl(void* opaque, uint32_t addr)
return s->config_reg;
}
-static void piix3_set_irq(void *pic, int irq_num, int level);
+static void piix3_set_irq(qemu_irq *pic, int irq_num, int level);
/* return the global irq number corresponding to a given device irq
pin. We could also use the bus number to have a more precise
@@ -155,14 +155,14 @@ static int i440fx_load(QEMUFile* f, void *opaque, int version_id)
return 0;
}
-PCIBus *i440fx_init(PCIDevice **pi440fx_state)
+PCIBus *i440fx_init(PCIDevice **pi440fx_state, qemu_irq *pic)
{
PCIBus *b;
PCIDevice *d;
I440FXState *s;
s = qemu_mallocz(sizeof(I440FXState));
- b = pci_register_bus(piix3_set_irq, pci_slot_get_pirq, NULL, 0, 4);
+ b = pci_register_bus(piix3_set_irq, pci_slot_get_pirq, pic, 0, 4);
s->bus = b;
register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s);
@@ -204,7 +204,7 @@ PCIDevice *piix4_dev;
static int pci_irq_levels[4];
-static void piix3_set_irq(void *pic, int irq_num, int level)
+static void piix3_set_irq(qemu_irq *pic, int irq_num, int level)
{
int i, pic_irq, pic_level;
@@ -221,7 +221,7 @@ static void piix3_set_irq(void *pic, int irq_num, int level)
if (pic_irq == piix3_dev->config[0x60 + i])
pic_level |= pci_irq_levels[i];
}
- pic_set_irq(pic_irq, pic_level);
+ qemu_set_irq(pic[pic_irq], pic_level);
}
}
diff --git a/hw/pl011.c b/hw/pl011.c
index fb7ab7b53d..29e551ad8b 100644
--- a/hw/pl011.c
+++ b/hw/pl011.c
@@ -27,8 +27,7 @@ typedef struct {
int read_count;
int read_trigger;
CharDriverState *chr;
- void *pic;
- int irq;
+ qemu_irq irq;
} pl011_state;
#define PL011_INT_TX 0x20
@@ -47,7 +46,7 @@ static void pl011_update(pl011_state *s)
uint32_t flags;
flags = s->int_level & s->int_enabled;
- pic_set_irq_new(s->pic, s->irq, flags != 0);
+ qemu_set_irq(s->irq, flags != 0);
}
static uint32_t pl011_read(void *opaque, target_phys_addr_t offset)
@@ -224,7 +223,7 @@ static CPUWriteMemoryFunc *pl011_writefn[] = {
pl011_write
};
-void pl011_init(uint32_t base, void *pic, int irq,
+void pl011_init(uint32_t base, qemu_irq irq,
CharDriverState *chr)
{
int iomemtype;
@@ -235,7 +234,6 @@ void pl011_init(uint32_t base, void *pic, int irq,
pl011_writefn, s);
cpu_register_physical_memory(base, 0x00000fff, iomemtype);
s->base = base;
- s->pic = pic;
s->irq = irq;
s->chr = chr;
s->read_trigger = 1;
diff --git a/hw/pl050.c b/hw/pl050.c
index 20451e532e..eed729461e 100644
--- a/hw/pl050.c
+++ b/hw/pl050.c
@@ -15,9 +15,8 @@ typedef struct {
uint32_t cr;
uint32_t clk;
uint32_t last;
- void *pic;
int pending;
- int irq;
+ qemu_irq irq;
int is_mouse;
} pl050_state;
@@ -32,7 +31,7 @@ static void pl050_update(void *opaque, int level)
s->pending = level;
raise = (s->pending && (s->cr & 0x10) != 0)
|| (s->cr & 0x08) != 0;
- pic_set_irq_new(s->pic, s->irq, raise);
+ qemu_set_irq(s->irq, raise);
}
static uint32_t pl050_read(void *opaque, target_phys_addr_t offset)
@@ -105,7 +104,7 @@ static CPUWriteMemoryFunc *pl050_writefn[] = {
pl050_write
};
-void pl050_init(uint32_t base, void *pic, int irq, int is_mouse)
+void pl050_init(uint32_t base, qemu_irq irq, int is_mouse)
{
int iomemtype;
pl050_state *s;
@@ -115,7 +114,6 @@ void pl050_init(uint32_t base, void *pic, int irq, int is_mouse)
pl050_writefn, s);
cpu_register_physical_memory(base, 0x00000fff, iomemtype);
s->base = base;
- s->pic = pic;
s->irq = irq;
s->is_mouse = is_mouse;
if (is_mouse)
diff --git a/hw/pl080.c b/hw/pl080.c
index 549b3bfd10..aab1cacb9a 100644
--- a/hw/pl080.c
+++ b/hw/pl080.c
@@ -49,8 +49,7 @@ typedef struct {
int nchannels;
/* Flag to avoid recursive DMA invocations. */
int running;
- void *pic;
- int irq;
+ qemu_irq irq;
} pl080_state;
static const unsigned char pl080_id[] =
@@ -63,9 +62,9 @@ static void pl080_update(pl080_state *s)
{
if ((s->tc_int & s->tc_mask)
|| (s->err_int & s->err_mask))
- pic_set_irq_new(s->pic, s->irq, 1);
+ qemu_irq_raise(s->irq);
else
- pic_set_irq_new(s->pic, s->irq, 1);
+ qemu_irq_lower(s->irq);
}
static void pl080_run(pl080_state *s)
@@ -325,7 +324,7 @@ static CPUWriteMemoryFunc *pl080_writefn[] = {
/* The PL080 and PL081 are the same except for the number of channels
they implement (8 and 2 respectively). */
-void *pl080_init(uint32_t base, void *pic, int irq, int nchannels)
+void *pl080_init(uint32_t base, qemu_irq irq, int nchannels)
{
int iomemtype;
pl080_state *s;
@@ -335,7 +334,6 @@ void *pl080_init(uint32_t base, void *pic, int irq, int nchannels)
pl080_writefn, s);
cpu_register_physical_memory(base, 0x00000fff, iomemtype);
s->base = base;
- s->pic = pic;
s->irq = irq;
s->nchannels = nchannels;
/* ??? Save/restore. */
diff --git a/hw/pl110.c b/hw/pl110.c
index 16de16c0dd..92a7e0bb6a 100644
--- a/hw/pl110.c
+++ b/hw/pl110.c
@@ -29,7 +29,6 @@ typedef struct {
DisplayState *ds;
/* The Versatile/PB uses a slightly modified PL110 controller. */
int versatile;
- void *pic;
uint32_t timing[4];
uint32_t cr;
uint32_t upbase;
@@ -42,7 +41,7 @@ typedef struct {
int invalidate;
uint32_t pallette[256];
uint32_t raw_pallette[128];
- int irq;
+ qemu_irq irq;
} pl110_state;
static const unsigned char pl110_id[] =
@@ -399,7 +398,7 @@ static CPUWriteMemoryFunc *pl110_writefn[] = {
pl110_write
};
-void *pl110_init(DisplayState *ds, uint32_t base, void *pic, int irq,
+void *pl110_init(DisplayState *ds, uint32_t base, qemu_irq irq,
int versatile)
{
pl110_state *s;
@@ -412,7 +411,6 @@ void *pl110_init(DisplayState *ds, uint32_t base, void *pic, int irq,
s->base = base;
s->ds = ds;
s->versatile = versatile;
- s->pic = pic;
s->irq = irq;
graphic_console_init(ds, pl110_update_display, pl110_invalidate_display,
NULL, s);
diff --git a/hw/pl181.c b/hw/pl181.c
index 7c3b5de4c6..cf731cce99 100644
--- a/hw/pl181.c
+++ b/hw/pl181.c
@@ -40,8 +40,7 @@ typedef struct {
int fifo_pos;
int fifo_len;
uint32_t fifo[PL181_FIFO_LEN];
- void *pic;
- int irq[2];
+ qemu_irq irq[2];
} pl181_state;
#define PL181_CMD_INDEX 0x3f
@@ -96,7 +95,7 @@ static void pl181_update(pl181_state *s)
{
int i;
for (i = 0; i < 2; i++) {
- pic_set_irq_new(s->pic, s->irq[i], (s->status & s->mask[i]) != 0);
+ qemu_set_irq(s->irq[i], (s->status & s->mask[i]) != 0);
}
}
@@ -425,7 +424,7 @@ static void pl181_reset(void *opaque)
}
void pl181_init(uint32_t base, BlockDriverState *bd,
- void *pic, int irq0, int irq1)
+ qemu_irq irq0, qemu_irq irq1)
{
int iomemtype;
pl181_state *s;
@@ -436,7 +435,6 @@ void pl181_init(uint32_t base, BlockDriverState *bd,
cpu_register_physical_memory(base, 0x00000fff, iomemtype);
s->base = base;
s->card = sd_init(bd);
- s->pic = pic;
s->irq[0] = irq0;
s->irq[1] = irq1;
qemu_register_reset(pl181_reset, s);
diff --git a/hw/pl190.c b/hw/pl190.c
index 55c7180f5a..12d935f8ae 100644
--- a/hw/pl190.c
+++ b/hw/pl190.c
@@ -17,7 +17,6 @@
#define PL190_NUM_PRIO 17
typedef struct {
- arm_pic_handler handler;
uint32_t base;
DisplayState *ds;
uint32_t level;
@@ -33,9 +32,8 @@ typedef struct {
/* Current priority level. */
int priority;
int prev_prio[PL190_NUM_PRIO];
- void *parent;
- int irq;
- int fiq;
+ qemu_irq irq;
+ qemu_irq fiq;
} pl190_state;
static const unsigned char pl190_id[] =
@@ -53,9 +51,9 @@ static void pl190_update(pl190_state *s)
int set;
set = (level & s->prio_mask[s->priority]) != 0;
- pic_set_irq_new(s->parent, s->irq, set);
+ qemu_set_irq(s->irq, set);
set = ((s->level | s->soft_level) & s->fiq_select) != 0;
- pic_set_irq_new(s->parent, s->fiq, set);
+ qemu_set_irq(s->fiq, set);
}
static void pl190_set_irq(void *opaque, int irq, int level)
@@ -232,21 +230,21 @@ void pl190_reset(pl190_state *s)
pl190_update_vectors(s);
}
-void *pl190_init(uint32_t base, void *parent, int irq, int fiq)
+qemu_irq *pl190_init(uint32_t base, qemu_irq irq, qemu_irq fiq)
{
pl190_state *s;
+ qemu_irq *qi;
int iomemtype;
s = (pl190_state *)qemu_mallocz(sizeof(pl190_state));
iomemtype = cpu_register_io_memory(0, pl190_readfn,
pl190_writefn, s);
cpu_register_physical_memory(base, 0x00000fff, iomemtype);
- s->handler = pl190_set_irq;
+ qi = qemu_allocate_irqs(pl190_set_irq, s, 16);
s->base = base;
- s->parent = parent;
s->irq = irq;
s->fiq = fiq;
pl190_reset(s);
/* ??? Save/restore. */
- return s;
+ return qi;
}
diff --git a/hw/ppc.c b/hw/ppc.c
index 273c75f026..44555bd634 100644
--- a/hw/ppc.c
+++ b/hw/ppc.c
@@ -31,8 +31,7 @@ extern int loglevel;
/* PowerPC internal fake IRQ controller
* used to manage multiple sources hardware events
*/
-/* XXX: should be protected */
-void ppc_set_irq (void *opaque, int n_IRQ, int level)
+static void ppc_set_irq (void *opaque, int n_IRQ, int level)
{
CPUState *env;
@@ -51,6 +50,17 @@ void ppc_set_irq (void *opaque, int n_IRQ, int level)
#endif
}
+void cpu_ppc_irq_init_cpu(CPUState *env)
+{
+ qemu_irq *qi;
+ int i;
+
+ qi = qemu_allocate_irqs(ppc_set_irq, env, 32);
+ for (i = 0; i < 32; i++) {
+ env->irq[i] = qi[i];
+ }
+}
+
/* External IRQ callback from OpenPIC IRQ controller */
void ppc_openpic_irq (void *opaque, int n_IRQ, int level)
{
diff --git a/hw/ppc_chrp.c b/hw/ppc_chrp.c
index 55ca6ac532..18a1aab2b5 100644
--- a/hw/ppc_chrp.c
+++ b/hw/ppc_chrp.c
@@ -264,11 +264,6 @@ static int vga_osi_call(CPUState *env)
return 1; /* osi_call handled */
}
-/* XXX: suppress that */
-static void pic_irq_request(void *opaque, int level)
-{
-}
-
static uint8_t nvram_chksum(const uint8_t *buf, int n)
{
int sum, i;
@@ -303,8 +298,7 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
{
CPUState *env;
char buf[1024];
- SetIRQFunc *set_irq;
- void *pic;
+ qemu_irq *pic;
m48t59_t *nvram;
int unin_memory;
int linux_boot, i;
@@ -314,6 +308,7 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
PCIBus *pci_bus;
const char *arch_name;
int vga_bios_size, bios_size;
+ qemu_irq *dummy_irq;
linux_boot = (kernel_filename != NULL);
@@ -335,6 +330,7 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
cpu_abort(env, "Unable to find PowerPC CPU definition\n");
}
cpu_ppc_register(env, def);
+ cpu_ppc_irq_init_cpu(env);
/* Set time-base frequency to 100 Mhz */
cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
@@ -416,17 +412,16 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
/* init basic PC hardware */
pic = heathrow_pic_init(&heathrow_pic_mem_index);
- set_irq = heathrow_pic_set_irq;
pci_bus = pci_grackle_init(0xfec00000, pic);
pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,
ram_size, vga_ram_size,
vga_bios_offset, vga_bios_size);
/* XXX: suppress that */
- isa_pic = pic_init(pic_irq_request, NULL);
+ dummy_irq = i8259_init(NULL);
/* XXX: use Mac Serial port */
- serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
+ serial_init(0x3f8, dummy_irq[4], serial_hds[0]);
for(i = 0; i < nb_nics; i++) {
if (!nd_table[i].model)
@@ -437,7 +432,7 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
pci_cmd646_ide_init(pci_bus, &bs_table[0], 0);
/* cuda also initialize ADB */
- cuda_mem_index = cuda_init(set_irq, pic, 0x12);
+ cuda_mem_index = cuda_init(pic[0x12]);
adb_kbd_init(&adb_bus);
adb_mouse_init(&adb_bus);
@@ -450,7 +445,7 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
macio_init(pci_bus, 0x0017);
- nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
+ nvram = m48t59_init(dummy_irq[8], 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
arch_name = "HEATHROW";
} else {
@@ -464,7 +459,6 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
cpu_register_physical_memory(0xf8000000, 0x00001000, unin_memory);
pic = openpic_init(NULL, &ppc_openpic_irq, &openpic_mem_index, 1, &env);
- set_irq = openpic_set_irq;
pci_bus = pci_pmac_init(pic);
/* init basic PC hardware */
pci_vga_init(pci_bus, ds, phys_ram_base + ram_size,
@@ -472,30 +466,30 @@ static void ppc_chrp_init (int ram_size, int vga_ram_size, int boot_device,
vga_bios_offset, vga_bios_size);
/* XXX: suppress that */
- isa_pic = pic_init(pic_irq_request, NULL);
+ dummy_irq = i8259_init(NULL);
/* XXX: use Mac Serial port */
- serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
+ serial_init(0x3f8, dummy_irq[4], serial_hds[0]);
for(i = 0; i < nb_nics; i++) {
if (!nd_table[i].model)
nd_table[i].model = "ne2k_pci";
pci_nic_init(pci_bus, &nd_table[i], -1);
}
#if 1
- ide0_mem_index = pmac_ide_init(&bs_table[0], set_irq, pic, 0x13);
- ide1_mem_index = pmac_ide_init(&bs_table[2], set_irq, pic, 0x14);
+ ide0_mem_index = pmac_ide_init(&bs_table[0], pic[0x13]);
+ ide1_mem_index = pmac_ide_init(&bs_table[2], pic[0x14]);
#else
pci_cmd646_ide_init(pci_bus, &bs_table[0], 0);
#endif
/* cuda also initialize ADB */
- cuda_mem_index = cuda_init(set_irq, pic, 0x19);
+ cuda_mem_index = cuda_init(pic[0x19]);
adb_kbd_init(&adb_bus);
adb_mouse_init(&adb_bus);
macio_init(pci_bus, 0x0022);
- nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
+ nvram = m48t59_init(dummy_irq[8], 0xFFF04000, 0x0074, NVRAM_SIZE, 59);
arch_name = "MAC99";
}
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index d504b1c6d8..225b531685 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -96,11 +96,6 @@ static uint32_t speaker_ioport_read (void *opaque, uint32_t addr)
return 0;
}
-static void pic_irq_request (void *opaque, int level)
-{
- ppc_set_irq(opaque, PPC_INTERRUPT_EXT, level);
-}
-
/* PCI intack register */
/* Read-only register (?) */
static void _PPC_intack_write (void *opaque,
@@ -532,6 +527,7 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
ppc_def_t *def;
PCIBus *pci_bus;
+ qemu_irq *i8259;
sysctrl = qemu_mallocz(sizeof(sysctrl_t));
if (sysctrl == NULL)
@@ -552,6 +548,7 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
cpu_abort(env, "Unable to find PowerPC CPU definition\n");
}
cpu_ppc_register(env, def);
+ cpu_ppc_irq_init_cpu(env);
/* Set time-base frequency to 100 Mhz */
cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
@@ -602,7 +599,8 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
}
isa_mem_base = 0xc0000000;
- pci_bus = pci_prep_init();
+ i8259 = i8259_init(first_cpu->irq[PPC_INTERRUPT_EXT]);
+ pci_bus = pci_prep_init(i8259);
// pci_bus = i440fx_init();
/* Register 8 MB of ISA IO space (needed for non-contiguous map) */
PPC_io_memory = cpu_register_io_memory(0, PPC_prep_io_read,
@@ -612,19 +610,18 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
/* init basic PC hardware */
pci_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size,
vga_ram_size, 0, 0);
- rtc_init(0x70, 8);
// openpic = openpic_init(0x00000000, 0xF0000000, 1);
- isa_pic = pic_init(pic_irq_request, first_cpu);
- // pit = pit_init(0x40, 0);
+ // pit = pit_init(0x40, i8259[0]);
+ rtc_init(0x70, i8259[8]);
- serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
+ serial_init(0x3f8, i8259[4], serial_hds[0]);
nb_nics1 = nb_nics;
if (nb_nics1 > NE2000_NB_MAX)
nb_nics1 = NE2000_NB_MAX;
for(i = 0; i < nb_nics1; i++) {
if (nd_table[0].model == NULL
|| strcmp(nd_table[0].model, "ne2k_isa") == 0) {
- isa_ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
+ isa_ne2000_init(ne2000_io[i], i8259[ne2000_irq[i]], &nd_table[i]);
} else {
fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
exit (1);
@@ -632,15 +629,15 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
}
for(i = 0; i < 2; i++) {
- isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
+ isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]],
bs_table[2 * i], bs_table[2 * i + 1]);
}
- kbd_init();
+ i8042_init(i8259[1], i8259[12], 0x60);
DMA_init(1);
// AUD_init();
// SB16_init();
- fdctrl_init(6, 2, 0, 0x3f0, fd_table);
+ fdctrl_init(i8259[6], 2, 0, 0x3f0, fd_table);
/* Register speaker port */
register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
@@ -667,7 +664,7 @@ static void ppc_prep_init (int ram_size, int vga_ram_size, int boot_device,
usb_ohci_init_pci(pci_bus, 3, -1);
}
- nvram = m48t59_init(8, 0, 0x0074, NVRAM_SIZE, 59);
+ nvram = m48t59_init(i8259[8], 0, 0x0074, NVRAM_SIZE, 59);
if (nvram == NULL)
return;
sysctrl->nvram = nvram;
diff --git a/hw/prep_pci.c b/hw/prep_pci.c
index 3d93c065ff..be62b8953b 100644
--- a/hw/prep_pci.c
+++ b/hw/prep_pci.c
@@ -123,19 +123,19 @@ static int prep_map_irq(PCIDevice *pci_dev, int irq_num)
return (irq_num + (pci_dev->devfn >> 3)) & 1;
}
-static void prep_set_irq(void *pic, int irq_num, int level)
+static void prep_set_irq(qemu_irq *pic, int irq_num, int level)
{
- pic_set_irq(irq_num ? 11 : 9, level);
+ qemu_set_irq(pic[irq_num ? 11 : 9], level);
}
-PCIBus *pci_prep_init(void)
+PCIBus *pci_prep_init(qemu_irq *pic)
{
PREPPCIState *s;
PCIDevice *d;
int PPC_io_memory;
s = qemu_mallocz(sizeof(PREPPCIState));
- s->bus = pci_register_bus(prep_set_irq, prep_map_irq, NULL, 0, 2);
+ s->bus = pci_register_bus(prep_set_irq, prep_map_irq, pic, 0, 2);
register_ioport_write(0xcf8, 4, 4, pci_prep_addr_writel, s);
register_ioport_read(0xcf8, 4, 4, pci_prep_addr_readl, s);
diff --git a/hw/realview.c b/hw/realview.c
index 1d351bf2b5..c15c231528 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -18,7 +18,7 @@ static void realview_init(int ram_size, int vga_ram_size, int boot_device,
const char *initrd_filename, const char *cpu_model)
{
CPUState *env;
- void *pic;
+ qemu_irq *pic;
void *scsi_hba;
PCIBus *pci_bus;
NICInfo *nd;
@@ -38,24 +38,24 @@ static void realview_init(int ram_size, int vga_ram_size, int boot_device,
/* ??? The documentation says GIC1 is nFIQ and either GIC2 or GIC3
is nIRQ (there are inconsistencies). However Linux 2.6.17 expects
GIC1 to be nIRQ and ignores all the others, so do that for now. */
- pic = arm_gic_init(0x10040000, pic, ARM_PIC_CPU_IRQ);
- pl050_init(0x10006000, pic, 20, 0);
- pl050_init(0x10007000, pic, 21, 1);
+ pic = arm_gic_init(0x10040000, pic[ARM_PIC_CPU_IRQ]);
+ pl050_init(0x10006000, pic[20], 0);
+ pl050_init(0x10007000, pic[21], 1);
- pl011_init(0x10009000, pic, 12, serial_hds[0]);
- pl011_init(0x1000a000, pic, 13, serial_hds[1]);
- pl011_init(0x1000b000, pic, 14, serial_hds[2]);
- pl011_init(0x1000c000, pic, 15, serial_hds[3]);
+ pl011_init(0x10009000, pic[12], serial_hds[0]);
+ pl011_init(0x1000a000, pic[13], serial_hds[1]);
+ pl011_init(0x1000b000, pic[14], serial_hds[2]);
+ pl011_init(0x1000c000, pic[15], serial_hds[3]);
/* DMA controller is optional, apparently. */
- pl080_init(0x10030000, pic, 24, 2);
+ pl080_init(0x10030000, pic[24], 2);
- sp804_init(0x10011000, pic, 4);
- sp804_init(0x10012000, pic, 5);
+ sp804_init(0x10011000, pic[4]);
+ sp804_init(0x10012000, pic[5]);
- pl110_init(ds, 0x10020000, pic, 23, 1);
+ pl110_init(ds, 0x10020000, pic[23], 1);
- pl181_init(0x10005000, sd_bdrv, pic, 17, 18);
+ pl181_init(0x10005000, sd_bdrv, pic[17], pic[18]);
pci_bus = pci_vpb_init(pic, 48, 1);
if (usb_enabled) {
@@ -72,7 +72,7 @@ static void realview_init(int ram_size, int vga_ram_size, int boot_device,
if (!nd->model)
nd->model = done_smc ? "rtl8139" : "smc91c111";
if (strcmp(nd->model, "smc91c111") == 0) {
- smc91c111_init(nd, 0x4e000000, pic, 28);
+ smc91c111_init(nd, 0x4e000000, pic[28]);
} else {
pci_nic_init(pci_bus, nd, -1);
}
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index ee5b9f5e32..d1e60e8294 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -687,7 +687,7 @@ static void rtl8139_update_irq(RTL8139State *s)
DEBUG_PRINT(("RTL8139: Set IRQ to %d (%04x %04x)\n",
isr ? 1 : 0, s->IntrStatus, s->IntrMask));
- pci_set_irq(s->pci_dev, 0, (isr != 0));
+ qemu_set_irq(s->pci_dev->irq[0], (isr != 0));
}
#define POLYNOMIAL 0x04c11db6
diff --git a/hw/sb16.c b/hw/sb16.c
index 04325ac031..1610b3288b 100644
--- a/hw/sb16.c
+++ b/hw/sb16.c
@@ -54,6 +54,7 @@ static struct {
typedef struct SB16State {
QEMUSoundCard card;
+ qemu_irq *pic;
int irq;
int dma;
int hdma;
@@ -187,7 +188,7 @@ static void aux_timer (void *opaque)
{
SB16State *s = opaque;
s->can_write = 1;
- pic_set_irq (s->irq, 1);
+ qemu_irq_raise (s->pic[s->irq]);
}
#define DMA8_AUTO 1
@@ -595,7 +596,7 @@ static void command (SB16State *s, uint8_t cmd)
case 0xf3:
dsp_out_data (s, 0xaa);
s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
- pic_set_irq (s->irq, 1);
+ qemu_irq_raise (s->pic[s->irq]);
break;
case 0xf9:
@@ -763,7 +764,7 @@ static void complete (SB16State *s)
bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
ticks = (bytes * ticks_per_sec) / freq;
if (ticks < ticks_per_sec / 1024) {
- pic_set_irq (s->irq, 1);
+ qemu_irq_raise (s->pic[s->irq]);
}
else {
if (s->aux_ts) {
@@ -855,10 +856,10 @@ static void legacy_reset (SB16State *s)
static void reset (SB16State *s)
{
- pic_set_irq (s->irq, 0);
+ qemu_irq_lower (s->pic[s->irq]);
if (s->dma_auto) {
- pic_set_irq (s->irq, 1);
- pic_set_irq (s->irq, 0);
+ qemu_irq_raise (s->pic[s->irq]);
+ qemu_irq_lower (s->pic[s->irq]);
}
s->mixer_regs[0x82] = 0;
@@ -894,7 +895,7 @@ static IO_WRITE_PROTO (dsp_write)
if (s->v2x6 == 1) {
if (0 && s->highspeed) {
s->highspeed = 0;
- pic_set_irq (s->irq, 0);
+ qemu_irq_lower (s->pic[s->irq]);
control (s, 0);
}
else {
@@ -1005,7 +1006,7 @@ static IO_READ_PROTO (dsp_read)
if (s->mixer_regs[0x82] & 1) {
ack = 1;
s->mixer_regs[0x82] &= 1;
- pic_set_irq (s->irq, 0);
+ qemu_irq_lower (s->pic[s->irq]);
}
break;
@@ -1014,7 +1015,7 @@ static IO_READ_PROTO (dsp_read)
if (s->mixer_regs[0x82] & 2) {
ack = 1;
s->mixer_regs[0x82] &= 2;
- pic_set_irq (s->irq, 0);
+ qemu_irq_lower (s->pic[s->irq]);
}
break;
@@ -1222,7 +1223,7 @@ static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
if (s->left_till_irq <= 0) {
s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
- pic_set_irq (s->irq, 1);
+ qemu_irq_raise (s->pic[s->irq]);
if (0 == s->dma_auto) {
control (s, 0);
speaker (s, 0);
@@ -1389,7 +1390,7 @@ static int SB_load (QEMUFile *f, void *opaque, int version_id)
return 0;
}
-int SB16_init (AudioState *audio)
+int SB16_init (AudioState *audio, qemu_irq *pic)
{
SB16State *s;
int i;
@@ -1409,6 +1410,7 @@ int SB16_init (AudioState *audio)
}
s->cmd = -1;
+ s->pic = pic;
s->irq = conf.irq;
s->dma = conf.dma;
s->hdma = conf.hdma;
diff --git a/hw/serial.c b/hw/serial.c
index ed2a857008..e0ff3a72c0 100644
--- a/hw/serial.c
+++ b/hw/serial.c
@@ -83,9 +83,7 @@ struct SerialState {
/* NOTE: this hidden state is necessary for tx irq generation as
it can be reset while reading iir */
int thr_ipending;
- SetIRQFunc *set_irq;
- void *irq_opaque;
- int irq;
+ qemu_irq irq;
CharDriverState *chr;
int last_break_enable;
target_ulong base;
@@ -102,9 +100,9 @@ static void serial_update_irq(SerialState *s)
s->iir = UART_IIR_NO_INT;
}
if (s->iir != UART_IIR_NO_INT) {
- s->set_irq(s->irq_opaque, s->irq, 1);
+ qemu_irq_raise(s->irq);
} else {
- s->set_irq(s->irq_opaque, s->irq, 0);
+ qemu_irq_lower(s->irq);
}
}
@@ -345,16 +343,13 @@ static int serial_load(QEMUFile *f, void *opaque, int version_id)
}
/* If fd is zero, it means that the serial device uses the console */
-SerialState *serial_init(SetIRQFunc *set_irq, void *opaque,
- int base, int irq, CharDriverState *chr)
+SerialState *serial_init(int base, qemu_irq irq, CharDriverState *chr)
{
SerialState *s;
s = qemu_mallocz(sizeof(SerialState));
if (!s)
return NULL;
- s->set_irq = set_irq;
- s->irq_opaque = opaque;
s->irq = irq;
s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
s->iir = UART_IIR_NO_INT;
@@ -428,9 +423,8 @@ static CPUWriteMemoryFunc *serial_mm_write[] = {
&serial_mm_writel,
};
-SerialState *serial_mm_init (SetIRQFunc *set_irq, void *opaque,
- target_ulong base, int it_shift,
- int irq, CharDriverState *chr,
+SerialState *serial_mm_init (target_ulong base, int it_shift,
+ qemu_irq irq, CharDriverState *chr,
int ioregister)
{
SerialState *s;
@@ -439,8 +433,6 @@ SerialState *serial_mm_init (SetIRQFunc *set_irq, void *opaque,
s = qemu_mallocz(sizeof(SerialState));
if (!s)
return NULL;
- s->set_irq = set_irq;
- s->irq_opaque = opaque;
s->irq = irq;
s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
s->iir = UART_IIR_NO_INT;
diff --git a/hw/shix.c b/hw/shix.c
index 5857d0e06b..000fd6af4d 100644
--- a/hw/shix.c
+++ b/hw/shix.c
@@ -42,11 +42,6 @@ void irq_info(void)
/* XXXXX */
}
-void pic_set_irq(int irq, int level)
-{
- /* XXXXX */
-}
-
void pic_info()
{
/* XXXXX */
diff --git a/hw/slavio_intctl.c b/hw/slavio_intctl.c
index ed145a3e14..0c1eb58359 100644
--- a/hw/slavio_intctl.c
+++ b/hw/slavio_intctl.c
@@ -277,7 +277,7 @@ static void slavio_check_interrupts(void *opaque)
* "irq" here is the bit number in the system interrupt register to
* separate serial and keyboard interrupts sharing a level.
*/
-void pic_set_irq_new(void *opaque, int irq, int level)
+void slavio_set_irq(void *opaque, int irq, int level)
{
SLAVIO_INTCTLState *s = opaque;
@@ -305,7 +305,7 @@ void pic_set_irq_cpu(void *opaque, int irq, int level, unsigned int cpu)
DPRINTF("Set cpu %d local irq %d level %d\n", cpu, irq, level);
if (cpu == (unsigned int)-1) {
- pic_set_irq_new(opaque, irq, level);
+ slavio_set_irq(opaque, irq, level);
return;
}
if (irq < 32) {
@@ -372,7 +372,8 @@ void slavio_intctl_set_cpu(void *opaque, unsigned int cpu, CPUState *env)
}
void *slavio_intctl_init(uint32_t addr, uint32_t addrg,
- const uint32_t *intbit_to_level)
+ const uint32_t *intbit_to_level,
+ qemu_irq **irq)
{
int slavio_intctl_io_memory, slavio_intctlm_io_memory, i;
SLAVIO_INTCTLState *s;
@@ -392,6 +393,7 @@ void *slavio_intctl_init(uint32_t addr, uint32_t addrg,
register_savevm("slavio_intctl", addr, 1, slavio_intctl_save, slavio_intctl_load, s);
qemu_register_reset(slavio_intctl_reset, s);
+ *irq = qemu_allocate_irqs(slavio_set_irq, s, 32);
slavio_intctl_reset(s);
return s;
}
diff --git a/hw/slavio_misc.c b/hw/slavio_misc.c
index 1f4128e3fe..9e7629ebb2 100644
--- a/hw/slavio_misc.c
+++ b/hw/slavio_misc.c
@@ -36,19 +36,15 @@
#ifdef DEBUG_MISC
#define MISC_DPRINTF(fmt, args...) \
do { printf("MISC: " fmt , ##args); } while (0)
-#define pic_set_irq_new(intctl, irq, level) \
- do { printf("MISC: set_irq(%d): %d\n", (irq), (level)); \
- pic_set_irq_new((intctl), (irq),(level));} while (0)
#else
#define MISC_DPRINTF(fmt, args...)
#endif
typedef struct MiscState {
- int irq;
+ qemu_irq irq;
uint8_t config;
uint8_t aux1, aux2;
uint8_t diag, mctrl, sysctrl;
- void *intctl;
} MiscState;
#define MISC_MAXADDR 1
@@ -58,9 +54,11 @@ static void slavio_misc_update_irq(void *opaque)
MiscState *s = opaque;
if ((s->aux2 & 0x4) && (s->config & 0x8)) {
- pic_set_irq_new(s->intctl, s->irq, 1);
+ MISC_DPRINTF("Raise IRQ\n");
+ qemu_irq_raise(s->irq);
} else {
- pic_set_irq_new(s->intctl, s->irq, 0);
+ MISC_DPRINTF("Lower IRQ\n");
+ qemu_irq_lower(s->irq);
}
}
@@ -184,8 +182,10 @@ static CPUWriteMemoryFunc *slavio_misc_mem_write[3] = {
static void slavio_misc_save(QEMUFile *f, void *opaque)
{
MiscState *s = opaque;
+ int tmp;
- qemu_put_be32s(f, &s->irq);
+ tmp = 0;
+ qemu_put_be32s(f, &tmp); /* ignored, was IRQ. */
qemu_put_8s(f, &s->config);
qemu_put_8s(f, &s->aux1);
qemu_put_8s(f, &s->aux2);
@@ -197,11 +197,12 @@ static void slavio_misc_save(QEMUFile *f, void *opaque)
static int slavio_misc_load(QEMUFile *f, void *opaque, int version_id)
{
MiscState *s = opaque;
+ int tmp;
if (version_id != 1)
return -EINVAL;
- qemu_get_be32s(f, &s->irq);
+ qemu_get_be32s(f, &tmp);
qemu_get_8s(f, &s->config);
qemu_get_8s(f, &s->aux1);
qemu_get_8s(f, &s->aux2);
@@ -211,7 +212,7 @@ static int slavio_misc_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
-void *slavio_misc_init(uint32_t base, int irq, void *intctl)
+void *slavio_misc_init(uint32_t base, qemu_irq irq)
{
int slavio_misc_io_memory;
MiscState *s;
@@ -237,7 +238,6 @@ void *slavio_misc_init(uint32_t base, int irq, void *intctl)
cpu_register_physical_memory(base + 0xa000000, MISC_MAXADDR, slavio_misc_io_memory);
s->irq = irq;
- s->intctl = intctl;
register_savevm("slavio_misc", base, 1, slavio_misc_save, slavio_misc_load, s);
qemu_register_reset(slavio_misc_reset, s);
diff --git a/hw/slavio_serial.c b/hw/slavio_serial.c
index 847710e3d1..2ca3eed65a 100644
--- a/hw/slavio_serial.c
+++ b/hw/slavio_serial.c
@@ -52,9 +52,6 @@
#ifdef DEBUG_SERIAL
#define SER_DPRINTF(fmt, args...) \
do { printf("SER: " fmt , ##args); } while (0)
-#define pic_set_irq_new(intctl, irq, level) \
- do { printf("SER: set_irq(%d): %d\n", (irq), (level)); \
- pic_set_irq_new((intctl), (irq),(level));} while (0)
#else
#define SER_DPRINTF(fmt, args...)
#endif
@@ -89,7 +86,7 @@ typedef struct {
} SERIOQueue;
typedef struct ChannelState {
- int irq;
+ qemu_irq irq;
int reg;
int rxint, txint, rxint_under_svc, txint_under_svc;
chn_id_t chn; // this channel, A (base+4) or B (base+0)
@@ -98,7 +95,6 @@ typedef struct ChannelState {
uint8_t rx, tx, wregs[16], rregs[16];
SERIOQueue queue;
CharDriverState *chr;
- void *intctl;
} ChannelState;
struct SerialState {
@@ -166,7 +162,8 @@ static void slavio_serial_update_irq(ChannelState *s)
irq = slavio_serial_update_irq_chn(s);
irq |= slavio_serial_update_irq_chn(s->otherchn);
- pic_set_irq_new(s->intctl, s->irq, irq);
+ SER_DPRINTF("IRQ = %d\n", irq);
+ qemu_set_irq(s->irq, irq);
}
static void slavio_serial_reset_chn(ChannelState *s)
@@ -494,7 +491,9 @@ static CPUWriteMemoryFunc *slavio_serial_mem_write[3] = {
static void slavio_serial_save_chn(QEMUFile *f, ChannelState *s)
{
- qemu_put_be32s(f, &s->irq);
+ int tmp;
+ tmp = 0;
+ qemu_put_be32s(f, &tmp); /* unused, was IRQ. */
qemu_put_be32s(f, &s->reg);
qemu_put_be32s(f, &s->rxint);
qemu_put_be32s(f, &s->txint);
@@ -516,10 +515,12 @@ static void slavio_serial_save(QEMUFile *f, void *opaque)
static int slavio_serial_load_chn(QEMUFile *f, ChannelState *s, int version_id)
{
+ int tmp;
+
if (version_id > 2)
return -EINVAL;
- qemu_get_be32s(f, &s->irq);
+ qemu_get_be32s(f, &tmp); /* unused */
qemu_get_be32s(f, &s->reg);
qemu_get_be32s(f, &s->rxint);
qemu_get_be32s(f, &s->txint);
@@ -547,8 +548,8 @@ static int slavio_serial_load(QEMUFile *f, void *opaque, int version_id)
}
-SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1,
- CharDriverState *chr2, void *intctl)
+SerialState *slavio_serial_init(int base, qemu_irq irq, CharDriverState *chr1,
+ CharDriverState *chr2)
{
int slavio_serial_io_memory, i;
SerialState *s;
@@ -567,7 +568,6 @@ SerialState *slavio_serial_init(int base, int irq, CharDriverState *chr1,
s->chn[i].irq = irq;
s->chn[i].chn = 1 - i;
s->chn[i].type = ser;
- s->chn[i].intctl = intctl;
if (s->chn[i].chr) {
qemu_chr_add_handlers(s->chn[i].chr, serial_can_receive,
serial_receive1, serial_event, &s->chn[i]);
@@ -665,7 +665,7 @@ static void sunmouse_event(void *opaque,
put_queue(s, 0);
}
-void slavio_serial_ms_kbd_init(int base, int irq, void *intctl)
+void slavio_serial_ms_kbd_init(int base, qemu_irq irq)
{
int slavio_serial_io_memory, i;
SerialState *s;
@@ -677,7 +677,6 @@ void slavio_serial_ms_kbd_init(int base, int irq, void *intctl)
s->chn[i].irq = irq;
s->chn[i].chn = 1 - i;
s->chn[i].chr = NULL;
- s->chn[i].intctl = intctl;
}
s->chn[0].otherchn = &s->chn[1];
s->chn[1].otherchn = &s->chn[0];
diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c
index 59fe6832f8..8898afc460 100644
--- a/hw/slavio_timer.c
+++ b/hw/slavio_timer.c
@@ -28,9 +28,6 @@
#ifdef DEBUG_TIMER
#define DPRINTF(fmt, args...) \
do { printf("TIMER: " fmt , ##args); } while (0)
-#define pic_set_irq_new(intctl, irq, level) \
- do { printf("TIMER: set_irq(%d): %d\n", (irq), (level)); \
- pic_set_irq_new((intctl), (irq),(level));} while (0)
#else
#define DPRINTF(fmt, args...)
#endif
diff --git a/hw/smc91c111.c b/hw/smc91c111.c
index 855a9b1f1d..d90ab32f65 100644
--- a/hw/smc91c111.c
+++ b/hw/smc91c111.c
@@ -24,8 +24,7 @@ typedef struct {
uint16_t gpr;
uint16_t ptr;
uint16_t ercv;
- void *pic;
- int irq;
+ qemu_irq irq;
int bank;
int packet_num;
int tx_alloc;
@@ -86,7 +85,7 @@ static void smc91c111_update(smc91c111_state *s)
if (s->tx_fifo_done_len != 0)
s->int_level |= INT_TX;
level = (s->int_level & s->int_mask) != 0;
- pic_set_irq_new(s->pic, s->irq, level);
+ qemu_set_irq(s->irq, level);
}
/* Try to allocate a packet. Returns 0x80 on failure. */
@@ -693,7 +692,7 @@ static CPUWriteMemoryFunc *smc91c111_writefn[] = {
smc91c111_writel
};
-void smc91c111_init(NICInfo *nd, uint32_t base, void *pic, int irq)
+void smc91c111_init(NICInfo *nd, uint32_t base, qemu_irq irq)
{
smc91c111_state *s;
int iomemtype;
@@ -703,7 +702,6 @@ void smc91c111_init(NICInfo *nd, uint32_t base, void *pic, int irq)
smc91c111_writefn, s);
cpu_register_physical_memory(base, 16, iomemtype);
s->base = base;
- s->pic = pic;
s->irq = irq;
memcpy(s->macaddr, nd->macaddr, 6);
diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
index b17a12b9e7..8480c8dbe0 100644
--- a/hw/sparc32_dma.c
+++ b/hw/sparc32_dma.c
@@ -37,9 +37,6 @@
#ifdef DEBUG_DMA
#define DPRINTF(fmt, args...) \
do { printf("DMA: " fmt , ##args); } while (0)
-#define pic_set_irq_new(ctl, irq, level) \
- do { printf("DMA: set_irq(%d): %d\n", (irq), (level)); \
- pic_set_irq_new((ctl), (irq),(level));} while (0)
#else
#define DPRINTF(fmt, args...)
#endif
@@ -58,17 +55,11 @@ typedef struct DMAState DMAState;
struct DMAState {
uint32_t dmaregs[DMA_REGS];
- int espirq, leirq;
- void *iommu, *esp_opaque, *lance_opaque, *intctl;
+ qemu_irq espirq, leirq;
+ void *iommu, *esp_opaque, *lance_opaque;
+ qemu_irq *pic;
};
-void ledma_set_irq(void *opaque, int isr)
-{
- DMAState *s = opaque;
-
- pic_set_irq_new(s->intctl, s->leirq, isr);
-}
-
/* Note: on sparc, the lance 16 bit bus is swapped */
void ledma_memory_read(void *opaque, target_phys_addr_t addr,
uint8_t *buf, int len, int do_bswap)
@@ -125,8 +116,9 @@ void espdma_raise_irq(void *opaque)
{
DMAState *s = opaque;
+ DPRINTF("Raise ESP IRQ\n");
s->dmaregs[0] |= DMA_INTR;
- pic_set_irq_new(s->intctl, s->espirq, 1);
+ qemu_irq_raise(s->espirq);
}
void espdma_clear_irq(void *opaque)
@@ -134,7 +126,8 @@ void espdma_clear_irq(void *opaque)
DMAState *s = opaque;
s->dmaregs[0] &= ~DMA_INTR;
- pic_set_irq_new(s->intctl, s->espirq, 0);
+ DPRINTF("Lower ESP IRQ\n");
+ qemu_irq_lower(s->espirq);
}
void espdma_memory_read(void *opaque, uint8_t *buf, int len)
@@ -179,8 +172,10 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
DPRINTF("write dmareg[%d]: 0x%8.8x -> 0x%8.8x\n", saddr, s->dmaregs[saddr], val);
switch (saddr) {
case 0:
- if (!(val & DMA_INTREN))
- pic_set_irq_new(s->intctl, s->espirq, 0);
+ if (!(val & DMA_INTREN)) {
+ DPRINTF("Lower ESP IRQ\n");
+ qemu_irq_lower(s->espirq);
+ }
if (val & DMA_RESET) {
esp_reset(s->esp_opaque);
} else if (val & 0x40) {
@@ -194,8 +189,12 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
s->dmaregs[0] |= DMA_LOADED;
break;
case 4:
- if (!(val & DMA_INTREN))
- pic_set_irq_new(s->intctl, s->leirq, 0);
+ /* ??? Should this mask out the lance IRQ? The NIC may re-assert
+ this IRQ unexpectedly. */
+ if (!(val & DMA_INTREN)) {
+ DPRINTF("Lower Lance IRQ\n");
+ qemu_irq_lower(s->leirq);
+ }
if (val & DMA_RESET)
pcnet_h_reset(s->lance_opaque);
val &= 0x0fffffff;
@@ -250,7 +249,8 @@ static int dma_load(QEMUFile *f, void *opaque, int version_id)
return 0;
}
-void *sparc32_dma_init(uint32_t daddr, int espirq, int leirq, void *iommu, void *intctl)
+void *sparc32_dma_init(uint32_t daddr, qemu_irq espirq, qemu_irq leirq,
+ void *iommu)
{
DMAState *s;
int dma_io_memory;
@@ -262,7 +262,6 @@ void *sparc32_dma_init(uint32_t daddr, int espirq, int leirq, void *iommu, void
s->espirq = espirq;
s->leirq = leirq;
s->iommu = iommu;
- s->intctl = intctl;
dma_io_memory = cpu_register_io_memory(0, dma_mem_read, dma_mem_write, s);
cpu_register_physical_memory(daddr, 16 * 2, dma_io_memory);
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 49e9c2287c..b41dd25b16 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -182,11 +182,6 @@ void irq_info()
slavio_irq_info(slavio_intctl);
}
-void pic_set_irq(int irq, int level)
-{
- pic_set_irq_new(slavio_intctl, irq, level);
-}
-
static void *slavio_misc;
void qemu_system_powerdown(void)
@@ -208,6 +203,7 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size,
unsigned int i;
void *iommu, *dma, *main_esp, *main_lance = NULL;
const sparc_def_t *def;
+ qemu_irq *slavio_irq;
/* init CPUs */
sparc_find_by_name(cpu_model, &def);
@@ -230,38 +226,40 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size,
iommu = iommu_init(hwdef->iommu_base);
slavio_intctl = slavio_intctl_init(hwdef->intctl_base,
hwdef->intctl_base + 0x10000,
- &hwdef->intbit_to_level[0]);
+ &hwdef->intbit_to_level[0],
+ &slavio_irq);
for(i = 0; i < smp_cpus; i++) {
slavio_intctl_set_cpu(slavio_intctl, i, envs[i]);
}
- dma = sparc32_dma_init(hwdef->dma_base, hwdef->esp_irq,
- hwdef->le_irq, iommu, slavio_intctl);
+ dma = sparc32_dma_init(hwdef->dma_base, slavio_irq[hwdef->esp_irq],
+ slavio_irq[hwdef->le_irq], iommu);
tcx_init(ds, hwdef->tcx_base, phys_ram_base + ram_size, ram_size,
hwdef->vram_size, graphic_width, graphic_height);
if (nd_table[0].vlan) {
if (nd_table[0].model == NULL
|| strcmp(nd_table[0].model, "lance") == 0) {
- main_lance = lance_init(&nd_table[0], hwdef->le_base, dma);
+ main_lance = lance_init(&nd_table[0], hwdef->le_base, dma,
+ slavio_irq[hwdef->le_irq]);
} else {
fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
exit (1);
}
}
- nvram = m48t59_init(0, hwdef->nvram_base, 0, hwdef->nvram_size, 8);
+ nvram = m48t59_init(slavio_irq[0], hwdef->nvram_base, 0,
+ hwdef->nvram_size, 8);
for (i = 0; i < MAX_CPUS; i++) {
slavio_timer_init(hwdef->counter_base + i * TARGET_PAGE_SIZE,
hwdef->clock_irq, 0, i, slavio_intctl);
}
slavio_timer_init(hwdef->counter_base + 0x10000, hwdef->clock1_irq, 2,
(unsigned int)-1, slavio_intctl);
- slavio_serial_ms_kbd_init(hwdef->ms_kb_base, hwdef->ms_kb_irq,
- slavio_intctl);
+ slavio_serial_ms_kbd_init(hwdef->ms_kb_base, slavio_irq[hwdef->ms_kb_irq]);
// Slavio TTYA (base+4, Linux ttyS0) is the first Qemu serial device
// Slavio TTYB (base+0, Linux ttyS1) is the second Qemu serial device
- slavio_serial_init(hwdef->serial_base, hwdef->ser_irq,
- serial_hds[1], serial_hds[0], slavio_intctl);
- fdctrl_init(hwdef->fd_irq, 0, 1, hwdef->fd_base, fd_table);
+ slavio_serial_init(hwdef->serial_base, slavio_irq[hwdef->ser_irq],
+ serial_hds[1], serial_hds[0]);
+ fdctrl_init(slavio_irq[hwdef->fd_irq], 0, 1, hwdef->fd_base, fd_table);
main_esp = esp_init(bs_table, hwdef->esp_base, dma);
for (i = 0; i < MAX_DISKS; i++) {
@@ -270,8 +268,8 @@ static void sun4m_hw_init(const struct hwdef *hwdef, int ram_size,
}
}
- slavio_misc = slavio_misc_init(hwdef->slavio_base, hwdef->me_irq,
- slavio_intctl);
+ slavio_misc = slavio_misc_init(hwdef->slavio_base,
+ slavio_irq[hwdef->me_irq]);
if (hwdef->cs_base != (target_ulong)-1)
cs_init(hwdef->cs_base, hwdef->cs_irq, slavio_intctl);
sparc32_dma_set_reset_data(dma, main_esp, main_lance);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index e536c48ea2..b10722f6e6 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -223,14 +223,6 @@ void irq_info()
{
}
-void pic_set_irq(int irq, int level)
-{
-}
-
-void pic_set_irq_new(void *opaque, int irq, int level)
-{
-}
-
void qemu_system_powerdown(void)
{
}
@@ -340,14 +332,13 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
for(i = 0; i < MAX_SERIAL_PORTS; i++) {
if (serial_hds[i]) {
- serial_init(&pic_set_irq_new, NULL,
- serial_io[i], serial_irq[i], serial_hds[i]);
+ serial_init(serial_io[i], NULL/*serial_irq[i]*/, serial_hds[i]);
}
}
for(i = 0; i < MAX_PARALLEL_PORTS; i++) {
if (parallel_hds[i]) {
- parallel_init(parallel_io[i], parallel_irq[i], parallel_hds[i]);
+ parallel_init(parallel_io[i], NULL/*parallel_irq[i]*/, parallel_hds[i]);
}
}
@@ -358,9 +349,10 @@ static void sun4u_init(int ram_size, int vga_ram_size, int boot_device,
}
pci_cmd646_ide_init(pci_bus, bs_table, 1);
- kbd_init();
- floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
- nvram = m48t59_init(8, 0, 0x0074, NVRAM_SIZE, 59);
+ /* FIXME: wire up interrupts. */
+ i8042_init(NULL/*1*/, NULL/*12*/, 0x60);
+ floppy_controller = fdctrl_init(NULL/*6*/, 2, 0, 0x3f0, fd_table);
+ nvram = m48t59_init(NULL/*8*/, 0, 0x0074, NVRAM_SIZE, 59);
sun4u_NVRAM_set_params(nvram, NVRAM_SIZE, "Sun4u", ram_size, boot_device,
KERNEL_LOAD_ADDR, kernel_size,
kernel_cmdline,
diff --git a/hw/unin_pci.c b/hw/unin_pci.c
index 6448a6f250..f32d19522f 100644
--- a/hw/unin_pci.c
+++ b/hw/unin_pci.c
@@ -146,12 +146,12 @@ static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num)
return (irq_num + (pci_dev->devfn >> 3)) & 3;
}
-static void pci_unin_set_irq(void *pic, int irq_num, int level)
+static void pci_unin_set_irq(qemu_irq *pic, int irq_num, int level)
{
- openpic_set_irq(pic, irq_num + 8, level);
+ qemu_set_irq(pic[irq_num + 8], level);
}
-PCIBus *pci_pmac_init(void *pic)
+PCIBus *pci_pmac_init(qemu_irq *pic)
{
UNINState *s;
PCIDevice *d;
diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
index a4f8aa6e31..6808579563 100644
--- a/hw/usb-ohci.c
+++ b/hw/usb-ohci.c
@@ -59,8 +59,7 @@ enum ohci_type {
};
typedef struct {
- void *pic;
- int irq;
+ qemu_irq irq;
enum ohci_type type;
target_phys_addr_t mem_base;
int mem;
@@ -282,10 +281,7 @@ static inline void ohci_intr_update(OHCIState *ohci)
(ohci->intr_status & ohci->intr))
level = 1;
- if (ohci->type == OHCI_TYPE_PCI)
- pci_set_irq((PCIDevice *)ohci->pic, ohci->irq, level);
- else
- pic_set_irq_new(ohci->pic, ohci->irq, level);
+ qemu_set_irq(ohci->irq, level);
}
/* Set an interrupt */
@@ -1263,7 +1259,7 @@ static CPUWriteMemoryFunc *ohci_writefn[3]={
};
static void usb_ohci_init(OHCIState *ohci, int num_ports, int devfn,
- void *pic, int irq, enum ohci_type type, const char *name)
+ qemu_irq irq, enum ohci_type type, const char *name)
{
int i;
@@ -1286,7 +1282,6 @@ static void usb_ohci_init(OHCIState *ohci, int num_ports, int devfn,
ohci->mem = cpu_register_io_memory(0, ohci_readfn, ohci_writefn, ohci);
ohci->name = name;
- ohci->pic = pic;
ohci->irq = irq;
ohci->type = type;
@@ -1334,19 +1329,19 @@ void usb_ohci_init_pci(struct PCIBus *bus, int num_ports, int devfn)
ohci->pci_dev.config[0x0b] = 0xc;
ohci->pci_dev.config[0x3d] = 0x01; /* interrupt pin 1 */
- usb_ohci_init(&ohci->state, num_ports, devfn, &ohci->pci_dev,
- 0, OHCI_TYPE_PCI, ohci->pci_dev.name);
+ usb_ohci_init(&ohci->state, num_ports, devfn, ohci->pci_dev.irq[0],
+ OHCI_TYPE_PCI, ohci->pci_dev.name);
pci_register_io_region((struct PCIDevice *)ohci, 0, 256,
PCI_ADDRESS_SPACE_MEM, ohci_mapfunc);
}
void usb_ohci_init_pxa(target_phys_addr_t base, int num_ports, int devfn,
- void *pic, int irq)
+ qemu_irq irq)
{
OHCIState *ohci = (OHCIState *)qemu_mallocz(sizeof(OHCIState));
- usb_ohci_init(ohci, num_ports, devfn, pic, irq,
+ usb_ohci_init(ohci, num_ports, devfn, irq,
OHCI_TYPE_PXA, "OHCI USB");
ohci->mem_base = base;
diff --git a/hw/usb-uhci.c b/hw/usb-uhci.c
index 509c54f7ca..638b199c43 100644
--- a/hw/usb-uhci.c
+++ b/hw/usb-uhci.c
@@ -119,7 +119,7 @@ static void uhci_update_irq(UHCIState *s)
} else {
level = 0;
}
- pci_set_irq(&s->dev, 3, level);
+ qemu_set_irq(s->dev.irq[3], level);
}
static void uhci_reset(UHCIState *s)
diff --git a/hw/usb.h b/hw/usb.h
index bd77eea8b0..02a7355e63 100644
--- a/hw/usb.h
+++ b/hw/usb.h
@@ -208,7 +208,7 @@ void usb_uhci_init(PCIBus *bus, int devfn);
/* usb-ohci.c */
void usb_ohci_init_pci(struct PCIBus *bus, int num_ports, int devfn);
void usb_ohci_init_pxa(target_phys_addr_t base, int num_ports, int devfn,
- void *pic, int irq);
+ qemu_irq irq);
/* usb-linux.c */
USBDevice *usb_host_device_open(const char *devname);
diff --git a/hw/versatile_pci.c b/hw/versatile_pci.c
index 32854c2f94..98a2f4fb12 100644
--- a/hw/versatile_pci.c
+++ b/hw/versatile_pci.c
@@ -84,12 +84,12 @@ static int pci_vpb_map_irq(PCIDevice *d, int irq_num)
return irq_num;
}
-static void pci_vpb_set_irq(void *pic, int irq_num, int level)
+static void pci_vpb_set_irq(qemu_irq *pic, int irq_num, int level)
{
- pic_set_irq_new(pic, pci_vpb_irq + irq_num, level);
+ qemu_set_irq(pic[pci_vpb_irq + irq_num], level);
}
-PCIBus *pci_vpb_init(void *pic, int irq, int realview)
+PCIBus *pci_vpb_init(qemu_irq *pic, int irq, int realview)
{
PCIBus *s;
PCIDevice *d;
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index a91d7eff88..c0908161ae 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -14,12 +14,11 @@
typedef struct vpb_sic_state
{
- arm_pic_handler handler;
uint32_t base;
uint32_t level;
uint32_t mask;
uint32_t pic_enable;
- void *parent;
+ qemu_irq *parent;
int irq;
} vpb_sic_state;
@@ -28,7 +27,7 @@ static void vpb_sic_update(vpb_sic_state *s)
uint32_t flags;
flags = s->level & s->mask;
- pic_set_irq_new(s->parent, s->irq, flags != 0);
+ qemu_set_irq(s->parent[s->irq], flags != 0);
}
static void vpb_sic_update_pic(vpb_sic_state *s)
@@ -40,7 +39,7 @@ static void vpb_sic_update_pic(vpb_sic_state *s)
mask = 1u << i;
if (!(s->pic_enable & mask))
continue;
- pic_set_irq_new(s->parent, i, (s->level & mask) != 0);
+ qemu_set_irq(s->parent[i], (s->level & mask) != 0);
}
}
@@ -52,7 +51,7 @@ static void vpb_sic_set_irq(void *opaque, int irq, int level)
else
s->level &= ~(1u << irq);
if (s->pic_enable & (1u << irq))
- pic_set_irq_new(s->parent, irq, level);
+ qemu_set_irq(s->parent[irq], level);
vpb_sic_update(s);
}
@@ -126,15 +125,16 @@ static CPUWriteMemoryFunc *vpb_sic_writefn[] = {
vpb_sic_write
};
-static vpb_sic_state *vpb_sic_init(uint32_t base, void *parent, int irq)
+static qemu_irq *vpb_sic_init(uint32_t base, qemu_irq *parent, int irq)
{
vpb_sic_state *s;
+ qemu_irq *qi;
int iomemtype;
s = (vpb_sic_state *)qemu_mallocz(sizeof(vpb_sic_state));
if (!s)
return NULL;
- s->handler = vpb_sic_set_irq;
+ qi = qemu_allocate_irqs(vpb_sic_set_irq, s, 32);
s->base = base;
s->parent = parent;
s->irq = irq;
@@ -142,7 +142,7 @@ static vpb_sic_state *vpb_sic_init(uint32_t base, void *parent, int irq)
vpb_sic_writefn, s);
cpu_register_physical_memory(base, 0x00000fff, iomemtype);
/* ??? Save/restore. */
- return s;
+ return qi;
}
/* Board init. */
@@ -158,8 +158,8 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
int board_id)
{
CPUState *env;
- void *pic;
- void *sic;
+ qemu_irq *pic;
+ qemu_irq *sic;
void *scsi_hba;
PCIBus *pci_bus;
NICInfo *nd;
@@ -176,10 +176,10 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
arm_sysctl_init(0x10000000, 0x41007004);
pic = arm_pic_init_cpu(env);
- pic = pl190_init(0x10140000, pic, ARM_PIC_CPU_IRQ, ARM_PIC_CPU_FIQ);
+ pic = pl190_init(0x10140000, pic[0], pic[1]);
sic = vpb_sic_init(0x10003000, pic, 31);
- pl050_init(0x10006000, sic, 3, 0);
- pl050_init(0x10007000, sic, 4, 1);
+ pl050_init(0x10006000, sic[3], 0);
+ pl050_init(0x10007000, sic[4], 1);
pci_bus = pci_vpb_init(sic, 27, 0);
/* The Versatile PCI bridge does not provide access to PCI IO space,
@@ -189,7 +189,7 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
if (!nd->model)
nd->model = done_smc ? "rtl8139" : "smc91c111";
if (strcmp(nd->model, "smc91c111") == 0) {
- smc91c111_init(nd, 0x10010000, sic, 25);
+ smc91c111_init(nd, 0x10010000, sic[25]);
} else {
pci_nic_init(pci_bus, nd, -1);
}
@@ -204,20 +204,20 @@ static void versatile_init(int ram_size, int vga_ram_size, int boot_device,
}
}
- pl011_init(0x101f1000, pic, 12, serial_hds[0]);
- pl011_init(0x101f2000, pic, 13, serial_hds[1]);
- pl011_init(0x101f3000, pic, 14, serial_hds[2]);
- pl011_init(0x10009000, sic, 6, serial_hds[3]);
+ pl011_init(0x101f1000, pic[12], serial_hds[0]);
+ pl011_init(0x101f2000, pic[13], serial_hds[1]);
+ pl011_init(0x101f3000, pic[14], serial_hds[2]);
+ pl011_init(0x10009000, sic[6], serial_hds[3]);
- pl080_init(0x10130000, pic, 17, 8);
- sp804_init(0x101e2000, pic, 4);
- sp804_init(0x101e3000, pic, 5);
+ pl080_init(0x10130000, pic[17], 8);
+ sp804_init(0x101e2000, pic[4]);
+ sp804_init(0x101e3000, pic[5]);
/* The versatile/PB actually has a modified Color LCD controller
that includes hardware cursor support from the PL111. */
- pl110_init(ds, 0x10120000, pic, 16, 1);
+ pl110_init(ds, 0x10120000, pic[16], 1);
- pl181_init(0x10005000, sd_bdrv, sic, 22, 1);
+ pl181_init(0x10005000, sd_bdrv, sic[22], sic[1]);
#if 0
/* Disabled because there's no way of specifying a block device. */
pl181_init(0x1000b000, NULL, sic, 23, 2);