From f2562152e800a8a4af3633e64ca83733cf024abb Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Tue, 15 Nov 2022 13:48:53 +0000 Subject: [PATCH] arch-riscv,sim-se: Support RV32 register ABI call 1. Add RegABI32, SyscallABI32 2. Support parse function arguments to host and save result to registers 3. Add write to ThreadPointerReg in archClone 4. Support RV32 M5Op syscall Change-Id: Ie327b517f41b5d633d2741b6abb5be955281c838 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/65532 Tested-by: kokoro Maintainer: Jason Lowe-Power Reviewed-by: Yu-hsin Wang Reviewed-by: Jason Lowe-Power --- src/arch/riscv/isa/formats/m5ops.isa | 8 ++++++-- src/arch/riscv/linux/linux.hh | 4 +++- src/arch/riscv/linux/se_workload.cc | 4 ++-- src/arch/riscv/linux/se_workload.hh | 4 ++-- src/arch/riscv/reg_abi.cc | 6 ++++++ src/arch/riscv/reg_abi.hh | 29 ++++++++++++++++++++++++++++ src/arch/riscv/se_workload.hh | 22 ++++++++++++++++++--- 7 files changed, 67 insertions(+), 10 deletions(-) diff --git a/src/arch/riscv/isa/formats/m5ops.isa b/src/arch/riscv/isa/formats/m5ops.isa index edc965a7f7..034a0dd2b5 100644 --- a/src/arch/riscv/isa/formats/m5ops.isa +++ b/src/arch/riscv/isa/formats/m5ops.isa @@ -38,8 +38,12 @@ def format M5Op() {{ iop = InstObjParams(name, Name, 'PseudoOp', ''' uint64_t result; - pseudo_inst::pseudoInst(xc->tcBase(), M5FUNC, result); - a0 = result''', + if (machInst.rv_type == RV32) { + pseudo_inst::pseudoInst(xc->tcBase(), M5FUNC, result); + } else { + pseudo_inst::pseudoInst(xc->tcBase(), M5FUNC, result); + } + a0 = rvSext(result)''', ['IsNonSpeculative', 'IsSerializeAfter']) header_output = BasicDeclare.subst(iop) decoder_output = BasicConstructor.subst(iop) diff --git a/src/arch/riscv/linux/linux.hh b/src/arch/riscv/linux/linux.hh index b0721836a5..de8bccc85e 100644 --- a/src/arch/riscv/linux/linux.hh +++ b/src/arch/riscv/linux/linux.hh @@ -371,8 +371,10 @@ class RiscvLinux32 : public RiscvLinux, public OpenFlagTable uint64_t stack, uint64_t tls) { ctc->getIsaPtr()->copyRegsFrom(ptc); + if (flags & TGT_CLONE_SETTLS) + ctc->setReg(RiscvISA::ThreadPointerReg, sext<32>(tls)); if (stack) - ctc->setReg(RiscvISA::StackPointerReg, stack); + ctc->setReg(RiscvISA::StackPointerReg, sext<32>(stack)); } }; diff --git a/src/arch/riscv/linux/se_workload.cc b/src/arch/riscv/linux/se_workload.cc index dac28071f4..952fe7140f 100644 --- a/src/arch/riscv/linux/se_workload.cc +++ b/src/arch/riscv/linux/se_workload.cc @@ -123,7 +123,7 @@ unameFunc32(SyscallDesc *desc, ThreadContext *tc, VPtr name) return 0; } -SyscallDescTable EmuLinux::syscallDescs64 = { +SyscallDescTable EmuLinux::syscallDescs64 = { { 0, "io_setup" }, { 1, "io_destroy" }, { 2, "io_submit" }, @@ -462,7 +462,7 @@ SyscallDescTable EmuLinux::syscallDescs64 = { { 2011, "getmainvars" } }; -SyscallDescTable EmuLinux::syscallDescs32 = { +SyscallDescTable EmuLinux::syscallDescs32 = { { 0, "io_setup" }, { 1, "io_destroy" }, { 2, "io_submit" }, diff --git a/src/arch/riscv/linux/se_workload.hh b/src/arch/riscv/linux/se_workload.hh index 41a3d41f61..4ec818b2ab 100644 --- a/src/arch/riscv/linux/se_workload.hh +++ b/src/arch/riscv/linux/se_workload.hh @@ -47,10 +47,10 @@ class EmuLinux : public SEWorkload protected: /// 64 bit syscall descriptors, indexed by call number. - static SyscallDescTable syscallDescs64; + static SyscallDescTable syscallDescs64; /// 32 bit syscall descriptors, indexed by call number. - static SyscallDescTable syscallDescs32; + static SyscallDescTable syscallDescs32; public: using Params = RiscvEmuLinuxParams; diff --git a/src/arch/riscv/reg_abi.cc b/src/arch/riscv/reg_abi.cc index b9827f74cf..3d48056b14 100644 --- a/src/arch/riscv/reg_abi.cc +++ b/src/arch/riscv/reg_abi.cc @@ -39,5 +39,11 @@ const std::vector RegABI64::ArgumentRegs = { int_reg::A4, int_reg::A5, int_reg::A6 }; +const std::vector RegABI32::ArgumentRegs = { + int_reg::A0, int_reg::A1, int_reg::A2, int_reg::A3, + int_reg::A4, int_reg::A5, int_reg::A6 +}; + + } // namespace RiscvISA } // namespace gem5 diff --git a/src/arch/riscv/reg_abi.hh b/src/arch/riscv/reg_abi.hh index 3419c31222..4c965321f7 100644 --- a/src/arch/riscv/reg_abi.hh +++ b/src/arch/riscv/reg_abi.hh @@ -44,7 +44,36 @@ struct RegABI64 : public GenericSyscallABI64 static const std::vector ArgumentRegs; }; +struct RegABI32 : public GenericSyscallABI32 +{ + static const std::vector ArgumentRegs; +}; + } // namespace RiscvISA + +namespace guest_abi +{ + +// This method will be used if the size of argument type of function is +// greater than 4 for Riscv 32. +template +struct Argument && + std::is_integral_v && + ABI::template IsWideV>> +{ + static Arg + get(ThreadContext *tc, typename ABI::State &state) + { + panic_if(state >= ABI::ArgumentRegs.size(), + "Ran out of syscall argument registers."); + return bits(tc->getReg(ABI::ArgumentRegs[state++]), 31, 0); + } +}; + +} + } // namespace gem5 #endif // __ARCH_RISCV_REG_ABI_HH__ diff --git a/src/arch/riscv/se_workload.hh b/src/arch/riscv/se_workload.hh index 9ae3be4c05..dd18a92905 100644 --- a/src/arch/riscv/se_workload.hh +++ b/src/arch/riscv/se_workload.hh @@ -60,8 +60,8 @@ class SEWorkload : public gem5::SEWorkload loader::Arch getArch() const override { return loader::Riscv64; } - //FIXME RISCV needs to handle 64 bit arguments in its 32 bit ISA. - using SyscallABI = RegABI64; + using SyscallABI64 = RegABI64; + using SyscallABI32 = RegABI32; }; } // namespace RiscvISA @@ -70,7 +70,7 @@ namespace guest_abi { template <> -struct Result +struct Result { static void store(ThreadContext *tc, const SyscallReturn &ret) @@ -85,6 +85,22 @@ struct Result } }; +template <> +struct Result +{ + static void + store(ThreadContext *tc, const SyscallReturn &ret) + { + if (ret.successful()) { + // no error + tc->setReg(RiscvISA::ReturnValueReg, sext<32>(ret.returnValue())); + } else { + // got an error, return details + tc->setReg(RiscvISA::ReturnValueReg, sext<32>(ret.encodedValue())); + } + } +}; + } // namespace guest_abi } // namespace gem5