summaryrefslogtreecommitdiffstats
path: root/linux-user/mips
diff options
context:
space:
mode:
authorLeon Alrae2019-02-11 16:09:23 +0100
committerAleksandar Markovic2019-02-14 17:47:28 +0100
commit33a07fa2db66376e6ee780d4a8b064dc5118cf34 (patch)
tree67abf3dfc5fb163e7437f697480eeccb489cf536 /linux-user/mips
parenttarget/mips: compare virtual addresses in LL/SC sequence (diff)
downloadqemu-33a07fa2db66376e6ee780d4a8b064dc5118cf34.tar.gz
qemu-33a07fa2db66376e6ee780d4a8b064dc5118cf34.tar.xz
qemu-33a07fa2db66376e6ee780d4a8b064dc5118cf34.zip
target/mips: reimplement SC instruction emulation and use cmpxchg
Completely rewrite conditional stores handling. Use cmpxchg. This eliminates need for separate implementations of SC instruction emulation for user and system emulation. Signed-off-by: Leon Alrae <leon.alrae@imgtec.com> Signed-off-by: Miodrag Dinic <miodrag.dinic@imgtec.com> Signed-off-by: Aleksandar Markovic <amarkovic@wavecomp.com> Acked-by: Alex Bennée <alex.bennee@linaro.org> Tested-by: Emilio G. Cota <cota@braap.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'linux-user/mips')
-rw-r--r--linux-user/mips/cpu_loop.c73
1 files changed, 0 insertions, 73 deletions
diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index d0f62ec9b6..61dc90d51c 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -392,70 +392,6 @@ static const uint8_t mips_syscall_args[] = {
# undef MIPS_SYS
# endif /* O32 */
-static int do_store_exclusive(CPUMIPSState *env)
-{
- target_ulong addr;
- target_ulong page_addr;
- target_ulong val;
- uint32_t val_wp = 0;
- uint32_t llnewval_wp = 0;
- int flags;
- int segv = 0;
- int reg;
- int d;
- int wp;
-
- addr = env->lladdr;
- page_addr = addr & TARGET_PAGE_MASK;
- start_exclusive();
- mmap_lock();
- flags = page_get_flags(page_addr);
- if ((flags & PAGE_READ) == 0) {
- segv = 1;
- } else {
- reg = env->llreg & 0x1f;
- d = (env->llreg & 0x20) != 0;
- wp = (env->llreg & 0x40) != 0;
- if (!wp) {
- if (d) {
- segv = get_user_s64(val, addr);
- } else {
- segv = get_user_s32(val, addr);
- }
- } else {
- segv = get_user_s32(val, addr);
- segv |= get_user_s32(val_wp, addr);
- llnewval_wp = env->llnewval_wp;
- }
- if (!segv) {
- if (val != env->llval && val_wp == llnewval_wp) {
- env->active_tc.gpr[reg] = 0;
- } else {
- if (!wp) {
- if (d) {
- segv = put_user_u64(env->llnewval, addr);
- } else {
- segv = put_user_u32(env->llnewval, addr);
- }
- } else {
- segv = put_user_u32(env->llnewval, addr);
- segv |= put_user_u32(env->llnewval_wp, addr + 4);
- }
- if (!segv) {
- env->active_tc.gpr[reg] = 1;
- }
- }
- }
- }
- env->lladdr = -1;
- if (!segv) {
- env->active_tc.PC += 4;
- }
- mmap_unlock();
- end_exclusive();
- return segv;
-}
-
/* Break codes */
enum {
BRK_OVERFLOW = 6,
@@ -597,15 +533,6 @@ done_syscall:
info.si_code = TARGET_TRAP_BRKPT;
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
break;
- case EXCP_SC:
- if (do_store_exclusive(env)) {
- info.si_signo = TARGET_SIGSEGV;
- info.si_errno = 0;
- info.si_code = TARGET_SEGV_MAPERR;
- info._sifields._sigfault._addr = env->active_tc.PC;
- queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
- }
- break;
case EXCP_DSPDIS:
info.si_signo = TARGET_SIGILL;
info.si_errno = 0;