mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 15:53:54 -06:00
Unify IRQ handling.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2635 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
b6e27ab8b1
commit
d537cf6c86
71 changed files with 592 additions and 624 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue