target/arm: Implement TT instruction

Implement the TT instruction which queries the security
state and access permissions of a memory location.

Backports commit 5158de241b0fb344a6c948dfcbc4e611ab5fafbe from qemu
This commit is contained in:
Peter Maydell 2018-03-05 13:28:43 -05:00 committed by Lioncash
parent 4e5ec9c0dc
commit 8fe6b6c308
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
17 changed files with 166 additions and 1 deletions

View file

@ -1098,6 +1098,7 @@
#define gen_helper_v7m_bxns gen_helper_v7m_bxns_aarch64
#define gen_helper_v7m_mrs gen_helper_v7m_mrs_aarch64
#define gen_helper_v7m_msr gen_helper_v7m_msr_aarch64
#define gen_helper_v7m_tt gen_helper_v7m_tt_aarch64
#define gen_helper_vfp_absd gen_helper_vfp_absd_aarch64
#define gen_helper_vfp_abss gen_helper_vfp_abss_aarch64
#define gen_helper_vfp_addd gen_helper_vfp_addd_aarch64
@ -2059,6 +2060,7 @@
#define helper_v7m_bxns helper_v7m_bxns_aarch64
#define helper_v7m_mrs helper_v7m_mrs_aarch64
#define helper_v7m_msr helper_v7m_msr_aarch64
#define helper_v7m_tt helper_v7m_tt_aarch64
#define helper_vfp_absd helper_vfp_absd_aarch64
#define helper_vfp_abss helper_vfp_abss_aarch64
#define helper_vfp_addd helper_vfp_addd_aarch64

View file

@ -1098,6 +1098,7 @@
#define gen_helper_v7m_bxns gen_helper_v7m_bxns_aarch64eb
#define gen_helper_v7m_mrs gen_helper_v7m_mrs_aarch64eb
#define gen_helper_v7m_msr gen_helper_v7m_msr_aarch64eb
#define gen_helper_v7m_tt gen_helper_v7m_tt_aarch64eb
#define gen_helper_vfp_absd gen_helper_vfp_absd_aarch64eb
#define gen_helper_vfp_abss gen_helper_vfp_abss_aarch64eb
#define gen_helper_vfp_addd gen_helper_vfp_addd_aarch64eb
@ -2059,6 +2060,7 @@
#define helper_v7m_bxns helper_v7m_bxns_aarch64eb
#define helper_v7m_mrs helper_v7m_mrs_aarch64eb
#define helper_v7m_msr helper_v7m_msr_aarch64eb
#define helper_v7m_tt helper_v7m_tt_aarch64eb
#define helper_vfp_absd helper_vfp_absd_aarch64eb
#define helper_vfp_abss helper_vfp_abss_aarch64eb
#define helper_vfp_addd helper_vfp_addd_aarch64eb

View file

@ -1098,6 +1098,7 @@
#define gen_helper_v7m_bxns gen_helper_v7m_bxns_arm
#define gen_helper_v7m_mrs gen_helper_v7m_mrs_arm
#define gen_helper_v7m_msr gen_helper_v7m_msr_arm
#define gen_helper_v7m_tt gen_helper_v7m_tt_arm
#define gen_helper_vfp_absd gen_helper_vfp_absd_arm
#define gen_helper_vfp_abss gen_helper_vfp_abss_arm
#define gen_helper_vfp_addd gen_helper_vfp_addd_arm
@ -2059,6 +2060,7 @@
#define helper_v7m_bxns helper_v7m_bxns_arm
#define helper_v7m_mrs helper_v7m_mrs_arm
#define helper_v7m_msr helper_v7m_msr_arm
#define helper_v7m_tt helper_v7m_tt_arm
#define helper_vfp_absd helper_vfp_absd_arm
#define helper_vfp_abss helper_vfp_abss_arm
#define helper_vfp_addd helper_vfp_addd_arm

View file

@ -1098,6 +1098,7 @@
#define gen_helper_v7m_bxns gen_helper_v7m_bxns_armeb
#define gen_helper_v7m_mrs gen_helper_v7m_mrs_armeb
#define gen_helper_v7m_msr gen_helper_v7m_msr_armeb
#define gen_helper_v7m_tt gen_helper_v7m_tt_armeb
#define gen_helper_vfp_absd gen_helper_vfp_absd_armeb
#define gen_helper_vfp_abss gen_helper_vfp_abss_armeb
#define gen_helper_vfp_addd gen_helper_vfp_addd_armeb
@ -2059,6 +2060,7 @@
#define helper_v7m_bxns helper_v7m_bxns_armeb
#define helper_v7m_mrs helper_v7m_mrs_armeb
#define helper_v7m_msr helper_v7m_msr_armeb
#define helper_v7m_tt helper_v7m_tt_armeb
#define helper_vfp_absd helper_vfp_absd_armeb
#define helper_vfp_abss helper_vfp_abss_armeb
#define helper_vfp_addd helper_vfp_addd_armeb

View file

@ -1104,6 +1104,7 @@ symbols = (
'gen_helper_v7m_bxns',
'gen_helper_v7m_mrs',
'gen_helper_v7m_msr',
'gen_helper_v7m_tt',
'gen_helper_vfp_absd',
'gen_helper_vfp_abss',
'gen_helper_vfp_addd',
@ -2065,6 +2066,7 @@ symbols = (
'helper_v7m_bxns',
'helper_v7m_mrs',
'helper_v7m_msr',
'helper_v7m_tt',
'helper_vfp_absd',
'helper_vfp_abss',
'helper_vfp_addd',

View file

@ -1098,6 +1098,7 @@
#define gen_helper_v7m_bxns gen_helper_v7m_bxns_m68k
#define gen_helper_v7m_mrs gen_helper_v7m_mrs_m68k
#define gen_helper_v7m_msr gen_helper_v7m_msr_m68k
#define gen_helper_v7m_tt gen_helper_v7m_tt_m68k
#define gen_helper_vfp_absd gen_helper_vfp_absd_m68k
#define gen_helper_vfp_abss gen_helper_vfp_abss_m68k
#define gen_helper_vfp_addd gen_helper_vfp_addd_m68k
@ -2059,6 +2060,7 @@
#define helper_v7m_bxns helper_v7m_bxns_m68k
#define helper_v7m_mrs helper_v7m_mrs_m68k
#define helper_v7m_msr helper_v7m_msr_m68k
#define helper_v7m_tt helper_v7m_tt_m68k
#define helper_vfp_absd helper_vfp_absd_m68k
#define helper_vfp_abss helper_vfp_abss_m68k
#define helper_vfp_addd helper_vfp_addd_m68k

View file

@ -1098,6 +1098,7 @@
#define gen_helper_v7m_bxns gen_helper_v7m_bxns_mips
#define gen_helper_v7m_mrs gen_helper_v7m_mrs_mips
#define gen_helper_v7m_msr gen_helper_v7m_msr_mips
#define gen_helper_v7m_tt gen_helper_v7m_tt_mips
#define gen_helper_vfp_absd gen_helper_vfp_absd_mips
#define gen_helper_vfp_abss gen_helper_vfp_abss_mips
#define gen_helper_vfp_addd gen_helper_vfp_addd_mips
@ -2059,6 +2060,7 @@
#define helper_v7m_bxns helper_v7m_bxns_mips
#define helper_v7m_mrs helper_v7m_mrs_mips
#define helper_v7m_msr helper_v7m_msr_mips
#define helper_v7m_tt helper_v7m_tt_mips
#define helper_vfp_absd helper_vfp_absd_mips
#define helper_vfp_abss helper_vfp_abss_mips
#define helper_vfp_addd helper_vfp_addd_mips

View file

@ -1098,6 +1098,7 @@
#define gen_helper_v7m_bxns gen_helper_v7m_bxns_mips64
#define gen_helper_v7m_mrs gen_helper_v7m_mrs_mips64
#define gen_helper_v7m_msr gen_helper_v7m_msr_mips64
#define gen_helper_v7m_tt gen_helper_v7m_tt_mips64
#define gen_helper_vfp_absd gen_helper_vfp_absd_mips64
#define gen_helper_vfp_abss gen_helper_vfp_abss_mips64
#define gen_helper_vfp_addd gen_helper_vfp_addd_mips64
@ -2059,6 +2060,7 @@
#define helper_v7m_bxns helper_v7m_bxns_mips64
#define helper_v7m_mrs helper_v7m_mrs_mips64
#define helper_v7m_msr helper_v7m_msr_mips64
#define helper_v7m_tt helper_v7m_tt_mips64
#define helper_vfp_absd helper_vfp_absd_mips64
#define helper_vfp_abss helper_vfp_abss_mips64
#define helper_vfp_addd helper_vfp_addd_mips64

View file

@ -1098,6 +1098,7 @@
#define gen_helper_v7m_bxns gen_helper_v7m_bxns_mips64el
#define gen_helper_v7m_mrs gen_helper_v7m_mrs_mips64el
#define gen_helper_v7m_msr gen_helper_v7m_msr_mips64el
#define gen_helper_v7m_tt gen_helper_v7m_tt_mips64el
#define gen_helper_vfp_absd gen_helper_vfp_absd_mips64el
#define gen_helper_vfp_abss gen_helper_vfp_abss_mips64el
#define gen_helper_vfp_addd gen_helper_vfp_addd_mips64el
@ -2059,6 +2060,7 @@
#define helper_v7m_bxns helper_v7m_bxns_mips64el
#define helper_v7m_mrs helper_v7m_mrs_mips64el
#define helper_v7m_msr helper_v7m_msr_mips64el
#define helper_v7m_tt helper_v7m_tt_mips64el
#define helper_vfp_absd helper_vfp_absd_mips64el
#define helper_vfp_abss helper_vfp_abss_mips64el
#define helper_vfp_addd helper_vfp_addd_mips64el

View file

@ -1098,6 +1098,7 @@
#define gen_helper_v7m_bxns gen_helper_v7m_bxns_mipsel
#define gen_helper_v7m_mrs gen_helper_v7m_mrs_mipsel
#define gen_helper_v7m_msr gen_helper_v7m_msr_mipsel
#define gen_helper_v7m_tt gen_helper_v7m_tt_mipsel
#define gen_helper_vfp_absd gen_helper_vfp_absd_mipsel
#define gen_helper_vfp_abss gen_helper_vfp_abss_mipsel
#define gen_helper_vfp_addd gen_helper_vfp_addd_mipsel
@ -2059,6 +2060,7 @@
#define helper_v7m_bxns helper_v7m_bxns_mipsel
#define helper_v7m_mrs helper_v7m_mrs_mipsel
#define helper_v7m_msr helper_v7m_msr_mipsel
#define helper_v7m_tt helper_v7m_tt_mipsel
#define helper_vfp_absd helper_vfp_absd_mipsel
#define helper_vfp_abss helper_vfp_abss_mipsel
#define helper_vfp_addd helper_vfp_addd_mipsel

View file

@ -1098,6 +1098,7 @@
#define gen_helper_v7m_bxns gen_helper_v7m_bxns_powerpc
#define gen_helper_v7m_mrs gen_helper_v7m_mrs_powerpc
#define gen_helper_v7m_msr gen_helper_v7m_msr_powerpc
#define gen_helper_v7m_tt gen_helper_v7m_tt_powerpc
#define gen_helper_vfp_absd gen_helper_vfp_absd_powerpc
#define gen_helper_vfp_abss gen_helper_vfp_abss_powerpc
#define gen_helper_vfp_addd gen_helper_vfp_addd_powerpc
@ -2059,6 +2060,7 @@
#define helper_v7m_bxns helper_v7m_bxns_powerpc
#define helper_v7m_mrs helper_v7m_mrs_powerpc
#define helper_v7m_msr helper_v7m_msr_powerpc
#define helper_v7m_tt helper_v7m_tt_powerpc
#define helper_vfp_absd helper_vfp_absd_powerpc
#define helper_vfp_abss helper_vfp_abss_powerpc
#define helper_vfp_addd helper_vfp_addd_powerpc

View file

@ -1098,6 +1098,7 @@
#define gen_helper_v7m_bxns gen_helper_v7m_bxns_sparc
#define gen_helper_v7m_mrs gen_helper_v7m_mrs_sparc
#define gen_helper_v7m_msr gen_helper_v7m_msr_sparc
#define gen_helper_v7m_tt gen_helper_v7m_tt_sparc
#define gen_helper_vfp_absd gen_helper_vfp_absd_sparc
#define gen_helper_vfp_abss gen_helper_vfp_abss_sparc
#define gen_helper_vfp_addd gen_helper_vfp_addd_sparc
@ -2059,6 +2060,7 @@
#define helper_v7m_bxns helper_v7m_bxns_sparc
#define helper_v7m_mrs helper_v7m_mrs_sparc
#define helper_v7m_msr helper_v7m_msr_sparc
#define helper_v7m_tt helper_v7m_tt_sparc
#define helper_vfp_absd helper_vfp_absd_sparc
#define helper_vfp_abss helper_vfp_abss_sparc
#define helper_vfp_addd helper_vfp_addd_sparc

View file

@ -1098,6 +1098,7 @@
#define gen_helper_v7m_bxns gen_helper_v7m_bxns_sparc64
#define gen_helper_v7m_mrs gen_helper_v7m_mrs_sparc64
#define gen_helper_v7m_msr gen_helper_v7m_msr_sparc64
#define gen_helper_v7m_tt gen_helper_v7m_tt_sparc64
#define gen_helper_vfp_absd gen_helper_vfp_absd_sparc64
#define gen_helper_vfp_abss gen_helper_vfp_abss_sparc64
#define gen_helper_vfp_addd gen_helper_vfp_addd_sparc64
@ -2059,6 +2060,7 @@
#define helper_v7m_bxns helper_v7m_bxns_sparc64
#define helper_v7m_mrs helper_v7m_mrs_sparc64
#define helper_v7m_msr helper_v7m_msr_sparc64
#define helper_v7m_tt helper_v7m_tt_sparc64
#define helper_vfp_absd helper_vfp_absd_sparc64
#define helper_vfp_abss helper_vfp_abss_sparc64
#define helper_vfp_addd helper_vfp_addd_sparc64

View file

@ -5206,6 +5206,28 @@ void HELPER(v7m_blxns)(CPUARMState *env, uint32_t dest)
g_assert_not_reached();
}
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
{
/* The TT instructions can be used by unprivileged code, but in
* user-only emulation we don't have the MPU.
* Luckily since we know we are NonSecure unprivileged (and that in
* turn means that the A flag wasn't specified), all the bits in the
* register must be zero:
* IREGION: 0 because IRVALID is 0
* IRVALID: 0 because NS
* S: 0 because NS
* NSRW: 0 because NS
* NSR: 0 because NS
* RW: 0 because unpriv and A flag not set
* R: 0 because unpriv and A flag not set
* SRVALID: 0 because NS
* MRVALID: 0 because unpriv and A flag not set
* SREGION: 0 becaus SRVALID is 0
* MREGION: 0 because MRVALID is 0
*/
return 0;
}
void switch_mode(CPUARMState *env, int mode)
{
ARMCPU *cpu = arm_env_get_cpu(env);
@ -9337,6 +9359,92 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t maskreg, uint32_t val)
}
}
uint32_t HELPER(v7m_tt)(CPUARMState *env, uint32_t addr, uint32_t op)
{
/* Implement the TT instruction. op is bits [7:6] of the insn. */
bool forceunpriv = op & 1;
bool alt = op & 2;
V8M_SAttributes sattrs = {0};
uint32_t tt_resp;
bool r, rw, nsr, nsrw, mrvalid;
int prot;
MemTxAttrs attrs = {0};
hwaddr phys_addr;
uint32_t fsr;
ARMMMUIdx mmu_idx;
uint32_t mregion;
bool targetpriv;
bool targetsec = env->v7m.secure;
/* Work out what the security state and privilege level we're
* interested in is...
*/
if (alt) {
targetsec = !targetsec;
}
if (forceunpriv) {
targetpriv = false;
} else {
targetpriv = arm_v7m_is_handler_mode(env) ||
!(env->v7m.control[targetsec] & R_V7M_CONTROL_NPRIV_MASK);
}
/* ...and then figure out which MMU index this is */
mmu_idx = arm_v7m_mmu_idx_for_secstate_and_priv(env, targetsec, targetpriv);
/* We know that the MPU and SAU don't care about the access type
* for our purposes beyond that we don't want to claim to be
* an insn fetch, so we arbitrarily call this a read.
*/
/* MPU region info only available for privileged or if
* inspecting the other MPU state.
*/
if (arm_current_el(env) != 0 || alt) {
/* We can ignore the return value as prot is always set */
pmsav8_mpu_lookup(env, addr, MMU_DATA_LOAD, mmu_idx,
&phys_addr, &attrs, &prot, &fsr, &mregion);
if (mregion == -1) {
mrvalid = false;
mregion = 0;
} else {
mrvalid = true;
}
r = prot & PAGE_READ;
rw = prot & PAGE_WRITE;
} else {
r = false;
rw = false;
mrvalid = false;
mregion = 0;
}
if (env->v7m.secure) {
v8m_security_lookup(env, addr, MMU_DATA_LOAD, mmu_idx, &sattrs);
nsr = sattrs.ns && r;
nsrw = sattrs.ns && rw;
} else {
sattrs.ns = true;
nsr = false;
nsrw = false;
}
tt_resp = (sattrs.iregion << 24) |
(sattrs.irvalid << 23) |
((!sattrs.ns) << 22) |
(nsrw << 21) |
(nsr << 20) |
(rw << 19) |
(r << 18) |
(sattrs.srvalid << 17) |
(mrvalid << 16) |
(sattrs.sregion << 8) |
mregion;
return tt_resp;
}
#endif
void HELPER(dc_zva)(CPUARMState *env, uint64_t vaddr_in)

View file

@ -68,6 +68,8 @@ DEF_HELPER_2(v7m_mrs, i32, env, i32)
DEF_HELPER_2(v7m_bxns, void, env, i32)
DEF_HELPER_2(v7m_blxns, void, env, i32)
DEF_HELPER_3(v7m_tt, i32, env, i32, i32)
DEF_HELPER_4(access_check_cp_reg, void, env, ptr, i32, i32)
DEF_HELPER_3(set_cp_reg, void, env, ptr, i32)
DEF_HELPER_2(get_cp_reg, i32, env, ptr)

View file

@ -9993,7 +9993,7 @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
if (insn & (1 << 22)) {
/* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
* - load/store doubleword, load/store exclusive, ldacq/strel,
* table branch.
* table branch, TT.
*/
if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
arm_dc_feature(s, ARM_FEATURE_V8)) {
@ -10070,8 +10070,35 @@ static int disas_thumb2_insn(DisasContext *s, uint32_t insn)
} else if ((insn & (1 << 23)) == 0) {
/* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
* - load/store exclusive word
* - TT (v8M only)
*/
if (rs == 15) {
if (!(insn & (1 << 20)) &&
arm_dc_feature(s, ARM_FEATURE_M) &&
arm_dc_feature(s, ARM_FEATURE_V8)) {
/* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
* - TT (v8M only)
*/
bool alt = insn & (1 << 7);
TCGv_i32 addr, op, ttresp;
if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
/* we UNDEF for these UNPREDICTABLE cases */
goto illegal_op;
}
if (alt && !s->v8m_secure) {
goto illegal_op;
}
addr = load_reg(s, rn);
op = tcg_const_i32(tcg_ctx, extract32(insn, 6, 2));
ttresp = tcg_temp_new_i32(tcg_ctx);
gen_helper_v7m_tt(tcg_ctx, ttresp, tcg_ctx->cpu_env, addr, op);
tcg_temp_free_i32(tcg_ctx, addr);
tcg_temp_free_i32(tcg_ctx, op);
store_reg(s, rd, ttresp);
}
goto illegal_op;
}
addr = tcg_temp_local_new_i32(tcg_ctx);

View file

@ -1098,6 +1098,7 @@
#define gen_helper_v7m_bxns gen_helper_v7m_bxns_x86_64
#define gen_helper_v7m_mrs gen_helper_v7m_mrs_x86_64
#define gen_helper_v7m_msr gen_helper_v7m_msr_x86_64
#define gen_helper_v7m_tt gen_helper_v7m_tt_x86_64
#define gen_helper_vfp_absd gen_helper_vfp_absd_x86_64
#define gen_helper_vfp_abss gen_helper_vfp_abss_x86_64
#define gen_helper_vfp_addd gen_helper_vfp_addd_x86_64
@ -2059,6 +2060,7 @@
#define helper_v7m_bxns helper_v7m_bxns_x86_64
#define helper_v7m_mrs helper_v7m_mrs_x86_64
#define helper_v7m_msr helper_v7m_msr_x86_64
#define helper_v7m_tt helper_v7m_tt_x86_64
#define helper_vfp_absd helper_vfp_absd_x86_64
#define helper_vfp_abss helper_vfp_abss_x86_64
#define helper_vfp_addd helper_vfp_addd_x86_64