/*
 * 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 "hw/qdev-properties.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, GString *buf)
{
    M68KIRQCState *s = M68K_IRQC(obj);
    g_string_append_printf(buf, "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(s->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 = (const VMStateField[]) {
        VMSTATE_UINT8(ipr, M68KIRQCState),
        VMSTATE_END_OF_LIST()
    }
};

static const Property m68k_irqc_properties[] = {
    DEFINE_PROP_LINK("m68k-cpu", M68KIRQCState, cpu,
                     TYPE_M68K_CPU, ArchCPU *),
};

static void m68k_irqc_class_init(ObjectClass *oc, const void *data)
 {
    DeviceClass *dc = DEVICE_CLASS(oc);
    NMIClass *nc = NMI_CLASS(oc);
    InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(oc);

    device_class_set_props(dc, m68k_irqc_properties);
    nc->nmi_monitor_handler = m68k_nmi;
    device_class_set_legacy_reset(dc, 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 = (const 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);
