/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
#include "qemu/osdep.h"
#include "qemu/rcu.h"
#include "cpu.h"
#include "exec/cpu-all.h"
#include "exec/memory.h"
#include "exec/ram_addr.h"
#include "migration/qemu-file.h"
#include "sysemu/char.h"
#include "hw/hw.h"
#include "exec/address-spaces.h"
#include "hw/sysbus.h"
#include "sysemu/sysemu.h"

#define TTY_DEVICE_VERSION 1

enum {
    TTY_PUT_CHAR       = 0x00,
    TTY_BYTES_READY    = 0x04,
    TTY_CMD            = 0x08,

    TTY_DATA_PTR       = 0x10,
    TTY_DATA_LEN       = 0x14,
    TTY_DATA_PTR_HIGH  = 0x18,

    TTY_VERSION        = 0x20,

    TTY_CMD_INT_DISABLE    = 0,
    TTY_CMD_INT_ENABLE     = 1,
    TTY_CMD_WRITE_BUFFER   = 2,
    TTY_CMD_READ_BUFFER    = 3,
};

struct tty_state {
    SysBusDevice parent;

    MemoryRegion iomem;
    qemu_irq irq;

    CharDriverState *cs;
    uint64_t ptr;
    uint32_t ptr_len;
    uint32_t ready;
    uint8_t data[128];
    uint32_t data_count;
};

#define  GOLDFISH_TTY_SAVE_VERSION  2

#define TYPE_GOLDFISH_TTY "goldfish_tty"
#define GOLDFISH_TTY(obj) OBJECT_CHECK(struct tty_state, (obj), TYPE_GOLDFISH_TTY)

/* Number of instantiated TTYs */
static int  instance_id = 0;

static void goldfish_tty_save(QEMUFile*  f, void*  opaque)
{
    struct tty_state*  s = opaque;

    qemu_put_be64( f, s->ptr );
    qemu_put_be32( f, s->ptr_len );
    qemu_put_byte( f, s->ready );
    qemu_put_byte( f, s->data_count );
    qemu_put_buffer( f, s->data, s->data_count );
}

static int goldfish_tty_load(QEMUFile*  f, void*  opaque, int  version_id)
{
    struct tty_state*  s = opaque;

    if ((version_id != GOLDFISH_TTY_SAVE_VERSION) &&
        (version_id != (GOLDFISH_TTY_SAVE_VERSION - 1))) {
        return -1;
    }
    if (version_id == (GOLDFISH_TTY_SAVE_VERSION - 1)) {
        s->ptr    = (uint64_t)qemu_get_be32(f);
    } else {
        s->ptr    = qemu_get_be64(f);
    }
    s->ptr_len    = qemu_get_be32(f);
    s->ready      = qemu_get_byte(f);
    s->data_count = qemu_get_byte(f);

    if (qemu_get_buffer(f, s->data, s->data_count) < s->data_count)
        return -1;

    qemu_set_irq(s->irq, s->ready && s->data_count > 0);
    return 0;
}

static uint64_t goldfish_tty_read(void *opaque, hwaddr offset, unsigned size)
{
    struct tty_state *s = (struct tty_state *)opaque;

    switch (offset) {
        case TTY_BYTES_READY:
            return s->data_count;
        case TTY_VERSION:
            return TTY_DEVICE_VERSION;
    default:
        cpu_abort(current_cpu,
                  "goldfish_tty_read: Bad offset %" HWADDR_PRIx "\n",
                  offset);
        return 0;
    }
}

static void goldfish_tty_write(void *opaque, hwaddr offset,
                               uint64_t value, unsigned size)
{
    struct tty_state *s = (struct tty_state *)opaque;

    switch(offset) {
        case TTY_PUT_CHAR: {
            uint8_t ch = value;
            if(s->cs)
                qemu_chr_fe_write(s->cs, &ch, 1);
        } break;

        case TTY_CMD:
            switch(value) {
                case TTY_CMD_INT_DISABLE:
                    if(s->ready) {
                        if(s->data_count > 0)
                            qemu_set_irq(s->irq, 0);
                        s->ready = 0;
                    }
                    break;

                case TTY_CMD_INT_ENABLE:
                    if(!s->ready) {
                        if(s->data_count > 0)
                            qemu_set_irq(s->irq, 1);
                        s->ready = 1;
                    }
                    break;

                case TTY_CMD_WRITE_BUFFER:
                    if(s->cs) {
                        hwaddr l = s->ptr_len;
                        void *ptr;

                        ptr = cpu_physical_memory_map(s->ptr, &l, 0);
                        qemu_chr_fe_write(s->cs, (const uint8_t*)ptr, l);
                        cpu_physical_memory_unmap(ptr, l, 0, 0);
                    }
                    break;

                case TTY_CMD_READ_BUFFER:
                    {
                        hwaddr l = s->ptr_len;
                        void *ptr;

                        if(s->ptr_len > s->data_count)
                            cpu_abort(current_cpu,
                                      "goldfish_tty_write: reading"
                                      " more data than available %d %d\n",
                                      s->ptr_len, s->data_count);

                        ptr = cpu_physical_memory_map(s->ptr, &l, 1);
                        memcpy(ptr, s->data, l);
                        cpu_physical_memory_unmap(ptr, l, 1, l);

                        if(s->data_count > l)
                            memmove(s->data, s->data + l, s->data_count - l);
                        s->data_count -= l;
                        if(s->data_count == 0 && s->ready)
                            qemu_set_irq(s->irq, 0);
                    }
                    break;

                default:
                    cpu_abort(current_cpu,
                              "goldfish_tty_write: Bad command %" PRIx64 "\n",
                              value);
            };
            break;

        case TTY_DATA_PTR:
#if defined(TARGET_MIPS64)
            s->ptr = (int32_t)deposit64(s->ptr, 0, 32, value);
#else
            s->ptr = deposit64(s->ptr, 0, 32, value);
#endif
            break;

        case TTY_DATA_PTR_HIGH:
            s->ptr = deposit64(s->ptr, 32, 32, value);
            break;

        case TTY_DATA_LEN:
            s->ptr_len = value;
            break;

        default:
            cpu_abort(current_cpu,
                      "goldfish_tty_write: Bad offset %" HWADDR_PRIx "\n",
                      offset);
    }
}

static int tty_can_receive(void *opaque)
{
    struct tty_state *s = opaque;

    return (sizeof(s->data) - s->data_count);
}

static void tty_receive(void *opaque, const uint8_t *buf, int size)
{
    struct tty_state *s = opaque;

    memcpy(s->data + s->data_count, buf, size);
    s->data_count += size;
    if(s->data_count > 0 && s->ready)
        qemu_set_irq(s->irq, 1);
}

static const MemoryRegionOps mips_qemu_ops = {
    .read = goldfish_tty_read,
    .write = goldfish_tty_write,
    .endianness = DEVICE_NATIVE_ENDIAN,
};

static void goldfish_tty_realize(DeviceState *dev, Error **errp)
{
    SysBusDevice *sbdev = SYS_BUS_DEVICE(dev);
    struct tty_state *s = GOLDFISH_TTY(dev);
    int i;

    if ((instance_id + 1) == MAX_SERIAL_PORTS) {
        cpu_abort(current_cpu,
                  "goldfish_tty: MAX_SERIAL_PORTS(%d) reached\n",
                  MAX_SERIAL_PORTS);
    }

    memory_region_init_io(&s->iomem, OBJECT(s), &mips_qemu_ops, s,
            "goldfish_tty", 0x1000);
    sysbus_init_mmio(sbdev, &s->iomem);
    sysbus_init_irq(sbdev, &s->irq);

    for(i = 0; i < MAX_SERIAL_PORTS; i++) {
        if(serial_hds[i]) {
            s->cs = serial_hds[i];
            qemu_chr_add_handlers(serial_hds[i], tty_can_receive,
                                  tty_receive, NULL, s);
            break;
        }
    }

    register_savevm(NULL,
                    "goldfish_tty",
                    instance_id++,
                    GOLDFISH_TTY_SAVE_VERSION,
                    goldfish_tty_save,
                    goldfish_tty_load,
                    s);
}

static void goldfish_tty_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = goldfish_tty_realize;
    dc->desc = "goldfish tty";
}

static const TypeInfo goldfish_tty_info = {
    .name          = TYPE_GOLDFISH_TTY,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(struct tty_state),
    .class_init    = goldfish_tty_class_init,
};

static void goldfish_tty_register(void)
{
    type_register_static(&goldfish_tty_info);
}

type_init(goldfish_tty_register);
