/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
#include "migration/qemu-file.h"
#include "hw/arm/pic.h"
#include "hw/android/goldfish/device.h"
#include "hw/irq.h"
#include "hw/hw.h"

enum {
    INTERRUPT_STATUS        = 0x00, // number of pending interrupts
    INTERRUPT_NUMBER        = 0x04,
    INTERRUPT_DISABLE_ALL   = 0x08,
    INTERRUPT_DISABLE       = 0x0c,
    INTERRUPT_ENABLE        = 0x10
};

struct goldfish_int_state {
    struct goldfish_device dev;
    uint32_t level;
    uint32_t pending_count;
    uint32_t irq_enabled;
    uint32_t fiq_enabled;
    qemu_irq parent_irq;
    qemu_irq parent_fiq;
};

#define  GOLDFISH_INT_SAVE_VERSION  1

#define  QFIELD_STRUCT  struct goldfish_int_state
QFIELD_BEGIN(goldfish_int_fields)
    QFIELD_INT32(level),
    QFIELD_INT32(pending_count),
    QFIELD_INT32(irq_enabled),
    QFIELD_INT32(fiq_enabled),
QFIELD_END

static void goldfish_int_save(QEMUFile*  f, void*  opaque)
{
    struct goldfish_int_state*  s = opaque;

    qemu_put_struct(f, goldfish_int_fields, s);
}

static void goldfish_int_update(struct goldfish_int_state *s)
{
    uint32_t flags;

    flags = (s->level & s->irq_enabled);
    qemu_set_irq(s->parent_irq, flags != 0);

    flags = (s->level & s->fiq_enabled);
    qemu_set_irq(s->parent_fiq, flags != 0);
}

static int  goldfish_int_load(QEMUFile*  f, void*  opaque, int  version_id)
{
    struct goldfish_int_state*  s = opaque;

    if (version_id != GOLDFISH_INT_SAVE_VERSION)
        return -1;

    if (qemu_get_struct(f, goldfish_int_fields, s) < 0)
        return -1;

    goldfish_int_update(s);
    return 0;
}

static void goldfish_int_set_irq(void *opaque, int irq, int level)
{
    struct goldfish_int_state *s = (struct goldfish_int_state *)opaque;
    uint32_t mask = (1U << irq);

    if(level) {
        if(!(s->level & mask)) {
            if(s->irq_enabled & mask)
                s->pending_count++;
            s->level |= mask;
        }
    }
    else {
        if(s->level & mask) {
            if(s->irq_enabled & mask)
                s->pending_count--;
            s->level &= ~mask;
        }
    }
    goldfish_int_update(s);
}

static uint32_t goldfish_int_read(void *opaque, hwaddr offset)
{
    struct goldfish_int_state *s = (struct goldfish_int_state *)opaque;

    switch (offset) {
    case INTERRUPT_STATUS: /* IRQ_STATUS */
        return s->pending_count;
    case INTERRUPT_NUMBER: {
        int i;
        uint32_t pending = s->level & s->irq_enabled;
        for(i = 0; i < 32; i++) {
            if(pending & (1U << i))
                return i;
        }
        return 0;
    }
    default:
        cpu_abort(current_cpu,
                  "goldfish_int_read: Bad offset %" HWADDR_PRIx "\n",
                  offset);
        return 0;
    }
}

static void goldfish_int_write(void *opaque, hwaddr offset, uint32_t value)
{
    struct goldfish_int_state *s = (struct goldfish_int_state *)opaque;
    uint32_t mask = (1U << value);

    switch (offset) {
        case INTERRUPT_DISABLE_ALL:
            s->pending_count = 0;
            s->level = 0;
            break;

        case INTERRUPT_DISABLE:
            if(s->irq_enabled & mask) {
                if(s->level & mask)
                    s->pending_count--;
                s->irq_enabled &= ~mask;
            }
            break;
        case INTERRUPT_ENABLE:
            if(!(s->irq_enabled & mask)) {
                s->irq_enabled |= mask;
                if(s->level & mask)
                    s->pending_count++;
            }
            break;

    default:
        cpu_abort(current_cpu,
                  "goldfish_int_write: Bad offset %" HWADDR_PRIx "\n",
                  offset);
        return;
    }
    goldfish_int_update(s);
}

static CPUReadMemoryFunc *goldfish_int_readfn[] = {
    goldfish_int_read,
    goldfish_int_read,
    goldfish_int_read
};

static CPUWriteMemoryFunc *goldfish_int_writefn[] = {
    goldfish_int_write,
    goldfish_int_write,
    goldfish_int_write
};

qemu_irq*  goldfish_interrupt_init(uint32_t base, qemu_irq parent_irq, qemu_irq parent_fiq)
{
    int ret;
    struct goldfish_int_state *s;
    qemu_irq*  qi;

    s = g_malloc0(sizeof(*s));
    qi = qemu_allocate_irqs(goldfish_int_set_irq, s, GFD_MAX_IRQ);
    s->dev.name = "goldfish_interrupt_controller";
    s->dev.id = -1;
    s->dev.base = base;
    s->dev.size = 0x1000;
    s->parent_irq = parent_irq;
    s->parent_fiq = parent_fiq;

    ret = goldfish_device_add(&s->dev, goldfish_int_readfn, goldfish_int_writefn, s);
    if(ret) {
        g_free(s);
        return NULL;
    }

    register_savevm(NULL,
                    "goldfish_int",
                    0,
                    GOLDFISH_INT_SAVE_VERSION,
                    goldfish_int_save,
                    goldfish_int_load,
                    s);

    return qi;
}

