Signed-off-by: Emilio G. Cota <c...@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
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