diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2019-05-28 11:52:53 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2019-05-28 11:52:53 +0100 |
| commit | 4bade28288b12a6268d2e1fc2e4fa1f77ccb1d89 (patch) | |
| tree | 768cd3b7fa0540172f102a06be60a84d45c444ee /target/riscv/csr.c | |
| parent | 2b01c1b3821788417ac63392839eccb85feadc3f (diff) | |
| parent | 1e0d985fa9136a563168a3da66f3d17820404ee2 (diff) | |
| download | focaccia-qemu-4bade28288b12a6268d2e1fc2e4fa1f77ccb1d89.tar.gz focaccia-qemu-4bade28288b12a6268d2e1fc2e4fa1f77ccb1d89.zip | |
Merge remote-tracking branch 'remotes/palmer/tags/riscv-for-master-4.1-sf0' into staging
RISC-V Patches for the 4.1 Soft Freeze, Part 1 This tag contains a handful of patches that I'd like to target for 4.1: * An emulation for SiFive's GPIO device. * A fix to disallow sfence.vma from userspace. * Additional decodetree cleanups that should have no functional impact. * C extension emulation fidelity fixes that were noticed as part of that cleanup process. * A new "spike" target, along with the deprecation of a handful of old targets and CPUs. * Some initial infastructure related to the hypervisor extension. * An emulation fidelity fix that prevents prevents arbitrary bits in the SIP CSR from being set. * A small performance improvement that avoids excessive TLB flushing when the ASID does not change. This time I've used a new testing workflow: I've tested on both 32-bit and 64-bit builds of OpenEmbedded, via the default OpenSBI-based boot flow. # gpg: Signature made Sat 25 May 2019 01:05:57 BST # gpg: using RSA key 00CE76D1834960DFCE886DF8EF4CA1502CCBAB41 # gpg: issuer "palmer@dabbelt.com" # gpg: Good signature from "Palmer Dabbelt <palmer@dabbelt.com>" [unknown] # gpg: aka "Palmer Dabbelt <palmer@sifive.com>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 00CE 76D1 8349 60DF CE88 6DF8 EF4C A150 2CCB AB41 * remotes/palmer/tags/riscv-for-master-4.1-sf0: (29 commits) target/riscv: Only flush TLB if SATP.ASID changes target/riscv: More accurate handling of `sip` CSR target/riscv: Add checks for several RVC reserved operands target/riscv: Add the HGATP register masks target/riscv: Add the HSTATUS register masks target/riscv: Add Hypervisor CSR macros target/riscv: Allow setting mstatus virtulisation bits target/riscv: Add the MPV and MTL mstatus bits target/riscv: Improve the scause logic target/riscv: Trigger interrupt on MIP update asynchronously target/riscv: Mark privilege level 2 as reserved riscv: spike: Add a generic spike machine target/riscv: Deprecate the generic no MMU CPUs target/riscv: Add a base 32 and 64 bit CPU target/riscv: Create settable CPU properties riscv: virt: Allow specifying a CPU via commandline linux-user/riscv: Add the CPU type as a comment target/riscv: Remove unused include of riscv_htif.h for virt board riscv target/riscv: Remove spaces from register names target/riscv: Split gen_arith_imm into functional and temp ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/riscv/csr.c')
| -rw-r--r-- | target/riscv/csr.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/target/riscv/csr.c b/target/riscv/csr.c index e1d91b6c60..f9e2910643 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -237,6 +237,7 @@ static const target_ulong sstatus_v1_9_mask = SSTATUS_SIE | SSTATUS_SPIE | static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS | SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD; +static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP; #if defined(TARGET_RISCV32) static const char valid_vm_1_09[16] = { @@ -290,7 +291,6 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val) { target_ulong mstatus = env->mstatus; target_ulong mask = 0; - target_ulong mpp = get_field(val, MSTATUS_MPP); /* flush tlb on mstatus fields that affect VM */ if (env->priv_ver <= PRIV_VERSION_1_09_1) { @@ -305,7 +305,7 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val) MSTATUS_VM : 0); } if (env->priv_ver >= PRIV_VERSION_1_10_0) { - if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | + if ((val ^ mstatus) & (MSTATUS_MXR | MSTATUS_MPP | MSTATUS_MPV | MSTATUS_MPRV | MSTATUS_SUM)) { tlb_flush(CPU(riscv_env_get_cpu(env))); } @@ -313,13 +313,13 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val) MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM | MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR | MSTATUS_TW; - } - - /* 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; +#if defined(TARGET_RISCV64) + /* + * RV32: MPV and MTL are not in mstatus. The current plan is to + * add them to mstatush. For now, we just don't support it. + */ + mask |= MSTATUS_MPP | MSTATUS_MPV; +#endif } mstatus = (mstatus & ~mask) | (val & mask); @@ -555,9 +555,7 @@ static int rmw_mip(CPURISCVState *env, int csrno, target_ulong *ret_value, uint32_t old_mip; if (mask) { - qemu_mutex_lock_iothread(); old_mip = riscv_cpu_update_mip(cpu, mask, (new_value & mask)); - qemu_mutex_unlock_iothread(); } else { old_mip = atomic_read(&env->mip); } @@ -685,8 +683,10 @@ static int write_sbadaddr(CPURISCVState *env, int csrno, target_ulong val) static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask) { - return rmw_mip(env, CSR_MSTATUS, ret_value, new_value, - write_mask & env->mideleg); + int ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value, + write_mask & env->mideleg & sip_writable_mask); + *ret_value &= env->mideleg; + return ret; } /* Supervisor Protection and Translation */ @@ -723,7 +723,9 @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val) if (env->priv == PRV_S && get_field(env->mstatus, MSTATUS_TVM)) { return -1; } else { - tlb_flush(CPU(riscv_env_get_cpu(env))); + if((val ^ env->satp) & SATP_ASID) { + tlb_flush(CPU(riscv_env_get_cpu(env))); + } env->satp = val; } } |