From 63c815b5fcf5a5faec3dc219dc9fc7941b03e340 Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Tue, 5 Mar 2024 15:57:43 +0000 Subject: [PATCH] dev-arm: Do not panic in the SMMUv3 for fauting transactions Rely on the architected solution instead of aborting simulation. This means handling writes to the Event queue to signal managing software there was a fault in the SMMU Change-Id: I7b69ca77021732c6059bd6b837ae722da71350ff Signed-off-by: Giacomo Travaglini --- src/dev/arm/smmu_v3_transl.cc | 52 ++++++++++++++++++++++++++++++----- src/dev/arm/smmu_v3_transl.hh | 1 + 2 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/dev/arm/smmu_v3_transl.cc b/src/dev/arm/smmu_v3_transl.cc index 479075ae24..204268efad 100644 --- a/src/dev/arm/smmu_v3_transl.cc +++ b/src/dev/arm/smmu_v3_transl.cc @@ -229,13 +229,11 @@ SMMUTranslationProcess::main(Yield &yield) hazardIdHold(yield); hazardIdRelease(); - if (tr.isFaulting()) - panic("Translation Fault (addr=%#x, size=%#x, sid=%d, ssid=%d, " - "isWrite=%d, isPrefetch=%d, isAtsRequest=%d)\n", - request.addr, request.size, request.sid, request.ssid, - request.isWrite, request.isPrefetch, request.isAtsRequest); - - completeTransaction(yield, tr); + if (tr.isFaulting()) { + abortTransaction(yield, tr); + } else { + completeTransaction(yield, tr); + } } } @@ -1232,6 +1230,46 @@ SMMUTranslationProcess::issuePrefetch(Addr addr) proc->scheduleWakeup(smmu.clockEdge(Cycles(1))); } +void +SMMUTranslationProcess::abortTransaction(Yield &yield, + const TranslResult &tr) +{ + DPRINTF(SMMUv3, "Translation Fault (addr=%#x, size=%#x, sid=%d, ssid=%d, " + "isWrite=%d, isPrefetch=%d, isAtsRequest=%d)\n", + request.addr, request.size, request.sid, request.ssid, + request.isWrite, request.isPrefetch, request.isAtsRequest); + + // If eventq is not enabled, silently discard event + // TODO: Handle full queue (we are currently aborting + // in send event) + if (smmu.regs.cr0 & CR0_EVENTQEN_MASK) { + SMMUEvent event = generateEvent(tr); + + sendEvent(yield, event); + } + + ifc.xlateSlotsRemaining++; + smmu.scheduleDeviceRetries(); + + if (smmu.system.isAtomicMode()) { + request.pkt->makeAtomicResponse(); + } else if (smmu.system.isTimingMode()) { + request.pkt->makeTimingResponse(); + } else { + panic("Not in atomic or timing mode"); + } + + request.pkt->setBadAddress(); + + SMMUAction a; + // Send the bad address response to the client device + a.type = ACTION_SEND_RESP; + a.pkt = request.pkt; + a.ifc = &ifc; + a.delay = 0; + yield(a); +} + void SMMUTranslationProcess::completeTransaction(Yield &yield, const TranslResult &tr) diff --git a/src/dev/arm/smmu_v3_transl.hh b/src/dev/arm/smmu_v3_transl.hh index 6dbedaeb72..bc6b4bc9a7 100644 --- a/src/dev/arm/smmu_v3_transl.hh +++ b/src/dev/arm/smmu_v3_transl.hh @@ -220,6 +220,7 @@ class SMMUTranslationProcess : public SMMUProcess void issuePrefetch(Addr addr); + void abortTransaction(Yield &yield, const TranslResult &tr); void completeTransaction(Yield &yield, const TranslResult &tr); void completePrefetch(Yield &yield);