mirror of
https://gitlab.com/qemu-project/qemu.git
synced 2026-10-28 11:54:41 +08:00
target/hexagon: implement control flow integrity (CFI)
Implement v83 restricted indirect-control-flow instructions and validate their targets. Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com> Reviewed-by: Marco Liebel <marco.liebel@oss.qualcomm.com> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
This commit is contained in:
1 parent
eada2cdbcf
commit
e35867b9ca
24 files changed
+307
-31
No files matched your search
@@ -49,6 +49,9 @@ void cpu_loop(CPUHexagonState *env)
|
||||
break;
|
||||
case HEX_EVENT_TRAP0:
|
||||
case HEX_EVENT_TRAP2:
|
||||
/* Exception entry ends any pending restricted-branch check. */
|
||||
env->cfi_active = 0;
|
||||
env->cfi_updated = 0;
|
||||
syscallnum = env->gpr[6];
|
||||
env->gpr[HEX_REG_PC] += 4;
|
||||
ret = do_syscall(env,
|
||||
@@ -78,6 +81,12 @@ void cpu_loop(CPUHexagonState *env)
|
||||
force_sig_fault(TARGET_SIGSEGV, TARGET_SEGV_BNDERR,
|
||||
env->gpr[HEX_REG_PC]);
|
||||
break;
|
||||
case HEX_CAUSE_CFI_VIOLATION:
|
||||
env->cfi_active = 0;
|
||||
env->cfi_updated = 0;
|
||||
force_sig_fault(TARGET_SIGILL, TARGET_ILL_ILLOPC,
|
||||
env->gpr[HEX_REG_PC]);
|
||||
break;
|
||||
case HEX_CAUSE_PRIV_USER_NO_GINSN:
|
||||
case HEX_CAUSE_PRIV_USER_NO_SINSN:
|
||||
case HEX_CAUSE_INVALID_PACKET:
|
||||
|
||||
@@ -106,6 +106,10 @@ static void setup_sigcontext(struct target_sigcontext *sc, CPUHexagonState *env)
|
||||
|
||||
__put_user(env->gpr[HEX_REG_CS0], &sc->sc_regs.cs0);
|
||||
__put_user(env->gpr[HEX_REG_CS1], &sc->sc_regs.cs1);
|
||||
/* Preserve a pending restricted-branch landing pad across the signal. */
|
||||
__put_user(env->cfi_active, &sc->sc_regs.pad1);
|
||||
env->cfi_active = 0;
|
||||
env->cfi_updated = 0;
|
||||
}
|
||||
|
||||
static void setup_ucontext(struct target_ucontext *uc,
|
||||
@@ -176,6 +180,7 @@ static void restore_sigcontext(CPUHexagonState *env,
|
||||
struct target_sigcontext *sc)
|
||||
{
|
||||
abi_ulong preds;
|
||||
abi_ulong cfi;
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
__get_user(env->gpr[HEX_REG_R00 + i], &sc->sc_regs.gpr[i]);
|
||||
@@ -199,6 +204,9 @@ static void restore_sigcontext(CPUHexagonState *env,
|
||||
|
||||
__get_user(env->gpr[HEX_REG_CS0], &sc->sc_regs.cs0);
|
||||
__get_user(env->gpr[HEX_REG_CS1], &sc->sc_regs.cs1);
|
||||
__get_user(cfi, &sc->sc_regs.pad1);
|
||||
env->cfi_active = cfi & 1;
|
||||
env->cfi_updated = 0;
|
||||
}
|
||||
|
||||
static void restore_ucontext(CPUHexagonState *env, struct target_ucontext *uc)
|
||||
|
||||
@@ -200,6 +200,7 @@ DEF_ATTRIB(NOTE_SHIFT_RESOURCE, "Uses the HVX shift resource.", "", "")
|
||||
/* Restrictions to make note of */
|
||||
DEF_ATTRIB(RESTRICT_NOSLOT1_STORE, "Packet must not have slot 1 store", "", "")
|
||||
DEF_ATTRIB(RESTRICT_LATEPRED, "Predicate can not be used as a .new.", "", "")
|
||||
DEF_ATTRIB(RESTRICT_TARGET, "Restricted branch target instruction", "", "")
|
||||
|
||||
/* HVX IEEE FP extension attributes */
|
||||
DEF_ATTRIB(HVX_IEEE_FP, "HVX IEEE FP extension instruction", "", "")
|
||||
|
||||
@@ -452,6 +452,9 @@ void hexagon_cpu_soft_reset(CPUHexagonState *env)
|
||||
|
||||
BQL_LOCK_GUARD();
|
||||
env->llsc_addr = ~0;
|
||||
env->cfi_active = 0;
|
||||
env->cfi_active_log = 0;
|
||||
env->cfi_updated = 0;
|
||||
env->t_sreg[HEX_SREG_SSR] = 0;
|
||||
hexagon_ssr_set_cause(env, HEX_CAUSE_RESET);
|
||||
|
||||
@@ -489,6 +492,9 @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
|
||||
set_float_default_nan_pattern(0b01111111, &env->hvx_fp_status);
|
||||
|
||||
env->llsc_addr = ~0;
|
||||
env->cfi_active = 0;
|
||||
env->cfi_active_log = 0;
|
||||
env->cfi_updated = 0;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
memset(env->t_sreg, 0, sizeof(uint32_t) * NUM_SREGS);
|
||||
memset(env->greg, 0, sizeof(uint32_t) * NUM_GREGS);
|
||||
|
||||
@@ -132,6 +132,9 @@ typedef struct CPUArchState {
|
||||
target_ulong gpr[TOTAL_PER_THREAD_REGS];
|
||||
target_ulong pred[NUM_PREGS];
|
||||
uint32_t cause_code;
|
||||
uint32_t cfi_active;
|
||||
uint32_t cfi_active_log;
|
||||
uint32_t cfi_updated;
|
||||
|
||||
/* For comparing with LLDB on target - see adjust_stack_ptrs function */
|
||||
target_ulong last_pc_dumped;
|
||||
|
||||
@@ -74,6 +74,7 @@ enum hex_cause {
|
||||
HEX_CAUSE_TRAP1 = 0x009,
|
||||
HEX_CAUSE_FETCH_NO_XPAGE = 0x011,
|
||||
HEX_CAUSE_FETCH_NO_UPAGE = 0x012,
|
||||
HEX_CAUSE_CFI_VIOLATION = 0x014,
|
||||
HEX_CAUSE_INVALID_PACKET = 0x015,
|
||||
HEX_CAUSE_INVALID_OPCODE = 0x015, /* alias: same cause as INVALID_PACKET */
|
||||
HEX_CAUSE_NO_COPROC_ENABLE = 0x016,
|
||||
|
||||
+62
-28
@@ -531,34 +531,8 @@
|
||||
do { RsV = RsV; } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
#define fGEN_TCG_V2_CHECK_AND_WRITE_VSP(VSP) \
|
||||
do { \
|
||||
TCGLabel *write_vsp = gen_new_label(); \
|
||||
tcg_gen_brcond_tl(TCG_COND_GEU, VSP, \
|
||||
hex_gpr[HEX_REG_VFRAMELIMIT], write_vsp); \
|
||||
gen_precise_exception(HEX_CAUSE_VECTOR_STACK_OVERFLOW, ctx->pkt.pc); \
|
||||
gen_set_label(write_vsp); \
|
||||
tcg_gen_mov_tl(hex_gpr[HEX_REG_VSP], VSP); \
|
||||
} while (0)
|
||||
#else
|
||||
#define fGEN_TCG_V2_CHECK_AND_WRITE_VSP(VSP) \
|
||||
do { \
|
||||
TCGLabel *write_vsp = gen_new_label(); \
|
||||
TCGv mode = tcg_temp_new(); \
|
||||
tcg_gen_andi_tl(mode, hex_t_sreg[HEX_SREG_SSR], \
|
||||
1 << reg_field_info[SSR_EX].offset); \
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, mode, 0, write_vsp); \
|
||||
tcg_gen_andi_tl(mode, hex_t_sreg[HEX_SREG_SSR], \
|
||||
1 << reg_field_info[SSR_UM].offset); \
|
||||
tcg_gen_brcondi_tl(TCG_COND_EQ, mode, 0, write_vsp); \
|
||||
tcg_gen_brcond_tl(TCG_COND_GEU, VSP, \
|
||||
hex_gpr[HEX_REG_VFRAMELIMIT], write_vsp); \
|
||||
gen_precise_exception(HEX_CAUSE_VECTOR_STACK_OVERFLOW, ctx->pkt.pc); \
|
||||
gen_set_label(write_vsp); \
|
||||
tcg_gen_mov_tl(hex_gpr[HEX_REG_VSP], VSP); \
|
||||
} while (0)
|
||||
#endif
|
||||
gen_vframecheck(ctx, VSP)
|
||||
#define fGEN_TCG_V2_vallocframe_imm(SHORTCODE) \
|
||||
do { \
|
||||
TCGv vsp = tcg_temp_new(); \
|
||||
@@ -589,6 +563,9 @@
|
||||
#define fGEN_TCG_S2_allocframe(SHORTCODE) \
|
||||
gen_allocframe(ctx, RxV, uiV)
|
||||
|
||||
#define fGEN_TCG_S2_allocframe_rb(SHORTCODE) \
|
||||
fGEN_TCG_S2_allocframe(SHORTCODE)
|
||||
|
||||
/* sub-instruction version (no RxV, so handle it manually) */
|
||||
#define fGEN_TCG_SS2_allocframe(SHORTCODE) \
|
||||
do { \
|
||||
@@ -597,6 +574,9 @@
|
||||
gen_allocframe(ctx, r29, uiV); \
|
||||
} while (0)
|
||||
|
||||
#define fGEN_TCG_SS2_allocframe_rb(SHORTCODE) \
|
||||
fGEN_TCG_SS2_allocframe(SHORTCODE)
|
||||
|
||||
/*
|
||||
* Rdd32 = deallocframe(Rs32):raw
|
||||
* RddV == r31:30
|
||||
@@ -777,6 +757,16 @@
|
||||
gen_callr(ctx, RsV)
|
||||
#define fGEN_TCG_J2_callrh(SHORTCODE) \
|
||||
gen_callr(ctx, RsV)
|
||||
#define fGEN_TCG_J2_callr_rb(SHORTCODE) \
|
||||
do { \
|
||||
gen_callr(ctx, RsV); \
|
||||
gen_set_cfi(ctx); \
|
||||
} while (0)
|
||||
#define fGEN_TCG_J2_callrh_rb(SHORTCODE) \
|
||||
do { \
|
||||
gen_callr(ctx, RsV); \
|
||||
gen_set_cfi(ctx); \
|
||||
} while (0)
|
||||
|
||||
#define fGEN_TCG_J2_callt(SHORTCODE) \
|
||||
gen_cond_call(ctx, PuV, TCG_COND_TSTEQ, riV)
|
||||
@@ -786,6 +776,16 @@
|
||||
gen_cond_callr(ctx, TCG_COND_TSTEQ, PuV, RsV)
|
||||
#define fGEN_TCG_J2_callrf(SHORTCODE) \
|
||||
gen_cond_callr(ctx, TCG_COND_TSTNE, PuV, RsV)
|
||||
#define fGEN_TCG_J2_callrt_rb(SHORTCODE) \
|
||||
do { \
|
||||
gen_cond_callr(ctx, TCG_COND_TSTEQ, PuV, RsV); \
|
||||
gen_cond_set_cfi(ctx, true, PuV, -1); \
|
||||
} while (0)
|
||||
#define fGEN_TCG_J2_callrf_rb(SHORTCODE) \
|
||||
do { \
|
||||
gen_cond_callr(ctx, TCG_COND_TSTNE, PuV, RsV); \
|
||||
gen_cond_set_cfi(ctx, false, PuV, -1); \
|
||||
} while (0)
|
||||
|
||||
#define fGEN_TCG_J2_loop0r(SHORTCODE) \
|
||||
gen_loop0r(ctx, RsV, riV)
|
||||
@@ -1006,6 +1006,39 @@
|
||||
gen_jumpr(ctx, RsV)
|
||||
#define fGEN_TCG_J2_jumprh(SHORTCODE) \
|
||||
gen_jumpr(ctx, RsV)
|
||||
#define fGEN_TCG_J2_jumpr_rb(SHORTCODE) \
|
||||
do { \
|
||||
gen_jumpr(ctx, RsV); \
|
||||
gen_set_cfi_for_target(ctx, RsN); \
|
||||
} while (0)
|
||||
#define fGEN_TCG_J2_jumprh_rb(SHORTCODE) \
|
||||
fGEN_TCG_J2_jumpr_rb(SHORTCODE)
|
||||
#define fGEN_TCG_J2_jumprt_rb(SHORTCODE) \
|
||||
do { \
|
||||
gen_cond_jumpr(ctx, RsV, TCG_COND_TSTEQ, PuV); \
|
||||
gen_cond_set_cfi(ctx, true, PuV, RsN); \
|
||||
} while (0)
|
||||
#define fGEN_TCG_J2_jumprf_rb(SHORTCODE) \
|
||||
do { \
|
||||
gen_cond_jumpr(ctx, RsV, TCG_COND_TSTNE, PuV); \
|
||||
gen_cond_set_cfi(ctx, false, PuV, RsN); \
|
||||
} while (0)
|
||||
#define fGEN_TCG_J2_jumprtpt_rb(SHORTCODE) fGEN_TCG_J2_jumprt_rb(SHORTCODE)
|
||||
#define fGEN_TCG_J2_jumprfpt_rb(SHORTCODE) fGEN_TCG_J2_jumprf_rb(SHORTCODE)
|
||||
#define fGEN_TCG_J2_jumprtnew_rb(SHORTCODE) \
|
||||
do { \
|
||||
gen_cond_jumpr(ctx, RsV, TCG_COND_TSTEQ, PuN); \
|
||||
gen_cond_set_cfi(ctx, true, PuN, RsN); \
|
||||
} while (0)
|
||||
#define fGEN_TCG_J2_jumprfnew_rb(SHORTCODE) \
|
||||
do { \
|
||||
gen_cond_jumpr(ctx, RsV, TCG_COND_TSTNE, PuN); \
|
||||
gen_cond_set_cfi(ctx, false, PuN, RsN); \
|
||||
} while (0)
|
||||
#define fGEN_TCG_J2_jumprtnewpt_rb(SHORTCODE) \
|
||||
fGEN_TCG_J2_jumprtnew_rb(SHORTCODE)
|
||||
#define fGEN_TCG_J2_jumprfnewpt_rb(SHORTCODE) \
|
||||
fGEN_TCG_J2_jumprfnew_rb(SHORTCODE)
|
||||
#define fGEN_TCG_J4_jumpseti(SHORTCODE) \
|
||||
do { \
|
||||
tcg_gen_movi_tl(RdV, UiV); \
|
||||
@@ -1195,7 +1228,7 @@
|
||||
RdV, tcg_constant_tl(0)); \
|
||||
} while (0)
|
||||
|
||||
#define fGEN_TCG_Y2_break(SHORTCODE)
|
||||
#define fGEN_TCG_Y2_break(SHORTCODE) gen_reset_cfi(ctx)
|
||||
#define fGEN_TCG_J2_unpause(SHORTCODE)
|
||||
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
@@ -1477,4 +1510,5 @@
|
||||
#endif
|
||||
|
||||
#define fGEN_TCG_A2_nop(SHORTCODE) do { } while (0)
|
||||
#define fGEN_TCG_A2_nop_rb(SHORTCODE) gen_reset_cfi(ctx)
|
||||
#define fGEN_TCG_SA1_setin1(SHORTCODE) tcg_gen_movi_tl(RdV, -1)
|
||||
@@ -131,11 +131,17 @@
|
||||
*/
|
||||
#define fGEN_TCG_J2_rte(SHORTCODE) \
|
||||
do { \
|
||||
TCGv_i32 cfi = tcg_temp_new_i32(); \
|
||||
TCGv_i32 new_ssr = tcg_temp_new_i32(); \
|
||||
tcg_gen_extract_i32(cfi, hex_t_sreg[HEX_SREG_SSR], \
|
||||
reg_field_info[SSR_CFI].offset, 1); \
|
||||
fSET_CFI(cfi); \
|
||||
tcg_gen_deposit_tl(new_ssr, hex_t_sreg[HEX_SREG_SSR], \
|
||||
tcg_constant_tl(0), \
|
||||
reg_field_info[SSR_EX].offset, \
|
||||
reg_field_info[SSR_EX].width); \
|
||||
tcg_gen_deposit_tl(new_ssr, new_ssr, tcg_constant_tl(0), \
|
||||
reg_field_info[SSR_CFI].offset, 1); \
|
||||
gen_log_sreg_write(ctx, HEX_SREG_SSR, new_ssr); \
|
||||
gen_jumpr(ctx, hex_t_sreg[HEX_SREG_ELR]); \
|
||||
} while (0)
|
||||
|
||||
@@ -1085,6 +1085,42 @@ static void gen_cond_callr(DisasContext *ctx,
|
||||
gen_set_label(skip);
|
||||
}
|
||||
|
||||
static void gen_set_cfi(DisasContext *ctx)
|
||||
{
|
||||
fSET_CFI(tcg_constant_i32(1));
|
||||
}
|
||||
|
||||
static void gen_reset_cfi(DisasContext *ctx)
|
||||
{
|
||||
fSET_CFI(tcg_constant_i32(0));
|
||||
}
|
||||
|
||||
/* Indirect transfers through LR are returns, which do not set the CFI state */
|
||||
static void gen_set_cfi_for_target(DisasContext *ctx, int rs_num)
|
||||
{
|
||||
if (rs_num == HEX_REG_LR) {
|
||||
gen_reset_cfi(ctx);
|
||||
} else {
|
||||
gen_set_cfi(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the CFI state if the predicate (true if @sense, else false) holds.
|
||||
* @rs_num is the jump target register, or -1 for calls.
|
||||
*/
|
||||
static void gen_cond_set_cfi(DisasContext *ctx, bool sense, TCGv pred,
|
||||
int rs_num)
|
||||
{
|
||||
TCGv lsb = tcg_temp_new();
|
||||
TCGLabel *skip = gen_new_label();
|
||||
|
||||
tcg_gen_andi_tl(lsb, pred, 1);
|
||||
tcg_gen_brcondi_tl(sense ? TCG_COND_EQ : TCG_COND_NE, lsb, 0, skip);
|
||||
gen_set_cfi_for_target(ctx, rs_num);
|
||||
gen_set_label(skip);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_HEXAGON_IDEF_PARSER
|
||||
/* frame = ((LR << 32) | FP) ^ (FRAMEKEY << 32)) */
|
||||
static TCGv_i64 gen_frame_scramble(void)
|
||||
|
||||
@@ -48,6 +48,7 @@ static void set_ssr_ex_cause(CPUHexagonState *env, int ex, uint32_t cause)
|
||||
old = env->t_sreg[HEX_SREG_SSR];
|
||||
SET_SYSTEM_FIELD(env, HEX_SREG_SSR, SSR_EX, ex);
|
||||
SET_SYSTEM_FIELD(env, HEX_SREG_SSR, SSR_CAUSE, cause);
|
||||
SET_SYSTEM_FIELD(env, HEX_SREG_SSR, SSR_CFI, env->cfi_active);
|
||||
new = env->t_sreg[HEX_SREG_SSR];
|
||||
hexagon_modify_ssr(env, new, old);
|
||||
}
|
||||
@@ -373,6 +374,8 @@ static void hex_accept_int(CPUHexagonState *env, int int_num)
|
||||
env->threadId);
|
||||
|
||||
set_ssr_ex_cause(env, 1, HEX_CAUSE_INT0 | int_num);
|
||||
env->cfi_active = 0;
|
||||
env->cfi_updated = 0;
|
||||
set_elr(env, elr);
|
||||
env->gpr[HEX_REG_PC] = evb | (cs->exception_index << 2);
|
||||
}
|
||||
|
||||
@@ -757,7 +757,17 @@ void hexagon_cpu_do_interrupt(CPUState *cs)
|
||||
env->llsc_addr = ~0;
|
||||
|
||||
ssr = env->t_sreg[HEX_SREG_SSR];
|
||||
if (GET_SSR_FIELD(SSR_EX, ssr) == 0) {
|
||||
SET_SSR_FIELD(env, SSR_CFI, env->cfi_active);
|
||||
}
|
||||
env->cfi_active = 0;
|
||||
env->cfi_updated = 0;
|
||||
|
||||
if (GET_SSR_FIELD(SSR_EX, ssr) == 1) {
|
||||
/*
|
||||
* Double exception: keep the SSR.CFI value saved by the first
|
||||
* exception, which a later rte would need to restore.
|
||||
*/
|
||||
if (cpu->globalregs) {
|
||||
hexagon_globalreg_write(cpu->globalregs, HEX_SREG_DIAG,
|
||||
env->cause_code, env->threadId);
|
||||
@@ -861,6 +871,7 @@ void hexagon_cpu_do_interrupt(CPUState *cs)
|
||||
switch (env->cause_code) {
|
||||
case HEX_CAUSE_FETCH_NO_XPAGE:
|
||||
case HEX_CAUSE_FETCH_NO_UPAGE:
|
||||
case HEX_CAUSE_CFI_VIOLATION:
|
||||
case HEX_CAUSE_PRIV_NO_READ:
|
||||
case HEX_CAUSE_PRIV_NO_UREAD:
|
||||
case HEX_CAUSE_PRIV_NO_WRITE:
|
||||
|
||||
@@ -241,6 +241,9 @@ Q6INSN(A2_minup,"Rdd32=minu(Rtt32,Rss32)",ATTRIBS(A_ARCHV3),
|
||||
Q6INSN(A2_nop,"nop",ATTRIBS(A_IT_NOP),
|
||||
"Nop (32-bit encoding)",
|
||||
fHIDE( { } ))
|
||||
Q6INSN(A2_nop_rb,"nop_rb",ATTRIBS(A_IT_NOP,A_RESTRICT_TARGET),
|
||||
"Restricted branch nop target",
|
||||
fHIDE( { } ))
|
||||
|
||||
|
||||
Q6INSN(A4_ext,"immext(#u26:6)",ATTRIBS(A_IT_EXTENDER),
|
||||
|
||||
@@ -37,6 +37,19 @@ Q6INSN(J2_jumpr,"jumpr Rs32",ATTRIBS(A_JINDIR), "indirect unconditional jump",
|
||||
Q6INSN(J2_jumprh,"jumprh Rs32",ATTRIBS(A_JINDIR, A_HINTED_COF), "indirect unconditional jump",
|
||||
{fJUMPR(RsN,RsV,COF_TYPE_JUMPR);})
|
||||
|
||||
Q6INSN(J2_jumpr_rb,"jumpr_rb Rs32",ATTRIBS(A_JINDIR),
|
||||
"restricted indirect unconditional jump",
|
||||
{fJUMPR(RsN,RsV,COF_TYPE_JUMPR);})
|
||||
Q6INSN(J2_jumprh_rb,"jumprh_rb Rs32",ATTRIBS(A_JINDIR, A_HINTED_COF),
|
||||
"restricted hinted indirect unconditional jump",
|
||||
{fJUMPR(RsN,RsV,COF_TYPE_JUMPR);})
|
||||
|
||||
#define OLDCOND_JUMP_RB(TAG,OPER,OPER2,ATTRIB,DESCR,SEMANTICS) \
|
||||
Q6INSN(TAG##t_rb,"if (Pu4) "OPER":nt "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBOLD(PuV),,SPECULATE_NOT_TAKEN,12,0); if (fLSBOLD(PuV)) { SEMANTICS; }}) \
|
||||
Q6INSN(TAG##f_rb,"if (!Pu4) "OPER":nt "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBOLDNOT(PuV),,SPECULATE_NOT_TAKEN,12,0); if (fLSBOLDNOT(PuV)) { SEMANTICS; }}) \
|
||||
Q6INSN(TAG##tpt_rb,"if (Pu4) "OPER":t "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBOLD(PuV),,SPECULATE_TAKEN,12,0); if (fLSBOLD(PuV)) { SEMANTICS; }}) \
|
||||
Q6INSN(TAG##fpt_rb,"if (!Pu4) "OPER":t "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBOLDNOT(PuV),,SPECULATE_TAKEN,12,0); if (fLSBOLDNOT(PuV)) { SEMANTICS; }})
|
||||
|
||||
#define OLDCOND_JUMP(TAG,OPER,OPER2,ATTRIB,DESCR,SEMANTICS) \
|
||||
Q6INSN(TAG##t,"if (Pu4) "OPER":nt "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBOLD(PuV),,SPECULATE_NOT_TAKEN,12,0); if (fLSBOLD(PuV)) { SEMANTICS; }}) \
|
||||
Q6INSN(TAG##f,"if (!Pu4) "OPER":nt "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBOLDNOT(PuV),,SPECULATE_NOT_TAKEN,12,0); if (fLSBOLDNOT(PuV)) { SEMANTICS; }}) \
|
||||
@@ -48,6 +61,9 @@ fIMMEXT(riV);fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMP);)
|
||||
|
||||
OLDCOND_JUMP(J2_jumpr,"jumpr","Rs32",ATTRIBS(A_JINDIROLD),"indirect conditional jump",
|
||||
fJUMPR(RsN,RsV,COF_TYPE_JUMPR);)
|
||||
OLDCOND_JUMP_RB(J2_jumpr,"jumpr_rb","Rs32",ATTRIBS(A_JINDIROLD),
|
||||
"restricted indirect conditional jump",
|
||||
fJUMPR(RsN,RsV,COF_TYPE_JUMPR);)
|
||||
|
||||
#define NEWCOND_JUMP(TAG,OPER,OPER2,ATTRIB,DESCR,SEMANTICS)\
|
||||
Q6INSN(TAG##tnew,"if (Pu4.new) "OPER":nt "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBNEW(PuN),, SPECULATE_NOT_TAKEN , 12,0)} {if(fLSBNEW(PuN)){SEMANTICS;}})\
|
||||
@@ -61,6 +77,17 @@ fIMMEXT(riV); fPCALIGN(riV); fBRANCH(fREAD_PC()+riV,COF_TYPE_JUMPNEW);)
|
||||
NEWCOND_JUMP(J2_jumpr,"jumpr","Rs32",ATTRIBS(A_JINDIRNEW,A_ARCHV3),"indirect conditional jump",
|
||||
fJUMPR(RsN,RsV,COF_TYPE_JUMPR);)
|
||||
|
||||
#define NEWCOND_JUMP_RB(TAG,OPER,OPER2,ATTRIB,DESCR,SEMANTICS) \
|
||||
Q6INSN(TAG##tnew_rb,"if (Pu4.new) "OPER":nt "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBNEW(PuN),, SPECULATE_NOT_TAKEN , 12,0)} {if(fLSBNEW(PuN)){SEMANTICS;}}) \
|
||||
Q6INSN(TAG##fnew_rb,"if (!Pu4.new) "OPER":nt "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBNEWNOT(PuN),, SPECULATE_NOT_TAKEN , 12,0)} {if(fLSBNEWNOT(PuN)){SEMANTICS;}}) \
|
||||
Q6INSN(TAG##tnewpt_rb,"if (Pu4.new) "OPER":t "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBNEW(PuN),, SPECULATE_TAKEN , 12,0)} {if(fLSBNEW(PuN)){SEMANTICS;}}) \
|
||||
Q6INSN(TAG##fnewpt_rb,"if (!Pu4.new) "OPER":t "OPER2,ATTRIB,DESCR,{fBRANCH_SPECULATE_STALL(fLSBNEWNOT(PuN),, SPECULATE_TAKEN , 12,0)} {if(fLSBNEWNOT(PuN)){SEMANTICS;}})
|
||||
|
||||
NEWCOND_JUMP_RB(J2_jumpr,"jumpr_rb","Rs32",
|
||||
ATTRIBS(A_JINDIRNEW,A_ARCHV3),
|
||||
"restricted indirect conditional jump",
|
||||
fJUMPR(RsN,RsV,COF_TYPE_JUMPR);)
|
||||
|
||||
|
||||
|
||||
Q6INSN(J4_hintjumpr,"hintjr(Rs32)",ATTRIBS(A_JINDIR),"hint indirect conditional jump",
|
||||
@@ -202,6 +229,17 @@ Q6INSN(J2_callrf,"if (!Pu4) callr Rs32",ATTRIBS(CINDIR_STD),"indirect conditiona
|
||||
Q6INSN(J2_callrh,"callrh Rs32",ATTRIBS(CINDIR_STD, A_HINTED_COF), "hinted indirect unconditional call",
|
||||
{ fCALLR(RsV); })
|
||||
|
||||
Q6INSN(J2_callr_rb,"callr_rb Rs32",ATTRIBS(CINDIR_STD),
|
||||
"restricted indirect unconditional call", { fCALLR(RsV); })
|
||||
Q6INSN(J2_callrh_rb,"callrh_rb Rs32",ATTRIBS(CINDIR_STD, A_HINTED_COF),
|
||||
"restricted hinted indirect unconditional call", { fCALLR(RsV); })
|
||||
Q6INSN(J2_callrt_rb,"if (Pu4) callr_rb Rs32",ATTRIBS(CINDIR_STD),
|
||||
"restricted indirect conditional call if true",
|
||||
{if (fLSBOLD(PuV)) { fCALLR(RsV); }})
|
||||
Q6INSN(J2_callrf_rb,"if (!Pu4) callr_rb Rs32",ATTRIBS(CINDIR_STD),
|
||||
"restricted indirect conditional call if false",
|
||||
{if (fLSBOLDNOT(PuV)) { fCALLR(RsV); }})
|
||||
|
||||
|
||||
|
||||
/*********************************************/
|
||||
|
||||
@@ -413,6 +413,20 @@ DEF_ENC32(V2_vallocframe_imm,"01100000100-----PP001----iiiiiii")
|
||||
DEF_ENC32(V2_vallocframe_reg,"01100000100sssssPP010-----------")
|
||||
DEF_ENC32(V2_vdeallocframe_imm,"01101010100-----PP001----iiiiiii")
|
||||
DEF_ENC32(V2_vdeallocframe_reg,"01101001010sssssPP010-----------")
|
||||
DEF_ENC32(J2_callr_rb,"01010000001sssssPP--------------")
|
||||
DEF_ENC32(J2_callrh_rb,"01010000010sssssPP--------------")
|
||||
DEF_ENC32(J2_callrt_rb,"01010001100sssssPP----uu--------")
|
||||
DEF_ENC32(J2_callrf_rb,"01010001101sssssPP----uu--------")
|
||||
DEF_ENC32(J2_jumpr_rb,"01010010000sssssPP--------------")
|
||||
DEF_ENC32(J2_jumprh_rb,"01010010010sssssPP--------------")
|
||||
DEF_ENC32(J2_jumprt_rb,"01010011110sssssPP-00-uu--------")
|
||||
DEF_ENC32(J2_jumprf_rb,"01010011111sssssPP-00-uu--------")
|
||||
DEF_ENC32(J2_jumprtpt_rb,"01010011110sssssPP-10-uu--------")
|
||||
DEF_ENC32(J2_jumprfpt_rb,"01010011111sssssPP-10-uu--------")
|
||||
DEF_ENC32(J2_jumprtnew_rb,"01010011110sssssPP-01-uu--------")
|
||||
DEF_ENC32(J2_jumprfnew_rb,"01010011111sssssPP-01-uu--------")
|
||||
DEF_ENC32(J2_jumprtnewpt_rb,"01010011110sssssPP-11-uu--------")
|
||||
DEF_ENC32(J2_jumprfnewpt_rb,"01010011111sssssPP-11-uu--------")
|
||||
DEF_ENC32(J2_trap2,"0101010011------PP-iiiii---iii--")
|
||||
|
||||
|
||||
@@ -514,6 +528,7 @@ DEF_ENC32(S2_pstorerdf_pi_nt,"10101010110xxxxxPP1ttttt0iiii1vv")
|
||||
/* x bus/cache */
|
||||
/* x store/cache */
|
||||
DEF_ENC32(S2_allocframe, ICLASS_ST" 000 01 00xxxxx PP000iii iiiiiiii")
|
||||
DEF_ENC32(S2_allocframe_rb,ICLASS_ST" 000 01 00xxxxx PP100iii iiiiiiii")
|
||||
DEF_ENC32(Y5_l2locka, ICLASS_ST" 000 01 11sssss PP1----- ------dd")
|
||||
DEF_ENC32(Y2_dczeroa, ICLASS_ST" 000 01 10sssss PP0----- --------")
|
||||
DEF_ENC32(Y2_dczeroa_nt,"10100000110sssssPP1-------------")
|
||||
@@ -1407,7 +1422,8 @@ DEF_ENC32(C2_cmoveif, ICLASS_ALU2op" 1110 1uu0iiii PP0iiiii iiiddddd")
|
||||
|
||||
|
||||
DEF_FIELDROW_DESC32( ICLASS_ALU2op" 1111 -------- PP------ --------","[#15] nop")
|
||||
DEF_ENC32(A2_nop, ICLASS_ALU2op" 1111 -------- PP------ --------")
|
||||
DEF_ENC32(A2_nop, ICLASS_ALU2op" 1111 0------- PP------ --------")
|
||||
DEF_ENC32(A2_nop_rb, ICLASS_ALU2op" 1111 1------- PP------ --------")
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -71,6 +71,7 @@ DEF_ENC_SUBINSN(SS2_storebi0, SUBINSN_S2, "100 10ssssiiii")
|
||||
DEF_ENC_SUBINSN(SS2_storebi1, SUBINSN_S2, "100 11ssssiiii")
|
||||
|
||||
DEF_ENC_SUBINSN(SS2_allocframe, SUBINSN_S2, "111 0iiiii----")
|
||||
DEF_ENC_SUBINSN(SS2_allocframe_rb,SUBINSN_S2, "111 1iiiii----")
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -135,6 +135,8 @@ STD_ST_AMODES(storerhnew, "Nt8.new", "memh","Store Half integer",ATTRIBS(A_REGWR
|
||||
|
||||
Q6INSN(S2_allocframe,"allocframe(Rx32,#u11:3):raw", ATTRIBS(A_REGWRSIZE_8B,A_MEMSIZE_8B,A_STORE,A_RESTRICT_SLOT0ONLY), "Allocate stack frame",
|
||||
{ fEA_RI(RxV,-8); fSTORE(1,8,EA,fFRAME_SCRAMBLE((fCAST8_8u(fREAD_LR()) << 32) | fCAST4_4u(fREAD_FP()))); fWRITE_FP(EA); fFRAMECHECK(EA-uiV,EA); RxV = EA-uiV; })
|
||||
Q6INSN(S2_allocframe_rb,"allocframe_rb(Rx32,#u11:3):raw", ATTRIBS(A_REGWRSIZE_8B,A_MEMSIZE_8B,A_STORE,A_RESTRICT_SLOT0ONLY,A_RESTRICT_TARGET), "Allocate stack frame",
|
||||
{ fEA_RI(RxV,-8); fSTORE(1,8,EA,fFRAME_SCRAMBLE((fCAST8_8u(fREAD_LR()) << 32) | fCAST4_4u(fREAD_FP()))); fWRITE_FP(EA); fFRAMECHECK(EA-uiV,EA); RxV = EA-uiV; })
|
||||
#define A_RETURN A_RESTRICT_COF_MAX1,A_RESTRICT_SLOT0ONLY,A_RESTRICT_NOSLOT1_STORE,A_RET_TYPE,A_DEALLOCRET
|
||||
|
||||
/**** Load Acquire Store Release Instructions****/
|
||||
|
||||
@@ -147,3 +147,5 @@ Q6INSN(SS2_storebi1, "memb(Rs16+#u4:0)=#1", ATTRIBS(A_MEMSIZE_1B,A_STORE,A_SUB
|
||||
|
||||
Q6INSN(SS2_allocframe,"allocframe(#u5:3)", ATTRIBS(A_REGWRSIZE_8B,A_SUBINSN,A_MEMSIZE_8B,A_STORE,A_RESTRICT_SLOT0ONLY), "Allocate stack frame",
|
||||
{ fEA_RI(fREAD_SP(),-8); fSTORE(1,8,EA,fFRAME_SCRAMBLE((fCAST8_8u(fREAD_LR()) << 32) | fCAST4_4u(fREAD_FP()))); fWRITE_FP(EA); fFRAMECHECK(EA-uiV,EA); fWRITE_SP(EA-uiV); })
|
||||
Q6INSN(SS2_allocframe_rb,"allocframe_rb(#u5:3)", ATTRIBS(A_REGWRSIZE_8B,A_SUBINSN,A_MEMSIZE_8B,A_STORE,A_RESTRICT_SLOT0ONLY,A_RESTRICT_TARGET), "Allocate stack frame",
|
||||
{ fEA_RI(fREAD_SP(),-8); fSTORE(1,8,EA,fFRAME_SCRAMBLE((fCAST8_8u(fREAD_LR()) << 32) | fCAST4_4u(fREAD_FP()))); fWRITE_FP(EA); fFRAMECHECK(EA-uiV,EA); fWRITE_SP(EA-uiV); })
|
||||
@@ -48,7 +48,7 @@ Q6INSN(J2_trap1,"trap1(Rx32,#u8)",ATTRIBS(A_COF,A_NOTE_NOPACKET,A_RESTRICT_NOPAC
|
||||
fVIRTINSN_SPSWAP(uiV,RxV);
|
||||
})
|
||||
|
||||
Q6INSN(J2_trap2,"trap2(#u8)",ATTRIBS(A_COF,A_RESTRICT_NOPACKET),
|
||||
Q6INSN(J2_trap2,"trap2(#u8)",ATTRIBS(A_COF,A_NOTE_NOPACKET,A_RESTRICT_NOPACKET),
|
||||
"Trap to Operating System", { fTRAP(2,uiV); })
|
||||
|
||||
Q6INSN(J2_pause,"pause(#u8)",ATTRIBS(A_COF,A_NOTE_NOPACKET,A_RESTRICT_NOPACKET),
|
||||
|
||||
@@ -21,7 +21,7 @@ static int hexagon_cpu_post_load(void *opaque, int version_id)
|
||||
|
||||
const VMStateDescription vmstate_hexagon_cpu = {
|
||||
.name = "cpu",
|
||||
.version_id = 2,
|
||||
.version_id = 3,
|
||||
.minimum_version_id = 2,
|
||||
.post_load = hexagon_cpu_post_load,
|
||||
.fields = (const VMStateField[]) {
|
||||
@@ -37,6 +37,7 @@ const VMStateDescription vmstate_hexagon_cpu = {
|
||||
VMSTATE_UINT32(env.cause_code, HexagonCPU),
|
||||
VMSTATE_UNUSED(sizeof(uint64_t)),
|
||||
VMSTATE_UINT32(env.imprecise_exception, HexagonCPU),
|
||||
VMSTATE_UINT32_V(env.cfi_active, HexagonCPU, 3),
|
||||
|
||||
VMSTATE_END_OF_LIST()
|
||||
},
|
||||
|
||||
@@ -423,6 +423,18 @@ static inline TCGv gen_read_ireg(TCGv result, TCGv val, int shift)
|
||||
#define fCAST8S_16S(A) (int128_exts64(A))
|
||||
#define fCAST16S_8S(A) (int128_getlo(A))
|
||||
|
||||
#define fSET_CFI(CFI_VALUE) \
|
||||
do { \
|
||||
TCGLabel *skip_cfi_reset = gen_new_label(); \
|
||||
tcg_gen_movcond_i32(TCG_COND_NE, hex_cfi_active_log, hex_cfi_updated, \
|
||||
tcg_constant_i32(1), tcg_constant_i32(0), \
|
||||
hex_cfi_active_log); \
|
||||
tcg_gen_movi_i32(hex_cfi_updated, 1); \
|
||||
tcg_gen_brcondi_i32(TCG_COND_EQ, CFI_VALUE, 0, skip_cfi_reset); \
|
||||
tcg_gen_movi_i32(hex_cfi_active_log, 1); \
|
||||
gen_set_label(skip_cfi_reset); \
|
||||
} while (0)
|
||||
|
||||
#ifdef QEMU_GENERATE
|
||||
#define fEA_RI(REG, IMM) tcg_gen_addi_tl(EA, REG, IMM)
|
||||
#define fEA_RRs(REG, REG2, SCALE) \
|
||||
|
||||
@@ -95,6 +95,7 @@ DEF_REG_FIELD(SYSCFG_L2GCA, 31, 1)
|
||||
/* SSR fields */
|
||||
DEF_REG_FIELD(SSR_CAUSE, 0, 8)
|
||||
DEF_REG_FIELD(SSR_ASID, 8, 7)
|
||||
DEF_REG_FIELD(SSR_CFI, 15, 1)
|
||||
DEF_REG_FIELD(SSR_UM, 16, 1)
|
||||
DEF_REG_FIELD(SSR_EX, 17, 1)
|
||||
DEF_REG_FIELD(SSR_IE, 18, 1)
|
||||
|
||||
@@ -707,6 +707,26 @@ static const struct tag_rev_info tag_rev_info[XX_LAST_OPCODE] = {
|
||||
.removed = HEX_VER_NONE },
|
||||
[V2_vdeallocframe_reg] = { .introduced = HEX_VER_V83,
|
||||
.removed = HEX_VER_NONE },
|
||||
[J2_callr_rb] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
|
||||
[J2_callrh_rb] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
|
||||
[J2_callrt_rb] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
|
||||
[J2_callrf_rb] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
|
||||
[J2_jumpr_rb] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
|
||||
[J2_jumprh_rb] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
|
||||
[J2_jumprt_rb] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
|
||||
[J2_jumprf_rb] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
|
||||
[J2_jumprtpt_rb] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
|
||||
[J2_jumprfpt_rb] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
|
||||
[J2_jumprtnew_rb] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
|
||||
[J2_jumprfnew_rb] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
|
||||
[J2_jumprtnewpt_rb] = { .introduced = HEX_VER_V83,
|
||||
.removed = HEX_VER_NONE },
|
||||
[J2_jumprfnewpt_rb] = { .introduced = HEX_VER_V83,
|
||||
.removed = HEX_VER_NONE },
|
||||
[S2_allocframe_rb] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
|
||||
[SS2_allocframe_rb] = { .introduced = HEX_VER_V83,
|
||||
.removed = HEX_VER_NONE },
|
||||
[A2_nop_rb] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
|
||||
[J2_trap2] = { .introduced = HEX_VER_V83, .removed = HEX_VER_NONE },
|
||||
|
||||
[Y4_dcfetch_multi] = { .introduced = HEX_VER_V85,
|
||||
|
||||
@@ -68,6 +68,9 @@ TCGv hex_imprecise_exception;
|
||||
TCGv hex_vstore_addr[VSTORES_MAX];
|
||||
TCGv hex_vstore_size[VSTORES_MAX];
|
||||
TCGv hex_vstore_pending[VSTORES_MAX];
|
||||
TCGv_i32 hex_cfi_active;
|
||||
TCGv_i32 hex_cfi_active_log;
|
||||
TCGv_i32 hex_cfi_updated;
|
||||
#ifndef CONFIG_USER_ONLY
|
||||
TCGv_ptr hex_hvx_ptr;
|
||||
#endif
|
||||
@@ -480,6 +483,45 @@ static void mark_implicit_reg_write(DisasContext *ctx, int attrib, int rnum)
|
||||
}
|
||||
}
|
||||
|
||||
static bool pkt_legal_cfi_target(const Packet *pkt)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < pkt->num_insns; i++) {
|
||||
if (GET_ATTRIB(pkt->insn[i].opcode, A_RESTRICT_TARGET) ||
|
||||
pkt->insn[i].opcode == Y2_break ||
|
||||
(pkt->insn[i].opcode == J2_trap0 &&
|
||||
pkt->insn[i].immed[0] == 0xdb)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void gen_cfi_check(DisasContext *ctx)
|
||||
{
|
||||
TCGLabel *skip;
|
||||
|
||||
if (ctx->hex_def->hex_version < HEX_VER_V83 ||
|
||||
pkt_legal_cfi_target(&ctx->pkt)) {
|
||||
return;
|
||||
}
|
||||
|
||||
skip = gen_new_label();
|
||||
tcg_gen_brcondi_i32(TCG_COND_EQ, hex_cfi_active, 0, skip);
|
||||
gen_precise_exception(HEX_CAUSE_CFI_VIOLATION, ctx->pkt.pc);
|
||||
gen_set_label(skip);
|
||||
}
|
||||
|
||||
static void gen_cfi_target_update(DisasContext *ctx)
|
||||
{
|
||||
if (ctx->hex_def->hex_version >= HEX_VER_V83 &&
|
||||
pkt_legal_cfi_target(&ctx->pkt)) {
|
||||
tcg_gen_movi_i32(hex_cfi_active_log, 0);
|
||||
tcg_gen_movi_i32(hex_cfi_updated, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void mark_implicit_usr_write(DisasContext *ctx, int attrib)
|
||||
{
|
||||
uint16_t opcode = ctx->insn->opcode;
|
||||
@@ -748,6 +790,9 @@ static void gen_start_packet(DisasContext *ctx)
|
||||
tcg_gen_movi_tl(hex_gpr[HEX_REG_PC], ctx->next_PC);
|
||||
}
|
||||
|
||||
gen_cfi_target_update(ctx);
|
||||
gen_cfi_check(ctx);
|
||||
|
||||
/* Preload the predicated registers into get_result_gpr(ctx, i) */
|
||||
if (ctx->need_commit &&
|
||||
!bitmap_empty(ctx->predicated_regs, TOTAL_PER_THREAD_REGS)) {
|
||||
@@ -1269,6 +1314,14 @@ static void gen_commit_packet(DisasContext *ctx)
|
||||
gen_helper_probe_pkt_scalar_store_s0(tcg_env, args_tcgv);
|
||||
}
|
||||
|
||||
if (ctx->hex_def->hex_version >= HEX_VER_V83) {
|
||||
/* A restricted branch commits before a faulting store in its packet. */
|
||||
tcg_gen_movcond_i32(TCG_COND_NE, hex_cfi_active, hex_cfi_updated,
|
||||
tcg_constant_i32(0), hex_cfi_active_log,
|
||||
hex_cfi_active);
|
||||
tcg_gen_movi_i32(hex_cfi_updated, 0);
|
||||
}
|
||||
|
||||
process_store_log(ctx);
|
||||
|
||||
gen_reg_writes(ctx);
|
||||
@@ -1518,6 +1571,12 @@ void hexagon_translate_init(void)
|
||||
}
|
||||
hex_new_value_usr = tcg_global_mem_new(tcg_env,
|
||||
offsetof(CPUHexagonState, new_value_usr), "new_value_usr");
|
||||
hex_cfi_active = tcg_global_mem_new_i32(tcg_env,
|
||||
offsetof(CPUHexagonState, cfi_active), "cfi_active");
|
||||
hex_cfi_active_log = tcg_global_mem_new_i32(tcg_env,
|
||||
offsetof(CPUHexagonState, cfi_active_log), "cfi_active_log");
|
||||
hex_cfi_updated = tcg_global_mem_new_i32(tcg_env,
|
||||
offsetof(CPUHexagonState, cfi_updated), "cfi_updated");
|
||||
|
||||
for (i = 0; i < NUM_PREGS; i++) {
|
||||
hex_pred[i] = tcg_global_mem_new(tcg_env,
|
||||
|
||||
@@ -365,6 +365,9 @@ extern TCGv_i64 hex_llsc_val_i64;
|
||||
extern TCGv hex_vstore_addr[VSTORES_MAX];
|
||||
extern TCGv hex_vstore_size[VSTORES_MAX];
|
||||
extern TCGv hex_vstore_pending[VSTORES_MAX];
|
||||
extern TCGv_i32 hex_cfi_active;
|
||||
extern TCGv_i32 hex_cfi_active_log;
|
||||
extern TCGv_i32 hex_cfi_updated;
|
||||
void gen_precise_exception(int cause, uint32_t pc);
|
||||
#ifdef CONFIG_USER_ONLY
|
||||
#define hex_hvx_ptr tcg_env
|
||||
|
||||
Reference in new issue
Block a user