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

#include "hw/ipack.h"
#include "hw/pci/pci.h"
#include "qemu/bitops.h"
#include <stdio.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)

typedef struct {
    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;
} TPCI200State;

#define TYPE_TPCI200 "tpci200"

#define TPCI200(obj) \
    OBJECT_CHECK(TPCI200State, (obj), TYPE_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) {
            qemu_set_irq(dev->dev.irq[0], !dev->int_set);
            qemu_set_irq(dev->dev.irq[0],  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) {
            qemu_irq_raise(dev->dev.irq[0]);
            dev->int_set = 1;
        } else if (!level_status && dev->int_set) {
            qemu_irq_lower(dev->dev.irq[0]);
            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 int tpci200_initfn(PCIDevice *pci_dev)
{
    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, &tpci200_cfg_ops,
                          s, "tpci200_mmio", 128);
    memory_region_init_io(&s->io,   &tpci200_cfg_ops,
                          s, "tpci200_io",   128);
    memory_region_init_io(&s->las0, &tpci200_las0_ops,
                          s, "tpci200_las0", 256);
    memory_region_init_io(&s->las1, &tpci200_las1_ops,
                          s, "tpci200_las1", 1024);
    memory_region_init_io(&s->las2, &tpci200_las2_ops,
                          s, "tpci200_las2", 1024*1024*32);
    memory_region_init_io(&s->las3, &tpci200_las3_ops,
                          s, "tpci200_las3", 1024*1024*16);
    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_new_inplace(&s->bus, DEVICE(&s->dev), NULL,
                          N_MODULES, tpci200_set_irq);

    return 0;
}

static void tpci200_exitfn(PCIDevice *pci_dev)
{
    TPCI200State *s = TPCI200(pci_dev);

    memory_region_destroy(&s->mmio);
    memory_region_destroy(&s->io);
    memory_region_destroy(&s->las0);
    memory_region_destroy(&s->las1);
    memory_region_destroy(&s->las2);
    memory_region_destroy(&s->las3);
}

static const VMStateDescription vmstate_tpci200 = {
    .name = "tpci200",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 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->init = tpci200_initfn;
    k->exit = tpci200_exitfn;
    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;
    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,
};

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

type_init(tpci200_register_types)
