linux-user: Add LoongArch elf support
Signed-off-by: Song Gao <gaosong@loongson.cn> Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Message-Id: <20220624031049.1716097-4-gaosong@loongson.cn> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
9d5cd6587a
commit
3418fe25fa
@ -922,6 +922,97 @@ 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)
|
||||
{
|
||||
/*Set crmd PG,DA = 1,0 */
|
||||
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];
|
||||
|
||||
enum {
|
||||
TARGET_EF_R0 = 0,
|
||||
TARGET_EF_CSR_ERA = TARGET_EF_R0 + 33,
|
||||
TARGET_EF_CSR_BADV = TARGET_EF_R0 + 34,
|
||||
};
|
||||
|
||||
static void elf_core_copy_regs(target_elf_gregset_t *regs,
|
||||
const CPULoongArchState *env)
|
||||
{
|
||||
int i;
|
||||
|
||||
(*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_BADV] = tswapreg(env->CSR_BADV);
|
||||
}
|
||||
|
||||
#define USE_ELF_CORE_DUMP
|
||||
#define ELF_EXEC_PAGESIZE 4096
|
||||
|
||||
#define ELF_HWCAP get_elf_hwcap()
|
||||
|
||||
/* 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),
|
||||
};
|
||||
|
||||
static uint32_t get_elf_hwcap(void)
|
||||
{
|
||||
LoongArchCPU *cpu = LOONGARCH_CPU(thread_cpu);
|
||||
uint32_t 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;
|
||||
}
|
||||
|
||||
return hwcaps;
|
||||
}
|
||||
|
||||
#define ELF_PLATFORM "loongarch"
|
||||
|
||||
#endif /* TARGET_LOONGARCH64 */
|
||||
|
||||
#ifdef TARGET_MIPS
|
||||
|
||||
#define ELF_START_MMAP 0x80000000
|
||||
|
12
linux-user/loongarch64/target_elf.h
Normal file
12
linux-user/loongarch64/target_elf.h
Normal file
@ -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 "la464";
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user