summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGene Wu <Gene.Wu@arm.com>2010-08-23 11:18:41 -0500
committerGene Wu <Gene.Wu@arm.com>2010-08-23 11:18:41 -0500
commitf29e09746a1380eb43d2309de37d56beec9afab7 (patch)
tree1a9254adf1c75aa136753a05c92e83095875772e /src
parent4b9de4243943086294d7a2d7ab81a134d4fe5a49 (diff)
downloadgem5-f29e09746a1380eb43d2309de37d56beec9afab7.tar.xz
ARM: Fix Uncachable TLB requests and decoding of xn bit
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/table_walker.cc6
-rw-r--r--src/arch/arm/table_walker.hh4
-rw-r--r--src/arch/arm/tlb.cc4
3 files changed, 11 insertions, 3 deletions
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index e17e15054..6dcb387a3 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -165,8 +165,12 @@ TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint8_t _cid, TLB::Mode _
assert(stateQueue.size() < 5);
currState = NULL;
} else {
+ Request::Flags flag = 0;
+ if (currState->sctlr.c == 0){
+ flag = Request::UNCACHEABLE;
+ }
port->dmaAction(MemCmd::ReadReq, l1desc_addr, sizeof(uint32_t),
- NULL, (uint8_t*)&currState->l1Desc.data, (Tick)0);
+ NULL, (uint8_t*)&currState->l1Desc.data, (Tick)0, flag);
doL1Descriptor();
f = currState->fault;
}
diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh
index 12c839d54..2a93c4460 100644
--- a/src/arch/arm/table_walker.hh
+++ b/src/arch/arm/table_walker.hh
@@ -107,13 +107,13 @@ class TableWalker : public MemObject
/** Is the translation global (no asid used)? */
bool global() const
{
- return bits(data, 4);
+ return bits(data, 17);
}
/** Is the translation not allow execution? */
bool xn() const
{
- return bits(data, 17);
+ return bits(data, 4);
}
/** Three bit access protection flags */
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index afa45901a..da2a34084 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -363,6 +363,10 @@ TLB::translateFs(RequestPtr req, ThreadContext *tc, Mode mode,
req->setFlags(Request::UNCACHEABLE);
return NoFault;
}
+ if ((req->isInstFetch() && (!sctlr.i)) ||
+ ((!req->isInstFetch()) && (!sctlr.c))){
+ req->setFlags(Request::UNCACHEABLE);
+ }
if (!is_fetch) {
assert(flags & MustBeOne);
if (sctlr.a || !(flags & AllowUnaligned)) {