/*
 * Copyright 2014, NICTA
 *
 * 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(NICTA_GPL)
 */

// Deals with ranges of memory mapped io

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

#include <sel4/sel4.h>

#include "vmm/debug.h"
#include "vmm/vmm.h"
#include "vmm/platform/vmcs.h"
#include "vmm/platform/vmexit.h"
#include "vmm/mmio.h"
#include "vmm/processor/decode.h"

#define EPT_VIOL_READ(qual) ((qual) & BIT(0))
#define EPT_VIOL_WRITE(qual) ((qual) & BIT(1))
#define EPT_VIOL_FETCH(qual) ((qual) & BIT(2))

int vmm_mmio_init(vmm_mmio_list_t *list) {
    list->num_ranges = 0;
    list->ranges = malloc(0);
    assert(list->ranges);

    return 0;
}

// Returns 0 if the exit was handled
int vmm_mmio_exit_handler(vmm_vcpu_t *vcpu, uintptr_t addr, unsigned int qualification) {
    int read = EPT_VIOL_READ(qualification);
    int write = EPT_VIOL_WRITE(qualification);
    int fetch = EPT_VIOL_FETCH(qualification);
    if (read && write) {
        // Indicates a fault while walking EPT
        return -1;
    }
    if (fetch) {
        // This is not MMIO
        return -1;
    }

    // Search the list
    for (int i = 0; i < vcpu->vmm->mmio_list.num_ranges; i++) {
        vmm_mmio_range_t *range = &vcpu->vmm->mmio_list.ranges[i];
        
        if (addr < range->start) {
            return -1;
        }

        if (addr <= range->end) {
            // Found a match
            if (read && range->read_handler == NULL) {
                return -1;
            }
            if (write && range->write_handler == NULL) {
                return -1;
            }

            // Decode instruction
            uint8_t ibuf[15];
            int instr_len = vmm_guest_exit_get_int_len(&vcpu->guest_state);
            vmm_fetch_instruction(vcpu,
                    vmm_guest_state_get_eip(&vcpu->guest_state),
                    vmm_guest_state_get_cr3(&vcpu->guest_state, vcpu->guest_vcpu),
                    instr_len, ibuf);

            int reg;
            uint32_t imm;
            int size;
            vmm_decode_instruction(ibuf, instr_len, &reg, &imm, &size);
assert(size == 4); // we don't support non-32 bit accesses. TODO fix this

            // Call handler
            if (read) {
                uint32_t result;
                range->read_handler(vcpu, range->cookie, addr - range->start, size, &result);

                // Inject into register
                assert(reg >= 0 && reg < 8);
                int vcpu_reg = vmm_decoder_reg_mapw[reg];
                assert(vcpu_reg >= 0);
                vmm_set_user_context(&vcpu->guest_state,
                        vcpu_reg, result);
            } else {
                // Get value to pass in
                uint32_t value = imm;
                assert (reg >= 0);
                int vcpu_reg =  vmm_decoder_reg_mapw[reg];
                assert(vcpu_reg >= 0);
                value = vmm_read_user_context(&vcpu->guest_state,
                        vcpu_reg);

                range->write_handler(vcpu, range->cookie, addr - range->start, size, value);
            }

            return 0;
        }
    }

    return -1;
}

static int range_cmp(const void *a, const void *b) {
    return ((const vmm_mmio_range_t *)a)->start - ((const vmm_mmio_range_t *)b)->start;
}

int vmm_mmio_add_handler(vmm_mmio_list_t *list, uintptr_t start, uintptr_t end,
        void *cookie, const char *name,
        vmm_mmio_read_fn read_handler, vmm_mmio_write_fn write_handler) {
    vmm_mmio_range_t *new = malloc(sizeof(*new));
    new->start = start;
    new->end = end;
    new->cookie = cookie;
    new->read_handler = read_handler;
    new->write_handler = write_handler;
    new->name = name;

    list->ranges = realloc(list->ranges, sizeof(vmm_mmio_range_t) * (list->num_ranges + 1));
    memcpy(&list->ranges[list->num_ranges++], new, sizeof(vmm_mmio_range_t));

    qsort(list->ranges, list->num_ranges, sizeof(vmm_mmio_range_t), range_cmp);

    return 0;
}

