From nobody Sun May 5 09:35:59 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1650309278391301.3392434536829; Mon, 18 Apr 2022 12:14:38 -0700 (PDT) Received: from localhost ([::1]:41606 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ngWpY-0000x7-WC for importer@patchew.org; Mon, 18 Apr 2022 15:14:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39984) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ngWms-0006gK-0I; Mon, 18 Apr 2022 15:11:50 -0400 Received: from [187.72.171.209] (port=10848 helo=outlook.eldorado.org.br) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ngWmq-00036o-3Q; Mon, 18 Apr 2022 15:11:49 -0400 Received: from p9ibm ([10.10.71.235]) by outlook.eldorado.org.br over TLS secured channel with Microsoft SMTPSVC(8.5.9600.16384); Mon, 18 Apr 2022 16:11:44 -0300 Received: from eldorado.org.br (unknown [10.10.70.45]) by p9ibm (Postfix) with ESMTP id C8FA58000A0; Mon, 18 Apr 2022 16:11:43 -0300 (-03) From: Leandro Lupori To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org Subject: [RFC PATCH v3 1/5] ppc64: Add semihosting support Date: Mon, 18 Apr 2022 16:10:56 -0300 Message-Id: <20220418191100.270334-2-leandro.lupori@eldorado.org.br> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220418191100.270334-1-leandro.lupori@eldorado.org.br> References: <20220418191100.270334-1-leandro.lupori@eldorado.org.br> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-OriginalArrivalTime: 18 Apr 2022 19:11:44.0259 (UTC) FILETIME=[24889D30:01D85358] X-Host-Lookup-Failed: Reverse DNS lookup failed for 187.72.171.209 (failed) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=187.72.171.209; envelope-from=leandro.lupori@eldorado.org.br; helo=outlook.eldorado.org.br X-Spam_score_int: -4 X-Spam_score: -0.5 X-Spam_bar: / X-Spam_report: (-0.5 / 5.0 requ) BAYES_00=-1.9, PDS_HP_HELO_NORDNS=0.659, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Leandro Lupori , danielhb413@gmail.com, richard.henderson@linaro.org, groug@kaod.org, clg@kaod.org, pbonzini@redhat.com, alex.bennee@linaro.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1650309279553100003 Content-Type: text/plain; charset="utf-8" Add semihosting support for PPC64. This implementation is based on the standard for ARM semihosting version 2.0, as implemented by QEMU and documented in https://github.com/ARM-software/abi-aa/releases The PPC64 specific differences are the following: Semihosting Trap Instruction: sc 7 Operation Number Register: r3 Parameter Register: r4 Return Register: r3 Data block field size: 64 bits Signed-off-by: Leandro Lupori Reviewed-by: Richard Henderson --- configs/devices/ppc64-softmmu/default.mak | 3 +++ qemu-options.hx | 18 ++++++++----- semihosting/arm-compat-semi.c | 33 +++++++++++++++++++++++ target/ppc/cpu.h | 3 ++- target/ppc/excp_helper.c | 9 +++++++ target/ppc/translate.c | 14 ++++++++++ 6 files changed, 72 insertions(+), 8 deletions(-) diff --git a/configs/devices/ppc64-softmmu/default.mak b/configs/devices/pp= c64-softmmu/default.mak index b90e5bf455..43b618fa32 100644 --- a/configs/devices/ppc64-softmmu/default.mak +++ b/configs/devices/ppc64-softmmu/default.mak @@ -8,3 +8,6 @@ CONFIG_POWERNV=3Dy =20 # For pSeries CONFIG_PSERIES=3Dy + +CONFIG_SEMIHOSTING=3Dy +CONFIG_ARM_COMPATIBLE_SEMIHOSTING=3Dy diff --git a/qemu-options.hx b/qemu-options.hx index 34e9b32a5c..6e76f7de96 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4527,11 +4527,12 @@ SRST ERST DEF("semihosting", 0, QEMU_OPTION_semihosting, "-semihosting semihosting mode\n", - QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | - QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV) + QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_MIPS | + QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV | QEMU_ARCH_PPC) SRST ``-semihosting`` - Enable semihosting mode (ARM, M68K, Xtensa, MIPS, Nios II, RISC-V only= ). + Enable semihosting mode (ARM, M68K, Xtensa, MIPS, Nios II, RISC-V and + PPC only). =20 Note that this allows guest direct access to the host filesystem, so should only be used with a trusted guest OS. @@ -4542,12 +4543,12 @@ ERST DEF("semihosting-config", HAS_ARG, QEMU_OPTION_semihosting_config, "-semihosting-config [enable=3Don|off][,target=3Dnative|gdb|auto][,cha= rdev=3Did][,arg=3Dstr[,...]]\n" \ " semihosting configuration\n", -QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | -QEMU_ARCH_MIPS | QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV) +QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_MIPS | +QEMU_ARCH_NIOS2 | QEMU_ARCH_RISCV | QEMU_ARCH_PPC) SRST ``-semihosting-config [enable=3Don|off][,target=3Dnative|gdb|auto][,charde= v=3Did][,arg=3Dstr[,...]]`` - Enable and configure semihosting (ARM, M68K, Xtensa, MIPS, Nios II, RI= SC-V - only). + Enable and configure semihosting (ARM, M68K, Xtensa, MIPS, Nios II, + RISC-V, PPC only). =20 Note that this allows guest direct access to the host filesystem, so should only be used with a trusted guest OS. @@ -4563,6 +4564,9 @@ SRST =20 On RISC-V this implements the standard semihosting API, version 0.2. =20 + On PPC this implements the standard Arm semihosting API, version 2.0, + with only the trap instruction and register definitions changed. + ``target=3Dnative|gdb|auto`` Defines where the semihosting calls will be addressed, to QEMU (``native``) or to GDB (``gdb``). The default is ``auto``, which diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c index 7a51fd0737..e1279c316c 100644 --- a/semihosting/arm-compat-semi.c +++ b/semihosting/arm-compat-semi.c @@ -268,6 +268,31 @@ common_semi_sys_exit_extended(CPUState *cs, int nr) =20 #endif =20 +#ifdef TARGET_PPC64 +static inline target_ulong +common_semi_arg(CPUState *cs, int argno) +{ + PowerPCCPU *cpu =3D POWERPC_CPU(cs); + CPUPPCState *env =3D &cpu->env; + return env->gpr[3 + argno]; +} + +static inline void +common_semi_set_ret(CPUState *cs, target_ulong ret) +{ + PowerPCCPU *cpu =3D POWERPC_CPU(cs); + CPUPPCState *env =3D &cpu->env; + env->gpr[3] =3D ret; +} + +static inline bool +common_semi_sys_exit_extended(CPUState *cs, int nr) +{ + return (nr =3D=3D TARGET_SYS_EXIT_EXTENDED || sizeof(target_ulong) =3D= =3D 8); +} + +#endif + /* * Allocate a new guest file descriptor and return it; if we * couldn't allocate a new fd then return -1. @@ -450,6 +475,12 @@ static target_ulong common_semi_flen_buf(CPUState *cs) =20 sp =3D env->gpr[xSP]; #endif +#ifdef TARGET_PPC64 + PowerPCCPU *cpu =3D POWERPC_CPU(cs); + CPUPPCState *env =3D &cpu->env; + + sp =3D env->gpr[1]; +#endif =20 return sp - 64; } @@ -780,6 +811,8 @@ static inline bool is_64bit_semihosting(CPUArchState *e= nv) return is_a64(env); #elif defined(TARGET_RISCV) return riscv_cpu_mxl(env) !=3D MXL_RV32; +#elif defined(TARGET_PPC64) + return true; #else #error un-handled architecture #endif diff --git a/target/ppc/cpu.h b/target/ppc/cpu.h index 047b24ba50..349104ad79 100644 --- a/target/ppc/cpu.h +++ b/target/ppc/cpu.h @@ -129,8 +129,9 @@ enum { POWERPC_EXCP_SYSCALL_VECTORED =3D 102, /* scv exception = */ POWERPC_EXCP_PERFM_EBB =3D 103, /* Performance Monitor EBB Exceptio= n */ POWERPC_EXCP_EXTERNAL_EBB =3D 104, /* External EBB Exception = */ + POWERPC_EXCP_SEMIHOST =3D 105, /* Semihosting Exception = */ /* EOL = */ - POWERPC_EXCP_NB =3D 105, + POWERPC_EXCP_NB =3D 106, /* QEMU exceptions: special cases we want to stop translation = */ POWERPC_EXCP_SYSCALL_USER =3D 0x203, /* System call in user mode only = */ }; diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index d3e2cfcd71..af34a57082 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -25,6 +25,7 @@ #include "helper_regs.h" =20 #include "trace.h" +#include "semihosting/common-semi.h" =20 #ifdef CONFIG_TCG #include "exec/helper-proto.h" @@ -100,6 +101,7 @@ static const char *powerpc_excp_name(int excp) case POWERPC_EXCP_SDOOR_HV: return "SDOOR_HV"; case POWERPC_EXCP_HVIRT: return "HVIRT"; case POWERPC_EXCP_SYSCALL_VECTORED: return "SYSCALL_VECTORED"; + case POWERPC_EXCP_SEMIHOST: return "SEMIHOST"; default: g_assert_not_reached(); } @@ -1327,6 +1329,13 @@ static void powerpc_excp_books(PowerPCCPU *cpu, int = excp) target_ulong msr, new_msr, vector; int srr0, srr1, lev =3D -1; =20 + /* Handle semihost exceptions first */ + if (excp =3D=3D POWERPC_EXCP_SEMIHOST) { + env->gpr[3] =3D do_common_semihosting(cs); + env->nip +=3D 4; + return; + } + /* new srr1 value excluding must-be-zero bits */ msr =3D env->msr & ~0x783f0000ULL; =20 diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 408ae26173..c013889a84 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -4520,6 +4520,20 @@ static void gen_sc(DisasContext *ctx) uint32_t lev; =20 lev =3D (ctx->opcode >> 5) & 0x7F; + +#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) + /* + * PowerPC semihosting uses the following + * instruction to flag a semihosting call: + * + * sc 7 0x440000e2 + */ + if (lev =3D=3D 7) { + gen_exception(ctx, POWERPC_EXCP_SEMIHOST); + return; + } +#endif + gen_exception_err(ctx, POWERPC_SYSCALL, lev); } =20 --=20 2.25.1 From nobody Sun May 5 09:35:59 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1650309501946513.7128031466669; Mon, 18 Apr 2022 12:18:21 -0700 (PDT) Received: from localhost ([::1]:48070 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ngWtA-0005Oy-H7 for importer@patchew.org; Mon, 18 Apr 2022 15:18:20 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39998) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ngWmu-0006gw-EZ; Mon, 18 Apr 2022 15:11:57 -0400 Received: from [187.72.171.209] (port=10848 helo=outlook.eldorado.org.br) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ngWms-00036o-W9; Mon, 18 Apr 2022 15:11:52 -0400 Received: from p9ibm ([10.10.71.235]) by outlook.eldorado.org.br over TLS secured channel with Microsoft SMTPSVC(8.5.9600.16384); Mon, 18 Apr 2022 16:11:46 -0300 Received: from eldorado.org.br (unknown [10.10.70.45]) by p9ibm (Postfix) with ESMTP id 5B9398000A0; Mon, 18 Apr 2022 16:11:46 -0300 (-03) From: Leandro Lupori To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org Subject: [RFC PATCH v3 2/5] ppc64: Fix semihosting on ppc64le Date: Mon, 18 Apr 2022 16:10:57 -0300 Message-Id: <20220418191100.270334-3-leandro.lupori@eldorado.org.br> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220418191100.270334-1-leandro.lupori@eldorado.org.br> References: <20220418191100.270334-1-leandro.lupori@eldorado.org.br> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-OriginalArrivalTime: 18 Apr 2022 19:11:46.0806 (UTC) FILETIME=[260D4160:01D85358] X-Host-Lookup-Failed: Reverse DNS lookup failed for 187.72.171.209 (failed) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=187.72.171.209; envelope-from=leandro.lupori@eldorado.org.br; helo=outlook.eldorado.org.br X-Spam_score_int: -4 X-Spam_score: -0.5 X-Spam_bar: / X-Spam_report: (-0.5 / 5.0 requ) BAYES_00=-1.9, PDS_HP_HELO_NORDNS=0.659, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Leandro Lupori , danielhb413@gmail.com, richard.henderson@linaro.org, groug@kaod.org, clg@kaod.org, pbonzini@redhat.com, alex.bennee@linaro.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1650309502520100001 Content-Type: text/plain; charset="utf-8" PPC64 CPUs can change its endian dynamically, so semihosting code must check its MSR at run time to determine if byte swapping is needed. Signed-off-by: Leandro Lupori --- include/exec/softmmu-semi.h | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/include/exec/softmmu-semi.h b/include/exec/softmmu-semi.h index fbcae88f4b..723aa2f58a 100644 --- a/include/exec/softmmu-semi.h +++ b/include/exec/softmmu-semi.h @@ -12,12 +12,27 @@ =20 #include "cpu.h" =20 +#ifdef TARGET_PPC64 +static inline uint64_t sh_swap64(CPUArchState *env, uint64_t val) +{ + return msr_le ? val : tswap64(val); +} + +static inline uint32_t sh_swap32(CPUArchState *env, uint32_t val) +{ + return msr_le ? val : tswap32(val); +} +#else +#define sh_swap64(env, val) tswap64(val) +#define sh_swap32(env, val) tswap32(val) +#endif + static inline uint64_t softmmu_tget64(CPUArchState *env, target_ulong addr) { uint64_t val; =20 cpu_memory_rw_debug(env_cpu(env), addr, (uint8_t *)&val, 8, 0); - return tswap64(val); + return sh_swap64(env, val); } =20 static inline uint32_t softmmu_tget32(CPUArchState *env, target_ulong addr) @@ -25,7 +40,7 @@ static inline uint32_t softmmu_tget32(CPUArchState *env, = target_ulong addr) uint32_t val; =20 cpu_memory_rw_debug(env_cpu(env), addr, (uint8_t *)&val, 4, 0); - return tswap32(val); + return sh_swap32(env, val); } =20 static inline uint32_t softmmu_tget8(CPUArchState *env, target_ulong addr) @@ -44,14 +59,14 @@ static inline uint32_t softmmu_tget8(CPUArchState *env,= target_ulong addr) static inline void softmmu_tput64(CPUArchState *env, target_ulong addr, uint64_t val) { - val =3D tswap64(val); + val =3D sh_swap64(env, val); cpu_memory_rw_debug(env_cpu(env), addr, (uint8_t *)&val, 8, 1); } =20 static inline void softmmu_tput32(CPUArchState *env, target_ulong addr, uint32_t val) { - val =3D tswap32(val); + val =3D sh_swap32(env, val); cpu_memory_rw_debug(env_cpu(env), addr, (uint8_t *)&val, 4, 1); } #define put_user_u64(arg, p) ({ softmmu_tput64(env, p, arg) ; 0; }) --=20 2.25.1 From nobody Sun May 5 09:35:59 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1650309258425855.1523803167; Mon, 18 Apr 2022 12:14:18 -0700 (PDT) Received: from localhost ([::1]:40990 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ngWpE-0000Xh-JU for importer@patchew.org; Mon, 18 Apr 2022 15:14:16 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:40012) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ngWmx-0006h0-CQ; Mon, 18 Apr 2022 15:11:57 -0400 Received: from [187.72.171.209] (port=10848 helo=outlook.eldorado.org.br) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ngWmv-00036o-Ce; Mon, 18 Apr 2022 15:11:55 -0400 Received: from p9ibm ([10.10.71.235]) by outlook.eldorado.org.br over TLS secured channel with Microsoft SMTPSVC(8.5.9600.16384); Mon, 18 Apr 2022 16:11:49 -0300 Received: from eldorado.org.br (unknown [10.10.70.45]) by p9ibm (Postfix) with ESMTP id 989E08000A0; Mon, 18 Apr 2022 16:11:48 -0300 (-03) From: Leandro Lupori To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org Subject: [RFC PATCH v3 3/5] tests/tcg/ppc64: Add basic softmmu test support Date: Mon, 18 Apr 2022 16:10:58 -0300 Message-Id: <20220418191100.270334-4-leandro.lupori@eldorado.org.br> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220418191100.270334-1-leandro.lupori@eldorado.org.br> References: <20220418191100.270334-1-leandro.lupori@eldorado.org.br> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-OriginalArrivalTime: 18 Apr 2022 19:11:49.0087 (UTC) FILETIME=[27694EF0:01D85358] X-Host-Lookup-Failed: Reverse DNS lookup failed for 187.72.171.209 (failed) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=187.72.171.209; envelope-from=leandro.lupori@eldorado.org.br; helo=outlook.eldorado.org.br X-Spam_score_int: -4 X-Spam_score: -0.5 X-Spam_bar: / X-Spam_report: (-0.5 / 5.0 requ) BAYES_00=-1.9, PDS_HP_HELO_NORDNS=0.659, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Leandro Lupori , danielhb413@gmail.com, richard.henderson@linaro.org, groug@kaod.org, clg@kaod.org, pbonzini@redhat.com, alex.bennee@linaro.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1650309259876100001 Add support to build and run the multiarch hello test, that simply prints a message and exits, through semihosting operations. The linker script was imported from https://github.com/legoater/pnv-test, that are the Microwatt tests adapted to use a PowerNV console. Boot.S code was inspired on mmu/head.S, also from pnv-test repo. Signed-off-by: Leandro Lupori --- MAINTAINERS | 2 + tests/tcg/ppc64/Makefile.softmmu-target | 56 +++++++++++++++++ tests/tcg/ppc64/system/include/asm.h | 68 ++++++++++++++++++++ tests/tcg/ppc64/system/lib/boot.S | 84 +++++++++++++++++++++++++ tests/tcg/ppc64/system/lib/powerpc.lds | 27 ++++++++ 5 files changed, 237 insertions(+) create mode 100644 tests/tcg/ppc64/Makefile.softmmu-target create mode 100644 tests/tcg/ppc64/system/include/asm.h create mode 100644 tests/tcg/ppc64/system/lib/boot.S create mode 100644 tests/tcg/ppc64/system/lib/powerpc.lds diff --git a/MAINTAINERS b/MAINTAINERS index 4ad2451e03..54f917f8ea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -266,6 +266,7 @@ M: C=C3=A9dric Le Goater M: Daniel Henrique Barboza R: David Gibson R: Greg Kurz +R: Leandro Lupori L: qemu-ppc@nongnu.org S: Maintained F: target/ppc/ @@ -273,6 +274,7 @@ F: hw/ppc/ppc.c F: hw/ppc/ppc_booke.c F: include/hw/ppc/ppc.h F: disas/ppc.c +F: tests/tcg/ppc64/ =20 RISC-V TCG CPUs M: Palmer Dabbelt diff --git a/tests/tcg/ppc64/Makefile.softmmu-target b/tests/tcg/ppc64/Make= file.softmmu-target new file mode 100644 index 0000000000..948427b70d --- /dev/null +++ b/tests/tcg/ppc64/Makefile.softmmu-target @@ -0,0 +1,56 @@ +# +# PowerPC64 system tests +# + +# For now, disable tests that are failing +DISABLED_TESTS :=3D memory +DISABLED_EXTRA_RUNS :=3D run-gdbstub-memory + +PPC64_SYSTEM_SRC=3D$(SRC_PATH)/tests/tcg/ppc64/system +VPATH+=3D$(PPC64_SYSTEM_SRC) + +# These objects provide the basic boot code and helper functions for all t= ests +CRT_PATH=3D$(PPC64_SYSTEM_SRC)/lib +CRT_OBJS=3Dboot.o + +LINK_SCRIPT=3D$(CRT_PATH)/powerpc.lds +# NOTE: --build-id is stored before the first code section in the linked +# binary, which causes problems for most tests, that expect to +# begin at address 0. +LDFLAGS=3D-Wl,-T$(LINK_SCRIPT) -Wl,--build-id=3Dnone -static -nostdlib \ + $(CRT_OBJS) $(MINILIB_OBJS) -lgcc +TESTS +=3D $(filter-out $(DISABLED_TESTS),$(MULTIARCH_TESTS)) +EXTRA_RUNS +=3D $(filter-out $(DISABLED_EXTRA_RUNS),$(MULTIARCH_RUNS)) + +# NOTE: -Os doesn't work well with -Wl,--oformat=3Dbinary +# Some linker generated functions, such as savegpr*/restgpr*, +# end up being undefined. +CFLAGS =3D -O -g -Wall -std=3Dc99 -msoft-float -mno-vsx -mno-altivec \ + -fno-stack-protector -ffreestanding \ + -I $(PPC64_SYSTEM_SRC)/include $(MINILIB_INC) \ + -mcpu=3Dpower8 + +# Uncomment to test in LE +# override EXTRA_CFLAGS +=3D -mlittle-endian -mabi=3Delfv2 + +# Leave the .elf files, to make debugging easier +.PRECIOUS: $(CRT_OBJS) $(addsuffix .elf,$(TESTS)) + +# Build CRT objects +%.o: $(CRT_PATH)/%.S + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -x assembler-with-cpp -c $< -o $@ + +# Build and link the tests + +# The .elf files are just for debugging +%.elf: %.c $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS) + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) + +%: %.c %.elf $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS) + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) -Wl,--oformat=3Dbinary + +memory: CFLAGS+=3D-DCHECK_UNALIGNED=3D1 + +# Running +QEMU_BASE_MACHINE=3D-cpu power9 -M powernv9 -m 1G -vga none -nographic +QEMU_OPTS+=3D$(QEMU_BASE_MACHINE) -serial chardev:output -bios diff --git a/tests/tcg/ppc64/system/include/asm.h b/tests/tcg/ppc64/system/= include/asm.h new file mode 100644 index 0000000000..127ed46730 --- /dev/null +++ b/tests/tcg/ppc64/system/include/asm.h @@ -0,0 +1,68 @@ +#ifndef PPC64_ASM_H +#define PPC64_ASM_H + +#define XCONCAT(a, b) a ## b +#define CONCAT(a, b) XCONCAT(a, b) + +/* Load an immediate 64-bit value into a register */ +#define LOAD_IMM64(r, e) \ + lis r, (e)@highest; \ + ori r, r, (e)@higher; \ + rldicr r, r, 32, 31; \ + oris r, r, (e)@h; \ + ori r, r, (e)@l; + +/* Switch CPU to little-endian mode, if needed */ +#define FIXUP_ENDIAN \ + tdi 0, 0, 0x48; /* Reverse endian of b . + 8 */ \ + b $ + 44; /* Skip trampoline if endian is good */ \ + .long 0xa600607d; /* mfmsr r11 */ \ + .long 0x01006b69; /* xori r11,r11,1 */ \ + .long 0x00004039; /* li r10,0 */ \ + .long 0x6401417d; /* mtmsrd r10,1 */ \ + .long 0x05009f42; /* bcl 20,31,$+4 */ \ + .long 0xa602487d; /* mflr r10 */ \ + .long 0x14004a39; /* addi r10,r10,20 */ \ + .long 0xa6035a7d; /* mtsrr0 r10 */ \ + .long 0xa6037b7d; /* mtsrr1 r11 */ \ + .long 0x2400004c /* rfid */ + +/* Handle differences between ELFv1 and ELFv2 ABIs */ + +#define DOT_LABEL(name) CONCAT(., name) + +#if !defined(_CALL_ELF) || _CALL_ELF =3D=3D 1 +#define FUNCTION(name) \ + .section ".opd", "aw"; \ + .p2align 3; \ + .globl name; \ +name: \ + .quad DOT_LABEL(name), .TOC.@tocbase, 0; \ + .previous; \ +DOT_LABEL(name): + +#define CALL(fn) \ + LOAD_IMM64(%r12, fn); \ + ld %r12, 0(%r12); \ + mtctr %r12; \ + bctrl + +#define CALL_LOCAL(fn) \ + bl DOT_LABEL(fn) + +#else +#define FUNCTION(name) \ + .globl name; \ +name: + +#define CALL(fn) \ + LOAD_IMM64(%r12, fn); \ + mtctr %r12; \ + bctrl + +#define CALL_LOCAL(fn) \ + bl fn + +#endif + +#endif diff --git a/tests/tcg/ppc64/system/lib/boot.S b/tests/tcg/ppc64/system/lib= /boot.S new file mode 100644 index 0000000000..b3bcd8a7da --- /dev/null +++ b/tests/tcg/ppc64/system/lib/boot.S @@ -0,0 +1,84 @@ +/* Copyright 2013-2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "asm.h" + +#define SPR_HID0 0x3f0 +#define SPR_HID0_POWER9_HILE 0x0800000000000000 + +#define ADP_STOPPED_APPLICATIONEXIT 0x20026 + + .section ".head","ax" + + /* QEMU enters in BE at 0x10 by default */ + . =3D 0x10 +.global start +start: + FIXUP_ENDIAN + + /* Setup TOC */ + LOAD_IMM64(%r2, .TOC.) + + /* Configure interrupt endian */ +#ifdef __LITTLE_ENDIAN__ + mfspr %r10, SPR_HID0 + LOAD_IMM64(%r11, SPR_HID0_POWER9_HILE) + or %r10, %r10, %r11 + mtspr SPR_HID0, %r10 +#endif + + /* Clear .bss */ + LOAD_IMM64(%r10, __bss_start) + LOAD_IMM64(%r11, __bss_end) + subf %r11, %r10, %r11 + addi %r11, %r11, 63 + srdi. %r11, %r11, 6 + beq 2f + mtctr %r11 +1: dcbz 0, %r10 + addi %r10, %r10, 64 + bdnz 1b + + /* Setup stack */ +2: LOAD_IMM64(%r1, __stack_top) + li %r0, 0 + stdu %r0, -32(%r1) + + CALL(main) + + /* Terminate on exit */ + CALL_LOCAL(sys_exit) + b . + +FUNCTION(sys_exit) + /* + * As semihosting operations are executed by non-translated QEMU code, + * we shouldn't need to save LR. + */ + LOAD_IMM64(%r4, ADP_STOPPED_APPLICATIONEXIT) + std %r4, -16(%r1) + std %r3, -8(%r1) + li %r3, 0x18 + addi %r4, %r1, -16 + sc 7 + blr + +FUNCTION(__sys_outc) + addi %r4, %r1, -1 + stb %r3, 0(%r4) + li %r3, 0x03 + sc 7 + blr diff --git a/tests/tcg/ppc64/system/lib/powerpc.lds b/tests/tcg/ppc64/syste= m/lib/powerpc.lds new file mode 100644 index 0000000000..db451e1fb9 --- /dev/null +++ b/tests/tcg/ppc64/system/lib/powerpc.lds @@ -0,0 +1,27 @@ +SECTIONS +{ + . =3D 0; + _start =3D .; + .head : { + KEEP(*(.head)) + } + . =3D ALIGN(0x1000); + .text : { *(.text) *(.text.*) *(.rodata) *(.rodata.*) } + . =3D ALIGN(0x1000); + .data : { *(.data) *(.data.*) *(.got) *(.toc) } + . =3D ALIGN(0x80); + __bss_start =3D .; + .bss : { + *(.dynsbss) + *(.sbss) + *(.scommon) + *(.dynbss) + *(.bss) + *(.common) + *(.bss.*) + } + . =3D ALIGN(0x80); + __bss_end =3D .; + . =3D . + 0x4000; + __stack_top =3D .; +} --=20 2.25.1 From nobody Sun May 5 09:35:59 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1650309532827666.6844428379735; Mon, 18 Apr 2022 12:18:52 -0700 (PDT) Received: from localhost ([::1]:48726 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ngWtf-0005qA-O2 for importer@patchew.org; Mon, 18 Apr 2022 15:18:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:40032) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ngWn1-0006hj-9C; Mon, 18 Apr 2022 15:11:59 -0400 Received: from [187.72.171.209] (port=10848 helo=outlook.eldorado.org.br) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ngWmy-00036o-CL; Mon, 18 Apr 2022 15:11:59 -0400 Received: from p9ibm ([10.10.71.235]) by outlook.eldorado.org.br over TLS secured channel with Microsoft SMTPSVC(8.5.9600.16384); Mon, 18 Apr 2022 16:11:52 -0300 Received: from eldorado.org.br (unknown [10.10.70.45]) by p9ibm (Postfix) with ESMTP id 7D7E18000A0; Mon, 18 Apr 2022 16:11:52 -0300 (-03) From: Leandro Lupori To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org Subject: [RFC PATCH v3 4/5] tests/tcg/ppc64: Add MMU test sources Date: Mon, 18 Apr 2022 16:10:59 -0300 Message-Id: <20220418191100.270334-5-leandro.lupori@eldorado.org.br> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220418191100.270334-1-leandro.lupori@eldorado.org.br> References: <20220418191100.270334-1-leandro.lupori@eldorado.org.br> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-OriginalArrivalTime: 18 Apr 2022 19:11:52.0994 (UTC) FILETIME=[29BD7820:01D85358] X-Host-Lookup-Failed: Reverse DNS lookup failed for 187.72.171.209 (failed) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=187.72.171.209; envelope-from=leandro.lupori@eldorado.org.br; helo=outlook.eldorado.org.br X-Spam_score_int: -4 X-Spam_score: -0.5 X-Spam_bar: / X-Spam_report: (-0.5 / 5.0 requ) BAYES_00=-1.9, PDS_HP_HELO_NORDNS=0.659, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Leandro Lupori , danielhb413@gmail.com, richard.henderson@linaro.org, groug@kaod.org, clg@kaod.org, pbonzini@redhat.com, alex.bennee@linaro.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1650309534586100003 Content-Type: text/plain; charset="utf-8" Add MMU test sources, from https://github.com/legoater/pnv-test, based on Microwatt tests but with some adaptations. In particular, the tests that check updates to RC bits were removed, because, apparently, Microwatt never updates RC bits, but just raise an exception when they must be updated, leaving the task to the OS (https://github.com/antonblanchard/microwatt/blob/master/mmu.vhdl#L402). Signed-off-by: Leandro Lupori --- tests/tcg/ppc64/system/mmu-head.S | 142 ++++++ tests/tcg/ppc64/system/mmu.c | 764 ++++++++++++++++++++++++++++++ tests/tcg/ppc64/system/mmu.h | 9 + 3 files changed, 915 insertions(+) create mode 100644 tests/tcg/ppc64/system/mmu-head.S create mode 100644 tests/tcg/ppc64/system/mmu.c create mode 100644 tests/tcg/ppc64/system/mmu.h diff --git a/tests/tcg/ppc64/system/mmu-head.S b/tests/tcg/ppc64/system/mmu= -head.S new file mode 100644 index 0000000000..e9e01f0642 --- /dev/null +++ b/tests/tcg/ppc64/system/mmu-head.S @@ -0,0 +1,142 @@ +/* Copyright 2013-2014 IBM Corp. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "asm.h" + +#include "lib/boot.S" + + /* Read a location with translation on */ +FUNCTION(test_read) + mfmsr %r9 + ori %r8,%r9,0x10 /* set MSR_DR */ + mtmsrd %r8,0 + mr %r6,%r3 + li %r3,0 + ld %r5,0(%r6) + li %r3,1 + /* land here if DSI occurred */ + mtmsrd %r9,0 + std %r5,0(%r4) + blr + + /* Write a location with translation on */ +FUNCTION(test_write) + mfmsr %r9 + ori %r8,%r9,0x10 /* set MSR_DR */ + mtmsrd %r8,0 + mr %r6,%r3 + li %r3,0 + std %r4,0(%r6) + li %r3,1 + /* land here if DSI occurred */ + mtmsrd %r9,0 + blr + + /* Do a dcbz with translation on */ +FUNCTION(test_dcbz) + mfmsr %r9 + ori %r8,%r9,0x10 /* set MSR_DR */ + mtmsrd %r8,0 + mr %r6,%r3 + li %r3,0 + dcbz 0,%r6 + li %r3,1 + /* land here if DSI occurred */ + mtmsrd %r9,0 + blr + +FUNCTION(test_exec) + mtsrr0 %r4 + mtsrr1 %r5 + rfid + +#define EXCEPTION(nr) \ + .=3D nr ;\ + li %r3, (nr >> 4) ;\ + CALL_LOCAL(sys_exit) + + /* DSI vector - skip the failing instruction + the next one */ + . =3D 0x300 + mtsprg0 %r10 + mfsrr0 %r10 + addi %r10,%r10,8 + mtsrr0 %r10 + rfid + + EXCEPTION(0x380) + + /* + * ISI vector - jump to LR to return from the test, + * with r3 cleared + */ + . =3D 0x400 + li %r3,0 + blr + + /* More exception stubs */ + EXCEPTION(0x480) + EXCEPTION(0x500) + EXCEPTION(0x600) + EXCEPTION(0x700) + EXCEPTION(0x800) + EXCEPTION(0x900) + EXCEPTION(0x980) + EXCEPTION(0xa00) + EXCEPTION(0xb00) + + /* + * System call - used to exit from tests where MSR[PR] + * may have been set. + */ + . =3D 0xc00 + blr + + EXCEPTION(0xd00) + EXCEPTION(0xe00) + EXCEPTION(0xe20) + EXCEPTION(0xe40) + EXCEPTION(0xe60) + EXCEPTION(0xe80) + EXCEPTION(0xf00) + EXCEPTION(0xf20) + EXCEPTION(0xf40) + EXCEPTION(0xf60) + EXCEPTION(0xf80) + + . =3D 0x1000 + /* + * This page gets mapped at various locations and + * the tests try to execute from it. + * r3 contains the test number. + */ +FUNCTION(test_start) + nop + nop + cmpdi %r3,1 + beq test_1 + cmpdi %r3,2 + beq test_2 +test_return: + li %r3,1 + sc + + . =3D 0x1ff8 + /* test a branch near the end of a page */ +test_1: b test_return + + /* test flowing from one page to the next */ +test_2: nop + b test_return diff --git a/tests/tcg/ppc64/system/mmu.c b/tests/tcg/ppc64/system/mmu.c new file mode 100644 index 0000000000..8e9fca2675 --- /dev/null +++ b/tests/tcg/ppc64/system/mmu.c @@ -0,0 +1,764 @@ +#include +#include +#include + +#include "minilib.h" +#include "mmu.h" + +#define MSR_LE 0x01 +#define MSR_DR 0x10 +#define MSR_IR 0x20 +#define MSR_HV 0x1000000000000000ul +#define MSR_SF 0x8000000000000000ul + +#ifdef __LITTLE_ENDIAN__ +#define MSR_DFLT (MSR_SF | MSR_HV | MSR_LE) +#else +#define MSR_DFLT (MSR_SF | MSR_HV) +#endif + +#define XSTR(x) #x +#define STR(x) XSTR(x) + +#define RIC_TLB 0 +#define RIC_PWC 1 +#define RIC_ALL 2 + +#define PRS 1 + +#define IS(x) ((unsigned long)(x) << 10) +#define IS_VA IS(0) +#define IS_PID IS(1) +#define IS_LPID IS(2) +#define IS_ALL IS(3) + +#define TLBIE_5(rb, rs, ric, prs, r) \ + __asm__ volatile(".long 0x7c000264 | " \ + "%0 << 21 | " \ + STR(ric) " << 18 | " \ + STR(prs) " << 17 | " \ + STR(r) "<< 16 | " \ + "%1 << 11" \ + : : "r" (rs), "r" (rb) : "memory") + +static inline void tlbie_all(int prs) +{ + if (prs) { + TLBIE_5(IS_ALL, 0, RIC_ALL, 1, 1); + } else { + TLBIE_5(IS_ALL, 0, RIC_ALL, 0, 1); + } +} + +static inline void tlbie_va(unsigned long va, int prs) +{ + va &=3D ~0xffful; + + if (prs) { + TLBIE_5(IS_VA | va, 0, RIC_TLB, 1, 1); + } else { + TLBIE_5(IS_VA | va, 0, RIC_TLB, 0, 1); + } + __asm__ volatile("eieio; tlbsync; ptesync" : : : "memory"); +} + +#define DSISR 18 +#define DAR 19 +#define SRR0 26 +#define SRR1 27 +#define PID 48 +#define LPCR 318 +#define PTCR 464 + +#define PPC_BIT(x) (0x8000000000000000ul >> (x)) + +#define LPCR_UPRT PPC_BIT(41) +#define LPCR_HR PPC_BIT(43) + +#define PATE_HR PPC_BIT(0) + +static inline unsigned long mfspr(int sprnum) +{ + long val; + + __asm__ volatile("mfspr %0,%1" : "=3Dr" (val) : "i" (sprnum)); + return val; +} + +static inline void mtspr(int sprnum, unsigned long val) +{ + __asm__ volatile("mtspr %0,%1" : : "i" (sprnum), "r" (val)); +} + +static inline void store_pte(unsigned long *p, unsigned long pte) +{ +#ifdef __LITTLE_ENDIAN__ + __asm__ volatile("stdbrx %1,0,%0" : : "r" (p), "r" (pte) : "memory"); +#else + __asm__ volatile("stdx %1,0,%0" : : "r" (p), "r" (pte) : "memory"); +#endif + __asm__ volatile("ptesync" : : : "memory"); +} + +#define CACHE_LINE_SIZE 64 + +void zero_memory(void *ptr, unsigned long nbytes) +{ + unsigned long nb, i, nl; + void *p; + + for (; nbytes !=3D 0; nbytes -=3D nb, ptr +=3D nb) { + nb =3D -((unsigned long)ptr) & (CACHE_LINE_SIZE - 1); + if (nb =3D=3D 0 && nbytes >=3D CACHE_LINE_SIZE) { + nl =3D nbytes / CACHE_LINE_SIZE; + p =3D ptr; + for (i =3D 0; i < nl; ++i) { + __asm__ volatile("dcbz 0,%0" : : "r" (p) : "memory"); + p +=3D CACHE_LINE_SIZE; + } + nb =3D nl * CACHE_LINE_SIZE; + } else { + if (nb > nbytes) { + nb =3D nbytes; + } + for (i =3D 0; i < nb; ++i) { + ((unsigned char *)ptr)[i] =3D 0; + } + } + } +} + +#define PAGE_SHIFT 12 +#define PAGE_SIZE (1ul << PAGE_SHIFT) + +/* Partition Page Dir params */ +#define PPD_L1_BITS 5 +#define PPD_L2_BITS 14 /* virtual level 2 PGD address bits */ +#define PPD_PA_INC (1ul << (PAGE_SHIFT + PPD_L2_BITS)) + +#define RPTE_V PPC_BIT(0) +#define RPTE_L PPC_BIT(1) +#define RPTE_RPN_MASK 0x01fffffffffff000ul +#define RPTE_R PPC_BIT(55) +#define RPTE_C PPC_BIT(56) +#define RPTE_PRIV PPC_BIT(60) +#define RPTE_RD PPC_BIT(61) +#define RPTE_RW PPC_BIT(62) +#define RPTE_EX PPC_BIT(63) +#define RPTE_PERM_ALL (RPTE_RD | RPTE_RW | RPTE_EX) + +#define PERM_EX RPTE_EX +#define PERM_WR RPTE_RW +#define PERM_RD RPTE_RD +#define PERM_PRIV RPTE_PRIV +#define ATTR_NC 0x020 +#define CHG RPTE_C +#define REF RPTE_R + +#define DFLT_PERM (PERM_WR | PERM_RD | REF | CHG) + +/* + * Set up an MMU translation tree using memory starting at the 64k point. + * We use 2 levels, mapping 2GB (the minimum size possible), with a + * 8kB PGD level pointing to 4kB PTE pages. + */ +unsigned long *pgdir =3D (unsigned long *) 0x10000; +unsigned long *proc_tbl =3D (unsigned long *) 0x12000; +unsigned long *part_tbl =3D (unsigned long *) 0x13000; +unsigned long *part_pgdir =3D (unsigned long *) 0x14000; +unsigned long free_ptr =3D 0x15000; +void *eas_mapped[4]; +int neas_mapped; + +void init_mmu(void) +{ + int i, n; + unsigned long pa, pte; + + /* Select Radix MMU (HR), with HW process table */ + mtspr(LPCR, mfspr(LPCR) | LPCR_UPRT | LPCR_HR); + + /* + * Set up partition page dir, needed to translate process table + * addresses. + * We use only 1 level, mapping 2GB 1-1, with 32 64M pages. + */ + zero_memory(part_tbl, PAGE_SIZE); + store_pte(&part_tbl[0], PATE_HR | (unsigned long) part_pgdir | + PPD_L1_BITS); + + for (i =3D 0, n =3D 1 << PPD_L1_BITS, pa =3D 0; + i < n; i++, pa +=3D PPD_PA_INC) { + pte =3D RPTE_V | RPTE_L | (pa & RPTE_RPN_MASK) | RPTE_PERM_ALL; + store_pte(&part_pgdir[i], pte); + } + + /* set up partition table */ + store_pte(&part_tbl[1], (unsigned long)proc_tbl); + /* set up process table */ + zero_memory(proc_tbl, 512 * sizeof(unsigned long)); + mtspr(PTCR, (unsigned long)part_tbl); + mtspr(PID, 1); + zero_memory(pgdir, 1024 * sizeof(unsigned long)); + /* RTS =3D 0 (2GB address space), RPDS =3D 10 (1024-entry top level) */ + store_pte(&proc_tbl[2 * 1], (unsigned long) pgdir | 10); + tlbie_all(0); /* invalidate all TLB entries */ +} + +static unsigned long *read_pgd(unsigned long i) +{ + unsigned long ret; + +#ifdef __LITTLE_ENDIAN__ + __asm__ volatile("ldbrx %0,%1,%2" : "=3Dr" (ret) : "b" (pgdir), + "r" (i * sizeof(unsigned long))); +#else + __asm__ volatile("ldx %0,%1,%2" : "=3Dr" (ret) : "b" (pgdir), + "r" (i * sizeof(unsigned long))); +#endif + return (unsigned long *) (ret & 0x00ffffffffffff00); +} + +void map(void *ea, void *pa, unsigned long perm_attr) +{ + unsigned long epn =3D (unsigned long) ea >> 12; + unsigned long i, j; + unsigned long *ptep; + + i =3D (epn >> 9) & 0x3ff; + j =3D epn & 0x1ff; + if (pgdir[i] =3D=3D 0) { + zero_memory((void *)free_ptr, 512 * sizeof(unsigned long)); + store_pte(&pgdir[i], 0x8000000000000000 | free_ptr | 9); + free_ptr +=3D 512 * sizeof(unsigned long); + } + ptep =3D read_pgd(i); + store_pte(&ptep[j], 0xc000000000000000 | ((unsigned long)pa & + 0x00fffffffffff000) | perm_a= ttr); + eas_mapped[neas_mapped++] =3D ea; +} + +void unmap(void *ea) +{ + unsigned long epn =3D (unsigned long) ea >> 12; + unsigned long i, j; + unsigned long *ptep; + + i =3D (epn >> 9) & 0x3ff; + j =3D epn & 0x1ff; + if (pgdir[i] =3D=3D 0) { + return; + } + ptep =3D read_pgd(i); + store_pte(&ptep[j], 0); + tlbie_va((unsigned long)ea, PRS); +} + +void unmap_all(void) +{ + int i; + + for (i =3D 0; i < neas_mapped; ++i) { + unmap(eas_mapped[i]); + } + neas_mapped =3D 0; +} + +int mmu_test_1(void) +{ + long *ptr =3D (long *) 0x123000; + long val; + + /* this should fail */ + if (test_read(ptr, &val, 0xdeadbeefd00d)) { + return 1; + } + /* dest reg of load should be unchanged */ + if (val !=3D 0xdeadbeefd00d) { + return 2; + } + /* DAR and DSISR should be set correctly */ + if (mfspr(DAR) !=3D (long) ptr || mfspr(DSISR) !=3D 0x40000000) { + return 3; + } + return 0; +} + +int mmu_test_2(void) +{ + long *mem =3D (long *) 0x8000; + long *ptr =3D (long *) 0x124000; + long *ptr2 =3D (long *) 0x1124000; + long val; + + /* create PTE */ + map(ptr, mem, DFLT_PERM); + /* initialize the memory content */ + mem[33] =3D 0xbadc0ffee; + /* this should succeed and be a cache miss */ + if (!test_read(&ptr[33], &val, 0xdeadbeefd00d)) { + return 1; + } + /* dest reg of load should have the value written */ + if (val !=3D 0xbadc0ffee) { + return 2; + } + /* load a second TLB entry in the same set as the first */ + map(ptr2, mem, DFLT_PERM); + /* this should succeed and be a cache hit */ + if (!test_read(&ptr2[33], &val, 0xdeadbeefd00d)) { + return 3; + } + /* dest reg of load should have the value written */ + if (val !=3D 0xbadc0ffee) { + return 4; + } + /* check that the first entry still works */ + if (!test_read(&ptr[33], &val, 0xdeadbeefd00d)) { + return 5; + } + if (val !=3D 0xbadc0ffee) { + return 6; + } + return 0; +} + +int mmu_test_3(void) +{ + long *mem =3D (long *) 0x9000; + long *ptr =3D (long *) 0x14a000; + long val; + + /* create PTE */ + map(ptr, mem, DFLT_PERM); + /* initialize the memory content */ + mem[45] =3D 0xfee1800d4ea; + /* this should succeed and be a cache miss */ + if (!test_read(&ptr[45], &val, 0xdeadbeefd0d0)) { + return 1; + } + /* dest reg of load should have the value written */ + if (val !=3D 0xfee1800d4ea) { + return 2; + } + /* remove the PTE */ + unmap(ptr); + /* this should fail */ + if (test_read(&ptr[45], &val, 0xdeadbeefd0d0)) { + return 3; + } + /* dest reg of load should be unchanged */ + if (val !=3D 0xdeadbeefd0d0) { + return 4; + } + /* DAR and DSISR should be set correctly */ + if (mfspr(DAR) !=3D (long) &ptr[45] || mfspr(DSISR) !=3D 0x40000000) { + return 5; + } + return 0; +} + +int mmu_test_4(void) +{ + long *mem =3D (long *) 0xa000; + long *ptr =3D (long *) 0x10b000; + long *ptr2 =3D (long *) 0x110b000; + long val; + + /* create PTE */ + map(ptr, mem, DFLT_PERM); + /* initialize the memory content */ + mem[27] =3D 0xf00f00f00f00; + /* this should succeed and be a cache miss */ + if (!test_write(&ptr[27], 0xe44badc0ffee)) { + return 1; + } + /* memory should now have the value written */ + if (mem[27] !=3D 0xe44badc0ffee) { + return 2; + } + /* load a second TLB entry in the same set as the first */ + map(ptr2, mem, DFLT_PERM); + /* this should succeed and be a cache hit */ + if (!test_write(&ptr2[27], 0x6e11ae)) { + return 3; + } + /* memory should have the value written */ + if (mem[27] !=3D 0x6e11ae) { + return 4; + } + /* check that the first entry still exists */ + /* (assumes TLB is 2-way associative or more) */ + if (!test_read(&ptr[27], &val, 0xdeadbeefd00d)) { + return 5; + } + if (val !=3D 0x6e11ae) { + return 6; + } + return 0; +} + +int mmu_test_5(void) +{ + long *mem =3D (long *) 0xbffd; + long *ptr =3D (long *) 0x39fffd; + long val; + + /* create PTE */ + map(ptr, mem, DFLT_PERM); + /* this should fail */ + if (test_read(ptr, &val, 0xdeadbeef0dd0)) { + return 1; + } + /* dest reg of load should be unchanged */ + if (val !=3D 0xdeadbeef0dd0) { + return 2; + } + /* DAR and DSISR should be set correctly */ + if (mfspr(DAR) !=3D ((long)ptr & ~0xfff) + 0x1000 || + mfspr(DSISR) !=3D 0x40000000) { + return 3; + } + return 0; +} + +int mmu_test_6(void) +{ + long *mem =3D (long *) 0xbffd; + long *ptr =3D (long *) 0x39fffd; + + /* create PTE */ + map(ptr, mem, DFLT_PERM); + /* initialize memory */ + *mem =3D 0x123456789abcdef0; + /* this should fail */ + if (test_write(ptr, 0xdeadbeef0dd0)) { + return 1; + } + /* DAR and DSISR should be set correctly */ + if (mfspr(DAR) !=3D ((long)ptr & ~0xfff) + 0x1000 || + mfspr(DSISR) !=3D 0x42000000) { + return 2; + } + return 0; +} + +int mmu_test_7(void) +{ + long *mem =3D (long *) 0x8000; + long *ptr =3D (long *) 0x124000; + long val; + + *mem =3D 0x123456789abcdef0; + /* create PTE without read or write permission */ + map(ptr, mem, REF); + /* this should fail */ + if (test_read(ptr, &val, 0xdeadd00dbeef)) { + return 1; + } + /* dest reg of load should be unchanged */ + if (val !=3D 0xdeadd00dbeef) { + return 2; + } + /* DAR and DSISR should be set correctly */ + if (mfspr(DAR) !=3D (long) ptr || mfspr(DSISR) !=3D 0x08000000) { + return 3; + } + /* this should fail */ + if (test_write(ptr, 0xdeadbeef0dd1)) { + return 4; + } + /* DAR and DSISR should be set correctly */ + if (mfspr(DAR) !=3D (long)ptr || mfspr(DSISR) !=3D 0x0a000000) { + return 5; + } + /* memory should be unchanged */ + if (*mem !=3D 0x123456789abcdef0) { + return 6; + } + return 0; +} + +int mmu_test_8(void) +{ + long *mem =3D (long *) 0x8000; + long *ptr =3D (long *) 0x124000; + long val; + + *mem =3D 0x123456789abcdef0; + /* create PTE with read but not write permission */ + map(ptr, mem, REF | PERM_RD); + /* this should succeed */ + if (!test_read(ptr, &val, 0xdeadd00dbeef)) { + return 1; + } + /* this should fail */ + if (test_write(ptr, 0xdeadbeef0dd1)) { + return 2; + } + /* DAR and DSISR should be set correctly */ + if (mfspr(DAR) !=3D (long)ptr || mfspr(DSISR) !=3D 0x0a000000) { + return 3; + } + /* memory should be unchanged */ + if (*mem !=3D 0x123456789abcdef0) { + return 4; + } + return 0; +} + +int mmu_test_9(void) +{ + unsigned long ptr =3D 0x523000; + + /* this should fail */ + if (test_exec(0, ptr, MSR_DFLT | MSR_IR)) { + return 1; + } + /* SRR0 and SRR1 should be set correctly */ + if (mfspr(SRR0) !=3D (long) ptr || + mfspr(SRR1) !=3D (MSR_DFLT | 0x40000000 | MSR_IR)) { + return 2; + } + return 0; +} + +int mmu_test_10(void) +{ + unsigned long mem =3D 0x1000; + unsigned long ptr =3D 0x324000; + unsigned long ptr2 =3D 0x1324000; + + /* create PTE */ + map((void *)ptr, (void *)mem, PERM_EX | REF); + /* this should succeed and be a cache miss */ + if (!test_exec(0, ptr, MSR_DFLT | MSR_IR)) { + return 1; + } + /* create a second PTE */ + map((void *)ptr2, (void *)mem, PERM_EX | REF); + /* this should succeed and be a cache hit */ + if (!test_exec(0, ptr2, MSR_DFLT | MSR_IR)) { + return 2; + } + return 0; +} + +int mmu_test_11(void) +{ + unsigned long mem =3D 0x1000; + unsigned long ptr =3D 0x349000; + unsigned long ptr2 =3D 0x34a000; + + /* create a PTE */ + map((void *)ptr, (void *)mem, PERM_EX | REF); + /* this should succeed */ + if (!test_exec(1, ptr, MSR_DFLT | MSR_IR)) { + return 1; + } + /* invalidate the PTE */ + unmap((void *)ptr); + /* install a second PTE */ + map((void *)ptr2, (void *)mem, PERM_EX | REF); + /* this should fail */ + if (test_exec(1, ptr, MSR_DFLT | MSR_IR)) { + return 2; + } + /* SRR0 and SRR1 should be set correctly */ + if (mfspr(SRR0) !=3D (long) ptr || + mfspr(SRR1) !=3D (MSR_DFLT | 0x40000000 | MSR_IR)) { + return 3; + } + return 0; +} + +int mmu_test_12(void) +{ + unsigned long mem =3D 0x1000; + unsigned long mem2 =3D 0x2000; + unsigned long ptr =3D 0x30a000; + unsigned long ptr2 =3D 0x30b000; + + /* create a PTE */ + map((void *)ptr, (void *)mem, PERM_EX | REF); + /* this should fail due to second page not being mapped */ + if (test_exec(2, ptr, MSR_DFLT | MSR_IR)) { + return 1; + } + /* SRR0 and SRR1 should be set correctly */ + if (mfspr(SRR0) !=3D ptr2 || + mfspr(SRR1) !=3D (MSR_DFLT | 0x40000000 | MSR_IR)) { + return 2; + } + /* create a PTE for the second page */ + map((void *)ptr2, (void *)mem2, PERM_EX | REF); + /* this should succeed */ + if (!test_exec(2, ptr, MSR_DFLT | MSR_IR)) { + return 3; + } + return 0; +} + +int mmu_test_13(void) +{ + unsigned long mem =3D 0x1000; + unsigned long ptr =3D 0x324000; + + /* create a PTE without execute permission */ + map((void *)ptr, (void *)mem, DFLT_PERM); + /* this should fail */ + if (test_exec(0, ptr, MSR_DFLT | MSR_IR)) { + return 1; + } + /* SRR0 and SRR1 should be set correctly */ + if (mfspr(SRR0) !=3D ptr || + mfspr(SRR1) !=3D (MSR_DFLT | 0x10000000 | MSR_IR)) { + return 2; + } + return 0; +} + +int mmu_test_14(void) +{ + unsigned long mem =3D 0x1000; + unsigned long mem2 =3D 0x2000; + unsigned long ptr =3D 0x30a000; + unsigned long ptr2 =3D 0x30b000; + + /* create a PTE */ + map((void *)ptr, (void *)mem, PERM_EX | REF); + /* create a PTE for the second page without execute permission */ + map((void *)ptr2, (void *)mem2, PERM_RD | REF); + /* this should fail due to second page being no-execute */ + if (test_exec(2, ptr, MSR_DFLT | MSR_IR)) { + return 1; + } + /* SRR0 and SRR1 should be set correctly */ + if (mfspr(SRR0) !=3D ptr2 || + mfspr(SRR1) !=3D (MSR_DFLT | 0x10000000 | MSR_IR)) { + return 2; + } + /* create a PTE for the second page with execute permission */ + map((void *)ptr2, (void *)mem2, PERM_RD | PERM_EX | REF); + /* this should succeed */ + if (!test_exec(2, ptr, MSR_DFLT | MSR_IR)) { + return 3; + } + return 0; +} + +int mmu_test_15(void) +{ + unsigned long mem =3D 0x1000; + unsigned long ptr =3D 0x349000; + + /* create a PTE without ref or execute permission */ + map((void *)ptr, (void *)mem, 0); + /* this should fail */ + if (test_exec(2, ptr, MSR_DFLT | MSR_IR)) { + return 1; + } + /* SRR0 and SRR1 should be set correctly */ + /* RC update fail bit should not be set */ + if (mfspr(SRR0) !=3D (long) ptr || + mfspr(SRR1) !=3D (MSR_DFLT | 0x10000000 | MSR_IR)) { + return 2; + } + return 0; +} + +int mmu_test_16(void) +{ + long *mem =3D (long *) 0x8000; + long *ptr =3D (long *) 0x124000; + long *ptr2 =3D (long *) 0x1124000; + + /* create PTE */ + map(ptr, mem, DFLT_PERM); + /* this should succeed and be a cache miss */ + if (!test_dcbz(&ptr[129])) { + return 1; + } + /* create a second PTE */ + map(ptr2, mem, DFLT_PERM); + /* this should succeed and be a cache hit */ + if (!test_dcbz(&ptr2[130])) { + return 2; + } + return 0; +} + +int mmu_test_17(void) +{ + long *mem =3D (long *) 0x8000; + long *ptr =3D (long *) 0x124000; + + *mem =3D 0x123456789abcdef0; + /* create PTE with read but not write permission */ + map(ptr, mem, REF | PERM_RD); + /* this should fail and create a TLB entry */ + if (test_write(ptr, 0xdeadbeef0dd1)) { + return 1; + } + /* DAR and DSISR should be set correctly */ + if (mfspr(DAR) !=3D (long)ptr || mfspr(DSISR) !=3D 0x0a000000) { + return 2; + } + /* Update the PTE to have write permission */ + map(ptr, mem, REF | CHG | PERM_RD | PERM_WR); + /* this should succeed */ + if (!test_write(ptr, 0xdeadbeef0dd1)) { + return 3; + } + return 0; +} + +int fail; + +void do_test(int num, int (*test)(void)) +{ + int ret; + + mtspr(DSISR, 0); + mtspr(DAR, 0); + unmap_all(); + ml_printf("test %d:", num); + ret =3D test(); + if (ret =3D=3D 0) { + ml_printf("PASS\r\n"); + } else { + fail =3D 1; + ml_printf("FAIL %d", ret); + if (num <=3D 10 || num =3D=3D 19) { + ml_printf(" DAR=3D%lx DSISR=3D%lx", mfspr(DAR), mfspr(DSISR)); + } else { + ml_printf(" SRR0=3D%lx SRR1=3D%lx", mfspr(SRR0), mfspr(SRR1)); + } + ml_printf("\r\n"); + } +} + +int main(void) +{ + init_mmu(); + + do_test(1, mmu_test_1); + do_test(2, mmu_test_2); + do_test(3, mmu_test_3); + do_test(4, mmu_test_4); + do_test(5, mmu_test_5); + do_test(6, mmu_test_6); + do_test(7, mmu_test_7); + do_test(8, mmu_test_8); + do_test(9, mmu_test_9); + do_test(10, mmu_test_10); + do_test(11, mmu_test_11); + do_test(12, mmu_test_12); + do_test(13, mmu_test_13); + do_test(14, mmu_test_14); + do_test(15, mmu_test_15); + do_test(16, mmu_test_16); + do_test(17, mmu_test_17); + + return fail; +} diff --git a/tests/tcg/ppc64/system/mmu.h b/tests/tcg/ppc64/system/mmu.h new file mode 100644 index 0000000000..eb191e4bd0 --- /dev/null +++ b/tests/tcg/ppc64/system/mmu.h @@ -0,0 +1,9 @@ +#ifndef PPC64_MMU_H +#define PPC64_MMU_H + +int test_read(long *addr, long *ret, long init); +int test_write(long *addr, long val); +int test_dcbz(long *addr); +int test_exec(int testno, unsigned long pc, unsigned long msr); + +#endif --=20 2.25.1 From nobody Sun May 5 09:35:59 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1650309584482704.7659391938422; Mon, 18 Apr 2022 12:19:44 -0700 (PDT) Received: from localhost ([::1]:50128 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ngWuU-0006mv-Vg for importer@patchew.org; Mon, 18 Apr 2022 15:19:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:40070) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ngWn4-0006jO-6O; Mon, 18 Apr 2022 15:12:02 -0400 Received: from [187.72.171.209] (port=10848 helo=outlook.eldorado.org.br) by eggs.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ngWn2-00036o-Cv; Mon, 18 Apr 2022 15:12:01 -0400 Received: from p9ibm ([10.10.71.235]) by outlook.eldorado.org.br over TLS secured channel with Microsoft SMTPSVC(8.5.9600.16384); Mon, 18 Apr 2022 16:11:55 -0300 Received: from eldorado.org.br (unknown [10.10.70.45]) by p9ibm (Postfix) with ESMTP id 494168000A0; Mon, 18 Apr 2022 16:11:55 -0300 (-03) From: Leandro Lupori To: qemu-devel@nongnu.org, qemu-ppc@nongnu.org Subject: [RFC PATCH v3 5/5] tests/tcg/ppc64: Build PowerNV and LE tests Date: Mon, 18 Apr 2022 16:11:00 -0300 Message-Id: <20220418191100.270334-6-leandro.lupori@eldorado.org.br> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20220418191100.270334-1-leandro.lupori@eldorado.org.br> References: <20220418191100.270334-1-leandro.lupori@eldorado.org.br> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-OriginalArrivalTime: 18 Apr 2022 19:11:55.0718 (UTC) FILETIME=[2B5D1E60:01D85358] X-Host-Lookup-Failed: Reverse DNS lookup failed for 187.72.171.209 (failed) Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=187.72.171.209; envelope-from=leandro.lupori@eldorado.org.br; helo=outlook.eldorado.org.br X-Spam_score_int: -4 X-Spam_score: -0.5 X-Spam_bar: / X-Spam_report: (-0.5 / 5.0 requ) BAYES_00=-1.9, PDS_HP_HELO_NORDNS=0.659, RDNS_NONE=0.793, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01, UPPERCASE_50_75=0.008 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Leandro Lupori , danielhb413@gmail.com, richard.henderson@linaro.org, groug@kaod.org, clg@kaod.org, pbonzini@redhat.com, alex.bennee@linaro.org, david@gibson.dropbear.id.au Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1650309584975100001 Content-Type: text/plain; charset="utf-8" Each Microwatt/PowerNV test use its own head.S file and thus needs different build rules. Also add rules to build and run all tests in LE mode. Signed-off-by: Leandro Lupori --- tests/tcg/ppc64/Makefile.softmmu-rules | 34 +++++++ tests/tcg/ppc64/Makefile.softmmu-target | 121 +++++++++++++++++++----- 2 files changed, 129 insertions(+), 26 deletions(-) create mode 100644 tests/tcg/ppc64/Makefile.softmmu-rules diff --git a/tests/tcg/ppc64/Makefile.softmmu-rules b/tests/tcg/ppc64/Makef= ile.softmmu-rules new file mode 100644 index 0000000000..abe0de0a7f --- /dev/null +++ b/tests/tcg/ppc64/Makefile.softmmu-rules @@ -0,0 +1,34 @@ +# +# Rules to build PowerPC64 softmmu tests, for both BE and LE +# + +# Build CRT and test objects +%$(LE_SUFFIX).o: $(CRT_PATH)/%.S + $(CC) $(PPC64_CFLAGS) -x assembler-with-cpp -c $< -o $@ + +%$(LE_SUFFIX).o: %.S + $(CC) $(PPC64_CFLAGS) -x assembler-with-cpp -c $< -o $@ + +%$(LE_SUFFIX).o: $(CRT_PATH)/%.c + $(CC) $(PPC64_CFLAGS) -c $< -o $@ + +%$(LE_SUFFIX).o: %.c + $(CC) $(PPC64_CFLAGS) -c $< -o $@ + +# Build .elf files for debugging +%$(LE_SUFFIX).elf: %$(LE_SUFFIX).o $(LINK_SCRIPT) $(CRT_DEPS) $(MINILIB_DE= PS) + $(CC) $(PPC64_CFLAGS) -o $@ $< $(LDFLAGS) + +$(PPC64_PNV_ELFS): %$(LE_SUFFIX).elf: %-head$(LE_SUFFIX).o %$(LE_SUFFIX).o= \ + $(LINK_SCRIPT) $(CRT_DEPS) $(MINILIB_DEPS) + $(CC) $(PPC64_CFLAGS) -o $@ $< $*$(LE_SUFFIX).o $(LDFLAGS) + +# Build test binaries +%$(LE_SUFFIX): %$(LE_SUFFIX).o $(LINK_SCRIPT) $(CRT_DEPS) $(MINILIB_DEPS) \ + %$(LE_SUFFIX).elf + $(CC) $(PPC64_CFLAGS) -o $@ $< $(LDFLAGS) -Wl,--oformat=3Dbinary + +$(PPC64_PNV_TESTS): %$(LE_SUFFIX): %-head$(LE_SUFFIX).o %$(LE_SUFFIX).o \ + $(LINK_SCRIPT) $(CRT_DEPS) $(MINILIB_DEPS) %$(LE_SUFFI= X).elf + $(CC) $(PPC64_CFLAGS) -o $@ $< $*$(LE_SUFFIX).o $(LDFLAGS) \ + -Wl,--oformat=3Dbinary diff --git a/tests/tcg/ppc64/Makefile.softmmu-target b/tests/tcg/ppc64/Make= file.softmmu-target index 948427b70d..cf89d2f950 100644 --- a/tests/tcg/ppc64/Makefile.softmmu-target +++ b/tests/tcg/ppc64/Makefile.softmmu-target @@ -5,22 +5,52 @@ # For now, disable tests that are failing DISABLED_TESTS :=3D memory DISABLED_EXTRA_RUNS :=3D run-gdbstub-memory +# Disable LE tests too +DISABLED_TESTS +=3D $(addsuffix -le, $(DISABLED_TESTS)) +DISABLED_EXTRA_RUNS +=3D $(addsuffix -le, $(DISABLED_EXTRA_RUNS)) =20 -PPC64_SYSTEM_SRC=3D$(SRC_PATH)/tests/tcg/ppc64/system -VPATH+=3D$(PPC64_SYSTEM_SRC) +PPC64_SRC :=3D $(SRC_PATH)/tests/tcg/ppc64 +PPC64_SYSTEM_SRC :=3D $(PPC64_SRC)/system +VPATH +=3D $(PPC64_SYSTEM_SRC) =20 # These objects provide the basic boot code and helper functions for all t= ests -CRT_PATH=3D$(PPC64_SYSTEM_SRC)/lib -CRT_OBJS=3Dboot.o +CRT_PATH :=3D $(PPC64_SYSTEM_SRC)/lib +CRT_OBJS_BE :=3D boot.o +CRT_OBJS_LE :=3D boot-le.o +# NOTE: %-head.o replaces boot.o on PowerNV tests +PNV_CRT_OBJS_BE :=3D $(filter-out boot.o, $(CRT_OBJS_BE)) +PNV_CRT_OBJS_LE :=3D $(filter-out boot-le.o, $(CRT_OBJS_LE)) =20 -LINK_SCRIPT=3D$(CRT_PATH)/powerpc.lds -# NOTE: --build-id is stored before the first code section in the linked -# binary, which causes problems for most tests, that expect to -# begin at address 0. -LDFLAGS=3D-Wl,-T$(LINK_SCRIPT) -Wl,--build-id=3Dnone -static -nostdlib \ - $(CRT_OBJS) $(MINILIB_OBJS) -lgcc -TESTS +=3D $(filter-out $(DISABLED_TESTS),$(MULTIARCH_TESTS)) -EXTRA_RUNS +=3D $(filter-out $(DISABLED_EXTRA_RUNS),$(MULTIARCH_RUNS)) +MINILIB_OBJS_BE :=3D $(MINILIB_OBJS) +MINILIB_OBJS_LE :=3D $(patsubst %.o, %-le.o, $(MINILIB_OBJS)) + +# Add BE and LE tests + +# Each Microwatt/PowerNV test use its own head.S file and thus needs +# different rules. +PPC64BE_PNV_TESTS :=3D mmu +PPC64BE_PNV_ELFS :=3D $(addsuffix .elf, $(PPC64BE_PNV_TESTS)) +PPC64LE_PNV_TESTS :=3D $(addsuffix -le, $(PPC64BE_PNV_TESTS)) +PPC64LE_PNV_ELFS :=3D $(addsuffix .elf, $(PPC64LE_PNV_TESTS)) + +# Remaining test sources are assumed to be non-PowerNV tests +PPC64_TEST_SRCS :=3D $(wildcard $(PPC64_SYSTEM_SRC)/*.c) +PPC64BE_TESTS :=3D $(MULTIARCH_TESTS) +PPC64BE_TESTS +=3D $(filter-out $(PPC64BE_PNV_TESTS),\ + $(patsubst $(PPC64_SYSTEM_SRC)/%.c, %, $(PPC64_TEST_SRCS)= )) +PPC64BE_ELFS :=3D $(addsuffix .elf,$(PPC64BE_TESTS)) +PPC64LE_TESTS :=3D $(addsuffix -le, $(PPC64BE_TESTS)) +PPC64LE_ELFS :=3D $(addsuffix .elf,$(PPC64LE_TESTS)) + +TESTS +=3D $(filter-out $(DISABLED_TESTS), $(PPC64BE_TESTS) $(PPC64LE_TEST= S)) +TESTS +=3D $(PPC64BE_PNV_TESTS) $(PPC64LE_PNV_TESTS) + +MULTIARCH_RUNS_BE :=3D $(MULTIARCH_RUNS) +MULTIARCH_RUNS_LE :=3D $(addsuffix -le, $(MULTIARCH_RUNS)) +EXTRA_RUNS +=3D $(filter-out $(DISABLED_EXTRA_RUNS), \ + $(MULTIARCH_RUNS_BE) $(MULTIARCH_RUNS_LE)) + +LINK_SCRIPT :=3D $(CRT_PATH)/powerpc.lds =20 # NOTE: -Os doesn't work well with -Wl,--oformat=3Dbinary # Some linker generated functions, such as savegpr*/restgpr*, @@ -30,27 +60,66 @@ CFLAGS =3D -O -g -Wall -std=3Dc99 -msoft-float -mno-vsx= -mno-altivec \ -I $(PPC64_SYSTEM_SRC)/include $(MINILIB_INC) \ -mcpu=3Dpower8 =20 -# Uncomment to test in LE -# override EXTRA_CFLAGS +=3D -mlittle-endian -mabi=3Delfv2 +# NOTE: --build-id is stored before the first code section in the linked +# binary, which causes problems for most tests, that expect to +# begin at address 0. +LDFLAGS =3D -Wl,-T$(LINK_SCRIPT) -Wl,--build-id=3Dnone -static -nostdlib \ + $(CRT_OBJS) $(MINILIB_OBJS) -lgcc + +memory memory-le: CFLAGS+=3D-DCHECK_UNALIGNED=3D1 + +# PowerNV tests build outputs +PPC64BE_PNV_OUTPUTS :=3D $(PPC64BE_PNV_TESTS) $(PPC64BE_PNV_ELFS) +PPC64LE_PNV_OUTPUTS :=3D $(PPC64LE_PNV_TESTS) $(PPC64LE_PNV_ELFS) +# Non-PowerNV tests build outputs +PPC64BE_OUTPUTS :=3D $(PPC64BE_TESTS) $(PPC64BE_ELFS) +PPC64LE_OUTPUTS :=3D $(PPC64LE_TESTS) $(PPC64LE_ELFS) +# Outputs of all tests +PPC64BE_ALL_OUTPUTS :=3D $(PPC64BE_OUTPUTS) $(PPC64BE_PNV_OUTPUTS) +PPC64LE_ALL_OUTPUTS :=3D $(PPC64LE_OUTPUTS) $(PPC64LE_PNV_OUTPUTS) + +PPC64_CFLAGS =3D $(CFLAGS) $(EXTRA_CFLAGS) $(PPC64LE_CFLAGS) =20 # Leave the .elf files, to make debugging easier -.PRECIOUS: $(CRT_OBJS) $(addsuffix .elf,$(TESTS)) +.PRECIOUS: $(CRT_OBJS_BE) $(CRT_OBJS_LE) $(addsuffix .elf,$(TESTS)) + +# BE rules + +LE_SUFFIX :=3D +CRT_DEPS :=3D $(CRT_OBJS_BE) +MINILIB_DEPS :=3D $(MINILIB_OBJS_BE) +PPC64_PNV_ELFS :=3D $(PPC64BE_PNV_ELFS) +PPC64_PNV_TESTS :=3D $(PPC64BE_PNV_TESTS) + +$(PPC64BE_ALL_OUTPUTS): LE_SUFFIX =3D +$(PPC64BE_ALL_OUTPUTS): PPC64LE_CFLAGS =3D +$(PPC64BE_OUTPUTS): CRT_OBJS =3D $(CRT_OBJS_BE) +$(PPC64BE_PNV_OUTPUTS): CRT_OBJS =3D $(PNV_CRT_OBJS_BE) +$(PPC64BE_ALL_OUTPUTS): MINILIB_OBJS =3D $(MINILIB_OBJS_BE) + +include $(PPC64_SRC)/Makefile.softmmu-rules =20 -# Build CRT objects -%.o: $(CRT_PATH)/%.S - $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -x assembler-with-cpp -c $< -o $@ +# LE rules =20 -# Build and link the tests +LE_SUFFIX :=3D -le +CRT_DEPS :=3D $(CRT_OBJS_LE) +MINILIB_DEPS :=3D $(MINILIB_OBJS_LE) +PPC64_PNV_ELFS :=3D $(PPC64LE_PNV_ELFS) +PPC64_PNV_TESTS :=3D $(PPC64LE_PNV_TESTS) =20 -# The .elf files are just for debugging -%.elf: %.c $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS) - $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) +$(PPC64LE_ALL_OUTPUTS): LE_SUFFIX =3D -le +$(PPC64LE_ALL_OUTPUTS): PPC64LE_CFLAGS =3D -mlittle-endian -mabi=3Delfv2 +$(PPC64LE_OUTPUTS): CRT_OBJS =3D $(CRT_OBJS_LE) +$(PPC64LE_PNV_OUTPUTS): CRT_OBJS =3D $(PNV_CRT_OBJS_LE) +$(PPC64LE_ALL_OUTPUTS): MINILIB_OBJS =3D $(MINILIB_OBJS_LE) =20 -%: %.c %.elf $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS) - $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) -Wl,--oformat=3Dbinary +include $(PPC64_SRC)/Makefile.softmmu-rules =20 -memory: CFLAGS+=3D-DCHECK_UNALIGNED=3D1 +# Build LE Minilib objs +%-le.o: $(SYSTEM_MINILIB_SRC)/%.c + $(CC) $(PPC64_CFLAGS) -c $< -o $@ =20 # Running QEMU_BASE_MACHINE=3D-cpu power9 -M powernv9 -m 1G -vga none -nographic -QEMU_OPTS+=3D$(QEMU_BASE_MACHINE) -serial chardev:output -bios +QEMU_OPTS+=3D$(QEMU_BASE_MACHINE) -semihosting-config \ + enable=3Don,target=3Dnative,chardev=3Doutput -bios --=20 2.25.1