@samitouri / QOSamiQemu / commits / acd2b7a2f1

target/hexagon: Implement wait helper

Reviewed-by: Taylor Simpson <ltaylorsimpson@gmail.com> Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>

Brian Cain committed Jun 22, 2026 at 15:28 UTC acd2b7a2f19ac04bd313e816e5f9e7f87adc9858
2 files changed +59 -3
target/hexagon/gen_tcg_sys.h
+1 -1
@@ -80,7 +80,7 @@
80 #define fGEN_TCG_Y2_wait(SHORTCODE) \
81 do { \
82 RsV = RsV; \
83 - gen_helper_wait(tcg_env, tcg_constant_tl(ctx->pkt->pc)); \
83 + gen_helper_wait(tcg_env, tcg_constant_tl(ctx->pkt.pc)); \
84 } while (0)
85
86 #define fGEN_TCG_Y2_resume(SHORTCODE) \
target/hexagon/op_helper.c
+58 -2
@@ -1487,9 +1487,65 @@ void HELPER(stop)(CPUHexagonState *env)
1487 hexagon_stop_thread(env);
1488 }
1489
1490 -void HELPER(wait)(CPUHexagonState *env, target_ulong PC)
1490 +static void set_wait_mode(CPUHexagonState *env)
1491 {
1492 - g_assert_not_reached();
1492 + HexagonCPU *cpu;
1493 + uint32_t modectl;
1494 + uint32_t thread_wait_mask;
1495 +
1496 + g_assert(bql_locked());
1497 +
1498 + cpu = env_archcpu(env);
1499 + if (!cpu->globalregs) {
1500 + return;
1501 + }
1502 + modectl =
1503 + hexagon_globalreg_read(cpu->globalregs, HEX_SREG_MODECTL,
1504 + env->threadId);
1505 + thread_wait_mask = GET_FIELD(MODECTL_W, modectl);
1506 + thread_wait_mask |= 0x1 << env->threadId;
1507 + SET_SYSTEM_FIELD(env, HEX_SREG_MODECTL, MODECTL_W, thread_wait_mask);
1508 +}
1509 +
1510 +static void hexagon_wait_thread(CPUHexagonState *env, uint32_t PC)
1511 +{
1512 + CPUState *cs;
1513 +
1514 + g_assert(bql_locked());
1515 +
1516 + if (qemu_loglevel_mask(LOG_GUEST_ERROR) &&
1517 + (env->k0_lock_state != HEX_LOCK_UNLOCKED ||
1518 + env->tlb_lock_state != HEX_LOCK_UNLOCKED)) {
1519 + qemu_log("WARNING: executing wait() with acquired lock"
1520 + "may lead to deadlock\n");
1521 + }
1522 + g_assert(get_exe_mode(env) != HEX_EXE_MODE_WAIT);
1523 +
1524 + cs = env_cpu(env);
1525 + /*
1526 + * The addtion of cpu_has_work is borrowed from arm's wfi helper
1527 + * and is critical for our stability
1528 + */
1529 + if ((cs->exception_index != HEX_EVENT_NONE) ||
1530 + (cpu_has_work(cs))) {
1531 + qemu_log_mask(CPU_LOG_INT,
1532 + "%s: thread %" PRIu32 " skipping WAIT mode, have some work\n",
1533 + __func__, env->threadId);
1534 + return;
1535 + }
1536 + set_wait_mode(env);
1537 + env->wait_next_pc = PC + 4;
1538 +
1539 + cpu_interrupt(cs, CPU_INTERRUPT_HALT);
1540 +}
1541 +
1542 +void HELPER(wait)(CPUHexagonState *env, uint32_t PC)
1543 +{
1544 + BQL_LOCK_GUARD();
1545 +
1546 + if (!fIN_DEBUG_MODE(env->threadId)) {
1547 + hexagon_wait_thread(env, PC);
1548 + }
1549 }
1550
1551 void HELPER(resume)(CPUHexagonState *env, uint32_t mask)