/*
 * QEMU Sparc SLAVIO interrupt controller emulation
 *
 * Copyright (c) 2003-2005 Fabrice Bellard
 *
 * 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 "sun4m.h"
#include "monitor.h"
#include "sysbus.h"
#include "trace.h"

//#define DEBUG_IRQ_COUNT

/*
 * Registers of interrupt controller in sun4m.
 *
 * This is the interrupt controller part of chip STP2001 (Slave I/O), also
 * produced as NCR89C105. See
 * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/NCR89C105.txt
 *
 * There is a system master controller and one for each cpu.
 *
 */

#define MAX_CPUS 16
#define MAX_PILS 16

struct SLAVIO_INTCTLState;

typedef struct SLAVIO_CPUINTCTLState {
    MemoryRegion iomem;
    struct SLAVIO_INTCTLState *master;
    uint32_t intreg_pending;
    uint32_t cpu;
    uint32_t irl_out;
} SLAVIO_CPUINTCTLState;

typedef struct SLAVIO_INTCTLState {
    SysBusDevice busdev;
    MemoryRegion iomem;
#ifdef DEBUG_IRQ_COUNT
    uint64_t irq_count[32];
#endif
    qemu_irq cpu_irqs[MAX_CPUS][MAX_PILS];
    SLAVIO_CPUINTCTLState slaves[MAX_CPUS];
    uint32_t intregm_pending;
    uint32_t intregm_disabled;
    uint32_t target_cpu;
} SLAVIO_INTCTLState;

#define INTCTL_MAXADDR 0xf
#define INTCTL_SIZE (INTCTL_MAXADDR + 1)
#define INTCTLM_SIZE 0x14
#define MASTER_IRQ_MASK ~0x0fa2007f
#define MASTER_DISABLE 0x80000000
#define CPU_SOFTIRQ_MASK 0xfffe0000
#define CPU_IRQ_INT15_IN (1 << 15)
#define CPU_IRQ_TIMER_IN (1 << 14)

static void slavio_check_interrupts(SLAVIO_INTCTLState *s, int set_irqs);

// per-cpu interrupt controller
static uint64_t slavio_intctl_mem_readl(void *opaque, hwaddr addr,
                                        unsigned size)
{
    SLAVIO_CPUINTCTLState *s = opaque;
    uint32_t saddr, ret;

    saddr = addr >> 2;
    switch (saddr) {
    case 0:
        ret = s->intreg_pending;
        break;
    default:
        ret = 0;
        break;
    }
    trace_slavio_intctl_mem_readl(s->cpu, addr, ret);

    return ret;
}

static void slavio_intctl_mem_writel(void *opaque, hwaddr addr,
                                     uint64_t val, unsigned size)
{
    SLAVIO_CPUINTCTLState *s = opaque;
    uint32_t saddr;

    saddr = addr >> 2;
    trace_slavio_intctl_mem_writel(s->cpu, addr, val);
    switch (saddr) {
    case 1: // clear pending softints
        val &= CPU_SOFTIRQ_MASK | CPU_IRQ_INT15_IN;
        s->intreg_pending &= ~val;
        slavio_check_interrupts(s->master, 1);
        trace_slavio_intctl_mem_writel_clear(s->cpu, val, s->intreg_pending);
        break;
    case 2: // set softint
        val &= CPU_SOFTIRQ_MASK;
        s->intreg_pending |= val;
        slavio_check_interrupts(s->master, 1);
        trace_slavio_intctl_mem_writel_set(s->cpu, val, s->intreg_pending);
        break;
    default:
        break;
    }
}

static const MemoryRegionOps slavio_intctl_mem_ops = {
    .read = slavio_intctl_mem_readl,
    .write = slavio_intctl_mem_writel,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

// master system interrupt controller
static uint64_t slavio_intctlm_mem_readl(void *opaque, hwaddr addr,
                                         unsigned size)
{
    SLAVIO_INTCTLState *s = opaque;
    uint32_t saddr, ret;

    saddr = addr >> 2;
    switch (saddr) {
    case 0:
        ret = s->intregm_pending & ~MASTER_DISABLE;
        break;
    case 1:
        ret = s->intregm_disabled & MASTER_IRQ_MASK;
        break;
    case 4:
        ret = s->target_cpu;
        break;
    default:
        ret = 0;
        break;
    }
    trace_slavio_intctlm_mem_readl(addr, ret);

    return ret;
}

static void slavio_intctlm_mem_writel(void *opaque, hwaddr addr,
                                      uint64_t val, unsigned size)
{
    SLAVIO_INTCTLState *s = opaque;
    uint32_t saddr;

    saddr = addr >> 2;
    trace_slavio_intctlm_mem_writel(addr, val);
    switch (saddr) {
    case 2: // clear (enable)
        // Force clear unused bits
        val &= MASTER_IRQ_MASK;
        s->intregm_disabled &= ~val;
        trace_slavio_intctlm_mem_writel_enable(val, s->intregm_disabled);
        slavio_check_interrupts(s, 1);
        break;
    case 3: // set (disable; doesn't affect pending)
        // Force clear unused bits
        val &= MASTER_IRQ_MASK;
        s->intregm_disabled |= val;
        slavio_check_interrupts(s, 1);
        trace_slavio_intctlm_mem_writel_disable(val, s->intregm_disabled);
        break;
    case 4:
        s->target_cpu = val & (MAX_CPUS - 1);
        slavio_check_interrupts(s, 1);
        trace_slavio_intctlm_mem_writel_target(s->target_cpu);
        break;
    default:
        break;
    }
}

static const MemoryRegionOps slavio_intctlm_mem_ops = {
    .read = slavio_intctlm_mem_readl,
    .write = slavio_intctlm_mem_writel,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

void slavio_pic_info(Monitor *mon, DeviceState *dev)
{
    SysBusDevice *sd;
    SLAVIO_INTCTLState *s;
    int i;

    sd = sysbus_from_qdev(dev);
    s = FROM_SYSBUS(SLAVIO_INTCTLState, sd);
    for (i = 0; i < MAX_CPUS; i++) {
        monitor_printf(mon, "per-cpu %d: pending 0x%08x\n", i,
                       s->slaves[i].intreg_pending);
    }
    monitor_printf(mon, "master: pending 0x%08x, disabled 0x%08x\n",
                   s->intregm_pending, s->intregm_disabled);
}

void slavio_irq_info(Monitor *mon, DeviceState *dev)
{
#ifndef DEBUG_IRQ_COUNT
    monitor_printf(mon, "irq statistic code not compiled.\n");
#else
    SysBusDevice *sd;
    SLAVIO_INTCTLState *s;
    int i;
    int64_t count;

    sd = sysbus_from_qdev(dev);
    s = FROM_SYSBUS(SLAVIO_INTCTLState, sd);
    monitor_printf(mon, "IRQ statistics:\n");
    for (i = 0; i < 32; i++) {
        count = s->irq_count[i];
        if (count > 0)
            monitor_printf(mon, "%2d: %" PRId64 "\n", i, count);
    }
#endif
}

static const uint32_t intbit_to_level[] = {
    2, 3, 5, 7, 9, 11, 13, 2,   3, 5, 7, 9, 11, 13, 12, 12,
    6, 13, 4, 10, 8, 9, 11, 0,  0, 0, 0, 15, 15, 15, 15, 0,
};

static void slavio_check_interrupts(SLAVIO_INTCTLState *s, int set_irqs)
{
    uint32_t pending = s->intregm_pending, pil_pending;
    unsigned int i, j;

    pending &= ~s->intregm_disabled;

    trace_slavio_check_interrupts(pending, s->intregm_disabled);
    for (i = 0; i < MAX_CPUS; i++) {
        pil_pending = 0;

        /* If we are the current interrupt target, get hard interrupts */
        if (pending && !(s->intregm_disabled & MASTER_DISABLE) &&
            (i == s->target_cpu)) {
            for (j = 0; j < 32; j++) {
                if ((pending & (1 << j)) && intbit_to_level[j]) {
                    pil_pending |= 1 << intbit_to_level[j];
                }
            }
        }

        /* Calculate current pending hard interrupts for display */
        s->slaves[i].intreg_pending &= CPU_SOFTIRQ_MASK | CPU_IRQ_INT15_IN |
            CPU_IRQ_TIMER_IN;
        if (i == s->target_cpu) {
            for (j = 0; j < 32; j++) {
                if ((s->intregm_pending & (1 << j)) && intbit_to_level[j]) {
                    s->slaves[i].intreg_pending |= 1 << intbit_to_level[j];
                }
            }
        }

        /* Level 15 and CPU timer interrupts are only masked when
           the MASTER_DISABLE bit is set */
        if (!(s->intregm_disabled & MASTER_DISABLE)) {
            pil_pending |= s->slaves[i].intreg_pending &
                (CPU_IRQ_INT15_IN | CPU_IRQ_TIMER_IN);
        }

        /* Add soft interrupts */
        pil_pending |= (s->slaves[i].intreg_pending & CPU_SOFTIRQ_MASK) >> 16;

        if (set_irqs) {
            /* Since there is not really an interrupt 0 (and pil_pending
             * and irl_out bit zero are thus always zero) there is no need
             * to do anything with cpu_irqs[i][0] and it is OK not to do
             * the j=0 iteration of this loop.
             */
            for (j = MAX_PILS-1; j > 0; j--) {
                if (pil_pending & (1 << j)) {
                    if (!(s->slaves[i].irl_out & (1 << j))) {
                        qemu_irq_raise(s->cpu_irqs[i][j]);
                    }
                } else {
                    if (s->slaves[i].irl_out & (1 << j)) {
                        qemu_irq_lower(s->cpu_irqs[i][j]);
                    }
                }
            }
        }
        s->slaves[i].irl_out = pil_pending;
    }
}

/*
 * "irq" here is the bit number in the system interrupt register to
 * separate serial and keyboard interrupts sharing a level.
 */
static void slavio_set_irq(void *opaque, int irq, int level)
{
    SLAVIO_INTCTLState *s = opaque;
    uint32_t mask = 1 << irq;
    uint32_t pil = intbit_to_level[irq];
    unsigned int i;

    trace_slavio_set_irq(s->target_cpu, irq, pil, level);
    if (pil > 0) {
        if (level) {
#ifdef DEBUG_IRQ_COUNT
            s->irq_count[pil]++;
#endif
            s->intregm_pending |= mask;
            if (pil == 15) {
                for (i = 0; i < MAX_CPUS; i++) {
                    s->slaves[i].intreg_pending |= 1 << pil;
                }
            }
        } else {
            s->intregm_pending &= ~mask;
            if (pil == 15) {
                for (i = 0; i < MAX_CPUS; i++) {
                    s->slaves[i].intreg_pending &= ~(1 << pil);
                }
            }
        }
        slavio_check_interrupts(s, 1);
    }
}

static void slavio_set_timer_irq_cpu(void *opaque, int cpu, int level)
{
    SLAVIO_INTCTLState *s = opaque;

    trace_slavio_set_timer_irq_cpu(cpu, level);

    if (level) {
        s->slaves[cpu].intreg_pending |= CPU_IRQ_TIMER_IN;
    } else {
        s->slaves[cpu].intreg_pending &= ~CPU_IRQ_TIMER_IN;
    }

    slavio_check_interrupts(s, 1);
}

static void slavio_set_irq_all(void *opaque, int irq, int level)
{
    if (irq < 32) {
        slavio_set_irq(opaque, irq, level);
    } else {
        slavio_set_timer_irq_cpu(opaque, irq - 32, level);
    }
}

static int vmstate_intctl_post_load(void *opaque, int version_id)
{
    SLAVIO_INTCTLState *s = opaque;

    slavio_check_interrupts(s, 0);
    return 0;
}

static const VMStateDescription vmstate_intctl_cpu = {
    .name ="slavio_intctl_cpu",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields      = (VMStateField []) {
        VMSTATE_UINT32(intreg_pending, SLAVIO_CPUINTCTLState),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_intctl = {
    .name ="slavio_intctl",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .post_load = vmstate_intctl_post_load,
    .fields      = (VMStateField []) {
        VMSTATE_STRUCT_ARRAY(slaves, SLAVIO_INTCTLState, MAX_CPUS, 1,
                             vmstate_intctl_cpu, SLAVIO_CPUINTCTLState),
        VMSTATE_UINT32(intregm_pending, SLAVIO_INTCTLState),
        VMSTATE_UINT32(intregm_disabled, SLAVIO_INTCTLState),
        VMSTATE_UINT32(target_cpu, SLAVIO_INTCTLState),
        VMSTATE_END_OF_LIST()
    }
};

static void slavio_intctl_reset(DeviceState *d)
{
    SLAVIO_INTCTLState *s = container_of(d, SLAVIO_INTCTLState, busdev.qdev);
    int i;

    for (i = 0; i < MAX_CPUS; i++) {
        s->slaves[i].intreg_pending = 0;
        s->slaves[i].irl_out = 0;
    }
    s->intregm_disabled = ~MASTER_IRQ_MASK;
    s->intregm_pending = 0;
    s->target_cpu = 0;
    slavio_check_interrupts(s, 0);
}

static int slavio_intctl_init1(SysBusDevice *dev)
{
    SLAVIO_INTCTLState *s = FROM_SYSBUS(SLAVIO_INTCTLState, dev);
    unsigned int i, j;
    char slave_name[45];

    qdev_init_gpio_in(&dev->qdev, slavio_set_irq_all, 32 + MAX_CPUS);
    memory_region_init_io(&s->iomem, &slavio_intctlm_mem_ops, s,
                          "master-interrupt-controller", INTCTLM_SIZE);
    sysbus_init_mmio(dev, &s->iomem);

    for (i = 0; i < MAX_CPUS; i++) {
        snprintf(slave_name, sizeof(slave_name),
                 "slave-interrupt-controller-%i", i);
        for (j = 0; j < MAX_PILS; j++) {
            sysbus_init_irq(dev, &s->cpu_irqs[i][j]);
        }
        memory_region_init_io(&s->slaves[i].iomem, &slavio_intctl_mem_ops,
                              &s->slaves[i], slave_name, INTCTL_SIZE);
        sysbus_init_mmio(dev, &s->slaves[i].iomem);
        s->slaves[i].cpu = i;
        s->slaves[i].master = s;
    }

    return 0;
}

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

    k->init = slavio_intctl_init1;
    dc->reset = slavio_intctl_reset;
    dc->vmsd = &vmstate_intctl;
}

static TypeInfo slavio_intctl_info = {
    .name          = "slavio_intctl",
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(SLAVIO_INTCTLState),
    .class_init    = slavio_intctl_class_init,
};

static void slavio_intctl_register_types(void)
{
    type_register_static(&slavio_intctl_info);
}

type_init(slavio_intctl_register_types)
