Message ID | 20201220112615.933036-5-laurent@vivier.eu |
---|---|
State | New |
Headers | show |
Series | m68k: add Virtual M68k Machine | expand |
On 12/20/20 12:26 PM, Laurent Vivier wrote: > Signed-off-by: Laurent Vivier <laurent@vivier.eu> > --- > include/hw/intc/m68k_irqc.h | 28 +++++++++ > hw/intc/m68k_irqc.c | 120 ++++++++++++++++++++++++++++++++++++ Missing MAINTAINERS entries? > hw/intc/Kconfig | 3 + > hw/intc/meson.build | 1 + > 4 files changed, 152 insertions(+) > create mode 100644 include/hw/intc/m68k_irqc.h > create mode 100644 hw/intc/m68k_irqc.c > > diff --git a/include/hw/intc/m68k_irqc.h b/include/hw/intc/m68k_irqc.h > new file mode 100644 > index 000000000000..c40b1b4df8fa > --- /dev/null > +++ b/include/hw/intc/m68k_irqc.h > @@ -0,0 +1,28 @@ > +/* > + * SPDX-License-Identifer: GPL-2.0-or-later > + * > + * QEMU Motorla 680x0 IRQ Controller Typo "Motorola". Are there any specs to refer at? > + * > + * (c) 2020 Laurent Vivier <laurent@vivier.eu> > + * > + */
Le 24/01/2021 à 17:46, Philippe Mathieu-Daudé a écrit : > On 12/20/20 12:26 PM, Laurent Vivier wrote: >> Signed-off-by: Laurent Vivier <laurent@vivier.eu> >> --- >> include/hw/intc/m68k_irqc.h | 28 +++++++++ >> hw/intc/m68k_irqc.c | 120 ++++++++++++++++++++++++++++++++++++ > > Missing MAINTAINERS entries? new devices are added in patch 7 (where I add the machine and the section in MAINTAINER), but I've missed this one. Thanks. > >> hw/intc/Kconfig | 3 + >> hw/intc/meson.build | 1 + >> 4 files changed, 152 insertions(+) >> create mode 100644 include/hw/intc/m68k_irqc.h >> create mode 100644 hw/intc/m68k_irqc.c >> >> diff --git a/include/hw/intc/m68k_irqc.h b/include/hw/intc/m68k_irqc.h >> new file mode 100644 >> index 000000000000..c40b1b4df8fa >> --- /dev/null >> +++ b/include/hw/intc/m68k_irqc.h >> @@ -0,0 +1,28 @@ >> +/* >> + * SPDX-License-Identifer: GPL-2.0-or-later >> + * >> + * QEMU Motorla 680x0 IRQ Controller > > Typo "Motorola". Thank you (there is another typo: "q800_irq_register_types" that must be renamed) > Are there any specs to refer at? > There is no specs. It's a (generic) copy of the GLUE device we already have for q800. I don't update Q800 because the GLUE device may disappear because Q800 uses actually djMEMC that is also a memory controller (I have that in my q800-dev branch, but for the moment it's only needed for the MacROM and Mark is working on that). Thanks, Laurent
On 12/20/20 12:26 PM, Laurent Vivier wrote: > Signed-off-by: Laurent Vivier <laurent@vivier.eu> > --- > include/hw/intc/m68k_irqc.h | 28 +++++++++ > hw/intc/m68k_irqc.c | 120 ++++++++++++++++++++++++++++++++++++ > hw/intc/Kconfig | 3 + > hw/intc/meson.build | 1 + > 4 files changed, 152 insertions(+) > create mode 100644 include/hw/intc/m68k_irqc.h > create mode 100644 hw/intc/m68k_irqc.c > > diff --git a/include/hw/intc/m68k_irqc.h b/include/hw/intc/m68k_irqc.h > new file mode 100644 > index 000000000000..c40b1b4df8fa > --- /dev/null > +++ b/include/hw/intc/m68k_irqc.h > @@ -0,0 +1,28 @@ > +/* > + * SPDX-License-Identifer: GPL-2.0-or-later > + * > + * QEMU Motorla 680x0 IRQ Controller > + * > + * (c) 2020 Laurent Vivier <laurent@vivier.eu> > + * > + */ > + > +#ifndef M68K_IRQC_H > +#define M68K_IRQC_H > + > +#include "hw/sysbus.h" > + > +#define TYPE_M68K_IRQC "m68k-irq-controller" > +#define M68K_IRQC(obj) OBJECT_CHECK(M68KIRQCState, (obj), \ > + TYPE_M68K_IRQC) > + > +typedef struct M68KIRQCState { > + SysBusDevice parent_obj; > + > + uint8_t ipr; > + > + /* statistics */ > + uint64_t stats_irq_count[7]; So we have 8 IRQs, one is NMI. Is that correct? Could you add #definitions? Patch LGTM but I'll wait for definitions to give a R-b ;) > +} M68KIRQCState; > + > +#endif
diff --git a/include/hw/intc/m68k_irqc.h b/include/hw/intc/m68k_irqc.h new file mode 100644 index 000000000000..c40b1b4df8fa --- /dev/null +++ b/include/hw/intc/m68k_irqc.h @@ -0,0 +1,28 @@ +/* + * SPDX-License-Identifer: GPL-2.0-or-later + * + * QEMU Motorla 680x0 IRQ Controller + * + * (c) 2020 Laurent Vivier <laurent@vivier.eu> + * + */ + +#ifndef M68K_IRQC_H +#define M68K_IRQC_H + +#include "hw/sysbus.h" + +#define TYPE_M68K_IRQC "m68k-irq-controller" +#define M68K_IRQC(obj) OBJECT_CHECK(M68KIRQCState, (obj), \ + TYPE_M68K_IRQC) + +typedef struct M68KIRQCState { + SysBusDevice parent_obj; + + uint8_t ipr; + + /* statistics */ + uint64_t stats_irq_count[7]; +} M68KIRQCState; + +#endif diff --git a/hw/intc/m68k_irqc.c b/hw/intc/m68k_irqc.c new file mode 100644 index 000000000000..bc68d8fe084a --- /dev/null +++ b/hw/intc/m68k_irqc.c @@ -0,0 +1,120 @@ +/* + * SPDX-License-Identifer: GPL-2.0-or-later + * + * QEMU Motorla 680x0 IRQ Controller + * + * (c) 2020 Laurent Vivier <laurent@vivier.eu> + * + */ + +#include "qemu/osdep.h" +#include "cpu.h" +#include "migration/vmstate.h" +#include "monitor/monitor.h" +#include "hw/nmi.h" +#include "hw/intc/intc.h" +#include "hw/intc/m68k_irqc.h" + + +static bool m68k_irqc_get_statistics(InterruptStatsProvider *obj, + uint64_t **irq_counts, unsigned int *nb_irqs) +{ + M68KIRQCState *s = M68K_IRQC(obj); + + *irq_counts = s->stats_irq_count; + *nb_irqs = ARRAY_SIZE(s->stats_irq_count); + return true; +} + +static void m68k_irqc_print_info(InterruptStatsProvider *obj, Monitor *mon) +{ + M68KIRQCState *s = M68K_IRQC(obj); + monitor_printf(mon, "m68k-irqc: ipr=0x%x\n", s->ipr); +} + +static void m68k_set_irq(void *opaque, int irq, int level) +{ + M68KIRQCState *s = opaque; + M68kCPU *cpu = M68K_CPU(first_cpu); + int i; + + + if (level) { + s->ipr |= 1 << irq; + s->stats_irq_count[irq]++; + } else { + s->ipr &= ~(1 << irq); + } + + for (i = 7; i >= 0; i--) { + if ((s->ipr >> i) & 1) { + m68k_set_irq_level(cpu, i + 1, i + 25); + return; + } + } + m68k_set_irq_level(cpu, 0, 0); +} + +static void m68k_irqc_reset(DeviceState *d) +{ + M68KIRQCState *s = M68K_IRQC(d); + int i; + + s->ipr = 0; + for (i = 0; i < ARRAY_SIZE(s->stats_irq_count); i++) { + s->stats_irq_count[i] = 0; + } +} + +static void m68k_irqc_instance_init(Object *obj) +{ + qdev_init_gpio_in(DEVICE(obj), m68k_set_irq, 8); +} + +static void m68k_nmi(NMIState *n, int cpu_index, Error **errp) +{ + m68k_set_irq(n, 6, 1); +} + +static const VMStateDescription vmstate_m68k_irqc = { + .name = "m68k-irqc", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT8(ipr, M68KIRQCState), + VMSTATE_END_OF_LIST() + } +}; + +static void m68k_irqc_class_init(ObjectClass *oc, void *data) + { + DeviceClass *dc = DEVICE_CLASS(oc); + NMIClass *nc = NMI_CLASS(oc); + InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(oc); + + nc->nmi_monitor_handler = m68k_nmi; + dc->reset = m68k_irqc_reset; + dc->vmsd = &vmstate_m68k_irqc; + ic->get_statistics = m68k_irqc_get_statistics; + ic->print_info = m68k_irqc_print_info; +} + +static const TypeInfo m68k_irqc_type_info = { + .name = TYPE_M68K_IRQC, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(M68KIRQCState), + .instance_init = m68k_irqc_instance_init, + .class_init = m68k_irqc_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_NMI }, + { TYPE_INTERRUPT_STATS_PROVIDER }, + { } + }, +}; + +static void q800_irq_register_types(void) +{ + type_register_static(&m68k_irqc_type_info); +} + +type_init(q800_irq_register_types); diff --git a/hw/intc/Kconfig b/hw/intc/Kconfig index 7ed79e7ac29f..318d76c7cb52 100644 --- a/hw/intc/Kconfig +++ b/hw/intc/Kconfig @@ -76,3 +76,6 @@ config SIFIVE_PLIC config GOLDFISH_PIC bool + +config M68K_IRQC + bool diff --git a/hw/intc/meson.build b/hw/intc/meson.build index 8a5dfe4289ae..81bd0191f9cd 100644 --- a/hw/intc/meson.build +++ b/hw/intc/meson.build @@ -55,3 +55,4 @@ specific_ss.add(when: 'CONFIG_XIVE', if_true: files('xive.c')) specific_ss.add(when: 'CONFIG_XIVE_KVM', if_true: files('spapr_xive_kvm.c')) specific_ss.add(when: 'CONFIG_XIVE_SPAPR', if_true: files('spapr_xive.c')) specific_ss.add(when: 'CONFIG_GOLDFISH_PIC', if_true: files('goldfish_pic.c')) +specific_ss.add(when: 'CONFIG_M68K_IRQC', if_true: files('m68k_irqc.c'))
Signed-off-by: Laurent Vivier <laurent@vivier.eu> --- include/hw/intc/m68k_irqc.h | 28 +++++++++ hw/intc/m68k_irqc.c | 120 ++++++++++++++++++++++++++++++++++++ hw/intc/Kconfig | 3 + hw/intc/meson.build | 1 + 4 files changed, 152 insertions(+) create mode 100644 include/hw/intc/m68k_irqc.h create mode 100644 hw/intc/m68k_irqc.c