diff mbox series

[08/39] target/hexagon: Implement get_exe_mode()

Message ID 20250301052845.1012069-9-brian.cain@oss.qualcomm.com (mailing list archive)
State New
Headers show
Series hexagon system emu, part 2/3 | expand

Commit Message

Brian Cain March 1, 2025, 5:28 a.m. UTC
From: Brian Cain <bcain@quicinc.com>

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 target/hexagon/reg_fields_def.h.inc | 11 +++++++++++
 target/hexagon/cpu_helper.c         | 24 ++++++++++++++++++++++++
 2 files changed, 35 insertions(+)
diff mbox series

Patch

diff --git a/target/hexagon/reg_fields_def.h.inc b/target/hexagon/reg_fields_def.h.inc
index 156a3514e7..50b8c26f8b 100644
--- a/target/hexagon/reg_fields_def.h.inc
+++ b/target/hexagon/reg_fields_def.h.inc
@@ -135,3 +135,14 @@  DEF_REG_FIELD(CCR_GRE, 27, 1)
 DEF_REG_FIELD(CCR_VV1, 29, 1)
 DEF_REG_FIELD(CCR_VV2, 30, 1)
 DEF_REG_FIELD(CCR_VV3, 31, 1)
+
+/* ISDB ST fields */
+DEF_REG_FIELD(ISDBST_WAITRUN, 24, 8)
+DEF_REG_FIELD(ISDBST_ONOFF, 16, 8)
+DEF_REG_FIELD(ISDBST_DEBUGMODE, 8, 8)
+DEF_REG_FIELD(ISDBST_STUFFSTATUS, 5, 1)
+DEF_REG_FIELD(ISDBST_CMDSTATUS, 4, 1)
+DEF_REG_FIELD(ISDBST_PROCMODE, 3, 1)
+DEF_REG_FIELD(ISDBST_MBXINSTATUS, 2, 1)
+DEF_REG_FIELD(ISDBST_MBXOUTSTATUS, 1, 1)
+DEF_REG_FIELD(ISDBST_READY, 0, 1)
diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
index e64568b9fc..e0dd120cd4 100644
--- a/target/hexagon/cpu_helper.c
+++ b/target/hexagon/cpu_helper.c
@@ -237,6 +237,30 @@  void hexagon_ssr_set_cause(CPUHexagonState *env, uint32_t cause)
 
 int get_exe_mode(CPUHexagonState *env)
 {
+    g_assert(bql_locked());
+
+    target_ulong modectl = arch_get_system_reg(env, HEX_SREG_MODECTL);
+    uint32_t thread_enabled_mask = GET_FIELD(MODECTL_E, modectl);
+    bool E_bit = thread_enabled_mask & (0x1 << env->threadId);
+    uint32_t thread_wait_mask = GET_FIELD(MODECTL_W, modectl);
+    bool W_bit = thread_wait_mask & (0x1 << env->threadId);
+    target_ulong isdbst = arch_get_system_reg(env, HEX_SREG_ISDBST);
+    uint32_t debugmode = GET_FIELD(ISDBST_DEBUGMODE, isdbst);
+    bool D_bit = debugmode & (0x1 << env->threadId);
+
+    /* Figure 4-2 */
+    if (!D_bit && !W_bit && !E_bit) {
+        return HEX_EXE_MODE_OFF;
+    }
+    if (!D_bit && !W_bit && E_bit) {
+        return HEX_EXE_MODE_RUN;
+    }
+    if (!D_bit && W_bit && E_bit) {
+        return HEX_EXE_MODE_WAIT;
+    }
+    if (D_bit && !W_bit && E_bit) {
+        return HEX_EXE_MODE_DEBUG;
+    }
     g_assert_not_reached();
 }