/*
 * QEMU SCI/SCIF serial port emulation
 *
 * Copyright (c) 2007 Magnus Damm
 *
 * Based on serial.c - QEMU 16450 UART emulation
 * Copyright (c) 2003-2004 Fabrice Bellard
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/sh4/sh.h"
#include "chardev/char-fe.h"
#include "qapi/error.h"
#include "qemu/timer.h"

//#define DEBUG_SERIAL

#define SH_SERIAL_FLAG_TEND (1 << 0)
#define SH_SERIAL_FLAG_TDE  (1 << 1)
#define SH_SERIAL_FLAG_RDF  (1 << 2)
#define SH_SERIAL_FLAG_BRK  (1 << 3)
#define SH_SERIAL_FLAG_DR   (1 << 4)

#define SH_RX_FIFO_LENGTH (16)

typedef struct {
    MemoryRegion iomem;
    MemoryRegion iomem_p4;
    MemoryRegion iomem_a7;
    uint8_t smr;
    uint8_t brr;
    uint8_t scr;
    uint8_t dr; /* ftdr / tdr */
    uint8_t sr; /* fsr / ssr */
    uint16_t fcr;
    uint8_t sptr;

    uint8_t rx_fifo[SH_RX_FIFO_LENGTH]; /* frdr / rdr */
    uint8_t rx_cnt;
    uint8_t rx_tail;
    uint8_t rx_head;

    int freq;
    int feat;
    int flags;
    int rtrg;

    CharBackend chr;
    QEMUTimer *fifo_timeout_timer;
    uint64_t etu; /* Elementary Time Unit (ns) */

    qemu_irq eri;
    qemu_irq rxi;
    qemu_irq txi;
    qemu_irq tei;
    qemu_irq bri;
} sh_serial_state;

static void sh_serial_clear_fifo(sh_serial_state * s)
{
    memset(s->rx_fifo, 0, SH_RX_FIFO_LENGTH);
    s->rx_cnt = 0;
    s->rx_head = 0;
    s->rx_tail = 0;
}

static void sh_serial_write(void *opaque, hwaddr offs,
                            uint64_t val, unsigned size)
{
    sh_serial_state *s = opaque;
    unsigned char ch;

#ifdef DEBUG_SERIAL
    printf("sh_serial: write offs=0x%02x val=0x%02x\n",
           offs, val);
#endif
    switch(offs) {
    case 0x00: /* SMR */
        s->smr = val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0x7b : 0xff);
        return;
    case 0x04: /* BRR */
        s->brr = val;
        return;
    case 0x08: /* SCR */
        /* TODO : For SH7751, SCIF mask should be 0xfb. */
        s->scr = val & ((s->feat & SH_SERIAL_FEAT_SCIF) ? 0xfa : 0xff);
        if (!(val & (1 << 5)))
            s->flags |= SH_SERIAL_FLAG_TEND;
        if ((s->feat & SH_SERIAL_FEAT_SCIF) && s->txi) {
            qemu_set_irq(s->txi, val & (1 << 7));
        }
        if (!(val & (1 << 6))) {
            qemu_set_irq(s->rxi, 0);
        }
        return;
    case 0x0c: /* FTDR / TDR */
        if (qemu_chr_fe_backend_connected(&s->chr)) {
            ch = val;
            /* XXX this blocks entire thread. Rewrite to use
             * qemu_chr_fe_write and background I/O callbacks */
            qemu_chr_fe_write_all(&s->chr, &ch, 1);
        }
        s->dr = val;
        s->flags &= ~SH_SERIAL_FLAG_TDE;
        return;
#if 0
    case 0x14: /* FRDR / RDR */
        ret = 0;
        break;
#endif
    }
    if (s->feat & SH_SERIAL_FEAT_SCIF) {
        switch(offs) {
        case 0x10: /* FSR */
            if (!(val & (1 << 6)))
                s->flags &= ~SH_SERIAL_FLAG_TEND;
            if (!(val & (1 << 5)))
                s->flags &= ~SH_SERIAL_FLAG_TDE;
            if (!(val & (1 << 4)))
                s->flags &= ~SH_SERIAL_FLAG_BRK;
            if (!(val & (1 << 1)))
                s->flags &= ~SH_SERIAL_FLAG_RDF;
            if (!(val & (1 << 0)))
                s->flags &= ~SH_SERIAL_FLAG_DR;

            if (!(val & (1 << 1)) || !(val & (1 << 0))) {
                if (s->rxi) {
                    qemu_set_irq(s->rxi, 0);
                }
            }
            return;
        case 0x18: /* FCR */
            s->fcr = val;
            switch ((val >> 6) & 3) {
            case 0:
                s->rtrg = 1;
                break;
            case 1:
                s->rtrg = 4;
                break;
            case 2:
                s->rtrg = 8;
                break;
            case 3:
                s->rtrg = 14;
                break;
            }
            if (val & (1 << 1)) {
                sh_serial_clear_fifo(s);
                s->sr &= ~(1 << 1);
            }

            return;
        case 0x20: /* SPTR */
            s->sptr = val & 0xf3;
            return;
        case 0x24: /* LSR */
            return;
        }
    }
    else {
        switch(offs) {
#if 0
        case 0x0c:
            ret = s->dr;
            break;
        case 0x10:
            ret = 0;
            break;
#endif
        case 0x1c:
            s->sptr = val & 0x8f;
            return;
        }
    }

    fprintf(stderr, "sh_serial: unsupported write to 0x%02"
            HWADDR_PRIx "\n", offs);
    abort();
}

static uint64_t sh_serial_read(void *opaque, hwaddr offs,
                               unsigned size)
{
    sh_serial_state *s = opaque;
    uint32_t ret = ~0;

#if 0
    switch(offs) {
    case 0x00:
        ret = s->smr;
        break;
    case 0x04:
        ret = s->brr;
        break;
    case 0x08:
        ret = s->scr;
        break;
    case 0x14:
        ret = 0;
        break;
    }
#endif
    if (s->feat & SH_SERIAL_FEAT_SCIF) {
        switch(offs) {
        case 0x00: /* SMR */
            ret = s->smr;
            break;
        case 0x08: /* SCR */
            ret = s->scr;
            break;
        case 0x10: /* FSR */
            ret = 0;
            if (s->flags & SH_SERIAL_FLAG_TEND)
                ret |= (1 << 6);
            if (s->flags & SH_SERIAL_FLAG_TDE)
                ret |= (1 << 5);
            if (s->flags & SH_SERIAL_FLAG_BRK)
                ret |= (1 << 4);
            if (s->flags & SH_SERIAL_FLAG_RDF)
                ret |= (1 << 1);
            if (s->flags & SH_SERIAL_FLAG_DR)
                ret |= (1 << 0);

            if (s->scr & (1 << 5))
                s->flags |= SH_SERIAL_FLAG_TDE | SH_SERIAL_FLAG_TEND;

            break;
        case 0x14:
            if (s->rx_cnt > 0) {
                ret = s->rx_fifo[s->rx_tail++];
                s->rx_cnt--;
                if (s->rx_tail == SH_RX_FIFO_LENGTH)
                    s->rx_tail = 0;
                if (s->rx_cnt < s->rtrg)
                    s->flags &= ~SH_SERIAL_FLAG_RDF;
            }
            break;
        case 0x18:
            ret = s->fcr;
            break;
        case 0x1c:
            ret = s->rx_cnt;
            break;
        case 0x20:
            ret = s->sptr;
            break;
        case 0x24:
            ret = 0;
            break;
        }
    }
    else {
        switch(offs) {
#if 0
        case 0x0c:
            ret = s->dr;
            break;
        case 0x10:
            ret = 0;
            break;
        case 0x14:
            ret = s->rx_fifo[0];
            break;
#endif
        case 0x1c:
            ret = s->sptr;
            break;
        }
    }
#ifdef DEBUG_SERIAL
    printf("sh_serial: read offs=0x%02x val=0x%x\n",
           offs, ret);
#endif

    if (ret & ~((1 << 16) - 1)) {
        fprintf(stderr, "sh_serial: unsupported read from 0x%02"
                HWADDR_PRIx "\n", offs);
        abort();
    }

    return ret;
}

static int sh_serial_can_receive(sh_serial_state *s)
{
    return s->scr & (1 << 4);
}

static void sh_serial_receive_break(sh_serial_state *s)
{
    if (s->feat & SH_SERIAL_FEAT_SCIF)
        s->sr |= (1 << 4);
}

static int sh_serial_can_receive1(void *opaque)
{
    sh_serial_state *s = opaque;
    return sh_serial_can_receive(s);
}

static void sh_serial_timeout_int(void *opaque)
{
    sh_serial_state *s = opaque;

    s->flags |= SH_SERIAL_FLAG_RDF;
    if (s->scr & (1 << 6) && s->rxi) {
        qemu_set_irq(s->rxi, 1);
    }
}

static void sh_serial_receive1(void *opaque, const uint8_t *buf, int size)
{
    sh_serial_state *s = opaque;

    if (s->feat & SH_SERIAL_FEAT_SCIF) {
        int i;
        for (i = 0; i < size; i++) {
            if (s->rx_cnt < SH_RX_FIFO_LENGTH) {
                s->rx_fifo[s->rx_head++] = buf[i];
                if (s->rx_head == SH_RX_FIFO_LENGTH) {
                    s->rx_head = 0;
                }
                s->rx_cnt++;
                if (s->rx_cnt >= s->rtrg) {
                    s->flags |= SH_SERIAL_FLAG_RDF;
                    if (s->scr & (1 << 6) && s->rxi) {
                        timer_del(s->fifo_timeout_timer);
                        qemu_set_irq(s->rxi, 1);
                    }
                } else {
                    timer_mod(s->fifo_timeout_timer,
                        qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 15 * s->etu);
                }
            }
        }
    } else {
        s->rx_fifo[0] = buf[0];
    }
}

static void sh_serial_event(void *opaque, int event)
{
    sh_serial_state *s = opaque;
    if (event == CHR_EVENT_BREAK)
        sh_serial_receive_break(s);
}

static const MemoryRegionOps sh_serial_ops = {
    .read = sh_serial_read,
    .write = sh_serial_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

void sh_serial_init(MemoryRegion *sysmem,
                    hwaddr base, int feat,
                    uint32_t freq, Chardev *chr,
                    qemu_irq eri_source,
                    qemu_irq rxi_source,
                    qemu_irq txi_source,
                    qemu_irq tei_source,
                    qemu_irq bri_source)
{
    sh_serial_state *s;

    s = g_malloc0(sizeof(sh_serial_state));

    s->feat = feat;
    s->flags = SH_SERIAL_FLAG_TEND | SH_SERIAL_FLAG_TDE;
    s->rtrg = 1;

    s->smr = 0;
    s->brr = 0xff;
    s->scr = 1 << 5; /* pretend that TX is enabled so early printk works */
    s->sptr = 0;

    if (feat & SH_SERIAL_FEAT_SCIF) {
        s->fcr = 0;
    }
    else {
        s->dr = 0xff;
    }

    sh_serial_clear_fifo(s);

    memory_region_init_io(&s->iomem, NULL, &sh_serial_ops, s,
                          "serial", 0x100000000ULL);

    memory_region_init_alias(&s->iomem_p4, NULL, "serial-p4", &s->iomem,
                             0, 0x28);
    memory_region_add_subregion(sysmem, P4ADDR(base), &s->iomem_p4);

    memory_region_init_alias(&s->iomem_a7, NULL, "serial-a7", &s->iomem,
                             0, 0x28);
    memory_region_add_subregion(sysmem, A7ADDR(base), &s->iomem_a7);

    if (chr) {
        qemu_chr_fe_init(&s->chr, chr, &error_abort);
        qemu_chr_fe_set_handlers(&s->chr, sh_serial_can_receive1,
                                 sh_serial_receive1,
                                 sh_serial_event, NULL, s, NULL, true);
    }

    s->fifo_timeout_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
                                         sh_serial_timeout_int, s);
    s->etu = NANOSECONDS_PER_SECOND / 9600;
    s->eri = eri_source;
    s->rxi = rxi_source;
    s->txi = txi_source;
    s->tei = tei_source;
    s->bri = bri_source;
}
