/*
 * QEMU Xilinx OPB Interrupt Controller.
 *
 * Copyright (c) 2009 Edgar E. Iglesias.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "hw/sysbus.h"
#include "hw/hw.h"

#define D(x)

#define R_ISR       0
#define R_IPR       1
#define R_IER       2
#define R_IAR       3
#define R_SIE       4
#define R_CIE       5
#define R_IVR       6
#define R_MER       7
#define R_MAX       8

#define TYPE_XILINX_INTC "xlnx.xps-intc"
#define XILINX_INTC(obj) OBJECT_CHECK(struct xlx_pic, (obj), TYPE_XILINX_INTC)

struct xlx_pic
{
    SysBusDevice parent_obj;

    MemoryRegion mmio;
    qemu_irq parent_irq;

    /* Configuration reg chosen at synthesis-time. QEMU populates
       the bits at board-setup.  */
    uint32_t c_kind_of_intr;

    /* Runtime control registers.  */
    uint32_t regs[R_MAX];
    /* state of the interrupt input pins */
    uint32_t irq_pin_state;
};

static void update_irq(struct xlx_pic *p)
{
    uint32_t i;

    /* level triggered interrupt */
    if (p->regs[R_MER] & 2) {
        p->regs[R_ISR] |= p->irq_pin_state & ~p->c_kind_of_intr;
    }

    /* Update the pending register.  */
    p->regs[R_IPR] = p->regs[R_ISR] & p->regs[R_IER];

    /* Update the vector register.  */
    for (i = 0; i < 32; i++) {
        if (p->regs[R_IPR] & (1U << i)) {
            break;
        }
    }
    if (i == 32)
        i = ~0;

    p->regs[R_IVR] = i;
    qemu_set_irq(p->parent_irq, (p->regs[R_MER] & 1) && p->regs[R_IPR]);
}

static uint64_t
pic_read(void *opaque, hwaddr addr, unsigned int size)
{
    struct xlx_pic *p = opaque;
    uint32_t r = 0;

    addr >>= 2;
    switch (addr)
    {
        default:
            if (addr < ARRAY_SIZE(p->regs))
                r = p->regs[addr];
            break;

    }
    D(printf("%s %x=%x\n", __func__, addr * 4, r));
    return r;
}

static void
pic_write(void *opaque, hwaddr addr,
          uint64_t val64, unsigned int size)
{
    struct xlx_pic *p = opaque;
    uint32_t value = val64;

    addr >>= 2;
    D(qemu_log("%s addr=%x val=%x\n", __func__, addr * 4, value));
    switch (addr) 
    {
        case R_IAR:
            p->regs[R_ISR] &= ~value; /* ACK.  */
            break;
        case R_SIE:
            p->regs[R_IER] |= value;  /* Atomic set ie.  */
            break;
        case R_CIE:
            p->regs[R_IER] &= ~value; /* Atomic clear ie.  */
            break;
        case R_MER:
            p->regs[R_MER] = value & 0x3;
            break;
        case R_ISR:
            if ((p->regs[R_MER] & 2)) {
                break;
            }
            /* fallthrough */
        default:
            if (addr < ARRAY_SIZE(p->regs))
                p->regs[addr] = value;
            break;
    }
    update_irq(p);
}

static const MemoryRegionOps pic_ops = {
    .read = pic_read,
    .write = pic_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4
    }
};

static void irq_handler(void *opaque, int irq, int level)
{
    struct xlx_pic *p = opaque;

    /* edge triggered interrupt */
    if (p->c_kind_of_intr & (1 << irq) && p->regs[R_MER] & 2) {
        p->regs[R_ISR] |= (level << irq);
    }

    p->irq_pin_state &= ~(1 << irq);
    p->irq_pin_state |= level << irq;
    update_irq(p);
}

static int xilinx_intc_init(SysBusDevice *sbd)
{
    DeviceState *dev = DEVICE(sbd);
    struct xlx_pic *p = XILINX_INTC(dev);

    qdev_init_gpio_in(dev, irq_handler, 32);
    sysbus_init_irq(sbd, &p->parent_irq);

    memory_region_init_io(&p->mmio, OBJECT(p), &pic_ops, p, "xlnx.xps-intc",
                          R_MAX * 4);
    sysbus_init_mmio(sbd, &p->mmio);
    return 0;
}

static Property xilinx_intc_properties[] = {
    DEFINE_PROP_UINT32("kind-of-intr", struct xlx_pic, c_kind_of_intr, 0),
    DEFINE_PROP_END_OF_LIST(),
};

static void xilinx_intc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    k->init = xilinx_intc_init;
    dc->props = xilinx_intc_properties;
}

static const TypeInfo xilinx_intc_info = {
    .name          = TYPE_XILINX_INTC,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(struct xlx_pic),
    .class_init    = xilinx_intc_class_init,
};

static void xilinx_intc_register_types(void)
{
    type_register_static(&xilinx_intc_info);
}

type_init(xilinx_intc_register_types)
