 65b4c8c759
			
		
	
	
		65b4c8c759
		
	
	
	
	
		
			
			Fix 'Identifer' -> 'Identifier' typo.
Cc: Laurent Vivier <laurent@vivier.eu>
Fixes: 8c6df16ff60 ("hw/char: add goldfish-tty")
Fixes: 87855593903 ("hw/intc: add goldfish-pic")
Fixes: 2fde99ee312 ("m68k: add an interrupt controller")
Fixes: 0791bc02b8f ("m68k: add a system controller")
Fixes: e1cecdca559 ("m68k: add Virtual M68k Machine")
Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Laurent Vivier <laurent@vivier.eu>
Message-Id: <20211103105311.3399293-1-f4bug@amsat.org>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
		
	
			
		
			
				
	
	
		
			120 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			120 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*
 | |
|  * SPDX-License-Identifier: GPL-2.0-or-later
 | |
|  *
 | |
|  * QEMU Motorola 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 = M68K_IRQC_LEVEL_7; i >= M68K_IRQC_LEVEL_1; i--) {
 | |
|         if ((s->ipr >> i) & 1) {
 | |
|             m68k_set_irq_level(cpu, i + 1, i + M68K_IRQC_AUTOVECTOR_BASE);
 | |
|             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, M68K_IRQC_LEVEL_NUM);
 | |
| }
 | |
| 
 | |
| static void m68k_nmi(NMIState *n, int cpu_index, Error **errp)
 | |
| {
 | |
|     m68k_set_irq(n, M68K_IRQC_LEVEL_7, 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);
 |