summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Sandberg <andreas.sandberg@arm.com>2016-03-21 15:54:58 +0000
committerAndreas Sandberg <andreas.sandberg@arm.com>2016-03-21 15:54:58 +0000
commit8d8e926b04702e891553198bed99ef55f018d160 (patch)
tree634e7b854e4d07b2d1865017c767f66ef9260973
parent1ab75c3ee2b330713a09d79709723ab2256d2c0b (diff)
downloadgem5-8d8e926b04702e891553198bed99ef55f018d160.tar.xz
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.
-rw-r--r--src/arch/arm/table_walker.cc41
-rw-r--r--src/arch/arm/table_walker.hh3
-rw-r--r--src/arch/arm/tlb.cc57
-rw-r--r--src/arch/arm/tlb.hh52
4 files changed, 110 insertions, 43 deletions
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index fd8645e97..e1e00442d 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -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)
{
diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh
index b960c320b..743b8aa93 100644
--- a/src/arch/arm/table_walker.hh
+++ b/src/arch/arm/table_walker.hh
@@ -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
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index bdcb91fac..1bce0f798 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -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)
@@ -577,19 +577,6 @@ TLB::translateSe(RequestPtr req, ThreadContext *tc, Mode mode,
}
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)
{
Addr vaddr = req->getVaddr(); // 32-bit don't have to purify
@@ -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()
{
diff --git a/src/arch/arm/tlb.hh b/src/arch/arm/tlb.hh
index 1f9ec01ec..298c603b9 100644
--- a/src/arch/arm/tlb.hh
+++ b/src/arch/arm/tlb.hh
@@ -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