summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNikos Nikoleris <nikos.nikoleris@arm.com>2017-02-21 14:14:44 +0000
committerNikos Nikoleris <nikos.nikoleris@arm.com>2017-02-21 14:14:44 +0000
commit2213fba5c5c4ea85477b7c5985e10d2f17f027c6 (patch)
tree3a038100bb0ad4d1bcb76696ad8e04eaff714385 /src
parentf2e2410a505ef48516f121ce1b2232ba7aa389af (diff)
downloadgem5-2213fba5c5c4ea85477b7c5985e10d2f17f027c6.tar.xz
arm: Blame the right instruction address on a Prefetch Abort
CPU models (e.g., O3CPU) issue instruction fetches for the whole cache block rather than a specific instruction. Consequently the TLB lookups translate the cache block virtual address. When the TLB lookup fails, however, the Prefetch Abort must be raised for the PC of the instruction that caused the fault rather than for the address of the block. This change fixes the way we instantiate the PrefetchAbort faults to use the PC of the request rather the address of the instruction fetch request. Change-Id: I8e45549da1c3be55ad204a060029c95ce822a851 Reviewed-by: Curtis Dunham <curtis.dunham@arm.com> Reviewed-by: Rekai Gonzalez Alberquilla <rekai.gonzalezalberquilla@arm.com> Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/tlb.cc15
1 files changed, 10 insertions, 5 deletions
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index 85bc12c5b..eeccca0c0 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2013, 2016 ARM Limited
+ * Copyright (c) 2010-2013, 2016-2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -642,12 +642,15 @@ TLB::checkPermissions(TlbEntry *te, RequestPtr req, Mode mode)
DPRINTF(TLB, "TLB Fault: Data abort on domain. DACR: %#x"
" domain: %#x write:%d\n", dacr,
static_cast<uint8_t>(te->domain), is_write);
- if (is_fetch)
+ if (is_fetch) {
+ // Use PC value instead of vaddr because vaddr might
+ // be aligned to cache line and should not be the
+ // address reported in FAR
return std::make_shared<PrefetchAbort>(
- vaddr,
+ req->getPC(),
ArmFault::DomainLL + te->lookupLevel,
isStage2, tranMethod);
- else
+ } else
return std::make_shared<DataAbort>(
vaddr, te->domain, is_write,
ArmFault::DomainLL + te->lookupLevel,
@@ -735,8 +738,10 @@ TLB::checkPermissions(TlbEntry *te, RequestPtr req, Mode mode)
DPRINTF(TLB, "TLB Fault: Prefetch abort on permission check. AP:%d "
"priv:%d write:%d ns:%d sif:%d sctlr.afe: %d \n",
ap, is_priv, is_write, te->ns, scr.sif,sctlr.afe);
+ // Use PC value instead of vaddr because vaddr might be aligned to
+ // cache line and should not be the address reported in FAR
return std::make_shared<PrefetchAbort>(
- vaddr,
+ req->getPC(),
ArmFault::PermissionLL + te->lookupLevel,
isStage2, tranMethod);
} else if (abt | hapAbt) {