On 7/13/2026 1:07 PM, Matheus Tavares Bernardino wrote:
> From: Matheus Tavares Bernardino <[email protected]>
> 
> Will be used for semihosting.
> 
> Signed-off-by: Matheus Tavares Bernardino <[email protected]>
> Signed-off-by: Brian Cain <[email protected]>
> ---
>  target/hexagon/cpu_helper.h |   6 ++
>  target/hexagon/cpu_helper.c | 133 ++++++++++++++++++++++++++++++++++++
>  2 files changed, 139 insertions(+)
> 
> diff --git a/target/hexagon/cpu_helper.h b/target/hexagon/cpu_helper.h
> index d1767503156..f6a31ecbab0 100644
> --- a/target/hexagon/cpu_helper.h
> +++ b/target/hexagon/cpu_helper.h
> @@ -7,6 +7,12 @@
>  #ifndef HEXAGON_CPU_HELPER_H
>  #define HEXAGON_CPU_HELPER_H
>  
> +void hexagon_read_memory(CPUHexagonState *env, target_ulong vaddr, int size,
> +                         void *retptr, uintptr_t retaddr);
> +void hexagon_write_memory(CPUHexagonState *env, target_ulong vaddr,
> +                          int size, uint64_t data, uintptr_t retaddr);
> +void hexagon_touch_memory(CPUHexagonState *env, uint32_t start_addr,
> +                          uint32_t length, uintptr_t retaddr);
>  uint32_t hexagon_get_pmu_counter(CPUHexagonState *cur_env, int index);
>  void hexagon_modify_ssr(CPUHexagonState *env, uint32_t new, uint32_t old);
>  int get_cpu_mode(CPUHexagonState *env);
> diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
> index 64c5746c6d9..1ab2564e3dc 100644
> --- a/target/hexagon/cpu_helper.c
> +++ b/target/hexagon/cpu_helper.c
> @@ -25,6 +25,139 @@
>  #include "sys_macros.h"
>  #include "arch.h"
>  
> +#ifndef CONFIG_USER_ONLY
> +
> +static bool hexagon_read_memory_small(CPUHexagonState *env, target_ulong 
> addr,
> +                                      int byte_count, unsigned char *dstbuf,
> +                                      int mmu_idx, uintptr_t retaddr)
> + {
> +    /* handle small sizes */
> +    switch (byte_count) {
> +    case 1:
> +        *dstbuf = cpu_ldub_mmuidx_ra(env, addr, mmu_idx, retaddr);
> +        return true;
> +
> +    case 2:
> +        if (QEMU_IS_ALIGNED(addr, 2)) {
> +            *(unsigned short *)dstbuf =
> +                cpu_lduw_le_mmuidx_ra(env, addr, mmu_idx, retaddr);
> +            return true;
> +        }
> +        break;
> +
> +    case 4:
> +        if (QEMU_IS_ALIGNED(addr, 4)) {
> +            *(uint32_t *)dstbuf =
> +                cpu_ldl_le_mmuidx_ra(env, addr, mmu_idx, retaddr);
> +            return true;
> +        }
> +        break;
> +
> +    case 8:
> +        if (QEMU_IS_ALIGNED(addr, 8)) {
> +            *(uint64_t *)dstbuf =
> +                cpu_ldq_le_mmuidx_ra(env, addr, mmu_idx, retaddr);
> +            return true;
> +        }
> +        break;
> +
> +    default:
> +        /* larger request, handle elsewhere */
> +        return false;
> +    }
> +
> +    /* not aligned, copy bytes */
> +    for (int i = 0; i < byte_count; ++i) {
> +        *dstbuf++ = cpu_ldub_mmuidx_ra(env, addr++, mmu_idx, retaddr);
> +    }
> +    return true;
> +}
> +
> +void hexagon_read_memory(CPUHexagonState *env, target_ulong vaddr, int size,
> +                         void *retptr, uintptr_t retaddr)
> +{
> +    BQL_LOCK_GUARD();
> +    CPUState *cs = env_cpu(env);
> +    unsigned mmu_idx = cpu_mmu_index(cs, false);
> +    if (!hexagon_read_memory_small(env, vaddr, size, retptr, mmu_idx,
> +                                   retaddr)) {
> +        cpu_abort(cs, "%s: ERROR: bad size = %d!\n", __func__, size);
> +    }
> +}
> +
> +static bool hexagon_write_memory_small(CPUHexagonState *env, target_ulong 
> addr,
> +                                       int byte_count, unsigned char *srcbuf,
> +                                       int mmu_idx, uintptr_t retaddr)
> +{
> +    /* handle small sizes */
> +    switch (byte_count) {
> +    case 1:
> +        cpu_stb_mmuidx_ra(env, addr, *srcbuf, mmu_idx, retaddr);
> +        return true;
> +
> +    case 2:
> +        if (QEMU_IS_ALIGNED(addr, 2)) {
> +            cpu_stw_le_mmuidx_ra(env, addr, *(uint16_t *)srcbuf, mmu_idx, 
> retaddr);
> +            return true;
> +        }
> +        break;
> +
> +    case 4:
> +        if (QEMU_IS_ALIGNED(addr, 4)) {
> +            cpu_stl_le_mmuidx_ra(env, addr, *(uint32_t *)srcbuf, mmu_idx, 
> retaddr);
> +            return true;
> +        }
> +        break;
> +
> +    case 8:
> +        if (QEMU_IS_ALIGNED(addr, 8)) {
> +            cpu_stq_le_mmuidx_ra(env, addr, *(uint64_t *)srcbuf, mmu_idx, 
> retaddr);
> +            return true;
> +        }
> +        break;
> +
> +    default:
> +        /* larger request, handle elsewhere */
> +        return false;
> +    }
> +
> +    /* not aligned, copy bytes */
> +    for (int i = 0; i < byte_count; ++i) {
> +        cpu_stb_mmuidx_ra(env, addr++, *srcbuf++, mmu_idx, retaddr);
> +    }
> +
> +    return true;
> +}
> +
> +void hexagon_write_memory(CPUHexagonState *env, target_ulong vaddr,
> +                          int size, uint64_t data, uintptr_t retaddr)
> +{
> +    CPUState *cs = env_cpu(env);
> +    unsigned mmu_idx = cpu_mmu_index(cs, false);
> +    if (!hexagon_write_memory_small(env, vaddr, size, (unsigned char *)&data,
> +                                   mmu_idx, retaddr)) {
> +        cpu_abort(cs, "%s: ERROR: bad size = %d!\n", __func__, size);
> +    }
> +}
> +
> +static inline uint32_t page_start(uint32_t addr)
> +{
> +    uint32_t page_align = ~(TARGET_PAGE_SIZE - 1);
> +    return addr & page_align;
> +}
> +
> +void hexagon_touch_memory(CPUHexagonState *env, uint32_t start_addr,
> +                          uint32_t length, uintptr_t retaddr)
> +{
> +    unsigned int warm;
> +    uint32_t first = page_start(start_addr);
> +    uint32_t last = page_start(start_addr + length - 1);
> +    for (uint32_t page = first; page <= last; page += TARGET_PAGE_SIZE) {
> +        hexagon_read_memory(env, page, 1, &warm, retaddr);
> +    }
> +}
> +

Name could be misleading, I would be expectng to see a read/write
sequence in each page instead of just reading.
Maybe hexagon_peek_memory_range?

> +#endif
>  
>  uint32_t hexagon_get_pmu_counter(CPUHexagonState *cur_env, int index)
>  {

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

Regards,
Pierrick

Reply via email to