From patchwork Fri Dec 16 19:13:55 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Henderson X-Patchwork-Id: 706554 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3tgL8W6kLTz9t3K for ; Sat, 17 Dec 2016 06:33:47 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="LO2VTx/n"; dkim-atps=neutral Received: from localhost ([::1]:33929 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cHyGH-0002DO-AT for incoming@patchwork.ozlabs.org; Fri, 16 Dec 2016 14:33:45 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37544) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cHxxW-0001pA-Sz for qemu-devel@nongnu.org; Fri, 16 Dec 2016 14:14:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cHxxV-0000S9-Fb for qemu-devel@nongnu.org; Fri, 16 Dec 2016 14:14:22 -0500 Received: from mail-pg0-x241.google.com ([2607:f8b0:400e:c05::241]:33596) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cHxxV-0000RH-8Y for qemu-devel@nongnu.org; Fri, 16 Dec 2016 14:14:21 -0500 Received: by mail-pg0-x241.google.com with SMTP id 3so10556503pgd.0 for ; Fri, 16 Dec 2016 11:14:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=GyDqdnkn9k684A1c27LICBAWyCEKOVIznEYg0Q54qKI=; b=LO2VTx/n4s9CTl8/wWk0uEChM5w90KlaLe+gRy8Tm1htYRcmPCm8QOOpWGnil3MXb6 Uo2jQ22ikKDwOKivTGwbd1CbADlvPEZYnsYUBWk2prANP3NaYKxaawOd/5s6+B5T+9qu KWPZ4mN6IcjkPJmAXzgPa2sJ6JrEjpKPcvb+kqUkppMBkLKdos6dwXGMUB2wiMQOhQvc 1mvakl6xSUI08kIg6H60NaOJdWpQ92Zgzgabh/Vz7TUqRfE3aRmt4bgYhR3hwYv2jI0G k/nMx8AkJDcshvh0Ddl4hHlPNAidA75rty4s0fB0LFrQj8stdZ0e8MOHiu/qBFvciknH r90Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references; bh=GyDqdnkn9k684A1c27LICBAWyCEKOVIznEYg0Q54qKI=; b=JF5AJ4Jx0XubiOIh7dLRvuDxHx0BptnLb/JKH4x8/+BiGEDtGSJkWq4KPuy2uaID8K 36z4t5TPXjdkOgDOzGB50hHJSF7coF7fzY7LON833CT16yYZEJYEJGfbW9FCWEOCbDpb NJ4AbSdX5l7fZ769SclvEjaSCJWeqgevscPLLo+IY/5v0LAAAoR1Ea8XvwMOw09OG4i5 5KGWl5lFFfrqFdnrMsF1M39AF4+8strjwuR0oOVNNoPt228xisY28rNAYRtm7bKaBkCl e/+C1+/3NRLHAmug54IKzv9c/W7LAf0rlwIv+4Ap65hcKtT2LKZpivIucg/Ho0BO3vX5 JBuw== X-Gm-Message-State: AKaTC01FhX4GUy27aDutFBi/lam/ehpuYeMnvqkUI67WBu3ta+XoKh4jXn5TNv25RDCSSg== X-Received: by 10.84.164.231 with SMTP id l36mr10006592plg.33.1481915660496; Fri, 16 Dec 2016 11:14:20 -0800 (PST) Received: from bigtime.domain ([2602:47:d954:1500:5e51:4fff:fe40:9c64]) by smtp.gmail.com with ESMTPSA id c22sm13735067pgn.12.2016.12.16.11.14.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 16 Dec 2016 11:14:20 -0800 (PST) From: Richard Henderson To: qemu-devel@nongnu.org Date: Fri, 16 Dec 2016 11:13:55 -0800 Message-Id: <20161216191405.9473-17-rth@twiddle.net> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20161216191405.9473-1-rth@twiddle.net> References: <20161216191405.9473-1-rth@twiddle.net> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:400e:c05::241 Subject: [Qemu-devel] [PATCH 16/26] linux-user: Add HPPA startup and main loop 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: Riku Voipio Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" Including support for the atomic memory op syscalls. Cc: Riku Voipio Signed-off-by: Richard Henderson --- linux-user/elfload.c | 24 +++++++ linux-user/main.c | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 196 insertions(+) diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 5cea39d..51794bb 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -1215,6 +1215,30 @@ static inline void init_thread(struct target_pt_regs *regs, #endif /* TARGET_TILEGX */ +#ifdef TARGET_HPPA + +#define ELF_START_MMAP 0x80000000 +#define ELF_CLASS ELFCLASS32 +#define ELF_ARCH EM_PARISC +#define ELF_PLATFORM "PARISC" +#define STACK_GROWS_DOWN 0 +#define STACK_ALIGNMENT 64 + +static inline void init_thread(struct target_pt_regs *regs, + struct image_info *infop) +{ + regs->iaoq[0] = infop->entry; + regs->iaoq[1] = infop->entry + 4; + regs->gr[23] = 0; + regs->gr[24] = infop->arg_start; + regs->gr[25] = (infop->arg_end - infop->arg_start) / sizeof(abi_ulong); + /* The top-of-stack contains a linkage buffer. */ + regs->gr[30] = infop->start_stack + 64; + regs->gr[31] = infop->entry; +} + +#endif /* TARGET_HPPA */ + #ifndef ELF_PLATFORM #define ELF_PLATFORM (NULL) #endif diff --git a/linux-user/main.c b/linux-user/main.c index 8251027..68ee0cd 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3505,6 +3505,169 @@ void cpu_loop(CPUTLGState *env) #endif +#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_SIGSEGV: + info.si_signo = TARGET_SIGSEGV; + info.si_errno = 0; + info.si_code = TARGET_SEGV_ACCERR; + info._sifields._sigfault._addr = env->ior; + queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info); + break; + case EXCP_SIGILL: + 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_SIGFPE: + 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 */ + THREAD CPUState *thread_cpu; bool qemu_cpu_is_self(CPUState *cpu) @@ -4532,6 +4695,15 @@ int main(int argc, char **argv, char **envp) } env->pc = regs->pc; } +#elif 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]; + } #else #error unsupported target CPU #endif