/*
 * 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 * const syborg_int_readfn[] = {
    syborg_int_read,
    syborg_int_read,
    syborg_int_read
};

static CPUWriteMemoryFunc * const 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 int 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,
                                       DEVICE_NATIVE_ENDIAN);
    sysbus_init_mmio(dev, 0x1000, iomemtype);
    s->flags = qemu_mallocz(s->num_irqs * sizeof(syborg_int_flags));

    register_savevm(&dev->qdev, "syborg_int", -1, 1, syborg_int_save,
                    syborg_int_load, s);
    return 0;
}

static SysBusDeviceInfo syborg_int_info = {
    .init = syborg_int_init,
    .qdev.name  = "syborg,interrupt",
    .qdev.size  = sizeof(SyborgIntState),
    .qdev.props = (Property[]) {
        DEFINE_PROP_UINT32("num-interrupts", SyborgIntState, num_irqs, 64),
        DEFINE_PROP_END_OF_LIST(),
    }
};

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

device_init(syborg_interrupt_register_devices)
