/*
 * QEMU Loongson Local I/O interrupt controler.
 *
 * Copyright (c) 2020 Huacai Chen <chenhc@lemote.com>
 * Copyright (c) 2020 Jiaxun Yang <jiaxun.yang@flygoat.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"
#include "qemu/module.h"
#include "qemu/log.h"
#include "hw/irq.h"
#include "hw/qdev-properties.h"
#include "hw/intc/loongson_liointc.h"

#define NUM_IRQS                32

#define NUM_CORES               4
#define NUM_IPS                 4
#define NUM_PARENTS             (NUM_CORES * NUM_IPS)
#define PARENT_COREx_IPy(x, y)  (NUM_IPS * x + y)

#define R_MAPPER_START          0x0
#define R_MAPPER_END            0x20
#define R_ISR                   R_MAPPER_END
#define R_IEN                   0x24
#define R_IEN_SET               0x28
#define R_IEN_CLR               0x2c
#define R_ISR_SIZE              0x8
#define R_START                 0x40
#define R_END                   (R_START + R_ISR_SIZE * NUM_CORES)

struct loongson_liointc {
    SysBusDevice parent_obj;

    MemoryRegion mmio;
    qemu_irq parent_irq[NUM_PARENTS];

    uint8_t mapper[NUM_IRQS]; /* 0:3 for core, 4:7 for IP */
    uint32_t isr;
    uint32_t ien;
    uint32_t per_core_isr[NUM_CORES];

    /* state of the interrupt input pins */
    uint32_t pin_state;
    bool parent_state[NUM_PARENTS];
};

static void update_irq(struct loongson_liointc *p)
{
    uint32_t irq, core, ip;
    uint32_t per_ip_isr[NUM_IPS] = {0};

    /* level triggered interrupt */
    p->isr = p->pin_state;

    /* Clear disabled IRQs */
    p->isr &= p->ien;

    /* Clear per_core_isr */
    for (core = 0; core < NUM_CORES; core++) {
        p->per_core_isr[core] = 0;
    }

    /* Update per_core_isr and per_ip_isr */
    for (irq = 0; irq < NUM_IRQS; irq++) {
        if (!(p->isr & (1 << irq))) {
            continue;
        }

        for (core = 0; core < NUM_CORES; core++) {
            if ((p->mapper[irq] & (1 << core))) {
                p->per_core_isr[core] |= (1 << irq);
            }
        }

        for (ip = 0; ip < NUM_IPS; ip++) {
            if ((p->mapper[irq] & (1 << (ip + 4)))) {
                per_ip_isr[ip] |= (1 << irq);
            }
        }
    }

    /* Emit IRQ to parent! */
    for (core = 0; core < NUM_CORES; core++) {
        for (ip = 0; ip < NUM_IPS; ip++) {
            int parent = PARENT_COREx_IPy(core, ip);
            if (p->parent_state[parent] !=
                (!!p->per_core_isr[core] && !!per_ip_isr[ip])) {
                p->parent_state[parent] = !p->parent_state[parent];
                qemu_set_irq(p->parent_irq[parent], p->parent_state[parent]);
            }
        }
    }
}

static uint64_t
liointc_read(void *opaque, hwaddr addr, unsigned int size)
{
    struct loongson_liointc *p = opaque;
    uint32_t r = 0;

    /* Mapper is 1 byte */
    if (size == 1 && addr < R_MAPPER_END) {
        r = p->mapper[addr];
        goto out;
    }

    /* Rest are 4 bytes */
    if (size != 4 || (addr % 4)) {
        goto out;
    }

    if (addr >= R_START && addr < R_END) {
        hwaddr offset = addr - R_START;
        int core = offset / R_ISR_SIZE;

        if (offset % R_ISR_SIZE) {
            goto out;
        }
        r = p->per_core_isr[core];
        goto out;
    }

    switch (addr) {
    case R_ISR:
        r = p->isr;
        break;
    case R_IEN:
        r = p->ien;
        break;
    default:
        break;
    }

out:
    qemu_log_mask(CPU_LOG_INT, "%s: size=%d, addr=%"HWADDR_PRIx", val=%x\n",
                  __func__, size, addr, r);
    return r;
}

static void
liointc_write(void *opaque, hwaddr addr,
          uint64_t val64, unsigned int size)
{
    struct loongson_liointc *p = opaque;
    uint32_t value = val64;

    qemu_log_mask(CPU_LOG_INT, "%s: size=%d, addr=%"HWADDR_PRIx", val=%x\n",
                  __func__, size, addr, value);

    /* Mapper is 1 byte */
    if (size == 1 && addr < R_MAPPER_END) {
        p->mapper[addr] = value;
        goto out;
    }

    /* Rest are 4 bytes */
    if (size != 4 || (addr % 4)) {
        goto out;
    }

    if (addr >= R_START && addr < R_END) {
        hwaddr offset = addr - R_START;
        int core = offset / R_ISR_SIZE;

        if (offset % R_ISR_SIZE) {
            goto out;
        }
        p->per_core_isr[core] = value;
        goto out;
    }

    switch (addr) {
    case R_IEN_SET:
        p->ien |= value;
        break;
    case R_IEN_CLR:
        p->ien &= ~value;
        break;
    default:
        break;
    }

out:
    update_irq(p);
}

static const MemoryRegionOps pic_ops = {
    .read = liointc_read,
    .write = liointc_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid = {
        .min_access_size = 1,
        .max_access_size = 4
    }
};

static void irq_handler(void *opaque, int irq, int level)
{
    struct loongson_liointc *p = opaque;

    p->pin_state &= ~(1 << irq);
    p->pin_state |= level << irq;
    update_irq(p);
}

static void loongson_liointc_init(Object *obj)
{
    struct loongson_liointc *p = LOONGSON_LIOINTC(obj);
    int i;

    qdev_init_gpio_in(DEVICE(obj), irq_handler, 32);

    for (i = 0; i < NUM_PARENTS; i++) {
        sysbus_init_irq(SYS_BUS_DEVICE(obj), &p->parent_irq[i]);
    }

    memory_region_init_io(&p->mmio, obj, &pic_ops, p,
                         TYPE_LOONGSON_LIOINTC, R_END);
    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &p->mmio);
}

static const TypeInfo loongson_liointc_info = {
    .name          = TYPE_LOONGSON_LIOINTC,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(struct loongson_liointc),
    .instance_init = loongson_liointc_init,
};

static void loongson_liointc_register_types(void)
{
    type_register_static(&loongson_liointc_info);
}

type_init(loongson_liointc_register_types)
