arm: Refactor the TLB test interface

Refactor the TLB and page table walker test interface to use a dynamic
registration mechanism. Instead of patching a couple of empty methods
to wire up a TLB tester, this change allows such testers to register
themselves using the setTestInterface() method.
This commit is contained in:
Andreas Sandberg 2016-03-21 15:54:58 +00:00
parent 1ab75c3ee2
commit 8d8e926b04
4 changed files with 110 additions and 43 deletions

View file

@ -502,9 +502,8 @@ TableWalker::processWalk()
// Trickbox address check
Fault f;
f = tlb->walkTrickBoxCheck(l1desc_addr, currState->isSecure,
currState->vaddr, sizeof(uint32_t), currState->isFetch,
currState->isWrite, TlbEntry::DomainType::NoAccess, L1);
f = testWalk(l1desc_addr, sizeof(uint32_t),
TlbEntry::DomainType::NoAccess, L1);
if (f) {
DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted);
if (currState->timing) {
@ -668,10 +667,8 @@ TableWalker::processWalkLPAE()
}
// Trickbox address check
Fault f = tlb->walkTrickBoxCheck(desc_addr, currState->isSecure,
currState->vaddr, sizeof(uint64_t), currState->isFetch,
currState->isWrite, TlbEntry::DomainType::NoAccess,
start_lookup_level);
Fault f = testWalk(desc_addr, sizeof(uint64_t),
TlbEntry::DomainType::NoAccess, start_lookup_level);
if (f) {
DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted);
if (currState->timing) {
@ -913,10 +910,8 @@ TableWalker::processWalkAArch64()
stride * (3 - start_lookup_level) + tg) << 3);
// Trickbox address check
Fault f = tlb->walkTrickBoxCheck(desc_addr, currState->isSecure,
currState->vaddr, sizeof(uint64_t), currState->isFetch,
currState->isWrite, TlbEntry::DomainType::NoAccess,
start_lookup_level);
Fault f = testWalk(desc_addr, sizeof(uint64_t),
TlbEntry::DomainType::NoAccess, start_lookup_level);
if (f) {
DPRINTF(TLB, "Trickbox check caused fault on %#x\n", currState->vaddr_tainted);
if (currState->timing) {
@ -1437,10 +1432,8 @@ TableWalker::doL1Descriptor()
l2desc_addr, currState->isSecure ? "s" : "ns");
// Trickbox address check
currState->fault = tlb->walkTrickBoxCheck(
l2desc_addr, currState->isSecure, currState->vaddr,
sizeof(uint32_t), currState->isFetch, currState->isWrite,
currState->l1Desc.domain(), L2);
currState->fault = testWalk(l2desc_addr, sizeof(uint32_t),
currState->l1Desc.domain(), L2);
if (currState->fault) {
if (!currState->timing) {
@ -1616,12 +1609,9 @@ TableWalker::doLongDescriptor()
}
// Trickbox address check
currState->fault = tlb->walkTrickBoxCheck(
next_desc_addr, currState->vaddr,
currState->vaddr, sizeof(uint64_t),
currState->isFetch, currState->isWrite,
TlbEntry::DomainType::Client,
toLookupLevel(currState->longDesc.lookupLevel +1));
currState->fault = testWalk(
next_desc_addr, sizeof(uint64_t), TlbEntry::DomainType::Client,
toLookupLevel(currState->longDesc.lookupLevel +1));
if (currState->fault) {
if (!currState->timing) {
@ -2096,6 +2086,15 @@ TableWalker::pendingChange()
}
}
Fault
TableWalker::testWalk(Addr pa, Addr size, TlbEntry::DomainType domain,
LookupLevel lookup_level)
{
return tlb->testWalk(pa, size, currState->vaddr, currState->isSecure,
currState->mode, domain, lookup_level);
}
uint8_t
TableWalker::pageSizeNtoStatBin(uint8_t N)
{

View file

@ -966,6 +966,9 @@ class TableWalker : public MemObject
void pendingChange();
static uint8_t pageSizeNtoStatBin(uint8_t N);
Fault testWalk(Addr pa, Addr size, TlbEntry::DomainType domain,
LookupLevel lookup_level);
};
} // namespace ArmISA

View file

@ -75,7 +75,7 @@ TLB::TLB(const ArmTLBParams *p)
: BaseTLB(p), table(new TlbEntry[p->size]), size(p->size),
isStage2(p->is_stage2), stage2Req(false), _attr(0),
directToStage2(false), tableWalker(p->walker), stage2Tlb(NULL),
stage2Mmu(NULL), rangeMRU(1),
stage2Mmu(NULL), test(nullptr), rangeMRU(1),
aarch64(false), aarch64EL(EL0), isPriv(false), isSecure(false),
isHyp(false), asid(0), vmid(0), dacr(0),
miscRegValid(false), miscRegContext(0), curTranType(NormalTran)
@ -576,19 +576,6 @@ TLB::translateSe(RequestPtr req, ThreadContext *tc, Mode mode,
return NoFault;
}
Fault
TLB::trickBoxCheck(RequestPtr req, Mode mode, TlbEntry::DomainType domain)
{
return NoFault;
}
Fault
TLB::walkTrickBoxCheck(Addr pa, bool is_secure, Addr va, Addr sz, bool is_exec,
bool is_write, TlbEntry::DomainType domain, LookupLevel lookup_level)
{
return NoFault;
}
Fault
TLB::checkPermissions(TlbEntry *te, RequestPtr req, Mode mode)
{
@ -1038,7 +1025,7 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
isStage2);
setAttr(temp_te.attributes);
return trickBoxCheck(req, mode, TlbEntry::DomainType::NoAccess);
return testTranslation(req, mode, TlbEntry::DomainType::NoAccess);
}
DPRINTF(TLBVerbose, "Translating %s=%#x context=%d\n",
@ -1091,9 +1078,8 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
}
// Check for a trickbox generated address fault
if (fault == NoFault) {
fault = trickBoxCheck(req, mode, te->domain);
}
if (fault == NoFault)
fault = testTranslation(req, mode, te->domain);
}
// Generate Illegal Inst Set State fault if IL bit is set in CPSR
@ -1419,6 +1405,41 @@ TLB::getResultTe(TlbEntry **te, RequestPtr req, ThreadContext *tc, Mode mode,
return fault;
}
void
TLB::setTestInterface(SimObject *_ti)
{
if (!_ti) {
test = nullptr;
} else {
TlbTestInterface *ti(dynamic_cast<TlbTestInterface *>(_ti));
fatal_if(!ti, "%s is not a valid ARM TLB tester\n", _ti->name());
test = ti;
}
}
Fault
TLB::testTranslation(RequestPtr req, Mode mode, TlbEntry::DomainType domain)
{
if (!test) {
return NoFault;
} else {
return test->translationCheck(req, isPriv, mode, domain);
}
}
Fault
TLB::testWalk(Addr pa, Addr size, Addr va, bool is_secure, Mode mode,
TlbEntry::DomainType domain, LookupLevel lookup_level)
{
if (!test) {
return NoFault;
} else {
return test->walkCheck(pa, size, va, is_secure, isPriv, mode,
domain, lookup_level);
}
}
ArmISA::TLB *
ArmTLBParams::create()
{

View file

@ -61,6 +61,43 @@ namespace ArmISA {
class TableWalker;
class Stage2LookUp;
class Stage2MMU;
class TLB;
class TlbTestInterface
{
public:
TlbTestInterface() {}
virtual ~TlbTestInterface() {}
/**
* Check if a TLB translation should be forced to fail.
*
* @param req Request requiring a translation.
* @param is_priv Access from a privileged mode (i.e., not EL0)
* @param mode Access type
* @param domain Domain type
*/
virtual Fault translationCheck(RequestPtr req, bool is_priv,
BaseTLB::Mode mode,
TlbEntry::DomainType domain) = 0;
/**
* Check if a page table walker access should be forced to fail.
*
* @param pa Physical address the walker is accessing
* @param size Walker access size
* @param va Virtual address that initiated the walk
* @param is_secure Access from secure state
* @param is_priv Access from a privileged mode (i.e., not EL0)
* @param mode Access type
* @param domain Domain type
* @param lookup_level Page table walker level
*/
virtual Fault walkCheck(Addr pa, Addr size, Addr va, bool is_secure,
Addr is_priv, BaseTLB::Mode mode,
TlbEntry::DomainType domain,
LookupLevel lookup_level) = 0;
};
class TLB : public BaseTLB
{
@ -105,6 +142,8 @@ class TLB : public BaseTLB
TLB *stage2Tlb;
Stage2MMU *stage2Mmu;
TlbTestInterface *test;
// Access Stats
mutable Stats::Scalar instHits;
mutable Stats::Scalar instMisses;
@ -160,6 +199,8 @@ class TLB : public BaseTLB
/// setup all the back pointers
void init() override;
void setTestInterface(SimObject *ti);
TableWalker *getTableWalker() { return tableWalker; }
void setMMU(Stage2MMU *m, MasterID master_id);
@ -224,10 +265,6 @@ class TLB : public BaseTLB
*/
void flushMva(Addr mva, bool secure_lookup, bool hyp, uint8_t target_el);
Fault trickBoxCheck(RequestPtr req, Mode mode, TlbEntry::DomainType domain);
Fault walkTrickBoxCheck(Addr pa, bool is_secure, Addr va, Addr sz, bool is_exec,
bool is_write, TlbEntry::DomainType domain, LookupLevel lookup_level);
void printTlb() const;
void demapPage(Addr vaddr, uint64_t asn) override
@ -356,6 +393,13 @@ private:
bool hyp, bool ignore_asn, uint8_t target_el);
bool checkELMatch(uint8_t target_el, uint8_t tentry_el, bool ignore_el);
public: /* Testing */
Fault testTranslation(RequestPtr req, Mode mode,
TlbEntry::DomainType domain);
Fault testWalk(Addr pa, Addr size, Addr va, bool is_secure, Mode mode,
TlbEntry::DomainType domain,
LookupLevel lookup_level);
};
} // namespace ArmISA