From patchwork Wed Mar 6 02:01:19 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Graf X-Patchwork-Id: 225245 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)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 55F6F2C0367 for ; Wed, 6 Mar 2013 13:03:43 +1100 (EST) Received: from localhost ([::1]:47135 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UD3hl-0003RF-Gc for incoming@patchwork.ozlabs.org; Tue, 05 Mar 2013 21:03:41 -0500 Received: from eggs.gnu.org ([208.118.235.92]:35626) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UD3fb-0008Ul-Sc for qemu-devel@nongnu.org; Tue, 05 Mar 2013 21:01:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UD3fX-000656-3z for qemu-devel@nongnu.org; Tue, 05 Mar 2013 21:01:27 -0500 Received: from cantor2.suse.de ([195.135.220.15]:43331 helo=mx2.suse.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UD3fW-00064X-Qk for qemu-devel@nongnu.org; Tue, 05 Mar 2013 21:01:23 -0500 Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 398CDA5215; Wed, 6 Mar 2013 03:01:21 +0100 (CET) From: Alexander Graf To: qemu-devel qemu-devel Date: Wed, 6 Mar 2013 03:01:19 +0100 Message-Id: <1362535280-5068-12-git-send-email-agraf@suse.de> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1362535280-5068-1-git-send-email-agraf@suse.de> References: <1362535280-5068-1-git-send-email-agraf@suse.de> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x X-Received-From: 195.135.220.15 Cc: Peter Maydell , Riku Voipio Subject: [Qemu-devel] [PATCH 11/12] linux-user: Add AArch64 support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This patch adds support for AArch64 in all the small corners of linux-user and beyond. Signed-off-by: Alexander Graf --- default-configs/arm64-linux-user.mak | 3 ++ linux-user/arm/syscall.h | 46 +++++++++++++++++++++++++++++---- linux-user/elfload.c | 15 +++++++++- linux-user/main.c | 9 ++++++ target-arm/cpu.h | 20 ++++++++++++--- 5 files changed, 81 insertions(+), 12 deletions(-) create mode 100644 default-configs/arm64-linux-user.mak diff --git a/default-configs/arm64-linux-user.mak b/default-configs/arm64-linux-user.mak new file mode 100644 index 0000000..46d4aa2 --- /dev/null +++ b/default-configs/arm64-linux-user.mak @@ -0,0 +1,3 @@ +# Default configuration for arm-linux-user + +CONFIG_GDBSTUB_XML=y diff --git a/linux-user/arm/syscall.h b/linux-user/arm/syscall.h index 003d424..769aac0 100644 --- a/linux-user/arm/syscall.h +++ b/linux-user/arm/syscall.h @@ -1,4 +1,36 @@ +#ifdef TARGET_ARM64 + +struct target_pt_regs { + uint64_t regs[31]; + uint64_t sp; + uint64_t pc; + uint64_t pstate; +}; + +#define ARM_cpsr uregs[16] +#define ARM_pc uregs[15] +#define ARM_lr uregs[14] +#define ARM_sp uregs[13] +#define ARM_ip uregs[12] +#define ARM_fp uregs[11] +#define ARM_r10 uregs[10] +#define ARM_r9 uregs[9] +#define ARM_r8 uregs[8] +#define ARM_r7 uregs[7] +#define ARM_r6 uregs[6] +#define ARM_r5 uregs[5] +#define ARM_r4 uregs[4] +#define ARM_r3 uregs[3] +#define ARM_r2 uregs[2] +#define ARM_r1 uregs[1] +#define ARM_r0 uregs[0] +#define ARM_ORIG_r0 uregs[17] + +#define UNAME_MACHINE "aarch64" + +#else /* TARGET_ARM64 */ + /* this struct defines the way the registers are stored on the stack during a system call. */ @@ -25,6 +57,14 @@ struct target_pt_regs { #define ARM_r0 uregs[0] #define ARM_ORIG_r0 uregs[17] +#if defined(TARGET_WORDS_BIGENDIAN) +#define UNAME_MACHINE "armv5teb" +#else +#define UNAME_MACHINE "armv5tel" +#endif + +#endif /* TARGET_ARM64 */ + #define ARM_SYSCALL_BASE 0x900000 #define ARM_THUMB_SYSCALL 0 @@ -34,9 +74,3 @@ struct target_pt_regs { #define ARM_NR_semihosting 0x123456 #define ARM_NR_thumb_semihosting 0xAB - -#if defined(TARGET_WORDS_BIGENDIAN) -#define UNAME_MACHINE "armv5teb" -#else -#define UNAME_MACHINE "armv5tel" -#endif diff --git a/linux-user/elfload.c b/linux-user/elfload.c index 89db49c..239687d 100644 --- a/linux-user/elfload.c +++ b/linux-user/elfload.c @@ -260,16 +260,26 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en #define ELF_START_MMAP 0x80000000 -#define elf_check_arch(x) ( (x) == EM_ARM ) +#define elf_check_arch(x) ( (x) == ELF_MACHINE ) +#define ELF_ARCH ELF_MACHINE + +#ifdef TARGET_ARM64 +#define ELF_CLASS ELFCLASS64 +#else #define ELF_CLASS ELFCLASS32 -#define ELF_ARCH EM_ARM +#endif static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) { abi_long stack = infop->start_stack; memset(regs, 0, sizeof(*regs)); + +#ifdef TARGET_ARM64 + regs->pc = infop->entry & ~0x3ULL; + regs->sp = stack; +#else regs->ARM_cpsr = 0x10; if (infop->entry & 1) regs->ARM_cpsr |= CPSR_T; @@ -283,6 +293,7 @@ static inline void init_thread(struct target_pt_regs *regs, /* For uClinux PIC binaries. */ /* XXX: Linux does this only on ARM with no MMU (do we care ?) */ regs->ARM_r10 = infop->start_data; +#endif } #define ELF_NREG 18 diff --git a/linux-user/main.c b/linux-user/main.c index d3f4b97..2e3c903 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -3882,6 +3882,15 @@ int main(int argc, char **argv, char **envp) cpu_x86_load_seg(env, R_FS, 0); cpu_x86_load_seg(env, R_GS, 0); #endif +#elif defined(TARGET_ARM64) + { + int i; + for(i = 0; i < 31; i++) { + env->xregs[i] = regs->regs[i]; + } + env->pc = regs->pc; + env->sp = regs->sp; + } #elif defined(TARGET_ARM) { int i; diff --git a/target-arm/cpu.h b/target-arm/cpu.h index ec292c9..34cc00c 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -288,7 +288,11 @@ int cpu_arm_handle_mmu_fault (CPUARMState *env, target_ulong address, int rw, static inline void cpu_set_tls(CPUARMState *env, target_ulong newtls) { - env->cp15.c13_tls2 = newtls; + if (is_a64(env)) { + env->sr.tpidr_el0 = newtls; + } else { + env->cp15.c13_tls2 = newtls; + } } #define CPSR_M (0x1f) @@ -696,9 +700,17 @@ static inline int cpu_mmu_index (CPUARMState *env) #if defined(CONFIG_USER_ONLY) static inline void cpu_clone_regs(CPUARMState *env, target_ulong newsp) { - if (newsp) - env->regs[13] = newsp; - env->regs[0] = 0; + if (is_a64(env)) { + if (newsp) { + env->sp = newsp; + } + env->xregs[0] = 0; + } else { + if (newsp) { + env->regs[13] = newsp; + } + env->regs[0] = 0; + } } #endif