diff options
author | Stafford Horne <shorne@gmail.com> | 2023-02-12 18:08:13 +0900 |
---|---|---|
committer | Stafford Horne <shorne@gmail.com> | 2023-05-11 15:40:03 +0100 |
commit | 08f021de3af599b8ca4c745f324a3559dc2990d3 (patch) | |
tree | 3c1f6ddc6ff00d55512747a2ccd0313010bbbca9 /target/openrisc/sys_helper.c | |
parent | c1eb2ddf0f8075faddc5f7c3d39feae3e8e9d6b4 (diff) | |
download | qemu-08f021de3af599b8ca4c745f324a3559dc2990d3.zip qemu-08f021de3af599b8ca4c745f324a3559dc2990d3.tar.gz qemu-08f021de3af599b8ca4c745f324a3559dc2990d3.tar.bz2 |
target/openrisc: Allow fpcsr access in user mode
As per OpenRISC spec 1.4 FPCSR can be read and written in user mode.
Update mtspr and mfspr helpers to support this by moving the is_user
check into the helper.
Link: https://raw.githubusercontent.com/openrisc/doc/master/openrisc-arch-1.4-rev0.pdf
Signed-off-by: Stafford Horne <shorne@gmail.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/openrisc/sys_helper.c')
-rw-r--r-- | target/openrisc/sys_helper.c | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/target/openrisc/sys_helper.c b/target/openrisc/sys_helper.c index ec14596..ccdee3b 100644 --- a/target/openrisc/sys_helper.c +++ b/target/openrisc/sys_helper.c @@ -29,17 +29,37 @@ #define TO_SPR(group, number) (((group) << 11) + (number)) +static inline bool is_user(CPUOpenRISCState *env) +{ +#ifdef CONFIG_USER_ONLY + return true; +#else + return (env->sr & SR_SM) == 0; +#endif +} + void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb) { -#ifndef CONFIG_USER_ONLY OpenRISCCPU *cpu = env_archcpu(env); +#ifndef CONFIG_USER_ONLY CPUState *cs = env_cpu(env); target_ulong mr; int idx; #endif + /* Handle user accessible SPRs first. */ switch (spr) { + case TO_SPR(0, 20): /* FPCSR */ + cpu_set_fpcsr(env, rb); + return; + } + + if (is_user(env)) { + raise_exception(cpu, EXCP_ILLEGAL); + } + #ifndef CONFIG_USER_ONLY + switch (spr) { case TO_SPR(0, 11): /* EVBAR */ env->evbar = rb; break; @@ -187,27 +207,33 @@ void HELPER(mtspr)(CPUOpenRISCState *env, target_ulong spr, target_ulong rb) cpu_openrisc_timer_update(cpu); qemu_mutex_unlock_iothread(); break; -#endif - - case TO_SPR(0, 20): /* FPCSR */ - cpu_set_fpcsr(env, rb); - break; } +#endif } target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, target_ulong spr) { + OpenRISCCPU *cpu = env_archcpu(env); #ifndef CONFIG_USER_ONLY uint64_t data[TARGET_INSN_START_WORDS]; MachineState *ms = MACHINE(qdev_get_machine()); - OpenRISCCPU *cpu = env_archcpu(env); CPUState *cs = env_cpu(env); int idx; #endif + /* Handle user accessible SPRs first. */ switch (spr) { + case TO_SPR(0, 20): /* FPCSR */ + return env->fpcsr; + } + + if (is_user(env)) { + raise_exception(cpu, EXCP_ILLEGAL); + } + #ifndef CONFIG_USER_ONLY + switch (spr) { case TO_SPR(0, 0): /* VR */ return env->vr; @@ -324,11 +350,8 @@ target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, cpu_openrisc_count_update(cpu); qemu_mutex_unlock_iothread(); return cpu_openrisc_count_get(cpu); -#endif - - case TO_SPR(0, 20): /* FPCSR */ - return env->fpcsr; } +#endif /* for rd is passed in, if rd unchanged, just keep it back. */ return rd; |