summaryrefslogtreecommitdiff
path: root/src/arch/arm/table_walker.cc
diff options
context:
space:
mode:
authorAli Saidi <Ali.Saidi@ARM.com>2010-06-02 12:58:16 -0500
committerAli Saidi <Ali.Saidi@ARM.com>2010-06-02 12:58:16 -0500
commitc1e1de8d69624b1cf18a13a46e624ad5827954b7 (patch)
tree60f11a14eafcc03715c283270edb336e0a44bccc /src/arch/arm/table_walker.cc
parent7de7ea3b22e16a6d489a71dc5c54ddba5a5b5a0e (diff)
downloadgem5-c1e1de8d69624b1cf18a13a46e624ad5827954b7.tar.xz
ARM: Some TLB bug fixes.
Diffstat (limited to 'src/arch/arm/table_walker.cc')
-rw-r--r--src/arch/arm/table_walker.cc27
1 files changed, 19 insertions, 8 deletions
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index 313b23316..e3ecb7ddd 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -111,21 +111,25 @@ TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint8_t _cid, TLB::Mode m
// If translation isn't enabled, we shouldn't be here
assert(sctlr.m);
- if (N == 0 || mbits(vaddr, 31, 32-N)) {
+ DPRINTF(TLB, "Begining table walk for address %#x, TTBCR: %#x, bits:%#x\n",
+ vaddr, N, mbits(vaddr, 31, 32-N));
+
+ if (N == 0 || !mbits(vaddr, 31, 32-N)) {
+ DPRINTF(TLB, " - Selecting TTBR0\n");
ttbr = tc->readMiscReg(MISCREG_TTBR0);
} else {
- ttbr = tc->readMiscReg(MISCREG_TTBR0);
+ DPRINTF(TLB, " - Selecting TTBR1\n");
+ ttbr = tc->readMiscReg(MISCREG_TTBR1);
N = 0;
}
Addr l1desc_addr = mbits(ttbr, 31, 14-N) | (bits(vaddr,31-N,20) << 2);
- DPRINTF(TLB, "Begining table walk for address %#x at descriptor %#x\n",
- vaddr, l1desc_addr);
+ DPRINTF(TLB, " - Descriptor at address %#x\n", l1desc_addr);
// Trickbox address check
fault = tlb->walkTrickBoxCheck(l1desc_addr, vaddr, sizeof(uint32_t),
- isFetch, 0, true);
+ isFetch, isWrite, 0, true);
if (fault) {
tc = NULL;
req = NULL;
@@ -210,7 +214,11 @@ TableWalker::doL1Descriptor()
case L1Descriptor::Reserved:
tc = NULL;
req = NULL;
- fault = new DataAbort(vaddr, NULL, isWrite, ArmFault::Translation0);
+ DPRINTF(TLB, "L1 Descriptor Reserved/Ignore, causing fault\n");
+ if (isFetch)
+ fault = new PrefetchAbort(vaddr, ArmFault::Translation0);
+ else
+ fault = new DataAbort(vaddr, NULL, isWrite, ArmFault::Translation0);
return;
case L1Descriptor::Section:
if (sctlr.afe && bits(l1Desc.ap(), 0) == 0)
@@ -252,7 +260,7 @@ TableWalker::doL1Descriptor()
// Trickbox address check
fault = tlb->walkTrickBoxCheck(l2desc_addr, vaddr, sizeof(uint32_t),
- isFetch, l1Desc.domain(), false);
+ isFetch, isWrite, l1Desc.domain(), false);
if (fault) {
tc = NULL;
req = NULL;
@@ -287,7 +295,10 @@ TableWalker::doL2Descriptor()
DPRINTF(TLB, "L2 descriptor invalid, causing fault\n");
tc = NULL;
req = NULL;
- fault = new DataAbort(vaddr, l1Desc.domain(), isWrite, ArmFault::Translation1);
+ if (isFetch)
+ fault = new PrefetchAbort(vaddr, ArmFault::Translation1);
+ else
+ fault = new DataAbort(vaddr, l1Desc.domain(), isWrite, ArmFault::Translation1);
return;
}