arch-arm: Move testWalk functionality to the TableWalker class

It's more efficient to pass a reference of the tester to the
TableWalkers. In this way a table walk check is tested directly
from the walkers instead of going through the MMU every time.

Change-Id: I9820dbabb8b551981005a65efa54a76b1a027541
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Richard Cooper <richard.cooper@arm.com>
This commit is contained in:
Giacomo Travaglini
2024-02-02 10:27:16 +00:00
parent bbe5bf2644
commit e450cfef16
4 changed files with 33 additions and 43 deletions

View File

@@ -1551,6 +1551,10 @@ MMU::setTestInterface(SimObject *_ti)
TlbTestInterface *ti(dynamic_cast<TlbTestInterface *>(_ti));
fatal_if(!ti, "%s is not a valid ARM TLB tester\n", _ti->name());
test = ti;
itbWalker->setTestInterface(test);
dtbWalker->setTestInterface(test);
itbStage2Walker->setTestInterface(test);
dtbStage2Walker->setTestInterface(test);
}
}
@@ -1566,28 +1570,6 @@ MMU::testTranslation(const RequestPtr &req, Mode mode,
}
}
Fault
MMU::testWalk(Addr pa, Addr size, Addr va, bool is_secure, Mode mode,
TlbEntry::DomainType domain, LookupLevel lookup_level,
bool stage2)
{
return testWalk(pa, size, va, is_secure, mode, domain, lookup_level,
stage2 ? s2State : s1State);
}
Fault
MMU::testWalk(Addr pa, Addr size, Addr va, bool is_secure, Mode mode,
TlbEntry::DomainType domain, LookupLevel lookup_level,
CachedState &state)
{
if (!test) {
return NoFault;
} else {
return test->walkCheck(pa, size, va, is_secure, state.isPriv, mode,
domain, lookup_level);
}
}
MMU::Stats::Stats(statistics::Group *parent)
: statistics::Group(parent),
ADD_STAT(alignFaults, statistics::units::Count::get(),

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2013, 2016, 2019-2023 Arm Limited
* Copyright (c) 2010-2013, 2016, 2019-2024 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -461,12 +461,6 @@ class MMU : public BaseMMU
Fault testTranslation(const RequestPtr &req, Mode mode,
TlbEntry::DomainType domain, CachedState &state);
Fault testWalk(Addr pa, Addr size, Addr va, bool is_secure, Mode mode,
TlbEntry::DomainType domain,
LookupLevel lookup_level, bool stage2);
Fault testWalk(Addr pa, Addr size, Addr va, bool is_secure, Mode mode,
TlbEntry::DomainType domain,
LookupLevel lookup_level, CachedState &state);
protected:
bool checkWalkCache() const;

View File

@@ -78,7 +78,8 @@ TableWalker::TableWalker(const Params &p)
doL3LongDescEvent([this]{ doL3LongDescriptorWrapper(); }, name()),
LongDescEventByLevel { &doL0LongDescEvent, &doL1LongDescEvent,
&doL2LongDescEvent, &doL3LongDescEvent },
doProcessEvent([this]{ processWalkWrapper(); }, name())
doProcessEvent([this]{ processWalkWrapper(); }, name()),
test(nullptr)
{
sctlr = 0;
@@ -651,7 +652,7 @@ TableWalker::processWalk()
currState->isSecure ? "s" : "ns");
Fault f = testWalk(l1desc_addr, sizeof(uint32_t),
TlbEntry::DomainType::NoAccess, LookupLevel::L1, isStage2);
TlbEntry::DomainType::NoAccess, LookupLevel::L1);
if (f) {
return f;
@@ -817,8 +818,8 @@ TableWalker::processWalkLPAE()
}
Fault f = testWalk(desc_addr, sizeof(uint64_t),
TlbEntry::DomainType::NoAccess, start_lookup_level,
isStage2);
TlbEntry::DomainType::NoAccess, start_lookup_level);
if (f) {
return f;
}
@@ -1057,7 +1058,7 @@ TableWalker::processWalkAArch64()
}
Fault f = testWalk(desc_addr, sizeof(uint64_t),
TlbEntry::DomainType::NoAccess, start_lookup_level, isStage2);
TlbEntry::DomainType::NoAccess, start_lookup_level);
if (f) {
return f;
}
@@ -1638,10 +1639,9 @@ TableWalker::doL1Descriptor()
DPRINTF(TLB, "L1 descriptor points to page table at: %#x (%s)\n",
l2desc_addr, currState->isSecure ? "s" : "ns");
// Trickbox address check
currState->fault = testWalk(l2desc_addr, sizeof(uint32_t),
currState->l1Desc.domain(),
LookupLevel::L2, isStage2);
LookupLevel::L2);
if (currState->fault) {
if (!currState->timing) {
@@ -1806,10 +1806,9 @@ TableWalker::doLongDescriptor()
return;
}
// Trickbox address check
currState->fault = testWalk(
next_desc_addr, sizeof(uint64_t), TlbEntry::DomainType::Client,
toLookupLevel(currState->longDesc.lookupLevel +1), isStage2);
toLookupLevel(currState->longDesc.lookupLevel +1));
if (currState->fault) {
if (!currState->timing) {
@@ -2343,12 +2342,22 @@ TableWalker::pendingChange()
Fault
TableWalker::testWalk(Addr pa, Addr size, TlbEntry::DomainType domain,
LookupLevel lookup_level, bool stage2)
LookupLevel lookup_level)
{
return mmu->testWalk(pa, size, currState->vaddr, currState->isSecure,
currState->mode, domain, lookup_level, stage2);
if (!test) {
return NoFault;
} else {
return test->walkCheck(pa, size, currState->vaddr, currState->isSecure,
currState->el != EL0,
currState->mode, domain, lookup_level);
}
}
void
TableWalker::setTestInterface(TlbTestInterface *ti)
{
test = ti;
}
uint8_t
TableWalker::pageSizeNtoStatBin(uint8_t N)

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010-2016, 2019, 2021-2023 Arm Limited
* Copyright (c) 2010-2016, 2019, 2021-2024 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -1185,8 +1185,13 @@ class TableWalker : public ClockedObject
static uint8_t pageSizeNtoStatBin(uint8_t N);
public: /* Testing */
TlbTestInterface *test;
void setTestInterface(TlbTestInterface *ti);
Fault testWalk(Addr pa, Addr size, TlbEntry::DomainType domain,
LookupLevel lookup_level, bool stage2);
LookupLevel lookup_level);
};
} // namespace ArmISA