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