/*
 * SCLP event type
 *    Ascii Console Data (VT220 Console)
 *
 * Copyright IBM, Corp. 2012
 *
 * Authors:
 *  Heinz Graalfs <graalfs@de.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or (at your
 * option) any later version.  See the COPYING file in the top-level directory.
 *
 */

#include <hw/qdev.h>
#include "qemu/thread.h"
#include "qemu/error-report.h"

#include "hw/s390x/sclp.h"
#include "hw/s390x/event-facility.h"
#include "sysemu/char.h"

typedef struct ASCIIConsoleData {
    EventBufferHeader ebh;
    char data[0];
} QEMU_PACKED ASCIIConsoleData;

/* max size for ASCII data in 4K SCCB page */
#define SIZE_BUFFER_VT220 4080

typedef struct SCLPConsole {
    SCLPEvent event;
    CharDriverState *chr;
    uint8_t iov[SIZE_BUFFER_VT220];
    uint32_t iov_sclp;      /* offset in buf for SCLP read operation       */
    uint32_t iov_bs;        /* offset in buf for char layer read operation */
    uint32_t iov_data_len;  /* length of byte stream in buffer             */
    uint32_t iov_sclp_rest; /* length of byte stream not read via SCLP     */
    bool notify;            /* qemu_notify_event() req'd if true           */
} SCLPConsole;

/* character layer call-back functions */

/* Return number of bytes that fit into iov buffer */
static int chr_can_read(void *opaque)
{
    SCLPConsole *scon = opaque;
    int avail = SIZE_BUFFER_VT220 - scon->iov_data_len;

    if (avail == 0) {
        scon->notify = true;
    }
    return avail;
}

/* Send data from a char device over to the guest */
static void chr_read(void *opaque, const uint8_t *buf, int size)
{
    SCLPConsole *scon = opaque;

    assert(scon);
    /* read data must fit into current buffer */
    assert(size <= SIZE_BUFFER_VT220 - scon->iov_data_len);

    /* put byte-stream from character layer into buffer */
    memcpy(&scon->iov[scon->iov_bs], buf, size);
    scon->iov_data_len += size;
    scon->iov_sclp_rest += size;
    scon->iov_bs += size;
    scon->event.event_pending = true;
    sclp_service_interrupt(0);
}

/* functions to be called by event facility */

static bool can_handle_event(uint8_t type)
{
    return type == SCLP_EVENT_ASCII_CONSOLE_DATA;
}

static unsigned int send_mask(void)
{
    return SCLP_EVENT_MASK_MSG_ASCII;
}

static unsigned int receive_mask(void)
{
    return SCLP_EVENT_MASK_MSG_ASCII;
}

/* triggered by SCLP's read_event_data -
 * copy console data byte-stream into provided (SCLP) buffer
 */
static void get_console_data(SCLPEvent *event, uint8_t *buf, size_t *size,
                             int avail)
{
    SCLPConsole *cons = DO_UPCAST(SCLPConsole, event, event);

    /* first byte is hex 0 saying an ascii string follows */
    *buf++ = '\0';
    avail--;
    /* if all data fit into provided SCLP buffer */
    if (avail >= cons->iov_sclp_rest) {
        /* copy character byte-stream to SCLP buffer */
        memcpy(buf, &cons->iov[cons->iov_sclp], cons->iov_sclp_rest);
        *size = cons->iov_sclp_rest + 1;
        cons->iov_sclp = 0;
        cons->iov_bs = 0;
        cons->iov_data_len = 0;
        cons->iov_sclp_rest = 0;
        event->event_pending = false;
        /* data provided and no more data pending */
    } else {
        /* if provided buffer is too small, just copy part */
        memcpy(buf, &cons->iov[cons->iov_sclp], avail);
        *size = avail + 1;
        cons->iov_sclp_rest -= avail;
        cons->iov_sclp += avail;
        /* more data pending */
    }
    if (cons->notify) {
        cons->notify = false;
        qemu_notify_event();
    }
}

static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr,
                           int *slen)
{
    int avail;
    size_t src_len;
    uint8_t *to;
    ASCIIConsoleData *acd = (ASCIIConsoleData *) evt_buf_hdr;

    if (!event->event_pending) {
        /* no data pending */
        return 0;
    }

    to = (uint8_t *)&acd->data;
    avail = *slen - sizeof(ASCIIConsoleData);
    get_console_data(event, to, &src_len, avail);

    acd->ebh.length = cpu_to_be16(sizeof(ASCIIConsoleData) + src_len);
    acd->ebh.type = SCLP_EVENT_ASCII_CONSOLE_DATA;
    acd->ebh.flags |= SCLP_EVENT_BUFFER_ACCEPTED;
    *slen = avail - src_len;

    return 1;
}

/* triggered by SCLP's write_event_data
 *  - write console data to character layer
 *  returns < 0 if an error occurred
 */
static ssize_t write_console_data(SCLPEvent *event, const uint8_t *buf,
                                  size_t len)
{
    SCLPConsole *scon = DO_UPCAST(SCLPConsole, event, event);

    if (!scon->chr) {
        /* If there's no backend, we can just say we consumed all data. */
        return len;
    }

    return qemu_chr_fe_write_all(scon->chr, buf, len);
}

static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr)
{
    int rc;
    int length;
    ssize_t written;
    ASCIIConsoleData *acd = (ASCIIConsoleData *) evt_buf_hdr;

    length = be16_to_cpu(evt_buf_hdr->length) - sizeof(EventBufferHeader);
    written = write_console_data(event, (uint8_t *)acd->data, length);

    rc = SCLP_RC_NORMAL_COMPLETION;
    /* set event buffer accepted flag */
    evt_buf_hdr->flags |= SCLP_EVENT_BUFFER_ACCEPTED;

    /* written will be zero if a pty is not connected - don't treat as error */
    if (written < 0) {
        /* event buffer not accepted due to error in character layer */
        evt_buf_hdr->flags &= ~(SCLP_EVENT_BUFFER_ACCEPTED);
        rc = SCLP_RC_CONTAINED_EQUIPMENT_CHECK;
    }

    return rc;
}

static const VMStateDescription vmstate_sclpconsole = {
    .name = "sclpconsole",
    .version_id = 0,
    .minimum_version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_BOOL(event.event_pending, SCLPConsole),
        VMSTATE_UINT8_ARRAY(iov, SCLPConsole, SIZE_BUFFER_VT220),
        VMSTATE_UINT32(iov_sclp, SCLPConsole),
        VMSTATE_UINT32(iov_bs, SCLPConsole),
        VMSTATE_UINT32(iov_data_len, SCLPConsole),
        VMSTATE_UINT32(iov_sclp_rest, SCLPConsole),
        VMSTATE_END_OF_LIST()
     }
};

/* qemu object creation and initialization functions */

/* tell character layer our call-back functions */

static int console_init(SCLPEvent *event)
{
    static bool console_available;

    SCLPConsole *scon = DO_UPCAST(SCLPConsole, event, event);

    if (console_available) {
        error_report("Multiple VT220 operator consoles are not supported");
        return -1;
    }
    console_available = true;
    if (scon->chr) {
        qemu_chr_add_handlers(scon->chr, chr_can_read,
                              chr_read, NULL, scon);
    }

    return 0;
}

static void console_reset(DeviceState *dev)
{
   SCLPEvent *event = SCLP_EVENT(dev);
   SCLPConsole *scon = DO_UPCAST(SCLPConsole, event, event);

   event->event_pending = false;
   scon->iov_sclp = 0;
   scon->iov_bs = 0;
   scon->iov_data_len = 0;
   scon->iov_sclp_rest = 0;
   scon->notify = false;
}

static int console_exit(SCLPEvent *event)
{
    return 0;
}

static Property console_properties[] = {
    DEFINE_PROP_CHR("chardev", SCLPConsole, chr),
    DEFINE_PROP_END_OF_LIST(),
};

static void console_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SCLPEventClass *ec = SCLP_EVENT_CLASS(klass);

    dc->props = console_properties;
    dc->reset = console_reset;
    dc->vmsd = &vmstate_sclpconsole;
    ec->init = console_init;
    ec->exit = console_exit;
    ec->get_send_mask = send_mask;
    ec->get_receive_mask = receive_mask;
    ec->can_handle_event = can_handle_event;
    ec->read_event_data = read_event_data;
    ec->write_event_data = write_event_data;
}

static const TypeInfo sclp_console_info = {
    .name          = "sclpconsole",
    .parent        = TYPE_SCLP_EVENT,
    .instance_size = sizeof(SCLPConsole),
    .class_init    = console_class_init,
    .class_size    = sizeof(SCLPEventClass),
};

static void register_types(void)
{
    type_register_static(&sclp_console_info);
}

type_init(register_types)
