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 <noreply+kokoro@google.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Reviewed-by: Yu-hsin Wang <yuhsingw@google.com>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
This commit is contained in:
Roger Chang
2022-11-15 13:48:53 +00:00
parent e4be93b55f
commit f2562152e8
7 changed files with 67 additions and 10 deletions

View File

@@ -38,8 +38,12 @@
def format M5Op() {{
iop = InstObjParams(name, Name, 'PseudoOp', '''
uint64_t result;
pseudo_inst::pseudoInst<RegABI64>(xc->tcBase(), M5FUNC, result);
a0 = result''',
if (machInst.rv_type == RV32) {
pseudo_inst::pseudoInst<RegABI32>(xc->tcBase(), M5FUNC, result);
} else {
pseudo_inst::pseudoInst<RegABI64>(xc->tcBase(), M5FUNC, result);
}
a0 = rvSext(result)''',
['IsNonSpeculative', 'IsSerializeAfter'])
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)

View File

@@ -371,8 +371,10 @@ class RiscvLinux32 : public RiscvLinux, public OpenFlagTable<RiscvLinux32>
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));
}
};

View File

@@ -123,7 +123,7 @@ unameFunc32(SyscallDesc *desc, ThreadContext *tc, VPtr<Linux::utsname> name)
return 0;
}
SyscallDescTable<SEWorkload::SyscallABI> EmuLinux::syscallDescs64 = {
SyscallDescTable<SEWorkload::SyscallABI64> EmuLinux::syscallDescs64 = {
{ 0, "io_setup" },
{ 1, "io_destroy" },
{ 2, "io_submit" },
@@ -462,7 +462,7 @@ SyscallDescTable<SEWorkload::SyscallABI> EmuLinux::syscallDescs64 = {
{ 2011, "getmainvars" }
};
SyscallDescTable<SEWorkload::SyscallABI> EmuLinux::syscallDescs32 = {
SyscallDescTable<SEWorkload::SyscallABI32> EmuLinux::syscallDescs32 = {
{ 0, "io_setup" },
{ 1, "io_destroy" },
{ 2, "io_submit" },

View File

@@ -47,10 +47,10 @@ class EmuLinux : public SEWorkload
protected:
/// 64 bit syscall descriptors, indexed by call number.
static SyscallDescTable<SEWorkload::SyscallABI> syscallDescs64;
static SyscallDescTable<SEWorkload::SyscallABI64> syscallDescs64;
/// 32 bit syscall descriptors, indexed by call number.
static SyscallDescTable<SEWorkload::SyscallABI> syscallDescs32;
static SyscallDescTable<SEWorkload::SyscallABI32> syscallDescs32;
public:
using Params = RiscvEmuLinuxParams;

View File

@@ -39,5 +39,11 @@ const std::vector<RegId> RegABI64::ArgumentRegs = {
int_reg::A4, int_reg::A5, int_reg::A6
};
const std::vector<RegId> 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

View File

@@ -44,7 +44,36 @@ struct RegABI64 : public GenericSyscallABI64
static const std::vector<RegId> ArgumentRegs;
};
struct RegABI32 : public GenericSyscallABI32
{
static const std::vector<RegId> 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 <typename ABI, typename Arg>
struct Argument<ABI, Arg,
typename std::enable_if_t<
std::is_base_of_v<RiscvISA::RegABI32, ABI> &&
std::is_integral_v<Arg> &&
ABI::template IsWideV<Arg>>>
{
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__

View File

@@ -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<RiscvISA::SEWorkload::SyscallABI, SyscallReturn>
struct Result<RiscvISA::SEWorkload::SyscallABI64, SyscallReturn>
{
static void
store(ThreadContext *tc, const SyscallReturn &ret)
@@ -85,6 +85,22 @@ struct Result<RiscvISA::SEWorkload::SyscallABI, SyscallReturn>
}
};
template <>
struct Result<RiscvISA::SEWorkload::SyscallABI32, SyscallReturn>
{
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