/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * KVM/MIPS: MIPS specific KVM APIs
 *
 * Copyright (C) 2012-2014 Imagination Technologies Ltd.
 * Authors: Sanjay Lal <sanjayl@kymasys.com>
*/

#include "qemu/osdep.h"
#include <sys/ioctl.h>

#include <linux/kvm.h>

#include "qemu-common.h"
#include "cpu.h"
#include "qemu/error-report.h"
#include "qemu/timer.h"
#include "sysemu/sysemu.h"
#include "sysemu/kvm.h"
#include "sysemu/cpus.h"
#include "kvm_mips.h"
#include "exec/memattrs.h"

#define DEBUG_KVM 0

#define DPRINTF(fmt, ...) \
    do { if (DEBUG_KVM) { fprintf(stderr, fmt, ## __VA_ARGS__); } } while (0)

static int kvm_mips_fpu_cap;
static int kvm_mips_msa_cap;

const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
    KVM_CAP_LAST_INFO
};

static void kvm_mips_update_state(void *opaque, int running, RunState state);

unsigned long kvm_arch_vcpu_id(CPUState *cs)
{
    return cs->cpu_index;
}

int kvm_arch_init(MachineState *ms, KVMState *s)
{
    /* MIPS has 128 signals */
    kvm_set_sigmask_len(s, 16);

    kvm_mips_fpu_cap = kvm_check_extension(s, KVM_CAP_MIPS_FPU);
    kvm_mips_msa_cap = kvm_check_extension(s, KVM_CAP_MIPS_MSA);

    DPRINTF("%s\n", __func__);
    return 0;
}

int kvm_arch_init_vcpu(CPUState *cs)
{
    MIPSCPU *cpu = MIPS_CPU(cs);
    CPUMIPSState *env = &cpu->env;
    int ret = 0;

    qemu_add_vm_change_state_handler(kvm_mips_update_state, cs);

    if (kvm_mips_fpu_cap && env->CP0_Config1 & (1 << CP0C1_FP)) {
        ret = kvm_vcpu_enable_cap(cs, KVM_CAP_MIPS_FPU, 0, 0);
        if (ret < 0) {
            /* mark unsupported so it gets disabled on reset */
            kvm_mips_fpu_cap = 0;
            ret = 0;
        }
    }

    if (kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) {
        ret = kvm_vcpu_enable_cap(cs, KVM_CAP_MIPS_MSA, 0, 0);
        if (ret < 0) {
            /* mark unsupported so it gets disabled on reset */
            kvm_mips_msa_cap = 0;
            ret = 0;
        }
    }

    DPRINTF("%s\n", __func__);
    return ret;
}

void kvm_mips_reset_vcpu(MIPSCPU *cpu)
{
    CPUMIPSState *env = &cpu->env;

    if (!kvm_mips_fpu_cap && env->CP0_Config1 & (1 << CP0C1_FP)) {
        fprintf(stderr, "Warning: KVM does not support FPU, disabling\n");
        env->CP0_Config1 &= ~(1 << CP0C1_FP);
    }
    if (!kvm_mips_msa_cap && env->CP0_Config3 & (1 << CP0C3_MSAP)) {
        fprintf(stderr, "Warning: KVM does not support MSA, disabling\n");
        env->CP0_Config3 &= ~(1 << CP0C3_MSAP);
    }

    DPRINTF("%s\n", __func__);
}

int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
{
    DPRINTF("%s\n", __func__);
    return 0;
}

int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
{
    DPRINTF("%s\n", __func__);
    return 0;
}

static inline int cpu_mips_io_interrupts_pending(MIPSCPU *cpu)
{
    CPUMIPSState *env = &cpu->env;

    return env->CP0_Cause & (0x1 << (2 + CP0Ca_IP));
}


void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
{
    MIPSCPU *cpu = MIPS_CPU(cs);
    int r;
    struct kvm_mips_interrupt intr;

    qemu_mutex_lock_iothread();

    if ((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
            cpu_mips_io_interrupts_pending(cpu)) {
        intr.cpu = -1;
        intr.irq = 2;
        r = kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr);
        if (r < 0) {
            error_report("%s: cpu %d: failed to inject IRQ %x",
                         __func__, cs->cpu_index, intr.irq);
        }
    }

    qemu_mutex_unlock_iothread();
}

MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
{
    return MEMTXATTRS_UNSPECIFIED;
}

int kvm_arch_process_async_events(CPUState *cs)
{
    return cs->halted;
}

int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
{
    int ret;

    DPRINTF("%s\n", __func__);
    switch (run->exit_reason) {
    default:
        error_report("%s: unknown exit reason %d",
                     __func__, run->exit_reason);
        ret = -1;
        break;
    }

    return ret;
}

bool kvm_arch_stop_on_emulation_error(CPUState *cs)
{
    DPRINTF("%s\n", __func__);
    return true;
}

int kvm_arch_on_sigbus_vcpu(CPUState *cs, int code, void *addr)
{
    DPRINTF("%s\n", __func__);
    return 1;
}

int kvm_arch_on_sigbus(int code, void *addr)
{
    DPRINTF("%s\n", __func__);
    return 1;
}

void kvm_arch_init_irq_routing(KVMState *s)
{
}

int kvm_mips_set_interrupt(MIPSCPU *cpu, int irq, int level)
{
    CPUState *cs = CPU(cpu);
    struct kvm_mips_interrupt intr;

    if (!kvm_enabled()) {
        return 0;
    }

    intr.cpu = -1;

    if (level) {
        intr.irq = irq;
    } else {
        intr.irq = -irq;
    }

    kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr);

    return 0;
}

int kvm_mips_set_ipi_interrupt(MIPSCPU *cpu, int irq, int level)
{
    CPUState *cs = current_cpu;
    CPUState *dest_cs = CPU(cpu);
    struct kvm_mips_interrupt intr;

    if (!kvm_enabled()) {
        return 0;
    }

    intr.cpu = dest_cs->cpu_index;

    if (level) {
        intr.irq = irq;
    } else {
        intr.irq = -irq;
    }

    DPRINTF("%s: CPU %d, IRQ: %d\n", __func__, intr.cpu, intr.irq);

    kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr);

    return 0;
}

#define MIPS_CP0_32(_R, _S)                                     \
    (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U32 | (8 * (_R) + (_S)))

#define MIPS_CP0_64(_R, _S)                                     \
    (KVM_REG_MIPS_CP0 | KVM_REG_SIZE_U64 | (8 * (_R) + (_S)))

#define KVM_REG_MIPS_CP0_INDEX          MIPS_CP0_32(0, 0)
#define KVM_REG_MIPS_CP0_CONTEXT        MIPS_CP0_64(4, 0)
#define KVM_REG_MIPS_CP0_USERLOCAL      MIPS_CP0_64(4, 2)
#define KVM_REG_MIPS_CP0_PAGEMASK       MIPS_CP0_32(5, 0)
#define KVM_REG_MIPS_CP0_WIRED          MIPS_CP0_32(6, 0)
#define KVM_REG_MIPS_CP0_HWRENA         MIPS_CP0_32(7, 0)
#define KVM_REG_MIPS_CP0_BADVADDR       MIPS_CP0_64(8, 0)
#define KVM_REG_MIPS_CP0_COUNT          MIPS_CP0_32(9, 0)
#define KVM_REG_MIPS_CP0_ENTRYHI        MIPS_CP0_64(10, 0)
#define KVM_REG_MIPS_CP0_COMPARE        MIPS_CP0_32(11, 0)
#define KVM_REG_MIPS_CP0_STATUS         MIPS_CP0_32(12, 0)
#define KVM_REG_MIPS_CP0_CAUSE          MIPS_CP0_32(13, 0)
#define KVM_REG_MIPS_CP0_EPC            MIPS_CP0_64(14, 0)
#define KVM_REG_MIPS_CP0_PRID           MIPS_CP0_32(15, 0)
#define KVM_REG_MIPS_CP0_CONFIG         MIPS_CP0_32(16, 0)
#define KVM_REG_MIPS_CP0_CONFIG1        MIPS_CP0_32(16, 1)
#define KVM_REG_MIPS_CP0_CONFIG2        MIPS_CP0_32(16, 2)
#define KVM_REG_MIPS_CP0_CONFIG3        MIPS_CP0_32(16, 3)
#define KVM_REG_MIPS_CP0_CONFIG4        MIPS_CP0_32(16, 4)
#define KVM_REG_MIPS_CP0_CONFIG5        MIPS_CP0_32(16, 5)
#define KVM_REG_MIPS_CP0_ERROREPC       MIPS_CP0_64(30, 0)

static inline int kvm_mips_put_one_reg(CPUState *cs, uint64_t reg_id,
                                       int32_t *addr)
{
    struct kvm_one_reg cp0reg = {
        .id = reg_id,
        .addr = (uintptr_t)addr
    };

    return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
}

static inline int kvm_mips_put_one_ureg(CPUState *cs, uint64_t reg_id,
                                        uint32_t *addr)
{
    struct kvm_one_reg cp0reg = {
        .id = reg_id,
        .addr = (uintptr_t)addr
    };

    return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
}

static inline int kvm_mips_put_one_ulreg(CPUState *cs, uint64_t reg_id,
                                         target_ulong *addr)
{
    uint64_t val64 = *addr;
    struct kvm_one_reg cp0reg = {
        .id = reg_id,
        .addr = (uintptr_t)&val64
    };

    return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
}

static inline int kvm_mips_put_one_reg64(CPUState *cs, uint64_t reg_id,
                                         int64_t *addr)
{
    struct kvm_one_reg cp0reg = {
        .id = reg_id,
        .addr = (uintptr_t)addr
    };

    return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
}

static inline int kvm_mips_put_one_ureg64(CPUState *cs, uint64_t reg_id,
                                          uint64_t *addr)
{
    struct kvm_one_reg cp0reg = {
        .id = reg_id,
        .addr = (uintptr_t)addr
    };

    return kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, &cp0reg);
}

static inline int kvm_mips_get_one_reg(CPUState *cs, uint64_t reg_id,
                                       int32_t *addr)
{
    struct kvm_one_reg cp0reg = {
        .id = reg_id,
        .addr = (uintptr_t)addr
    };

    return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
}

static inline int kvm_mips_get_one_ureg(CPUState *cs, uint64_t reg_id,
                                        uint32_t *addr)
{
    struct kvm_one_reg cp0reg = {
        .id = reg_id,
        .addr = (uintptr_t)addr
    };

    return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
}

static inline int kvm_mips_get_one_ulreg(CPUState *cs, uint64_t reg_id,
                                         target_ulong *addr)
{
    int ret;
    uint64_t val64 = 0;
    struct kvm_one_reg cp0reg = {
        .id = reg_id,
        .addr = (uintptr_t)&val64
    };

    ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
    if (ret >= 0) {
        *addr = val64;
    }
    return ret;
}

static inline int kvm_mips_get_one_reg64(CPUState *cs, uint64_t reg_id,
                                         int64_t *addr)
{
    struct kvm_one_reg cp0reg = {
        .id = reg_id,
        .addr = (uintptr_t)addr
    };

    return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
}

static inline int kvm_mips_get_one_ureg64(CPUState *cs, uint64_t reg_id,
                                          uint64_t *addr)
{
    struct kvm_one_reg cp0reg = {
        .id = reg_id,
        .addr = (uintptr_t)addr
    };

    return kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, &cp0reg);
}

#define KVM_REG_MIPS_CP0_CONFIG_MASK    (1U << CP0C0_M)
#define KVM_REG_MIPS_CP0_CONFIG1_MASK   ((1U << CP0C1_M) | \
                                         (1U << CP0C1_FP))
#define KVM_REG_MIPS_CP0_CONFIG2_MASK   (1U << CP0C2_M)
#define KVM_REG_MIPS_CP0_CONFIG3_MASK   ((1U << CP0C3_M) | \
                                         (1U << CP0C3_MSAP))
#define KVM_REG_MIPS_CP0_CONFIG4_MASK   (1U << CP0C4_M)
#define KVM_REG_MIPS_CP0_CONFIG5_MASK   ((1U << CP0C5_MSAEn) | \
                                         (1U << CP0C5_UFE) | \
                                         (1U << CP0C5_FRE) | \
                                         (1U << CP0C5_UFR))

static inline int kvm_mips_change_one_reg(CPUState *cs, uint64_t reg_id,
                                          int32_t *addr, int32_t mask)
{
    int err;
    int32_t tmp, change;

    err = kvm_mips_get_one_reg(cs, reg_id, &tmp);
    if (err < 0) {
        return err;
    }

    /* only change bits in mask */
    change = (*addr ^ tmp) & mask;
    if (!change) {
        return 0;
    }

    tmp = tmp ^ change;
    return kvm_mips_put_one_reg(cs, reg_id, &tmp);
}

/*
 * We freeze the KVM timer when either the VM clock is stopped or the state is
 * saved (the state is dirty).
 */

/*
 * Save the state of the KVM timer when VM clock is stopped or state is synced
 * to QEMU.
 */
static int kvm_mips_save_count(CPUState *cs)
{
    MIPSCPU *cpu = MIPS_CPU(cs);
    CPUMIPSState *env = &cpu->env;
    uint64_t count_ctl;
    int err, ret = 0;

    /* freeze KVM timer */
    err = kvm_mips_get_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
    if (err < 0) {
        DPRINTF("%s: Failed to get COUNT_CTL (%d)\n", __func__, err);
        ret = err;
    } else if (!(count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)) {
        count_ctl |= KVM_REG_MIPS_COUNT_CTL_DC;
        err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
        if (err < 0) {
            DPRINTF("%s: Failed to set COUNT_CTL.DC=1 (%d)\n", __func__, err);
            ret = err;
        }
    }

    /* read CP0_Cause */
    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CAUSE, &env->CP0_Cause);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_CAUSE (%d)\n", __func__, err);
        ret = err;
    }

    /* read CP0_Count */
    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_COUNT, &env->CP0_Count);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_COUNT (%d)\n", __func__, err);
        ret = err;
    }

    return ret;
}

/*
 * Restore the state of the KVM timer when VM clock is restarted or state is
 * synced to KVM.
 */
static int kvm_mips_restore_count(CPUState *cs)
{
    MIPSCPU *cpu = MIPS_CPU(cs);
    CPUMIPSState *env = &cpu->env;
    uint64_t count_ctl;
    int err_dc, err, ret = 0;

    /* check the timer is frozen */
    err_dc = kvm_mips_get_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
    if (err_dc < 0) {
        DPRINTF("%s: Failed to get COUNT_CTL (%d)\n", __func__, err_dc);
        ret = err_dc;
    } else if (!(count_ctl & KVM_REG_MIPS_COUNT_CTL_DC)) {
        /* freeze timer (sets COUNT_RESUME for us) */
        count_ctl |= KVM_REG_MIPS_COUNT_CTL_DC;
        err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
        if (err < 0) {
            DPRINTF("%s: Failed to set COUNT_CTL.DC=1 (%d)\n", __func__, err);
            ret = err;
        }
    }

    /* load CP0_Cause */
    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_CAUSE, &env->CP0_Cause);
    if (err < 0) {
        DPRINTF("%s: Failed to put CP0_CAUSE (%d)\n", __func__, err);
        ret = err;
    }

    /* load CP0_Count */
    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_COUNT, &env->CP0_Count);
    if (err < 0) {
        DPRINTF("%s: Failed to put CP0_COUNT (%d)\n", __func__, err);
        ret = err;
    }

    /* resume KVM timer */
    if (err_dc >= 0) {
        count_ctl &= ~KVM_REG_MIPS_COUNT_CTL_DC;
        err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_CTL, &count_ctl);
        if (err < 0) {
            DPRINTF("%s: Failed to set COUNT_CTL.DC=0 (%d)\n", __func__, err);
            ret = err;
        }
    }

    return ret;
}

/*
 * Handle the VM clock being started or stopped
 */
static void kvm_mips_update_state(void *opaque, int running, RunState state)
{
    CPUState *cs = opaque;
    int ret;
    uint64_t count_resume;

    /*
     * If state is already dirty (synced to QEMU) then the KVM timer state is
     * already saved and can be restored when it is synced back to KVM.
     */
    if (!running) {
        if (!cs->kvm_vcpu_dirty) {
            ret = kvm_mips_save_count(cs);
            if (ret < 0) {
                fprintf(stderr, "Failed saving count\n");
            }
        }
    } else {
        /* Set clock restore time to now */
        count_resume = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
        ret = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_COUNT_RESUME,
                                      &count_resume);
        if (ret < 0) {
            fprintf(stderr, "Failed setting COUNT_RESUME\n");
            return;
        }

        if (!cs->kvm_vcpu_dirty) {
            ret = kvm_mips_restore_count(cs);
            if (ret < 0) {
                fprintf(stderr, "Failed restoring count\n");
            }
        }
    }
}

static int kvm_mips_put_fpu_registers(CPUState *cs, int level)
{
    MIPSCPU *cpu = MIPS_CPU(cs);
    CPUMIPSState *env = &cpu->env;
    int err, ret = 0;
    unsigned int i;

    /* Only put FPU state if we're emulating a CPU with an FPU */
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
        /* FPU Control Registers */
        if (level == KVM_PUT_FULL_STATE) {
            err = kvm_mips_put_one_ureg(cs, KVM_REG_MIPS_FCR_IR,
                                        &env->active_fpu.fcr0);
            if (err < 0) {
                DPRINTF("%s: Failed to put FCR_IR (%d)\n", __func__, err);
                ret = err;
            }
        }
        err = kvm_mips_put_one_ureg(cs, KVM_REG_MIPS_FCR_CSR,
                                    &env->active_fpu.fcr31);
        if (err < 0) {
            DPRINTF("%s: Failed to put FCR_CSR (%d)\n", __func__, err);
            ret = err;
        }

        /*
         * FPU register state is a subset of MSA vector state, so don't put FPU
         * registers if we're emulating a CPU with MSA.
         */
        if (!(env->CP0_Config3 & (1 << CP0C3_MSAP))) {
            /* Floating point registers */
            for (i = 0; i < 32; ++i) {
                if (env->CP0_Status & (1 << CP0St_FR)) {
                    err = kvm_mips_put_one_ureg64(cs, KVM_REG_MIPS_FPR_64(i),
                                                  &env->active_fpu.fpr[i].d);
                } else {
                    err = kvm_mips_get_one_ureg(cs, KVM_REG_MIPS_FPR_32(i),
                                    &env->active_fpu.fpr[i].w[FP_ENDIAN_IDX]);
                }
                if (err < 0) {
                    DPRINTF("%s: Failed to put FPR%u (%d)\n", __func__, i, err);
                    ret = err;
                }
            }
        }
    }

    /* Only put MSA state if we're emulating a CPU with MSA */
    if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
        /* MSA Control Registers */
        if (level == KVM_PUT_FULL_STATE) {
            err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_MSA_IR,
                                       &env->msair);
            if (err < 0) {
                DPRINTF("%s: Failed to put MSA_IR (%d)\n", __func__, err);
                ret = err;
            }
        }
        err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_MSA_CSR,
                                   &env->active_tc.msacsr);
        if (err < 0) {
            DPRINTF("%s: Failed to put MSA_CSR (%d)\n", __func__, err);
            ret = err;
        }

        /* Vector registers (includes FP registers) */
        for (i = 0; i < 32; ++i) {
            /* Big endian MSA not supported by QEMU yet anyway */
            err = kvm_mips_put_one_reg64(cs, KVM_REG_MIPS_VEC_128(i),
                                         env->active_fpu.fpr[i].wr.d);
            if (err < 0) {
                DPRINTF("%s: Failed to put VEC%u (%d)\n", __func__, i, err);
                ret = err;
            }
        }
    }

    return ret;
}

static int kvm_mips_get_fpu_registers(CPUState *cs)
{
    MIPSCPU *cpu = MIPS_CPU(cs);
    CPUMIPSState *env = &cpu->env;
    int err, ret = 0;
    unsigned int i;

    /* Only get FPU state if we're emulating a CPU with an FPU */
    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
        /* FPU Control Registers */
        err = kvm_mips_get_one_ureg(cs, KVM_REG_MIPS_FCR_IR,
                                    &env->active_fpu.fcr0);
        if (err < 0) {
            DPRINTF("%s: Failed to get FCR_IR (%d)\n", __func__, err);
            ret = err;
        }
        err = kvm_mips_get_one_ureg(cs, KVM_REG_MIPS_FCR_CSR,
                                    &env->active_fpu.fcr31);
        if (err < 0) {
            DPRINTF("%s: Failed to get FCR_CSR (%d)\n", __func__, err);
            ret = err;
        } else {
            restore_fp_status(env);
        }

        /*
         * FPU register state is a subset of MSA vector state, so don't save FPU
         * registers if we're emulating a CPU with MSA.
         */
        if (!(env->CP0_Config3 & (1 << CP0C3_MSAP))) {
            /* Floating point registers */
            for (i = 0; i < 32; ++i) {
                if (env->CP0_Status & (1 << CP0St_FR)) {
                    err = kvm_mips_get_one_ureg64(cs, KVM_REG_MIPS_FPR_64(i),
                                                  &env->active_fpu.fpr[i].d);
                } else {
                    err = kvm_mips_get_one_ureg(cs, KVM_REG_MIPS_FPR_32(i),
                                    &env->active_fpu.fpr[i].w[FP_ENDIAN_IDX]);
                }
                if (err < 0) {
                    DPRINTF("%s: Failed to get FPR%u (%d)\n", __func__, i, err);
                    ret = err;
                }
            }
        }
    }

    /* Only get MSA state if we're emulating a CPU with MSA */
    if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
        /* MSA Control Registers */
        err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_MSA_IR,
                                   &env->msair);
        if (err < 0) {
            DPRINTF("%s: Failed to get MSA_IR (%d)\n", __func__, err);
            ret = err;
        }
        err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_MSA_CSR,
                                   &env->active_tc.msacsr);
        if (err < 0) {
            DPRINTF("%s: Failed to get MSA_CSR (%d)\n", __func__, err);
            ret = err;
        } else {
            restore_msa_fp_status(env);
        }

        /* Vector registers (includes FP registers) */
        for (i = 0; i < 32; ++i) {
            /* Big endian MSA not supported by QEMU yet anyway */
            err = kvm_mips_get_one_reg64(cs, KVM_REG_MIPS_VEC_128(i),
                                         env->active_fpu.fpr[i].wr.d);
            if (err < 0) {
                DPRINTF("%s: Failed to get VEC%u (%d)\n", __func__, i, err);
                ret = err;
            }
        }
    }

    return ret;
}


static int kvm_mips_put_cp0_registers(CPUState *cs, int level)
{
    MIPSCPU *cpu = MIPS_CPU(cs);
    CPUMIPSState *env = &cpu->env;
    int err, ret = 0;

    (void)level;

    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_INDEX, &env->CP0_Index);
    if (err < 0) {
        DPRINTF("%s: Failed to put CP0_INDEX (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_CONTEXT,
                                 &env->CP0_Context);
    if (err < 0) {
        DPRINTF("%s: Failed to put CP0_CONTEXT (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_USERLOCAL,
                                 &env->active_tc.CP0_UserLocal);
    if (err < 0) {
        DPRINTF("%s: Failed to put CP0_USERLOCAL (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PAGEMASK,
                               &env->CP0_PageMask);
    if (err < 0) {
        DPRINTF("%s: Failed to put CP0_PAGEMASK (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_WIRED, &env->CP0_Wired);
    if (err < 0) {
        DPRINTF("%s: Failed to put CP0_WIRED (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_HWRENA, &env->CP0_HWREna);
    if (err < 0) {
        DPRINTF("%s: Failed to put CP0_HWRENA (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_BADVADDR,
                                 &env->CP0_BadVAddr);
    if (err < 0) {
        DPRINTF("%s: Failed to put CP0_BADVADDR (%d)\n", __func__, err);
        ret = err;
    }

    /* If VM clock stopped then state will be restored when it is restarted */
    if (runstate_is_running()) {
        err = kvm_mips_restore_count(cs);
        if (err < 0) {
            ret = err;
        }
    }

    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_ENTRYHI,
                                 &env->CP0_EntryHi);
    if (err < 0) {
        DPRINTF("%s: Failed to put CP0_ENTRYHI (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_COMPARE,
                               &env->CP0_Compare);
    if (err < 0) {
        DPRINTF("%s: Failed to put CP0_COMPARE (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_STATUS, &env->CP0_Status);
    if (err < 0) {
        DPRINTF("%s: Failed to put CP0_STATUS (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_EPC, &env->CP0_EPC);
    if (err < 0) {
        DPRINTF("%s: Failed to put CP0_EPC (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_put_one_reg(cs, KVM_REG_MIPS_CP0_PRID, &env->CP0_PRid);
    if (err < 0) {
        DPRINTF("%s: Failed to put CP0_PRID (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG,
                                  &env->CP0_Config0,
                                  KVM_REG_MIPS_CP0_CONFIG_MASK);
    if (err < 0) {
        DPRINTF("%s: Failed to change CP0_CONFIG (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG1,
                                  &env->CP0_Config1,
                                  KVM_REG_MIPS_CP0_CONFIG1_MASK);
    if (err < 0) {
        DPRINTF("%s: Failed to change CP0_CONFIG1 (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG2,
                                  &env->CP0_Config2,
                                  KVM_REG_MIPS_CP0_CONFIG2_MASK);
    if (err < 0) {
        DPRINTF("%s: Failed to change CP0_CONFIG2 (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG3,
                                  &env->CP0_Config3,
                                  KVM_REG_MIPS_CP0_CONFIG3_MASK);
    if (err < 0) {
        DPRINTF("%s: Failed to change CP0_CONFIG3 (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG4,
                                  &env->CP0_Config4,
                                  KVM_REG_MIPS_CP0_CONFIG4_MASK);
    if (err < 0) {
        DPRINTF("%s: Failed to change CP0_CONFIG4 (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_change_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG5,
                                  &env->CP0_Config5,
                                  KVM_REG_MIPS_CP0_CONFIG5_MASK);
    if (err < 0) {
        DPRINTF("%s: Failed to change CP0_CONFIG5 (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_put_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
                                 &env->CP0_ErrorEPC);
    if (err < 0) {
        DPRINTF("%s: Failed to put CP0_ERROREPC (%d)\n", __func__, err);
        ret = err;
    }

    return ret;
}

static int kvm_mips_get_cp0_registers(CPUState *cs)
{
    MIPSCPU *cpu = MIPS_CPU(cs);
    CPUMIPSState *env = &cpu->env;
    int err, ret = 0;

    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_INDEX, &env->CP0_Index);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_INDEX (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_CONTEXT,
                                 &env->CP0_Context);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_CONTEXT (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_USERLOCAL,
                                 &env->active_tc.CP0_UserLocal);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_USERLOCAL (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PAGEMASK,
                               &env->CP0_PageMask);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_PAGEMASK (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_WIRED, &env->CP0_Wired);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_WIRED (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_HWRENA, &env->CP0_HWREna);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_HWRENA (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_BADVADDR,
                                 &env->CP0_BadVAddr);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_BADVADDR (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_ENTRYHI,
                                 &env->CP0_EntryHi);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_ENTRYHI (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_COMPARE,
                               &env->CP0_Compare);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_COMPARE (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_STATUS, &env->CP0_Status);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_STATUS (%d)\n", __func__, err);
        ret = err;
    }

    /* If VM clock stopped then state was already saved when it was stopped */
    if (runstate_is_running()) {
        err = kvm_mips_save_count(cs);
        if (err < 0) {
            ret = err;
        }
    }

    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_EPC, &env->CP0_EPC);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_EPC (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_PRID, &env->CP0_PRid);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_PRID (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG, &env->CP0_Config0);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_CONFIG (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG1, &env->CP0_Config1);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_CONFIG1 (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG2, &env->CP0_Config2);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_CONFIG2 (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG3, &env->CP0_Config3);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_CONFIG3 (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG4, &env->CP0_Config4);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_CONFIG4 (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_reg(cs, KVM_REG_MIPS_CP0_CONFIG5, &env->CP0_Config5);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_CONFIG5 (%d)\n", __func__, err);
        ret = err;
    }
    err = kvm_mips_get_one_ulreg(cs, KVM_REG_MIPS_CP0_ERROREPC,
                                 &env->CP0_ErrorEPC);
    if (err < 0) {
        DPRINTF("%s: Failed to get CP0_ERROREPC (%d)\n", __func__, err);
        ret = err;
    }

    return ret;
}

int kvm_arch_put_registers(CPUState *cs, int level)
{
    MIPSCPU *cpu = MIPS_CPU(cs);
    CPUMIPSState *env = &cpu->env;
    struct kvm_regs regs;
    int ret;
    int i;

    /* Set the registers based on QEMU's view of things */
    for (i = 0; i < 32; i++) {
        regs.gpr[i] = (int64_t)(target_long)env->active_tc.gpr[i];
    }

    regs.hi = (int64_t)(target_long)env->active_tc.HI[0];
    regs.lo = (int64_t)(target_long)env->active_tc.LO[0];
    regs.pc = (int64_t)(target_long)env->active_tc.PC;

    ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, &regs);

    if (ret < 0) {
        return ret;
    }

    ret = kvm_mips_put_cp0_registers(cs, level);
    if (ret < 0) {
        return ret;
    }

    ret = kvm_mips_put_fpu_registers(cs, level);
    if (ret < 0) {
        return ret;
    }

    return ret;
}

int kvm_arch_get_registers(CPUState *cs)
{
    MIPSCPU *cpu = MIPS_CPU(cs);
    CPUMIPSState *env = &cpu->env;
    int ret = 0;
    struct kvm_regs regs;
    int i;

    /* Get the current register set as KVM seems it */
    ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);

    if (ret < 0) {
        return ret;
    }

    for (i = 0; i < 32; i++) {
        env->active_tc.gpr[i] = regs.gpr[i];
    }

    env->active_tc.HI[0] = regs.hi;
    env->active_tc.LO[0] = regs.lo;
    env->active_tc.PC = regs.pc;

    kvm_mips_get_cp0_registers(cs);
    kvm_mips_get_fpu_registers(cs);

    return ret;
}

int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
                             uint64_t address, uint32_t data, PCIDevice *dev)
{
    return 0;
}

int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
                                int vector, PCIDevice *dev)
{
    return 0;
}

int kvm_arch_release_virq_post(int virq)
{
    return 0;
}

int kvm_arch_msi_data_to_gsi(uint32_t data)
{
    abort();
}
