/*
 * RX Interrupt Control Unit
 *
 * Warning: Only ICUa is supported.
 *
 * Datasheet: RX62N Group, RX621 Group User's Manual: Hardware
 *            (Rev.1.40 R01UH0033EJ0140)
 *
 * Copyright (c) 2019 Yoshinori Sato
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2 or later, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
#include "hw/irq.h"
#include "hw/registerfields.h"
#include "hw/qdev-properties.h"
#include "hw/intc/rx_icu.h"
#include "migration/vmstate.h"

REG8(IR, 0)
  FIELD(IR, IR,  0, 1)
REG8(DTCER, 0x100)
  FIELD(DTCER, DTCE,  0, 1)
REG8(IER, 0x200)
REG8(SWINTR, 0x2e0)
  FIELD(SWINTR, SWINT, 0, 1)
REG16(FIR, 0x2f0)
  FIELD(FIR, FVCT, 0,  8)
  FIELD(FIR, FIEN, 15, 1)
REG8(IPR, 0x300)
  FIELD(IPR, IPR, 0, 4)
REG8(DMRSR, 0x400)
REG8(IRQCR, 0x500)
  FIELD(IRQCR, IRQMD, 2, 2)
REG8(NMISR, 0x580)
  FIELD(NMISR, NMIST, 0, 1)
  FIELD(NMISR, LVDST, 1, 1)
  FIELD(NMISR, OSTST, 2, 1)
REG8(NMIER, 0x581)
  FIELD(NMIER, NMIEN, 0, 1)
  FIELD(NMIER, LVDEN, 1, 1)
  FIELD(NMIER, OSTEN, 2, 1)
REG8(NMICLR, 0x582)
  FIELD(NMICLR, NMICLR, 0, 1)
  FIELD(NMICLR, OSTCLR, 2, 1)
REG8(NMICR, 0x583)
  FIELD(NMICR, NMIMD, 3, 1)

static void set_irq(RXICUState *icu, int n_IRQ, int req)
{
    if ((icu->fir & R_FIR_FIEN_MASK) &&
        (icu->fir & R_FIR_FVCT_MASK) == n_IRQ) {
        qemu_set_irq(icu->_fir, req);
    } else {
        qemu_set_irq(icu->_irq, req);
    }
}

static uint16_t rxicu_level(RXICUState *icu, unsigned n)
{
    return (icu->ipr[icu->map[n]] << 8) | n;
}

static void rxicu_request(RXICUState *icu, int n_IRQ)
{
    int enable;

    enable = icu->ier[n_IRQ / 8] & (1 << (n_IRQ & 7));
    if (n_IRQ > 0 && enable != 0 && qatomic_read(&icu->req_irq) < 0) {
        qatomic_set(&icu->req_irq, n_IRQ);
        set_irq(icu, n_IRQ, rxicu_level(icu, n_IRQ));
    }
}

static void rxicu_set_irq(void *opaque, int n_IRQ, int level)
{
    RXICUState *icu = opaque;
    struct IRQSource *src;
    int issue;

    if (n_IRQ >= NR_IRQS) {
        error_report("%s: IRQ %d out of range", __func__, n_IRQ);
        return;
    }

    src = &icu->src[n_IRQ];

    level = (level != 0);
    switch (src->sense) {
    case TRG_LEVEL:
        /* level-sensitive irq */
        issue = level;
        src->level = level;
        break;
    case TRG_NEDGE:
        issue = (level == 0 && src->level == 1);
        src->level = level;
        break;
    case TRG_PEDGE:
        issue = (level == 1 && src->level == 0);
        src->level = level;
        break;
    case TRG_BEDGE:
        issue = ((level ^ src->level) & 1);
        src->level = level;
        break;
    default:
        g_assert_not_reached();
    }
    if (issue == 0 && src->sense == TRG_LEVEL) {
        icu->ir[n_IRQ] = 0;
        if (qatomic_read(&icu->req_irq) == n_IRQ) {
            /* clear request */
            set_irq(icu, n_IRQ, 0);
            qatomic_set(&icu->req_irq, -1);
        }
        return;
    }
    if (issue) {
        icu->ir[n_IRQ] = 1;
        rxicu_request(icu, n_IRQ);
    }
}

static void rxicu_ack_irq(void *opaque, int no, int level)
{
    RXICUState *icu = opaque;
    int i;
    int n_IRQ;
    int max_pri;

    n_IRQ = qatomic_read(&icu->req_irq);
    if (n_IRQ < 0) {
        return;
    }
    qatomic_set(&icu->req_irq, -1);
    if (icu->src[n_IRQ].sense != TRG_LEVEL) {
        icu->ir[n_IRQ] = 0;
    }

    max_pri = 0;
    n_IRQ = -1;
    for (i = 0; i < NR_IRQS; i++) {
        if (icu->ir[i]) {
            if (max_pri < icu->ipr[icu->map[i]]) {
                n_IRQ = i;
                max_pri = icu->ipr[icu->map[i]];
            }
        }
    }

    if (n_IRQ >= 0) {
        rxicu_request(icu, n_IRQ);
    }
}

static uint64_t icu_read(void *opaque, hwaddr addr, unsigned size)
{
    RXICUState *icu = opaque;
    int reg = addr & 0xff;

    if ((addr != A_FIR && size != 1) ||
        (addr == A_FIR && size != 2)) {
        qemu_log_mask(LOG_GUEST_ERROR, "rx_icu: Invalid read size 0x%"
                                       HWADDR_PRIX "\n",
                      addr);
        return UINT64_MAX;
    }
    switch (addr) {
    case A_IR ... A_IR + 0xff:
        return icu->ir[reg] & R_IR_IR_MASK;
    case A_DTCER ... A_DTCER + 0xff:
        return icu->dtcer[reg] & R_DTCER_DTCE_MASK;
    case A_IER ... A_IER + 0x1f:
        return icu->ier[reg];
    case A_SWINTR:
        return 0;
    case A_FIR:
        return icu->fir & (R_FIR_FIEN_MASK | R_FIR_FVCT_MASK);
    case A_IPR ... A_IPR + 0x8f:
        return icu->ipr[reg] & R_IPR_IPR_MASK;
    case A_DMRSR:
    case A_DMRSR + 4:
    case A_DMRSR + 8:
    case A_DMRSR + 12:
        return icu->dmasr[reg >> 2];
    case A_IRQCR ... A_IRQCR + 0x1f:
        return icu->src[64 + reg].sense << R_IRQCR_IRQMD_SHIFT;
    case A_NMISR:
    case A_NMICLR:
        return 0;
    case A_NMIER:
        return icu->nmier;
    case A_NMICR:
        return icu->nmicr;
    default:
        qemu_log_mask(LOG_UNIMP, "rx_icu: Register 0x%" HWADDR_PRIX " "
                                 "not implemented.\n",
                      addr);
        break;
    }
    return UINT64_MAX;
}

static void icu_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
{
    RXICUState *icu = opaque;
    int reg = addr & 0xff;

    if ((addr != A_FIR && size != 1) ||
        (addr == A_FIR && size != 2)) {
        qemu_log_mask(LOG_GUEST_ERROR, "rx_icu: Invalid write size at "
                                       "0x%" HWADDR_PRIX "\n",
                      addr);
        return;
    }
    switch (addr) {
    case A_IR ... A_IR + 0xff:
        if (icu->src[reg].sense != TRG_LEVEL && val == 0) {
            icu->ir[reg] = 0;
        }
        break;
    case A_DTCER ... A_DTCER + 0xff:
        icu->dtcer[reg] = val & R_DTCER_DTCE_MASK;
        qemu_log_mask(LOG_UNIMP, "rx_icu: DTC not implemented\n");
        break;
    case A_IER ... A_IER + 0x1f:
        icu->ier[reg] = val;
        break;
    case A_SWINTR:
        if (val & R_SWINTR_SWINT_MASK) {
            qemu_irq_pulse(icu->_swi);
        }
        break;
    case A_FIR:
        icu->fir = val & (R_FIR_FIEN_MASK | R_FIR_FVCT_MASK);
        break;
    case A_IPR ... A_IPR + 0x8f:
        icu->ipr[reg] = val & R_IPR_IPR_MASK;
        break;
    case A_DMRSR:
    case A_DMRSR + 4:
    case A_DMRSR + 8:
    case A_DMRSR + 12:
        icu->dmasr[reg >> 2] = val;
        qemu_log_mask(LOG_UNIMP, "rx_icu: DMAC not implemented\n");
        break;
    case A_IRQCR ... A_IRQCR + 0x1f:
        icu->src[64 + reg].sense = val >> R_IRQCR_IRQMD_SHIFT;
        break;
    case A_NMICLR:
        break;
    case A_NMIER:
        icu->nmier |= val & (R_NMIER_NMIEN_MASK |
                             R_NMIER_LVDEN_MASK |
                             R_NMIER_OSTEN_MASK);
        break;
    case A_NMICR:
        if ((icu->nmier & R_NMIER_NMIEN_MASK) == 0) {
            icu->nmicr = val & R_NMICR_NMIMD_MASK;
        }
        break;
    default:
        qemu_log_mask(LOG_UNIMP, "rx_icu: Register 0x%" HWADDR_PRIX " "
                                 "not implemented\n",
                      addr);
        break;
    }
}

static const MemoryRegionOps icu_ops = {
    .write = icu_write,
    .read  = icu_read,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .impl = {
        .min_access_size = 1,
        .max_access_size = 2,
    },
    .valid = {
        .min_access_size = 1,
        .max_access_size = 2,
    },
};

static void rxicu_realize(DeviceState *dev, Error **errp)
{
    RXICUState *icu = RX_ICU(dev);
    int i, j;

    if (icu->init_sense == NULL) {
        qemu_log_mask(LOG_GUEST_ERROR,
                      "rx_icu: trigger-level property must be set.");
        return;
    }
    for (i = j = 0; i < NR_IRQS; i++) {
        if (icu->init_sense[j] == i) {
            icu->src[i].sense = TRG_LEVEL;
            if (j < icu->nr_sense) {
                j++;
            }
        } else {
            icu->src[i].sense = TRG_PEDGE;
        }
    }
    icu->req_irq = -1;
}

static void rxicu_init(Object *obj)
{
    SysBusDevice *d = SYS_BUS_DEVICE(obj);
    RXICUState *icu = RX_ICU(obj);

    memory_region_init_io(&icu->memory, OBJECT(icu), &icu_ops,
                          icu, "rx-icu", 0x600);
    sysbus_init_mmio(d, &icu->memory);

    qdev_init_gpio_in(DEVICE(d), rxicu_set_irq, NR_IRQS);
    qdev_init_gpio_in_named(DEVICE(d), rxicu_ack_irq, "ack", 1);
    sysbus_init_irq(d, &icu->_irq);
    sysbus_init_irq(d, &icu->_fir);
    sysbus_init_irq(d, &icu->_swi);
}

static void rxicu_fini(Object *obj)
{
    RXICUState *icu = RX_ICU(obj);
    g_free(icu->map);
    g_free(icu->init_sense);
}

static const VMStateDescription vmstate_rxicu = {
    .name = "rx-icu",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8_ARRAY(ir, RXICUState, NR_IRQS),
        VMSTATE_UINT8_ARRAY(dtcer, RXICUState, NR_IRQS),
        VMSTATE_UINT8_ARRAY(ier, RXICUState, NR_IRQS / 8),
        VMSTATE_UINT8_ARRAY(ipr, RXICUState, 142),
        VMSTATE_UINT8_ARRAY(dmasr, RXICUState, 4),
        VMSTATE_UINT16(fir, RXICUState),
        VMSTATE_UINT8(nmisr, RXICUState),
        VMSTATE_UINT8(nmier, RXICUState),
        VMSTATE_UINT8(nmiclr, RXICUState),
        VMSTATE_UINT8(nmicr, RXICUState),
        VMSTATE_INT16(req_irq, RXICUState),
        VMSTATE_END_OF_LIST()
    }
};

static Property rxicu_properties[] = {
    DEFINE_PROP_ARRAY("ipr-map", RXICUState, nr_irqs, map,
                      qdev_prop_uint8, uint8_t),
    DEFINE_PROP_ARRAY("trigger-level", RXICUState, nr_sense, init_sense,
                      qdev_prop_uint8, uint8_t),
    DEFINE_PROP_END_OF_LIST(),
};

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

    dc->realize = rxicu_realize;
    dc->vmsd = &vmstate_rxicu;
    device_class_set_props(dc, rxicu_properties);
}

static const TypeInfo rxicu_info = {
    .name = TYPE_RX_ICU,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(RXICUState),
    .instance_init = rxicu_init,
    .instance_finalize = rxicu_fini,
    .class_init = rxicu_class_init,
};

static void rxicu_register_types(void)
{
    type_register_static(&rxicu_info);
}

type_init(rxicu_register_types)
