qemu-devel
[Top][All Lists]
Advanced

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

[Qemu-devel] [RFC 5/8] aie: add module for Atomic Instruction Emulation


From: Emilio G. Cota
Subject: [Qemu-devel] [RFC 5/8] aie: add module for Atomic Instruction Emulation
Date: Fri, 8 May 2015 17:02:11 -0400

Signed-off-by: Emilio G. Cota <address@hidden>
---
 Makefile.target    |  1 +
 aie.c              | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/qemu/aie.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 translate-all.c    |  2 ++
 4 files changed, 103 insertions(+)
 create mode 100644 aie.c
 create mode 100644 include/qemu/aie.h

diff --git a/Makefile.target b/Makefile.target
index 1083377..ab2fe6c 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -83,6 +83,7 @@ all: $(PROGS) stap
 #########################################################
 # cpu emulator library
 obj-y = exec.o translate-all.o cpu-exec.o
+obj-y += aie.o
 obj-y += tcg/tcg.o tcg/tcg-op.o tcg/optimize.o
 obj-$(CONFIG_TCG_INTERPRETER) += tci.o
 obj-$(CONFIG_TCG_INTERPRETER) += disas/tci.o
diff --git a/aie.c b/aie.c
new file mode 100644
index 0000000..a22098b
--- /dev/null
+++ b/aie.c
@@ -0,0 +1,52 @@
+/*
+ * Atomic instruction emulation (AIE).
+ * This applies to LL/SC and higher-order atomic instructions.
+ * More info:
+ *   http://en.wikipedia.org/wiki/Load-link/store-conditional
+ * License: XXX
+ */
+#include "qemu-common.h"
+#include "qemu/radix-tree.h"
+#include "qemu/thread.h"
+#include "qemu/aie.h"
+
+#if defined(CONFIG_USER_ONLY)
+# define AIE_FULL_ADDR_BITS  TARGET_VIRT_ADDR_SPACE_BITS
+#else
+#if HOST_LONG_BITS < TARGET_PHYS_ADDR_SPACE_BITS
+/* in this case QEMU restricts the maximum RAM size to fit in the host */
+# define AIE_FULL_ADDR_BITS  HOST_LONG_BITS
+#else
+# define AIE_FULL_ADDR_BITS  TARGET_PHYS_ADDR_SPACE_BITS
+#endif
+#endif /* CONFIG_USER_ONLY */
+
+#define AIE_ADDR_BITS  (AIE_FULL_ADDR_BITS - AIE_DISCARD_BITS)
+#define AIE_RADIX     8
+
+QemuRadixTree aie_rtree;
+
+static inline void *aie_entry_init(unsigned long index)
+{
+    AIEEntry *entry;
+
+    entry = qemu_memalign(64, sizeof(*entry));
+    tiny_set_init(&entry->ts);
+    qemu_mutex_init(&entry->lock);
+    return entry;
+}
+
+AIEEntry *aie_entry_get_lock(hwaddr addr)
+{
+    aie_addr_t laddr = to_aie(addr);
+    AIEEntry *e;
+
+    e = qemu_radix_tree_find_alloc(&aie_rtree, laddr, aie_entry_init, g_free);
+    qemu_mutex_lock(&e->lock);
+    return e;
+}
+
+void aie_init(void)
+{
+    qemu_radix_tree_init(&aie_rtree, AIE_ADDR_BITS, AIE_RADIX);
+}
diff --git a/include/qemu/aie.h b/include/qemu/aie.h
new file mode 100644
index 0000000..ae4e85e
--- /dev/null
+++ b/include/qemu/aie.h
@@ -0,0 +1,48 @@
+/*
+ * Atomic instruction emulation (AIE)
+ * License: XXX
+ */
+#ifndef AIE_H
+#define AIE_H
+
+#include "qemu/radix-tree.h"
+#include "qemu/tiny_set.h"
+#include "qemu/thread.h"
+#include "qemu/bitops.h"
+
+#include "exec/hwaddr.h"
+
+typedef hwaddr aie_addr_t;
+
+typedef struct AIEEntry AIEEntry;
+
+struct AIEEntry {
+    union {
+        struct {
+            TinySet ts;
+            QemuMutex lock;
+        };
+        uint8_t pad[64];
+    };
+} __attribute((aligned(64)));
+
+/* support atomic ops of up to 16-byte size */
+#define AIE_DISCARD_BITS 4
+
+extern QemuRadixTree aie_rtree;
+
+static inline aie_addr_t to_aie(hwaddr paddr)
+{
+    return paddr >> AIE_DISCARD_BITS;
+}
+
+void aie_init(void);
+
+AIEEntry *aie_entry_get_lock(hwaddr addr);
+
+static inline bool aie_entry_exists(hwaddr addr)
+{
+    return !!qemu_radix_tree_find(&aie_rtree, to_aie(addr));
+}
+
+#endif /* AIE_H */
diff --git a/translate-all.c b/translate-all.c
index 65a76c5..c12f333 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -61,6 +61,7 @@
 #include "translate-all.h"
 #include "qemu/bitmap.h"
 #include "qemu/timer.h"
+#include "qemu/aie.h"
 
 //#define DEBUG_TB_INVALIDATE
 //#define DEBUG_FLUSH
@@ -684,6 +685,7 @@ void tcg_exec_init(unsigned long tb_size)
     tcg_ctx.code_gen_ptr = tcg_ctx.code_gen_buffer;
     tcg_register_jit(tcg_ctx.code_gen_buffer, tcg_ctx.code_gen_buffer_size);
     page_init();
+    aie_init();
 #if !defined(CONFIG_USER_ONLY) || !defined(CONFIG_USE_GUEST_BASE)
     /* There's no guest base to take into account, so go ahead and
        initialize the prologue now.  */
-- 
1.8.3




reply via email to

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