Commit 2671377a10 for qemu.org
commit 2671377a10c4eb730dc789da69639d7d69812001
Author: Brian Cain <brian.cain@oss.qualcomm.com>
Date: Tue Sep 1 10:33:52 2026 -0700
target/hexagon: fix iassign{r, w} to cover all threads
iassignw/iassignr were filtering CPU_FOREACH by MODECTL_E, the
thread-enabled mask. That mask reflects whether a thread has been
started, not whether it exists, so IMASK writes/reads never reached
threads that hadn't been started yet, leaving their IMASK stale or
unreadable. Drop the MODECTL_E filtering and operate on every thread.
Reviewed-by: Pierrick Bouvier <pierrick.bouvier@oss.qualcomm.com>
Signed-off-by: Brian Cain <brian.cain@oss.qualcomm.com>
diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
index f9e66acf84..2168c6361d 100644
--- a/target/hexagon/op_helper.c
+++ b/target/hexagon/op_helper.c
@@ -1635,61 +1635,39 @@ void HELPER(cswi)(CPUHexagonState *env, uint32_t mask)
void HELPER(iassignw)(CPUHexagonState *env, uint32_t src)
{
- uint32_t modectl;
- uint32_t thread_enabled_mask;
CPUState *cpu;
- HexagonCPU *hex_cpu;
BQL_LOCK_GUARD();
- hex_cpu = env_archcpu(env);
- modectl = hex_cpu->globalregs ?
- hexagon_globalreg_read(hex_cpu->globalregs, HEX_SREG_MODECTL,
- env->threadId) : 0;
- thread_enabled_mask = GET_FIELD(MODECTL_E, modectl);
CPU_FOREACH(cpu) {
CPUHexagonState *thread_env = &(HEXAGON_CPU(cpu)->env);
- uint32_t thread_id_mask = 0x1 << thread_env->threadId;
- if (thread_enabled_mask & thread_id_mask) {
- uint32_t imask = thread_env->t_sreg[HEX_SREG_IMASK];
- uint32_t intbitpos = (src >> 16) & 0xF;
- uint32_t val = (src >> thread_env->threadId) & 0x1;
- imask = deposit32(imask, intbitpos, 1, val);
- thread_env->t_sreg[HEX_SREG_IMASK] = imask;
-
- qemu_log_mask(CPU_LOG_INT, "%s: thread " TARGET_FMT_ld
- ", new imask 0x%" PRIx32 "\n", __func__,
- thread_env->threadId, imask);
- }
+ uint32_t imask = thread_env->t_sreg[HEX_SREG_IMASK];
+ uint32_t intbitpos = (src >> 16) & 0xF;
+ uint32_t val = (src >> thread_env->threadId) & 0x1;
+ imask = deposit32(imask, intbitpos, 1, val);
+ thread_env->t_sreg[HEX_SREG_IMASK] = imask;
+
+ qemu_log_mask(CPU_LOG_INT, "%s: thread " TARGET_FMT_ld
+ ", new imask 0x%" PRIx32 "\n", __func__,
+ thread_env->threadId, imask);
}
hex_interrupt_update(env);
}
uint32_t HELPER(iassignr)(CPUHexagonState *env, uint32_t src)
{
- uint32_t modectl;
- uint32_t thread_enabled_mask;
uint32_t intbitpos;
uint32_t dest_reg;
CPUState *cpu;
- HexagonCPU *hex_cpu;
BQL_LOCK_GUARD();
- hex_cpu = env_archcpu(env);
- modectl = hex_cpu->globalregs ?
- hexagon_globalreg_read(hex_cpu->globalregs, HEX_SREG_MODECTL,
- env->threadId) : 0;
- thread_enabled_mask = GET_FIELD(MODECTL_E, modectl);
/* src fields are in same position as modectl, but mean different things */
intbitpos = GET_FIELD(MODECTL_W, src);
dest_reg = 0;
CPU_FOREACH(cpu) {
CPUHexagonState *thread_env = &(HEXAGON_CPU(cpu)->env);
- uint32_t thread_id_mask = 0x1 << thread_env->threadId;
- if (thread_enabled_mask & thread_id_mask) {
- uint32_t imask = thread_env->t_sreg[HEX_SREG_IMASK];
- dest_reg |= ((imask >> intbitpos) & 0x1) << thread_env->threadId;
- }
+ uint32_t imask = thread_env->t_sreg[HEX_SREG_IMASK];
+ dest_reg |= ((imask >> intbitpos) & 0x1) << thread_env->threadId;
}
return dest_reg;