[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC 16/38] aie: add module for Atomic Instruction Emulatio
From: |
Emilio G. Cota |
Subject: |
[Qemu-devel] [RFC 16/38] aie: add module for Atomic Instruction Emulation |
Date: |
Sun, 23 Aug 2015 20:23:45 -0400 |
Signed-off-by: Emilio G. Cota <address@hidden>
---
Makefile.target | 1 +
aie.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/qemu/aie.h | 49 ++++++++++++++++++++++++++++++++++++++++++++++
translate-all.c | 2 ++
4 files changed, 109 insertions(+)
create mode 100644 aie.c
create mode 100644 include/qemu/aie.h
diff --git a/Makefile.target b/Makefile.target
index 3e7aafd..840e257 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -85,6 +85,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..588c02b
--- /dev/null
+++ b/aie.c
@@ -0,0 +1,57 @@
+/*
+ * 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
+ */
+#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;
+unsigned long *aie_bm;
+
+static void *aie_entry_init(unsigned long index)
+{
+ AIEEntry *entry;
+
+ entry = qemu_memalign(64, sizeof(*entry));
+ qemu_spin_init(&entry->lock);
+ entry->bm_set = false;
+ return entry;
+}
+
+AIEEntry *aie_entry_get_lock(hwaddr paddr)
+{
+ aie_addr_t idx = to_aie(paddr);
+ AIEEntry *e;
+
+ e = qemu_radix_tree_find_alloc(&aie_rtree, idx, aie_entry_init,
qemu_vfree);
+ qemu_spin_lock(&e->lock);
+ if (!e->bm_set) {
+ set_bit_atomic(idx & (AIE_BM_NR_ITEMS - 1), aie_bm);
+ e->bm_set = true;
+ }
+ return e;
+}
+
+void aie_init(void)
+{
+ qemu_radix_tree_init(&aie_rtree, AIE_ADDR_BITS, AIE_RADIX);
+ aie_bm = bitmap_new(AIE_BM_NR_ITEMS);
+}
diff --git a/include/qemu/aie.h b/include/qemu/aie.h
new file mode 100644
index 0000000..667f36c
--- /dev/null
+++ b/include/qemu/aie.h
@@ -0,0 +1,49 @@
+/*
+ * Atomic instruction emulation (AIE)
+ */
+#ifndef AIE_H
+#define AIE_H
+
+#include "qemu/radix-tree.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 {
+ QemuSpin lock;
+ bool bm_set;
+ };
+ uint8_t pad[64];
+ };
+} __attribute((aligned(64)));
+
+#define AIE_DISCARD_BITS 6
+
+#define AIE_BM_BITS 21
+#define AIE_BM_NR_ITEMS BIT(AIE_BM_BITS)
+
+extern QemuRadixTree aie_rtree;
+extern unsigned long *aie_bm;
+
+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 test_bit(to_aie(addr) & (AIE_BM_NR_ITEMS - 1), aie_bm);
+}
+
+#endif /* AIE_H */
diff --git a/translate-all.c b/translate-all.c
index b873d5c..f07547e 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -62,6 +62,7 @@
#include "translate-all.h"
#include "qemu/bitmap.h"
#include "qemu/timer.h"
+#include "qemu/aie.h"
//#define DEBUG_TB_INVALIDATE
//#define DEBUG_FLUSH
@@ -730,6 +731,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.9.1
- Re: [Qemu-devel] [RFC 05/38] thread-posix: inline qemu_spin functions, (continued)
[Qemu-devel] [RFC 11/38] qemu-thread: handle spurious futex_wait wakeups, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 13/38] cputlb: add physical address to CPUTLBEntry, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 14/38] softmmu: add helpers to get ld/st physical addresses, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 17/38] aie: add target helpers, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 15/38] radix-tree: add generic lockless radix tree module, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 16/38] aie: add module for Atomic Instruction Emulation,
Emilio G. Cota <=
[Qemu-devel] [RFC 20/38] tcg/i386: implement fences, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 29/38] tcg: export have_tb_lock, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 25/38] cpu: add barriers around cpu->tcg_exit_req, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 23/38] cpu-exec: grab iothread lock during interrupt handling, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 24/38] cpu-exec: reset mmap_lock after exiting the CPU loop, Emilio G. Cota, 2015/08/23