From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1CgSKM-0008NO-VX for qemu-devel@nongnu.org; Mon, 20 Dec 2004 13:32:15 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1CgSKM-0008Mz-8L for qemu-devel@nongnu.org; Mon, 20 Dec 2004 13:32:14 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1CgSKM-0008Mw-3r for qemu-devel@nongnu.org; Mon, 20 Dec 2004 13:32:14 -0500 Received: from [64.233.184.198] (helo=wproxy.gmail.com) by monty-python.gnu.org with esmtp (Exim 4.34) id 1CgRkh-00070m-SV for qemu-devel@nongnu.org; Mon, 20 Dec 2004 12:55:24 -0500 Received: by wproxy.gmail.com with SMTP id 63so102326wri for ; Mon, 20 Dec 2004 09:55:21 -0800 (PST) Message-ID: Date: Mon, 20 Dec 2004 18:55:21 +0100 From: Magnus Damm Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_239_21434038.1103565321654" Subject: [Qemu-devel] [PATCH] CONFIG_MMU_MAP powerpc host support Reply-To: Magnus Damm , qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org ------=_Part_239_21434038.1103565321654 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Content-Disposition: inline Hello, This patch adds powerpc host support to the CONFIG_MMU_MAP patch written by Piotrek. My patch should be applied on top of v1-part[1-3].patch.gz. I have only tested the code with a x86 guest on a ppc host running Linux - someone, please test on a host running OSX. Performance gain reported by nbench: Memory index: 50% Integer index: 44% Fp index: 4% Right now each map-memory access consists of 5-6 powerpc instructions. If a direct pointer to mem_map could be kept in a register then we would be down to 3-4 instructions per memoy access... / magnus ------=_Part_239_21434038.1103565321654 Content-Type: application/octet-stream; name=qemu-mmap_20041217-ppc.patch Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="qemu-mmap_20041217-ppc.patch" diff -urN qemu-mmap_20041217/configure qemu-mmap_20041217-ppc/configure --- qemu-mmap_20041217/configure 2004-12-19 00:01:12.000000000 +0100 +++ qemu-mmap_20041217-ppc/configure 2004-12-19 00:20:59.000000000 +0100 @@ -547,6 +547,10 @@ echo "CONFIG_MMU_MAP=yes" >> $config_mak echo "#define CONFIG_MMU_MAP 1" >> $config_h fi +if test "$target_softmmu" = "yes" -a "$target_cpu" = "i386" -a "$cpu" = "powerpc" ; then + echo "CONFIG_MMU_MAP=yes" >> $config_mak + echo "#define CONFIG_MMU_MAP 1" >> $config_h +fi if test "$target_user_only" = "yes" ; then echo "CONFIG_USER_ONLY=yes" >> $config_mak echo "#define CONFIG_USER_ONLY 1" >> $config_h diff -urN qemu-mmap_20041217/mmu_map.h qemu-mmap_20041217-ppc/mmu_map.h --- qemu-mmap_20041217/mmu_map.h 2004-12-19 00:01:12.000000000 +0100 +++ qemu-mmap_20041217-ppc/mmu_map.h 2004-12-20 12:54:38.000000000 +0100 @@ -132,5 +132,44 @@ } #else +#if defined(__powerpc__) + +#ifdef linux +#define R3 uc->uc_mcontext.regs->gpr[3] +#endif + +#ifdef __APPLE__ +#include +#define R3 uc->uc_mcontext->ss.r3 +#endif + +#ifndef R3 +#error unsupported host operating system +#endif + +static inline target_ulong mmu_map_fault_get_vaddr(ucontext_t *uc, + unsigned long addr) +{ + target_ulong vaddr; + + vaddr = addr - R3; + return vaddr; +} + +static inline void mmu_map_fault_update_uc(ucontext_t *uc, MmuMap *map, + unsigned long vaddr, int is_write) +{ + target_ulong vpage; + + vpage = vaddr >> TARGET_PAGE_BITS; + if (is_write) { + R3 = map->add_write[vpage]; + } else { + R3 = map->add_read[vpage]; + } +} + +#else #error unsupported host CPU #endif +#endif diff -urN qemu-mmap_20041217/mmu_map_templ.h qemu-mmap_20041217-ppc/mmu_map_templ.h --- qemu-mmap_20041217/mmu_map_templ.h 2004-12-19 00:01:12.000000000 +0100 +++ qemu-mmap_20041217-ppc/mmu_map_templ.h 2004-12-20 18:23:40.000000000 +0100 @@ -125,9 +125,145 @@ } #else -#error unsupported host CPU +#if defined(__powerpc__) + +/* this code assumes that the host ppc is running in big endian mode */ + +#ifdef TARGET_I386 +#define ENDIAN_SWAP +#endif + +#if 0 + /* slow lookup, first shift right, then left */ + "rlwinm 3, %1, 32 - %2, %2, 31\n" + "addis 4, %3, %4@ha\n" + "rlwinm 3, 3, 2, 0, 31 - 2\n" + "addi 4, 4, %4@l\n" + "lwzx 3, 4, 3\n" + + /* current lookup, one shift and mask operation */ + "addis 4, %3, %4@ha\n" + "rlwinm 3, %1, 32 - (%2 - 2), (%2 - 2), 31 - 2\n" + "addi 4, 4, %4@l\n" + "lwzx 3, 4, 3\n" + + /* better lookup, one shift and mask operation, mmu_map in register */ + "rlwinm 3, %1, 32 - (%2 - 2), (%2 - 2), 31 - 2\n" + "lwzx 3, %3, 3\n" +#endif + +static inline RES_TYPE glue(glue(ld, USUFFIX), MEMSUFFIX)(void *ptr) +{ + RES_TYPE val; + + asm volatile ( + "addis 4, %3, %4@ha\n" + "rlwinm 3, %1, 32 - (%2 - 2), (%2 - 2), 31 - 2\n" + "addi 4, 4, %4@l\n" + "lwzx 3, 4, 3\n" + +#if DATA_SIZE == 1 + "lbzx %0, %1, 3\n" +#elif DATA_SIZE == 2 +#ifdef ENDIAN_SWAP + "lhbrx %0, %1, 3\n" +#else + "lhzx %0, %1, 3\n" +#endif +#elif DATA_SIZE == 4 +#ifdef ENDIAN_SWAP + "lwbrx %0, %1, 3\n" +#else + "lwzx %0, %1, 3\n" #endif +#else +#error unsupported size +#endif + : "=r" (val) + : "r" (ptr), + "I" (TARGET_PAGE_BITS), + "r" (env), + "i" (offsetof(CPUState, mmu_map[CPU_MEM_INDEX].add_read)) + : "%r3", "%r4", "memory"); + return val; +} + +#if DATA_SIZE <= 2 +static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(void *ptr) +{ + int val; + + asm volatile ( + "addis 4, %3, %4@ha\n" + "rlwinm 3, %1, 32 - (%2 - 2), (%2 - 2), 31 - 2\n" + "addi 4, 4, %4@l\n" + "lwzx 3, 4, 3\n" + +#if DATA_SIZE == 1 + "lbzx 4, %1, 3\n" + "extsb %0, 4\n" +#elif DATA_SIZE == 2 +#ifdef ENDIAN_SWAP + "lhbrx 4, %1, 3\n" + "extsh %0, 4\n" +#else + "lhax %0, %1, 3\n" +#endif +#else +#error unsupported size +#endif + : "=r" (val) + : "r" (ptr), + "I" (TARGET_PAGE_BITS), + "r" (env), + "i" (offsetof(CPUState, mmu_map[CPU_MEM_INDEX].add_read)) + : "%r3", "%r4", "memory"); + + return val; +} +#endif + +static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(void *ptr, RES_TYPE val) +{ + + asm volatile ( + "addis 4, %3, %4@ha\n" + "rlwinm 3, %1, 32 - (%2 - 2), (%2 - 2), 31 - 2\n" + "addi 4, 4, %4@l\n" + "lwzx 3, 4, 3\n" + +#if DATA_SIZE == 1 + "stbx %0, %1, 3\n" +#elif DATA_SIZE == 2 +#ifdef ENDIAN_SWAP + "sthbrx %0, %1, 3\n" +#else + "sthx %0, %1, 3\n" +#endif +#elif DATA_SIZE == 4 +#ifdef ENDIAN_SWAP + "stwbrx %0, %1, 3\n" +#else + "stwx %0, %1, 3\n" +#endif +#else +#error unsupported size +#endif + : + : "r" (val), + "r" (ptr), + "I" (TARGET_PAGE_BITS), + "r" (env), + "i" (offsetof(CPUState, mmu_map[CPU_MEM_INDEX].add_write)) + : "%r3", "%r4", "memory"); + +} + +#else +#error unsupported host CPU +#endif +#endif #undef RES_TYPE #undef DATA_TYPE ------=_Part_239_21434038.1103565321654--