[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 13/34] target-mips: add restrictions for possible val
From: |
Leon Alrae |
Subject: |
[Qemu-devel] [PULL 13/34] target-mips: add restrictions for possible values in registers |
Date: |
Mon, 3 Nov 2014 16:11:27 +0000 |
In Release 6 not all the values are allowed to be written to a register.
If the value is not valid or unsupported then it should stay unchanged.
For pre-R6 the existing behaviour has been changed only for CP0_Index register
as the current implementation does not seem to be correct - it looks like it
tries to limit the input value but the limit is higher than the actual
number of tlb entries.
Signed-off-by: Leon Alrae <address@hidden>
Reviewed-by: Yongbok Kim <address@hidden>
---
target-mips/op_helper.c | 70 +++++++++++++++++++++++++++++++++++++------------
1 file changed, 53 insertions(+), 17 deletions(-)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index 875aa2c..99bdbcf 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -959,14 +959,14 @@ target_ulong helper_dmfc0_watchlo(CPUMIPSState *env,
uint32_t sel)
void helper_mtc0_index(CPUMIPSState *env, target_ulong arg1)
{
- int num = 1;
- unsigned int tmp = env->tlb->nb_tlb;
-
- do {
- tmp >>= 1;
- num <<= 1;
- } while (tmp);
- env->CP0_Index = (env->CP0_Index & 0x80000000) | (arg1 & (num - 1));
+ uint32_t index_p = env->CP0_Index & 0x80000000;
+ uint32_t tlb_index = arg1 & 0x7fffffff;
+ if (tlb_index < env->tlb->nb_tlb) {
+ if (env->insn_flags & ISA_MIPS32R6) {
+ index_p |= arg1 & 0x80000000;
+ }
+ env->CP0_Index = index_p | tlb_index;
+ }
}
void helper_mtc0_mvpcontrol(CPUMIPSState *env, target_ulong arg1)
@@ -1294,8 +1294,13 @@ void helper_mtc0_context(CPUMIPSState *env, target_ulong
arg1)
void helper_mtc0_pagemask(CPUMIPSState *env, target_ulong arg1)
{
- /* 1k pages not implemented */
- env->CP0_PageMask = arg1 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
+ uint64_t mask = arg1 >> (TARGET_PAGE_BITS + 1);
+ if (!(env->insn_flags & ISA_MIPS32R6) || (arg1 == ~0) ||
+ (mask == 0x0000 || mask == 0x0003 || mask == 0x000F ||
+ mask == 0x003F || mask == 0x00FF || mask == 0x03FF ||
+ mask == 0x0FFF || mask == 0x3FFF || mask == 0xFFFF)) {
+ env->CP0_PageMask = arg1 & (0x1FFFFFFF & (TARGET_PAGE_MASK << 1));
+ }
}
void helper_mtc0_pagegrain(CPUMIPSState *env, target_ulong arg1)
@@ -1309,7 +1314,13 @@ void helper_mtc0_pagegrain(CPUMIPSState *env,
target_ulong arg1)
void helper_mtc0_wired(CPUMIPSState *env, target_ulong arg1)
{
- env->CP0_Wired = arg1 % env->tlb->nb_tlb;
+ if (env->insn_flags & ISA_MIPS32R6) {
+ if (arg1 < env->tlb->nb_tlb) {
+ env->CP0_Wired = arg1;
+ }
+ } else {
+ env->CP0_Wired = arg1 % env->tlb->nb_tlb;
+ }
}
void helper_mtc0_srsconf0(CPUMIPSState *env, target_ulong arg1)
@@ -1368,11 +1379,21 @@ void helper_mtc0_entryhi(CPUMIPSState *env,
target_ulong arg1)
}
/* 1k pages not implemented */
- val = arg1 & mask;
#if defined(TARGET_MIPS64)
- val &= env->SEGMask;
+ if (env->insn_flags & ISA_MIPS32R6) {
+ int entryhi_r = extract64(arg1, 62, 2);
+ int config0_at = extract32(env->CP0_Config0, 13, 2);
+ bool no_supervisor = (env->CP0_Status_rw_bitmask & 0x8) == 0;
+ if ((entryhi_r == 2) ||
+ (entryhi_r == 1 && (no_supervisor || config0_at == 1))) {
+ /* skip EntryHi.R field if new value is reserved */
+ mask &= ~(0x3ull << 62);
+ }
+ }
+ mask &= env->SEGMask;
#endif
old = env->CP0_EntryHi;
+ val = (arg1 & mask) | (old & ~mask);
env->CP0_EntryHi = val;
if (env->CP0_Config3 & (1 << CP0C3_MT)) {
sync_c0_entryhi(env, env->current_tc);
@@ -1402,6 +1423,13 @@ void helper_mtc0_status(CPUMIPSState *env, target_ulong
arg1)
uint32_t val, old;
uint32_t mask = env->CP0_Status_rw_bitmask;
+ if (env->insn_flags & ISA_MIPS32R6) {
+ if (extract32(env->CP0_Status, CP0St_KSU, 2) == 0x3) {
+ mask &= ~(3 << CP0St_KSU);
+ }
+ mask &= ~(0x00180000 & arg1);
+ }
+
val = arg1 & mask;
old = env->CP0_Status;
env->CP0_Status = (env->CP0_Status & ~mask) | val;
@@ -1457,6 +1485,9 @@ static void mtc0_cause(CPUMIPSState *cpu, target_ulong
arg1)
if (cpu->insn_flags & ISA_MIPS32R2) {
mask |= 1 << CP0Ca_DC;
}
+ if (cpu->insn_flags & ISA_MIPS32R6) {
+ mask &= ~((1 << CP0Ca_WP) & arg1);
+ }
cpu->CP0_Cause = (cpu->CP0_Cause & ~mask) | (arg1 & mask);
@@ -2391,8 +2422,9 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1,
uint32_t fs, uint32_t rt)
}
break;
case 25:
- if (arg1 & 0xffffff00)
+ if ((env->insn_flags & ISA_MIPS32R6) || (arg1 & 0xffffff00)) {
return;
+ }
env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0x017fffff) | ((arg1
& 0xfe) << 24) |
((arg1 & 0x1) << 23);
break;
@@ -2408,9 +2440,13 @@ void helper_ctc1(CPUMIPSState *env, target_ulong arg1,
uint32_t fs, uint32_t rt)
((arg1 & 0x4) << 22);
break;
case 31:
- if (arg1 & 0x007c0000)
- return;
- env->active_fpu.fcr31 = arg1;
+ if (env->insn_flags & ISA_MIPS32R6) {
+ uint32_t mask = 0xfefc0000;
+ env->active_fpu.fcr31 = (arg1 & ~mask) |
+ (env->active_fpu.fcr31 & mask);
+ } else if (!(arg1 & 0x007c0000)) {
+ env->active_fpu.fcr31 = arg1;
+ }
break;
default:
return;
--
2.1.0
- [Qemu-devel] [PULL 03/34] target-mips: distinguish between data load and instruction fetch, (continued)
- [Qemu-devel] [PULL 03/34] target-mips: distinguish between data load and instruction fetch, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 02/34] softmmu: provide softmmu access type enum, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 06/34] target-mips: add new Read-Inhibit and Execute-Inhibit exceptions, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 04/34] target-mips: add RI and XI fields to TLB entry, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 05/34] target-mips: update PageGrain and m{t, f}c0 EntryLo{0, 1}, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 12/34] target-mips: CP0_Status.CU0 no longer allows the user to access CP0, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 08/34] target-mips: add BadInstr and BadInstrP support, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 07/34] target-mips: add TLBINV support, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 10/34] target-mips: add Config5.SBRI, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 11/34] target-mips: implement forbidden slot, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 13/34] target-mips: add restrictions for possible values in registers,
Leon Alrae <=
- [Qemu-devel] [PULL 09/34] target-mips: update cpu_save/cpu_load to support new registers, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 15/34] target-mips: enable features in MIPS64R6-generic CPU, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 16/34] target-mips: add MSA defines and data structure, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 17/34] target-mips: add MSA exceptions, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 19/34] target-mips: stop translation after ctc1, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 18/34] target-mips: remove duplicated mips/ieee mapping function, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 22/34] target-mips: add msa_helper.c, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 21/34] target-mips: add msa_reset(), global msa register, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 23/34] target-mips: add MSA branch instructions, Leon Alrae, 2014/11/03
- [Qemu-devel] [PULL 20/34] target-mips: add MSA opcode enum, Leon Alrae, 2014/11/03