/*
 * Raspberry Pi emulation (c) 2012 Gregory Estrade
 * Refactoring for Pi2 Copyright (c) 2015, Microsoft. Written by Andrew Baumann.
 * Heavily based on pl190.c, copyright terms below:
 *
 * Arm PrimeCell PL190 Vector Interrupt Controller
 *
 * Copyright (c) 2006 CodeSourcery.
 * Written by Paul Brook
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or later.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "hw/intc/bcm2835_ic.h"
#include "hw/irq.h"
#include "migration/vmstate.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "trace.h"

#define GPU_IRQS 64
#define ARM_IRQS 8

#define IRQ_PENDING_BASIC       0x00 /* IRQ basic pending */
#define IRQ_PENDING_1           0x04 /* IRQ pending 1 */
#define IRQ_PENDING_2           0x08 /* IRQ pending 2 */
#define FIQ_CONTROL             0x0C /* FIQ register */
#define IRQ_ENABLE_1            0x10 /* Interrupt enable register 1 */
#define IRQ_ENABLE_2            0x14 /* Interrupt enable register 2 */
#define IRQ_ENABLE_BASIC        0x18 /* Base interrupt enable register */
#define IRQ_DISABLE_1           0x1C /* Interrupt disable register 1 */
#define IRQ_DISABLE_2           0x20 /* Interrupt disable register 2 */
#define IRQ_DISABLE_BASIC       0x24 /* Base interrupt disable register */

/* Update interrupts.  */
static void bcm2835_ic_update(BCM2835ICState *s)
{
    bool set = false;

    if (s->fiq_enable) {
        if (s->fiq_select >= GPU_IRQS) {
            /* ARM IRQ */
            set = extract32(s->arm_irq_level, s->fiq_select - GPU_IRQS, 1);
        } else {
            set = extract64(s->gpu_irq_level, s->fiq_select, 1);
        }
    }
    qemu_set_irq(s->fiq, set);

    set = (s->gpu_irq_level & s->gpu_irq_enable)
        || (s->arm_irq_level & s->arm_irq_enable);
    qemu_set_irq(s->irq, set);
}

static void bcm2835_ic_set_gpu_irq(void *opaque, int irq, int level)
{
    BCM2835ICState *s = opaque;

    assert(irq >= 0 && irq < 64);
    trace_bcm2835_ic_set_gpu_irq(irq, level);
    s->gpu_irq_level = deposit64(s->gpu_irq_level, irq, 1, level != 0);
    bcm2835_ic_update(s);
}

static void bcm2835_ic_set_arm_irq(void *opaque, int irq, int level)
{
    BCM2835ICState *s = opaque;

    assert(irq >= 0 && irq < 8);
    trace_bcm2835_ic_set_cpu_irq(irq, level);
    s->arm_irq_level = deposit32(s->arm_irq_level, irq, 1, level != 0);
    bcm2835_ic_update(s);
}

static const int irq_dups[] = { 7, 9, 10, 18, 19, 53, 54, 55, 56, 57, 62 };

static uint64_t bcm2835_ic_read(void *opaque, hwaddr offset, unsigned size)
{
    BCM2835ICState *s = opaque;
    uint32_t res = 0;
    uint64_t gpu_pending = s->gpu_irq_level & s->gpu_irq_enable;
    int i;

    switch (offset) {
    case IRQ_PENDING_BASIC:
        /* bits 0-7: ARM irqs */
        res = s->arm_irq_level & s->arm_irq_enable;

        /* bits 8 & 9: pending registers 1 & 2 */
        res |= (((uint32_t)gpu_pending) != 0) << 8;
        res |= ((gpu_pending >> 32) != 0) << 9;

        /* bits 10-20: selected GPU IRQs */
        for (i = 0; i < ARRAY_SIZE(irq_dups); i++) {
            res |= extract64(gpu_pending, irq_dups[i], 1) << (i + 10);
        }
        break;
    case IRQ_PENDING_1:
        res = gpu_pending;
        break;
    case IRQ_PENDING_2:
        res = gpu_pending >> 32;
        break;
    case FIQ_CONTROL:
        res = (s->fiq_enable << 7) | s->fiq_select;
        break;
    case IRQ_ENABLE_1:
        res = s->gpu_irq_enable;
        break;
    case IRQ_ENABLE_2:
        res = s->gpu_irq_enable >> 32;
        break;
    case IRQ_ENABLE_BASIC:
        res = s->arm_irq_enable;
        break;
    case IRQ_DISABLE_1:
        res = ~s->gpu_irq_enable;
        break;
    case IRQ_DISABLE_2:
        res = ~s->gpu_irq_enable >> 32;
        break;
    case IRQ_DISABLE_BASIC:
        res = ~s->arm_irq_enable;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
                      __func__, offset);
        return 0;
    }

    return res;
}

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

    switch (offset) {
    case FIQ_CONTROL:
        s->fiq_select = extract32(val, 0, 7);
        s->fiq_enable = extract32(val, 7, 1);
        break;
    case IRQ_ENABLE_1:
        s->gpu_irq_enable |= val;
        break;
    case IRQ_ENABLE_2:
        s->gpu_irq_enable |= val << 32;
        break;
    case IRQ_ENABLE_BASIC:
        s->arm_irq_enable |= val & 0xff;
        break;
    case IRQ_DISABLE_1:
        s->gpu_irq_enable &= ~val;
        break;
    case IRQ_DISABLE_2:
        s->gpu_irq_enable &= ~(val << 32);
        break;
    case IRQ_DISABLE_BASIC:
        s->arm_irq_enable &= ~val & 0xff;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n",
                      __func__, offset);
        return;
    }
    bcm2835_ic_update(s);
}

static const MemoryRegionOps bcm2835_ic_ops = {
    .read = bcm2835_ic_read,
    .write = bcm2835_ic_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid.min_access_size = 4,
    .valid.max_access_size = 4,
};

static void bcm2835_ic_reset(DeviceState *d)
{
    BCM2835ICState *s = BCM2835_IC(d);

    s->gpu_irq_enable = 0;
    s->arm_irq_enable = 0;
    s->fiq_enable = false;
    s->fiq_select = 0;
}

static void bcm2835_ic_init(Object *obj)
{
    BCM2835ICState *s = BCM2835_IC(obj);

    memory_region_init_io(&s->iomem, obj, &bcm2835_ic_ops, s, TYPE_BCM2835_IC,
                          0x200);
    sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem);

    qdev_init_gpio_in_named(DEVICE(s), bcm2835_ic_set_gpu_irq,
                            BCM2835_IC_GPU_IRQ, GPU_IRQS);
    qdev_init_gpio_in_named(DEVICE(s), bcm2835_ic_set_arm_irq,
                            BCM2835_IC_ARM_IRQ, ARM_IRQS);

    sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq);
    sysbus_init_irq(SYS_BUS_DEVICE(s), &s->fiq);
}

static const VMStateDescription vmstate_bcm2835_ic = {
    .name = TYPE_BCM2835_IC,
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT64(gpu_irq_level, BCM2835ICState),
        VMSTATE_UINT64(gpu_irq_enable, BCM2835ICState),
        VMSTATE_UINT8(arm_irq_level, BCM2835ICState),
        VMSTATE_UINT8(arm_irq_enable, BCM2835ICState),
        VMSTATE_BOOL(fiq_enable, BCM2835ICState),
        VMSTATE_UINT8(fiq_select, BCM2835ICState),
        VMSTATE_END_OF_LIST()
    }
};

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

    device_class_set_legacy_reset(dc, bcm2835_ic_reset);
    dc->vmsd = &vmstate_bcm2835_ic;
}

static const TypeInfo bcm2835_ic_info = {
    .name          = TYPE_BCM2835_IC,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(BCM2835ICState),
    .class_init    = bcm2835_ic_class_init,
    .instance_init = bcm2835_ic_init,
};

static void bcm2835_ic_register_types(void)
{
    type_register_static(&bcm2835_ic_info);
}

type_init(bcm2835_ic_register_types)
