/*
 * QEMU GE IP-Octal 232 IndustryPack 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 "ipack.h"
#include "qemu/bitops.h"
#include "char/char.h"

/* #define DEBUG_IPOCTAL */

#ifdef DEBUG_IPOCTAL
#define DPRINTF2(fmt, ...) \
    do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
#else
#define DPRINTF2(fmt, ...) do { } while (0)
#endif

#define DPRINTF(fmt, ...) DPRINTF2("IP-Octal: " fmt, ## __VA_ARGS__)

#define RX_FIFO_SIZE 3

/* The IP-Octal has 8 channels (a-h)
   divided into 4 blocks (A-D) */
#define N_CHANNELS 8
#define N_BLOCKS   4

#define REG_MRa  0x01
#define REG_MRb  0x11
#define REG_SRa  0x03
#define REG_SRb  0x13
#define REG_CSRa 0x03
#define REG_CSRb 0x13
#define REG_CRa  0x05
#define REG_CRb  0x15
#define REG_RHRa 0x07
#define REG_RHRb 0x17
#define REG_THRa 0x07
#define REG_THRb 0x17
#define REG_ACR  0x09
#define REG_ISR  0x0B
#define REG_IMR  0x0B
#define REG_OPCR 0x1B

#define CR_ENABLE_RX    BIT(0)
#define CR_DISABLE_RX   BIT(1)
#define CR_ENABLE_TX    BIT(2)
#define CR_DISABLE_TX   BIT(3)
#define CR_CMD(cr)      ((cr) >> 4)
#define CR_NO_OP        0
#define CR_RESET_MR     1
#define CR_RESET_RX     2
#define CR_RESET_TX     3
#define CR_RESET_ERR    4
#define CR_RESET_BRKINT 5
#define CR_START_BRK    6
#define CR_STOP_BRK     7
#define CR_ASSERT_RTSN  8
#define CR_NEGATE_RTSN  9
#define CR_TIMEOUT_ON   10
#define CR_TIMEOUT_OFF  12

#define SR_RXRDY   BIT(0)
#define SR_FFULL   BIT(1)
#define SR_TXRDY   BIT(2)
#define SR_TXEMT   BIT(3)
#define SR_OVERRUN BIT(4)
#define SR_PARITY  BIT(5)
#define SR_FRAMING BIT(6)
#define SR_BREAK   BIT(7)

#define ISR_TXRDYA BIT(0)
#define ISR_RXRDYA BIT(1)
#define ISR_BREAKA BIT(2)
#define ISR_CNTRDY BIT(3)
#define ISR_TXRDYB BIT(4)
#define ISR_RXRDYB BIT(5)
#define ISR_BREAKB BIT(6)
#define ISR_MPICHG BIT(7)
#define ISR_TXRDY(CH) (((CH) & 1) ? BIT(4) : BIT(0))
#define ISR_RXRDY(CH) (((CH) & 1) ? BIT(5) : BIT(1))
#define ISR_BREAK(CH) (((CH) & 1) ? BIT(6) : BIT(2))

typedef struct IPOctalState IPOctalState;
typedef struct SCC2698Channel SCC2698Channel;
typedef struct SCC2698Block SCC2698Block;

struct SCC2698Channel {
    IPOctalState *ipoctal;
    CharDriverState *dev;
    bool rx_enabled;
    uint8_t mr[2];
    uint8_t mr_idx;
    uint8_t sr;
    uint8_t rhr[RX_FIFO_SIZE];
    uint8_t rhr_idx;
    uint8_t rx_pending;
};

struct SCC2698Block {
    uint8_t imr;
    uint8_t isr;
};

struct IPOctalState {
    IPackDevice dev;
    SCC2698Channel ch[N_CHANNELS];
    SCC2698Block blk[N_BLOCKS];
    uint8_t irq_vector;
};

#define TYPE_IPOCTAL "ipoctal232"

#define IPOCTAL(obj) \
    OBJECT_CHECK(IPOctalState, (obj), TYPE_IPOCTAL)

static const VMStateDescription vmstate_scc2698_channel = {
    .name = "scc2698_channel",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields      = (VMStateField[]) {
        VMSTATE_BOOL(rx_enabled, SCC2698Channel),
        VMSTATE_UINT8_ARRAY(mr, SCC2698Channel, 2),
        VMSTATE_UINT8(mr_idx, SCC2698Channel),
        VMSTATE_UINT8(sr, SCC2698Channel),
        VMSTATE_UINT8_ARRAY(rhr, SCC2698Channel, RX_FIFO_SIZE),
        VMSTATE_UINT8(rhr_idx, SCC2698Channel),
        VMSTATE_UINT8(rx_pending, SCC2698Channel),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_scc2698_block = {
    .name = "scc2698_block",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields      = (VMStateField[]) {
        VMSTATE_UINT8(imr, SCC2698Block),
        VMSTATE_UINT8(isr, SCC2698Block),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_ipoctal = {
    .name = "ipoctal232",
    .version_id = 1,
    .minimum_version_id = 1,
    .minimum_version_id_old = 1,
    .fields      = (VMStateField[]) {
        VMSTATE_IPACK_DEVICE(dev, IPOctalState),
        VMSTATE_STRUCT_ARRAY(ch, IPOctalState, N_CHANNELS, 1,
                             vmstate_scc2698_channel, SCC2698Channel),
        VMSTATE_STRUCT_ARRAY(blk, IPOctalState, N_BLOCKS, 1,
                             vmstate_scc2698_block, SCC2698Block),
        VMSTATE_UINT8(irq_vector, IPOctalState),
        VMSTATE_END_OF_LIST()
    }
};

/* data[10] is 0x0C, not 0x0B as the doc says */
static const uint8_t id_prom_data[] = {
    0x49, 0x50, 0x41, 0x43, 0xF0, 0x22,
    0xA1, 0x00, 0x00, 0x00, 0x0C, 0xCC
};

static void update_irq(IPOctalState *dev, unsigned block)
{
    /* Blocks A and B interrupt on INT0#, C and D on INT1#.
       Thus, to get the status we have to check two blocks. */
    SCC2698Block *blk0 = &dev->blk[block];
    SCC2698Block *blk1 = &dev->blk[block^1];
    unsigned intno = block / 2;

    if ((blk0->isr & blk0->imr) || (blk1->isr & blk1->imr)) {
        qemu_irq_raise(dev->dev.irq[intno]);
    } else {
        qemu_irq_lower(dev->dev.irq[intno]);
    }
}

static void write_cr(IPOctalState *dev, unsigned channel, uint8_t val)
{
    SCC2698Channel *ch = &dev->ch[channel];
    SCC2698Block *blk = &dev->blk[channel / 2];

    DPRINTF("Write CR%c %u: ", channel + 'a', val);

    /* The lower 4 bits are used to enable and disable Tx and Rx */
    if (val & CR_ENABLE_RX) {
        DPRINTF2("Rx on, ");
        ch->rx_enabled = true;
    }
    if (val & CR_DISABLE_RX) {
        DPRINTF2("Rx off, ");
        ch->rx_enabled = false;
    }
    if (val & CR_ENABLE_TX) {
        DPRINTF2("Tx on, ");
        ch->sr |= SR_TXRDY | SR_TXEMT;
        blk->isr |= ISR_TXRDY(channel);
    }
    if (val & CR_DISABLE_TX) {
        DPRINTF2("Tx off, ");
        ch->sr &= ~(SR_TXRDY | SR_TXEMT);
        blk->isr &= ~ISR_TXRDY(channel);
    }

    DPRINTF2("cmd: ");

    /* The rest of the bits implement different commands */
    switch (CR_CMD(val)) {
    case CR_NO_OP:
        DPRINTF2("none");
        break;
    case CR_RESET_MR:
        DPRINTF2("reset MR");
        ch->mr_idx = 0;
        break;
    case CR_RESET_RX:
        DPRINTF2("reset Rx");
        ch->rx_enabled = false;
        ch->rx_pending = 0;
        ch->sr &= ~SR_RXRDY;
        blk->isr &= ~ISR_RXRDY(channel);
        break;
    case CR_RESET_TX:
        DPRINTF2("reset Tx");
        ch->sr &= ~(SR_TXRDY | SR_TXEMT);
        blk->isr &= ~ISR_TXRDY(channel);
        break;
    case CR_RESET_ERR:
        DPRINTF2("reset err");
        ch->sr &= ~(SR_OVERRUN | SR_PARITY | SR_FRAMING | SR_BREAK);
        break;
    case CR_RESET_BRKINT:
        DPRINTF2("reset brk ch int");
        blk->isr &= ~(ISR_BREAKA | ISR_BREAKB);
        break;
    default:
        DPRINTF2("unsupported 0x%x", CR_CMD(val));
    }

    DPRINTF2("\n");
}

static uint16_t io_read(IPackDevice *ip, uint8_t addr)
{
    IPOctalState *dev = IPOCTAL(ip);
    uint16_t ret = 0;
    /* addr[7:6]: block   (A-D)
       addr[7:5]: channel (a-h)
       addr[5:0]: register */
    unsigned block = addr >> 5;
    unsigned channel = addr >> 4;
    /* Big endian, accessed using 8-bit bytes at odd locations */
    unsigned offset = (addr & 0x1F) ^ 1;
    SCC2698Channel *ch = &dev->ch[channel];
    SCC2698Block *blk = &dev->blk[block];
    uint8_t old_isr = blk->isr;

    switch (offset) {

    case REG_MRa:
    case REG_MRb:
        ret = ch->mr[ch->mr_idx];
        DPRINTF("Read MR%u%c: 0x%x\n", ch->mr_idx + 1, channel + 'a', ret);
        ch->mr_idx = 1;
        break;

    case REG_SRa:
    case REG_SRb:
        ret = ch->sr;
        DPRINTF("Read SR%c: 0x%x\n", channel + 'a', ret);
        break;

    case REG_RHRa:
    case REG_RHRb:
        ret = ch->rhr[ch->rhr_idx];
        if (ch->rx_pending > 0) {
            ch->rx_pending--;
            if (ch->rx_pending == 0) {
                ch->sr &= ~SR_RXRDY;
                blk->isr &= ~ISR_RXRDY(channel);
                if (ch->dev) {
                    qemu_chr_accept_input(ch->dev);
                }
            } else {
                ch->rhr_idx = (ch->rhr_idx + 1) % RX_FIFO_SIZE;
            }
            if (ch->sr & SR_BREAK) {
                ch->sr &= ~SR_BREAK;
                blk->isr |= ISR_BREAK(channel);
            }
        }
        DPRINTF("Read RHR%c (0x%x)\n", channel + 'a', ret);
        break;

    case REG_ISR:
        ret = blk->isr;
        DPRINTF("Read ISR%c: 0x%x\n", block + 'A', ret);
        break;

    default:
        DPRINTF("Read unknown/unsupported register 0x%02x\n", offset);
    }

    if (old_isr != blk->isr) {
        update_irq(dev, block);
    }

    return ret;
}

static void io_write(IPackDevice *ip, uint8_t addr, uint16_t val)
{
    IPOctalState *dev = IPOCTAL(ip);
    unsigned reg = val & 0xFF;
    /* addr[7:6]: block   (A-D)
       addr[7:5]: channel (a-h)
       addr[5:0]: register */
    unsigned block = addr >> 5;
    unsigned channel = addr >> 4;
    /* Big endian, accessed using 8-bit bytes at odd locations */
    unsigned offset = (addr & 0x1F) ^ 1;
    SCC2698Channel *ch = &dev->ch[channel];
    SCC2698Block *blk = &dev->blk[block];
    uint8_t old_isr = blk->isr;
    uint8_t old_imr = blk->imr;

    switch (offset) {

    case REG_MRa:
    case REG_MRb:
        ch->mr[ch->mr_idx] = reg;
        DPRINTF("Write MR%u%c 0x%x\n", ch->mr_idx + 1, channel + 'a', reg);
        ch->mr_idx = 1;
        break;

    /* Not implemented */
    case REG_CSRa:
    case REG_CSRb:
        DPRINTF("Write CSR%c: 0x%x\n", channel + 'a', reg);
        break;

    case REG_CRa:
    case REG_CRb:
        write_cr(dev, channel, reg);
        break;

    case REG_THRa:
    case REG_THRb:
        if (ch->sr & SR_TXRDY) {
            DPRINTF("Write THR%c (0x%x)\n", channel + 'a', reg);
            if (ch->dev) {
                uint8_t thr = reg;
                qemu_chr_fe_write(ch->dev, &thr, 1);
            }
        } else {
            DPRINTF("Write THR%c (0x%x), Tx disabled\n", channel + 'a', reg);
        }
        break;

    /* Not implemented */
    case REG_ACR:
        DPRINTF("Write ACR%c 0x%x\n", block + 'A', val);
        break;

    case REG_IMR:
        DPRINTF("Write IMR%c 0x%x\n", block + 'A', val);
        blk->imr = reg;
        break;

    /* Not implemented */
    case REG_OPCR:
        DPRINTF("Write OPCR%c 0x%x\n", block + 'A', val);
        break;

    default:
        DPRINTF("Write unknown/unsupported register 0x%02x %u\n", offset, val);
    }

    if (old_isr != blk->isr || old_imr != blk->imr) {
        update_irq(dev, block);
    }
}

static uint16_t id_read(IPackDevice *ip, uint8_t addr)
{
    uint16_t ret = 0;
    unsigned pos = addr / 2; /* The ID PROM data is stored every other byte */

    if (pos < ARRAY_SIZE(id_prom_data)) {
        ret = id_prom_data[pos];
    } else {
        DPRINTF("Attempt to read unavailable PROM data at 0x%x\n",  addr);
    }

    return ret;
}

static void id_write(IPackDevice *ip, uint8_t addr, uint16_t val)
{
    IPOctalState *dev = IPOCTAL(ip);
    if (addr == 1) {
        DPRINTF("Write IRQ vector: %u\n", (unsigned) val);
        dev->irq_vector = val; /* Undocumented, but the hw works like that */
    } else {
        DPRINTF("Attempt to write 0x%x to 0x%x\n", val, addr);
    }
}

static uint16_t int_read(IPackDevice *ip, uint8_t addr)
{
    IPOctalState *dev = IPOCTAL(ip);
    /* Read address 0 to ACK INT0# and address 2 to ACK INT1# */
    if (addr != 0 && addr != 2) {
        DPRINTF("Attempt to read from 0x%x\n", addr);
        return 0;
    } else {
        /* Update interrupts if necessary */
        update_irq(dev, addr);
        return dev->irq_vector;
    }
}

static void int_write(IPackDevice *ip, uint8_t addr, uint16_t val)
{
    DPRINTF("Attempt to write 0x%x to 0x%x\n", val, addr);
}

static uint16_t mem_read16(IPackDevice *ip, uint32_t addr)
{
    DPRINTF("Attempt to read from 0x%x\n", addr);
    return 0;
}

static void mem_write16(IPackDevice *ip, uint32_t addr, uint16_t val)
{
    DPRINTF("Attempt to write 0x%x to 0x%x\n", val, addr);
}

static uint8_t mem_read8(IPackDevice *ip, uint32_t addr)
{
    DPRINTF("Attempt to read from 0x%x\n", addr);
    return 0;
}

static void mem_write8(IPackDevice *ip, uint32_t addr, uint8_t val)
{
    IPOctalState *dev = IPOCTAL(ip);
    if (addr == 1) {
        DPRINTF("Write IRQ vector: %u\n", (unsigned) val);
        dev->irq_vector = val;
    } else {
        DPRINTF("Attempt to write 0x%x to 0x%x\n", val, addr);
    }
}

static int hostdev_can_receive(void *opaque)
{
    SCC2698Channel *ch = opaque;
    int available_bytes = RX_FIFO_SIZE - ch->rx_pending;
    return ch->rx_enabled ? available_bytes : 0;
}

static void hostdev_receive(void *opaque, const uint8_t *buf, int size)
{
    SCC2698Channel *ch = opaque;
    IPOctalState *dev = ch->ipoctal;
    unsigned pos = ch->rhr_idx + ch->rx_pending;
    int i;

    assert(size + ch->rx_pending <= RX_FIFO_SIZE);

    /* Copy data to the RxFIFO */
    for (i = 0; i < size; i++) {
        pos %= RX_FIFO_SIZE;
        ch->rhr[pos++] = buf[i];
    }

    ch->rx_pending += size;

    /* If the RxFIFO was empty raise an interrupt */
    if (!(ch->sr & SR_RXRDY)) {
        unsigned block, channel = 0;
        /* Find channel number to update the ISR register */
        while (&dev->ch[channel] != ch) {
            channel++;
        }
        block = channel / 2;
        dev->blk[block].isr |= ISR_RXRDY(channel);
        ch->sr |= SR_RXRDY;
        update_irq(dev, block);
    }
}

static void hostdev_event(void *opaque, int event)
{
    SCC2698Channel *ch = opaque;
    switch (event) {
    case CHR_EVENT_OPENED:
        DPRINTF("Device %s opened\n", ch->dev->label);
        break;
    case CHR_EVENT_BREAK: {
        uint8_t zero = 0;
        DPRINTF("Device %s received break\n", ch->dev->label);

        if (!(ch->sr & SR_BREAK)) {
            IPOctalState *dev = ch->ipoctal;
            unsigned block, channel = 0;

            while (&dev->ch[channel] != ch) {
                channel++;
            }
            block = channel / 2;

            ch->sr |= SR_BREAK;
            dev->blk[block].isr |= ISR_BREAK(channel);
        }

        /* Put a zero character in the buffer */
        hostdev_receive(ch, &zero, 1);
    }
        break;
    default:
        DPRINTF("Device %s received event %d\n", ch->dev->label, event);
    }
}

static int ipoctal_init(IPackDevice *ip)
{
    IPOctalState *s = IPOCTAL(ip);
    unsigned i;

    for (i = 0; i < N_CHANNELS; i++) {
        SCC2698Channel *ch = &s->ch[i];
        ch->ipoctal = s;

        /* Redirect IP-Octal channels to host character devices */
        if (ch->dev) {
            qemu_chr_add_handlers(ch->dev, hostdev_can_receive,
                                  hostdev_receive, hostdev_event, ch);
            DPRINTF("Redirecting channel %u to %s\n", i, ch->dev->label);
        } else {
            DPRINTF("Could not redirect channel %u, no chardev set\n", i);
        }
    }

    return 0;
}

static Property ipoctal_properties[] = {
    DEFINE_PROP_CHR("chardev0", IPOctalState, ch[0].dev),
    DEFINE_PROP_CHR("chardev1", IPOctalState, ch[1].dev),
    DEFINE_PROP_CHR("chardev2", IPOctalState, ch[2].dev),
    DEFINE_PROP_CHR("chardev3", IPOctalState, ch[3].dev),
    DEFINE_PROP_CHR("chardev4", IPOctalState, ch[4].dev),
    DEFINE_PROP_CHR("chardev5", IPOctalState, ch[5].dev),
    DEFINE_PROP_CHR("chardev6", IPOctalState, ch[6].dev),
    DEFINE_PROP_CHR("chardev7", IPOctalState, ch[7].dev),
    DEFINE_PROP_END_OF_LIST(),
};

static void ipoctal_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    IPackDeviceClass *ic = IPACK_DEVICE_CLASS(klass);

    ic->init        = ipoctal_init;
    ic->io_read     = io_read;
    ic->io_write    = io_write;
    ic->id_read     = id_read;
    ic->id_write    = id_write;
    ic->int_read    = int_read;
    ic->int_write   = int_write;
    ic->mem_read16  = mem_read16;
    ic->mem_write16 = mem_write16;
    ic->mem_read8   = mem_read8;
    ic->mem_write8  = mem_write8;

    dc->desc    = "GE IP-Octal 232 8-channel RS-232 IndustryPack";
    dc->props   = ipoctal_properties;
    dc->vmsd    = &vmstate_ipoctal;
}

static const TypeInfo ipoctal_info = {
    .name          = TYPE_IPOCTAL,
    .parent        = TYPE_IPACK_DEVICE,
    .instance_size = sizeof(IPOctalState),
    .class_init    = ipoctal_class_init,
};

static void ipoctal_register_types(void)
{
    type_register_static(&ipoctal_info);
}

type_init(ipoctal_register_types)
