diff mbox series

[v13,20/26] linux-user: Add LoongArch elf support

Message ID 1638610165-15036-21-git-send-email-gaosong@loongson.cn
State New
Headers show
Series Add LoongArch linux-user emulation support | expand

Commit Message

gaosong Dec. 4, 2021, 9:29 a.m. UTC
Signed-off-by: Song Gao <gaosong@loongson.cn>
Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/elf.h                       |  2 ++
 linux-user/elfload.c                | 58 +++++++++++++++++++++++++++++++++++++
 linux-user/loongarch64/target_elf.h | 12 ++++++++
 3 files changed, 72 insertions(+)
 create mode 100644 linux-user/loongarch64/target_elf.h

Comments

Philippe Mathieu-Daudé Dec. 4, 2021, 5:05 p.m. UTC | #1
On 12/4/21 10:29, Song Gao wrote:
> Signed-off-by: Song Gao <gaosong@loongson.cn>
> Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/elf.h                       |  2 ++
>  linux-user/elfload.c                | 58 +++++++++++++++++++++++++++++++++++++
>  linux-user/loongarch64/target_elf.h | 12 ++++++++
>  3 files changed, 72 insertions(+)
>  create mode 100644 linux-user/loongarch64/target_elf.h

> +/* See linux kernel: arch/loongarch/include/asm/reg.h.  */
> +enum {
> +    TARGET_EF_R0 = 0,
> +    TARGET_EF_CSR_ERA = TARGET_EF_R0 + 32,
> +    TARGET_EF_CSR_BADVADDR = TARGET_EF_R0 + 33,
> +};
> +
> +/* See linux kernel: arch/loongarch/kernel/process.c:loongarch_dump_regs64. */
> +static void elf_core_copy_regs(target_elf_gregset_t *regs,
> +                               const CPULoongArchState *env)
> +{
> +    int i;
> +
> +    for (i = 0; i < TARGET_EF_R0; i++) {
> +        (*regs)[i] = 0;
> +    }

Dead code... Removing it:

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>

> +    (*regs)[TARGET_EF_R0] = 0;
> +
> +    for (i = 1; i < ARRAY_SIZE(env->gpr); i++) {
> +        (*regs)[TARGET_EF_R0 + i] = tswapreg(env->gpr[i]);
> +    }
> +
> +    (*regs)[TARGET_EF_CSR_ERA] = tswapreg(env->pc);
> +    (*regs)[TARGET_EF_CSR_BADVADDR] = tswapreg(env->badaddr);
> +}
diff mbox series

Patch

diff --git a/include/elf.h b/include/elf.h
index 811bf4a..3a4bcb6 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -182,6 +182,8 @@  typedef struct mips_elf_abiflags_v0 {
 
 #define EM_NANOMIPS     249     /* Wave Computing nanoMIPS */
 
+#define EM_LOONGARCH    258     /* LoongArch */
+
 /*
  * This is an interim value that we will use until the committee comes
  * up with a final number.
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 767f54c..841ea18 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -914,6 +914,64 @@  static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUPPCState *en
 
 #endif
 
+#ifdef TARGET_LOONGARCH64
+
+#define ELF_START_MMAP 0x80000000
+
+#define ELF_CLASS   ELFCLASS64
+#define ELF_ARCH    EM_LOONGARCH
+
+#define elf_check_arch(x) ((x) == EM_LOONGARCH)
+static inline void init_thread(struct target_pt_regs *regs,
+                               struct image_info *infop)
+{
+    regs->csr_crmd = 2 << 3;
+    regs->csr_era = infop->entry;
+    regs->regs[3] = infop->start_stack;
+}
+
+/* See linux kernel: arch/loongarch/include/asm/elf.h.  */
+#define ELF_NREG 45
+typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
+
+/* See linux kernel: arch/loongarch/include/asm/reg.h.  */
+enum {
+    TARGET_EF_R0 = 0,
+    TARGET_EF_CSR_ERA = TARGET_EF_R0 + 32,
+    TARGET_EF_CSR_BADVADDR = TARGET_EF_R0 + 33,
+};
+
+/* See linux kernel: arch/loongarch/kernel/process.c:loongarch_dump_regs64. */
+static void elf_core_copy_regs(target_elf_gregset_t *regs,
+                               const CPULoongArchState *env)
+{
+    int i;
+
+    for (i = 0; i < TARGET_EF_R0; i++) {
+        (*regs)[i] = 0;
+    }
+    (*regs)[TARGET_EF_R0] = 0;
+
+    for (i = 1; i < ARRAY_SIZE(env->gpr); i++) {
+        (*regs)[TARGET_EF_R0 + i] = tswapreg(env->gpr[i]);
+    }
+
+    (*regs)[TARGET_EF_CSR_ERA] = tswapreg(env->pc);
+    (*regs)[TARGET_EF_CSR_BADVADDR] = tswapreg(env->badaddr);
+}
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE        4096
+
+#define ELF_HWCAP get_elf_hwcap()
+
+static uint32_t get_elf_hwcap(void)
+{
+    return 0;
+}
+
+#endif /* TARGET_LOONGARCH64 */
+
 #ifdef TARGET_MIPS
 
 #define ELF_START_MMAP 0x80000000
diff --git a/linux-user/loongarch64/target_elf.h b/linux-user/loongarch64/target_elf.h
new file mode 100644
index 0000000..3c690bb
--- /dev/null
+++ b/linux-user/loongarch64/target_elf.h
@@ -0,0 +1,12 @@ 
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (c) 2021 Loongson Technology Corporation Limited
+ */
+
+#ifndef LOONGARCH_TARGET_ELF_H
+#define LOONGARCH_TARGET_ELF_H
+static inline const char *cpu_get_model(uint32_t eflags)
+{
+    return "Loongson-3A5000";
+}
+#endif