From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:32928) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZTfZ4-0006vd-Qj for qemu-devel@nongnu.org; Sun, 23 Aug 2015 20:24:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZTfZ2-0000hD-50 for qemu-devel@nongnu.org; Sun, 23 Aug 2015 20:24:42 -0400 Received: from out4-smtp.messagingengine.com ([66.111.4.28]:53286) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZTfZ2-0000h8-1y for qemu-devel@nongnu.org; Sun, 23 Aug 2015 20:24:40 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id E9D8C20976 for ; Sun, 23 Aug 2015 20:24:39 -0400 (EDT) From: "Emilio G. Cota" Date: Sun, 23 Aug 2015 20:23:45 -0400 Message-Id: <1440375847-17603-17-git-send-email-cota@braap.org> In-Reply-To: <1440375847-17603-1-git-send-email-cota@braap.org> References: <1440375847-17603-1-git-send-email-cota@braap.org> Subject: [Qemu-devel] [RFC 16/38] aie: add module for Atomic Instruction Emulation List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, mttcg@listserver.greensocs.com Cc: mark.burton@greensocs.com, a.rigo@virtualopensystems.com, guillaume.delbergue@greensocs.com, pbonzini@redhat.com, alex.bennee@linaro.org, Frederic Konrad Signed-off-by: Emilio G. Cota --- 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