Unify IRQ handling.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2635 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
pbrook
2007-04-07 18:14:41 +00:00
parent b6e27ab8b1
commit d537cf6c86
71 changed files with 592 additions and 624 deletions
+1
View File
@@ -360,6 +360,7 @@ VL_OBJS=vl.o osdep.o readline.o monitor.o pci.o console.o loader.o isa_mmio.o
VL_OBJS+=cutils.o VL_OBJS+=cutils.o
VL_OBJS+=block.o block-raw.o VL_OBJS+=block.o block-raw.o
VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o block-vpc.o block-vvfat.o block-qcow2.o VL_OBJS+=block-cow.o block-qcow.o aes.o block-vmdk.o block-cloop.o block-dmg.o block-bochs.o block-vpc.o block-vvfat.o block-qcow2.o
VL_OBJS+=irq.o
ifdef CONFIG_WIN32 ifdef CONFIG_WIN32
VL_OBJS+=tap-win32.o VL_OBJS+=tap-win32.o
endif endif
+1 -1
View File
@@ -92,7 +92,7 @@ static void pm_update_sci(PIIX4PMState *s)
pmsts = get_pmsts(s); pmsts = get_pmsts(s);
sci_level = (((pmsts & s->pmen) & sci_level = (((pmsts & s->pmen) &
(RTC_EN | PWRBTN_EN | GBL_EN | TMROF_EN)) != 0); (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 */ /* schedule a timer interruption if needed */
if ((s->pmen & TMROF_EN) && !(pmsts & TMROF_EN)) { if ((s->pmen & TMROF_EN) && !(pmsts & TMROF_EN)) {
expire_time = muldiv64(s->tmr_overflow_time, ticks_per_sec, PM_FREQ); expire_time = muldiv64(s->tmr_overflow_time, ticks_per_sec, PM_FREQ);
+1 -1
View File
@@ -267,7 +267,7 @@ static void Adlib_fini (AdlibState *s)
AUD_remove_card (&s->card); AUD_remove_card (&s->card);
} }
int Adlib_init (AudioState *audio) int Adlib_init (AudioState *audio, qemu_irq *pic)
{ {
AdlibState *s = &glob_adlib; AdlibState *s = &glob_adlib;
audsettings_t as; audsettings_t as;
+3 -3
View File
@@ -200,14 +200,14 @@ static int pci_pbm_map_irq(PCIDevice *pci_dev, int irq_num)
return bus_offset + 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. */ /* 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, PCIBus *pci_apb_init(target_ulong special_base, target_ulong mem_base,
void *pic) qemu_irq *pic)
{ {
APBState *s; APBState *s;
PCIDevice *d; PCIDevice *d;
+9 -11
View File
@@ -60,10 +60,8 @@ typedef struct gic_irq_state
typedef struct gic_state typedef struct gic_state
{ {
arm_pic_handler handler;
uint32_t base; uint32_t base;
void *parent; qemu_irq parent_irq;
int parent_irq;
int enabled; int enabled;
int cpu_enabled; int cpu_enabled;
@@ -88,7 +86,7 @@ static void gic_update(gic_state *s)
s->current_pending = 1023; s->current_pending = 1023;
if (!s->enabled || !s->cpu_enabled) { if (!s->enabled || !s->cpu_enabled) {
pic_set_irq_new(s->parent, s->parent_irq, 0); qemu_irq_lower(s->parent_irq);
return; return;
} }
best_prio = 0x100; best_prio = 0x100;
@@ -102,12 +100,12 @@ static void gic_update(gic_state *s)
} }
} }
if (best_prio > s->priority_mask) { if (best_prio > s->priority_mask) {
pic_set_irq_new(s->parent, s->parent_irq, 0); qemu_irq_lower(s->parent_irq);
} else { } else {
s->current_pending = best_irq; s->current_pending = best_irq;
if (best_prio < s->running_priority) { if (best_prio < s->running_priority) {
DPRINTF("Raised pending IRQ %d\n", best_irq); 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"); DPRINTF("ACK no pending IRQ\n");
return 1023; 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; s->last_active[new_irq] = s->running_irq;
/* For level triggered interrupts we clear the pending bit while /* For level triggered interrupts we clear the pending bit while
the interrupt is active. */ the interrupt is active. */
@@ -520,16 +518,16 @@ static void gic_reset(gic_state *s)
s->cpu_enabled = 0; 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; gic_state *s;
qemu_irq *qi;
int iomemtype; int iomemtype;
s = (gic_state *)qemu_mallocz(sizeof(gic_state)); s = (gic_state *)qemu_mallocz(sizeof(gic_state));
if (!s) if (!s)
return NULL; return NULL;
s->handler = gic_set_irq; qi = qemu_allocate_irqs(gic_set_irq, s, GIC_NIRQ);
s->parent = parent;
s->parent_irq = parent_irq; s->parent_irq = parent_irq;
if (base != 0xffffffff) { if (base != 0xffffffff) {
iomemtype = cpu_register_io_memory(0, gic_cpu_readfn, 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; s->base = 0;
} }
gic_reset(s); gic_reset(s);
return s; return qi;
} }
+9 -34
View File
@@ -11,11 +11,6 @@
#include "arm_pic.h" #include "arm_pic.h"
/* Stub functions for hardware that doesn't exist. */ /* 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) void pic_info(void)
{ {
} }
@@ -25,49 +20,29 @@ void irq_info(void)
} }
void pic_set_irq_new(void *opaque, int irq, int level) /* Input 0 is IRQ and input 1 is FIQ. */
{
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;
static void arm_pic_cpu_handler(void *opaque, int irq, int level) 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) { switch (irq) {
case ARM_PIC_CPU_IRQ: case ARM_PIC_CPU_IRQ:
if (level) if (level)
cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD); cpu_interrupt(env, CPU_INTERRUPT_HARD);
else else
cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_HARD); cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
break; break;
case ARM_PIC_CPU_FIQ: case ARM_PIC_CPU_FIQ:
if (level) if (level)
cpu_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ); cpu_interrupt(env, CPU_INTERRUPT_FIQ);
else else
cpu_reset_interrupt(s->cpu_env, CPU_INTERRUPT_FIQ); cpu_reset_interrupt(env, CPU_INTERRUPT_FIQ);
break; break;
default: default:
cpu_abort(s->cpu_env, "arm_pic_cpu_handler: Bad interrput line %d\n", cpu_abort(env, "arm_pic_cpu_handler: Bad interrput line %d\n", irq);
irq);
} }
} }
void *arm_pic_init_cpu(CPUState *env) qemu_irq *arm_pic_init_cpu(CPUState *env)
{ {
arm_pic_cpu_state *s; return qemu_allocate_irqs(arm_pic_cpu_handler, env, 2);
s = (arm_pic_cpu_state *)malloc(sizeof(arm_pic_cpu_state));
s->handler = arm_pic_cpu_handler;
s->cpu_env = env;
return s;
} }
+1 -5
View File
@@ -14,14 +14,10 @@
#ifndef ARM_INTERRUPT_H #ifndef ARM_INTERRUPT_H
#define ARM_INTERRUPT_H 1 #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. */ /* The CPU is also modeled as an interrupt controller. */
#define ARM_PIC_CPU_IRQ 0 #define ARM_PIC_CPU_IRQ 0
#define ARM_PIC_CPU_FIQ 1 #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 */ #endif /* !ARM_INTERRUPT_H */
+16 -21
View File
@@ -32,8 +32,7 @@ typedef struct {
int raw_freq; int raw_freq;
int freq; int freq;
int int_level; int int_level;
void *pic; qemu_irq irq;
int irq;
} arm_timer_state; } arm_timer_state;
/* Calculate the new expiry time of the given timer. */ /* 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. */ /* Update interrupts. */
if (s->int_level && (s->control & TIMER_CTRL_IE)) { if (s->int_level && (s->control & TIMER_CTRL_IE)) {
pic_set_irq_new(s->pic, s->irq, 1); qemu_irq_raise(s->irq);
} else { } else {
pic_set_irq_new(s->pic, s->irq, 0); qemu_irq_lower(s->irq);
} }
next = now; next = now;
@@ -215,12 +214,11 @@ static void arm_timer_tick(void *opaque)
arm_timer_update((arm_timer_state *)opaque, now); 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; arm_timer_state *s;
s = (arm_timer_state *)qemu_mallocz(sizeof(arm_timer_state)); s = (arm_timer_state *)qemu_mallocz(sizeof(arm_timer_state));
s->pic = pic;
s->irq = irq; s->irq = irq;
s->raw_freq = s->freq = 1000000; s->raw_freq = s->freq = 1000000;
s->control = TIMER_CTRL_IE; 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. */ Integrator/CP timer modules. */
typedef struct { typedef struct {
/* Include a pseudo-PIC device to merge the two interrupt sources. */
arm_pic_handler handler;
void *timer[2]; void *timer[2];
int level[2]; int level[2];
uint32_t base; uint32_t base;
/* The output PIC device. */ qemu_irq irq;
void *pic;
int irq;
} sp804_state; } sp804_state;
/* Merge the IRQs from the two component devices. */
static void sp804_set_irq(void *opaque, int irq, int level) static void sp804_set_irq(void *opaque, int irq, int level)
{ {
sp804_state *s = (sp804_state *)opaque; sp804_state *s = (sp804_state *)opaque;
s->level[irq] = level; 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) static uint32_t sp804_read(void *opaque, target_phys_addr_t offset)
@@ -293,20 +288,20 @@ static CPUWriteMemoryFunc *sp804_writefn[] = {
sp804_write sp804_write
}; };
void sp804_init(uint32_t base, void *pic, int irq) void sp804_init(uint32_t base, qemu_irq irq)
{ {
int iomemtype; int iomemtype;
sp804_state *s; sp804_state *s;
qemu_irq *qi;
s = (sp804_state *)qemu_mallocz(sizeof(sp804_state)); 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->base = base;
s->pic = pic;
s->irq = irq; s->irq = irq;
/* ??? The timers are actually configurable between 32kHz and 1MHz, but /* ??? The timers are actually configurable between 32kHz and 1MHz, but
we don't implement that. */ we don't implement that. */
s->timer[0] = arm_timer_init(1000000, s, 0); s->timer[0] = arm_timer_init(1000000, qi[0]);
s->timer[1] = arm_timer_init(1000000, s, 1); s->timer[1] = arm_timer_init(1000000, qi[1]);
iomemtype = cpu_register_io_memory(0, sp804_readfn, iomemtype = cpu_register_io_memory(0, sp804_readfn,
sp804_writefn, s); sp804_writefn, s);
cpu_register_physical_memory(base, 0x00000fff, iomemtype); cpu_register_physical_memory(base, 0x00000fff, iomemtype);
@@ -362,7 +357,7 @@ static CPUWriteMemoryFunc *icp_pit_writefn[] = {
icp_pit_write 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; int iomemtype;
icp_pit_state *s; 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 = (icp_pit_state *)qemu_mallocz(sizeof(icp_pit_state));
s->base = base; s->base = base;
/* Timer 0 runs at the system clock speed (40MHz). */ /* 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. */ /* The other two timers run at 1MHz. */
s->timer[1] = arm_timer_init(1000000, pic, irq + 1); s->timer[1] = arm_timer_init(1000000, pic[irq + 1]);
s->timer[2] = arm_timer_init(1000000, pic, irq + 2); s->timer[2] = arm_timer_init(1000000, pic[irq + 2]);
iomemtype = cpu_register_io_memory(0, icp_pit_readfn, iomemtype = cpu_register_io_memory(0, icp_pit_readfn,
icp_pit_writefn, s); icp_pit_writefn, s);
-3
View File
@@ -47,9 +47,6 @@ typedef struct CSState {
#ifdef DEBUG_CS #ifdef DEBUG_CS
#define DPRINTF(fmt, args...) \ #define DPRINTF(fmt, args...) \
do { printf("CS: " fmt , ##args); } while (0) 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 #else
#define DPRINTF(fmt, args...) #define DPRINTF(fmt, args...)
#endif #endif
+4 -8
View File
@@ -124,9 +124,7 @@ typedef struct CUDAState {
int data_in_index; int data_in_index;
int data_out_index; int data_out_index;
SetIRQFunc *set_irq; qemu_irq irq;
int irq;
void *irq_opaque;
uint8_t autopoll; uint8_t autopoll;
uint8_t data_in[128]; uint8_t data_in[128];
uint8_t data_out[16]; 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) static void cuda_update_irq(CUDAState *s)
{ {
if (s->ifr & s->ier & (SR_INT | T1_INT)) { if (s->ifr & s->ier & (SR_INT | T1_INT)) {
s->set_irq(s->irq_opaque, s->irq, 1); qemu_irq_raise(s->irq);
} else { } 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, &cuda_readl,
}; };
int cuda_init(SetIRQFunc *set_irq, void *irq_opaque, int irq) int cuda_init(qemu_irq irq)
{ {
CUDAState *s = &cuda_state; CUDAState *s = &cuda_state;
int cuda_mem_index; int cuda_mem_index;
s->set_irq = set_irq;
s->irq_opaque = irq_opaque;
s->irq = irq; s->irq = irq;
s->timers[0].index = 0; s->timers[0].index = 0;
+2 -2
View File
@@ -326,7 +326,7 @@ static void disable_interrupt(EEPRO100State * s)
{ {
if (s->int_stat) { if (s->int_stat) {
logout("interrupt disabled\n"); logout("interrupt disabled\n");
pci_set_irq(s->pci_dev, 0, 0); qemu_irq_lower(s->pci_dev->irq[0]);
s->int_stat = 0; s->int_stat = 0;
} }
} }
@@ -335,7 +335,7 @@ static void enable_interrupt(EEPRO100State * s)
{ {
if (!s->int_stat) { if (!s->int_stat) {
logout("interrupt enabled\n"); logout("interrupt enabled\n");
pci_set_irq(s->pci_dev, 0, 1); qemu_irq_raise(s->pci_dev->irq[0]);
s->int_stat = 1; s->int_stat = 1;
} }
} }
+2 -2
View File
@@ -324,7 +324,7 @@ static void es1370_update_status (ES1370State *s, uint32_t new_status)
else { else {
s->status = new_status & ~STAT_INTR; 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) static void es1370_reset (ES1370State *s)
@@ -350,7 +350,7 @@ static void es1370_reset (ES1370State *s)
s->dac_voice[i] = NULL; 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) static void es1370_maybe_lower_irq (ES1370State *s, uint32_t sctl)
+5 -5
View File
@@ -368,7 +368,7 @@ struct fdctrl_t {
/* Controller's identification */ /* Controller's identification */
uint8_t version; uint8_t version;
/* HW */ /* HW */
int irq_lvl; qemu_irq irq;
int dma_chann; int dma_chann;
uint32_t io_base; uint32_t io_base;
/* Controller state */ /* Controller state */
@@ -485,7 +485,7 @@ static CPUWriteMemoryFunc *fdctrl_mem_write[3] = {
fdctrl_write_mem, 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, uint32_t io_base,
BlockDriverState **fds) BlockDriverState **fds)
{ {
@@ -501,7 +501,7 @@ fdctrl_t *fdctrl_init (int irq_lvl, int dma_chann, int mem_mapped,
fdctrl_result_timer, fdctrl); fdctrl_result_timer, fdctrl);
fdctrl->version = 0x90; /* Intel 82078 controller */ fdctrl->version = 0x90; /* Intel 82078 controller */
fdctrl->irq_lvl = irq_lvl; fdctrl->irq = irq;
fdctrl->dma_chann = dma_chann; fdctrl->dma_chann = dma_chann;
fdctrl->io_base = io_base; fdctrl->io_base = io_base;
fdctrl->config = 0x60; /* Implicit seek, polling & FIFO enabled */ 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) static void fdctrl_reset_irq (fdctrl_t *fdctrl)
{ {
FLOPPY_DPRINTF("Reset interrupt\n"); FLOPPY_DPRINTF("Reset interrupt\n");
pic_set_irq(fdctrl->irq_lvl, 0); qemu_set_irq(fdctrl->irq, 0);
fdctrl->state &= ~FD_CTRL_INTR; fdctrl->state &= ~FD_CTRL_INTR;
} }
@@ -557,7 +557,7 @@ static void fdctrl_raise_irq (fdctrl_t *fdctrl, uint8_t status)
} }
#endif #endif
if (~(fdctrl->state & FD_CTRL_INTR)) { if (~(fdctrl->state & FD_CTRL_INTR)) {
pic_set_irq(fdctrl->irq_lvl, 1); qemu_set_irq(fdctrl->irq, 1);
fdctrl->state |= FD_CTRL_INTR; fdctrl->state |= FD_CTRL_INTR;
} }
FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", status); FLOPPY_DPRINTF("Set interrupt status to 0x%02x\n", status);
+3 -3
View File
@@ -80,12 +80,12 @@ static int pci_grackle_map_irq(PCIDevice *pci_dev, int irq_num)
return (irq_num + (pci_dev->devfn >> 3)) & 3; 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; GrackleState *s;
PCIDevice *d; PCIDevice *d;
+3 -3
View File
@@ -520,7 +520,7 @@ static int pci_gt64120_map_irq(PCIDevice *pci_dev, int irq_num)
extern PCIDevice *piix4_dev; extern PCIDevice *piix4_dev;
static int pci_irq_levels[4]; 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; 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]) if (pic_irq == piix4_dev->config[0x60 + i])
pic_level |= pci_irq_levels[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); gt64120_pci_mapping(s);
} }
PCIBus *pci_gt64120_init(void *pic) PCIBus *pci_gt64120_init(qemu_irq *pic)
{ {
GT64120State *s; GT64120State *s;
PCIDevice *d; PCIDevice *d;
+5 -5
View File
@@ -32,9 +32,9 @@ typedef struct HeathrowPIC {
uint32_t level_triggered; uint32_t level_triggered;
} HeathrowPIC; } HeathrowPIC;
struct HeathrowPICS { typedef struct HeathrowPICS {
HeathrowPIC pics[2]; HeathrowPIC pics[2];
}; } HeathrowPICS;
static inline int check_irq(HeathrowPIC *pic) 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; HeathrowPICS *s = opaque;
HeathrowPIC *pic; HeathrowPIC *pic;
@@ -156,7 +156,7 @@ void heathrow_pic_set_irq(void *opaque, int num, int level)
heathrow_pic_update(s); heathrow_pic_update(s);
} }
HeathrowPICS *heathrow_pic_init(int *pmem_index) qemu_irq *heathrow_pic_init(int *pmem_index)
{ {
HeathrowPICS *s; HeathrowPICS *s;
@@ -164,5 +164,5 @@ HeathrowPICS *heathrow_pic_init(int *pmem_index)
s->pics[0].level_triggered = 0; s->pics[0].level_triggered = 0;
s->pics[1].level_triggered = 0x1ff00000; s->pics[1].level_triggered = 0x1ff00000;
*pmem_index = cpu_register_io_memory(0, pic_read, pic_write, s); *pmem_index = cpu_register_io_memory(0, pic_read, pic_write, s);
return s; return qemu_allocate_irqs(heathrow_pic_set_irq, s, 64);
} }
+3 -3
View File
@@ -47,7 +47,7 @@ typedef struct PITChannelState {
/* irq handling */ /* irq handling */
int64_t next_transition_time; int64_t next_transition_time;
QEMUTimer *irq_timer; QEMUTimer *irq_timer;
int irq; qemu_irq irq;
} PITChannelState; } PITChannelState;
struct PITState { struct PITState {
@@ -366,7 +366,7 @@ static void pit_irq_timer_update(PITChannelState *s, int64_t current_time)
return; return;
expire_time = pit_get_next_transition_time(s, current_time); expire_time = pit_get_next_transition_time(s, current_time);
irq_level = pit_get_out1(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 #ifdef DEBUG_PIT
printf("irq_level=%d next_delay=%f\n", printf("irq_level=%d next_delay=%f\n",
irq_level, 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; PITState *pit = &pit_state;
PITChannelState *s; PITChannelState *s;
+11 -16
View File
@@ -54,7 +54,7 @@ struct PicState2 {
/* 0 is master pic, 1 is slave pic */ /* 0 is master pic, 1 is slave pic */
/* XXX: better separation between the two pics */ /* XXX: better separation between the two pics */
PicState pics[2]; PicState pics[2];
IRQRequestFunc *irq_request; qemu_irq parent_irq;
void *irq_request_opaque; void *irq_request_opaque;
/* IOAPIC callback support */ /* IOAPIC callback support */
SetIRQFunc *alt_irq_func; SetIRQFunc *alt_irq_func;
@@ -160,13 +160,13 @@ void pic_update_irq(PicState2 *s)
} }
printf("pic: cpu_interrupt\n"); printf("pic: cpu_interrupt\n");
#endif #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 */ /* all targets should do this rather than acking the IRQ in the cpu */
#if defined(TARGET_MIPS) #if defined(TARGET_MIPS)
else { else {
s->irq_request(s->irq_request_opaque, 0); qemu_irq_lower(s->parent_irq);
} }
#endif #endif
} }
@@ -175,14 +175,14 @@ void pic_update_irq(PicState2 *s)
int64_t irq_time[16]; int64_t irq_time[16];
#endif #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; PicState2 *s = opaque;
#if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT) #if defined(DEBUG_PIC) || defined(DEBUG_IRQ_COUNT)
if (level != irq_level[irq]) { if (level != irq_level[irq]) {
#if defined(DEBUG_PIC) #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 #endif
irq_level[irq] = level; irq_level[irq] = level;
#ifdef DEBUG_IRQ_COUNT #ifdef DEBUG_IRQ_COUNT
@@ -203,12 +203,6 @@ void pic_set_irq_new(void *opaque, int irq, int level)
pic_update_irq(s); 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' */ /* acknowledge interrupt 'irq' */
static inline void pic_intack(PicState *s, int 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 */ /* init */
pic_reset(s); pic_reset(s);
/* deassert a pending interrupt */ /* 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->init_state = 1;
s->init4 = val & 1; s->init4 = val & 1;
s->single_mode = val & 2; s->single_mode = val & 2;
@@ -546,9 +540,10 @@ void irq_info(void)
#endif #endif
} }
PicState2 *pic_init(IRQRequestFunc *irq_request, void *irq_request_opaque) qemu_irq *i8259_init(qemu_irq parent_irq)
{ {
PicState2 *s; PicState2 *s;
s = qemu_mallocz(sizeof(PicState2)); s = qemu_mallocz(sizeof(PicState2));
if (!s) if (!s)
return NULL; return NULL;
@@ -556,11 +551,11 @@ PicState2 *pic_init(IRQRequestFunc *irq_request, void *irq_request_opaque)
pic_init1(0xa0, 0x4d1, &s->pics[1]); pic_init1(0xa0, 0x4d1, &s->pics[1]);
s->pics[0].elcr_mask = 0xf8; s->pics[0].elcr_mask = 0xf8;
s->pics[1].elcr_mask = 0xde; s->pics[1].elcr_mask = 0xde;
s->irq_request = irq_request; s->parent_irq = parent_irq;
s->irq_request_opaque = irq_request_opaque;
s->pics[0].pics_state = s; s->pics[0].pics_state = s;
s->pics[1].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, void pic_set_alt_irq_func(PicState2 *s, SetIRQFunc *alt_irq_func,
+18 -24
View File
@@ -300,9 +300,7 @@ typedef struct IDEState {
int mult_sectors; int mult_sectors;
int identify_set; int identify_set;
uint16_t identify_data[256]; uint16_t identify_data[256];
SetIRQFunc *set_irq; qemu_irq irq;
void *irq_opaque;
int irq;
PCIDevice *pci_dev; PCIDevice *pci_dev;
struct BMDMAState *bmdma; struct BMDMAState *bmdma;
int drive_serial; int drive_serial;
@@ -575,7 +573,7 @@ static inline void ide_set_irq(IDEState *s)
if (bm) { if (bm) {
bm->status |= BM_STATUS_INT; 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; ret = 0;
else else
ret = s->status; ret = s->status;
s->set_irq(s->irq_opaque, s->irq, 0); qemu_irq_lower(s->irq);
break; break;
} }
#ifdef DEBUG_IDE #ifdef DEBUG_IDE
@@ -2084,7 +2082,7 @@ static int guess_disk_lchs(IDEState *s,
static void ide_init2(IDEState *ide_state, static void ide_init2(IDEState *ide_state,
BlockDriverState *hd0, BlockDriverState *hd1, BlockDriverState *hd0, BlockDriverState *hd1,
SetIRQFunc *set_irq, void *irq_opaque, int irq) qemu_irq irq)
{ {
IDEState *s; IDEState *s;
static int drive_serial = 1; static int drive_serial = 1;
@@ -2155,8 +2153,6 @@ static void ide_init2(IDEState *ide_state,
} }
} }
s->drive_serial = drive_serial++; s->drive_serial = drive_serial++;
s->set_irq = set_irq;
s->irq_opaque = irq_opaque;
s->irq = irq; s->irq = irq;
s->sector_write_timer = qemu_new_timer(vm_clock, s->sector_write_timer = qemu_new_timer(vm_clock,
ide_sector_write_timer_cb, s); 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 */ /* 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) BlockDriverState *hd0, BlockDriverState *hd1)
{ {
IDEState *ide_state; IDEState *ide_state;
@@ -2192,7 +2188,7 @@ void isa_ide_init(int iobase, int iobase2, int irq,
if (!ide_state) if (!ide_state)
return; 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); 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_BLK_CH0)) ||
((d->dev.config[MRDMODE] & MRDMODE_INTR_CH1) && ((d->dev.config[MRDMODE] & MRDMODE_INTR_CH1) &&
!(d->dev.config[MRDMODE] & MRDMODE_BLK_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 */ /* 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; PCIIDEState *d;
uint8_t *pci_conf; uint8_t *pci_conf;
int i; int i;
qemu_irq *irq;
d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE", d = (PCIIDEState *)pci_register_device(bus, "CMD646 IDE",
sizeof(PCIIDEState), sizeof(PCIIDEState),
@@ -2462,10 +2459,10 @@ void pci_cmd646_ide_init(PCIBus *bus, BlockDriverState **hd_table,
for(i = 0; i < 4; i++) for(i = 0; i < 4; i++)
d->ide_if[i].pci_dev = (PCIDevice *)d; 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); irq = qemu_allocate_irqs(cmd646_set_irq, d, 2);
ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], irq[0]);
cmd646_set_irq, d, 1); ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], irq[1]);
} }
static void pci_ide_save(QEMUFile* f, void *opaque) 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 */ /* hd_table must contain 4 block drivers */
/* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */ /* 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; PCIIDEState *d;
uint8_t *pci_conf; 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_register_io_region((PCIDevice *)d, 4, 0x10,
PCI_ADDRESS_SPACE_IO, bmdma_map); PCI_ADDRESS_SPACE_IO, bmdma_map);
ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], ide_init2(&d->ide_if[0], hd_table[0], hd_table[1], pic[14]);
pic_set_irq_new, isa_pic, 14); ide_init2(&d->ide_if[2], hd_table[2], hd_table[3], pic[15]);
ide_init2(&d->ide_if[2], hd_table[2], hd_table[3],
pic_set_irq_new, isa_pic, 15);
ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6); ide_init_ioport(&d->ide_if[0], 0x1f0, 0x3f6);
ide_init_ioport(&d->ide_if[2], 0x170, 0x376); 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 */ /* hd_table must contain 4 block drivers */
/* PowerMac uses memory mapped registers, not I/O. Return the memory /* PowerMac uses memory mapped registers, not I/O. Return the memory
I/O index to access the ide. */ I/O index to access the ide. */
int pmac_ide_init (BlockDriverState **hd_table, int pmac_ide_init (BlockDriverState **hd_table, qemu_irq irq)
SetIRQFunc *set_irq, void *irq_opaque, int irq)
{ {
IDEState *ide_if; IDEState *ide_if;
int pmac_ide_memory; int pmac_ide_memory;
ide_if = qemu_mallocz(sizeof(IDEState) * 2); ide_if = qemu_mallocz(sizeof(IDEState) * 2);
ide_init2(&ide_if[0], hd_table[0], hd_table[1], ide_init2(&ide_if[0], hd_table[0], hd_table[1], irq);
set_irq, irq_opaque, irq);
pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read, pmac_ide_memory = cpu_register_io_memory(0, pmac_ide_read,
pmac_ide_write, &ide_if[0]); pmac_ide_write, &ide_if[0]);
+25 -30
View File
@@ -267,28 +267,22 @@ static void integratorcm_init(int memsz, uint32_t flash_offset)
typedef struct icp_pic_state typedef struct icp_pic_state
{ {
arm_pic_handler handler;
uint32_t base; uint32_t base;
uint32_t level; uint32_t level;
uint32_t irq_enabled; uint32_t irq_enabled;
uint32_t fiq_enabled; uint32_t fiq_enabled;
void *parent; qemu_irq parent_irq;
int parent_irq; qemu_irq parent_fiq;
int parent_fiq;
} icp_pic_state; } icp_pic_state;
static void icp_pic_update(icp_pic_state *s) static void icp_pic_update(icp_pic_state *s)
{ {
uint32_t flags; uint32_t flags;
if (s->parent_irq != -1) { flags = (s->level & s->irq_enabled);
flags = (s->level & s->irq_enabled); qemu_set_irq(s->parent_irq, flags != 0);
pic_set_irq_new(s->parent, s->parent_irq, flags != 0); flags = (s->level & s->fiq_enabled);
} qemu_set_irq(s->parent_fiq, flags != 0);
if (s->parent_fiq != -1) {
flags = (s->level & s->fiq_enabled);
pic_set_irq_new(s->parent, s->parent_fiq, flags != 0);
}
} }
static void icp_pic_set_irq(void *opaque, int irq, int level) 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; break;
case 4: /* INT_SOFTSET */ case 4: /* INT_SOFTSET */
if (value & 1) if (value & 1)
pic_set_irq_new(s, 0, 1); icp_pic_set_irq(s, 0, 1);
break; break;
case 5: /* INT_SOFTCLR */ case 5: /* INT_SOFTCLR */
if (value & 1) if (value & 1)
pic_set_irq_new(s, 0, 0); icp_pic_set_irq(s, 0, 0);
break; break;
case 10: /* FRQ_ENABLESET */ case 10: /* FRQ_ENABLESET */
s->fiq_enabled |= value; s->fiq_enabled |= value;
@@ -380,25 +374,25 @@ static CPUWriteMemoryFunc *icp_pic_writefn[] = {
icp_pic_write icp_pic_write
}; };
static icp_pic_state *icp_pic_init(uint32_t base, void *parent, static qemu_irq *icp_pic_init(uint32_t base,
int parent_irq, int parent_fiq) qemu_irq parent_irq, qemu_irq parent_fiq)
{ {
icp_pic_state *s; icp_pic_state *s;
int iomemtype; int iomemtype;
qemu_irq *qi;
s = (icp_pic_state *)qemu_mallocz(sizeof(icp_pic_state)); s = (icp_pic_state *)qemu_mallocz(sizeof(icp_pic_state));
if (!s) if (!s)
return NULL; return NULL;
s->handler = icp_pic_set_irq; qi = qemu_allocate_irqs(icp_pic_set_irq, s, 32);
s->base = base; s->base = base;
s->parent = parent;
s->parent_irq = parent_irq; s->parent_irq = parent_irq;
s->parent_fiq = parent_fiq; s->parent_fiq = parent_fiq;
iomemtype = cpu_register_io_memory(0, icp_pic_readfn, iomemtype = cpu_register_io_memory(0, icp_pic_readfn,
icp_pic_writefn, s); icp_pic_writefn, s);
cpu_register_physical_memory(base, 0x007fffff, iomemtype); cpu_register_physical_memory(base, 0x007fffff, iomemtype);
/* ??? Save/restore. */ /* ??? Save/restore. */
return s; return qi;
} }
/* CP control registers. */ /* CP control registers. */
@@ -475,8 +469,8 @@ static void integratorcp_init(int ram_size, int vga_ram_size, int boot_device,
{ {
CPUState *env; CPUState *env;
uint32_t bios_offset; uint32_t bios_offset;
icp_pic_state *pic; qemu_irq *pic;
void *cpu_pic; qemu_irq *cpu_pic;
env = cpu_init(); env = cpu_init();
if (!cpu_model) 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); integratorcm_init(ram_size >> 20, bios_offset);
cpu_pic = arm_pic_init_cpu(env); cpu_pic = arm_pic_init_cpu(env);
pic = icp_pic_init(0x14000000, cpu_pic, ARM_PIC_CPU_IRQ, ARM_PIC_CPU_FIQ); pic = icp_pic_init(0x14000000, cpu_pic[ARM_PIC_CPU_IRQ],
icp_pic_init(0xca000000, pic, 26, -1); cpu_pic[ARM_PIC_CPU_FIQ]);
icp_pic_init(0xca000000, pic[26], NULL);
icp_pit_init(0x13000000, pic, 5); icp_pit_init(0x13000000, pic, 5);
pl011_init(0x16000000, pic, 1, serial_hds[0]); pl011_init(0x16000000, pic[1], serial_hds[0]);
pl011_init(0x17000000, pic, 2, serial_hds[1]); pl011_init(0x17000000, pic[2], serial_hds[1]);
icp_control_init(0xcb000000); icp_control_init(0xcb000000);
pl050_init(0x18000000, pic, 3, 0); pl050_init(0x18000000, pic[3], 0);
pl050_init(0x19000000, pic, 4, 1); pl050_init(0x19000000, pic[4], 1);
pl181_init(0x1c000000, sd_bdrv, pic, 23, 24); pl181_init(0x1c000000, sd_bdrv, pic[23], pic[24]);
if (nd_table[0].vlan) { if (nd_table[0].vlan) {
if (nd_table[0].model == NULL if (nd_table[0].model == NULL
|| strcmp(nd_table[0].model, "smc91c111") == 0) { || strcmp(nd_table[0].model, "smc91c111") == 0) {
smc91c111_init(&nd_table[0], 0xc8000000, pic, 27); smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
} else { } else {
fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);
exit (1); 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, arm_load_kernel(env, ram_size, kernel_filename, kernel_cmdline,
initrd_filename, 0x113); initrd_filename, 0x113);

Some files were not shown because too many files have changed in this diff Show More