SSR:XE gates access to the HVX coprocessor: executing an HVX instruction while it is clear must raise a precise exception with cause 0x16, NO_COPROC_ENABLE.
Carry SSR:XE in a TB flag and emit the exception for the first HVX packet of a TB when the coprocessor is disabled. Reviewed-by: Marco Liebel <[email protected]> Signed-off-by: Brian Cain <[email protected]> --- target/hexagon/cpu.h | 1 + target/hexagon/translate.h | 2 ++ target/hexagon/cpu.c | 2 ++ target/hexagon/translate.c | 11 +++++++++++ 4 files changed, 16 insertions(+) diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h index b1533680bd7..97f689fda22 100644 --- a/target/hexagon/cpu.h +++ b/target/hexagon/cpu.h @@ -207,6 +207,7 @@ struct ArchCPU { FIELD(TB_FLAGS, IS_TIGHT_LOOP, 0, 1) FIELD(TB_FLAGS, MMU_INDEX, 1, 3) FIELD(TB_FLAGS, PCYCLE_ENABLED, 4, 1) +FIELD(TB_FLAGS, HVX_COPROC_ENABLED, 5, 1) G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env, uint32_t exception, diff --git a/target/hexagon/translate.h b/target/hexagon/translate.h index d8628383f1d..b87a2b20e2f 100644 --- a/target/hexagon/translate.h +++ b/target/hexagon/translate.h @@ -89,6 +89,8 @@ typedef struct DisasContext { TCGv branch_taken; TCGv dczero_addr; bool pcycle_enabled; + bool hvx_coproc_enabled; + bool hvx_check_emitted; uint32_t num_cycles; } DisasContext; diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c index fad526ccfb5..19486e0f741 100644 --- a/target/hexagon/cpu.c +++ b/target/hexagon/cpu.c @@ -340,6 +340,8 @@ static TCGTBCPUState hexagon_get_tb_cpu_state(CPUState *cs) hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, MMU_INDEX, cpu_mmu_index(env_cpu(env), false)); hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, PCYCLE_ENABLED, 1); + hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, HVX_COPROC_ENABLED, + GET_SSR_FIELD(SSR_XE, env->t_sreg[HEX_SREG_SSR])); #else hex_flags = FIELD_DP32(hex_flags, TB_FLAGS, MMU_INDEX, MMU_USER_IDX); #endif diff --git a/target/hexagon/translate.c b/target/hexagon/translate.c index fd1de87405c..0cb3dbe5420 100644 --- a/target/hexagon/translate.c +++ b/target/hexagon/translate.c @@ -720,6 +720,14 @@ static void gen_start_packet(DisasContext *ctx) i = find_next_bit(ctx->predicated_tmp_vregs, NUM_VREGS, i + 1); } } + +#ifndef CONFIG_USER_ONLY + if (ctx->pkt.pkt_has_hvx && !ctx->hvx_coproc_enabled && + !ctx->hvx_check_emitted) { + gen_precise_exception(HEX_CAUSE_NO_COPROC_ENABLE, ctx->pkt.pc); + ctx->hvx_check_emitted = true; + } +#endif } bool is_gather_store_insn(DisasContext *ctx) @@ -1239,6 +1247,9 @@ static void hexagon_tr_init_disas_context(DisasContextBase *dcbase, #ifndef CONFIG_USER_ONLY ctx->num_cycles = 0; ctx->pcycle_enabled = FIELD_EX32(hex_flags, TB_FLAGS, PCYCLE_ENABLED); + ctx->hvx_coproc_enabled = + FIELD_EX32(hex_flags, TB_FLAGS, HVX_COPROC_ENABLED); + ctx->hvx_check_emitted = false; #endif } -- 2.34.1
