Message ID | 1254305917-14784-58-git-send-email-yamahata@valinux.co.jp |
---|---|
State | Superseded |
Headers | show |
On Wed, Sep 30, 2009 at 07:18:33PM +0900, Isaku Yamahata wrote: > Add hooks to ioapic. > This is necessary for pci interrupt routing mode from > PIC mode to IO APIC mode. According to my very brief looking at ICH9 spec switching from PIC mode to IO APIC mode is done separately for each PIRQ by setting bit 7 of PIRQ[n]_ROUT register to 1. This callback looks completely out of place. > > Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> > --- > hw/ioapic.c | 20 +++++++++++++++++++- > hw/pc.h | 2 ++ > 2 files changed, 21 insertions(+), 1 deletions(-) > > diff --git a/hw/ioapic.c b/hw/ioapic.c > index a9a8e00..882ca9d 100644 > --- a/hw/ioapic.c > +++ b/hw/ioapic.c > @@ -53,8 +53,16 @@ struct IOAPICState { > > uint32_t irr; > uint64_t ioredtbl[IOAPIC_NUM_PINS]; > + ioapic_update_fn update_fn; > + void *opaque; > }; > > +static void ioapic_callback(IOAPICState *s, int reset) > +{ > + if (s->update_fn) > + s->update_fn(s->opaque, reset); > +} > + > static void ioapic_service(IOAPICState *s) > { > uint8_t i; > @@ -186,6 +194,7 @@ static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t va > s->ioredtbl[index] &= ~0xffffffffULL; > s->ioredtbl[index] |= val; > } > + ioapic_callback(s, 0); > ioapic_service(s); > } > } > @@ -210,6 +219,8 @@ static void ioapic_reset(void *opaque) > IOAPICState *s = opaque; > int i; > > + ioapic_callback(s, 1); > + > memset(s, 0, sizeof(*s)); > for(i = 0; i < IOAPIC_NUM_PINS; i++) > s->ioredtbl[i] = 1 << 16; /* mask LVT */ > @@ -227,13 +238,15 @@ static CPUWriteMemoryFunc * const ioapic_mem_write[3] = { > ioapic_mem_writel, > }; > > -qemu_irq *ioapic_init(void) > +qemu_irq *ioapic_init_with_arg(ioapic_update_fn update_fn, void *opaque) > { > IOAPICState *s; > qemu_irq *irq; > int io_memory; > > s = qemu_mallocz(sizeof(IOAPICState)); > + s->update_fn = update_fn; > + s->opaque = opaque; > ioapic_reset(s); > > io_memory = cpu_register_io_memory(ioapic_mem_read, > @@ -246,3 +259,8 @@ qemu_irq *ioapic_init(void) > > return irq; > } > + > +qemu_irq *ioapic_init(void) > +{ > + return ioapic_init_with_arg(NULL, NULL); > +} > diff --git a/hw/pc.h b/hw/pc.h > index 7577956..44eac49 100644 > --- a/hw/pc.h > +++ b/hw/pc.h > @@ -52,6 +52,8 @@ int apic_accept_pic_intr(CPUState *env); > void apic_deliver_pic_intr(CPUState *env, int level); > int apic_get_interrupt(CPUState *env); > qemu_irq *ioapic_init(void); > +typedef void (*ioapic_update_fn)(void *opaque, int reset); > +qemu_irq *ioapic_init_with_arg(ioapic_update_fn update_fn, void *opaque); > void apic_reset_irq_delivered(void); > int apic_get_irq_delivered(void); > > -- > 1.6.0.2 > > -- Gleb.
On 10/01/2009 03:37 PM, Gleb Natapov wrote: > On Wed, Sep 30, 2009 at 07:18:33PM +0900, Isaku Yamahata wrote: > >> Add hooks to ioapic. >> This is necessary for pci interrupt routing mode from >> PIC mode to IO APIC mode. >> > According to my very brief looking at ICH9 spec switching from PIC mode > to IO APIC mode is done separately for each PIRQ by setting bit 7 of > PIRQ[n]_ROUT register to 1. This callback looks completely out of place. > Disassembling the _PIC and _PRT methods of a Q35 machine will probably yield how this is done on real hardware.
diff --git a/hw/ioapic.c b/hw/ioapic.c index a9a8e00..882ca9d 100644 --- a/hw/ioapic.c +++ b/hw/ioapic.c @@ -53,8 +53,16 @@ struct IOAPICState { uint32_t irr; uint64_t ioredtbl[IOAPIC_NUM_PINS]; + ioapic_update_fn update_fn; + void *opaque; }; +static void ioapic_callback(IOAPICState *s, int reset) +{ + if (s->update_fn) + s->update_fn(s->opaque, reset); +} + static void ioapic_service(IOAPICState *s) { uint8_t i; @@ -186,6 +194,7 @@ static void ioapic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t va s->ioredtbl[index] &= ~0xffffffffULL; s->ioredtbl[index] |= val; } + ioapic_callback(s, 0); ioapic_service(s); } } @@ -210,6 +219,8 @@ static void ioapic_reset(void *opaque) IOAPICState *s = opaque; int i; + ioapic_callback(s, 1); + memset(s, 0, sizeof(*s)); for(i = 0; i < IOAPIC_NUM_PINS; i++) s->ioredtbl[i] = 1 << 16; /* mask LVT */ @@ -227,13 +238,15 @@ static CPUWriteMemoryFunc * const ioapic_mem_write[3] = { ioapic_mem_writel, }; -qemu_irq *ioapic_init(void) +qemu_irq *ioapic_init_with_arg(ioapic_update_fn update_fn, void *opaque) { IOAPICState *s; qemu_irq *irq; int io_memory; s = qemu_mallocz(sizeof(IOAPICState)); + s->update_fn = update_fn; + s->opaque = opaque; ioapic_reset(s); io_memory = cpu_register_io_memory(ioapic_mem_read, @@ -246,3 +259,8 @@ qemu_irq *ioapic_init(void) return irq; } + +qemu_irq *ioapic_init(void) +{ + return ioapic_init_with_arg(NULL, NULL); +} diff --git a/hw/pc.h b/hw/pc.h index 7577956..44eac49 100644 --- a/hw/pc.h +++ b/hw/pc.h @@ -52,6 +52,8 @@ int apic_accept_pic_intr(CPUState *env); void apic_deliver_pic_intr(CPUState *env, int level); int apic_get_interrupt(CPUState *env); qemu_irq *ioapic_init(void); +typedef void (*ioapic_update_fn)(void *opaque, int reset); +qemu_irq *ioapic_init_with_arg(ioapic_update_fn update_fn, void *opaque); void apic_reset_irq_delivered(void); int apic_get_irq_delivered(void);
Add hooks to ioapic. This is necessary for pci interrupt routing mode from PIC mode to IO APIC mode. Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> --- hw/ioapic.c | 20 +++++++++++++++++++- hw/pc.h | 2 ++ 2 files changed, 21 insertions(+), 1 deletions(-)