/*
 * Arm PrimeCell PL022 Synchronous Serial Port
 *
 * Copyright (c) 2007 CodeSourcery.
 * Written by Paul Brook
 *
 * This code is licenced under the GPL.
 */

#include "vl.h"

//#define DEBUG_PL022 1

#ifdef DEBUG_PL022
#define DPRINTF(fmt, args...) \
do { printf("pl022: " fmt , ##args); } while (0)
#define BADF(fmt, args...) \
do { fprintf(stderr, "pl022: error: " fmt , ##args); exit(1);} while (0)
#else
#define DPRINTF(fmt, args...) do {} while(0)
#define BADF(fmt, args...) \
do { fprintf(stderr, "pl022: error: " fmt , ##args);} while (0)
#endif

#define PL022_CR1_LBM 0x01
#define PL022_CR1_SSE 0x02
#define PL022_CR1_MS  0x04
#define PL022_CR1_SDO 0x08

#define PL022_SR_TFE  0x01
#define PL022_SR_TNF  0x02
#define PL022_SR_RNE  0x04
#define PL022_SR_RFF  0x08
#define PL022_SR_BSY  0x10

#define PL022_INT_ROR 0x01
#define PL022_INT_RT  0x04
#define PL022_INT_RX  0x04
#define PL022_INT_TX  0x08

typedef struct {
    uint32_t base;
    uint32_t cr0;
    uint32_t cr1;
    uint32_t bitmask;
    uint32_t sr;
    uint32_t cpsr;
    uint32_t is;
    uint32_t im;
    /* The FIFO head points to the next empty entry.  */
    int tx_fifo_head;
    int rx_fifo_head;
    int tx_fifo_len;
    int rx_fifo_len;
    uint16_t tx_fifo[8];
    uint16_t rx_fifo[8];
    qemu_irq irq;
    int (*xfer_cb)(void *, int);
    void *opaque;
} pl022_state;

static const unsigned char pl022_id[8] =
  { 0x22, 0x10, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1 };

static void pl022_update(pl022_state *s)
{
    s->sr = 0;
    if (s->tx_fifo_len == 0)
        s->sr |= PL022_SR_TFE;
    if (s->tx_fifo_len != 8)
        s->sr |= PL022_SR_TNF;
    if (s->rx_fifo_len != 0)
        s->sr |= PL022_SR_RNE;
    if (s->rx_fifo_len == 8)
        s->sr |= PL022_SR_RFF;
    if (s->tx_fifo_len)
        s->sr |= PL022_SR_BSY;
    s->is = 0;
    if (s->rx_fifo_len >= 4)
        s->is |= PL022_INT_RX;
    if (s->tx_fifo_len <= 4)
        s->is |= PL022_INT_TX;

    qemu_set_irq(s->irq, (s->is & s->im) != 0);
}

static void pl022_xfer(pl022_state *s)
{
    int i;
    int o;
    int val;

    if ((s->cr1 & PL022_CR1_SSE) == 0) {
        pl022_update(s);
        DPRINTF("Disabled\n");
        return;
    }

    DPRINTF("Maybe xfer %d/%d\n", s->tx_fifo_len, s->rx_fifo_len);
    i = (s->tx_fifo_head - s->tx_fifo_len) & 7;
    o = s->rx_fifo_head;
    /* ??? We do not emulate the line speed.
       This may break some applications.  The are two problematic cases:
        (a) A driver feeds data into the TX FIFO until it is full,
         and only then drains the RX FIFO.  On real hardware the CPU can
         feed data fast enough that the RX fifo never gets chance to overflow.
        (b) A driver transmits data, deliberately allowing the RX FIFO to
         overflow because it ignores the RX data anyway.

       We choose to support (a) by stalling the transmit engine if it would
       cause the RX FIFO to overflow.  In practice much transmit-only code
       falls into (a) because it flushes the RX FIFO to determine when
       the transfer has completed.  */
    while (s->tx_fifo_len && s->rx_fifo_len < 8) {
        DPRINTF("xfer\n");
        val = s->tx_fifo[i];
        if (s->cr1 & PL022_CR1_LBM) {
            /* Loopback mode.  */
        } else if (s->xfer_cb) {
            val = s->xfer_cb(s->opaque, val);
        } else {
            val = 0;
        }
        s->rx_fifo[o] = val & s->bitmask;
        i = (i + 1) & 7;
        o = (o + 1) & 7;
        s->tx_fifo_len--;
        s->rx_fifo_len++;
    }
    s->rx_fifo_head = o;
    pl022_update(s);
}

static uint32_t pl022_read(void *opaque, target_phys_addr_t offset)
{
    pl022_state *s = (pl022_state *)opaque;
    int val;

    offset -= s->base;
    if (offset >= 0xfe0 && offset < 0x1000) {
        return pl022_id[(offset - 0xfe0) >> 2];
    }
    switch (offset) {
    case 0x00: /* CR0 */
      return s->cr0;
    case 0x04: /* CR1 */
      return s->cr1;
    case 0x08: /* DR */
        if (s->rx_fifo_len) {
            val = s->rx_fifo[(s->rx_fifo_head - s->rx_fifo_len) & 7];
            DPRINTF("RX %02x\n", val);
            s->rx_fifo_len--;
            pl022_xfer(s);
        } else {
            val = 0;
        }
        return val;
    case 0x0c: /* SR */
        return s->sr;
    case 0x10: /* CPSR */
        return s->cpsr;
    case 0x14: /* IMSC */
        return s->im;
    case 0x18: /* RIS */
        return s->is;
    case 0x1c: /* MIS */
        return s->im & s->is;
    case 0x20: /* DMACR */
        /* Not implemented.  */
        return 0;
    default:
        cpu_abort (cpu_single_env, "pl022_read: Bad offset %x\n",
                   (int)offset);
        return 0;
    }
}

static void pl022_write(void *opaque, target_phys_addr_t offset,
                        uint32_t value)
{
    pl022_state *s = (pl022_state *)opaque;

    offset -= s->base;
    switch (offset) {
    case 0x00: /* CR0 */
        s->cr0 = value;
        /* Clock rate and format are ignored.  */
        s->bitmask = (1 << ((value & 15) + 1)) - 1;
        break;
    case 0x04: /* CR1 */
        s->cr1 = value;
        if ((s->cr1 & (PL022_CR1_MS | PL022_CR1_SSE))
                   == (PL022_CR1_MS | PL022_CR1_SSE)) {
            BADF("SPI slave mode not implemented\n");
        }
        pl022_xfer(s);
        break;
    case 0x08: /* DR */
        if (s->tx_fifo_len < 8) {
            DPRINTF("TX %02x\n", value);
            s->tx_fifo[s->tx_fifo_head] = value & s->bitmask;
            s->tx_fifo_head = (s->tx_fifo_head + 1) & 7;
            s->tx_fifo_len++;
            pl022_xfer(s);
        }
        break;
    case 0x10: /* CPSR */
        /* Prescaler.  Ignored.  */
        s->cpsr = value & 0xff;
        break;
    case 0x14: /* IMSC */
        s->im = value;
        pl022_update(s);
        break;
    case 0x20: /* DMACR */
        if (value)
            cpu_abort (cpu_single_env, "pl022: DMA not implemented\n");
        break;
    default:
        cpu_abort (cpu_single_env, "pl022_write: Bad offset %x\n",
                   (int)offset);
    }
}

static void pl022_reset(pl022_state *s)
{
    s->rx_fifo_len = 0;
    s->tx_fifo_len = 0;
    s->im = 0;
    s->is = PL022_INT_TX;
    s->sr = PL022_SR_TFE | PL022_SR_TNF;
}

static CPUReadMemoryFunc *pl022_readfn[] = {
   pl022_read,
   pl022_read,
   pl022_read
};

static CPUWriteMemoryFunc *pl022_writefn[] = {
   pl022_write,
   pl022_write,
   pl022_write
};

void pl022_init(uint32_t base, qemu_irq irq, int (*xfer_cb)(void *, int),
                void * opaque)
{
    int iomemtype;
    pl022_state *s;

    s = (pl022_state *)qemu_mallocz(sizeof(pl022_state));
    iomemtype = cpu_register_io_memory(0, pl022_readfn,
                                       pl022_writefn, s);
    cpu_register_physical_memory(base, 0x00001000, iomemtype);
    s->base = base;
    s->irq = irq;
    s->xfer_cb = xfer_cb;
    s->opaque = opaque;
    pl022_reset(s);
    /* ??? Save/restore.  */
}


