/*
 * Inter-Thread Communication Unit emulation.
 *
 * Copyright (c) 2016 Imagination Technologies
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "cpu.h"
#include "qemu/log.h"
#include "exec/exec-all.h"
#include "hw/hw.h"
#include "hw/sysbus.h"
#include "sysemu/sysemu.h"
#include "hw/misc/mips_itu.h"

#define ITC_TAG_ADDRSPACE_SZ (ITC_ADDRESSMAP_NUM * 8)
/* Initialize as 4kB area to fit all 32 cells with default 128B grain.
   Storage may be resized by the software. */
#define ITC_STORAGE_ADDRSPACE_SZ 0x1000

#define ITC_FIFO_NUM_MAX 16
#define ITC_SEMAPH_NUM_MAX 16
#define ITC_AM1_NUMENTRIES_OFS 20

#define ITC_CELL_PV_MAX_VAL 0xFFFF

#define ITC_CELL_TAG_FIFO_DEPTH 28
#define ITC_CELL_TAG_FIFO_PTR 18
#define ITC_CELL_TAG_FIFO 17
#define ITC_CELL_TAG_T 16
#define ITC_CELL_TAG_F 1
#define ITC_CELL_TAG_E 0

#define ITC_AM0_BASE_ADDRESS_MASK 0xFFFFFC00ULL
#define ITC_AM0_EN_MASK 0x1

#define ITC_AM1_ADDR_MASK_MASK 0x1FC00
#define ITC_AM1_ENTRY_GRAIN_MASK 0x7

typedef enum ITCView {
    ITCVIEW_BYPASS  = 0,
    ITCVIEW_CONTROL = 1,
    ITCVIEW_EF_SYNC = 2,
    ITCVIEW_EF_TRY  = 3,
    ITCVIEW_PV_SYNC = 4,
    ITCVIEW_PV_TRY  = 5
} ITCView;

MemoryRegion *mips_itu_get_tag_region(MIPSITUState *itu)
{
    return &itu->tag_io;
}

static uint64_t itc_tag_read(void *opaque, hwaddr addr, unsigned size)
{
    MIPSITUState *tag = (MIPSITUState *)opaque;
    uint64_t index = addr >> 3;

    if (index >= ITC_ADDRESSMAP_NUM) {
        qemu_log_mask(LOG_GUEST_ERROR, "Read 0x%" PRIx64 "\n", addr);
        return 0;
    }

    return tag->ITCAddressMap[index];
}

static void itc_reconfigure(MIPSITUState *tag)
{
    uint64_t *am = &tag->ITCAddressMap[0];
    MemoryRegion *mr = &tag->storage_io;
    hwaddr address = am[0] & ITC_AM0_BASE_ADDRESS_MASK;
    uint64_t size = (1 << 10) + (am[1] & ITC_AM1_ADDR_MASK_MASK);
    bool is_enabled = (am[0] & ITC_AM0_EN_MASK) != 0;

    memory_region_transaction_begin();
    if (!(size & (size - 1))) {
        memory_region_set_size(mr, size);
    }
    memory_region_set_address(mr, address);
    memory_region_set_enabled(mr, is_enabled);
    memory_region_transaction_commit();
}

static void itc_tag_write(void *opaque, hwaddr addr,
                          uint64_t data, unsigned size)
{
    MIPSITUState *tag = (MIPSITUState *)opaque;
    uint64_t *am = &tag->ITCAddressMap[0];
    uint64_t am_old, mask;
    uint64_t index = addr >> 3;

    switch (index) {
    case 0:
        mask = ITC_AM0_BASE_ADDRESS_MASK | ITC_AM0_EN_MASK;
        break;
    case 1:
        mask = ITC_AM1_ADDR_MASK_MASK | ITC_AM1_ENTRY_GRAIN_MASK;
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR, "Bad write 0x%" PRIx64 "\n", addr);
        return;
    }

    am_old = am[index];
    am[index] = (data & mask) | (am_old & ~mask);
    if (am_old != am[index]) {
        itc_reconfigure(tag);
    }
}

static const MemoryRegionOps itc_tag_ops = {
    .read = itc_tag_read,
    .write = itc_tag_write,
    .impl = {
        .max_access_size = 8,
    },
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static inline uint32_t get_num_cells(MIPSITUState *s)
{
    return s->num_fifo + s->num_semaphores;
}

static inline ITCView get_itc_view(hwaddr addr)
{
    return (addr >> 3) & 0xf;
}

static inline int get_cell_stride_shift(const MIPSITUState *s)
{
    /* Minimum interval (for EntryGain = 0) is 128 B */
    return 7 + (s->ITCAddressMap[1] & ITC_AM1_ENTRY_GRAIN_MASK);
}

static inline ITCStorageCell *get_cell(MIPSITUState *s,
                                       hwaddr addr)
{
    uint32_t cell_idx = addr >> get_cell_stride_shift(s);
    uint32_t num_cells = get_num_cells(s);

    if (cell_idx >= num_cells) {
        cell_idx = num_cells - 1;
    }

    return &s->cell[cell_idx];
}

static void wake_blocked_threads(ITCStorageCell *c)
{
    CPUState *cs;
    CPU_FOREACH(cs) {
        if (cs->halted && (c->blocked_threads & (1ULL << cs->cpu_index))) {
            cpu_interrupt(cs, CPU_INTERRUPT_WAKE);
        }
    }
    c->blocked_threads = 0;
}

static void QEMU_NORETURN block_thread_and_exit(ITCStorageCell *c)
{
    c->blocked_threads |= 1ULL << current_cpu->cpu_index;
    cpu_restore_state(current_cpu, current_cpu->mem_io_pc);
    current_cpu->halted = 1;
    current_cpu->exception_index = EXCP_HLT;
    cpu_loop_exit(current_cpu);
}

/* ITC Bypass View */

static inline uint64_t view_bypass_read(ITCStorageCell *c)
{
    if (c->tag.FIFO) {
        return c->data[c->fifo_out];
    } else {
        return c->data[0];
    }
}

static inline void view_bypass_write(ITCStorageCell *c, uint64_t val)
{
    if (c->tag.FIFO && (c->tag.FIFOPtr > 0)) {
        int idx = (c->fifo_out + c->tag.FIFOPtr - 1) % ITC_CELL_DEPTH;
        c->data[idx] = val;
    }

    /* ignore a write to the semaphore cell */
}

/* ITC Control View */

static inline uint64_t view_control_read(ITCStorageCell *c)
{
    return ((uint64_t)c->tag.FIFODepth << ITC_CELL_TAG_FIFO_DEPTH) |
           (c->tag.FIFOPtr << ITC_CELL_TAG_FIFO_PTR) |
           (c->tag.FIFO << ITC_CELL_TAG_FIFO) |
           (c->tag.T << ITC_CELL_TAG_T) |
           (c->tag.E << ITC_CELL_TAG_E) |
           (c->tag.F << ITC_CELL_TAG_F);
}

static inline void view_control_write(ITCStorageCell *c, uint64_t val)
{
    c->tag.T = (val >> ITC_CELL_TAG_T) & 1;
    c->tag.E = (val >> ITC_CELL_TAG_E) & 1;
    c->tag.F = (val >> ITC_CELL_TAG_F) & 1;

    if (c->tag.E) {
        c->tag.FIFOPtr = 0;
    }
}

/* ITC Empty/Full View */

static uint64_t view_ef_common_read(ITCStorageCell *c, bool blocking)
{
    uint64_t ret = 0;

    if (!c->tag.FIFO) {
        return 0;
    }

    c->tag.F = 0;

    if (blocking && c->tag.E) {
        block_thread_and_exit(c);
    }

    if (c->blocked_threads) {
        wake_blocked_threads(c);
    }

    if (c->tag.FIFOPtr > 0) {
        ret = c->data[c->fifo_out];
        c->fifo_out = (c->fifo_out + 1) % ITC_CELL_DEPTH;
        c->tag.FIFOPtr--;
    }

    if (c->tag.FIFOPtr == 0) {
        c->tag.E = 1;
    }

    return ret;
}

static uint64_t view_ef_sync_read(ITCStorageCell *c)
{
    return view_ef_common_read(c, true);
}

static uint64_t view_ef_try_read(ITCStorageCell *c)
{
    return view_ef_common_read(c, false);
}

static inline void view_ef_common_write(ITCStorageCell *c, uint64_t val,
                                        bool blocking)
{
    if (!c->tag.FIFO) {
        return;
    }

    c->tag.E = 0;

    if (blocking && c->tag.F) {
        block_thread_and_exit(c);
    }

    if (c->blocked_threads) {
        wake_blocked_threads(c);
    }

    if (c->tag.FIFOPtr < ITC_CELL_DEPTH) {
        int idx = (c->fifo_out + c->tag.FIFOPtr) % ITC_CELL_DEPTH;
        c->data[idx] = val;
        c->tag.FIFOPtr++;
    }

    if (c->tag.FIFOPtr == ITC_CELL_DEPTH) {
        c->tag.F = 1;
    }
}

static void view_ef_sync_write(ITCStorageCell *c, uint64_t val)
{
    view_ef_common_write(c, val, true);
}

static void view_ef_try_write(ITCStorageCell *c, uint64_t val)
{
    view_ef_common_write(c, val, false);
}

/* ITC P/V View */

static uint64_t view_pv_common_read(ITCStorageCell *c, bool blocking)
{
    uint64_t ret = c->data[0];

    if (c->tag.FIFO) {
        return 0;
    }

    if (c->data[0] > 0) {
        c->data[0]--;
    } else if (blocking) {
        block_thread_and_exit(c);
    }

    return ret;
}

static uint64_t view_pv_sync_read(ITCStorageCell *c)
{
    return view_pv_common_read(c, true);
}

static uint64_t view_pv_try_read(ITCStorageCell *c)
{
    return view_pv_common_read(c, false);
}

static inline void view_pv_common_write(ITCStorageCell *c)
{
    if (c->tag.FIFO) {
        return;
    }

    if (c->data[0] < ITC_CELL_PV_MAX_VAL) {
        c->data[0]++;
    }

    if (c->blocked_threads) {
        wake_blocked_threads(c);
    }
}

static void view_pv_sync_write(ITCStorageCell *c)
{
    view_pv_common_write(c);
}

static void view_pv_try_write(ITCStorageCell *c)
{
    view_pv_common_write(c);
}

static uint64_t itc_storage_read(void *opaque, hwaddr addr, unsigned size)
{
    MIPSITUState *s = (MIPSITUState *)opaque;
    ITCStorageCell *cell = get_cell(s, addr);
    ITCView view = get_itc_view(addr);
    uint64_t ret = -1;

    switch (view) {
    case ITCVIEW_BYPASS:
        ret = view_bypass_read(cell);
        break;
    case ITCVIEW_CONTROL:
        ret = view_control_read(cell);
        break;
    case ITCVIEW_EF_SYNC:
        ret = view_ef_sync_read(cell);
        break;
    case ITCVIEW_EF_TRY:
        ret = view_ef_try_read(cell);
        break;
    case ITCVIEW_PV_SYNC:
        ret = view_pv_sync_read(cell);
        break;
    case ITCVIEW_PV_TRY:
        ret = view_pv_try_read(cell);
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "itc_storage_read: Bad ITC View %d\n", (int)view);
        break;
    }

    return ret;
}

static void itc_storage_write(void *opaque, hwaddr addr, uint64_t data,
                              unsigned size)
{
    MIPSITUState *s = (MIPSITUState *)opaque;
    ITCStorageCell *cell = get_cell(s, addr);
    ITCView view = get_itc_view(addr);

    switch (view) {
    case ITCVIEW_BYPASS:
        view_bypass_write(cell, data);
        break;
    case ITCVIEW_CONTROL:
        view_control_write(cell, data);
        break;
    case ITCVIEW_EF_SYNC:
        view_ef_sync_write(cell, data);
        break;
    case ITCVIEW_EF_TRY:
        view_ef_try_write(cell, data);
        break;
    case ITCVIEW_PV_SYNC:
        view_pv_sync_write(cell);
        break;
    case ITCVIEW_PV_TRY:
        view_pv_try_write(cell);
        break;
    default:
        qemu_log_mask(LOG_GUEST_ERROR,
                      "itc_storage_write: Bad ITC View %d\n", (int)view);
        break;
    }

}

static const MemoryRegionOps itc_storage_ops = {
    .read = itc_storage_read,
    .write = itc_storage_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void itc_reset_cells(MIPSITUState *s)
{
    int i;

    memset(s->cell, 0, get_num_cells(s) * sizeof(s->cell[0]));

    for (i = 0; i < s->num_fifo; i++) {
        s->cell[i].tag.E = 1;
        s->cell[i].tag.FIFO = 1;
        s->cell[i].tag.FIFODepth = ITC_CELL_DEPTH_SHIFT;
    }
}

static void mips_itu_init(Object *obj)
{
    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);
    MIPSITUState *s = MIPS_ITU(obj);

    memory_region_init_io(&s->storage_io, OBJECT(s), &itc_storage_ops, s,
                          "mips-itc-storage", ITC_STORAGE_ADDRSPACE_SZ);
    sysbus_init_mmio(sbd, &s->storage_io);

    memory_region_init_io(&s->tag_io, OBJECT(s), &itc_tag_ops, s,
                          "mips-itc-tag", ITC_TAG_ADDRSPACE_SZ);
}

static void mips_itu_realize(DeviceState *dev, Error **errp)
{
    MIPSITUState *s = MIPS_ITU(dev);

    if (s->num_fifo > ITC_FIFO_NUM_MAX) {
        error_setg(errp, "Exceed maximum number of FIFO cells: %d",
                   s->num_fifo);
        return;
    }
    if (s->num_semaphores > ITC_SEMAPH_NUM_MAX) {
        error_setg(errp, "Exceed maximum number of Semaphore cells: %d",
                   s->num_semaphores);
        return;
    }

    s->cell = g_new(ITCStorageCell, get_num_cells(s));
}

static void mips_itu_reset(DeviceState *dev)
{
    MIPSITUState *s = MIPS_ITU(dev);

    s->ITCAddressMap[0] = 0;
    s->ITCAddressMap[1] =
        ((ITC_STORAGE_ADDRSPACE_SZ - 1) & ITC_AM1_ADDR_MASK_MASK) |
        (get_num_cells(s) << ITC_AM1_NUMENTRIES_OFS);
    itc_reconfigure(s);

    itc_reset_cells(s);
}

static Property mips_itu_properties[] = {
    DEFINE_PROP_INT32("num-fifo", MIPSITUState, num_fifo,
                      ITC_FIFO_NUM_MAX),
    DEFINE_PROP_INT32("num-semaphores", MIPSITUState, num_semaphores,
                      ITC_SEMAPH_NUM_MAX),
    DEFINE_PROP_END_OF_LIST(),
};

static void mips_itu_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->props = mips_itu_properties;
    dc->realize = mips_itu_realize;
    dc->reset = mips_itu_reset;
}

static const TypeInfo mips_itu_info = {
    .name          = TYPE_MIPS_ITU,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(MIPSITUState),
    .instance_init = mips_itu_init,
    .class_init    = mips_itu_class_init,
};

static void mips_itu_register_types(void)
{
    type_register_static(&mips_itu_info);
}

type_init(mips_itu_register_types)
