From 76b10e2b4abf36e441707e7e075ade75b11ab667 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Wed, 9 Oct 2019 14:53:38 +0100 Subject: [PATCH] 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 Reviewed-by: Andreas Sandberg Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/22443 Reviewed-by: Nikos Nikoleris Tested-by: kokoro --- src/arch/arm/faults.cc | 3 +++ src/arch/arm/faults.hh | 4 ++++ src/arch/arm/insts/mem64.hh | 7 +++++-- src/arch/arm/isa/insts/data64.isa | 7 ++++++- 4 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/arch/arm/faults.cc b/src/arch/arm/faults.cc index b006d12ca..dbad5bf66 100644 --- a/src/arch/arm/faults.cc +++ b/src/arch/arm/faults.cc @@ -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; diff --git a/src/arch/arm/faults.hh b/src/arch/arm/faults.hh index 645a461fe..3f61bc722 100644 --- a/src/arch/arm/faults.hh +++ b/src/arch/arm/faults.hh @@ -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 diff --git a/src/arch/arm/insts/mem64.hh b/src/arch/arm/insts/mem64.hh index 886c54f35..25ef14841 100644 --- a/src/arch/arm/insts/mem64.hh +++ b/src/arch/arm/insts/mem64.hh @@ -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( diff --git a/src/arch/arm/isa/insts/data64.isa b/src/arch/arm/isa/insts/data64.isa index fcce0112a..75d47925f 100644 --- a/src/arch/arm/isa/insts/data64.isa +++ b/src/arch/arm/isa/insts/data64.isa @@ -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()) && -- 2.30.2