@@ -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
new file mode 100644
@@ -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);
+}
new file mode 100644
@@ -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 */
@@ -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. */
Signed-off-by: Emilio G. Cota <cota@braap.org> --- 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