/*
 * 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_irqchip_create(MachineState *ms, KVMState *s)
{
    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;
}

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();
}
