MIPS patches 2015-07-16

Changes:
 * bug fixes
 -----BEGIN PGP SIGNATURE-----
 
 iQEcBAABAgAGBQJVp2WoAAoJEFIRjjwLKdprb6IH/2LjKE10eFTn6M08glegVKMc
 8yt/Ba212lKnAMnp57L2iqL3zjTHgYofKc0iThqopBWpiS6+2UhlXSukExKcNcZ2
 8UgvR89zvEqadKchv64EXcKh+K8/ylMPPDkuf9UZJOGt+YQncdvGPNw/vqaCeEqj
 tUQQNyDITs/+JCaMksNtIURgrkOqCprOvI4/wYxvZUJjecSrN9kpmv1NI3Cmqwlw
 SlQ+HjecHNEms50C6T12OhQprNuuwEb+nOysWoJjldkWeayAuTmCg7g89flF9wu9
 dE0xZN3XtAVxmW9stTqHp0IwO3mwFAw13CZxiZ7dnT0rx5KGaq9nj53qlIqG9L0=
 =dHki
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/lalrae/tags/mips-20150716' into staging

MIPS patches 2015-07-16

Changes:
* bug fixes

# gpg: Signature made Thu Jul 16 09:04:56 2015 BST using RSA key ID 0B29DA6B
# gpg: Good signature from "Leon Alrae <leon.alrae@imgtec.com>"
# 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: 8DD3 2F98 5495 9D66 35D4  4FC0 5211 8E3C 0B29 DA6B

* remotes/lalrae/tags/mips-20150716:
  target-mips: fix page fault address for LWL/LWR/LDL/LDR
  linux-user: Fix MIPS N64 trap and break instruction bug
  target-mips: fix resource leak reported by Coverity
  target-mips: fix logically dead code reported by Coverity
  target-mips: correct DERET instruction
  target-mips: fix ASID synchronisation for MIPS MT
  disas/mips: fix disassembling R6 instructions
  target-mips: fix to clear MSACSR.Cause
  target-mips: fix MIPS64R6-generic configuration

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2015-07-16 10:40:22 +01:00
commit 2d5ee9e7a7
8 changed files with 60 additions and 25 deletions

View file

@ -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}, {"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}, {"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}, {"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}, {"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}, {"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}, {"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}, {"scd", "t,+o(b)", 0x7c000027, 0xfc00007f, LDD|RD_b|WR_t, 0, I64R6},
{"pref", "h,o(b)", 0x7c000035, 0xfc00007f, RD_b, 0, I32R6}, {"pref", "h,+o(b)", 0x7c000035, 0xfc00007f, RD_b, 0, I32R6},
{"cache", "k,o(b)", 0x7c000025, 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}, {"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}, {"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}, {"maddf.s", "D,S,T", 0x46000018, 0xffe0003f, WR_D|RD_S|RD_T|FP_S, 0, I32R6},

View file

@ -2577,7 +2577,7 @@ done_syscall:
code = (trap_instr >> 6) & 0x3f; code = (trap_instr >> 6) & 0x3f;
} }
} else { } else {
ret = get_user_ual(trap_instr, env->active_tc.PC); ret = get_user_u32(trap_instr, env->active_tc.PC);
if (ret != 0) { if (ret != 0) {
goto error; goto error;
} }
@ -2611,7 +2611,7 @@ done_syscall:
trap_instr = (instr[0] << 16) | instr[1]; trap_instr = (instr[0] << 16) | instr[1];
} else { } else {
ret = get_user_ual(trap_instr, env->active_tc.PC); ret = get_user_u32(trap_instr, env->active_tc.PC);
} }
if (ret != 0) { if (ret != 0) {

View file

@ -11,7 +11,7 @@
#if defined(TARGET_MIPS64) #if defined(TARGET_MIPS64)
#define TARGET_LONG_BITS 64 #define TARGET_LONG_BITS 64
#define TARGET_PHYS_ADDR_SPACE_BITS 48 #define TARGET_PHYS_ADDR_SPACE_BITS 48
#define TARGET_VIRT_ADDR_SPACE_BITS 42 #define TARGET_VIRT_ADDR_SPACE_BITS 48
#else #else
#define TARGET_LONG_BITS 32 #define TARGET_LONG_BITS 32
#define TARGET_PHYS_ADDR_SPACE_BITS 40 #define TARGET_PHYS_ADDR_SPACE_BITS 40

View file

@ -220,6 +220,23 @@ static int copy_argn_to_target(CPUMIPSState *env, int arg_num,
} \ } \
} while (0) } 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) \ #define FREE_TARGET_STRING(p, gpr) \
do { \ do { \
unlock_user(p, gpr, 0); \ unlock_user(p, gpr, 0); \
@ -322,8 +339,7 @@ void helper_do_semihosting(CPUMIPSState *env)
FREE_TARGET_STRING(p, gpr[4]); FREE_TARGET_STRING(p, gpr[4]);
break; break;
case UHI_assert: case UHI_assert:
GET_TARGET_STRING(p, gpr[4]); GET_TARGET_STRINGS_2(p, gpr[4], p2, gpr[5]);
GET_TARGET_STRING(p2, gpr[5]);
printf("assertion '"); printf("assertion '");
printf("\"%s\"", p); printf("\"%s\"", p);
printf("': file \"%s\", line %d\n", p2, (int)gpr[6]); printf("': file \"%s\", line %d\n", p2, (int)gpr[6]);
@ -341,8 +357,7 @@ void helper_do_semihosting(CPUMIPSState *env)
break; break;
#ifndef _WIN32 #ifndef _WIN32
case UHI_link: case UHI_link:
GET_TARGET_STRING(p, gpr[4]); GET_TARGET_STRINGS_2(p, gpr[4], p2, gpr[5]);
GET_TARGET_STRING(p2, gpr[5]);
gpr[2] = link(p, p2); gpr[2] = link(p, p2);
gpr[3] = errno_mips(errno); gpr[3] = errno_mips(errno);
FREE_TARGET_STRING(p2, gpr[5]); FREE_TARGET_STRING(p2, gpr[5]);

View file

@ -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); wr_t *pwt = &(env->active_fpu.fpr[wt].wr);
uint32_t i; uint32_t i;
clear_msacsr_cause(env);
switch (df) { switch (df) {
case DF_WORD: case DF_WORD:
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { 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); wr_t *pws = &(env->active_fpu.fpr[ws].wr);
uint32_t i; uint32_t i;
clear_msacsr_cause(env);
switch (df) { switch (df) {
case DF_WORD: case DF_WORD:
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { 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); wr_t *pws = &(env->active_fpu.fpr[ws].wr);
uint32_t i; uint32_t i;
clear_msacsr_cause(env);
switch (df) { switch (df) {
case DF_WORD: case DF_WORD:
for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) { for (i = 0; i < DF_ELEMENTS(DF_WORD); i++) {

View file

@ -661,7 +661,7 @@ static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc,
/* Sync the TASID with EntryHi. */ /* Sync the TASID with EntryHi. */
cpu->CP0_EntryHi &= ~0xff; cpu->CP0_EntryHi &= ~0xff;
cpu->CP0_EntryHi = tasid; cpu->CP0_EntryHi |= tasid;
compute_hflags(cpu); compute_hflags(cpu);
} }
@ -2154,10 +2154,9 @@ void helper_deret(CPUMIPSState *env)
debug_pre_eret(env); debug_pre_eret(env);
set_pc(env, env->CP0_DEPC); set_pc(env, env->CP0_DEPC);
env->hflags &= MIPS_HFLAG_DM; env->hflags &= ~MIPS_HFLAG_DM;
compute_hflags(env); compute_hflags(env);
debug_post_eret(env); debug_post_eret(env);
env->lladdr = 1;
} }
#endif /* !CONFIG_USER_ONLY */ #endif /* !CONFIG_USER_ONLY */

View file

@ -2142,6 +2142,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
break; break;
case OPC_LDL: case OPC_LDL:
t1 = tcg_temp_new(); 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); tcg_gen_andi_tl(t1, t0, 7);
#ifndef TARGET_WORDS_BIGENDIAN #ifndef TARGET_WORDS_BIGENDIAN
tcg_gen_xori_tl(t1, t1, 7); tcg_gen_xori_tl(t1, t1, 7);
@ -2163,6 +2166,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
break; break;
case OPC_LDR: case OPC_LDR:
t1 = tcg_temp_new(); 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); tcg_gen_andi_tl(t1, t0, 7);
#ifdef TARGET_WORDS_BIGENDIAN #ifdef TARGET_WORDS_BIGENDIAN
tcg_gen_xori_tl(t1, t1, 7); tcg_gen_xori_tl(t1, t1, 7);
@ -2229,6 +2235,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
break; break;
case OPC_LWL: case OPC_LWL:
t1 = tcg_temp_new(); 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); tcg_gen_andi_tl(t1, t0, 3);
#ifndef TARGET_WORDS_BIGENDIAN #ifndef TARGET_WORDS_BIGENDIAN
tcg_gen_xori_tl(t1, t1, 3); tcg_gen_xori_tl(t1, t1, 3);
@ -2251,6 +2260,9 @@ static void gen_ld(DisasContext *ctx, uint32_t opc,
break; break;
case OPC_LWR: case OPC_LWR:
t1 = tcg_temp_new(); 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); tcg_gen_andi_tl(t1, t0, 3);
#ifdef TARGET_WORDS_BIGENDIAN #ifdef TARGET_WORDS_BIGENDIAN
tcg_gen_xori_tl(t1, t1, 3); 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); gen_cmp_s(ctx, func-48, ft, fs, cc);
opn = condnames[func-48]; opn = condnames[func-48];
} }
optype = CMPOP;
break; break;
case OPC_ADD_D: case OPC_ADD_D:
check_cp1_registers(ctx, fs | ft | fd); 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); gen_cmp_d(ctx, func-48, ft, fs, cc);
opn = condnames[func-48]; opn = condnames[func-48];
} }
optype = CMPOP;
break; break;
case OPC_CVT_S_D: case OPC_CVT_S_D:
check_cp1_registers(ctx, fs); 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); gen_cmp_ps(ctx, func-48, ft, fs, cc);
opn = condnames[func-48]; opn = condnames[func-48];
} }
optype = CMPOP;
break; break;
default: default:
MIPS_INVAL(opn); MIPS_INVAL(opn);

View file

@ -655,14 +655,14 @@ static const mips_def_t mips_defs[] =
(2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) | (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
(0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP), (0 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
.CP0_Config2 = MIPS_CONFIG2, .CP0_Config2 = MIPS_CONFIG2,
.CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_RXI) | (1 << CP0C3_BP) | .CP0_Config3 = MIPS_CONFIG3 | (1U << CP0C3_M) | (1 << CP0C3_MSAP) |
(1 << CP0C3_BI) | (1 << CP0C3_ULRI) | (1 << CP0C3_LPA) | (1 << CP0C3_BP) | (1 << CP0C3_BI) | (1 << CP0C3_ULRI) |
(1U << CP0C3_M), (1 << CP0C3_RXI) | (1 << CP0C3_LPA),
.CP0_Config4 = MIPS_CONFIG4 | (0xfc << CP0C4_KScrExist) | .CP0_Config4 = MIPS_CONFIG4 | (1U << CP0C4_M) | (3 << CP0C4_IE) |
(3 << CP0C4_IE) | (1 << CP0C4_M), (0xfc << CP0C4_KScrExist),
.CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_LLB), .CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_LLB),
.CP0_Config5_rw_bitmask = (1 << CP0C5_SBRI) | (1 << CP0C5_FRE) | .CP0_Config5_rw_bitmask = (1 << CP0C5_MSAEn) | (1 << CP0C5_SBRI) |
(1 << CP0C5_UFE), (1 << CP0C5_FRE) | (1 << CP0C5_UFE),
.CP0_LLAddr_rw_bitmask = 0, .CP0_LLAddr_rw_bitmask = 0,
.CP0_LLAddr_shift = 0, .CP0_LLAddr_shift = 0,
.SYNCI_Step = 32, .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) | .CP1_fcr0 = (1 << FCR0_FREP) | (1 << FCR0_F64) | (1 << FCR0_L) |
(1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) | (1 << FCR0_W) | (1 << FCR0_D) | (1 << FCR0_S) |
(0x00 << FCR0_PRID) | (0x0 << FCR0_REV), (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
.SEGBITS = 42, .SEGBITS = 48,
.PABITS = 48, .PABITS = 48,
.insn_flags = CPU_MIPS64R6, .insn_flags = CPU_MIPS64R6 | ASE_MSA,
.mmu_type = MMU_TYPE_R4000, .mmu_type = MMU_TYPE_R4000,
}, },
{ {