From 66021630879b0cf15ce9077692be2debaa41ecee Mon Sep 17 00:00:00 2001 From: Yongbok Kim Date: Thu, 22 Feb 2018 10:58:03 -0500 Subject: [PATCH] target-mips: add MAAR, MAARI register The MAAR register is a read/write register included in Release 5 of the architecture that defines the accessibility attributes of physical address regions. In particular, MAAR defines whether an instruction fetch or data load can speculatively access a memory region within the physical address bounds specified by MAAR. As QEMU doesn't do speculative access, hence this patch only provides ability to access the registers. Backports commit f6d4dd810983fdf3d1c9fb81838167efef63d1c8 from qemu --- qemu/header_gen.py | 6 ++++ qemu/mips.h | 6 ++++ qemu/mips64.h | 6 ++++ qemu/mips64el.h | 6 ++++ qemu/mipsel.h | 6 ++++ qemu/target-mips/cpu.h | 4 +++ qemu/target-mips/helper.h | 6 ++++ qemu/target-mips/op_helper.c | 45 ++++++++++++++++++++++++++ qemu/target-mips/translate.c | 52 +++++++++++++++++++++++++++++++ qemu/target-mips/translate_init.c | 2 +- 10 files changed, 138 insertions(+), 1 deletion(-) diff --git a/qemu/header_gen.py b/qemu/header_gen.py index 21d09162..43ff0e2e 100644 --- a/qemu/header_gen.py +++ b/qemu/header_gen.py @@ -3603,6 +3603,8 @@ mips_symbols = ( 'helper_mftc0_cause', 'helper_mftc0_status', 'helper_mfc0_lladdr', + 'helper_mfc0_maar', + 'helper_mfhc0_maar', 'helper_mfc0_watchlo', 'helper_mfc0_watchhi', 'helper_mfc0_debug', @@ -3665,6 +3667,9 @@ mips_symbols = ( 'helper_mtc0_config4', 'helper_mtc0_config5', 'helper_mtc0_lladdr', + 'helper_mtc0_maar', + 'helper_mthc0_maar', + 'helper_mtc0_maari', 'helper_mtc0_watchlo', 'helper_mtc0_watchhi', 'helper_mtc0_xcontext', @@ -4107,6 +4112,7 @@ mips_symbols = ( 'helper_dmfc0_tcschedule', 'helper_dmfc0_tcschefback', 'helper_dmfc0_lladdr', + 'helper_dmfc0_maar', 'helper_dmfc0_watchlo', 'helper_dmtc0_entrylo0', 'helper_dmtc0_entrylo1', diff --git a/qemu/mips.h b/qemu/mips.h index 34d6d4fb..3c09ed00 100644 --- a/qemu/mips.h +++ b/qemu/mips.h @@ -3550,6 +3550,8 @@ #define helper_mftc0_cause helper_mftc0_cause_mips #define helper_mftc0_status helper_mftc0_status_mips #define helper_mfc0_lladdr helper_mfc0_lladdr_mips +#define helper_mfc0_maar helper_mfc0_maar_mips +#define helper_mfhc0_maar helper_mfhc0_maar_mips #define helper_mfc0_watchlo helper_mfc0_watchlo_mips #define helper_mfc0_watchhi helper_mfc0_watchhi_mips #define helper_mfc0_debug helper_mfc0_debug_mips @@ -3612,6 +3614,9 @@ #define helper_mtc0_config4 helper_mtc0_config4_mips #define helper_mtc0_config5 helper_mtc0_config5_mips #define helper_mtc0_lladdr helper_mtc0_lladdr_mips +#define helper_mtc0_maar helper_mtc0_maar_mips +#define helper_mthc0_maar helper_mthc0_maar_mips +#define helper_mtc0_maari helper_mtc0_maari_mips #define helper_mtc0_watchlo helper_mtc0_watchlo_mips #define helper_mtc0_watchhi helper_mtc0_watchhi_mips #define helper_mtc0_xcontext helper_mtc0_xcontext_mips @@ -4054,6 +4059,7 @@ #define helper_dmfc0_tcschedule helper_dmfc0_tcschedule_mips #define helper_dmfc0_tcschefback helper_dmfc0_tcschefback_mips #define helper_dmfc0_lladdr helper_dmfc0_lladdr_mips +#define helper_dmfc0_maar helper_dmfc0_maar_mips #define helper_dmfc0_watchlo helper_dmfc0_watchlo_mips #define helper_dmtc0_entrylo0 helper_dmtc0_entrylo0_mips #define helper_dmtc0_entrylo1 helper_dmtc0_entrylo1_mips diff --git a/qemu/mips64.h b/qemu/mips64.h index 7c0be780..d0cf0986 100644 --- a/qemu/mips64.h +++ b/qemu/mips64.h @@ -3550,6 +3550,8 @@ #define helper_mftc0_cause helper_mftc0_cause_mips64 #define helper_mftc0_status helper_mftc0_status_mips64 #define helper_mfc0_lladdr helper_mfc0_lladdr_mips64 +#define helper_mfc0_maar helper_mfc0_maar_mips64 +#define helper_mfhc0_maar helper_mfhc0_maar_mips64 #define helper_mfc0_watchlo helper_mfc0_watchlo_mips64 #define helper_mfc0_watchhi helper_mfc0_watchhi_mips64 #define helper_mfc0_debug helper_mfc0_debug_mips64 @@ -3612,6 +3614,9 @@ #define helper_mtc0_config4 helper_mtc0_config4_mips64 #define helper_mtc0_config5 helper_mtc0_config5_mips64 #define helper_mtc0_lladdr helper_mtc0_lladdr_mips64 +#define helper_mtc0_maar helper_mtc0_maar_mips64 +#define helper_mthc0_maar helper_mthc0_maar_mips64 +#define helper_mtc0_maari helper_mtc0_maari_mips64 #define helper_mtc0_watchlo helper_mtc0_watchlo_mips64 #define helper_mtc0_watchhi helper_mtc0_watchhi_mips64 #define helper_mtc0_xcontext helper_mtc0_xcontext_mips64 @@ -4054,6 +4059,7 @@ #define helper_dmfc0_tcschedule helper_dmfc0_tcschedule_mips64 #define helper_dmfc0_tcschefback helper_dmfc0_tcschefback_mips64 #define helper_dmfc0_lladdr helper_dmfc0_lladdr_mips64 +#define helper_dmfc0_maar helper_dmfc0_maar_mips64 #define helper_dmfc0_watchlo helper_dmfc0_watchlo_mips64 #define helper_dmtc0_entrylo0 helper_dmtc0_entrylo0_mips64 #define helper_dmtc0_entrylo1 helper_dmtc0_entrylo1_mips64 diff --git a/qemu/mips64el.h b/qemu/mips64el.h index 0c945e5f..cf3fc1e8 100644 --- a/qemu/mips64el.h +++ b/qemu/mips64el.h @@ -3550,6 +3550,8 @@ #define helper_mftc0_cause helper_mftc0_cause_mips64el #define helper_mftc0_status helper_mftc0_status_mips64el #define helper_mfc0_lladdr helper_mfc0_lladdr_mips64el +#define helper_mfc0_maar helper_mfc0_maar_mips64el +#define helper_mfhc0_maar helper_mfhc0_maar_mips64el #define helper_mfc0_watchlo helper_mfc0_watchlo_mips64el #define helper_mfc0_watchhi helper_mfc0_watchhi_mips64el #define helper_mfc0_debug helper_mfc0_debug_mips64el @@ -3612,6 +3614,9 @@ #define helper_mtc0_config4 helper_mtc0_config4_mips64el #define helper_mtc0_config5 helper_mtc0_config5_mips64el #define helper_mtc0_lladdr helper_mtc0_lladdr_mips64el +#define helper_mtc0_maar helper_mtc0_maar_mips64el +#define helper_mthc0_maar helper_mthc0_maar_mips64el +#define helper_mtc0_maari helper_mtc0_maari_mips64el #define helper_mtc0_watchlo helper_mtc0_watchlo_mips64el #define helper_mtc0_watchhi helper_mtc0_watchhi_mips64el #define helper_mtc0_xcontext helper_mtc0_xcontext_mips64el @@ -4054,6 +4059,7 @@ #define helper_dmfc0_tcschedule helper_dmfc0_tcschedule_mips64el #define helper_dmfc0_tcschefback helper_dmfc0_tcschefback_mips64el #define helper_dmfc0_lladdr helper_dmfc0_lladdr_mips64el +#define helper_dmfc0_maar helper_dmfc0_maar_mips64el #define helper_dmfc0_watchlo helper_dmfc0_watchlo_mips64el #define helper_dmtc0_entrylo0 helper_dmtc0_entrylo0_mips64el #define helper_dmtc0_entrylo1 helper_dmtc0_entrylo1_mips64el diff --git a/qemu/mipsel.h b/qemu/mipsel.h index b94a0cf7..1af1082d 100644 --- a/qemu/mipsel.h +++ b/qemu/mipsel.h @@ -3550,6 +3550,8 @@ #define helper_mftc0_cause helper_mftc0_cause_mipsel #define helper_mftc0_status helper_mftc0_status_mipsel #define helper_mfc0_lladdr helper_mfc0_lladdr_mipsel +#define helper_mfc0_maar helper_mfc0_maar_mipsel +#define helper_mfhc0_maar helper_mfhc0_maar_mipsel #define helper_mfc0_watchlo helper_mfc0_watchlo_mipsel #define helper_mfc0_watchhi helper_mfc0_watchhi_mipsel #define helper_mfc0_debug helper_mfc0_debug_mipsel @@ -3612,6 +3614,9 @@ #define helper_mtc0_config4 helper_mtc0_config4_mipsel #define helper_mtc0_config5 helper_mtc0_config5_mipsel #define helper_mtc0_lladdr helper_mtc0_lladdr_mipsel +#define helper_mtc0_maar helper_mtc0_maar_mipsel +#define helper_mthc0_maar helper_mthc0_maar_mipsel +#define helper_mtc0_maari helper_mtc0_maari_mipsel #define helper_mtc0_watchlo helper_mtc0_watchlo_mipsel #define helper_mtc0_watchhi helper_mtc0_watchhi_mipsel #define helper_mtc0_xcontext helper_mtc0_xcontext_mipsel @@ -4054,6 +4059,7 @@ #define helper_dmfc0_tcschedule helper_dmfc0_tcschedule_mipsel #define helper_dmfc0_tcschefback helper_dmfc0_tcschefback_mipsel #define helper_dmfc0_lladdr helper_dmfc0_lladdr_mipsel +#define helper_dmfc0_maar helper_dmfc0_maar_mipsel #define helper_dmfc0_watchlo helper_dmfc0_watchlo_mipsel #define helper_dmtc0_entrylo0 helper_dmtc0_entrylo0_mipsel #define helper_dmtc0_entrylo1 helper_dmtc0_entrylo1_mipsel diff --git a/qemu/target-mips/cpu.h b/qemu/target-mips/cpu.h index d5dce2ce..133e6508 100644 --- a/qemu/target-mips/cpu.h +++ b/qemu/target-mips/cpu.h @@ -163,6 +163,7 @@ typedef struct mips_def_t mips_def_t; #define MIPS_FPU_MAX 1 #define MIPS_DSP_ACC 4 #define MIPS_KSCRATCH_NUM 6 +#define MIPS_MAAR_MAX 16 /* Must be an even number. */ typedef struct TCState TCState; struct TCState { @@ -481,10 +482,13 @@ struct CPUMIPSState { #define CP0C5_SBRI 6 #define CP0C5_MVH 5 #define CP0C5_LLB 4 +#define CP0C5_MRP 3 #define CP0C5_UFR 2 #define CP0C5_NFExists 0 int32_t CP0_Config6; int32_t CP0_Config7; + uint64_t CP0_MAAR[MIPS_MAAR_MAX]; + int32_t CP0_MAARI; /* XXX: Maybe make LLAddr per-TC? */ uint64_t lladdr; target_ulong llval; diff --git a/qemu/target-mips/helper.h b/qemu/target-mips/helper.h index 5dd0bdb3..770c90cf 100644 --- a/qemu/target-mips/helper.h +++ b/qemu/target-mips/helper.h @@ -77,6 +77,8 @@ DEF_HELPER_1(mftc0_epc, tl, env) DEF_HELPER_1(mftc0_ebase, tl, env) DEF_HELPER_2(mftc0_configx, tl, env, tl) DEF_HELPER_1(mfc0_lladdr, tl, env) +DEF_HELPER_1(mfc0_maar, tl, env) +DEF_HELPER_1(mfhc0_maar, tl, env) DEF_HELPER_2(mfc0_watchlo, tl, env, i32) DEF_HELPER_2(mfc0_watchhi, tl, env, i32) DEF_HELPER_1(mfc0_debug, tl, env) @@ -88,6 +90,7 @@ DEF_HELPER_1(dmfc0_tccontext, tl, env) DEF_HELPER_1(dmfc0_tcschedule, tl, env) DEF_HELPER_1(dmfc0_tcschefback, tl, env) DEF_HELPER_1(dmfc0_lladdr, tl, env) +DEF_HELPER_1(dmfc0_maar, tl, env) DEF_HELPER_2(dmfc0_watchlo, tl, env, i32) #endif /* TARGET_MIPS64 */ @@ -144,6 +147,9 @@ DEF_HELPER_2(mtc0_config3, void, env, tl) DEF_HELPER_2(mtc0_config4, void, env, tl) DEF_HELPER_2(mtc0_config5, void, env, tl) DEF_HELPER_2(mtc0_lladdr, void, env, tl) +DEF_HELPER_2(mtc0_maar, void, env, tl) +DEF_HELPER_2(mthc0_maar, void, env, tl) +DEF_HELPER_2(mtc0_maari, void, env, tl) DEF_HELPER_3(mtc0_watchlo, void, env, tl, i32) DEF_HELPER_3(mtc0_watchhi, void, env, tl, i32) DEF_HELPER_2(mtc0_xcontext, void, env, tl) diff --git a/qemu/target-mips/op_helper.c b/qemu/target-mips/op_helper.c index f6641472..41499199 100644 --- a/qemu/target-mips/op_helper.c +++ b/qemu/target-mips/op_helper.c @@ -887,6 +887,16 @@ target_ulong helper_mfc0_lladdr(CPUMIPSState *env) return (int32_t)(env->lladdr >> env->CP0_LLAddr_shift); } +target_ulong helper_mfc0_maar(CPUMIPSState *env) +{ + return (int32_t) env->CP0_MAAR[env->CP0_MAARI]; +} + +target_ulong helper_mfhc0_maar(CPUMIPSState *env) +{ + return env->CP0_MAAR[env->CP0_MAARI] >> 32; +} + target_ulong helper_mfc0_watchlo(CPUMIPSState *env, uint32_t sel) { return (int32_t)env->CP0_WatchLo[sel]; @@ -953,6 +963,11 @@ target_ulong helper_dmfc0_lladdr(CPUMIPSState *env) return env->lladdr >> env->CP0_LLAddr_shift; } +target_ulong helper_dmfc0_maar(CPUMIPSState *env) +{ + return env->CP0_MAAR[env->CP0_MAARI]; +} + target_ulong helper_dmfc0_watchlo(CPUMIPSState *env, uint32_t sel) { return env->CP0_WatchLo[sel]; @@ -1577,6 +1592,36 @@ void helper_mtc0_lladdr(CPUMIPSState *env, target_ulong arg1) env->lladdr = (env->lladdr & ~mask) | (arg1 & mask); } +#define MTC0_MAAR_MASK(env) \ + ((0x1ULL << 63) | ((env->PAMask >> 4) & ~0xFFFull) | 0x3) + +void helper_mtc0_maar(CPUMIPSState *env, target_ulong arg1) +{ + env->CP0_MAAR[env->CP0_MAARI] = arg1 & MTC0_MAAR_MASK(env); +} + +void helper_mthc0_maar(CPUMIPSState *env, target_ulong arg1) +{ + env->CP0_MAAR[env->CP0_MAARI] = + (((uint64_t) arg1 << 32) & MTC0_MAAR_MASK(env)) | + (env->CP0_MAAR[env->CP0_MAARI] & 0x00000000ffffffffULL); +} + +void helper_mtc0_maari(CPUMIPSState *env, target_ulong arg1) +{ + int index = arg1 & 0x3f; + if (index == 0x3f) { + /* Software may write all ones to INDEX to determine the + maximum value supported. */ + env->CP0_MAARI = MIPS_MAAR_MAX - 1; + } else if (index < MIPS_MAAR_MAX) { + env->CP0_MAARI = index; + } + /* Other than the all ones, if the + value written is not supported, then INDEX is unchanged + from its previous value. */ +} + void helper_mtc0_watchlo(CPUMIPSState *env, target_ulong arg1, uint32_t sel) { /* Watch exceptions for instructions, data loads, data stores diff --git a/qemu/target-mips/translate.c b/qemu/target-mips/translate.c index 376eebc7..48c4ca04 100644 --- a/qemu/target-mips/translate.c +++ b/qemu/target-mips/translate.c @@ -1418,6 +1418,7 @@ typedef struct DisasContext { bool ps; bool vp; bool cmgcr; + bool mrp; // Unicorn engine struct uc_struct *uc; } DisasContext; @@ -4885,6 +4886,11 @@ static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel) ctx->CP0_LLAddr_shift); rn = "LLAddr"; break; + case 1: + CP0_CHECK(ctx->mrp); + gen_helper_mfhc0_maar(s, arg, s->cpu_env); + rn = "MAAR"; + break; default: goto cp0_unimplemented; } @@ -4955,6 +4961,11 @@ static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel) treating MTHC0 to LLAddr as NOP. */ rn = "LLAddr"; break; + case 1: + CP0_CHECK(ctx->mrp); + gen_helper_mthc0_maar(s, s->cpu_env, arg); + rn = "MAAR"; + break; default: goto cp0_unimplemented; } @@ -5425,6 +5436,16 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_helper_mfc0_lladdr(tcg_ctx, arg, tcg_ctx->cpu_env); rn = "LLAddr"; break; + case 1: + CP0_CHECK(ctx->mrp); + gen_helper_mfc0_maar(tcg_ctx, arg, tcg_ctx->cpu_env); + rn = "MAAR"; + break; + case 2: + CP0_CHECK(ctx->mrp); + gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_MAARI)); + rn = "MAARI"; + break; default: goto cp0_unimplemented; } @@ -6070,6 +6091,16 @@ static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_helper_mtc0_lladdr(tcg_ctx, tcg_ctx->cpu_env, arg); rn = "LLAddr"; break; + case 1: + CP0_CHECK(ctx->mrp); + gen_helper_mtc0_maar(tcg_ctx, tcg_ctx->cpu_env, arg); + rn = "MAAR"; + break; + case 2: + CP0_CHECK(ctx->mrp); + gen_helper_mtc0_maari(tcg_ctx, tcg_ctx->cpu_env, arg); + rn = "MAARI"; + break; default: goto cp0_unimplemented; } @@ -6706,6 +6737,16 @@ static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_helper_dmfc0_lladdr(tcg_ctx, arg, tcg_ctx->cpu_env); rn = "LLAddr"; break; + case 1: + CP0_CHECK(ctx->mrp); + gen_helper_dmfc0_maar(tcg_ctx, arg, tcg_ctx->cpu_env); + rn = "MAAR"; + break; + case 2: + CP0_CHECK(ctx->mrp); + gen_mfc0_load32(ctx, arg, offsetof(CPUMIPSState, CP0_MAARI)); + rn = "MAARI"; + break; default: goto cp0_unimplemented; } @@ -7338,6 +7379,16 @@ static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel) gen_helper_mtc0_lladdr(tcg_ctx, tcg_ctx->cpu_env, arg); rn = "LLAddr"; break; + case 1: + CP0_CHECK(ctx->mrp); + gen_helper_mtc0_maar(tcg_ctx, tcg_ctx->cpu_env, arg); + rn = "MAAR"; + break; + case 2: + CP0_CHECK(ctx->mrp); + gen_helper_mtc0_maari(tcg_ctx, tcg_ctx->cpu_env, arg); + rn = "MAARI"; + break; default: goto cp0_unimplemented; } @@ -19846,6 +19897,7 @@ void gen_intermediate_code(CPUMIPSState *env, struct TranslationBlock *tb) ctx.ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) || (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)); ctx.vp = (env->CP0_Config5 >> CP0C5_VP) & 1; + ctx.mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1; restore_cpu_state(env, &ctx); #ifdef CONFIG_USER_ONLY ctx.mem_idx = MIPS_HFLAG_UM; diff --git a/qemu/target-mips/translate_init.c b/qemu/target-mips/translate_init.c index de140e12..7d65263c 100644 --- a/qemu/target-mips/translate_init.c +++ b/qemu/target-mips/translate_init.c @@ -510,7 +510,7 @@ static const mips_def_t mips_defs[] = MIPS_CONFIG4 | (1U << CP0C4_M) | (2 << CP0C4_IE) | (0x1c << CP0C4_KScrExist), 0, - MIPS_CONFIG5 | (1 << CP0C5_MVH) | (1 << CP0C5_LLB), + MIPS_CONFIG5 | (1 << CP0C5_MVH) | (1 << CP0C5_LLB) | (1 << CP0C5_MRP), (1 << CP0C5_K) | (1 << CP0C5_CV) | (1 << CP0C5_MSAEn) | (1 << CP0C5_UFE) | (1 << CP0C5_FRE) | (1 << CP0C5_UFR),