Message ID | 20220901162613.6939-8-shentey@gmail.com |
---|---|
State | New |
Headers | show |
Series | Consolidate PIIX south bridges | expand |
On 01/09/2022 17:25, Bernhard Beschow wrote: > Having an i8259 proxy allows for ISA PICs to be created and wired up in > southbridges. This is especially interesting for PIIX3 for two reasons: > First, the southbridge doesn't need to care about the virtualization > technology used (KVM, TCG, Xen) due to in-IRQs (where devices get > attached) and out-IRQs (which will trigger the IRQs of the respective > virtzalization technology) are separated. Second, since the in-IRQs are > populated with fully initialized qemu_irq's, they can already be wired > up inside PIIX3. > > Signed-off-by: Bernhard Beschow <shentey@gmail.com> > --- > hw/intc/i8259.c | 27 +++++++++++++++++++++++++++ > include/hw/intc/i8259.h | 14 ++++++++++++++ > 2 files changed, 41 insertions(+) > > diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c > index cc4e21ffec..531f6cca53 100644 > --- a/hw/intc/i8259.c > +++ b/hw/intc/i8259.c > @@ -458,9 +458,36 @@ static const TypeInfo i8259_info = { > .class_size = sizeof(PICClass), > }; > > +static void isapic_set_irq(void *opaque, int irq, int level) > +{ > + ISAPICState *s = opaque; > + > + qemu_set_irq(s->out_irqs[irq], level); > +} > + > +static void isapic_init(Object *obj) > +{ > + ISAPICState *s = ISA_PIC(obj); > + > + qdev_init_gpio_in(DEVICE(s), isapic_set_irq, ISA_NUM_IRQS); > + qdev_init_gpio_out(DEVICE(s), s->out_irqs, ISA_NUM_IRQS); > + > + for (int i = 0; i < ISA_NUM_IRQS; ++i) { > + s->in_irqs[i] = qdev_get_gpio_in(DEVICE(s), i); > + } > +} > + > +static const TypeInfo isapic_info = { > + .name = TYPE_ISA_PIC, > + .parent = TYPE_ISA_DEVICE, > + .instance_size = sizeof(ISAPICState), > + .instance_init = isapic_init, > +}; > + > static void pic_register_types(void) > { > type_register_static(&i8259_info); > + type_register_static(&isapic_info); > } > > type_init(pic_register_types) > diff --git a/include/hw/intc/i8259.h b/include/hw/intc/i8259.h > index e2b1e8c59a..0246ab6ac6 100644 > --- a/include/hw/intc/i8259.h > +++ b/include/hw/intc/i8259.h > @@ -1,6 +1,20 @@ > #ifndef HW_I8259_H > #define HW_I8259_H > > +#include "qom/object.h" > +#include "hw/isa/isa.h" > +#include "qemu/typedefs.h" > + > +#define TYPE_ISA_PIC "isa-pic" > +OBJECT_DECLARE_SIMPLE_TYPE(ISAPICState, ISA_PIC) > + > +struct ISAPICState { > + ISADevice parent_obj; > + > + qemu_irq in_irqs[ISA_NUM_IRQS]; > + qemu_irq out_irqs[ISA_NUM_IRQS]; > +}; > + > /* i8259.c */ > > extern DeviceState *isa_pic; So effectively this proxy device is working around the issue that we don't yet have a qdev-ified PIC that can be used to wire up ISA bus IRQs via qdev_connect_gpio_out(). Whilst ultimately this is the goal, I think having the proxy is a nice intermediate step as long as we can ensure that the device is not user-visible (i.e. it won't be exposed via the command line) so that this can be improved later. ATB, Mark.
diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c index cc4e21ffec..531f6cca53 100644 --- a/hw/intc/i8259.c +++ b/hw/intc/i8259.c @@ -458,9 +458,36 @@ static const TypeInfo i8259_info = { .class_size = sizeof(PICClass), }; +static void isapic_set_irq(void *opaque, int irq, int level) +{ + ISAPICState *s = opaque; + + qemu_set_irq(s->out_irqs[irq], level); +} + +static void isapic_init(Object *obj) +{ + ISAPICState *s = ISA_PIC(obj); + + qdev_init_gpio_in(DEVICE(s), isapic_set_irq, ISA_NUM_IRQS); + qdev_init_gpio_out(DEVICE(s), s->out_irqs, ISA_NUM_IRQS); + + for (int i = 0; i < ISA_NUM_IRQS; ++i) { + s->in_irqs[i] = qdev_get_gpio_in(DEVICE(s), i); + } +} + +static const TypeInfo isapic_info = { + .name = TYPE_ISA_PIC, + .parent = TYPE_ISA_DEVICE, + .instance_size = sizeof(ISAPICState), + .instance_init = isapic_init, +}; + static void pic_register_types(void) { type_register_static(&i8259_info); + type_register_static(&isapic_info); } type_init(pic_register_types) diff --git a/include/hw/intc/i8259.h b/include/hw/intc/i8259.h index e2b1e8c59a..0246ab6ac6 100644 --- a/include/hw/intc/i8259.h +++ b/include/hw/intc/i8259.h @@ -1,6 +1,20 @@ #ifndef HW_I8259_H #define HW_I8259_H +#include "qom/object.h" +#include "hw/isa/isa.h" +#include "qemu/typedefs.h" + +#define TYPE_ISA_PIC "isa-pic" +OBJECT_DECLARE_SIMPLE_TYPE(ISAPICState, ISA_PIC) + +struct ISAPICState { + ISADevice parent_obj; + + qemu_irq in_irqs[ISA_NUM_IRQS]; + qemu_irq out_irqs[ISA_NUM_IRQS]; +}; + /* i8259.c */ extern DeviceState *isa_pic;
Having an i8259 proxy allows for ISA PICs to be created and wired up in southbridges. This is especially interesting for PIIX3 for two reasons: First, the southbridge doesn't need to care about the virtualization technology used (KVM, TCG, Xen) due to in-IRQs (where devices get attached) and out-IRQs (which will trigger the IRQs of the respective virtzalization technology) are separated. Second, since the in-IRQs are populated with fully initialized qemu_irq's, they can already be wired up inside PIIX3. Signed-off-by: Bernhard Beschow <shentey@gmail.com> --- hw/intc/i8259.c | 27 +++++++++++++++++++++++++++ include/hw/intc/i8259.h | 14 ++++++++++++++ 2 files changed, 41 insertions(+)