diff --git a/disas/mips.c b/disas/mips.c index 32940feb95..01336a8385 100644 --- a/disas/mips.c +++ b/disas/mips.c @@ -1296,12 +1296,12 @@ const struct mips_opcode mips_builtin_opcodes[] = {"dmod", "d,s,t", 0x000000de, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6}, {"ddivu", "d,s,t", 0x0000009f, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6}, {"dmodu", "d,s,t", 0x000000df, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I64R6}, -{"ll", "t,o(b)", 0x7c000036, 0xfc00007f, LDD|RD_b|WR_t, 0, I32R6}, -{"sc", "t,o(b)", 0x7c000026, 0xfc00007f, LDD|RD_b|WR_t, 0, I32R6}, -{"lld", "t,o(b)", 0x7c000037, 0xfc00007f, LDD|RD_b|WR_t, 0, I64R6}, -{"scd", "t,o(b)", 0x7c000027, 0xfc00007f, LDD|RD_b|WR_t, 0, I64R6}, -{"pref", "h,o(b)", 0x7c000035, 0xfc00007f, RD_b, 0, I32R6}, -{"cache", "k,o(b)", 0x7c000025, 0xfc00007f, RD_b, 0, I32R6}, +{"ll", "t,+o(b)", 0x7c000036, 0xfc00007f, LDD|RD_b|WR_t, 0, I32R6}, +{"sc", "t,+o(b)", 0x7c000026, 0xfc00007f, LDD|RD_b|WR_t, 0, I32R6}, +{"lld", "t,+o(b)", 0x7c000037, 0xfc00007f, LDD|RD_b|WR_t, 0, I64R6}, +{"scd", "t,+o(b)", 0x7c000027, 0xfc00007f, LDD|RD_b|WR_t, 0, I64R6}, +{"pref", "h,+o(b)", 0x7c000035, 0xfc00007f, RD_b, 0, I32R6}, +{"cache", "k,+o(b)", 0x7c000025, 0xfc00007f, RD_b, 0, I32R6}, {"seleqz", "d,v,t", 0x00000035, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, {"selnez", "d,v,t", 0x00000037, 0xfc0007ff, WR_d|RD_s|RD_t, 0, I32R6}, {"maddf.s", "D,S,T", 0x46000018, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I32R6}, diff --git a/linux-user/main.c b/linux-user/main.c index 05914b11e4..fdee981351 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -2577,7 +2577,7 @@ done_syscall: code = (trap_instr >> 6) & 0x3f; } } else { - ret = get_user_ual(trap_instr, env->active_tc.PC); + ret = get_user_u32(trap_instr, env->active_tc.PC); if (ret != 0) { goto error; } @@ -2611,7 +2611,7 @@ done_syscall: trap_instr = (instr[0] << 16) | instr[1]; } else { - ret = get_user_ual(trap_instr, env->active_tc.PC); + ret = get_user_u32(trap_instr, env->active_tc.PC); } if (ret != 0) { diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h index 20aa87c24c..53b185ebd3 100644 --- a/target-mips/mips-defs.h +++ b/target-mips/mips-defs.h @@ -11,7 +11,7 @@ #if defined(TARGET_MIPS64) #define TARGET_LONG_BITS 64 #define TARGET_PHYS_ADDR_SPACE_BITS 48 -#define TARGET_VIRT_ADDR_SPACE_BITS 42 +#define TARGET_VIRT_ADDR_SPACE_BITS 48 #else #define TARGET_LONG_BITS 32 #define TARGET_PHYS_ADDR_SPACE_BITS 40 diff --git a/target-mips/mips-semi.c b/target-mips/mips-semi.c index 1162c76df9..5050940c20 100644 --- a/target-mips/mips-semi.c +++ b/target-mips/mips-semi.c @@ -220,6 +220,23 @@ static int copy_argn_to_target(CPUMIPSState *env, int arg_num, } \ } while (0) +#define GET_TARGET_STRINGS_2(p, addr, p2, addr2) \ + do { \ + p = lock_user_string(addr); \ + if (!p) { \ + gpr[2] = -1; \ + gpr[3] = EFAULT; \ + goto uhi_done; \ + } \ + p2 = lock_user_string(addr2); \ + if (!p2) { \ + unlock_user(p, addr, 0); \ + gpr[2] = -1; \ + gpr[3] = EFAULT; \ + goto uhi_done; \ + } \ + } while (0) + #define FREE_TARGET_STRING(p, gpr) \ do { \ unlock_user(p, gpr, 0); \ @@ -322,8 +339,7 @@ void helper_do_semihosting(CPUMIPSState *env) FREE_TARGET_STRING(p, gpr[4]); break; case UHI_assert: - GET_TARGET_STRING(p, gpr[4]); - GET_TARGET_STRING(p2, gpr[5]); + GET_TARGET_STRINGS_2(p, gpr[4], p2, gpr[5]); printf("assertion '"); printf("\"%s\"", p); printf("': file \"%s\", line %d\n", p2, (int)gpr[6]); @@ -341,8 +357,7 @@ void helper_do_semihosting(CPUMIPSState *env) break; #ifndef _WIN32 case UHI_link: - GET_TARGET_STRING(p, gpr[4]); - GET_TARGET_STRING(p2, gpr[5]); + GET_TARGET_STRINGS_2(p, gpr[4], p2, gpr[5]); gpr[2] = link(p, p2); gpr[3] = errno_mips(errno); FREE_TARGET_STRING(p2, gpr[5]); diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c index 26ffdc726e..a1cb48f2a9 100644 --- a/target-mips/msa_helper.c +++ b/target-mips/msa_helper.c @@ -2642,6 +2642,8 @@ void helper_msa_fexdo_df(CPUMIPSState *env, uint32_t df, uint32_t wd, wr_t *pwt = &(env->active_fpu.fpr[wt].wr); uint32_t i; + clear_msacsr_cause(env); + switch (df) { case DF_WORD: for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { @@ -3192,6 +3194,8 @@ void helper_msa_fexupl_df(CPUMIPSState *env, uint32_t df, uint32_t wd, wr_t *pws = &(env->active_fpu.fpr[ws].wr); uint32_t i; + clear_msacsr_cause(env); + switch (df) { case DF_WORD: for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { @@ -3224,6 +3228,8 @@ void helper_msa_fexupr_df(CPUMIPSState *env, uint32_t df, uint32_t wd, wr_t *pws = &(env->active_fpu.fpr[ws].wr); uint32_t i; + clear_msacsr_cause(env); + switch (df) { case DF_WORD: for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c index 2a9ddff70f..9c28631dc1 100644 --- a/target-mips/op_helper.c +++ b/target-mips/op_helper.c @@ -661,7 +661,7 @@ static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc, /* Sync the TASID with EntryHi. */ cpu->CP0_EntryHi &= ~0xff; - cpu->CP0_EntryHi = tasid; + cpu->CP0_EntryHi |= tasid; compute_hflags(cpu); } @@ -2154,10 +2154,9 @@ void helper_deret(CPUMIPSState *env) debug_pre_eret(env); set_pc(env, env->CP0_DEPC); - env->hflags &= MIPS_HFLAG_DM; + env->hflags &= ~MIPS_HFLAG_DM; compute_hflags(env); debug_post_eret(env); - env->lladdr = 1; } #endif /* !CONFIG_USER_ONLY */ diff --git a/target-mips/translate.c b/target-mips/translate.c index 73028572c9..d1de35ad30 100644 --- a/target-mips/translate.c +++ b/target-mips/translate.c @@ -2142,6 +2142,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, break; case OPC_LDL: t1 = tcg_temp_new(); + /* Do a byte access to possibly trigger a page + fault with the unaligned address. */ + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); tcg_gen_andi_tl(t1, t0, 7); #ifndef TARGET_WORDS_BIGENDIAN tcg_gen_xori_tl(t1, t1, 7); @@ -2163,6 +2166,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, break; case OPC_LDR: t1 = tcg_temp_new(); + /* Do a byte access to possibly trigger a page + fault with the unaligned address. */ + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); tcg_gen_andi_tl(t1, t0, 7); #ifdef TARGET_WORDS_BIGENDIAN tcg_gen_xori_tl(t1, t1, 7); @@ -2229,6 +2235,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, break; case OPC_LWL: t1 = tcg_temp_new(); + /* Do a byte access to possibly trigger a page + fault with the unaligned address. */ + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); tcg_gen_andi_tl(t1, t0, 3); #ifndef TARGET_WORDS_BIGENDIAN tcg_gen_xori_tl(t1, t1, 3); @@ -2251,6 +2260,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc, break; case OPC_LWR: t1 = tcg_temp_new(); + /* Do a byte access to possibly trigger a page + fault with the unaligned address. */ + tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB); tcg_gen_andi_tl(t1, t0, 3); #ifdef TARGET_WORDS_BIGENDIAN tcg_gen_xori_tl(t1, t1, 3); @@ -9552,6 +9564,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, gen_cmp_s(ctx, func-48, ft, fs, cc); opn = condnames[func-48]; } + optype = CMPOP; break; case OPC_ADD_D: check_cp1_registers(ctx, fs | ft | fd); @@ -10036,6 +10049,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, gen_cmp_d(ctx, func-48, ft, fs, cc); opn = condnames[func-48]; } + optype = CMPOP; break; case OPC_CVT_S_D: check_cp1_registers(ctx, fs); @@ -10461,6 +10475,7 @@ static void gen_farith (DisasContext *ctx, enum fopcode op1, gen_cmp_ps(ctx, func-48, ft, fs, cc); opn = condnames[func-48]; } + optype = CMPOP; break; default: MIPS_INVAL(opn); diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c index ddfaff8052..9304e746b4 100644 --- a/target-mips/translate_init.c +++ b/target-mips/translate_init.c @@ -655,14 +655,14 @@ static const mips_def_t mips_defs[] = (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), .CP0_Config2 = MIPS_CONFIG2, - .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_RXI) | (1 << CP0C3_BP) | - (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | (1 << CP0C3_LPA) | - (1U << CP0C3_M), - .CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) | - (3 << CP0C4_IE) | (1 << CP0C4_M), + .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_MSAP) | + (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) | + (1 << CP0C3_RXI) | (1 << CP0C3_LPA), + .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) | + (0xfc << CP0C4_KScrExist), .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_LLB), - .CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) | - (1 << CP0C5_UFE), + .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) | + (1 << CP0C5_FRE) | (1 << CP0C5_UFE), .CP0_LLAddr_rw_bitmask = 0, .CP0_LLAddr_shift = 0, .SYNCI_Step = 32, @@ -674,9 +674,9 @@ static const mips_def_t mips_defs[] = .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV), - .SEGBITS = 42, + .SEGBITS = 48, .PABITS = 48, - .insn_flags = CPU_MIPS64R6, + .insn_flags = CPU_MIPS64R6 | ASE_MSA, .mmu_type = MMU_TYPE_R4000, }, {