fastmodel: Add an address translation mechanism to the ThreadContext.
This will be used by the TLB to do the actual translation. Unfortunately there isn't a great way to tell what translation type to use, so we just go through all of them for now. The ARM subclass might specialize and figure out which address spaces to use based on control register state. Change-Id: Id1fcad66554acf9d69af683917b3c2834f825da0 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/22118 Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
|
||||
#include "arch/arm/fastmodel/iris/arm/thread_context.hh"
|
||||
|
||||
#include "arch/arm/fastmodel/iris/memory_spaces.hh"
|
||||
#include "iris/detail/IrisCppAdapter.h"
|
||||
#include "iris/detail/IrisObjects.h"
|
||||
|
||||
@@ -43,6 +44,43 @@ ArmThreadContext::ArmThreadContext(
|
||||
vecRegs(TheISA::NumVecRegs), pcRscId(iris::IRIS_UINT64_MAX)
|
||||
{}
|
||||
|
||||
bool
|
||||
ArmThreadContext::translateAddress(Addr &paddr, Addr vaddr)
|
||||
{
|
||||
// Determine what memory spaces are currently active.
|
||||
CanonicalMsn in_msn;
|
||||
switch (currEL(this)) {
|
||||
case EL3:
|
||||
in_msn = SecureMonitorMsn;
|
||||
break;
|
||||
case EL2:
|
||||
in_msn = NsHypMsn;
|
||||
break;
|
||||
default:
|
||||
in_msn = GuestMsn;
|
||||
break;
|
||||
}
|
||||
|
||||
CanonicalMsn out_msn = inSecureState(this) ?
|
||||
PhysicalMemorySecureMsn : PhysicalMemoryNonSecureMsn;
|
||||
|
||||
// Figure out what memory spaces match the canonical numbers we need.
|
||||
iris::MemorySpaceId in = iris::IRIS_UINT64_MAX;
|
||||
iris::MemorySpaceId out = iris::IRIS_UINT64_MAX;
|
||||
|
||||
for (auto &space: memorySpaces) {
|
||||
if (space.canonicalMsn == in_msn)
|
||||
in = space.spaceId;
|
||||
else if (space.canonicalMsn == out_msn)
|
||||
out = space.spaceId;
|
||||
}
|
||||
|
||||
panic_if(in == iris::IRIS_UINT64_MAX || out == iris::IRIS_UINT64_MAX,
|
||||
"Canonical IRIS memory space numbers not found.");
|
||||
|
||||
return ThreadContext::translateAddress(paddr, out, vaddr, in);
|
||||
}
|
||||
|
||||
void
|
||||
ArmThreadContext::initFromIrisInstance(const ResourceMap &resources)
|
||||
{
|
||||
|
||||
@@ -55,6 +55,8 @@ class ArmThreadContext : public Iris::ThreadContext
|
||||
iris::IrisConnectionInterface *iris_if,
|
||||
const std::string &iris_path);
|
||||
|
||||
bool translateAddress(Addr &paddr, Addr vaddr) override;
|
||||
|
||||
void initFromIrisInstance(const ResourceMap &resources) override;
|
||||
|
||||
TheISA::PCState pcState() const override;
|
||||
|
||||
@@ -43,6 +43,9 @@ ThreadContext::initFromIrisInstance(const ResourceMap &resources)
|
||||
_status = enabled ? Active : Suspended;
|
||||
|
||||
suspend();
|
||||
|
||||
call().memory_getMemorySpaces(_instId, memorySpaces);
|
||||
call().memory_getUsefulAddressTranslations(_instId, translations);
|
||||
}
|
||||
|
||||
iris::ResourceId
|
||||
@@ -231,6 +234,36 @@ ThreadContext::~ThreadContext()
|
||||
client.unregisterEventCallback("ec_IRIS_SIMULATION_TIME_EVENT");
|
||||
}
|
||||
|
||||
bool
|
||||
ThreadContext::translateAddress(Addr &paddr, iris::MemorySpaceId p_space,
|
||||
Addr vaddr, iris::MemorySpaceId v_space)
|
||||
{
|
||||
iris::MemoryAddressTranslationResult result;
|
||||
auto ret = noThrow().memory_translateAddress(
|
||||
_instId, result, v_space, vaddr, p_space);
|
||||
|
||||
if (ret != iris::E_ok) {
|
||||
// Check if there was a legal translation between these two spaces.
|
||||
// If so, something else went wrong.
|
||||
for (auto &trans: translations)
|
||||
if (trans.inSpaceId == v_space && trans.outSpaceId == p_space)
|
||||
return false;
|
||||
|
||||
panic("No legal translation IRIS address translation found.");
|
||||
}
|
||||
|
||||
if (result.address.empty())
|
||||
return false;
|
||||
|
||||
if (result.address.size() > 1) {
|
||||
warn("Multiple mappings for address %#x.", vaddr);
|
||||
return false;
|
||||
}
|
||||
|
||||
paddr = result.address[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ThreadContext::scheduleInstCountEvent(Event *event, Tick count)
|
||||
{
|
||||
|
||||
@@ -74,6 +74,9 @@ class ThreadContext : public ::ThreadContext
|
||||
ResourceIds miscRegIds;
|
||||
ResourceIds intRegIds;
|
||||
|
||||
std::vector<iris::MemorySpaceInfo> memorySpaces;
|
||||
std::vector<iris::MemorySupportedAddressTranslationResult> translations;
|
||||
|
||||
|
||||
// A queue to keep track of instruction count based events.
|
||||
EventQueue comInstEventQueue;
|
||||
@@ -101,6 +104,9 @@ class ThreadContext : public ::ThreadContext
|
||||
iris::IrisCppAdapter &call() const { return client.irisCall(); }
|
||||
iris::IrisCppAdapter &noThrow() const { return client.irisCallNoThrow(); }
|
||||
|
||||
bool translateAddress(Addr &paddr, iris::MemorySpaceId p_space,
|
||||
Addr vaddr, iris::MemorySpaceId v_space);
|
||||
|
||||
public:
|
||||
ThreadContext(::BaseCPU *cpu, int id, System *system,
|
||||
::BaseTLB *dtb, ::BaseTLB *itb,
|
||||
@@ -108,6 +114,8 @@ class ThreadContext : public ::ThreadContext
|
||||
const std::string &iris_path);
|
||||
virtual ~ThreadContext();
|
||||
|
||||
virtual bool translateAddress(Addr &paddr, Addr vaddr) = 0;
|
||||
|
||||
bool schedule(PCEvent *e) override { return false; }
|
||||
bool remove(PCEvent *e) override { return false; }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user