[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 11/12] linux-user: Add AArch64 support
From: |
Alexander Graf |
Subject: |
[Qemu-devel] [PATCH 11/12] linux-user: Add AArch64 support |
Date: |
Wed, 6 Mar 2013 03:01:19 +0100 |
This patch adds support for AArch64 in all the small corners of
linux-user and beyond.
Signed-off-by: Alexander Graf <address@hidden>
---
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
--
1.6.0.2
- [Qemu-devel] [PATCH 02/12] ARM: Export cpu_env, (continued)
- [Qemu-devel] [PATCH 05/12] AArch64: Add gdb stub, Alexander Graf, 2013/03/05
- [Qemu-devel] [PATCH 07/12] linux-user: AArch64 requires at least 3.8.0, Alexander Graf, 2013/03/05
- [Qemu-devel] [PATCH 11/12] linux-user: Add AArch64 support,
Alexander Graf <=
- [Qemu-devel] [PATCH 01/12] ARM: Extract the disas struct to a header file, Alexander Graf, 2013/03/05
- [Qemu-devel] [PATCH 06/12] linux-user: Don't treat aarch64 cpu names specially, Alexander Graf, 2013/03/05
- [Qemu-devel] [PATCH 08/12] linux-user: Add syscall handling for AArch64, Alexander Graf, 2013/03/05
- [Qemu-devel] [PATCH 10/12] linux-user: Add signal handling for AArch64, Alexander Graf, 2013/03/05
- [Qemu-devel] [PATCH 04/12] ARM: Add AArch64 translation stub, Alexander Graf, 2013/03/05