diff --git a/src/dev/arm/SConscript b/src/dev/arm/SConscript index 0a68e480f3..f516df842a 100644 --- a/src/dev/arm/SConscript +++ b/src/dev/arm/SConscript @@ -87,6 +87,7 @@ Source('kmi.cc', tags='arm isa') Source('smmu_v3.cc', tags='arm isa'); Source('smmu_v3_caches.cc', tags='arm isa'); Source('smmu_v3_cmdexec.cc', tags='arm isa'); +Source('smmu_v3_defs.cc', tags='arm isa'); Source('smmu_v3_events.cc', tags='arm isa'); Source('smmu_v3_ports.cc', tags='arm isa'); Source('smmu_v3_proc.cc', tags='arm isa'); diff --git a/src/dev/arm/smmu_v3_defs.cc b/src/dev/arm/smmu_v3_defs.cc new file mode 100644 index 0000000000..cdf7546824 --- /dev/null +++ b/src/dev/arm/smmu_v3_defs.cc @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024 Arm Limited + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer; + * redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution; + * neither the name of the copyright holders nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "dev/arm/smmu_v3_defs.hh" + +namespace gem5 +{ + +std::string +SMMUEvent::print() const +{ + return csprintf("type=%#x sid=%#x ssid=%#x va=%#08x\n", + data.dw0.eventType, data.dw0.streamId, data.dw0.substreamId, + data.dw2.inputAddr); +} + +} // namespace gem5 diff --git a/src/dev/arm/smmu_v3_defs.hh b/src/dev/arm/smmu_v3_defs.hh index 8b7dfe02cf..c2f8d23e1d 100644 --- a/src/dev/arm/smmu_v3_defs.hh +++ b/src/dev/arm/smmu_v3_defs.hh @@ -384,25 +384,41 @@ struct SMMUCommand } }; -enum SMMUEventTypes -{ - EVT_FAULT = 0x0001, -}; - -enum SMMUEventFlags -{ - EVF_WRITE = 0x0001, -}; - struct SMMUEvent { - uint16_t type; - uint16_t stag; - uint32_t flags; - uint32_t streamId; - uint32_t substreamId; - uint64_t va; - uint64_t ipa; + struct Data { + BitUnion64(DWORD0) + Bitfield<7, 0> eventType; + Bitfield<11> ssv; + Bitfield<31, 12> substreamId; + Bitfield<63, 32> streamId; + EndBitUnion(DWORD0) + DWORD0 dw0; + + BitUnion64(DWORD1) + Bitfield<16, 0> stag; + Bitfield<33> pnu; + Bitfield<34> ind; + Bitfield<35> rnw; + Bitfield<38> nsipa; + Bitfield<39> s2; + Bitfield<41, 40> clss; + EndBitUnion(DWORD1) + DWORD1 dw1; + + BitUnion64(DWORD2) + Bitfield<63, 0> inputAddr; + EndBitUnion(DWORD2) + DWORD2 dw2; + + BitUnion64(DWORD3) + Bitfield<51, 3> fetchAddr; + Bitfield<51, 12> ipa; + EndBitUnion(DWORD3) + DWORD3 dw3; + } data; + + std::string print() const; }; enum diff --git a/src/dev/arm/smmu_v3_transl.cc b/src/dev/arm/smmu_v3_transl.cc index ba0757f3d9..479075ae24 100644 --- a/src/dev/arm/smmu_v3_transl.cc +++ b/src/dev/arm/smmu_v3_transl.cc @@ -1307,6 +1307,32 @@ SMMUTranslationProcess::completePrefetch(Yield &yield) yield(a); } +SMMUEvent +SMMUTranslationProcess::generateEvent(const TranslResult &tr) +{ + SMMUEvent event; + switch (tr.fault.type) { + case FAULT_PERMISSION: + case FAULT_TRANSLATION: + event.data.dw0.streamId = request.sid; + event.data.dw0.substreamId = request.ssid; + event.data.dw1.rnw = !request.isWrite; + event.data.dw2.inputAddr = request.addr; + event.data.dw1.s2 = tr.fault.stage2; + if (tr.fault.stage2) { + // Only support non-secure mode in the SMMU + event.data.dw1.nsipa = true; + event.data.dw3.ipa = tr.fault.ipa; + } + event.data.dw1.clss = tr.fault.clss; + break; + default: + panic("Unsupported fault: %d\n", tr.fault.type); + } + + return event; +} + void SMMUTranslationProcess::sendEvent(Yield &yield, const SMMUEvent &ev) { @@ -1318,17 +1344,15 @@ SMMUTranslationProcess::sendEvent(Yield &yield, const SMMUEvent &ev) Addr event_addr = (smmu.regs.eventq_base & Q_BASE_ADDR_MASK) + - (smmu.regs.eventq_prod & sizeMask) * sizeof(ev); + (smmu.regs.eventq_prod & sizeMask) * sizeof(ev.data); - DPRINTF(SMMUv3, "Sending event to addr=%#08x (pos=%d): type=%#x stag=%#x " - "flags=%#x sid=%#x ssid=%#x va=%#08x ipa=%#x\n", - event_addr, smmu.regs.eventq_prod, ev.type, ev.stag, - ev.flags, ev.streamId, ev.substreamId, ev.va, ev.ipa); + DPRINTF(SMMUv3, "Sending event to addr=%#08x (pos=%d): %s\n", + event_addr, smmu.regs.eventq_prod, ev.print()); // This deliberately resets the overflow field in eventq_prod! smmu.regs.eventq_prod = (smmu.regs.eventq_prod + 1) & sizeMask; - doWrite(yield, event_addr, &ev, sizeof(ev)); + doWrite(yield, event_addr, &ev.data, sizeof(ev.data)); if (!(smmu.regs.eventq_irq_cfg0 & E_BASE_ENABLE_MASK)) panic("eventq msi not enabled\n"); diff --git a/src/dev/arm/smmu_v3_transl.hh b/src/dev/arm/smmu_v3_transl.hh index 33a4fab2c0..6dbedaeb72 100644 --- a/src/dev/arm/smmu_v3_transl.hh +++ b/src/dev/arm/smmu_v3_transl.hh @@ -223,6 +223,7 @@ class SMMUTranslationProcess : public SMMUProcess void completeTransaction(Yield &yield, const TranslResult &tr); void completePrefetch(Yield &yield); + SMMUEvent generateEvent(const TranslResult &tr); void sendEvent(Yield &yield, const SMMUEvent &ev); void doReadSTE(Yield &yield, StreamTableEntry &ste, uint32_t sid);