From patchwork Wed Apr 11 18:56:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 897388 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=2001:4830:134:3::11; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=vivier.eu Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40LvHP18Ymz9s1s for ; Thu, 12 Apr 2018 05:29:20 +1000 (AEST) Received: from localhost ([::1]:49345 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f6LQk-0008Bi-Jv for incoming@patchwork.ozlabs.org; Wed, 11 Apr 2018 15:29:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38024) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1f6Kw5-00065L-Qu for qemu-devel@nongnu.org; Wed, 11 Apr 2018 14:57:42 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1f6Kw2-0007rX-Os for qemu-devel@nongnu.org; Wed, 11 Apr 2018 14:57:37 -0400 Received: from mout.kundenserver.de ([212.227.17.10]:39287) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1f6Kw2-0007qm-8Y; Wed, 11 Apr 2018 14:57:34 -0400 Received: from localhost.localdomain ([78.238.229.36]) by mrelayeu.kundenserver.de (mreue105 [212.227.15.183]) with ESMTPSA (Nemesis) id 0LkQIt-1eUn7v2Nwp-00cS2N; Wed, 11 Apr 2018 20:57:25 +0200 From: Laurent Vivier To: qemu-devel@nongnu.org Date: Wed, 11 Apr 2018 20:56:50 +0200 Message-Id: <20180411185651.21351-19-laurent@vivier.eu> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180411185651.21351-1-laurent@vivier.eu> References: <20180411185651.21351-1-laurent@vivier.eu> MIME-Version: 1.0 X-Provags-ID: V03:K1:lMxU0AzJiBnwpNapLANHzLyyBfBGM8WzRaZ6+jrhEEPzDWcpIbk F4j2qlKfUhF5uvp5UCGMNCfzQMhHWfvUq2Wc7wBaD6XSw7gmKebb5axYIVz/uxmf5FFFaFi BT8Zyw3RbYCSj/NlhleVPNVYE+NbU0Gc8ptsmjQJ+7YMfFv2hqetWbxZE0Mf4I9WKq5C6SK wD/QLY3f5Qnmz9lFrnJfA== X-UI-Out-Filterresults: notjunk:1; V01:K0:pseWA0w6mRE=:zNeZnsjozNFOzd1acNWtbC pD0l7LpfetYyVgsObJHZj7WuRtF+eHYtaadumjGE6MWRq9kk+w5me8kZrvxjv3KlvUTOeG0Pp t9jmUa8IX8WPfJ9VAZ5Hq1MRsx57gSabQDLQqLz6qKXOtDlpPOukntwNChyXCeBXc1xFbmy1+ XrFrTVqEYcSJVDoUmJ7iOutOAy9iD36TeL6nCcVsK2D2FMQrOiGn0MrigqK1MbVo/cJ+oyNn0 RuSPdsulGn75Gg2wC2s8XrNZudNbZCfGLCQDkBeggtTld3qSzbqwNS3MqmdKDvdW8dBBXRH1l 5ARwciOZiFq5Cme+xIfDFR/QOrToGy/kRAYqu06b3BLYimZC8E/3hLYfyFiks+hJB9HJv2NY9 n8Xdh7H3X21T0ueWCwdWKZ9mtxawb1S7uVTU1GtvitG+8mFpYkXOji+qILJsxdh/gNYkY6gYy 7hDUOEcHYz1NCdJrIFlKu0wIhbHcQybjWjQPzHN3qk5+7nAOwVQ0w3nDwr8CcZZQlxc/DIoie hzcxBorNS5tSbqmqd7NN45JE+8yHq8daMwV5Wxx52XEETs2GLN+tvSmPHwtZiMNiokGY+RMq2 GlY0+DU/uW9HaIEClrbOo73RMS/oC8udG6Q9i7pCTUxwEJciginzmx2p3a5DpwMcI3g+zT8iz sRnOyWWEtO1Lr2lbh8Jys/wt5MLZ8jFfpQ1tJTFtDBXbHTlVpLbzFs8tbRRPzcmYED+6ZEDZE xCMDGlfPCuE2PfIXwNmFFDMGX8cHOM/U1u/CXMH1WBg3zpPiZRoYh1B3I48= X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.17.10 Subject: [Qemu-devel] [PATCH for 2.13 v2 18/19] linux-user: move hppa cpu loop to hppa directory X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , Cornelia Huck , Riku Voipio , Richard Henderson , =?utf-8?q?Philippe_Mathieu-Daud=C3=A9?= , Laurent Vivier , qemu-s390x@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" No code change, only move code from main.c to hppa/cpu_loop.c. Signed-off-by: Laurent Vivier Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé --- linux-user/hppa/cpu_loop.c | 185 ++++++++++++++++++++++++++++++++++++++++++ linux-user/main.c | 194 +-------------------------------------------- 2 files changed, 186 insertions(+), 193 deletions(-) diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c index b7700a5561..0301c766c6 100644 --- a/linux-user/hppa/cpu_loop.c +++ b/linux-user/hppa/cpu_loop.c @@ -21,6 +21,191 @@ #include "qemu.h" #include "cpu_loop-common.h" +static abi_ulong hppa_lws(CPUHPPAState *env) +{ + uint32_t which = env->gr[20]; + abi_ulong addr = env->gr[26]; + abi_ulong old = env->gr[25]; + abi_ulong new = env->gr[24]; + abi_ulong size, ret; + + switch (which) { + default: + return -TARGET_ENOSYS; + + case 0: /* elf32 atomic 32bit cmpxchg */ + if ((addr & 3) || !access_ok(VERIFY_WRITE, addr, 4)) { + return -TARGET_EFAULT; + } + old = tswap32(old); + new = tswap32(new); + ret = atomic_cmpxchg((uint32_t *)g2h(addr), old, new); + ret = tswap32(ret); + break; + + case 2: /* elf32 atomic "new" cmpxchg */ + size = env->gr[23]; + if (size >= 4) { + return -TARGET_ENOSYS; + } + if (((addr | old | new) & ((1 << size) - 1)) + || !access_ok(VERIFY_WRITE, addr, 1 << size) + || !access_ok(VERIFY_READ, old, 1 << size) + || !access_ok(VERIFY_READ, new, 1 << size)) { + return -TARGET_EFAULT; + } + /* Note that below we use host-endian loads so that the cmpxchg + can be host-endian as well. */ + switch (size) { + case 0: + old = *(uint8_t *)g2h(old); + new = *(uint8_t *)g2h(new); + ret = atomic_cmpxchg((uint8_t *)g2h(addr), old, new); + ret = ret != old; + break; + case 1: + old = *(uint16_t *)g2h(old); + new = *(uint16_t *)g2h(new); + ret = atomic_cmpxchg((uint16_t *)g2h(addr), old, new); + ret = ret != old; + break; + case 2: + old = *(uint32_t *)g2h(old); + new = *(uint32_t *)g2h(new); + ret = atomic_cmpxchg((uint32_t *)g2h(addr), old, new); + ret = ret != old; + break; + case 3: + { + uint64_t o64, n64, r64; + o64 = *(uint64_t *)g2h(old); + n64 = *(uint64_t *)g2h(new); +#ifdef CONFIG_ATOMIC64 + r64 = atomic_cmpxchg__nocheck((uint64_t *)g2h(addr), o64, n64); + ret = r64 != o64; +#else + start_exclusive(); + r64 = *(uint64_t *)g2h(addr); + ret = 1; + if (r64 == o64) { + *(uint64_t *)g2h(addr) = n64; + ret = 0; + } + end_exclusive(); +#endif + } + break; + } + break; + } + + env->gr[28] = ret; + return 0; +} + +void cpu_loop(CPUHPPAState *env) +{ + CPUState *cs = CPU(hppa_env_get_cpu(env)); + target_siginfo_t info; + abi_ulong ret; + int trapnr; + + while (1) { + cpu_exec_start(cs); + trapnr = cpu_exec(cs); + cpu_exec_end(cs); + process_queued_cpu_work(cs); + + switch (trapnr) { + case EXCP_SYSCALL: + ret = do_syscall(env, env->gr[20], + env->gr[26], env->gr[25], + env->gr[24], env->gr[23], + env->gr[22], env->gr[21], 0, 0); + switch (ret) { + default: + env->gr[28] = ret; + /* We arrived here by faking the gateway page. Return. */ + env->iaoq_f = env->gr[31]; + env->iaoq_b = env->gr[31] + 4; + break; + case -TARGET_ERESTARTSYS: + case -TARGET_QEMU_ESIGRETURN: + break; + } + break; + case EXCP_SYSCALL_LWS: + env->gr[21] = hppa_lws(env); + /* We arrived here by faking the gateway page. Return. */ + env->iaoq_f = env->gr[31]; + env->iaoq_b = env->gr[31] + 4; + break; + case EXCP_ITLB_MISS: + case EXCP_DTLB_MISS: + case EXCP_NA_ITLB_MISS: + case EXCP_NA_DTLB_MISS: + case EXCP_IMP: + case EXCP_DMP: + case EXCP_DMB: + case EXCP_PAGE_REF: + case EXCP_DMAR: + case EXCP_DMPI: + info.si_signo = TARGET_SIGSEGV; + info.si_errno = 0; + info.si_code = TARGET_SEGV_ACCERR; + info._sifields._sigfault._addr = env->cr[CR_IOR]; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; + case EXCP_UNALIGN: + info.si_signo = TARGET_SIGBUS; + info.si_errno = 0; + info.si_code = 0; + info._sifields._sigfault._addr = env->cr[CR_IOR]; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; + case EXCP_ILL: + case EXCP_PRIV_OPR: + case EXCP_PRIV_REG: + info.si_signo = TARGET_SIGILL; + info.si_errno = 0; + info.si_code = TARGET_ILL_ILLOPN; + info._sifields._sigfault._addr = env->iaoq_f; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; + case EXCP_OVERFLOW: + case EXCP_COND: + case EXCP_ASSIST: + info.si_signo = TARGET_SIGFPE; + info.si_errno = 0; + info.si_code = 0; + info._sifields._sigfault._addr = env->iaoq_f; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; + case EXCP_DEBUG: + trapnr = gdb_handlesig(cs, TARGET_SIGTRAP); + if (trapnr) { + info.si_signo = trapnr; + info.si_errno = 0; + info.si_code = TARGET_TRAP_BRKPT; + queue_signal(env, trapnr, QEMU_SI_FAULT, &info); + } + break; + case EXCP_INTERRUPT: + /* just indicate that signals should be handled asap */ + break; + default: + g_assert_not_reached(); + } + process_pending_signals(env); + } +} + void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) { + int i; + for (i = 1; i < 32; i++) { + env->gr[i] = regs->gr[i]; + } + env->iaoq_f = regs->iaoq[0]; + env->iaoq_b = regs->iaoq[1]; } diff --git a/linux-user/main.c b/linux-user/main.c index 834ec0bfe5..aa48b048a7 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -149,189 +149,6 @@ void fork_end(int child) } } -#ifdef TARGET_HPPA - -static abi_ulong hppa_lws(CPUHPPAState *env) -{ - uint32_t which = env->gr[20]; - abi_ulong addr = env->gr[26]; - abi_ulong old = env->gr[25]; - abi_ulong new = env->gr[24]; - abi_ulong size, ret; - - switch (which) { - default: - return -TARGET_ENOSYS; - - case 0: /* elf32 atomic 32bit cmpxchg */ - if ((addr & 3) || !access_ok(VERIFY_WRITE, addr, 4)) { - return -TARGET_EFAULT; - } - old = tswap32(old); - new = tswap32(new); - ret = atomic_cmpxchg((uint32_t *)g2h(addr), old, new); - ret = tswap32(ret); - break; - - case 2: /* elf32 atomic "new" cmpxchg */ - size = env->gr[23]; - if (size >= 4) { - return -TARGET_ENOSYS; - } - if (((addr | old | new) & ((1 << size) - 1)) - || !access_ok(VERIFY_WRITE, addr, 1 << size) - || !access_ok(VERIFY_READ, old, 1 << size) - || !access_ok(VERIFY_READ, new, 1 << size)) { - return -TARGET_EFAULT; - } - /* Note that below we use host-endian loads so that the cmpxchg - can be host-endian as well. */ - switch (size) { - case 0: - old = *(uint8_t *)g2h(old); - new = *(uint8_t *)g2h(new); - ret = atomic_cmpxchg((uint8_t *)g2h(addr), old, new); - ret = ret != old; - break; - case 1: - old = *(uint16_t *)g2h(old); - new = *(uint16_t *)g2h(new); - ret = atomic_cmpxchg((uint16_t *)g2h(addr), old, new); - ret = ret != old; - break; - case 2: - old = *(uint32_t *)g2h(old); - new = *(uint32_t *)g2h(new); - ret = atomic_cmpxchg((uint32_t *)g2h(addr), old, new); - ret = ret != old; - break; - case 3: - { - uint64_t o64, n64, r64; - o64 = *(uint64_t *)g2h(old); - n64 = *(uint64_t *)g2h(new); -#ifdef CONFIG_ATOMIC64 - r64 = atomic_cmpxchg__nocheck((uint64_t *)g2h(addr), o64, n64); - ret = r64 != o64; -#else - start_exclusive(); - r64 = *(uint64_t *)g2h(addr); - ret = 1; - if (r64 == o64) { - *(uint64_t *)g2h(addr) = n64; - ret = 0; - } - end_exclusive(); -#endif - } - break; - } - break; - } - - env->gr[28] = ret; - return 0; -} - -void cpu_loop(CPUHPPAState *env) -{ - CPUState *cs = CPU(hppa_env_get_cpu(env)); - target_siginfo_t info; - abi_ulong ret; - int trapnr; - - while (1) { - cpu_exec_start(cs); - trapnr = cpu_exec(cs); - cpu_exec_end(cs); - process_queued_cpu_work(cs); - - switch (trapnr) { - case EXCP_SYSCALL: - ret = do_syscall(env, env->gr[20], - env->gr[26], env->gr[25], - env->gr[24], env->gr[23], - env->gr[22], env->gr[21], 0, 0); - switch (ret) { - default: - env->gr[28] = ret; - /* We arrived here by faking the gateway page. Return. */ - env->iaoq_f = env->gr[31]; - env->iaoq_b = env->gr[31] + 4; - break; - case -TARGET_ERESTARTSYS: - case -TARGET_QEMU_ESIGRETURN: - break; - } - break; - case EXCP_SYSCALL_LWS: - env->gr[21] = hppa_lws(env); - /* We arrived here by faking the gateway page. Return. */ - env->iaoq_f = env->gr[31]; - env->iaoq_b = env->gr[31] + 4; - break; - case EXCP_ITLB_MISS: - case EXCP_DTLB_MISS: - case EXCP_NA_ITLB_MISS: - case EXCP_NA_DTLB_MISS: - case EXCP_IMP: - case EXCP_DMP: - case EXCP_DMB: - case EXCP_PAGE_REF: - case EXCP_DMAR: - case EXCP_DMPI: - info.si_signo = TARGET_SIGSEGV; - info.si_errno = 0; - info.si_code = TARGET_SEGV_ACCERR; - info._sifields._sigfault._addr = env->cr[CR_IOR]; - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - break; - case EXCP_UNALIGN: - info.si_signo = TARGET_SIGBUS; - info.si_errno = 0; - info.si_code = 0; - info._sifields._sigfault._addr = env->cr[CR_IOR]; - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - break; - case EXCP_ILL: - case EXCP_PRIV_OPR: - case EXCP_PRIV_REG: - info.si_signo = TARGET_SIGILL; - info.si_errno = 0; - info.si_code = TARGET_ILL_ILLOPN; - info._sifields._sigfault._addr = env->iaoq_f; - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - break; - case EXCP_OVERFLOW: - case EXCP_COND: - case EXCP_ASSIST: - info.si_signo = TARGET_SIGFPE; - info.si_errno = 0; - info.si_code = 0; - info._sifields._sigfault._addr = env->iaoq_f; - queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); - break; - case EXCP_DEBUG: - trapnr = gdb_handlesig(cs, TARGET_SIGTRAP); - if (trapnr) { - info.si_signo = trapnr; - info.si_errno = 0; - info.si_code = TARGET_TRAP_BRKPT; - queue_signal(env, trapnr, QEMU_SI_FAULT, &info); - } - break; - case EXCP_INTERRUPT: - /* just indicate that signals should be handled asap */ - break; - default: - g_assert_not_reached(); - } - process_pending_signals(env); - } -} - -#endif /* TARGET_HPPA */ - #ifdef TARGET_XTENSA static void xtensa_rfw(CPUXtensaState *env) @@ -1228,16 +1045,7 @@ int main(int argc, char **argv, char **envp) target_cpu_copy_regs(env, regs); -#if defined(TARGET_HPPA) - { - int i; - for (i = 1; i < 32; i++) { - env->gr[i] = regs->gr[i]; - } - env->iaoq_f = regs->iaoq[0]; - env->iaoq_b = regs->iaoq[1]; - } -#elif defined(TARGET_XTENSA) +#if defined(TARGET_XTENSA) { int i; for (i = 0; i < 16; ++i) {