From e7139c440c489ed31bb81ccb5e456ae9d8fe1c1e Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Mon, 30 Nov 2009 15:39:54 +0100 Subject: target-mips: use physical address in lladdr Currently the ll/sc instructions use the virtual address in both user and system mode. Use the physical address insteead in system mode. Signed-off-by: Aurelien Jarno --- target-mips/op_helper.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'target-mips/op_helper.c') diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index fe1c916..be75af5 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -275,6 +275,45 @@ void helper_dmultu (target_ulong arg1, target_ulong arg2) } #endif +#ifndef CONFIG_USER_ONLY +#define HELPER_LD_ATOMIC(name, insn) \ +target_ulong helper_##name(target_ulong arg, int mem_idx) \ +{ \ + env->lladdr = do_translate_address(env, arg, 0); \ + env->llval = do_##insn(arg, mem_idx); \ + return env->llval; \ +} +HELPER_LD_ATOMIC(ll, lw) +#ifdef TARGET_MIPS64 +HELPER_LD_ATOMIC(lld, ld) +#endif +#undef HELPER_LD_ATOMIC + +#define HELPER_ST_ATOMIC(name, ld_insn, st_insn, almask) \ +target_ulong helper_##name(target_ulong arg1, target_ulong arg2, int mem_idx) \ +{ \ + target_long tmp; \ + \ + if (arg2 & almask) { \ + env->CP0_BadVAddr = arg2; \ + helper_raise_exception(EXCP_AdES); \ + } \ + if (do_translate_address(env, arg2, 1) == env->lladdr) { \ + tmp = do_##ld_insn(arg2, mem_idx); \ + if (tmp == env->llval) { \ + do_##st_insn(arg2, arg1, mem_idx); \ + return 1; \ + } \ + } \ + return 0; \ +} +HELPER_ST_ATOMIC(sc, lw, sw, 0x3) +#ifdef TARGET_MIPS64 +HELPER_ST_ATOMIC(scd, ld, sd, 0x7) +#endif +#undef HELPER_ST_ATOMIC +#endif + #ifdef TARGET_WORDS_BIGENDIAN #define GET_LMASK(v) ((v) & 3) #define GET_OFFSET(addr, offset) (addr + (offset)) -- cgit v1.1