/*
 * 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)
 */

/*handling msr read & write exceptions*/

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

#include <sel4/sel4.h>

#include "vmm/debug.h"
#include "vmm/vmm.h"
#include "vmm/processor/msr.h"

int vmm_rdmsr_handler(vmm_vcpu_t *vcpu) {

    int ret = 0;
    unsigned int msr_no = vmm_read_user_context(&vcpu->guest_state, USER_CONTEXT_ECX);
    uint64_t data = 0;

    DPRINTF(4, "rdmsr ecx 0x%x\n", msr_no);

    // src reference: Linux kernel 3.11 kvm arch/x86/kvm/x86.c
    switch (msr_no) {
        case MSR_IA32_PLATFORM_ID:
        case MSR_IA32_EBL_CR_POWERON:
        case MSR_IA32_DEBUGCTLMSR:
        case MSR_IA32_LASTBRANCHFROMIP:
        case MSR_IA32_LASTBRANCHTOIP:
        case MSR_IA32_LASTINTFROMIP:
        case MSR_IA32_LASTINTTOIP:
        case MSR_IA32_MISC_ENABLE:
            data = 0;
            break;

        case MSR_IA32_UCODE_REV:
            data = 0x100000000ULL;
            break;

        case MSR_P6_PERFCTR0:
        case MSR_P6_PERFCTR1:
        case MSR_P6_EVNTSEL0:
        case MSR_P6_EVNTSEL1:
        case MSR_IA32_PERF_GLOBAL_STATUS_SET:
            /* performance counters not supported. */
            data = 0;
            break;

        case 0xcd: /* fsb frequency */
            data = 3;
            break;

        case MSR_EBC_FREQUENCY_ID:
            data = 1 << 24;
            break;

        case MSR_IA32_APICBASE:
            data = vmm_lapic_get_base_msr(vcpu);
            break;

        default:
            DPRINTF(1, "rdmsr WARNING unsupported msr_no 0x%x\n", msr_no);
            // generate a GP fault
            vmm_inject_exception(vcpu, 13, 1, 0);
            return 0;

   }

    if (!ret) {
        vmm_set_user_context(&vcpu->guest_state, USER_CONTEXT_EAX, (uint32_t)(data & 0xffffffff));
        vmm_set_user_context(&vcpu->guest_state, USER_CONTEXT_EDX, (uint32_t)(data >> 32));
        vmm_guest_exit_next_instruction(&vcpu->guest_state, vcpu->guest_vcpu);
    }

    return ret;
}

int vmm_wrmsr_handler(vmm_vcpu_t *vcpu) {

    int ret = 0;

    unsigned int msr_no = vmm_read_user_context(&vcpu->guest_state, USER_CONTEXT_ECX);
    unsigned int val_high = vmm_read_user_context(&vcpu->guest_state, USER_CONTEXT_EDX);
    unsigned int val_low = vmm_read_user_context(&vcpu->guest_state, USER_CONTEXT_EAX);

    DPRINTF(4, "wrmsr ecx 0x%x   value: 0x%x  0x%x\n", msr_no, val_high, val_low);

    // src reference: Linux kernel 3.11 kvm arch/x86/kvm/x86.c
    switch (msr_no) {
        case MSR_IA32_UCODE_REV:
        case MSR_IA32_UCODE_WRITE:
            break;

        case MSR_P6_PERFCTR0:
        case MSR_P6_PERFCTR1:
        case MSR_P6_EVNTSEL0:
        case MSR_P6_EVNTSEL1:
        case MSR_IA32_PERF_GLOBAL_STATUS_SET:
            /* performance counters not supported. */
            break;

        case MSR_IA32_APICBASE:
            vmm_lapic_set_base_msr(vcpu, val_low);
            break;

        default:
            DPRINTF(1, "wrmsr WARNING unsupported msr_no 0x%x\n", msr_no);
            // generate a GP fault
            vmm_inject_exception(vcpu, 13, 1, 0);
            return 0;
    }

    if (!ret)
        vmm_guest_exit_next_instruction(&vcpu->guest_state, vcpu->guest_vcpu);

    return ret;
}
