On 9/15/2026 6:42 PM, Taylor Simpson wrote:


On Tue, Sep 15, 2026 at 9:45 AM Brian Cain <[email protected]> wrote:

    Hand the k0lock/tlblock helpers the packet PC as a constant instead
    of relying on next_PC's opcode-dependent staging.


The word "helpers" isn't entirely accurate.  The QEMU helpers already take PC as an argument. This patch adds the PC argument to the implementation functions hex_tlb_lock/hex_k0_lock called from the respective helpers.
See my comment below on hex_common.py.

Thanks for the feedback.  I'll work on a follow up series to address the issues you raised in this one.



    Signed-off-by: Brian Cain <[email protected]>
    ---
     target/hexagon/hex_mmu.h     |  9 +++++----
     target/hexagon/sys_macros.h  |  4 ++--
     target/hexagon/hex_mmu.c     | 15 ++++++++-------
     target/hexagon/op_helper.c   | 15 ++++++++-------
     target/hexagon/hex_common.py |  6 +++++-
     5 files changed, 28 insertions(+), 21 deletions(-)

    diff --git a/target/hexagon/hex_mmu.h b/target/hexagon/hex_mmu.h
    index 56b2c4a89d0..4eaf15c4996 100644
    --- a/target/hexagon/hex_mmu.h
    +++ b/target/hexagon/hex_mmu.h
    @@ -17,12 +17,13 @@ extern uint32_t hex_tlb_lookup(CPUHexagonState
    *env, uint32_t ssr, uint32_t VA);
     extern void hex_mmu_on(CPUHexagonState *env);
     extern void hex_mmu_off(CPUHexagonState *env);
     extern void hex_mmu_mode_change(CPUHexagonState *env);
    -extern bool hex_tlb_find_match(CPUHexagonState *env, uint32_t VA,
    -                               MMUAccessType access_type, hwaddr
    *PA, int *prot,
    -                               uint64_t *size, int32_t *excp, int
    mmu_idx);
    +extern bool hex_tlb_find_match(CPUHexagonState *env, target_ulong VA,
    +                               MMUAccessType access_type,
    +                               hwaddr *PA, int *prot, uint64_t *size,
    +                               int32_t *excp, int mmu_idx);


Why is this change included in this patch?

     extern int hex_tlb_check_overlap(CPUHexagonState *env, uint64_t
    entry,
                                      uint64_t index);
    -extern void hex_tlb_lock(CPUHexagonState *env);
    +extern void hex_tlb_lock(CPUHexagonState *env, target_ulong PC);
     extern void hex_tlb_unlock(CPUHexagonState *env);
     void dump_mmu(MonitorHMP *hmp, CPUHexagonState *env);
     #endif
    diff --git a/target/hexagon/sys_macros.h b/target/hexagon/sys_macros.h
    index a5b9b7f2592..72179d49ab3 100644
    --- a/target/hexagon/sys_macros.h
    +++ b/target/hexagon/sys_macros.h
    @@ -145,10 +145,10 @@
     #define fDCINVIDX(REG)
     #define fDCINVA(REG) do { REG = REG; } while (0) /* Nothing to do
    in qemu */

    -#define fSET_TLB_LOCK()       hex_tlb_lock(env);
    +#define fSET_TLB_LOCK()       hex_tlb_lock(env, PC);
     #define fCLEAR_TLB_LOCK()     hex_tlb_unlock(env);

    -#define fSET_K0_LOCK()        hex_k0_lock(env);
    +#define fSET_K0_LOCK()        hex_k0_lock(env, PC);
     #define fCLEAR_K0_LOCK()      hex_k0_unlock(env);

     #define fTLB_IDXMASK(INDEX) \
    diff --git a/target/hexagon/hex_mmu.c b/target/hexagon/hex_mmu.c
    index d6ee7c40798..d7acaae5ac8 100644
    --- a/target/hexagon/hex_mmu.c
    +++ b/target/hexagon/hex_mmu.c
    @@ -156,7 +156,7 @@ static inline void print_thread_states(const
    char *str)
         }
     }

    -void hex_tlb_lock(CPUHexagonState *env)
    +void hex_tlb_lock(CPUHexagonState *env, target_ulong PC)
     {
         qemu_log_mask(CPU_LOG_MMU, "hex_tlb_lock: " TARGET_FMT_ld "\n",
                       env->threadId);
    @@ -170,7 +170,6 @@ void hex_tlb_lock(CPUHexagonState *env)
         uint8_t tlb_lock = GET_SYSCFG_FIELD(SYSCFG_TLBLOCK, syscfg);
         if (tlb_lock) {
             if (env->tlb_lock_state == HEX_LOCK_QUEUED) {
    -            env->next_PC += 4;
                 env->tlb_lock_count++;
                 env->tlb_lock_state = HEX_LOCK_OWNER;
                 SET_SYSCFG_FIELD(env, SYSCFG_TLBLOCK, 1);
    @@ -178,19 +177,21 @@ void hex_tlb_lock(CPUHexagonState *env)
             }
             if (env->tlb_lock_state == HEX_LOCK_OWNER) {
                 qemu_log_mask(CPU_LOG_MMU | LOG_GUEST_ERROR,
    -                          "Double tlblock at PC: 0x%" PRIx32
    -                          ", thread may hang\n",
    -                          env->next_PC);
    -            env->next_PC += 4;
    +                          "Double tlblock at PC: 0x%x, thread may
    hang\n", PC);


Don't use %x, use TARGET_FMT_lx.

                 CPUState *cs = env_cpu(env);
                 cpu_interrupt(cs, CPU_INTERRUPT_HALT);
                 return;
             }
             env->tlb_lock_state = HEX_LOCK_WAITING;
    +        /*
    +         * next_PC has already been advanced past this packet. 
    Rewind it
    +         * so that the thread re-executes the tlblock when it is
    woken by
    +         * the thread that releases the lock.
    +         */
    +        env->next_PC = PC;
             CPUState *cs = env_cpu(env);
             cpu_interrupt(cs, CPU_INTERRUPT_HALT);
         } else {
    -        env->next_PC += 4;
             env->tlb_lock_count++;
             env->tlb_lock_state = HEX_LOCK_OWNER;
             SET_SYSCFG_FIELD(env, SYSCFG_TLBLOCK, 1);
    diff --git a/target/hexagon/op_helper.c b/target/hexagon/op_helper.c
    index 0d08ac77361..07ba639449c 100644
    --- a/target/hexagon/op_helper.c
    +++ b/target/hexagon/op_helper.c
    @@ -1278,7 +1278,7 @@ void HELPER(modify_ssr)(CPUHexagonState
    *env, uint32_t new, uint32_t old)
         hexagon_modify_ssr(env, new, old);
     }

    -static void hex_k0_lock(CPUHexagonState *env)
    +static void hex_k0_lock(CPUHexagonState *env, target_ulong PC)
     {
         HexagonCPU *cpu = env_archcpu(env);
         CPUState *cs = env_cpu(env);
    @@ -1292,7 +1292,6 @@ static void hex_k0_lock(CPUHexagonState *env)
                                    env->threadId) : 0;
         if (GET_SYSCFG_FIELD(SYSCFG_K0LOCK, syscfg)) {
             if (env->k0_lock_state == HEX_LOCK_QUEUED) {
    -            env->next_PC += 4;
                 env->k0_lock_count++;
                 env->k0_lock_state = HEX_LOCK_OWNER;
                 SET_SYSCFG_FIELD(env, SYSCFG_K0LOCK, 1);
    @@ -1300,19 +1299,21 @@ static void hex_k0_lock(CPUHexagonState *env)
             }
             if (env->k0_lock_state == HEX_LOCK_OWNER) {
                 qemu_log_mask(LOG_GUEST_ERROR,
    -                          "Double k0lock at PC: 0x%" PRIx32
    -                          ", thread may hang\n",
    -                          env->next_PC);
    -            env->next_PC += 4;
    +                          "Double k0lock at PC: 0x%x, thread may
    hang\n", PC);


Don't use %x, use TARGET_FMT_lx.

                 cpu_interrupt(cs, CPU_INTERRUPT_HALT);
                 cpu_loop_exit(cs);
                 return;
             }
             env->k0_lock_state = HEX_LOCK_WAITING;
    +        /*
    +         * next_PC has already been advanced past this packet. 
    Rewind it
    +         * so that the thread re-executes the k0lock when it is
    woken by
    +         * the thread that releases the lock.
    +         */
    +        env->next_PC = PC;
             cpu_interrupt(cs, CPU_INTERRUPT_HALT);
             cpu_loop_exit(cs);
         } else {
    -        env->next_PC += 4;
             env->k0_lock_count++;
             env->k0_lock_state = HEX_LOCK_OWNER;
             SET_SYSCFG_FIELD(env, SYSCFG_K0LOCK, 1);
    diff --git a/target/hexagon/hex_common.py
    b/target/hexagon/hex_common.py
    index c180c19b092..1bd31f76a4f 100755
    --- a/target/hexagon/hex_common.py
    +++ b/target/hexagon/hex_common.py
    @@ -284,7 +284,11 @@ def need_ea(tag):


     def need_PC(tag):
    -    return "A_IMPLICIT_READS_PC" in attribdict[tag]
    +    return (
    +        "A_IMPLICIT_READS_PC" in attribdict[tag]
    +        or tag == "Y2_k0lock"
    +        or tag == "Y2_tlblock"
    +    )


This isn't needed.  These 2 opcodes already have A_IMPLICIT_READS_PC set.
Look for fSET_K0_LOCK and fSET_TLB_LOCK in calculate_attribs in hex_common.py.

Thanks,
Taylor

Reply via email to