sim: enable pseudo instructions with varying pointer size
In this patch, Addr is subtituted by a struct wrapper (uint64_t) in the pseudo instruction functions. This enables a correct argument handling in systems where pointer size != 64 bit. Change-Id: Ie84b43b4ab8e6c0d38c7b6b16e19fc043110681b
This commit is contained in:
@@ -169,7 +169,8 @@ template <typename ABI, typename Arg>
|
||||
static Arg
|
||||
getArgument(ThreadContext *tc, typename ABI::State &state)
|
||||
{
|
||||
return Argument<ABI, Arg>::get(tc, state);
|
||||
auto arg = Argument<ABI, Arg>::get(tc, state);
|
||||
return *reinterpret_cast<Arg*>(&arg);
|
||||
}
|
||||
|
||||
} // namespace guest_abi
|
||||
|
||||
@@ -256,27 +256,27 @@ loadsymbol(ThreadContext *tc)
|
||||
}
|
||||
|
||||
void
|
||||
addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr)
|
||||
addsymbol(ThreadContext *tc, GuestAddr addr, GuestAddr symbolAddr)
|
||||
{
|
||||
DPRINTF(PseudoInst, "pseudo_inst::addsymbol(0x%x, 0x%x)\n",
|
||||
addr, symbolAddr);
|
||||
addr.addr, symbolAddr.addr);
|
||||
|
||||
std::string symbol;
|
||||
TranslatingPortProxy fs_proxy(tc);
|
||||
SETranslatingPortProxy se_proxy(tc);
|
||||
PortProxy &virt_proxy = FullSystem ? fs_proxy : se_proxy;
|
||||
|
||||
virt_proxy.readString(symbol, symbolAddr);
|
||||
virt_proxy.readString(symbol, symbolAddr.addr);
|
||||
|
||||
DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr);
|
||||
DPRINTF(Loader, "Loaded symbol: %s @ %#llx\n", symbol, addr.addr);
|
||||
|
||||
tc->getSystemPtr()->workload->insertSymbol(
|
||||
{ loader::Symbol::Binding::Global,
|
||||
loader::Symbol::SymbolType::Function, symbol, addr }
|
||||
loader::Symbol::SymbolType::Function, symbol, addr.addr }
|
||||
);
|
||||
loader::debugSymbolTable.insert(
|
||||
{ loader::Symbol::Binding::Global,
|
||||
loader::Symbol::SymbolType::Function, symbol, addr }
|
||||
loader::Symbol::SymbolType::Function, symbol, addr.addr }
|
||||
);
|
||||
}
|
||||
|
||||
@@ -368,10 +368,10 @@ m5checkpoint(ThreadContext *tc, Tick delay, Tick period)
|
||||
}
|
||||
|
||||
uint64_t
|
||||
readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset)
|
||||
readfile(ThreadContext *tc, GuestAddr vaddr, uint64_t len, uint64_t offset)
|
||||
{
|
||||
DPRINTF(PseudoInst, "pseudo_inst::readfile(0x%x, 0x%x, 0x%x)\n",
|
||||
vaddr, len, offset);
|
||||
vaddr.addr, len, offset);
|
||||
|
||||
const std::string &file = tc->getSystemPtr()->params().readfile;
|
||||
if (file.empty()) {
|
||||
@@ -404,17 +404,17 @@ readfile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset)
|
||||
SETranslatingPortProxy se_proxy(tc);
|
||||
PortProxy &virt_proxy = FullSystem ? fs_proxy : se_proxy;
|
||||
|
||||
virt_proxy.writeBlob(vaddr, buf, result);
|
||||
virt_proxy.writeBlob(vaddr.addr, buf, result);
|
||||
delete [] buf;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
writefile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset,
|
||||
Addr filename_addr)
|
||||
writefile(ThreadContext *tc, GuestAddr vaddr, uint64_t len, uint64_t offset,
|
||||
GuestAddr filename_addr)
|
||||
{
|
||||
DPRINTF(PseudoInst, "pseudo_inst::writefile(0x%x, 0x%x, 0x%x, 0x%x)\n",
|
||||
vaddr, len, offset, filename_addr);
|
||||
vaddr.addr, len, offset, filename_addr.addr);
|
||||
|
||||
// copy out target filename
|
||||
std::string filename;
|
||||
@@ -422,7 +422,7 @@ writefile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset,
|
||||
SETranslatingPortProxy se_proxy(tc);
|
||||
PortProxy &virt_proxy = FullSystem ? fs_proxy : se_proxy;
|
||||
|
||||
virt_proxy.readString(filename, filename_addr);
|
||||
virt_proxy.readString(filename, filename_addr.addr);
|
||||
|
||||
OutputStream *out;
|
||||
if (offset == 0) {
|
||||
@@ -448,7 +448,7 @@ writefile(ThreadContext *tc, Addr vaddr, uint64_t len, uint64_t offset,
|
||||
// copy out data and write to file
|
||||
char *buf = new char[len];
|
||||
|
||||
virt_proxy.readBlob(vaddr, buf, len);
|
||||
virt_proxy.readBlob(vaddr.addr, buf, len);
|
||||
os->write(buf, len);
|
||||
if (os->fail() || os->bad())
|
||||
panic("Error while doing writefile!\n");
|
||||
|
||||
@@ -64,18 +64,29 @@ decodeAddrOffset(Addr offset, uint8_t &func)
|
||||
func = bits(offset, 15, 8);
|
||||
}
|
||||
|
||||
struct GuestAddr
|
||||
{
|
||||
uint64_t addr;
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& os, const GuestAddr addr)
|
||||
{
|
||||
return os << addr.addr;
|
||||
}
|
||||
|
||||
void arm(ThreadContext *tc);
|
||||
void quiesce(ThreadContext *tc);
|
||||
void quiesceSkip(ThreadContext *tc);
|
||||
void quiesceNs(ThreadContext *tc, uint64_t ns);
|
||||
void quiesceCycles(ThreadContext *tc, uint64_t cycles);
|
||||
uint64_t quiesceTime(ThreadContext *tc);
|
||||
uint64_t readfile(ThreadContext *tc, Addr vaddr, uint64_t len,
|
||||
uint64_t readfile(ThreadContext *tc, GuestAddr vaddr, uint64_t len,
|
||||
uint64_t offset);
|
||||
uint64_t writefile(ThreadContext *tc, Addr vaddr, uint64_t len,
|
||||
uint64_t offset, Addr filenameAddr);
|
||||
uint64_t writefile(ThreadContext *tc, GuestAddr vaddr, uint64_t len,
|
||||
uint64_t offset, GuestAddr filenameAddr);
|
||||
void loadsymbol(ThreadContext *xc);
|
||||
void addsymbol(ThreadContext *tc, Addr addr, Addr symbolAddr);
|
||||
void addsymbol(ThreadContext *tc, GuestAddr addr, GuestAddr symbolAddr);
|
||||
uint64_t initParam(ThreadContext *xc, uint64_t key_str1, uint64_t key_str2);
|
||||
uint64_t rpns(ThreadContext *tc);
|
||||
void wakeCPU(ThreadContext *tc, uint64_t cpuid);
|
||||
@@ -95,6 +106,7 @@ void m5Syscall(ThreadContext *tc);
|
||||
void togglesync(ThreadContext *tc);
|
||||
void triggerWorkloadEvent(ThreadContext *tc);
|
||||
|
||||
|
||||
/**
|
||||
* Execute a decoded M5 pseudo instruction
|
||||
*
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include "base/types.hh"
|
||||
#include "cpu/thread_context.hh"
|
||||
#include "sim/guest_abi.hh"
|
||||
#include "sim/pseudo_inst.hh"
|
||||
#include "sim/syscall_return.hh"
|
||||
|
||||
namespace gem5
|
||||
@@ -78,19 +79,22 @@ struct GenericSyscallABI32 : public GenericSyscallABI
|
||||
namespace guest_abi
|
||||
{
|
||||
|
||||
using namespace pseudo_inst;
|
||||
|
||||
// For 64 bit systems, return syscall args directly.
|
||||
template <typename ABI, typename Arg>
|
||||
struct Argument<ABI, Arg,
|
||||
typename std::enable_if_t<
|
||||
std::is_base_of_v<GenericSyscallABI64, ABI> &&
|
||||
std::is_integral_v<Arg>>>
|
||||
(std::is_integral_v<Arg> || std::is_same<Arg,GuestAddr>::value)>>
|
||||
{
|
||||
static Arg
|
||||
get(ThreadContext *tc, typename ABI::State &state)
|
||||
{
|
||||
panic_if(state >= ABI::ArgumentRegs.size(),
|
||||
"Ran out of syscall argument registers.");
|
||||
return tc->getReg(ABI::ArgumentRegs[state++]);
|
||||
auto arg = tc->getReg(ABI::ArgumentRegs[state++]);
|
||||
return *reinterpret_cast<Arg*>(&arg);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user