/*
 * Copyright 2017, Data61
 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
 * ABN 41 687 119 230.
 *
 * This software may be distributed and modified according to the terms of
 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
 * See "LICENSE_GPLv2.txt" for details.
 *
 * @TAG(DATA61_GPL)
 */

/*vm exits related with io instructions*/

#include <stdio.h>
#include <stdlib.h>

#include <sel4/sel4.h>
#include <sel4utils/util.h>
#include <simple/simple.h>

#include "vmm/debug.h"
#include "vmm/io.h"
#include "vmm/vmm.h"

static int io_port_cmp(const void *pkey, const void *pelem) {
    unsigned int key = (unsigned int)(uintptr_t)pkey;
    const ioport_range_t *elem = (const ioport_range_t*)pelem;
    if (key < elem->port_start) {
        return -1;
    }
    if (key > elem->port_end) {
        return 1;
    }
    return 0;
}

static int io_port_cmp2(const void *a, const void *b) {
    const ioport_range_t *aa = (const ioport_range_t*) a;
    const ioport_range_t *bb = (const ioport_range_t*) b;
    return aa->port_start - bb->port_start;
}

static ioport_range_t *search_port(vmm_io_port_list_t *io_port, unsigned int port_no) {
    return (ioport_range_t*)bsearch((void*)(uintptr_t)port_no, io_port->ioports, io_port->num_ioports, sizeof(ioport_range_t), io_port_cmp);
}

/* Debug helper function for port no. */
static const char* vmm_debug_io_portno_desc(vmm_io_port_list_t *io_port, int port_no) {
    ioport_range_t *port = search_port(io_port, port_no);
    return port ? port->desc : "Unknown IO Port";
}

/* IO instruction execution handler. */
int vmm_io_instruction_handler(vmm_vcpu_t *vcpu) {

    unsigned int exit_qualification = vmm_guest_exit_get_qualification(&vcpu->guest_state);
    unsigned int string, rep;
    int ret;
    unsigned int port_no;
    unsigned int size;
    unsigned int value;
    int is_in;

    string = (exit_qualification & 16) != 0;
    is_in = (exit_qualification & 8) != 0;
    port_no = exit_qualification >> 16;
    size = (exit_qualification & 7) + 1;
    rep = (exit_qualification & 0x20) >> 5;

    DPRINTF(4, "vm exit io request: string %d  in %d rep %d  port no 0x%x (%s) size %d\n", string,
            is_in, rep, port_no, vmm_debug_io_portno_desc(&vcpu->vmm->io_port, port_no), size);

    /*FIXME: does not support string and rep instructions*/
    if (string || rep) {
        DPRINTF(0, "vm exit io request: FIXME: does not support string and rep instructions");
        DPRINTF(0, "vm exit io ERROR: string %d  in %d rep %d  port no 0x%x (%s) size %d\n", 0,
                is_in, 0, port_no, vmm_debug_io_portno_desc(&vcpu->vmm->io_port, port_no), size);
        return -1;
    }

    ioport_range_t *port = search_port(&vcpu->vmm->io_port, port_no);
    if (!port) {
        static int last_port = -1;
        if (last_port != port_no) {
            DPRINTF(3, "vm exit io request: WARNING - ignoring unsupported ioport 0x%x (%s)\n", port_no,
                    vmm_debug_io_portno_desc(&vcpu->vmm->io_port, port_no));
            last_port = port_no;
        }
        if (is_in) {
            uint32_t eax;
            if ( size < 4) {
                eax = vmm_read_user_context(&vcpu->guest_state, USER_CONTEXT_EAX);
                eax |= MASK(size * 8);
            } else {
                eax = -1;
            }
            vmm_set_user_context(&vcpu->guest_state, USER_CONTEXT_EAX, eax);
        }
        vmm_guest_exit_next_instruction(&vcpu->guest_state, vcpu->guest_vcpu);
        return 0;
    }

    if (is_in) {
        uint32_t eax;
        ret = port->port_in(port->cookie, port_no, size, &value);
        if (size < 4) {
            eax = vmm_read_user_context(&vcpu->guest_state, USER_CONTEXT_EAX);
            eax &= ~MASK(size * 8);
            eax |= value;
        } else {
            eax = value;
        }
        vmm_set_user_context(&vcpu->guest_state, USER_CONTEXT_EAX, eax);
    } else {
        value = vmm_read_user_context(&vcpu->guest_state, USER_CONTEXT_EAX);
        if (size < 4)
            value &= MASK(size * 8);
        ret = port->port_out(port->cookie, port_no, size, value);
    }

    if (ret) {
        ZF_LOGE("vm exit io request: handler returned error.");
        ZF_LOGE("vm exit io ERROR: string %d  in %d rep %d  port no 0x%x (%s) size %d", 0,
                is_in, 0, port_no, vmm_debug_io_portno_desc(&vcpu->vmm->io_port, port_no), size);
        return -1;
    }

    vmm_guest_exit_next_instruction(&vcpu->guest_state, vcpu->guest_vcpu);

    return 0;
}

static int add_io_port_range(vmm_io_port_list_t *io_list, ioport_range_t port) {
    /* ensure this range does not overlap */
    for (int i = 0; i < io_list->num_ioports; i++) {
        if (io_list->ioports[i].port_end >= port.port_start && io_list->ioports[i].port_start <= port.port_end) {
            ZF_LOGE("Requested ioport range 0x%x-0x%x for %s overlaps with existing range 0x%x-0x%x for %s",
                port.port_start, port.port_end, port.desc ? port.desc : "Unknown IO Port", io_list->ioports[i].port_start, io_list->ioports[i].port_end, io_list->ioports[i].desc ? io_list->ioports[i].desc : "Unknown IO Port");
            return -1;
        }
    }
    /* grow the array */
    io_list->ioports = realloc(io_list->ioports, sizeof(ioport_range_t) * (io_list->num_ioports + 1));
    assert(io_list->ioports);
    /* add the new entry */
    io_list->ioports[io_list->num_ioports] = port;
    io_list->num_ioports++;
    /* sort */
    qsort(io_list->ioports, io_list->num_ioports, sizeof(ioport_range_t), io_port_cmp2);
    return 0;
}

int vmm_io_port_add_passthrough(vmm_io_port_list_t *io_list, uint16_t start, uint16_t end, const char *desc) {
    return add_io_port_range(io_list, (ioport_range_t){start, end, 1, NULL, NULL, NULL, desc});
}

/* Add an io port range for emulation */
int vmm_io_port_add_handler(vmm_io_port_list_t *io_list, uint16_t start, uint16_t end, void *cookie, ioport_in_fn port_in, ioport_out_fn port_out, const char *desc) {
    return add_io_port_range(io_list, (ioport_range_t){start, end, 0, cookie, port_in, port_out, desc});
}

/*configure io ports for a guest*/
int vmm_io_port_init_guest(vmm_io_port_list_t *io_list, simple_t *simple, seL4_CPtr vcpu, vka_t *vka) {
    int UNUSED error;

    for (int i = 0; i < io_list->num_ioports; i++) {
        ioport_range_t *port = &io_list->ioports[i];
        if (port->passthrough) {
            DPRINTF(1, "vmm io port: setting %s IO port 0x%x - 0x%x to passthrough\n", port->desc, port->port_start, port->port_end);
            cspacepath_t path;
            int error;
            error = vka_cspace_alloc_path(vka, &path);
            if (error) {
                ZF_LOGE("Failed to allocate slot");
                return error;
            }
            error = simple_get_IOPort_cap(simple, port->port_start, port->port_end, path.root, path.capPtr, path.capDepth);
            if (error) {
                ZF_LOGE("Failed to get \"%s\" io port from simple for range 0x%x - 0x%x", port->desc, port->port_start, port->port_end);
                return error;
            }
            error = seL4_X86_VCPU_EnableIOPort(vcpu, path.capPtr, port->port_start, port->port_end);
            assert(error == seL4_NoError);
        }
    }

    return 0;
}

int vmm_io_port_init(vmm_io_port_list_t *io_list) {
    io_list->num_ioports = 0;
    io_list->ioports = malloc(0);
    assert(io_list->ioports);
    return 0;
}
