/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * QEMU Loongson 7A1000 I/O interrupt controller.
 *
 * Copyright (C) 2021 Loongson Technology Corporation Limited
 */

#include "qemu/osdep.h"
#include "hw/sysbus.h"
#include "hw/loongarch/virt.h"
#include "hw/irq.h"
#include "hw/intc/loongarch_pch_pic.h"
#include "migration/vmstate.h"
#include "trace.h"

static void pch_pic_update_irq(LoongArchPCHPIC *s, uint64_t mask, int level)
{
    uint64_t val;
    int irq;

    if (level) {
        val = mask & s->intirr & ~s->int_mask;
        if (val) {
            irq = ctz64(val);
            s->intisr |= MAKE_64BIT_MASK(irq, 1);
            qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 1);
        }
    } else {
        val = mask & s->intisr;
        if (val) {
            irq = ctz64(val);
            s->intisr &= ~MAKE_64BIT_MASK(irq, 1);
            qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 0);
        }
    }
}

static void pch_pic_irq_handler(void *opaque, int irq, int level)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
    uint64_t mask = 1ULL << irq;

    assert(irq < PCH_PIC_IRQ_NUM);
    trace_loongarch_pch_pic_irq_handler(irq, level);

    if (s->intedge & mask) {
        /* Edge triggered */
        if (level) {
            if ((s->last_intirr & mask) == 0) {
                s->intirr |= mask;
            }
            s->last_intirr |= mask;
        } else {
            s->last_intirr &= ~mask;
        }
    } else {
        /* Level triggered */
        if (level) {
            s->intirr |= mask;
            s->last_intirr |= mask;
        } else {
            s->intirr &= ~mask;
            s->last_intirr &= ~mask;
        }
    }
    pch_pic_update_irq(s, mask, level);
}

static uint64_t loongarch_pch_pic_low_readw(void *opaque, hwaddr addr,
                                            unsigned size)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
    uint64_t val = 0;
    uint32_t offset = addr & 0xfff;

    switch (offset) {
    case PCH_PIC_INT_ID_LO:
        val = PCH_PIC_INT_ID_VAL;
        break;
    case PCH_PIC_INT_ID_HI:
        val = PCH_PIC_INT_ID_NUM;
        break;
    case PCH_PIC_INT_MASK_LO:
        val = (uint32_t)s->int_mask;
        break;
    case PCH_PIC_INT_MASK_HI:
        val = s->int_mask >> 32;
        break;
    case PCH_PIC_INT_EDGE_LO:
        val = (uint32_t)s->intedge;
        break;
    case PCH_PIC_INT_EDGE_HI:
        val = s->intedge >> 32;
        break;
    case PCH_PIC_HTMSI_EN_LO:
        val = (uint32_t)s->htmsi_en;
        break;
    case PCH_PIC_HTMSI_EN_HI:
        val = s->htmsi_en >> 32;
        break;
    case PCH_PIC_AUTO_CTRL0_LO:
    case PCH_PIC_AUTO_CTRL0_HI:
    case PCH_PIC_AUTO_CTRL1_LO:
    case PCH_PIC_AUTO_CTRL1_HI:
        break;
    default:
        break;
    }

    trace_loongarch_pch_pic_low_readw(size, addr, val);
    return val;
}

static uint64_t get_writew_val(uint64_t value, uint32_t target, bool hi)
{
    uint64_t mask = 0xffffffff00000000;
    uint64_t data = target;

    return hi ? (value & ~mask) | (data << 32) : (value & mask) | data;
}

static void loongarch_pch_pic_low_writew(void *opaque, hwaddr addr,
                                         uint64_t value, unsigned size)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
    uint32_t offset, old_valid, data = (uint32_t)value;
    uint64_t old, int_mask;
    offset = addr & 0xfff;

    trace_loongarch_pch_pic_low_writew(size, addr, data);

    switch (offset) {
    case PCH_PIC_INT_MASK_LO:
        old = s->int_mask;
        s->int_mask = get_writew_val(old, data, 0);
        old_valid = (uint32_t)old;
        if (old_valid & ~data) {
            pch_pic_update_irq(s, (old_valid & ~data), 1);
        }
        if (~old_valid & data) {
            pch_pic_update_irq(s, (~old_valid & data), 0);
        }
        break;
    case PCH_PIC_INT_MASK_HI:
        old = s->int_mask;
        s->int_mask = get_writew_val(old, data, 1);
        old_valid = (uint32_t)(old >> 32);
        int_mask = old_valid & ~data;
        if (int_mask) {
            pch_pic_update_irq(s, int_mask << 32, 1);
        }
        int_mask = ~old_valid & data;
        if (int_mask) {
            pch_pic_update_irq(s, int_mask << 32, 0);
        }
        break;
    case PCH_PIC_INT_EDGE_LO:
        s->intedge = get_writew_val(s->intedge, data, 0);
        break;
    case PCH_PIC_INT_EDGE_HI:
        s->intedge = get_writew_val(s->intedge, data, 1);
        break;
    case PCH_PIC_INT_CLEAR_LO:
        if (s->intedge & data) {
            s->intirr &= (~data);
            pch_pic_update_irq(s, data, 0);
            s->intisr &= (~data);
        }
        break;
    case PCH_PIC_INT_CLEAR_HI:
        value <<= 32;
        if (s->intedge & value) {
            s->intirr &= (~value);
            pch_pic_update_irq(s, value, 0);
            s->intisr &= (~value);
        }
        break;
    case PCH_PIC_HTMSI_EN_LO:
        s->htmsi_en = get_writew_val(s->htmsi_en, data, 0);
        break;
    case PCH_PIC_HTMSI_EN_HI:
        s->htmsi_en = get_writew_val(s->htmsi_en, data, 1);
        break;
    case PCH_PIC_AUTO_CTRL0_LO:
    case PCH_PIC_AUTO_CTRL0_HI:
    case PCH_PIC_AUTO_CTRL1_LO:
    case PCH_PIC_AUTO_CTRL1_HI:
        break;
    default:
        break;
    }
}

static uint64_t loongarch_pch_pic_high_readw(void *opaque, hwaddr addr,
                                        unsigned size)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
    uint64_t val = 0;
    uint32_t offset = addr & 0xfff;

    switch (offset) {
    case STATUS_LO_START:
        val = (uint32_t)(s->intisr & (~s->int_mask));
        break;
    case STATUS_HI_START:
        val = (s->intisr & (~s->int_mask)) >> 32;
        break;
    case POL_LO_START:
        val = (uint32_t)s->int_polarity;
        break;
    case POL_HI_START:
        val = s->int_polarity >> 32;
        break;
    default:
        break;
    }

    trace_loongarch_pch_pic_high_readw(size, addr, val);
    return val;
}

static void loongarch_pch_pic_high_writew(void *opaque, hwaddr addr,
                                     uint64_t value, unsigned size)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
    uint32_t offset, data = (uint32_t)value;
    offset = addr & 0xfff;

    trace_loongarch_pch_pic_high_writew(size, addr, data);

    switch (offset) {
    case STATUS_LO_START:
        s->intisr = get_writew_val(s->intisr, data, 0);
        break;
    case STATUS_HI_START:
        s->intisr = get_writew_val(s->intisr, data, 1);
        break;
    case POL_LO_START:
        s->int_polarity = get_writew_val(s->int_polarity, data, 0);
        break;
    case POL_HI_START:
        s->int_polarity = get_writew_val(s->int_polarity, data, 1);
        break;
    default:
        break;
    }
}

static uint64_t loongarch_pch_pic_readb(void *opaque, hwaddr addr,
                                        unsigned size)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
    uint64_t val = 0;
    uint32_t offset = (addr & 0xfff) + PCH_PIC_ROUTE_ENTRY_OFFSET;
    int64_t offset_tmp;

    switch (offset) {
    case PCH_PIC_HTMSI_VEC_OFFSET ... PCH_PIC_HTMSI_VEC_END:
        offset_tmp = offset - PCH_PIC_HTMSI_VEC_OFFSET;
        if (offset_tmp >= 0 && offset_tmp < 64) {
            val = s->htmsi_vector[offset_tmp];
        }
        break;
    case PCH_PIC_ROUTE_ENTRY_OFFSET ... PCH_PIC_ROUTE_ENTRY_END:
        offset_tmp = offset - PCH_PIC_ROUTE_ENTRY_OFFSET;
        if (offset_tmp >= 0 && offset_tmp < 64) {
            val = s->route_entry[offset_tmp];
        }
        break;
    default:
        break;
    }

    trace_loongarch_pch_pic_readb(size, addr, val);
    return val;
}

static void loongarch_pch_pic_writeb(void *opaque, hwaddr addr,
                                     uint64_t data, unsigned size)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(opaque);
    int32_t offset_tmp;
    uint32_t offset = (addr & 0xfff) + PCH_PIC_ROUTE_ENTRY_OFFSET;

    trace_loongarch_pch_pic_writeb(size, addr, data);

    switch (offset) {
    case PCH_PIC_HTMSI_VEC_OFFSET ... PCH_PIC_HTMSI_VEC_END:
        offset_tmp = offset - PCH_PIC_HTMSI_VEC_OFFSET;
        if (offset_tmp >= 0 && offset_tmp < 64) {
            s->htmsi_vector[offset_tmp] = (uint8_t)(data & 0xff);
        }
        break;
    case PCH_PIC_ROUTE_ENTRY_OFFSET ... PCH_PIC_ROUTE_ENTRY_END:
        offset_tmp = offset - PCH_PIC_ROUTE_ENTRY_OFFSET;
        if (offset_tmp >= 0 && offset_tmp < 64) {
            s->route_entry[offset_tmp] = (uint8_t)(data & 0xff);
        }
        break;
    default:
        break;
    }
}

static const MemoryRegionOps loongarch_pch_pic_reg32_low_ops = {
    .read = loongarch_pch_pic_low_readw,
    .write = loongarch_pch_pic_low_writew,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static const MemoryRegionOps loongarch_pch_pic_reg32_high_ops = {
    .read = loongarch_pch_pic_high_readw,
    .write = loongarch_pch_pic_high_writew,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static const MemoryRegionOps loongarch_pch_pic_reg8_ops = {
    .read = loongarch_pch_pic_readb,
    .write = loongarch_pch_pic_writeb,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 1,
    },
    .impl = {
        .min_access_size = 1,
        .max_access_size = 1,
    },
    .endianness = DEVICE_LITTLE_ENDIAN,
};

static void loongarch_pch_pic_reset(DeviceState *d)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(d);
    int i;

    s->int_mask = -1;
    s->htmsi_en = 0x0;
    s->intedge  = 0x0;
    s->intclr   = 0x0;
    s->auto_crtl0 = 0x0;
    s->auto_crtl1 = 0x0;
    for (i = 0; i < 64; i++) {
        s->route_entry[i] = 0x1;
        s->htmsi_vector[i] = 0x0;
    }
    s->intirr = 0x0;
    s->intisr = 0x0;
    s->last_intirr = 0x0;
    s->int_polarity = 0x0;
}

static void loongarch_pch_pic_init(Object *obj)
{
    LoongArchPCHPIC *s = LOONGARCH_PCH_PIC(obj);
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    memory_region_init_io(&s->iomem32_low, obj,
                          &loongarch_pch_pic_reg32_low_ops,
                          s, PCH_PIC_NAME(.reg32_part1), 0x100);
    memory_region_init_io(&s->iomem8, obj, &loongarch_pch_pic_reg8_ops,
                          s, PCH_PIC_NAME(.reg8), 0x2a0);
    memory_region_init_io(&s->iomem32_high, obj,
                          &loongarch_pch_pic_reg32_high_ops,
                          s, PCH_PIC_NAME(.reg32_part2), 0xc60);
    sysbus_init_mmio(sbd, &s->iomem32_low);
    sysbus_init_mmio(sbd, &s->iomem8);
    sysbus_init_mmio(sbd, &s->iomem32_high);

    qdev_init_gpio_out(DEVICE(obj), s->parent_irq, PCH_PIC_IRQ_NUM);
    qdev_init_gpio_in(DEVICE(obj), pch_pic_irq_handler, PCH_PIC_IRQ_NUM);
}

static const VMStateDescription vmstate_loongarch_pch_pic = {
    .name = TYPE_LOONGARCH_PCH_PIC,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT64(int_mask, LoongArchPCHPIC),
        VMSTATE_UINT64(htmsi_en, LoongArchPCHPIC),
        VMSTATE_UINT64(intedge, LoongArchPCHPIC),
        VMSTATE_UINT64(intclr, LoongArchPCHPIC),
        VMSTATE_UINT64(auto_crtl0, LoongArchPCHPIC),
        VMSTATE_UINT64(auto_crtl1, LoongArchPCHPIC),
        VMSTATE_UINT8_ARRAY(route_entry, LoongArchPCHPIC, 64),
        VMSTATE_UINT8_ARRAY(htmsi_vector, LoongArchPCHPIC, 64),
        VMSTATE_UINT64(last_intirr, LoongArchPCHPIC),
        VMSTATE_UINT64(intirr, LoongArchPCHPIC),
        VMSTATE_UINT64(intisr, LoongArchPCHPIC),
        VMSTATE_UINT64(int_polarity, LoongArchPCHPIC),
        VMSTATE_END_OF_LIST()
    }
};

static void loongarch_pch_pic_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->reset = loongarch_pch_pic_reset;
    dc->vmsd = &vmstate_loongarch_pch_pic;
}

static const TypeInfo loongarch_pch_pic_info = {
    .name          = TYPE_LOONGARCH_PCH_PIC,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(LoongArchPCHPIC),
    .instance_init = loongarch_pch_pic_init,
    .class_init    = loongarch_pch_pic_class_init,
};

static void loongarch_pch_pic_register_types(void)
{
    type_register_static(&loongarch_pch_pic_info);
}

type_init(loongarch_pch_pic_register_types)
