On 6/1/2026 12:39 PM, Brian Cain wrote:
> On Mon, Jun 1, 2026 at 2:23 PM Pierrick Bouvier
> <[email protected]> wrote:
>>
>> On 5/29/2026 2:57 PM, Brian Cain wrote:
>>> From: Brian Cain <[email protected]>
>>>
>>> The hardware-assisted scheduler helps manage tasks on the run queue
>>> and interrupt steering.
>>>
>>> Signed-off-by: Brian Cain <[email protected]>
>>> ---
>>>  target/hexagon/op_helper.c | 77 ++++++++++++++++++++++++++++++++++++++
>>>  1 file changed, 77 insertions(+)
>>>
>>> diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
>>> index 64f1fb2043f..82062a2f802 100644
>>> --- a/target/hexagon/op_helper.c
>>> +++ b/target/hexagon/op_helper.c
>>> @@ -1589,6 +1589,64 @@ static void hexagon_wait_thread(CPUHexagonState 
>>> *env, uint32_t PC)
>>>      cpu_interrupt(cs, CPU_INTERRUPT_HALT);
>>>  }
>>>
>>> +static inline QEMU_ALWAYS_INLINE void resched(CPUHexagonState *env)
>>> +{
>>> +    uint32_t schedcfg;
>>> +    uint32_t schedcfg_en;
>>> +    int int_number;
>>> +    CPUState *cs;
>>> +    uint32_t lowest_th_prio = 0; /* 0 is highest prio */
>>> +    uint32_t bestwait_reg;
>>> +    uint32_t best_prio;
>>> +    HexagonCPU *cpu;
>>> +
>>> +    BQL_LOCK_GUARD();
>>> +    qemu_log_mask(CPU_LOG_INT, "%s: check resched\n", __func__);
>>> +    cpu = env_archcpu(env);
>>> +    schedcfg = cpu->globalregs ?
>>> +        hexagon_globalreg_read(cpu->globalregs, HEX_SREG_SCHEDCFG,
>>> +                               env->threadId) : 0;
>>> +    schedcfg_en = GET_FIELD(SCHEDCFG_EN, schedcfg);
>>> +    int_number = GET_FIELD(SCHEDCFG_INTNO, schedcfg);
>>> +
>>> +    if (!schedcfg_en) {
>>> +        return;
>>> +    }
>>> +
>>
>> Is that really a noop in this case?
>> Or should it trigger an exception if sched is not enabled?
> 
> It's a noop, the scheduler has no effect when SCHEDCFG_EN is disabled.
>

Ok.

>>> +    CPU_FOREACH(cs) {
>>> +        HexagonCPU *thread = HEXAGON_CPU(cs);
>>> +        CPUHexagonState *thread_env = &(thread->env);
>>> +        uint32_t th_prio = GET_FIELD(
>>> +            STID_PRIO, thread_env->t_sreg[HEX_SREG_STID]);
>>> +        if (!hexagon_thread_is_enabled(thread_env)) {
>>> +            continue;
>>> +        }
>>> +
>>> +        lowest_th_prio = (lowest_th_prio > th_prio)
>>> +            ? lowest_th_prio
>>> +            : th_prio;
>>> +    }
>>> +
>>> +    bestwait_reg = cpu->globalregs ?
>>> +        hexagon_globalreg_read(cpu->globalregs, HEX_SREG_BESTWAIT,
>>> +                               env->threadId) : 0;
>>> +    best_prio = GET_FIELD(BESTWAIT_PRIO, bestwait_reg);
>>> +
>>> +    /*
>>> +     * If the lowest priority thread is lower priority than the
>>> +     * value in the BESTWAIT register, we must raise the reschedule
>>> +     * interrupt on the lowest priority thread.
>>> +     */
>>> +    if (lowest_th_prio > best_prio) {
>>> +        qemu_log_mask(CPU_LOG_INT,
>>> +                "%s: raising resched int %u,"
>>> +                " cur PC 0x%" PRIx32 "\n",
>>> +                __func__, (unsigned)int_number, env->gpr[HEX_REG_PC]);
>>> +        SET_SYSTEM_FIELD(env, HEX_SREG_BESTWAIT, BESTWAIT_PRIO, ~0);
>>> +        hex_raise_interrupts(env, 1 << int_number, CPU_INTERRUPT_SWI);
>>> +    }
>>> +}
>>> +
>>>  void HELPER(wait)(CPUHexagonState *env, uint32_t PC)
>>>  {
>>>      BQL_LOCK_GUARD();
>>> @@ -1697,8 +1755,27 @@ uint64_t HELPER(greg_read_pair)(CPUHexagonState 
>>> *env, uint32_t reg)
>>>      g_assert_not_reached();
>>>  }
>>>
>>> +/*
>>> + * setprio/resched - hardware-assisted scheduler helpers for managing
>>> + * the run queue and interrupt steering.
>>> + */
>>>  void HELPER(setprio)(CPUHexagonState *env, uint32_t thread, uint32_t prio)
>>>  {
>>> +    CPUState *cs;
>>> +
>>> +    BQL_LOCK_GUARD();
>>> +    CPU_FOREACH(cs) {
>>> +        HexagonCPU *found_cpu = HEXAGON_CPU(cs);
>>> +        CPUHexagonState *found_env = &found_cpu->env;
>>> +        if (thread == found_env->threadId) {
>>> +            SET_SYSTEM_FIELD(found_env, HEX_SREG_STID, STID_PRIO, prio);
>>> +            qemu_log_mask(CPU_LOG_INT,
>>> +                          "%s: tid %" PRIu32 " prio = 0x%" PRIx32 "\n",
>>> +                          __func__, found_env->threadId, prio);
>>> +            resched(env);
>>> +            return;
>>> +        }
>>> +    }
>>>      g_assert_not_reached();
>>>  }
>>>
>>

Reviewed-by: Pierrick Bouvier <[email protected]>


Reply via email to