/* 
 * ARM AMBA Generic/Distributed Interrupt Controller
 *
 * Copyright (c) 2006 CodeSourcery.
 * Written by Paul Brook
 *
 * This code is licenced under the GPL.
 */

/* TODO: Some variants of this controller can handle multiple CPUs.
   Currently only single CPU operation is implemented.  */

#include "vl.h"
#include "arm_pic.h"

//#define DEBUG_GIC

#ifdef DEBUG_GIC
#define DPRINTF(fmt, args...) \
do { printf("arm_gic: " fmt , ##args); } while (0)
#else
#define DPRINTF(fmt, args...) do {} while(0)
#endif

/* Distributed interrupt controller.  */

static const uint8_t gic_id[] =
{ 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };

#define GIC_NIRQ 96

typedef struct gic_irq_state
{
    unsigned enabled:1;
    unsigned pending:1;
    unsigned active:1;
    unsigned level:1;
    unsigned model:1; /* 0 = 1:N, 1 = N:N */
    unsigned trigger:1; /* nonzero = edge triggered.  */
} gic_irq_state;

#define GIC_SET_ENABLED(irq) s->irq_state[irq].enabled = 1
#define GIC_CLEAR_ENABLED(irq) s->irq_state[irq].enabled = 0
#define GIC_TEST_ENABLED(irq) s->irq_state[irq].enabled
#define GIC_SET_PENDING(irq) s->irq_state[irq].pending = 1
#define GIC_CLEAR_PENDING(irq) s->irq_state[irq].pending = 0
#define GIC_TEST_PENDING(irq) s->irq_state[irq].pending
#define GIC_SET_ACTIVE(irq) s->irq_state[irq].active = 1
#define GIC_CLEAR_ACTIVE(irq) s->irq_state[irq].active = 0
#define GIC_TEST_ACTIVE(irq) s->irq_state[irq].active
#define GIC_SET_MODEL(irq) s->irq_state[irq].model = 1
#define GIC_CLEAR_MODEL(irq) s->irq_state[irq].model = 0
#define GIC_TEST_MODEL(irq) s->irq_state[irq].model
#define GIC_SET_LEVEL(irq) s->irq_state[irq].level = 1
#define GIC_CLEAR_LEVEL(irq) s->irq_state[irq].level = 0
#define GIC_TEST_LEVEL(irq) s->irq_state[irq].level
#define GIC_SET_TRIGGER(irq) s->irq_state[irq].trigger = 1
#define GIC_CLEAR_TRIGGER(irq) s->irq_state[irq].trigger = 0
#define GIC_TEST_TRIGGER(irq) s->irq_state[irq].trigger

typedef struct gic_state
{
    arm_pic_handler handler;
    uint32_t base;
    void *parent;
    int parent_irq;
    int enabled;
    int cpu_enabled;

    gic_irq_state irq_state[GIC_NIRQ];
    int irq_target[GIC_NIRQ];
    int priority[GIC_NIRQ];
    int last_active[GIC_NIRQ];

    int priority_mask;
    int running_irq;
    int running_priority;
    int current_pending;
} gic_state;

/* TODO: Many places that call this routine could be optimized.  */
/* Update interrupt status after enabled or pending bits have been changed.  */
static void gic_update(gic_state *s)
{
    int best_irq;
    int best_prio;
    int irq;

    s->current_pending = 1023;
    if (!s->enabled || !s->cpu_enabled) {
        pic_set_irq_new(s->parent, s->parent_irq, 0);
        return;
    }
    best_prio = 0x100;
    best_irq = 1023;
    for (irq = 0; irq < 96; irq++) {
        if (GIC_TEST_ENABLED(irq) && GIC_TEST_PENDING(irq)) {
            if (s->priority[irq] < best_prio) {
                best_prio = s->priority[irq];
                best_irq = irq;
            }
        }
    }
    if (best_prio > s->priority_mask) {
        pic_set_irq_new(s->parent, s->parent_irq, 0);
    } else {
        s->current_pending = best_irq;
        if (best_prio < s->running_priority) {
            DPRINTF("Raised pending IRQ %d\n", best_irq);
            pic_set_irq_new(s->parent, s->parent_irq, 1);
        }
    }
}

static void gic_set_irq(void *opaque, int irq, int level)
{
    gic_state *s = (gic_state *)opaque;
    /* The first external input line is internal interrupt 32.  */
    irq += 32;
    if (level == GIC_TEST_LEVEL(irq)) 
        return;

    if (level) {
        GIC_SET_LEVEL(irq);
        if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq)) {
            DPRINTF("Set %d pending\n", irq);
            GIC_SET_PENDING(irq);
        }
    } else {
        GIC_CLEAR_LEVEL(irq);
    }
    gic_update(s);
}

static void gic_set_running_irq(gic_state *s, int irq)
{
    s->running_irq = irq;
    if (irq == 1023)
        s->running_priority = 0x100;
    else
        s->running_priority = s->priority[irq];
    gic_update(s);
}

static uint32_t gic_acknowledge_irq(gic_state *s)
{
    int new_irq;
    new_irq = s->current_pending;
    if (new_irq == 1023 || s->priority[new_irq] >= s->running_priority) {
        DPRINTF("ACK no pending IRQ\n");
        return 1023;
    }
    pic_set_irq_new(s->parent, s->parent_irq, 0);
    s->last_active[new_irq] = s->running_irq;
    /* For level triggered interrupts we clear the pending bit while
       the interrupt is active.  */
    GIC_CLEAR_PENDING(new_irq);
    gic_set_running_irq(s, new_irq);
    DPRINTF("ACK %d\n", new_irq);
    return new_irq;
}

static void gic_complete_irq(gic_state * s, int irq)
{
    int update = 0;
    DPRINTF("EOI %d\n", irq);
    if (s->running_irq == 1023)
        return; /* No active IRQ.  */
    if (irq != 1023) {
        /* Mark level triggered interrupts as pending if they are still
           raised.  */
        if (!GIC_TEST_TRIGGER(irq) && GIC_TEST_ENABLED(irq)
                && GIC_TEST_LEVEL(irq)) {
            GIC_SET_PENDING(irq);
            update = 1;
        }
    }
    if (irq != s->running_irq) {
        /* Complete an IRQ that is not currently running.  */
        int tmp = s->running_irq;
        while (s->last_active[tmp] != 1023) {
            if (s->last_active[tmp] == irq) {
                s->last_active[tmp] = s->last_active[irq];
                break;
            }
            tmp = s->last_active[tmp];
        }
        if (update) {
            gic_update(s);
        }
    } else {
        /* Complete the current running IRQ.  */
        gic_set_running_irq(s, s->last_active[s->running_irq]);
    }
}

static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset)
{
    gic_state *s = (gic_state *)opaque;
    uint32_t res;
    int irq;
    int i;

    offset -= s->base + 0x1000;
    if (offset < 0x100) {
        if (offset == 0)
            return s->enabled;
        if (offset == 4)
            return (GIC_NIRQ / 32) - 1;
        if (offset < 0x08)
            return 0;
        goto bad_reg;
    } else if (offset < 0x200) {
        /* Interrupt Set/Clear Enable.  */
        if (offset < 0x180)
            irq = (offset - 0x100) * 8;
        else
            irq = (offset - 0x180) * 8;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        res = 0;
        for (i = 0; i < 8; i++) {
            if (GIC_TEST_ENABLED(irq + i)) {
                res |= (1 << i);
            }
        }
    } else if (offset < 0x300) {
        /* Interrupt Set/Clear Pending.  */
        if (offset < 0x280)
            irq = (offset - 0x200) * 8;
        else
            irq = (offset - 0x280) * 8;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        res = 0;
        for (i = 0; i < 8; i++) {
            if (GIC_TEST_PENDING(irq + i)) {
                res |= (1 << i);
            }
        }
    } else if (offset < 0x400) {
        /* Interrupt Active.  */
        irq = (offset - 0x300) * 8;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        res = 0;
        for (i = 0; i < 8; i++) {
            if (GIC_TEST_ACTIVE(irq + i)) {
                res |= (1 << i);
            }
        }
    } else if (offset < 0x800) {
        /* Interrupt Priority.  */
        irq = offset - 0x400;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        res = s->priority[irq];
    } else if (offset < 0xc00) {
        /* Interrupt CPU Target.  */
        irq = offset - 0x800;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        res = s->irq_target[irq];
    } else if (offset < 0xf00) {
        /* Interrupt Configuration.  */
        irq = (offset - 0xc00) * 2;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        res = 0;
        for (i = 0; i < 4; i++) {
            if (GIC_TEST_MODEL(irq + i))
                res |= (1 << (i * 2));
            if (GIC_TEST_TRIGGER(irq + i))
                res |= (2 << (i * 2));
        }
    } else if (offset < 0xfe0) {
        goto bad_reg;
    } else /* offset >= 0xfe0 */ {
        if (offset & 3) {
            res = 0;
        } else {
            res = gic_id[(offset - 0xfe0) >> 2];
        }
    }
    return res;
bad_reg:
    cpu_abort (cpu_single_env, "gic_dist_readb: Bad offset %x\n", offset);
    return 0;
}

static uint32_t gic_dist_readw(void *opaque, target_phys_addr_t offset)
{
    uint32_t val;
    val = gic_dist_readb(opaque, offset);
    val |= gic_dist_readb(opaque, offset + 1) << 8;
    return val;
}

static uint32_t gic_dist_readl(void *opaque, target_phys_addr_t offset)
{
    uint32_t val;
    val = gic_dist_readw(opaque, offset);
    val |= gic_dist_readw(opaque, offset + 2) << 16;
    return val;
}

static void gic_dist_writeb(void *opaque, target_phys_addr_t offset,
                            uint32_t value)
{
    gic_state *s = (gic_state *)opaque;
    int irq;
    int i;

    offset -= s->base + 0x1000;
    if (offset < 0x100) {
        if (offset == 0) {
            s->enabled = (value & 1);
            DPRINTF("Distribution %sabled\n", s->enabled ? "En" : "Dis");
        } else if (offset < 4) {
            /* ignored.  */
        } else {
            goto bad_reg;
        }
    } else if (offset < 0x180) {
        /* Interrupt Set Enable.  */
        irq = (offset - 0x100) * 8;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        for (i = 0; i < 8; i++) {
            if (value & (1 << i)) {
                if (!GIC_TEST_ENABLED(irq + i))
                    DPRINTF("Enabled IRQ %d\n", irq + i);
                GIC_SET_ENABLED(irq + i);
                /* If a raised level triggered IRQ enabled then mark
                   is as pending.  */
                if (GIC_TEST_LEVEL(irq + i) && !GIC_TEST_TRIGGER(irq + i))
                    GIC_SET_PENDING(irq + i);
            }
        }
    } else if (offset < 0x200) {
        /* Interrupt Clear Enable.  */
        irq = (offset - 0x180) * 8;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        for (i = 0; i < 8; i++) {
            if (value & (1 << i)) {
                if (GIC_TEST_ENABLED(irq + i))
                    DPRINTF("Disabled IRQ %d\n", irq + i);
                GIC_CLEAR_ENABLED(irq + i);
            }
        }
    } else if (offset < 0x280) {
        /* Interrupt Set Pending.  */
        irq = (offset - 0x200) * 8;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        for (i = 0; i < 8; i++) {
            if (value & (1 << i)) {
                GIC_SET_PENDING(irq + i);
            }
        }
    } else if (offset < 0x300) {
        /* Interrupt Clear Pending.  */
        irq = (offset - 0x280) * 8;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        for (i = 0; i < 8; i++) {
            if (value & (1 << i)) {
                GIC_CLEAR_PENDING(irq + i);
            }
        }
    } else if (offset < 0x400) {
        /* Interrupt Active.  */
        goto bad_reg;
    } else if (offset < 0x800) {
        /* Interrupt Priority.  */
        irq = offset - 0x400;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        s->priority[irq] = value;
    } else if (offset < 0xc00) {
        /* Interrupt CPU Target.  */
        irq = offset - 0x800;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        s->irq_target[irq] = value;
    } else if (offset < 0xf00) {
        /* Interrupt Configuration.  */
        irq = (offset - 0xc00) * 4;
        if (irq >= GIC_NIRQ)
            goto bad_reg;
        for (i = 0; i < 4; i++) {
            if (value & (1 << (i * 2))) {
                GIC_SET_MODEL(irq + i);
            } else {
                GIC_CLEAR_MODEL(irq + i);
            }
            if (value & (2 << (i * 2))) {
                GIC_SET_TRIGGER(irq + i);
            } else {
                GIC_CLEAR_TRIGGER(irq + i);
            }
        }
    } else {
        /* 0xf00 is only handled for word writes.  */
        goto bad_reg;
    }
    gic_update(s);
    return;
bad_reg:
    cpu_abort (cpu_single_env, "gic_dist_writeb: Bad offset %x\n", offset);
}

static void gic_dist_writew(void *opaque, target_phys_addr_t offset,
                            uint32_t value)
{
    gic_state *s = (gic_state *)opaque;
    if (offset - s->base == 0xf00) {
        GIC_SET_PENDING(value & 0x3ff);
        gic_update(s);
        return;
    }
    gic_dist_writeb(opaque, offset, value & 0xff);
    gic_dist_writeb(opaque, offset + 1, value >> 8);
}

static void gic_dist_writel(void *opaque, target_phys_addr_t offset,
                            uint32_t value)
{
    gic_dist_writew(opaque, offset, value & 0xffff);
    gic_dist_writew(opaque, offset + 2, value >> 16);
}

static CPUReadMemoryFunc *gic_dist_readfn[] = {
   gic_dist_readb,
   gic_dist_readw,
   gic_dist_readl
};

static CPUWriteMemoryFunc *gic_dist_writefn[] = {
   gic_dist_writeb,
   gic_dist_writew,
   gic_dist_writel
};

static uint32_t gic_cpu_read(void *opaque, target_phys_addr_t offset)
{
    gic_state *s = (gic_state *)opaque;
    offset -= s->base;
    switch (offset) {
    case 0x00: /* Control */
        return s->cpu_enabled;
    case 0x04: /* Priority mask */
        return s->priority_mask;
    case 0x08: /* Binary Point */
        /* ??? Not implemented.  */
        return 0;
    case 0x0c: /* Acknowledge */
        return gic_acknowledge_irq(s);
    case 0x14: /* Runing Priority */
        return s->running_priority;
    case 0x18: /* Highest Pending Interrupt */
        return s->current_pending;
    default:
        cpu_abort (cpu_single_env, "gic_cpu_writeb: Bad offset %x\n", offset);
        return 0;
    }
}

static void gic_cpu_write(void *opaque, target_phys_addr_t offset,
                          uint32_t value)
{
    gic_state *s = (gic_state *)opaque;
    offset -= s->base;
    switch (offset) {
    case 0x00: /* Control */
        s->cpu_enabled = (value & 1);
        DPRINTF("CPU %sabled\n", s->cpu_enabled ? "En" : "Dis");
        break;
    case 0x04: /* Priority mask */
        s->priority_mask = (value & 0x3ff);
        break;
    case 0x08: /* Binary Point */
        /* ??? Not implemented.  */
        break;
    case 0x10: /* End Of Interrupt */
        return gic_complete_irq(s, value & 0x3ff);
    default:
        cpu_abort (cpu_single_env, "gic_cpu_writeb: Bad offset %x\n", offset);
        return;
    }
    gic_update(s);
}

static CPUReadMemoryFunc *gic_cpu_readfn[] = {
   gic_cpu_read,
   gic_cpu_read,
   gic_cpu_read
};

static CPUWriteMemoryFunc *gic_cpu_writefn[] = {
   gic_cpu_write,
   gic_cpu_write,
   gic_cpu_write
};

static void gic_reset(gic_state *s)
{
    int i;
    memset(s->irq_state, 0, GIC_NIRQ * sizeof(gic_irq_state));
    s->priority_mask = 0xf0;
    s->current_pending = 1023;
    s->running_irq = 1023;
    s->running_priority = 0x100;
    for (i = 0; i < 15; i++) {
        GIC_SET_ENABLED(i);
        GIC_SET_TRIGGER(i);
    }
    s->enabled = 0;
    s->cpu_enabled = 0;
}

void *arm_gic_init(uint32_t base, void *parent, int parent_irq)
{
    gic_state *s;
    int iomemtype;

    s = (gic_state *)qemu_mallocz(sizeof(gic_state));
    if (!s)
        return NULL;
    s->handler = gic_set_irq;
    s->parent = parent;
    s->parent_irq = parent_irq;
    if (base != 0xffffffff) {
        iomemtype = cpu_register_io_memory(0, gic_cpu_readfn,
                                           gic_cpu_writefn, s);
        cpu_register_physical_memory(base, 0x00000fff, iomemtype);
        iomemtype = cpu_register_io_memory(0, gic_dist_readfn,
                                           gic_dist_writefn, s);
        cpu_register_physical_memory(base + 0x1000, 0x00000fff, iomemtype);
        s->base = base;
    } else {
        s->base = 0;
    }
    gic_reset(s);
    return s;
}
