[PATCH v4 03/28] target/hexagon: Implement start/stop helpers, soft reset

Brian Cain posted 28 patches 3 days, 14 hours ago
[PATCH v4 03/28] target/hexagon: Implement start/stop helpers, soft reset
Posted by Brian Cain 3 days, 14 hours ago
From: Brian Cain <bcain@quicinc.com>

Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
---
 target/hexagon/cpu.h       |  9 +++++++++
 target/hexagon/cpu.c       | 28 ++++++++++++++++++++++++++--
 target/hexagon/op_helper.c |  4 ++--
 3 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/target/hexagon/cpu.h b/target/hexagon/cpu.h
index 3049b5a411a..2938291ff1d 100644
--- a/target/hexagon/cpu.h
+++ b/target/hexagon/cpu.h
@@ -212,6 +212,15 @@ G_NORETURN void hexagon_raise_exception_err(CPUHexagonState *env,
                                             uint32_t exception,
                                             uintptr_t pc);
 
+#ifndef CONFIG_USER_ONLY
+/*
+ * @return true if the @a thread_env hardware thread is
+ * not stopped.
+ */
+bool hexagon_thread_is_enabled(CPUHexagonState *thread_env);
+void hexagon_cpu_soft_reset(CPUHexagonState *env);
+#endif
+
 typedef HexagonCPU ArchCPU;
 
 void hexagon_translate_init(void);
diff --git a/target/hexagon/cpu.c b/target/hexagon/cpu.c
index 9ae8e104043..fe7bb198d72 100644
--- a/target/hexagon/cpu.c
+++ b/target/hexagon/cpu.c
@@ -33,6 +33,7 @@
 #ifndef CONFIG_USER_ONLY
 #include "sys_macros.h"
 #include "accel/tcg/cpu-ldst.h"
+#include "qemu/main-loop.h"
 #endif
 
 static void hexagon_v66_cpu_init(Object *obj) { }
@@ -315,6 +316,28 @@ static void hexagon_restore_state_to_opc(CPUState *cs,
 }
 
 
+#ifndef CONFIG_USER_ONLY
+void hexagon_cpu_soft_reset(CPUHexagonState *env)
+{
+    HexagonCPU *cpu;
+
+    BQL_LOCK_GUARD();
+    env->t_sreg[HEX_SREG_SSR] = 0;
+    hexagon_ssr_set_cause(env, HEX_CAUSE_RESET);
+
+    cpu = env_archcpu(env);
+    if (cpu->globalregs) {
+        uint32_t evb =
+            hexagon_globalreg_read(cpu->globalregs, HEX_SREG_EVB,
+                                   env->threadId);
+        env->gpr[HEX_REG_PC] = evb;
+    } else {
+        env->gpr[HEX_REG_PC] = cpu->boot_addr;
+    }
+}
+#endif
+
+
 static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
 {
     CPUState *cs = CPU(obj);
@@ -344,9 +367,10 @@ static void hexagon_cpu_reset_hold(Object *obj, ResetType type)
 
     env->t_sreg[HEX_SREG_HTID] = cpu->htid;
     env->threadId = cpu->htid;
-    env->gpr[HEX_REG_PC] = cpu->boot_addr;
-#endif
+    hexagon_cpu_soft_reset(env);
     env->cause_code = HEX_EVENT_NONE;
+    env->gpr[HEX_REG_PC] = cpu->boot_addr;
+#endif
 }
 
 static void hexagon_cpu_disas_set_info(const CPUState *cs,
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index 7e6e04e512a..a28ed061412 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1478,12 +1478,12 @@ uint32_t HELPER(iassignr)(CPUHexagonState *env, uint32_t src)
 
 void HELPER(start)(CPUHexagonState *env, uint32_t imask)
 {
-    g_assert_not_reached();
+    hexagon_start_threads(env, imask);
 }
 
 void HELPER(stop)(CPUHexagonState *env)
 {
-    g_assert_not_reached();
+    hexagon_stop_thread(env);
 }
 
 void HELPER(wait)(CPUHexagonState *env, target_ulong PC)
-- 
2.34.1