qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC 6/8] aie: add target helpers


From: Emilio G. Cota
Subject: [Qemu-devel] [RFC 6/8] aie: add target helpers
Date: Fri, 8 May 2015 17:02:12 -0400

Signed-off-by: Emilio G. Cota <address@hidden>
---
 aie-helper.c              | 179 ++++++++++++++++++++++++++++++++++++++++++++++
 include/exec/cpu-defs.h   |   5 ++
 include/qemu/aie-helper.h |  21 ++++++
 3 files changed, 205 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..8bc8955
--- /dev/null
+++ b/aie-helper.c
@@ -0,0 +1,179 @@
+/*
+ * 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)
+{
+    return vaddr;
+}
+
+static inline hwaddr h_get_st_phys(CPUArchState *env, target_ulong vaddr)
+{
+    return vaddr;
+}
+#else
+/* these need to be macros due to GETRA() */
+#define h_get_ld_phys(env, vaddr)                                       \
+    helper_ret_get_ld_phys(env, vaddr, cpu_mmu_index(env), GETRA())
+#define h_get_st_phys(env, vaddr)                                       \
+    helper_ret_get_st_phys(env, vaddr, cpu_mmu_index(env), GETRA())
+#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_mutex_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;
+}
+
+void HELPER(aie_llsc_st_tracking_enable)(CPUArchState *env)
+{
+    CPUState *other_cs;
+
+    if (likely(atomic_read(&env->aie_llsc_st_tracking))) {
+        return;
+    }
+    CPU_FOREACH(other_cs) {
+        CPUArchState *other_env = other_cs->env_ptr;
+
+        atomic_set(&other_env->aie_llsc_st_tracking, true);
+    }
+}
+
+void HELPER(aie_ld_lock)(CPUArchState *env, target_ulong vaddr)
+{
+    hwaddr paddr;
+
+    assert(!env->aie_locked);
+    paddr = h_get_ld_phys(env, vaddr);
+    h_aie_lock(env, paddr);
+}
+
+void HELPER(aie_st_lock)(CPUArchState *env, target_ulong vaddr)
+{
+    hwaddr paddr;
+
+    assert(!env->aie_locked);
+    paddr = h_get_st_phys(env, vaddr);
+    h_aie_lock(env, paddr);
+}
+
+void HELPER(aie_insert_lock)(CPUArchState *env, target_ulong vaddr)
+{
+    AIEEntry *entry;
+    hwaddr paddr;
+
+    assert(!env->aie_locked);
+    paddr = h_get_ld_phys(env, vaddr);
+    entry = aie_entry_get_lock(paddr);
+
+    tiny_set_insert(&entry->ts, current_cpu);
+    env->aie_entry = entry;
+    env->aie_locked = true;
+}
+
+uint32_t HELPER(aie_contains_lock)(CPUArchState *env)
+{
+    AIEEntry *entry = env->aie_entry;
+
+    /* clrex could arrive between ldrex and strex due to preemption */
+    if (unlikely(entry == NULL)) {
+        return -1;
+    }
+    qemu_mutex_lock(&entry->lock);
+    env->aie_locked = true;
+    if (tiny_set_contains(&entry->ts, current_cpu)) {
+        tiny_set_remove_all(&entry->ts);
+        return 0;
+    }
+    qemu_mutex_unlock(&entry->lock);
+    env->aie_locked = false;
+    env->aie_entry = NULL;
+    return -1;
+}
+
+void HELPER(aie_unlock)(CPUArchState *env)
+{
+    h_aie_unlock(env);
+}
+
+void HELPER(aie_unlock__done)(CPUArchState *env)
+{
+    h_aie_unlock__done(env);
+}
+
+void HELPER(aie_clear)(CPUArchState *env)
+{
+    AIEEntry *entry = env->aie_entry;
+
+    assert(!env->aie_locked);
+    if (!entry) {
+        return;
+    }
+
+    qemu_mutex_lock(&env->aie_entry->lock);
+    tiny_set_remove(&entry->ts, current_cpu);
+    qemu_mutex_unlock(&env->aie_entry->lock);
+    env->aie_entry = NULL;
+}
+
+void HELPER(aie_ld_pre)(CPUArchState *env, target_ulong vaddr)
+{
+    if (likely(!env->aie_lock_enabled) || env->aie_locked) {
+        return;
+    }
+    helper_aie_ld_lock(env, vaddr);
+}
+
+void HELPER(aie_st_pre)(CPUArchState *env, target_ulong vaddr)
+{
+    if (unlikely(env->aie_lock_enabled)) {
+        if (env->aie_locked) {
+            return;
+        }
+        helper_aie_st_lock(env, vaddr);
+    } else {
+        hwaddr paddr = h_get_st_phys(env, vaddr);
+
+        if (unlikely(aie_entry_exists(paddr))) {
+            h_aie_lock(env, paddr);
+        }
+    }
+}
+
+void HELPER(aie_llsc_st_pre)(CPUArchState *env, target_ulong vaddr)
+{
+    hwaddr paddr;
+
+    assert(!env->aie_locked);
+    if (!env->aie_llsc_st_tracking) {
+        return;
+    }
+    paddr = h_get_st_phys(env, vaddr);
+    if (unlikely(aie_entry_exists(paddr))) {
+        h_aie_lock(env, paddr);
+    }
+}
+
+void HELPER(aie_llsc_st_post)(CPUArchState *env)
+{
+    if (unlikely(env->aie_locked)) {
+        h_aie_unlock__done(env);
+    }
+}
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 67aa0a0..8891f16 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -27,6 +27,7 @@
 #include <inttypes.h>
 #include "qemu/osdep.h"
 #include "qemu/queue.h"
+#include "qemu/aie.h"
 #ifndef CONFIG_USER_ONLY
 #include "exec/hwaddr.h"
 #endif
@@ -135,5 +136,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..7605e07
--- /dev/null
+++ b/include/qemu/aie-helper.h
@@ -0,0 +1,21 @@
+#ifdef TARGET_ARM
+#define AIE_VADDR_TCG_TYPE glue(i, TARGET_VIRT_ADDR_SPACE_BITS)
+#else
+#define AIE_VADDR_TCG_TYPE tl
+#endif /* TARGET_ARM */
+
+DEF_HELPER_2(aie_ld_pre, void, env, AIE_VADDR_TCG_TYPE)
+DEF_HELPER_2(aie_st_pre, void, env, AIE_VADDR_TCG_TYPE)
+DEF_HELPER_2(aie_llsc_st_pre, void, env, AIE_VADDR_TCG_TYPE)
+DEF_HELPER_1(aie_llsc_st_post, void, env)
+DEF_HELPER_1(aie_llsc_st_tracking_enable, void, env)
+
+DEF_HELPER_2(aie_ld_lock, void, env, AIE_VADDR_TCG_TYPE)
+DEF_HELPER_2(aie_st_lock, void, env, AIE_VADDR_TCG_TYPE)
+DEF_HELPER_2(aie_insert_lock, void, env, AIE_VADDR_TCG_TYPE)
+DEF_HELPER_1(aie_contains_lock, i32, env)
+DEF_HELPER_1(aie_unlock, void, env)
+DEF_HELPER_1(aie_unlock__done, void, env)
+DEF_HELPER_1(aie_clear, void, env)
+
+#undef AIE_VADDR_TCG_TYPE
-- 
1.8.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]