/*
 * i.MX31 Vectored Interrupt Controller
 *
 * Note this is NOT the PL192 provided by ARM, but
 * a custom implementation by Freescale.
 *
 * Copyright (c) 2008 OKL
 * Copyright (c) 2011 NICTA Pty Ltd
 * Originally written by Hans Jiang
 * Updated by Jean-Christophe Dubois <jcd@tribudubois.net>
 *
 * This code is licensed under the GPL version 2 or later.  See
 * the COPYING file in the top-level directory.
 *
 * TODO: implement vectors.
 */

#include "hw/intc/imx_avic.h"

#ifndef DEBUG_IMX_AVIC
#define DEBUG_IMX_AVIC 0
#endif

#define DPRINTF(fmt, args...) \
    do { \
        if (DEBUG_IMX_AVIC) { \
            fprintf(stderr, "[%s]%s: " fmt , TYPE_IMX_AVIC, \
                                             __func__, ##args); \
        } \
    } while (0)

static const VMStateDescription vmstate_imx_avic = {
    .name = TYPE_IMX_AVIC,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT64(pending, IMXAVICState),
        VMSTATE_UINT64(enabled, IMXAVICState),
        VMSTATE_UINT64(is_fiq, IMXAVICState),
        VMSTATE_UINT32(intcntl, IMXAVICState),
        VMSTATE_UINT32(intmask, IMXAVICState),
        VMSTATE_UINT32_ARRAY(prio, IMXAVICState, PRIO_WORDS),
        VMSTATE_END_OF_LIST()
    },
};

static inline int imx_avic_prio(IMXAVICState *s, int irq)
{
    uint32_t word = irq / PRIO_PER_WORD;
    uint32_t part = 4 * (irq % PRIO_PER_WORD);
    return 0xf & (s->prio[word] >> part);
}

/* Update interrupts.  */
static void imx_avic_update(IMXAVICState *s)
{
    int i;
    uint64_t new = s->pending & s->enabled;
    uint64_t flags;

    flags = new & s->is_fiq;
    qemu_set_irq(s->fiq, !!flags);

    flags = new & ~s->is_fiq;
    if (!flags || (s->intmask == 0x1f)) {
        qemu_set_irq(s->irq, !!flags);
        return;
    }

    /*
     * Take interrupt if there's a pending interrupt with
     * priority higher than the value of intmask
     */
    for (i = 0; i < IMX_AVIC_NUM_IRQS; i++) {
        if (flags & (1UL << i)) {
            if (imx_avic_prio(s, i) > s->intmask) {
                qemu_set_irq(s->irq, 1);
                return;
            }
        }
    }
    qemu_set_irq(s->irq, 0);
}

static void imx_avic_set_irq(void *opaque, int irq, int level)
{
    IMXAVICState *s = (IMXAVICState *)opaque;

    if (level) {
        DPRINTF("Raising IRQ %d, prio %d\n",
                irq, imx_avic_prio(s, irq));
        s->pending |= (1ULL << irq);
    } else {
        DPRINTF("Clearing IRQ %d, prio %d\n",
                irq, imx_avic_prio(s, irq));
        s->pending &= ~(1ULL << irq);
    }

    imx_avic_update(s);
}


static uint64_t imx_avic_read(void *opaque,
                             hwaddr offset, unsigned size)
{
    IMXAVICState *s = (IMXAVICState *)opaque;

    DPRINTF("read(offset = 0x%" HWADDR_PRIx ")\n", offset);

    switch (offset >> 2) {
    case 0: /* INTCNTL */
        return s->intcntl;

    case 1: /* Normal Interrupt Mask Register, NIMASK */
        return s->intmask;

    case 2: /* Interrupt Enable Number Register, INTENNUM */
    case 3: /* Interrupt Disable Number Register, INTDISNUM */
        return 0;

    case 4: /* Interrupt Enabled Number Register High */
        return s->enabled >> 32;

    case 5: /* Interrupt Enabled Number Register Low */
        return s->enabled & 0xffffffffULL;

    case 6: /* Interrupt Type Register High */
        return s->is_fiq >> 32;

    case 7: /* Interrupt Type Register Low */
        return s->is_fiq & 0xffffffffULL;

    case 8: /* Normal Interrupt Priority Register 7 */
    case 9: /* Normal Interrupt Priority Register 6 */
    case 10:/* Normal Interrupt Priority Register 5 */
    case 11:/* Normal Interrupt Priority Register 4 */
    case 12:/* Normal Interrupt Priority Register 3 */
    case 13:/* Normal Interrupt Priority Register 2 */
    case 14:/* Normal Interrupt Priority Register 1 */
    case 15:/* Normal Interrupt Priority Register 0 */
        return s->prio[15-(offset>>2)];

    case 16: /* Normal interrupt vector and status register */
    {
        /*
         * This returns the highest priority
         * outstanding interrupt.  Where there is more than
         * one pending IRQ with the same priority,
         * take the highest numbered one.
         */
        uint64_t flags = s->pending & s->enabled & ~s->is_fiq;
        int i;
        int prio = -1;
        int irq = -1;
        for (i = 63; i >= 0; --i) {
            if (flags & (1ULL<<i)) {
                int irq_prio = imx_avic_prio(s, i);
                if (irq_prio > prio) {
                    irq = i;
                    prio = irq_prio;
                }
            }
        }
        if (irq >= 0) {
            imx_avic_set_irq(s, irq, 0);
            return irq << 16 | prio;
        }
        return 0xffffffffULL;
    }
    case 17:/* Fast Interrupt vector and status register */
    {
        uint64_t flags = s->pending & s->enabled & s->is_fiq;
        int i = ctz64(flags);
        if (i < 64) {
            imx_avic_set_irq(opaque, i, 0);
            return i;
        }
        return 0xffffffffULL;
    }
    case 18:/* Interrupt source register high */
        return s->pending >> 32;

    case 19:/* Interrupt source register low */
        return s->pending & 0xffffffffULL;

    case 20:/* Interrupt Force Register high */
    case 21:/* Interrupt Force Register low */
        return 0;

    case 22:/* Normal Interrupt Pending Register High */
        return (s->pending & s->enabled & ~s->is_fiq) >> 32;

    case 23:/* Normal Interrupt Pending Register Low */
        return (s->pending & s->enabled & ~s->is_fiq) & 0xffffffffULL;

    case 24: /* Fast Interrupt Pending Register High  */
        return (s->pending & s->enabled & s->is_fiq) >> 32;

    case 25: /* Fast Interrupt Pending Register Low  */
        return (s->pending & s->enabled & s->is_fiq) & 0xffffffffULL;

    case 0x40:            /* AVIC vector 0, use for WFI WAR */
        return 0x4;

    default:
        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
                      HWADDR_PRIx "\n", TYPE_IMX_AVIC, __func__, offset);
        return 0;
    }
}

static void imx_avic_write(void *opaque, hwaddr offset,
                          uint64_t val, unsigned size)
{
    IMXAVICState *s = (IMXAVICState *)opaque;

    /* Vector Registers not yet supported */
    if (offset >= 0x100 && offset <= 0x2fc) {
        qemu_log_mask(LOG_UNIMP, "[%s]%s: vector %d ignored\n",
                      TYPE_IMX_AVIC, __func__, (int)((offset - 0x100) >> 2));
        return;
    }

    DPRINTF("(0x%" HWADDR_PRIx ") = 0x%x\n", offset, (unsigned int)val);

    switch (offset >> 2) {
    case 0: /* Interrupt Control Register, INTCNTL */
        s->intcntl = val & (ABFEN | NIDIS | FIDIS | NIAD | FIAD | NM);
        if (s->intcntl & ABFEN) {
            s->intcntl &= ~(val & ABFLAG);
        }
        break;

    case 1: /* Normal Interrupt Mask Register, NIMASK */
        s->intmask = val & 0x1f;
        break;

    case 2: /* Interrupt Enable Number Register, INTENNUM */
        DPRINTF("enable(%d)\n", (int)val);
        val &= 0x3f;
        s->enabled |= (1ULL << val);
        break;

    case 3: /* Interrupt Disable Number Register, INTDISNUM */
        DPRINTF("disable(%d)\n", (int)val);
        val &= 0x3f;
        s->enabled &= ~(1ULL << val);
        break;

    case 4: /* Interrupt Enable Number Register High */
        s->enabled = (s->enabled & 0xffffffffULL) | (val << 32);
        break;

    case 5: /* Interrupt Enable Number Register Low */
        s->enabled = (s->enabled & 0xffffffff00000000ULL) | val;
        break;

    case 6: /* Interrupt Type Register High */
        s->is_fiq = (s->is_fiq & 0xffffffffULL) | (val << 32);
        break;

    case 7: /* Interrupt Type Register Low */
        s->is_fiq = (s->is_fiq & 0xffffffff00000000ULL) | val;
        break;

    case 8: /* Normal Interrupt Priority Register 7 */
    case 9: /* Normal Interrupt Priority Register 6 */
    case 10:/* Normal Interrupt Priority Register 5 */
    case 11:/* Normal Interrupt Priority Register 4 */
    case 12:/* Normal Interrupt Priority Register 3 */
    case 13:/* Normal Interrupt Priority Register 2 */
    case 14:/* Normal Interrupt Priority Register 1 */
    case 15:/* Normal Interrupt Priority Register 0 */
        s->prio[15-(offset>>2)] = val;
        break;

        /* Read-only registers, writes ignored */
    case 16:/* Normal Interrupt Vector and Status register */
    case 17:/* Fast Interrupt vector and status register */
    case 18:/* Interrupt source register high */
    case 19:/* Interrupt source register low */
        return;

    case 20:/* Interrupt Force Register high */
        s->pending = (s->pending & 0xffffffffULL) | (val << 32);
        break;

    case 21:/* Interrupt Force Register low */
        s->pending = (s->pending & 0xffffffff00000000ULL) | val;
        break;

    case 22:/* Normal Interrupt Pending Register High */
    case 23:/* Normal Interrupt Pending Register Low */
    case 24: /* Fast Interrupt Pending Register High  */
    case 25: /* Fast Interrupt Pending Register Low  */
        return;

    default:
        qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad register at offset 0x%"
                      HWADDR_PRIx "\n", TYPE_IMX_AVIC, __func__, offset);
    }
    imx_avic_update(s);
}

static const MemoryRegionOps imx_avic_ops = {
    .read = imx_avic_read,
    .write = imx_avic_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void imx_avic_reset(DeviceState *dev)
{
    IMXAVICState *s = IMX_AVIC(dev);

    s->pending = 0;
    s->enabled = 0;
    s->is_fiq = 0;
    s->intmask = 0x1f;
    s->intcntl = 0;
    memset(s->prio, 0, sizeof s->prio);
}

static int imx_avic_init(SysBusDevice *sbd)
{
    DeviceState *dev = DEVICE(sbd);
    IMXAVICState *s = IMX_AVIC(dev);

    memory_region_init_io(&s->iomem, OBJECT(s), &imx_avic_ops, s,
                          TYPE_IMX_AVIC, 0x1000);
    sysbus_init_mmio(sbd, &s->iomem);

    qdev_init_gpio_in(dev, imx_avic_set_irq, IMX_AVIC_NUM_IRQS);
    sysbus_init_irq(sbd, &s->irq);
    sysbus_init_irq(sbd, &s->fiq);

    return 0;
}


static void imx_avic_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
    k->init = imx_avic_init;
    dc->vmsd = &vmstate_imx_avic;
    dc->reset = imx_avic_reset;
    dc->desc = "i.MX Advanced Vector Interrupt Controller";
}

static const TypeInfo imx_avic_info = {
    .name = TYPE_IMX_AVIC,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(IMXAVICState),
    .class_init = imx_avic_class_init,
};

static void imx_avic_register_types(void)
{
    type_register_static(&imx_avic_info);
}

type_init(imx_avic_register_types)
