/*
 * Syborg interrupt controller.
 *
 * Copyright (c) 2008 CodeSourcery
 *
 * 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 "sysbus.h"
#include "syborg.h"

//#define DEBUG_SYBORG_INT

#ifdef DEBUG_SYBORG_INT
#define DPRINTF(fmt, ...) \
do { printf("syborg_int: " fmt , ## __VA_ARGS__); } while (0)
#define BADF(fmt, ...) \
do { fprintf(stderr, "syborg_int: error: " fmt , ## __VA_ARGS__); \
    exit(1);} while (0)
#else
#define DPRINTF(fmt, ...) do {} while(0)
#define BADF(fmt, ...) \
do { fprintf(stderr, "syborg_int: error: " fmt , ## __VA_ARGS__);} while (0)
#endif
enum {
    INT_ID            = 0,
    INT_STATUS        = 1, /* number of pending interrupts */
    INT_CURRENT       = 2, /* next interrupt to be serviced */
    INT_DISABLE_ALL   = 3,
    INT_DISABLE       = 4,
    INT_ENABLE        = 5,
    INT_TOTAL         = 6
};

typedef struct {
    unsigned level:1;
    unsigned enabled:1;
} syborg_int_flags;

typedef struct {
    SysBusDevice busdev;
    int pending_count;
    uint32_t num_irqs;
    syborg_int_flags *flags;
    qemu_irq parent_irq;
} SyborgIntState;

static void syborg_int_update(SyborgIntState *s)
{
    DPRINTF("pending %d\n", s->pending_count);
    qemu_set_irq(s->parent_irq, s->pending_count > 0);
}

static void syborg_int_set_irq(void *opaque, int irq, int level)
{
    SyborgIntState *s = (SyborgIntState *)opaque;

    if (s->flags[irq].level == level)
        return;

    s->flags[irq].level = level;
    if (s->flags[irq].enabled) {
        if (level)
            s->pending_count++;
        else
            s->pending_count--;
        syborg_int_update(s);
    }
}

static uint32_t syborg_int_read(void *opaque, target_phys_addr_t offset)
{
    SyborgIntState *s = (SyborgIntState *)opaque;
    int i;

    offset &= 0xfff;
    switch (offset >> 2) {
    case INT_ID:
        return SYBORG_ID_INT;
    case INT_STATUS:
        DPRINTF("read status=%d\n", s->pending_count);
        return s->pending_count;

    case INT_CURRENT:
        for (i = 0; i < s->num_irqs; i++) {
            if (s->flags[i].level & s->flags[i].enabled) {
                DPRINTF("read current=%d\n", i);
                return i;
            }
        }
        DPRINTF("read current=none\n");
        return 0xffffffffu;

    default:
        cpu_abort(cpu_single_env, "syborg_int_read: Bad offset %x\n",
                  (int)offset);
        return 0;
    }
}

static void syborg_int_write(void *opaque, target_phys_addr_t offset, uint32_t value)
{
    SyborgIntState *s = (SyborgIntState *)opaque;
    int i;
    offset &= 0xfff;

    DPRINTF("syborg_int_write offset=%d val=%d\n", (int)offset, (int)value);
    switch (offset >> 2) {
    case INT_DISABLE_ALL:
        s->pending_count = 0;
        for (i = 0; i < s->num_irqs; i++)
            s->flags[i].enabled = 0;
        break;

    case INT_DISABLE:
        if (value >= s->num_irqs)
            break;
        if (s->flags[value].enabled) {
            if (s->flags[value].enabled)
                s->pending_count--;
            s->flags[value].enabled = 0;
        }
        break;

    case INT_ENABLE:
      if (value >= s->num_irqs)
          break;
      if (!(s->flags[value].enabled)) {
          if(s->flags[value].level)
              s->pending_count++;
          s->flags[value].enabled = 1;
      }
      break;

    default:
        cpu_abort(cpu_single_env, "syborg_int_write: Bad offset %x\n",
                  (int)offset);
        return;
    }
    syborg_int_update(s);
}

static CPUReadMemoryFunc *syborg_int_readfn[] = {
    syborg_int_read,
    syborg_int_read,
    syborg_int_read
};

static CPUWriteMemoryFunc *syborg_int_writefn[] = {
    syborg_int_write,
    syborg_int_write,
    syborg_int_write
};

static void syborg_int_save(QEMUFile *f, void *opaque)
{
    SyborgIntState *s = (SyborgIntState *)opaque;
    int i;

    qemu_put_be32(f, s->num_irqs);
    qemu_put_be32(f, s->pending_count);
    for (i = 0; i < s->num_irqs; i++) {
        qemu_put_be32(f, s->flags[i].enabled
                         | ((unsigned)s->flags[i].level << 1));
    }
}

static int syborg_int_load(QEMUFile *f, void *opaque, int version_id)
{
    SyborgIntState *s = (SyborgIntState *)opaque;
    uint32_t val;
    int i;

    if (version_id != 1)
        return -EINVAL;

    val = qemu_get_be32(f);
    if (val != s->num_irqs)
        return -EINVAL;
    s->pending_count = qemu_get_be32(f);
    for (i = 0; i < s->num_irqs; i++) {
        val = qemu_get_be32(f);
        s->flags[i].enabled = val & 1;
        s->flags[i].level = (val >> 1) & 1;
    }
    return 0;
}

static void syborg_int_init(SysBusDevice *dev)
{
    SyborgIntState *s = FROM_SYSBUS(SyborgIntState, dev);
    int iomemtype;

    sysbus_init_irq(dev, &s->parent_irq);
    qdev_init_gpio_in(&dev->qdev, syborg_int_set_irq, s->num_irqs);
    iomemtype = cpu_register_io_memory(syborg_int_readfn,
                                       syborg_int_writefn, s);
    sysbus_init_mmio(dev, 0x1000, iomemtype);
    s->flags = qemu_mallocz(s->num_irqs * sizeof(syborg_int_flags));

    register_savevm("syborg_int", -1, 1, syborg_int_save, syborg_int_load, s);
}

static SysBusDeviceInfo syborg_int_info = {
    .init = syborg_int_init,
    .qdev.name  = "syborg,interrupt",
    .qdev.size  = sizeof(SyborgIntState),
    .qdev.props = (Property[]) {
        {
            .name   = "num-interrupts",
            .info   = &qdev_prop_uint32,
            .offset = offsetof(SyborgIntState, num_irqs),
            .defval = (uint32_t[]) { 64 },
        },
        {/* end of list */}
    }
};

static void syborg_interrupt_register_devices(void)
{
    sysbus_register_withprop(&syborg_int_info);
}

device_init(syborg_interrupt_register_devices)
