Signed-off-by: Emilio G. Cota <c...@braap.org> --- aie-helper.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++ include/exec/cpu-defs.h | 5 +++ include/qemu/aie-helper.h | 6 +++ 3 files changed, 123 insertions(+) create mode 100644 aie-helper.c create mode 100644 include/qemu/aie-helper.h
diff --git a/aie-helper.c b/aie-helper.c new file mode 100644 index 0000000..7521150 --- /dev/null +++ b/aie-helper.c @@ -0,0 +1,112 @@ +/* + * To be included directly from the target's helper.c + */ +#include "qemu/aie.h" + +#ifdef CONFIG_USER_ONLY +static inline +hwaddr h_get_ld_phys(CPUArchState *env, target_ulong vaddr, uintptr_t retaddr) +{ + return vaddr; +} + +static inline +hwaddr h_get_st_phys(CPUArchState *env, target_ulong vaddr, uintptr_t retaddr) +{ + return vaddr; +} +#else +static inline +hwaddr h_get_ld_phys(CPUArchState *env, target_ulong vaddr, uintptr_t retaddr) +{ + return helper_ret_get_ld_phys(env, vaddr, cpu_mmu_index(env), retaddr); +} + +static inline +hwaddr h_get_st_phys(CPUArchState *env, target_ulong vaddr, uintptr_t retaddr) +{ + return helper_ret_get_st_phys(env, vaddr, cpu_mmu_index(env), retaddr); +} +#endif /* CONFIG_USER_ONLY */ + +static inline void h_aie_lock(CPUArchState *env, hwaddr paddr) +{ + AIEEntry *entry = aie_entry_get_lock(paddr); + + env->aie_entry = entry; + env->aie_locked = true; +} + +static inline void h_aie_unlock(CPUArchState *env) +{ + assert(env->aie_entry && env->aie_locked); + qemu_spin_unlock(&env->aie_entry->lock); + env->aie_locked = false; +} + +static inline void h_aie_unlock__done(CPUArchState *env) +{ + h_aie_unlock(env); + env->aie_entry = NULL; +} + +static inline +void aie_ld_lock_ret(CPUArchState *env, target_ulong vaddr, uintptr_t retaddr) +{ + hwaddr paddr; + + assert(!env->aie_locked); + paddr = h_get_ld_phys(env, vaddr, retaddr); + h_aie_lock(env, paddr); +} + +void HELPER(aie_ld_lock)(CPUArchState *env, target_ulong vaddr) +{ + aie_ld_lock_ret(env, vaddr, GETRA()); +} + +static inline +void aie_st_lock_ret(CPUArchState *env, target_ulong vaddr, uintptr_t retaddr) +{ + hwaddr paddr; + + assert(!env->aie_locked); + paddr = h_get_st_phys(env, vaddr, retaddr); + h_aie_lock(env, paddr); +} + +void HELPER(aie_unlock__done)(CPUArchState *env) +{ + h_aie_unlock__done(env); +} + +void HELPER(aie_ld_pre)(CPUArchState *env, target_ulong vaddr) +{ + if (likely(!env->aie_lock_enabled) || env->aie_locked) { + return; + } + aie_ld_lock_ret(env, vaddr, GETRA()); +} + +void HELPER(aie_st_pre)(CPUArchState *env, target_ulong vaddr) +{ + if (unlikely(env->aie_lock_enabled)) { + if (env->aie_locked) { + return; + } + aie_st_lock_ret(env, vaddr, GETRA()); + } else { + hwaddr paddr = h_get_st_phys(env, vaddr, GETRA()); + + if (unlikely(aie_entry_exists(paddr))) { + h_aie_lock(env, paddr); + } + } +} + +void HELPER(aie_st_post)(CPUArchState *env, target_ulong vaddr) +{ + if (unlikely(!env->aie_lock_enabled && env->aie_locked)) { + h_aie_unlock__done(env); + } +} diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h index ca9c85c..e6e4568 100644 --- a/include/exec/cpu-defs.h +++ b/include/exec/cpu-defs.h @@ -28,6 +28,7 @@ #include "qemu/osdep.h" #include "qemu/queue.h" #include "tcg-target.h" +#include "qemu/aie.h" #ifndef CONFIG_USER_ONLY #include "exec/hwaddr.h" #endif @@ -152,5 +153,9 @@ typedef struct CPUIOTLBEntry { #define CPU_COMMON \ /* soft mmu support */ \ CPU_COMMON_TLB \ + AIEEntry *aie_entry; \ + bool aie_locked; \ + bool aie_lock_enabled; \ + bool aie_llsc_st_tracking; \ #endif diff --git a/include/qemu/aie-helper.h b/include/qemu/aie-helper.h new file mode 100644 index 0000000..86a786a --- /dev/null +++ b/include/qemu/aie-helper.h @@ -0,0 +1,6 @@ +DEF_HELPER_2(aie_ld_pre, void, env, tl) +DEF_HELPER_2(aie_st_pre, void, env, tl) +DEF_HELPER_2(aie_st_post, void, env, tl) + +DEF_HELPER_2(aie_ld_lock, void, env, tl) +DEF_HELPER_1(aie_unlock__done, void, env) -- 1.9.1