/*
 * RISC-V Emulation Helpers for QEMU.
 *
 * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu
 * Copyright (c) 2017-2018 SiFive, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2 or later, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/log.h"
#include "cpu.h"
#include "qemu/main-loop.h"
#include "exec/exec-all.h"
#include "exec/helper-proto.h"

#ifndef CONFIG_USER_ONLY

#if defined(TARGET_RISCV32)
static const char valid_vm_1_09[16] = {
    [VM_1_09_MBARE] = 1,
    [VM_1_09_SV32] = 1,
};
static const char valid_vm_1_10[16] = {
    [VM_1_10_MBARE] = 1,
    [VM_1_10_SV32] = 1
};
#elif defined(TARGET_RISCV64)
static const char valid_vm_1_09[16] = {
    [VM_1_09_MBARE] = 1,
    [VM_1_09_SV39] = 1,
    [VM_1_09_SV48] = 1,
};
static const char valid_vm_1_10[16] = {
    [VM_1_10_MBARE] = 1,
    [VM_1_10_SV39] = 1,
    [VM_1_10_SV48] = 1,
    [VM_1_10_SV57] = 1
};
#endif

static int validate_vm(CPURISCVState *env, target_ulong vm)
{
    return (env->priv_ver >= PRIV_VERSION_1_10_0) ?
        valid_vm_1_10[vm & 0xf] : valid_vm_1_09[vm & 0xf];
}

#endif

/* Exceptions processing helpers */
void QEMU_NORETURN do_raise_exception_err(CPURISCVState *env,
                                          uint32_t exception, uintptr_t pc)
{
    CPUState *cs = CPU(riscv_env_get_cpu(env));
    qemu_log_mask(CPU_LOG_INT, "%s: %d\n", __func__, exception);
    cs->exception_index = exception;
    cpu_loop_exit_restore(cs, pc);
}

void helper_raise_exception(CPURISCVState *env, uint32_t exception)
{
    do_raise_exception_err(env, exception, 0);
}

static void validate_mstatus_fs(CPURISCVState *env, uintptr_t ra)
{
#ifndef CONFIG_USER_ONLY
    if (!(env->mstatus & MSTATUS_FS)) {
        do_raise_exception_err(env, RISCV_EXCP_ILLEGAL_INST, ra);
    }
#endif
}

/*
 * Handle writes to CSRs and any resulting special behavior
 *
 * Adapted from Spike's processor_t::set_csr
 */
void csr_write_helper(CPURISCVState *env, target_ulong val_to_write,
        target_ulong csrno)
{
#ifndef CONFIG_USER_ONLY
    uint64_t delegable_ints = MIP_SSIP | MIP_STIP | MIP_SEIP | (1 << IRQ_X_COP);
    uint64_t all_ints = delegable_ints | MIP_MSIP | MIP_MTIP;
#endif

    switch (csrno) {
    case CSR_FFLAGS:
        validate_mstatus_fs(env, GETPC());
        cpu_riscv_set_fflags(env, val_to_write & (FSR_AEXC >> FSR_AEXC_SHIFT));
        break;
    case CSR_FRM:
        validate_mstatus_fs(env, GETPC());
        env->frm = val_to_write & (FSR_RD >> FSR_RD_SHIFT);
        break;
    case CSR_FCSR:
        validate_mstatus_fs(env, GETPC());
        env->frm = (val_to_write & FSR_RD) >> FSR_RD_SHIFT;
        cpu_riscv_set_fflags(env, (val_to_write & FSR_AEXC) >> FSR_AEXC_SHIFT);
        break;
#ifndef CONFIG_USER_ONLY
    case CSR_MSTATUS: {
        target_ulong mstatus = env->mstatus;
        target_ulong mask = 0;
        target_ulong mpp = get_field(val_to_write, MSTATUS_MPP);

        /* flush tlb on mstatus fields that affect VM */
        if (env->priv_ver <= PRIV_VERSION_1_09_1) {
            if ((val_to_write ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP |
                    MSTATUS_MPRV | MSTATUS_SUM | MSTATUS_VM)) {
                helper_tlb_flush(env);
            }
            mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
                MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
                MSTATUS_MPP | MSTATUS_MXR |
                (validate_vm(env, get_field(val_to_write, MSTATUS_VM)) ?
                    MSTATUS_VM : 0);
        }
        if (env->priv_ver >= PRIV_VERSION_1_10_0) {
            if ((val_to_write ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP |
                    MSTATUS_MPRV | MSTATUS_SUM)) {
                helper_tlb_flush(env);
            }
            mask = MSTATUS_SIE | MSTATUS_SPIE | MSTATUS_MIE | MSTATUS_MPIE |
                MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
                MSTATUS_MPP | MSTATUS_MXR;
        }

        /* silenty discard mstatus.mpp writes for unsupported modes */
        if (mpp == PRV_H ||
            (!riscv_has_ext(env, RVS) && mpp == PRV_S) ||
            (!riscv_has_ext(env, RVU) && mpp == PRV_U)) {
            mask &= ~MSTATUS_MPP;
        }

        mstatus = (mstatus & ~mask) | (val_to_write & mask);

        /* Note: this is a workaround for an issue where mstatus.FS
           does not report dirty after floating point operations
           that modify floating point state. This workaround is
           technically compliant with the RISC-V Privileged
           specification as it is legal to return only off, or dirty.
           at the expense of extra floating point save/restore. */

        /* FP is always dirty or off */
        if (mstatus & MSTATUS_FS) {
            mstatus |= MSTATUS_FS;
        }

        int dirty = ((mstatus & MSTATUS_FS) == MSTATUS_FS) |
                    ((mstatus & MSTATUS_XS) == MSTATUS_XS);
        mstatus = set_field(mstatus, MSTATUS_SD, dirty);
        env->mstatus = mstatus;
        break;
    }
    case CSR_MIP: {
        /*
         * Since the writeable bits in MIP are not set asynchrously by the
         * CLINT, no additional locking is needed for read-modifiy-write
         * CSR operations
         */
        qemu_mutex_lock_iothread();
        RISCVCPU *cpu = riscv_env_get_cpu(env);
        riscv_set_local_interrupt(cpu, MIP_SSIP,
                                  (val_to_write & MIP_SSIP) != 0);
        riscv_set_local_interrupt(cpu, MIP_STIP,
                                  (val_to_write & MIP_STIP) != 0);
        /*
         * csrs, csrc on mip.SEIP is not decomposable into separate read and
         * write steps, so a different implementation is needed
         */
        qemu_mutex_unlock_iothread();
        break;
    }
    case CSR_MIE: {
        env->mie = (env->mie & ~all_ints) |
            (val_to_write & all_ints);
        break;
    }
    case CSR_MIDELEG:
        env->mideleg = (env->mideleg & ~delegable_ints)
                                | (val_to_write & delegable_ints);
        break;
    case CSR_MEDELEG: {
        target_ulong mask = 0;
        mask |= 1ULL << (RISCV_EXCP_INST_ADDR_MIS);
        mask |= 1ULL << (RISCV_EXCP_INST_ACCESS_FAULT);
        mask |= 1ULL << (RISCV_EXCP_ILLEGAL_INST);
        mask |= 1ULL << (RISCV_EXCP_BREAKPOINT);
        mask |= 1ULL << (RISCV_EXCP_LOAD_ADDR_MIS);
        mask |= 1ULL << (RISCV_EXCP_LOAD_ACCESS_FAULT);
        mask |= 1ULL << (RISCV_EXCP_STORE_AMO_ADDR_MIS);
        mask |= 1ULL << (RISCV_EXCP_STORE_AMO_ACCESS_FAULT);
        mask |= 1ULL << (RISCV_EXCP_U_ECALL);
        mask |= 1ULL << (RISCV_EXCP_S_ECALL);
        mask |= 1ULL << (RISCV_EXCP_H_ECALL);
        mask |= 1ULL << (RISCV_EXCP_M_ECALL);
        mask |= 1ULL << (RISCV_EXCP_INST_PAGE_FAULT);
        mask |= 1ULL << (RISCV_EXCP_LOAD_PAGE_FAULT);
        mask |= 1ULL << (RISCV_EXCP_STORE_PAGE_FAULT);
        env->medeleg = (env->medeleg & ~mask)
                                | (val_to_write & mask);
        break;
    }
    case CSR_MINSTRET:
        /* minstret is WARL so unsupported writes are ignored */
        break;
    case CSR_MCYCLE:
        /* mcycle is WARL so unsupported writes are ignored */
        break;
#if defined(TARGET_RISCV32)
    case CSR_MINSTRETH:
        /* minstreth is WARL so unsupported writes are ignored */
        break;
    case CSR_MCYCLEH:
        /* mcycleh is WARL so unsupported writes are ignored */
        break;
#endif
    case CSR_MUCOUNTEREN:
        if (env->priv_ver <= PRIV_VERSION_1_09_1) {
            env->scounteren = val_to_write;
            break;
        } else {
            goto do_illegal;
        }
    case CSR_MSCOUNTEREN:
        if (env->priv_ver <= PRIV_VERSION_1_09_1) {
            env->mcounteren = val_to_write;
            break;
        } else {
            goto do_illegal;
        }
    case CSR_SSTATUS: {
        target_ulong ms = env->mstatus;
        target_ulong mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_UIE
            | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS
            | SSTATUS_SUM | SSTATUS_SD;
        if (env->priv_ver >= PRIV_VERSION_1_10_0) {
            mask |= SSTATUS_MXR;
        }
        ms = (ms & ~mask) | (val_to_write & mask);
        csr_write_helper(env, ms, CSR_MSTATUS);
        break;
    }
    case CSR_SIP: {
        qemu_mutex_lock_iothread();
        target_ulong next_mip = (env->mip & ~env->mideleg)
                                | (val_to_write & env->mideleg);
        qemu_mutex_unlock_iothread();
        csr_write_helper(env, next_mip, CSR_MIP);
        break;
    }
    case CSR_SIE: {
        target_ulong next_mie = (env->mie & ~env->mideleg)
                                | (val_to_write & env->mideleg);
        csr_write_helper(env, next_mie, CSR_MIE);
        break;
    }
    case CSR_SATP: /* CSR_SPTBR */ {
        if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
            break;
        }
        if (env->priv_ver <= PRIV_VERSION_1_09_1 && (val_to_write ^ env->sptbr))
        {
            helper_tlb_flush(env);
            env->sptbr = val_to_write & (((target_ulong)
                1 << (TARGET_PHYS_ADDR_SPACE_BITS - PGSHIFT)) - 1);
        }
        if (env->priv_ver >= PRIV_VERSION_1_10_0 &&
            validate_vm(env, get_field(val_to_write, SATP_MODE)) &&
            ((val_to_write ^ env->satp) & (SATP_MODE | SATP_ASID | SATP_PPN)))
        {
            helper_tlb_flush(env);
            env->satp = val_to_write;
        }
        break;
    }
    case CSR_SEPC:
        env->sepc = val_to_write;
        break;
    case CSR_STVEC:
        /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */
        if ((val_to_write & 3) == 0) {
            env->stvec = val_to_write >> 2 << 2;
        } else {
            qemu_log_mask(LOG_UNIMP,
                          "CSR_STVEC: vectored traps not supported\n");
        }
        break;
    case CSR_SCOUNTEREN:
        if (env->priv_ver >= PRIV_VERSION_1_10_0) {
            env->scounteren = val_to_write;
            break;
        } else {
            goto do_illegal;
        }
    case CSR_SSCRATCH:
        env->sscratch = val_to_write;
        break;
    case CSR_SCAUSE:
        env->scause = val_to_write;
        break;
    case CSR_SBADADDR:
        env->sbadaddr = val_to_write;
        break;
    case CSR_MEPC:
        env->mepc = val_to_write;
        break;
    case CSR_MTVEC:
        /* bits [1:0] indicate mode; 0 = direct, 1 = vectored, 2 >= reserved */
        if ((val_to_write & 3) == 0) {
            env->mtvec = val_to_write >> 2 << 2;
        } else {
            qemu_log_mask(LOG_UNIMP,
                          "CSR_MTVEC: vectored traps not supported\n");
        }
        break;
    case CSR_MCOUNTEREN:
        if (env->priv_ver >= PRIV_VERSION_1_10_0) {
            env->mcounteren = val_to_write;
            break;
        } else {
            goto do_illegal;
        }
    case CSR_MSCRATCH:
        env->mscratch = val_to_write;
        break;
    case CSR_MCAUSE:
        env->mcause = val_to_write;
        break;
    case CSR_MBADADDR:
        env->mbadaddr = val_to_write;
        break;
    case CSR_MISA:
        /* misa is WARL so unsupported writes are ignored */
        break;
    case CSR_PMPCFG0:
    case CSR_PMPCFG1:
    case CSR_PMPCFG2:
    case CSR_PMPCFG3:
       pmpcfg_csr_write(env, csrno - CSR_PMPCFG0, val_to_write);
       break;
    case CSR_PMPADDR0:
    case CSR_PMPADDR1:
    case CSR_PMPADDR2:
    case CSR_PMPADDR3:
    case CSR_PMPADDR4:
    case CSR_PMPADDR5:
    case CSR_PMPADDR6:
    case CSR_PMPADDR7:
    case CSR_PMPADDR8:
    case CSR_PMPADDR9:
    case CSR_PMPADDR10:
    case CSR_PMPADDR11:
    case CSR_PMPADDR12:
    case CSR_PMPADDR13:
    case CSR_PMPADDR14:
    case CSR_PMPADDR15:
       pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val_to_write);
       break;
#endif
#if !defined(CONFIG_USER_ONLY)
    do_illegal:
#endif
    default:
        do_raise_exception_err(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
    }
}

/*
 * Handle reads to CSRs and any resulting special behavior
 *
 * Adapted from Spike's processor_t::get_csr
 */
target_ulong csr_read_helper(CPURISCVState *env, target_ulong csrno)
{
#ifndef CONFIG_USER_ONLY
    target_ulong ctr_en = env->priv == PRV_U ? env->scounteren :
                          env->priv == PRV_S ? env->mcounteren : -1U;
#else
    target_ulong ctr_en = -1;
#endif
    target_ulong ctr_ok = (ctr_en >> (csrno & 31)) & 1;

    if (csrno >= CSR_HPMCOUNTER3 && csrno <= CSR_HPMCOUNTER31) {
        if (ctr_ok) {
            return 0;
        }
    }
#if defined(TARGET_RISCV32)
    if (csrno >= CSR_HPMCOUNTER3H && csrno <= CSR_HPMCOUNTER31H) {
        if (ctr_ok) {
            return 0;
        }
    }
#endif
    if (csrno >= CSR_MHPMCOUNTER3 && csrno <= CSR_MHPMCOUNTER31) {
        return 0;
    }
#if defined(TARGET_RISCV32)
    if (csrno >= CSR_MHPMCOUNTER3 && csrno <= CSR_MHPMCOUNTER31) {
        return 0;
    }
#endif
    if (csrno >= CSR_MHPMEVENT3 && csrno <= CSR_MHPMEVENT31) {
        return 0;
    }

    switch (csrno) {
    case CSR_FFLAGS:
        validate_mstatus_fs(env, GETPC());
        return cpu_riscv_get_fflags(env);
    case CSR_FRM:
        validate_mstatus_fs(env, GETPC());
        return env->frm;
    case CSR_FCSR:
        validate_mstatus_fs(env, GETPC());
        return (cpu_riscv_get_fflags(env) << FSR_AEXC_SHIFT)
                | (env->frm << FSR_RD_SHIFT);
    /* rdtime/rdtimeh is trapped and emulated by bbl in system mode */
#ifdef CONFIG_USER_ONLY
    case CSR_TIME:
        return cpu_get_host_ticks();
#if defined(TARGET_RISCV32)
    case CSR_TIMEH:
        return cpu_get_host_ticks() >> 32;
#endif
#endif
    case CSR_INSTRET:
    case CSR_CYCLE:
        if (ctr_ok) {
#if !defined(CONFIG_USER_ONLY)
            if (use_icount) {
                return cpu_get_icount();
            } else {
                return cpu_get_host_ticks();
            }
#else
            return cpu_get_host_ticks();
#endif
        }
        break;
#if defined(TARGET_RISCV32)
    case CSR_INSTRETH:
    case CSR_CYCLEH:
        if (ctr_ok) {
#if !defined(CONFIG_USER_ONLY)
            if (use_icount) {
                return cpu_get_icount() >> 32;
            } else {
                return cpu_get_host_ticks() >> 32;
            }
#else
            return cpu_get_host_ticks() >> 32;
#endif
        }
        break;
#endif
#ifndef CONFIG_USER_ONLY
    case CSR_MINSTRET:
    case CSR_MCYCLE:
        if (use_icount) {
            return cpu_get_icount();
        } else {
            return cpu_get_host_ticks();
        }
    case CSR_MINSTRETH:
    case CSR_MCYCLEH:
#if defined(TARGET_RISCV32)
        if (use_icount) {
            return cpu_get_icount() >> 32;
        } else {
            return cpu_get_host_ticks() >> 32;
        }
#endif
        break;
    case CSR_MUCOUNTEREN:
        if (env->priv_ver <= PRIV_VERSION_1_09_1) {
            return env->scounteren;
        } else {
            break; /* illegal instruction */
        }
    case CSR_MSCOUNTEREN:
        if (env->priv_ver <= PRIV_VERSION_1_09_1) {
            return env->mcounteren;
        } else {
            break; /* illegal instruction */
        }
    case CSR_SSTATUS: {
        target_ulong mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_UIE
            | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS
            | SSTATUS_SUM | SSTATUS_SD;
        if (env->priv_ver >= PRIV_VERSION_1_10_0) {
            mask |= SSTATUS_MXR;
        }
        return env->mstatus & mask;
    }
    case CSR_SIP: {
        qemu_mutex_lock_iothread();
        target_ulong tmp = env->mip & env->mideleg;
        qemu_mutex_unlock_iothread();
        return tmp;
    }
    case CSR_SIE:
        return env->mie & env->mideleg;
    case CSR_SEPC:
        return env->sepc;
    case CSR_SBADADDR:
        return env->sbadaddr;
    case CSR_STVEC:
        return env->stvec;
    case CSR_SCOUNTEREN:
        if (env->priv_ver >= PRIV_VERSION_1_10_0) {
            return env->scounteren;
        } else {
            break; /* illegal instruction */
        }
    case CSR_SCAUSE:
        return env->scause;
    case CSR_SATP: /* CSR_SPTBR */
        if (!riscv_feature(env, RISCV_FEATURE_MMU)) {
            return 0;
        }
        if (env->priv_ver >= PRIV_VERSION_1_10_0) {
            return env->satp;
        } else {
            return env->sptbr;
        }
    case CSR_SSCRATCH:
        return env->sscratch;
    case CSR_MSTATUS:
        return env->mstatus;
    case CSR_MIP: {
        qemu_mutex_lock_iothread();
        target_ulong tmp = env->mip;
        qemu_mutex_unlock_iothread();
        return tmp;
    }
    case CSR_MIE:
        return env->mie;
    case CSR_MEPC:
        return env->mepc;
    case CSR_MSCRATCH:
        return env->mscratch;
    case CSR_MCAUSE:
        return env->mcause;
    case CSR_MBADADDR:
        return env->mbadaddr;
    case CSR_MISA:
        return env->misa;
    case CSR_MARCHID:
        return 0; /* as spike does */
    case CSR_MIMPID:
        return 0; /* as spike does */
    case CSR_MVENDORID:
        return 0; /* as spike does */
    case CSR_MHARTID:
        return env->mhartid;
    case CSR_MTVEC:
        return env->mtvec;
    case CSR_MCOUNTEREN:
        if (env->priv_ver >= PRIV_VERSION_1_10_0) {
            return env->mcounteren;
        } else {
            break; /* illegal instruction */
        }
    case CSR_MEDELEG:
        return env->medeleg;
    case CSR_MIDELEG:
        return env->mideleg;
    case CSR_PMPCFG0:
    case CSR_PMPCFG1:
    case CSR_PMPCFG2:
    case CSR_PMPCFG3:
       return pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
    case CSR_PMPADDR0:
    case CSR_PMPADDR1:
    case CSR_PMPADDR2:
    case CSR_PMPADDR3:
    case CSR_PMPADDR4:
    case CSR_PMPADDR5:
    case CSR_PMPADDR6:
    case CSR_PMPADDR7:
    case CSR_PMPADDR8:
    case CSR_PMPADDR9:
    case CSR_PMPADDR10:
    case CSR_PMPADDR11:
    case CSR_PMPADDR12:
    case CSR_PMPADDR13:
    case CSR_PMPADDR14:
    case CSR_PMPADDR15:
       return pmpaddr_csr_read(env, csrno - CSR_PMPADDR0);
#endif
    }
    /* used by e.g. MTIME read */
    do_raise_exception_err(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
}

/*
 * Check that CSR access is allowed.
 *
 * Adapted from Spike's decode.h:validate_csr
 */
static void validate_csr(CPURISCVState *env, uint64_t which,
                         uint64_t write, uintptr_t ra)
{
#ifndef CONFIG_USER_ONLY
    unsigned csr_priv = get_field((which), 0x300);
    unsigned csr_read_only = get_field((which), 0xC00) == 3;
    if (((write) && csr_read_only) || (env->priv < csr_priv)) {
        do_raise_exception_err(env, RISCV_EXCP_ILLEGAL_INST, ra);
    }
#endif
}

target_ulong helper_csrrw(CPURISCVState *env, target_ulong src,
        target_ulong csr)
{
    validate_csr(env, csr, 1, GETPC());
    uint64_t csr_backup = csr_read_helper(env, csr);
    csr_write_helper(env, src, csr);
    return csr_backup;
}

target_ulong helper_csrrs(CPURISCVState *env, target_ulong src,
        target_ulong csr, target_ulong rs1_pass)
{
    validate_csr(env, csr, rs1_pass != 0, GETPC());
    uint64_t csr_backup = csr_read_helper(env, csr);
    if (rs1_pass != 0) {
        csr_write_helper(env, src | csr_backup, csr);
    }
    return csr_backup;
}

target_ulong helper_csrrc(CPURISCVState *env, target_ulong src,
        target_ulong csr, target_ulong rs1_pass)
{
    validate_csr(env, csr, rs1_pass != 0, GETPC());
    uint64_t csr_backup = csr_read_helper(env, csr);
    if (rs1_pass != 0) {
        csr_write_helper(env, (~src) & csr_backup, csr);
    }
    return csr_backup;
}

#ifndef CONFIG_USER_ONLY

/* iothread_mutex must be held */
void riscv_set_local_interrupt(RISCVCPU *cpu, target_ulong mask, int value)
{
    target_ulong old_mip = cpu->env.mip;
    cpu->env.mip = (old_mip & ~mask) | (value ? mask : 0);

    if (cpu->env.mip && !old_mip) {
        cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
    } else if (!cpu->env.mip && old_mip) {
        cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
    }
}

void riscv_set_mode(CPURISCVState *env, target_ulong newpriv)
{
    if (newpriv > PRV_M) {
        g_assert_not_reached();
    }
    if (newpriv == PRV_H) {
        newpriv = PRV_U;
    }
    /* tlb_flush is unnecessary as mode is contained in mmu_idx */
    env->priv = newpriv;
}

target_ulong helper_sret(CPURISCVState *env, target_ulong cpu_pc_deb)
{
    if (!(env->priv >= PRV_S)) {
        do_raise_exception_err(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
    }

    target_ulong retpc = env->sepc;
    if (!riscv_has_ext(env, RVC) && (retpc & 0x3)) {
        do_raise_exception_err(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
    }

    target_ulong mstatus = env->mstatus;
    target_ulong prev_priv = get_field(mstatus, MSTATUS_SPP);
    mstatus = set_field(mstatus,
        env->priv_ver >= PRIV_VERSION_1_10_0 ?
        MSTATUS_SIE : MSTATUS_UIE << prev_priv,
        get_field(mstatus, MSTATUS_SPIE));
    mstatus = set_field(mstatus, MSTATUS_SPIE, 0);
    mstatus = set_field(mstatus, MSTATUS_SPP, PRV_U);
    riscv_set_mode(env, prev_priv);
    csr_write_helper(env, mstatus, CSR_MSTATUS);

    return retpc;
}

target_ulong helper_mret(CPURISCVState *env, target_ulong cpu_pc_deb)
{
    if (!(env->priv >= PRV_M)) {
        do_raise_exception_err(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
    }

    target_ulong retpc = env->mepc;
    if (!riscv_has_ext(env, RVC) && (retpc & 0x3)) {
        do_raise_exception_err(env, RISCV_EXCP_INST_ADDR_MIS, GETPC());
    }

    target_ulong mstatus = env->mstatus;
    target_ulong prev_priv = get_field(mstatus, MSTATUS_MPP);
    mstatus = set_field(mstatus,
        env->priv_ver >= PRIV_VERSION_1_10_0 ?
        MSTATUS_MIE : MSTATUS_UIE << prev_priv,
        get_field(mstatus, MSTATUS_MPIE));
    mstatus = set_field(mstatus, MSTATUS_MPIE, 0);
    mstatus = set_field(mstatus, MSTATUS_MPP, PRV_U);
    riscv_set_mode(env, prev_priv);
    csr_write_helper(env, mstatus, CSR_MSTATUS);

    return retpc;
}


void helper_wfi(CPURISCVState *env)
{
    CPUState *cs = CPU(riscv_env_get_cpu(env));

    cs->halted = 1;
    cs->exception_index = EXCP_HLT;
    cpu_loop_exit(cs);
}

void helper_tlb_flush(CPURISCVState *env)
{
    RISCVCPU *cpu = riscv_env_get_cpu(env);
    CPUState *cs = CPU(cpu);
    tlb_flush(cs);
}

#endif /* !CONFIG_USER_ONLY */
