/*
 * INTC device simulation in PKUnity SoC
 *
 * Copyright (C) 2010-2012 Guan Xuetao
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation, or any later version.
 * See the COPYING file in the top-level directory.
 */

#include "qemu/osdep.h"
#include "hw/irq.h"
#include "hw/sysbus.h"
#include "qom/object.h"

#undef DEBUG_PUV3
#include "hw/unicore32/puv3.h"
#include "qemu/module.h"
#include "qemu/log.h"

#define TYPE_PUV3_INTC "puv3_intc"
OBJECT_DECLARE_SIMPLE_TYPE(PUV3INTCState, PUV3_INTC)

struct PUV3INTCState {
    SysBusDevice parent_obj;

    MemoryRegion iomem;
    qemu_irq parent_irq;

    uint32_t reg_ICMR;
    uint32_t reg_ICPR;
};

/* Update interrupt status after enabled or pending bits have been changed.  */
static void puv3_intc_update(PUV3INTCState *s)
{
    if (s->reg_ICMR & s->reg_ICPR) {
        qemu_irq_raise(s->parent_irq);
    } else {
        qemu_irq_lower(s->parent_irq);
    }
}

/* Process a change in an external INTC input. */
static void puv3_intc_handler(void *opaque, int irq, int level)
{
    PUV3INTCState *s = opaque;

    DPRINTF("irq 0x%x, level 0x%x\n", irq, level);
    if (level) {
        s->reg_ICPR |= (1 << irq);
    } else {
        s->reg_ICPR &= ~(1 << irq);
    }
    puv3_intc_update(s);
}

static uint64_t puv3_intc_read(void *opaque, hwaddr offset,
        unsigned size)
{
    PUV3INTCState *s = opaque;
    uint32_t ret = 0;

    switch (offset) {
    case 0x04: /* INTC_ICMR */
        ret = s->reg_ICMR;
        break;
    case 0x0c: /* INTC_ICIP */
        ret = s->reg_ICPR; /* the same value with ICPR */
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Bad read offset 0x%"HWADDR_PRIx"\n",
                      __func__, offset);
    }
    DPRINTF("offset 0x%x, value 0x%x\n", offset, ret);
    return ret;
}

static void puv3_intc_write(void *opaque, hwaddr offset,
        uint64_t value, unsigned size)
{
    PUV3INTCState *s = opaque;

    DPRINTF("offset 0x%x, value 0x%x\n", offset, value);
    switch (offset) {
    case 0x00: /* INTC_ICLR */
    case 0x14: /* INTC_ICCR */
        break;
    case 0x04: /* INTC_ICMR */
        s->reg_ICMR = value;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "%s: Bad write offset 0x%"HWADDR_PRIx"\n",
                      __func__, offset);
        return;
    }
    puv3_intc_update(s);
}

static const MemoryRegionOps puv3_intc_ops = {
    .read = puv3_intc_read,
    .write = puv3_intc_write,
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void puv3_intc_realize(DeviceState *dev, Error **errp)
{
    PUV3INTCState *s = PUV3_INTC(dev);
    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);

    qdev_init_gpio_in(dev, puv3_intc_handler, PUV3_IRQS_NR);
    sysbus_init_irq(sbd, &s->parent_irq);

    s->reg_ICMR = 0;
    s->reg_ICPR = 0;

    memory_region_init_io(&s->iomem, OBJECT(s), &puv3_intc_ops, s, "puv3_intc",
                          PUV3_REGS_OFFSET);
    sysbus_init_mmio(sbd, &s->iomem);
}

static void puv3_intc_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    dc->realize = puv3_intc_realize;
}

static const TypeInfo puv3_intc_info = {
    .name = TYPE_PUV3_INTC,
    .parent = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(PUV3INTCState),
    .class_init = puv3_intc_class_init,
};

static void puv3_intc_register_type(void)
{
    type_register_static(&puv3_intc_info);
}

type_init(puv3_intc_register_type)
