/*
 * Copyright (c) 2013 - 2019, Max Filippov, Open Source and Linux Lab.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Open Source and Linux Lab nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "qemu/osdep.h"
#include "hw/irq.h"
#include "hw/xtensa/mx_pic.h"
#include "qemu/log.h"

#define MX_MAX_CPU 32
#define MX_MAX_IRQ 32

#define MIROUT 0x0
#define MIPICAUSE 0x100
#define MIPISET 0x140
#define MIENG 0x180
#define MIENGSET 0x184
#define MIASG 0x188
#define MIASGSET 0x18c
#define MIPIPART 0x190
#define SYSCFGID 0x1a0
#define MPSCORE 0x200
#define CCON 0x220

struct XtensaMxPic {
    unsigned n_cpu;
    unsigned n_irq;

    uint32_t ext_irq_state;
    uint32_t mieng;
    uint32_t miasg;
    uint32_t mirout[MX_MAX_IRQ];
    uint32_t mipipart;
    uint32_t runstall;

    qemu_irq *irq_inputs;
    struct XtensaMxPicCpu {
        XtensaMxPic *mx;
        qemu_irq *irq;
        qemu_irq runstall;
        uint32_t mipicause;
        uint32_t mirout_cache;
        uint32_t irq_state_cache;
        uint32_t ccon;
        MemoryRegion reg;
    } cpu[MX_MAX_CPU];
};

static uint64_t xtensa_mx_pic_ext_reg_read(void *opaque, hwaddr offset,
                                           unsigned size)
{
    struct XtensaMxPicCpu *mx_cpu = opaque;
    struct XtensaMxPic *mx = mx_cpu->mx;

    if (offset < MIROUT + MX_MAX_IRQ) {
        return mx->mirout[offset - MIROUT];
    } else if (offset >= MIPICAUSE && offset < MIPICAUSE + MX_MAX_CPU) {
        return mx->cpu[offset - MIPICAUSE].mipicause;
    } else {
        switch (offset) {
        case MIENG:
            return mx->mieng;

        case MIASG:
            return mx->miasg;

        case MIPIPART:
            return mx->mipipart;

        case SYSCFGID:
            return ((mx->n_cpu - 1) << 18) | (mx_cpu - mx->cpu);

        case MPSCORE:
            return mx->runstall;

        case CCON:
            return mx_cpu->ccon;

        default:
            qemu_log_mask(LOG_GUEST_ERROR,
                          "unknown RER in MX PIC range: 0x%08x\n",
                          (uint32_t)offset);
            return 0;
        }
    }
}

static uint32_t xtensa_mx_pic_get_ipi_for_cpu(const XtensaMxPic *mx,
                                              unsigned cpu)
{
    uint32_t mipicause = mx->cpu[cpu].mipicause;
    uint32_t mipipart = mx->mipipart;

    return (((mipicause & 1) << (mipipart & 3)) |
            ((mipicause & 0x000e) != 0) << ((mipipart >> 2) & 3) |
            ((mipicause & 0x00f0) != 0) << ((mipipart >> 4) & 3) |
            ((mipicause & 0xff00) != 0) << ((mipipart >> 6) & 3)) & 0x7;
}

static uint32_t xtensa_mx_pic_get_ext_irq_for_cpu(const XtensaMxPic *mx,
                                                  unsigned cpu)
{
    return ((((mx->ext_irq_state & mx->mieng) | mx->miasg) &
             mx->cpu[cpu].mirout_cache) << 2) |
        xtensa_mx_pic_get_ipi_for_cpu(mx, cpu);
}

static void xtensa_mx_pic_update_cpu(XtensaMxPic *mx, unsigned cpu)
{
    uint32_t irq = xtensa_mx_pic_get_ext_irq_for_cpu(mx, cpu);
    uint32_t changed_irq = mx->cpu[cpu].irq_state_cache ^ irq;
    unsigned i;

    qemu_log_mask(CPU_LOG_INT, "%s: CPU %d, irq: %08x, changed_irq: %08x\n",
                  __func__, cpu, irq, changed_irq);
    mx->cpu[cpu].irq_state_cache = irq;
    for (i = 0; changed_irq; ++i) {
        uint32_t mask = 1u << i;

        if (changed_irq & mask) {
            changed_irq ^= mask;
            qemu_set_irq(mx->cpu[cpu].irq[i], irq & mask);
        }
    }
}

static void xtensa_mx_pic_update_all(XtensaMxPic *mx)
{
    unsigned cpu;

    for (cpu = 0; cpu < mx->n_cpu; ++cpu) {
        xtensa_mx_pic_update_cpu(mx, cpu);
    }
}

static void xtensa_mx_pic_ext_reg_write(void *opaque, hwaddr offset,
                                        uint64_t v, unsigned size)
{
    struct XtensaMxPicCpu *mx_cpu = opaque;
    struct XtensaMxPic *mx = mx_cpu->mx;
    unsigned cpu;

    if (offset < MIROUT + mx->n_irq) {
        mx->mirout[offset - MIROUT] = v;
        for (cpu = 0; cpu < mx->n_cpu; ++cpu) {
            uint32_t mask = 1u << (offset - MIROUT);

            if (!(mx->cpu[cpu].mirout_cache & mask) != !(v & (1u << cpu))) {
                mx->cpu[cpu].mirout_cache ^= mask;
                xtensa_mx_pic_update_cpu(mx, cpu);
            }
        }
    } else if (offset >= MIPICAUSE && offset < MIPICAUSE + mx->n_cpu) {
        cpu = offset - MIPICAUSE;
        mx->cpu[cpu].mipicause &= ~v;
        xtensa_mx_pic_update_cpu(mx, cpu);
    } else if (offset >= MIPISET && offset < MIPISET + 16) {
        for (cpu = 0; cpu < mx->n_cpu; ++cpu) {
            if (v & (1u << cpu)) {
                mx->cpu[cpu].mipicause |= 1u << (offset - MIPISET);
                xtensa_mx_pic_update_cpu(mx, cpu);
            }
        }
    } else {
        uint32_t change = 0;
        uint32_t oldv, newv;
        const char *name = "???";

        switch (offset) {
        case MIENG:
            change = mx->mieng & v;
            oldv = mx->mieng;
            mx->mieng &= ~v;
            newv = mx->mieng;
            name = "MIENG";
            break;

        case MIENGSET:
            change = ~mx->mieng & v;
            oldv = mx->mieng;
            mx->mieng |= v;
            newv = mx->mieng;
            name = "MIENG";
            break;

        case MIASG:
            change = mx->miasg & v;
            oldv = mx->miasg;
            mx->miasg &= ~v;
            newv = mx->miasg;
            name = "MIASG";
            break;

        case MIASGSET:
            change = ~mx->miasg & v;
            oldv = mx->miasg;
            mx->miasg |= v;
            newv = mx->miasg;
            name = "MIASG";
            break;

        case MIPIPART:
            change = mx->mipipart ^ v;
            oldv = mx->mipipart;
            mx->mipipart = v;
            newv = mx->mipipart;
            name = "MIPIPART";
            break;

        case MPSCORE:
            change = mx->runstall ^ v;
            oldv = mx->runstall;
            mx->runstall = v;
            newv = mx->runstall;
            name = "RUNSTALL";
            for (cpu = 0; cpu < mx->n_cpu; ++cpu) {
                if (change & (1u << cpu)) {
                    qemu_set_irq(mx->cpu[cpu].runstall, v & (1u << cpu));
                }
            }
            break;

        case CCON:
            mx_cpu->ccon = v & 0x1;
            break;

        default:
            qemu_log_mask(LOG_GUEST_ERROR,
                          "unknown WER in MX PIC range: 0x%08x = 0x%08x\n",
                          (uint32_t)offset, (uint32_t)v);
            break;
        }
        if (change) {
            qemu_log_mask(CPU_LOG_INT,
                          "%s: %s changed by CPU %d: %08x -> %08x\n",
                          __func__, name, (int)(mx_cpu - mx->cpu),
                          oldv, newv);
            xtensa_mx_pic_update_all(mx);
        }
    }
}

static const MemoryRegionOps xtensa_mx_pic_ops = {
    .read = xtensa_mx_pic_ext_reg_read,
    .write = xtensa_mx_pic_ext_reg_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .unaligned = true,
    },
};

MemoryRegion *xtensa_mx_pic_register_cpu(XtensaMxPic *mx,
                                         qemu_irq *irq,
                                         qemu_irq runstall)
{
    struct XtensaMxPicCpu *mx_cpu = mx->cpu + mx->n_cpu;

    mx_cpu->mx = mx;
    mx_cpu->irq = irq;
    mx_cpu->runstall = runstall;

    memory_region_init_io(&mx_cpu->reg, NULL, &xtensa_mx_pic_ops, mx_cpu,
                          "mx_pic", 0x280);

    ++mx->n_cpu;
    return &mx_cpu->reg;
}

static void xtensa_mx_pic_set_irq(void *opaque, int irq, int active)
{
    XtensaMxPic *mx = opaque;

    if (irq < mx->n_irq) {
        uint32_t old_irq_state = mx->ext_irq_state;

        if (active) {
            mx->ext_irq_state |= 1u << irq;
        } else {
            mx->ext_irq_state &= ~(1u << irq);
        }
        if (old_irq_state != mx->ext_irq_state) {
            qemu_log_mask(CPU_LOG_INT,
                          "%s: IRQ %d, active: %d, ext_irq_state: %08x -> %08x\n",
                          __func__, irq, active,
                          old_irq_state, mx->ext_irq_state);
            xtensa_mx_pic_update_all(mx);
        }
    } else {
        qemu_log_mask(LOG_GUEST_ERROR, "%s: IRQ %d out of range\n",
                      __func__, irq);
    }
}

XtensaMxPic *xtensa_mx_pic_init(unsigned n_irq)
{
    XtensaMxPic *mx = calloc(1, sizeof(XtensaMxPic));

    mx->n_irq = n_irq + 1;
    mx->irq_inputs = qemu_allocate_irqs(xtensa_mx_pic_set_irq, mx,
                                        mx->n_irq);
    return mx;
}

void xtensa_mx_pic_reset(void *opaque)
{
    XtensaMxPic *mx = opaque;
    unsigned i;

    mx->ext_irq_state = 0;
    mx->mieng = mx->n_irq < 32 ? (1u << mx->n_irq) - 1 : ~0u;
    mx->miasg = 0;
    mx->mipipart = 0;
    for (i = 0; i < mx->n_irq; ++i) {
        mx->mirout[i] = 1;
    }
    for (i = 0; i < mx->n_cpu; ++i) {
        mx->cpu[i].mipicause = 0;
        mx->cpu[i].mirout_cache = i ? 0 : mx->mieng;
        mx->cpu[i].irq_state_cache = 0;
        mx->cpu[i].ccon = 0;
    }
    mx->runstall = (1u << mx->n_cpu) - 2;
    for (i = 0; i < mx->n_cpu; ++i) {
        qemu_set_irq(mx->cpu[i].runstall, i > 0);
    }
}

qemu_irq *xtensa_mx_pic_get_extints(XtensaMxPic *mx)
{
    return mx->irq_inputs + 1;
}
