diff options
Diffstat (limited to 'linux-user/loongarch64')
| -rw-r--r-- | linux-user/loongarch64/cpu_loop.c | 11 | ||||
| -rw-r--r-- | linux-user/loongarch64/elfload.c | 78 | ||||
| -rw-r--r-- | linux-user/loongarch64/target_elf.h | 21 | ||||
| -rw-r--r-- | linux-user/loongarch64/target_ptrace.h | 15 | ||||
| -rw-r--r-- | linux-user/loongarch64/target_syscall.h | 23 |
5 files changed, 114 insertions, 34 deletions
diff --git a/linux-user/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c index ec8a06c88c..a0a4cbb7cc 100644 --- a/linux-user/loongarch64/cpu_loop.c +++ b/linux-user/loongarch64/cpu_loop.c @@ -120,13 +120,10 @@ void cpu_loop(CPULoongArchState *env) } } -void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs) +void init_main_thread(CPUState *cs, struct image_info *info) { - int i; - - for (i = 0; i < 32; i++) { - env->gpr[i] = regs->regs[i]; - } - env->pc = regs->csr.era; + CPUArchState *env = cpu_env(cs); + env->pc = info->entry; + env->gpr[3] = info->start_stack; } diff --git a/linux-user/loongarch64/elfload.c b/linux-user/loongarch64/elfload.c new file mode 100644 index 0000000000..ce3bd0c607 --- /dev/null +++ b/linux-user/loongarch64/elfload.c @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include "qemu/osdep.h" +#include "qemu.h" +#include "loader.h" +#include "target_elf.h" + + +const char *get_elf_cpu_model(uint32_t eflags) +{ + return "la464"; +} + +/* See arch/loongarch/include/uapi/asm/hwcap.h */ +enum { + HWCAP_LOONGARCH_CPUCFG = (1 << 0), + HWCAP_LOONGARCH_LAM = (1 << 1), + HWCAP_LOONGARCH_UAL = (1 << 2), + HWCAP_LOONGARCH_FPU = (1 << 3), + HWCAP_LOONGARCH_LSX = (1 << 4), + HWCAP_LOONGARCH_LASX = (1 << 5), + HWCAP_LOONGARCH_CRC32 = (1 << 6), + HWCAP_LOONGARCH_COMPLEX = (1 << 7), + HWCAP_LOONGARCH_CRYPTO = (1 << 8), + HWCAP_LOONGARCH_LVZ = (1 << 9), + HWCAP_LOONGARCH_LBT_X86 = (1 << 10), + HWCAP_LOONGARCH_LBT_ARM = (1 << 11), + HWCAP_LOONGARCH_LBT_MIPS = (1 << 12), +}; + +abi_ulong get_elf_hwcap(CPUState *cs) +{ + LoongArchCPU *cpu = LOONGARCH_CPU(cs); + abi_ulong hwcaps = 0; + + hwcaps |= HWCAP_LOONGARCH_CRC32; + + if (FIELD_EX32(cpu->env.cpucfg[1], CPUCFG1, UAL)) { + hwcaps |= HWCAP_LOONGARCH_UAL; + } + + if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, FP)) { + hwcaps |= HWCAP_LOONGARCH_FPU; + } + + if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LAM)) { + hwcaps |= HWCAP_LOONGARCH_LAM; + } + + if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LSX)) { + hwcaps |= HWCAP_LOONGARCH_LSX; + } + + if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LASX)) { + hwcaps |= HWCAP_LOONGARCH_LASX; + } + + return hwcaps; +} + +const char *get_elf_platform(CPUState *cs) +{ + return "loongarch"; +} + +#define tswapreg(ptr) tswapal(ptr) + +void elf_core_copy_regs(target_elf_gregset_t *r, const CPULoongArchState *env) +{ + r->pt.regs[0] = 0; + + for (int i = 1; i < ARRAY_SIZE(env->gpr); i++) { + r->pt.regs[i] = tswapreg(env->gpr[i]); + } + + r->pt.csr_era = tswapreg(env->pc); + r->pt.csr_badv = tswapreg(env->CSR_BADV); +} diff --git a/linux-user/loongarch64/target_elf.h b/linux-user/loongarch64/target_elf.h index 95c3f05a46..3aa8c83958 100644 --- a/linux-user/loongarch64/target_elf.h +++ b/linux-user/loongarch64/target_elf.h @@ -5,8 +5,21 @@ #ifndef LOONGARCH_TARGET_ELF_H #define LOONGARCH_TARGET_ELF_H -static inline const char *cpu_get_model(uint32_t eflags) -{ - return "la464"; -} + +#include "target_ptrace.h" + +#define ELF_CLASS ELFCLASS64 +#define ELF_MACHINE EM_LOONGARCH +#define EXSTACK_DEFAULT true +#define VDSO_HEADER "vdso.c.inc" + +#define HAVE_ELF_HWCAP 1 +#define HAVE_ELF_PLATFORM 1 +#define HAVE_ELF_CORE_DUMP 1 + +/* See linux kernel: arch/loongarch/include/asm/elf.h */ +typedef struct target_elf_gregset_t { + struct target_user_pt_regs pt; +} target_elf_gregset_t; + #endif diff --git a/linux-user/loongarch64/target_ptrace.h b/linux-user/loongarch64/target_ptrace.h new file mode 100644 index 0000000000..2578e09207 --- /dev/null +++ b/linux-user/loongarch64/target_ptrace.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef LOONGARCH64_TARGET_PTRACE_H +#define LOONGARCH64_TARGET_PTRACE_H + +/* See arch/loongarch/include/uapi/asm/ptrace.h. */ +struct target_user_pt_regs { + abi_ulong regs[32]; + abi_ulong orig_a0; + abi_ulong csr_era; + abi_ulong csr_badv; + abi_ulong reserved[10]; +}; + +#endif /* LOONGARCH64_TARGET_PTRACE_H */ diff --git a/linux-user/loongarch64/target_syscall.h b/linux-user/loongarch64/target_syscall.h index 39f229bb9c..f7ced7b2be 100644 --- a/linux-user/loongarch64/target_syscall.h +++ b/linux-user/loongarch64/target_syscall.h @@ -8,29 +8,6 @@ #include "qemu/units.h" -/* - * this struct defines the way the registers are stored on the - * stack during a system call. - */ - -struct target_pt_regs { - /* Saved main processor registers. */ - target_ulong regs[32]; - - /* Saved special registers. */ - struct { - target_ulong era; - target_ulong badv; - target_ulong crmd; - target_ulong prmd; - target_ulong euen; - target_ulong ecfg; - target_ulong estat; - } csr; - target_ulong orig_a0; - target_ulong __last[0]; -}; - #define UNAME_MACHINE "loongarch64" #define UNAME_MINIMUM_RELEASE "5.19.0" |