/*
 * 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 Property m68k_irqc_properties[] = {
    DEFINE_PROP_LINK("m68k-cpu", M68KIRQCState, cpu,
                     TYPE_M68K_CPU, ArchCPU *),
    DEFINE_PROP_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);

    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 = (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);
