From 5836c3eccedb6dfab16b8f606f2de24b8938b69c Mon Sep 17 00:00:00 2001 From: Kito Cheng Date: Sat, 16 Mar 2019 01:20:46 +0000 Subject: [PATCH] RISC-V: linux-user support for RVE ABI This change checks elf_flags for EF_RISCV_RVE and if present uses the RVE linux syscall ABI which uses t0 for the syscall number instead of a7. Warn and exit if a non-RVE ABI binary is run on a cpu with the RVE extension as it is incompatible. Cc: Palmer Dabbelt Cc: Sagar Karandikar Cc: Bastian Koppelmann Cc: Alistair Francis Co-authored-by: Kito Cheng Co-authored-by: Michael Clark Signed-off-by: Michael Clark Signed-off-by: Alistair Francis Signed-off-by: Palmer Dabbelt --- linux-user/riscv/cpu_loop.c | 15 ++++++++++++++- target/riscv/cpu.h | 4 ++++ target/riscv/cpu_user.h | 3 ++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c index 4cf3e94632..a9bac4ca79 100644 --- a/linux-user/riscv/cpu_loop.c +++ b/linux-user/riscv/cpu_loop.c @@ -18,8 +18,10 @@ */ #include "qemu/osdep.h" +#include "qemu/error-report.h" #include "qemu.h" #include "cpu_loop-common.h" +#include "elf.h" void cpu_loop(CPURISCVState *env) { @@ -53,7 +55,8 @@ void cpu_loop(CPURISCVState *env) ret = 0; } else { ret = do_syscall(env, - env->gpr[xA7], + env->gpr[(env->elf_flags & EF_RISCV_RVE) + ? xT0 : xA7], env->gpr[xA0], env->gpr[xA1], env->gpr[xA2], @@ -113,6 +116,16 @@ void cpu_loop(CPURISCVState *env) void target_cpu_copy_regs(CPUArchState *env, struct target_pt_regs *regs) { + CPUState *cpu = ENV_GET_CPU(env); + TaskState *ts = cpu->opaque; + struct image_info *info = ts->info; + env->pc = regs->sepc; env->gpr[xSP] = regs->sp; + env->elf_flags = info->elf_flags; + + if ((env->misa & RVE) && !(env->elf_flags & EF_RISCV_RVE)) { + error_report("Incompatible ELF: RVE cpu requires RVE ABI binary"); + exit(EXIT_FAILURE); + } } diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index df43a0898d..20bce8742e 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -123,6 +123,10 @@ struct CPURISCVState { uint32_t features; +#ifdef CONFIG_USER_ONLY + uint32_t elf_flags; +#endif + #ifndef CONFIG_USER_ONLY target_ulong priv; target_ulong resetvec; diff --git a/target/riscv/cpu_user.h b/target/riscv/cpu_user.h index c2199610ab..52d380aa98 100644 --- a/target/riscv/cpu_user.h +++ b/target/riscv/cpu_user.h @@ -10,4 +10,5 @@ #define xA4 14 #define xA5 15 #define xA6 16 -#define xA7 17 /* syscall number goes here */ +#define xA7 17 /* syscall number for RVI ABI */ +#define xT0 5 /* syscall number for RVE ABI */