/*
 * QEMU TEWS TPCI200 IndustryPack carrier emulation
 *
 * Copyright (C) 2012 Igalia, S.L.
 * Author: Alberto Garcia <berto@igalia.com>
 *
 * This code is licensed under the GNU GPL v2 or (at your option) any
 * later version.
 */

#include "qemu/osdep.h"
#include "qemu/units.h"
#include "hw/ipack/ipack.h"
#include "hw/irq.h"
#include "hw/pci/pci.h"
#include "migration/vmstate.h"
#include "qemu/bitops.h"
#include "qemu/module.h"
#include "qom/object.h"

/* #define DEBUG_TPCI */

#ifdef DEBUG_TPCI
#define DPRINTF(fmt, ...) \
    do { fprintf(stderr, "TPCI200: " fmt, ## __VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...) do { } while (0)
#endif

#define N_MODULES 4

#define IP_ID_SPACE  2
#define IP_INT_SPACE 3
#define IP_IO_SPACE_ADDR_MASK  0x7F
#define IP_ID_SPACE_ADDR_MASK  0x3F
#define IP_INT_SPACE_ADDR_MASK 0x3F

#define STATUS_INT(IP, INTNO) BIT((IP) * 2 + (INTNO))
#define STATUS_TIME(IP)       BIT((IP) + 12)
#define STATUS_ERR_ANY        0xF00

#define CTRL_CLKRATE          BIT(0)
#define CTRL_RECOVER          BIT(1)
#define CTRL_TIME_INT         BIT(2)
#define CTRL_ERR_INT          BIT(3)
#define CTRL_INT_EDGE(INTNO)  BIT(4 + (INTNO))
#define CTRL_INT(INTNO)       BIT(6 + (INTNO))

#define REG_REV_ID    0x00
#define REG_IP_A_CTRL 0x02
#define REG_IP_B_CTRL 0x04
#define REG_IP_C_CTRL 0x06
#define REG_IP_D_CTRL 0x08
#define REG_RESET     0x0A
#define REG_STATUS    0x0C
#define IP_N_FROM_REG(REG) ((REG) / 2 - 1)

struct TPCI200State {
    PCIDevice dev;
    IPackBus bus;
    MemoryRegion mmio;
    MemoryRegion io;
    MemoryRegion las0;
    MemoryRegion las1;
    MemoryRegion las2;
    MemoryRegion las3;
    bool big_endian[3];
    uint8_t ctrl[N_MODULES];
    uint16_t status;
    uint8_t int_set;
};

#define TYPE_TPCI200 "tpci200"

OBJECT_DECLARE_SIMPLE_TYPE(TPCI200State, TPCI200)

static const uint8_t local_config_regs[] = {
    0x00, 0xFF, 0xFF, 0x0F, 0x00, 0xFC, 0xFF, 0x0F, 0x00, 0x00, 0x00,
    0x0E, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
    0x00, 0x08, 0x01, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x01,
    0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x60, 0x41, 0xD4,
    0xA2, 0x20, 0x41, 0x14, 0xA2, 0x20, 0x41, 0x14, 0xA2, 0x20, 0x01,
    0x14, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x08, 0x01, 0x02,
    0x00, 0x04, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x80, 0x02, 0x41,
    0x00, 0x00, 0x00, 0x00, 0x40, 0x7A, 0x00, 0x52, 0x92, 0x24, 0x02
};

static void adjust_addr(bool big_endian, hwaddr *addr, unsigned size)
{
    /* During 8 bit access in big endian mode,
       odd and even addresses are swapped */
    if (big_endian && size == 1) {
        *addr ^= 1;
    }
}

static uint64_t adjust_value(bool big_endian, uint64_t *val, unsigned size)
{
    /* Local spaces only support 8/16 bit access,
     * so there's no need to care for sizes > 2 */
    if (big_endian && size == 2) {
        *val = bswap16(*val);
    }
    return *val;
}

static void tpci200_set_irq(void *opaque, int intno, int level)
{
    IPackDevice *ip = opaque;
    IPackBus *bus = IPACK_BUS(qdev_get_parent_bus(DEVICE(ip)));
    PCIDevice *pcidev = PCI_DEVICE(BUS(bus)->parent);
    TPCI200State *dev = TPCI200(pcidev);
    unsigned ip_n = ip->slot;
    uint16_t prev_status = dev->status;

    assert(ip->slot >= 0 && ip->slot < N_MODULES);

    /* The requested interrupt must be enabled in the IP CONTROL
     * register */
    if (!(dev->ctrl[ip_n] & CTRL_INT(intno))) {
        return;
    }

    /* Update the interrupt status in the IP STATUS register */
    if (level) {
        dev->status |=  STATUS_INT(ip_n, intno);
    } else {
        dev->status &= ~STATUS_INT(ip_n, intno);
    }

    /* Return if there are no changes */
    if (dev->status == prev_status) {
        return;
    }

    DPRINTF("IP %u INT%u#: %u\n", ip_n, intno, level);

    /* Check if the interrupt is edge sensitive */
    if (dev->ctrl[ip_n] & CTRL_INT_EDGE(intno)) {
        if (level) {
            pci_set_irq(&dev->dev, !dev->int_set);
            pci_set_irq(&dev->dev,  dev->int_set);
        }
    } else {
        unsigned i, j;
        uint16_t level_status = dev->status;

        /* Check if there are any level sensitive interrupts set by
           removing the ones that are edge sensitive from the status
           register */
        for (i = 0; i < N_MODULES; i++) {
            for (j = 0; j < 2; j++) {
                if (dev->ctrl[i] & CTRL_INT_EDGE(j)) {
                    level_status &= ~STATUS_INT(i, j);
                }
            }
        }

        if (level_status && !dev->int_set) {
            pci_irq_assert(&dev->dev);
            dev->int_set = 1;
        } else if (!level_status && dev->int_set) {
            pci_irq_deassert(&dev->dev);
            dev->int_set = 0;
        }
    }
}

static uint64_t tpci200_read_cfg(void *opaque, hwaddr addr, unsigned size)
{
    TPCI200State *s = opaque;
    uint8_t ret = 0;
    if (addr < ARRAY_SIZE(local_config_regs)) {
        ret = local_config_regs[addr];
    }
    /* Endianness is stored in the first bit of these registers */
    if ((addr == 0x2b && s->big_endian[0]) ||
        (addr == 0x2f && s->big_endian[1]) ||
        (addr == 0x33 && s->big_endian[2])) {
        ret |= 1;
    }
    DPRINTF("Read from LCR 0x%x: 0x%x\n", (unsigned) addr, (unsigned) ret);
    return ret;
}

static void tpci200_write_cfg(void *opaque, hwaddr addr, uint64_t val,
                              unsigned size)
{
    TPCI200State *s = opaque;
    /* Endianness is stored in the first bit of these registers */
    if (addr == 0x2b || addr == 0x2f || addr == 0x33) {
        unsigned las = (addr - 0x2b) / 4;
        s->big_endian[las] = val & 1;
        DPRINTF("LAS%u big endian mode: %u\n", las, (unsigned) val & 1);
    } else {
        DPRINTF("Write to LCR 0x%x: 0x%x\n", (unsigned) addr, (unsigned) val);
    }
}

static uint64_t tpci200_read_las0(void *opaque, hwaddr addr, unsigned size)
{
    TPCI200State *s = opaque;
    uint64_t ret = 0;

    switch (addr) {

    case REG_REV_ID:
        DPRINTF("Read REVISION ID\n"); /* Current value is 0x00 */
        break;

    case REG_IP_A_CTRL:
    case REG_IP_B_CTRL:
    case REG_IP_C_CTRL:
    case REG_IP_D_CTRL:
        {
            unsigned ip_n = IP_N_FROM_REG(addr);
            ret = s->ctrl[ip_n];
            DPRINTF("Read IP %c CONTROL: 0x%x\n", 'A' + ip_n, (unsigned) ret);
        }
        break;

    case REG_RESET:
        DPRINTF("Read RESET\n"); /* Not implemented */
        break;

    case REG_STATUS:
        ret = s->status;
        DPRINTF("Read STATUS: 0x%x\n", (unsigned) ret);
        break;

    /* Reserved */
    default:
        DPRINTF("Unsupported read from LAS0 0x%x\n", (unsigned) addr);
        break;
    }

    return adjust_value(s->big_endian[0], &ret, size);
}

static void tpci200_write_las0(void *opaque, hwaddr addr, uint64_t val,
                               unsigned size)
{
    TPCI200State *s = opaque;

    adjust_value(s->big_endian[0], &val, size);

    switch (addr) {

    case REG_REV_ID:
        DPRINTF("Write Revision ID: 0x%x\n", (unsigned) val); /* No effect */
        break;

    case REG_IP_A_CTRL:
    case REG_IP_B_CTRL:
    case REG_IP_C_CTRL:
    case REG_IP_D_CTRL:
        {
            unsigned ip_n = IP_N_FROM_REG(addr);
            s->ctrl[ip_n] = val;
            DPRINTF("Write IP %c CONTROL: 0x%x\n", 'A' + ip_n, (unsigned) val);
        }
        break;

    case REG_RESET:
        DPRINTF("Write RESET: 0x%x\n", (unsigned) val); /* Not implemented */
        break;

    case REG_STATUS:
        {
            unsigned i;

            for (i = 0; i < N_MODULES; i++) {
                IPackDevice *ip = ipack_device_find(&s->bus, i);

                if (ip != NULL) {
                    if (val & STATUS_INT(i, 0)) {
                        DPRINTF("Clear IP %c INT0# status\n", 'A' + i);
                        qemu_irq_lower(ip->irq[0]);
                    }
                    if (val & STATUS_INT(i, 1)) {
                        DPRINTF("Clear IP %c INT1# status\n", 'A' + i);
                        qemu_irq_lower(ip->irq[1]);
                    }
                }

                if (val & STATUS_TIME(i)) {
                    DPRINTF("Clear IP %c timeout\n", 'A' + i);
                    s->status &= ~STATUS_TIME(i);
                }
            }

            if (val & STATUS_ERR_ANY) {
                DPRINTF("Unexpected write to STATUS register: 0x%x\n",
                        (unsigned) val);
            }
        }
        break;

    /* Reserved */
    default:
        DPRINTF("Unsupported write to LAS0 0x%x: 0x%x\n",
                (unsigned) addr, (unsigned) val);
        break;
    }
}

static uint64_t tpci200_read_las1(void *opaque, hwaddr addr, unsigned size)
{
    TPCI200State *s = opaque;
    IPackDevice *ip;
    uint64_t ret = 0;
    unsigned ip_n, space;
    uint8_t offset;

    adjust_addr(s->big_endian[1], &addr, size);

    /*
     * The address is divided into the IP module number (0-4), the IP
     * address space (I/O, ID, INT) and the offset within that space.
     */
    ip_n = addr >> 8;
    space = (addr >> 6) & 3;
    ip = ipack_device_find(&s->bus, ip_n);

    if (ip == NULL) {
        DPRINTF("Read LAS1: IP module %u not installed\n", ip_n);
    } else {
        IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip);
        switch (space) {

        case IP_ID_SPACE:
            offset = addr & IP_ID_SPACE_ADDR_MASK;
            if (k->id_read) {
                ret = k->id_read(ip, offset);
            }
            break;

        case IP_INT_SPACE:
            offset = addr & IP_INT_SPACE_ADDR_MASK;

            /* Read address 0 to ACK IP INT0# and address 2 to ACK IP INT1# */
            if (offset == 0 || offset == 2) {
                unsigned intno = offset / 2;
                bool int_set = s->status & STATUS_INT(ip_n, intno);
                bool int_edge_sensitive = s->ctrl[ip_n] & CTRL_INT_EDGE(intno);
                if (int_set && !int_edge_sensitive) {
                    qemu_irq_lower(ip->irq[intno]);
                }
            }

            if (k->int_read) {
                ret = k->int_read(ip, offset);
            }
            break;

        default:
            offset = addr & IP_IO_SPACE_ADDR_MASK;
            if (k->io_read) {
                ret = k->io_read(ip, offset);
            }
            break;
        }
    }

    return adjust_value(s->big_endian[1], &ret, size);
}

static void tpci200_write_las1(void *opaque, hwaddr addr, uint64_t val,
                               unsigned size)
{
    TPCI200State *s = opaque;
    IPackDevice *ip;
    unsigned ip_n, space;
    uint8_t offset;

    adjust_addr(s->big_endian[1], &addr, size);
    adjust_value(s->big_endian[1], &val, size);

    /*
     * The address is divided into the IP module number, the IP
     * address space (I/O, ID, INT) and the offset within that space.
     */
    ip_n = addr >> 8;
    space = (addr >> 6) & 3;
    ip = ipack_device_find(&s->bus, ip_n);

    if (ip == NULL) {
        DPRINTF("Write LAS1: IP module %u not installed\n", ip_n);
    } else {
        IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip);
        switch (space) {

        case IP_ID_SPACE:
            offset = addr & IP_ID_SPACE_ADDR_MASK;
            if (k->id_write) {
                k->id_write(ip, offset, val);
            }
            break;

        case IP_INT_SPACE:
            offset = addr & IP_INT_SPACE_ADDR_MASK;
            if (k->int_write) {
                k->int_write(ip, offset, val);
            }
            break;

        default:
            offset = addr & IP_IO_SPACE_ADDR_MASK;
            if (k->io_write) {
                k->io_write(ip, offset, val);
            }
            break;
        }
    }
}

static uint64_t tpci200_read_las2(void *opaque, hwaddr addr, unsigned size)
{
    TPCI200State *s = opaque;
    IPackDevice *ip;
    uint64_t ret = 0;
    unsigned ip_n;
    uint32_t offset;

    adjust_addr(s->big_endian[2], &addr, size);

    /*
     * The address is divided into the IP module number and the offset
     * within the IP module MEM space.
     */
    ip_n = addr >> 23;
    offset = addr & 0x7fffff;
    ip = ipack_device_find(&s->bus, ip_n);

    if (ip == NULL) {
        DPRINTF("Read LAS2: IP module %u not installed\n", ip_n);
    } else {
        IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip);
        if (k->mem_read16) {
            ret = k->mem_read16(ip, offset);
        }
    }

    return adjust_value(s->big_endian[2], &ret, size);
}

static void tpci200_write_las2(void *opaque, hwaddr addr, uint64_t val,
                               unsigned size)
{
    TPCI200State *s = opaque;
    IPackDevice *ip;
    unsigned ip_n;
    uint32_t offset;

    adjust_addr(s->big_endian[2], &addr, size);
    adjust_value(s->big_endian[2], &val, size);

    /*
     * The address is divided into the IP module number and the offset
     * within the IP module MEM space.
     */
    ip_n = addr >> 23;
    offset = addr & 0x7fffff;
    ip = ipack_device_find(&s->bus, ip_n);

    if (ip == NULL) {
        DPRINTF("Write LAS2: IP module %u not installed\n", ip_n);
    } else {
        IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip);
        if (k->mem_write16) {
            k->mem_write16(ip, offset, val);
        }
    }
}

static uint64_t tpci200_read_las3(void *opaque, hwaddr addr, unsigned size)
{
    TPCI200State *s = opaque;
    IPackDevice *ip;
    uint64_t ret = 0;
    /*
     * The address is divided into the IP module number and the offset
     * within the IP module MEM space.
     */
    unsigned ip_n = addr >> 22;
    uint32_t offset = addr & 0x3fffff;

    ip = ipack_device_find(&s->bus, ip_n);

    if (ip == NULL) {
        DPRINTF("Read LAS3: IP module %u not installed\n", ip_n);
    } else {
        IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip);
        if (k->mem_read8) {
            ret = k->mem_read8(ip, offset);
        }
    }

    return ret;
}

static void tpci200_write_las3(void *opaque, hwaddr addr, uint64_t val,
                               unsigned size)
{
    TPCI200State *s = opaque;
    IPackDevice *ip;
    /*
     * The address is divided into the IP module number and the offset
     * within the IP module MEM space.
     */
    unsigned ip_n = addr >> 22;
    uint32_t offset = addr & 0x3fffff;

    ip = ipack_device_find(&s->bus, ip_n);

    if (ip == NULL) {
        DPRINTF("Write LAS3: IP module %u not installed\n", ip_n);
    } else {
        IPackDeviceClass *k = IPACK_DEVICE_GET_CLASS(ip);
        if (k->mem_write8) {
            k->mem_write8(ip, offset, val);
        }
    }
}

static const MemoryRegionOps tpci200_cfg_ops = {
    .read = tpci200_read_cfg,
    .write = tpci200_write_cfg,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid =  {
        .min_access_size = 1,
        .max_access_size = 4
    },
    .impl = {
        .min_access_size = 1,
        .max_access_size = 1
    }
};

static const MemoryRegionOps tpci200_las0_ops = {
    .read = tpci200_read_las0,
    .write = tpci200_write_las0,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid =  {
        .min_access_size = 2,
        .max_access_size = 2
    }
};

static const MemoryRegionOps tpci200_las1_ops = {
    .read = tpci200_read_las1,
    .write = tpci200_write_las1,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid =  {
        .min_access_size = 1,
        .max_access_size = 2
    }
};

static const MemoryRegionOps tpci200_las2_ops = {
    .read = tpci200_read_las2,
    .write = tpci200_write_las2,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid =  {
        .min_access_size = 1,
        .max_access_size = 2
    }
};

static const MemoryRegionOps tpci200_las3_ops = {
    .read = tpci200_read_las3,
    .write = tpci200_write_las3,
    .endianness = DEVICE_NATIVE_ENDIAN,
    .valid =  {
        .min_access_size = 1,
        .max_access_size = 1
    }
};

static void tpci200_realize(PCIDevice *pci_dev, Error **errp)
{
    TPCI200State *s = TPCI200(pci_dev);
    uint8_t *c = s->dev.config;

    pci_set_word(c + PCI_COMMAND, 0x0003);
    pci_set_word(c + PCI_STATUS,  0x0280);

    pci_set_byte(c + PCI_INTERRUPT_PIN, 0x01); /* Interrupt pin A */

    pci_set_byte(c + PCI_CAPABILITY_LIST, 0x40);
    pci_set_long(c + 0x40, 0x48014801);
    pci_set_long(c + 0x48, 0x00024C06);
    pci_set_long(c + 0x4C, 0x00000003);

    memory_region_init_io(&s->mmio, OBJECT(s), &tpci200_cfg_ops,
                          s, "tpci200_mmio", 128);
    memory_region_init_io(&s->io, OBJECT(s),   &tpci200_cfg_ops,
                          s, "tpci200_io",   128);
    memory_region_init_io(&s->las0, OBJECT(s), &tpci200_las0_ops,
                          s, "tpci200_las0", 256);
    memory_region_init_io(&s->las1, OBJECT(s), &tpci200_las1_ops,
                          s, "tpci200_las1", 1024);
    memory_region_init_io(&s->las2, OBJECT(s), &tpci200_las2_ops,
                          s, "tpci200_las2", 32 * MiB);
    memory_region_init_io(&s->las3, OBJECT(s), &tpci200_las3_ops,
                          s, "tpci200_las3", 16 * MiB);
    pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
    pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO,     &s->io);
    pci_register_bar(&s->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las0);
    pci_register_bar(&s->dev, 3, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las1);
    pci_register_bar(&s->dev, 4, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las2);
    pci_register_bar(&s->dev, 5, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->las3);

    ipack_bus_init(&s->bus, sizeof(s->bus), DEVICE(pci_dev),
                   N_MODULES, tpci200_set_irq);
}

static const VMStateDescription vmstate_tpci200 = {
    .name = "tpci200",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_PCI_DEVICE(dev, TPCI200State),
        VMSTATE_BOOL_ARRAY(big_endian, TPCI200State, 3),
        VMSTATE_UINT8_ARRAY(ctrl, TPCI200State, N_MODULES),
        VMSTATE_UINT16(status, TPCI200State),
        VMSTATE_UINT8(int_set, TPCI200State),
        VMSTATE_END_OF_LIST()
    }
};

static void tpci200_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);

    k->realize = tpci200_realize;
    k->vendor_id = PCI_VENDOR_ID_TEWS;
    k->device_id = PCI_DEVICE_ID_TEWS_TPCI200;
    k->class_id = PCI_CLASS_BRIDGE_OTHER;
    k->subsystem_vendor_id = PCI_VENDOR_ID_TEWS;
    k->subsystem_id = 0x300A;
    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
    dc->desc = "TEWS TPCI200 IndustryPack carrier";
    dc->vmsd = &vmstate_tpci200;
}

static const TypeInfo tpci200_info = {
    .name          = TYPE_TPCI200,
    .parent        = TYPE_PCI_DEVICE,
    .instance_size = sizeof(TPCI200State),
    .class_init    = tpci200_class_init,
    .interfaces = (InterfaceInfo[]) {
        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
        { },
    },
};

static void tpci200_register_types(void)
{
    type_register_static(&tpci200_info);
}

type_init(tpci200_register_types)
