/*
 * QEMU RISC-V Host Target Interface (HTIF) Emulation
 *
 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
 * Copyright (c) 2017-2018 SiFive, Inc.
 *
 * This provides HTIF device emulation for QEMU. At the moment this allows
 * for identical copies of bbl/linux to run on both spike and QEMU.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2 or later, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope 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.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/log.h"
#include "hw/char/riscv_htif.h"
#include "chardev/char.h"
#include "chardev/char-fe.h"
#include "qemu/timer.h"
#include "qemu/error-report.h"
#include "exec/address-spaces.h"
#include "exec/tswap.h"
#include "system/dma.h"
#include "system/runstate.h"
#include "trace.h"

#define HTIF_DEV_SHIFT          56
#define HTIF_CMD_SHIFT          48

#define HTIF_DEV_SYSTEM         0
#define HTIF_DEV_CONSOLE        1

#define HTIF_SYSTEM_CMD_SYSCALL 0
#define HTIF_CONSOLE_CMD_GETC   0
#define HTIF_CONSOLE_CMD_PUTC   1

/* PK system call number */
#define PK_SYS_WRITE            64

const char *sig_file;
uint8_t line_size = 16;

static uint64_t fromhost_addr, tohost_addr, begin_sig_addr, end_sig_addr;

void htif_symbol_callback(const char *st_name, int st_info, uint64_t st_value,
                          uint64_t st_size)
{
    if (strcmp("fromhost", st_name) == 0) {
        fromhost_addr = st_value;
        if (st_size != 8) {
            error_report("HTIF fromhost must be 8 bytes");
            exit(1);
        }
    } else if (strcmp("tohost", st_name) == 0) {
        tohost_addr = st_value;
        if (st_size != 8) {
            error_report("HTIF tohost must be 8 bytes");
            exit(1);
        }
    } else if (strcmp("begin_signature", st_name) == 0) {
        begin_sig_addr = st_value;
    } else if (strcmp("end_signature", st_name) == 0) {
        end_sig_addr = st_value;
    }
}

/*
 * Called by the char dev to see if HTIF is ready to accept input.
 */
static int htif_can_recv(void *opaque)
{
    return 1;
}

/*
 * Called by the char dev to supply input to HTIF console.
 * We assume that we will receive one character at a time.
 */
static void htif_recv(void *opaque, const uint8_t *buf, int size)
{
    HTIFState *s = opaque;

    if (size != 1) {
        return;
    }

    /*
     * TODO - we need to check whether mfromhost is zero which indicates
     *        the device is ready to receive. The current implementation
     *        will drop characters
     */

    uint64_t val_written = s->pending_read;
    uint64_t resp = 0x100 | *buf;

    s->fromhost = (val_written >> 48 << 48) | (resp << 16 >> 16);
}

/*
 * Called by the char dev to supply special events to the HTIF console.
 * Not used for HTIF.
 */
static void htif_event(void *opaque, QEMUChrEvent event)
{

}

static int htif_be_change(void *opaque)
{
    HTIFState *s = opaque;

    qemu_chr_fe_set_handlers(&s->chr, htif_can_recv, htif_recv, htif_event,
        htif_be_change, s, NULL, true);

    return 0;
}

/*
 * See below the tohost register format.
 *
 * Bits 63:56 indicate the "device".
 * Bits 55:48 indicate the "command".
 *
 * Device 0 is the syscall device, which is used to emulate Unixy syscalls.
 * It only implements command 0, which has two subfunctions:
 * - If bit 0 is clear, then bits 47:0 represent a pointer to a struct
 *   describing the syscall.
 * - If bit 1 is set, then bits 47:1 represent an exit code, with a zero
 *   value indicating success and other values indicating failure.
 *
 * Device 1 is the blocking character device.
 * - Command 0 reads a character
 * - Command 1 writes a character from the 8 LSBs of tohost
 *
 * For RV32, the tohost register is zero-extended, so only device=0 and
 * command=0 (i.e. HTIF syscalls/exit codes) are supported.
 */
static void htif_handle_tohost_write(HTIFState *s, uint64_t val_written)
{
    uint8_t device = val_written >> HTIF_DEV_SHIFT;
    uint8_t cmd = val_written >> HTIF_CMD_SHIFT;
    uint64_t payload = val_written & 0xFFFFFFFFFFFFULL;
    int resp = 0;

    trace_htif_uart_write_to_host(device, cmd, payload);

    /*
     * Currently, there is a fixed mapping of devices:
     * 0: riscv-tests Pass/Fail Reporting Only (no syscall proxy)
     * 1: Console
     */
    if (unlikely(device == HTIF_DEV_SYSTEM)) {
        /* frontend syscall handler, shutdown and exit code support */
        if (cmd == HTIF_SYSTEM_CMD_SYSCALL) {
            if (payload & 0x1) {
                /* exit code */
                int exit_code = payload >> 1;

                /*
                 * Dump signature data if sig_file is specified and
                 * begin/end_signature symbols exist.
                 */
                if (sig_file && begin_sig_addr && end_sig_addr) {
                    uint64_t sig_len = end_sig_addr - begin_sig_addr;
                    char *sig_data = g_malloc(sig_len);
                    dma_memory_read(&address_space_memory, begin_sig_addr,
                                    sig_data, sig_len, MEMTXATTRS_UNSPECIFIED);
                    FILE *signature = fopen(sig_file, "w");
                    if (signature == NULL) {
                        error_report("Unable to open %s with error %s",
                                     sig_file, strerror(errno));
                        exit(1);
                    }

                    for (int i = 0; i < sig_len; i += line_size) {
                        for (int j = line_size; j > 0; j--) {
                            if (i + j <= sig_len) {
                                fprintf(signature, "%02x",
                                        sig_data[i + j - 1] & 0xff);
                            } else {
                                fprintf(signature, "%02x", 0);
                            }
                        }
                        fprintf(signature, "\n");
                    }

                    fclose(signature);
                    g_free(sig_data);
                }

                qemu_system_shutdown_request_with_code(
                    SHUTDOWN_CAUSE_GUEST_SHUTDOWN, exit_code);
                return;
            } else {
                uint64_t syscall[8];
                cpu_physical_memory_read(payload, syscall, sizeof(syscall));
                if (le64_to_cpu(syscall[0]) == PK_SYS_WRITE &&
                    le64_to_cpu(syscall[1]) == HTIF_DEV_CONSOLE &&
                    le64_to_cpu(syscall[3]) == HTIF_CONSOLE_CMD_PUTC) {
                    uint8_t ch;
                    cpu_physical_memory_read(le64_to_cpu(syscall[2]), &ch, 1);
                    /*
                     * 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);
                    resp = 0x100 | (uint8_t)payload;
                } else {
                    qemu_log_mask(LOG_UNIMP,
                                  "pk syscall proxy not supported\n");
                }
            }
        } else {
            qemu_log("HTIF device %d: unknown command\n", device);
        }
    } else if (likely(device == HTIF_DEV_CONSOLE)) {
        /* HTIF Console */
        if (cmd == HTIF_CONSOLE_CMD_GETC) {
            /* this should be a queue, but not yet implemented as such */
            s->pending_read = val_written;
            s->tohost = 0; /* clear to indicate we read */
            return;
        } else if (cmd == HTIF_CONSOLE_CMD_PUTC) {
            uint8_t ch = (uint8_t)payload;
            /*
             * 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);
            resp = 0x100 | (uint8_t)payload;
        } else {
            qemu_log("HTIF device %d: unknown command\n", device);
        }
    } else {
        qemu_log("HTIF unknown device or command\n");
        trace_htif_uart_unknown_device_command(device, cmd, payload);
    }
    /*
     * Latest bbl does not set fromhost to 0 if there is a value in tohost.
     * With this code enabled, qemu hangs waiting for fromhost to go to 0.
     * With this code disabled, qemu works with bbl priv v1.9.1 and v1.10.
     * HTIF needs protocol documentation and a more complete state machine.
     *
     *  while (!s->fromhost_inprogress &&
     *      s->fromhost != 0x0) {
     *  }
     */
    s->fromhost = (val_written >> 48 << 48) | (resp << 16 >> 16);
    s->tohost = 0; /* clear to indicate we read */
}

#define TOHOST_OFFSET1      (s->tohost_offset)
#define TOHOST_OFFSET2      (s->tohost_offset + 4)
#define FROMHOST_OFFSET1    (s->fromhost_offset)
#define FROMHOST_OFFSET2    (s->fromhost_offset + 4)

/* CPU wants to read an HTIF register */
static uint64_t htif_mm_read(void *opaque, hwaddr addr, unsigned size)
{
    HTIFState *s = opaque;
    if (addr == TOHOST_OFFSET1) {
        return s->tohost & 0xFFFFFFFF;
    } else if (addr == TOHOST_OFFSET2) {
        return (s->tohost >> 32) & 0xFFFFFFFF;
    } else if (addr == FROMHOST_OFFSET1) {
        return s->fromhost & 0xFFFFFFFF;
    } else if (addr == FROMHOST_OFFSET2) {
        return (s->fromhost >> 32) & 0xFFFFFFFF;
    } else {
        qemu_log("Invalid htif read: address %016" PRIx64 "\n",
            (uint64_t)addr);
        return 0;
    }
}

/* CPU wrote to an HTIF register */
static void htif_mm_write(void *opaque, hwaddr addr,
                          uint64_t value, unsigned size)
{
    HTIFState *s = opaque;
    if (addr == TOHOST_OFFSET1) {
        if (s->tohost == 0x0) {
            s->allow_tohost = 1;
            s->tohost = value & 0xFFFFFFFF;
        } else {
            s->allow_tohost = 0;
        }
    } else if (addr == TOHOST_OFFSET2) {
        if (s->allow_tohost) {
            s->tohost |= value << 32;
            htif_handle_tohost_write(s, s->tohost);
        }
    } else if (addr == FROMHOST_OFFSET1) {
        s->fromhost_inprogress = 1;
        s->fromhost = value & 0xFFFFFFFF;
    } else if (addr == FROMHOST_OFFSET2) {
        s->fromhost |= value << 32;
        s->fromhost_inprogress = 0;
    } else {
        qemu_log("Invalid htif write: address %016" PRIx64 "\n",
            (uint64_t)addr);
    }
}

static const MemoryRegionOps htif_mm_ops = {
    .read = htif_mm_read,
    .write = htif_mm_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .impl = {
        .min_access_size = 4,
        .max_access_size = 4,
    },
};

HTIFState *htif_mm_init(MemoryRegion *address_space, Chardev *chr,
                        uint64_t nonelf_base, bool custom_base)
{
    uint64_t base, size, tohost_offset, fromhost_offset;

    if (custom_base) {
        fromhost_addr = nonelf_base;
        tohost_addr = nonelf_base + 8;
    } else {
        if (!fromhost_addr || !tohost_addr) {
            error_report("Invalid HTIF fromhost or tohost address");
            exit(1);
        }
    }

    base = MIN(tohost_addr, fromhost_addr);
    size = MAX(tohost_addr + 8, fromhost_addr + 8) - base;
    tohost_offset = tohost_addr - base;
    fromhost_offset = fromhost_addr - base;

    HTIFState *s = g_new0(HTIFState, 1);
    s->tohost_offset = tohost_offset;
    s->fromhost_offset = fromhost_offset;
    s->pending_read = 0;
    s->allow_tohost = 0;
    s->fromhost_inprogress = 0;
    qemu_chr_fe_init(&s->chr, chr, &error_abort);
    qemu_chr_fe_set_handlers(&s->chr, htif_can_recv, htif_recv, htif_event,
        htif_be_change, s, NULL, true);

    memory_region_init_io(&s->mmio, NULL, &htif_mm_ops, s,
                          TYPE_HTIF_UART, size);
    memory_region_add_subregion_overlap(address_space, base,
                                        &s->mmio, 1);

    return s;
}
