arch-arm: Annotate original address in CMOs

This is needed when a CMO triggers an exception (e.g. DataAbort) In that
case the faulting address should be the one encoded in the instruction
rather than the cacheline address:

According to armarm:
If a memory fault that sets FAR_EL1 is generated from a data cache
maintenance or other DC instruction, FAR_EL1[63:0] holds the address
specified in the register argument of the instruction.

Change-Id: I6d0dadbef6e70db57438b01a76c5def3bdd2d974
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/22443
Reviewed-by: Nikos Nikoleris <nikos.nikoleris@arm.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Giacomo Travaglini
2019-10-09 14:53:38 +01:00
parent 75a127e8ba
commit 76b10e2b4a
4 changed files with 18 additions and 3 deletions

View File

@@ -1418,6 +1418,9 @@ DataAbort::annotate(AnnotationIDs id, uint64_t val)
case CM:
cm = val;
break;
case OFA:
faultAddr = val;
break;
// Just ignore unknown ID's
default:
break;

View File

@@ -137,6 +137,10 @@ class ArmFault : public FaultBase
SSE, // DataAbort: Syndrome Sign Extend
SRT, // DataAbort: Syndrome Register Transfer
CM, // DataAbort: Cache Maintenance/Address Translation Op
OFA, // DataAbort: Override fault Address. This is needed when
// the abort is triggered by a CMO. The faulting address is
// then the address specified in the register argument of the
// instruction and not the cacheline address (See FAR doc)
// AArch64 only
SF, // DataAbort: width of the accessed register is SixtyFour

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011-2013,2017 ARM Limited
* Copyright (c) 2011-2013,2017-2019 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -52,10 +52,13 @@ class SysDC64 : public MiscRegOp64
MiscRegIndex dest;
uint64_t imm;
// This is used for fault handling only
mutable Addr faultAddr;
SysDC64(const char *mnem, ExtMachInst _machInst, OpClass __opClass,
IntRegIndex _base, MiscRegIndex _dest, uint64_t _imm)
: MiscRegOp64(mnem, _machInst, __opClass, false),
base(_base), dest(_dest), imm(_imm)
base(_base), dest(_dest), imm(_imm), faultAddr(0)
{}
std::string generateDisassembly(

View File

@@ -412,9 +412,10 @@ let {{
# Cache maintenance fault annotation
# The DC ZVA instruction is not classified as a cache maintenance
# instruction, and therefore we shouldn't annotate it
# instruction, and therefore we shouldn't annotate it.
cachem_fa = '''
fault->annotate(ArmFault::CM, 1);
fault->annotate(ArmFault::OFA, faultAddr);
'''
msrdccvau_ea_code = msr_check_code
@@ -422,6 +423,7 @@ let {{
Request::Flags memAccessFlags = Request::CLEAN | Request::DST_POU |
ArmISA::TLB::MustBeOne;
EA = XBase;
faultAddr = EA;
System *sys = xc->tcBase()->getSystemPtr();
Addr op_size = sys->cacheLineSize();
EA &= ~(op_size - 1);
@@ -446,6 +448,7 @@ let {{
Request::Flags memAccessFlags = Request::CLEAN | Request::DST_POC |
ArmISA::TLB::MustBeOne;
EA = XBase;
faultAddr = EA;
System *sys = xc->tcBase()->getSystemPtr();
Addr op_size = sys->cacheLineSize();
EA &= ~(op_size - 1);
@@ -470,6 +473,7 @@ let {{
Request::Flags memAccessFlags = Request::CLEAN |
Request::INVALIDATE | Request::DST_POC | ArmISA::TLB::MustBeOne;
EA = XBase;
faultAddr = EA;
System *sys = xc->tcBase()->getSystemPtr();
Addr op_size = sys->cacheLineSize();
EA &= ~(op_size - 1);
@@ -494,6 +498,7 @@ let {{
Request::Flags memAccessFlags = Request::INVALIDATE |
Request::DST_POC | ArmISA::TLB::MustBeOne;
EA = XBase;
faultAddr = EA;
HCR hcr = Hcr64;
SCR scr = Scr64;
if (el == EL1 && ArmSystem::haveVirtualization(xc->tcBase()) &&