From aca3f40b374428e9c01068cf96294483cbb760a0 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 15 Apr 2014 19:18:41 +0100 Subject: target-arm: A64: Implement DC ZVA Implement the DC ZVA instruction, which clears a block of memory. The fast path obtains a pointer to the underlying RAM via the TCG TLB data structure so we can do a direct memset(), with fallback to a simple byte-store loop in the slow path. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Acked-by: Peter Crosthwaite --- include/exec/softmmu_exec.h | 52 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'include/exec') diff --git a/include/exec/softmmu_exec.h b/include/exec/softmmu_exec.h index 6fde154..470db20 100644 --- a/include/exec/softmmu_exec.h +++ b/include/exec/softmmu_exec.h @@ -162,3 +162,55 @@ #define stw(p, v) stw_data(p, v) #define stl(p, v) stl_data(p, v) #define stq(p, v) stq_data(p, v) + +/** + * tlb_vaddr_to_host: + * @env: CPUArchState + * @addr: guest virtual address to look up + * @access_type: 0 for read, 1 for write, 2 for execute + * @mmu_idx: MMU index to use for lookup + * + * Look up the specified guest virtual index in the TCG softmmu TLB. + * If the TLB contains a host virtual address suitable for direct RAM + * access, then return it. Otherwise (TLB miss, TLB entry is for an + * I/O access, etc) return NULL. + * + * This is the equivalent of the initial fast-path code used by + * TCG backends for guest load and store accesses. + */ +static inline void *tlb_vaddr_to_host(CPUArchState *env, target_ulong addr, + int access_type, int mmu_idx) +{ + int index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + CPUTLBEntry *tlbentry = &env->tlb_table[mmu_idx][index]; + target_ulong tlb_addr; + uintptr_t haddr; + + switch (access_type) { + case 0: + tlb_addr = tlbentry->addr_read; + break; + case 1: + tlb_addr = tlbentry->addr_write; + break; + case 2: + tlb_addr = tlbentry->addr_code; + break; + default: + g_assert_not_reached(); + } + + if ((addr & TARGET_PAGE_MASK) + != (tlb_addr & (TARGET_PAGE_MASK | TLB_INVALID_MASK))) { + /* TLB entry is for a different page */ + return NULL; + } + + if (tlb_addr & ~TARGET_PAGE_MASK) { + /* IO access */ + return NULL; + } + + haddr = addr + env->tlb_table[mmu_idx][index].addend; + return (void *)haddr; +} -- cgit v1.1