42 #include "debug/SMMUv3.hh" 43 #include "debug/SMMUv3Hazard.hh" 54 req.
sid = pkt->
req->streamId();
55 req.
ssid = pkt->
req->hasSubstreamId() ?
56 pkt->
req->substreamId() : 0;
121 assert(!
"Stalls are broken");
126 DPRINTF(
SMMUv3,
"Resume at tick = %d. Fault duration = %d (%.3fus)\n",
148 panic(
"Transaction crosses 4k boundary (addr=%#x size=%#x)!\n",
170 bool wasPrefetched =
false;
229 panic(
"Translation Fault (addr=%#x, size=%#x, sid=%d, ssid=%d, " 230 "isWrite=%d, isPrefetch=%d, isAtsRequest=%d)\n",
264 bool haveConfig =
true;
325 DPRINTF(
SMMUv3,
"micro TLB miss vaddr=%#x sid=%#x ssid=%#x\n",
332 "micro TLB hit vaddr=%#x amask=%#x sid=%#x ssid=%#x paddr=%#x\n",
358 "SLAVE Interface TLB miss vaddr=%#x sid=%#x ssid=%#x\n",
365 "SLAVE Interface TLB hit vaddr=%#x amask=%#x sid=%#x ssid=%#x " 391 DPRINTF(
SMMUv3,
"SMMU TLB miss vaddr=%#x asid=%#x vmid=%#x\n",
398 "SMMU TLB hit vaddr=%#x amask=%#x asid=%#x vmid=%#x paddr=%#x\n",
433 "micro TLB upd vaddr=%#x amask=%#x paddr=%#x sid=%#x ssid=%#x\n",
470 "SLAVE Interface upd vaddr=%#x amask=%#x paddr=%#x sid=%#x " 499 "SMMU TLB upd vaddr=%#x amask=%#x paddr=%#x asid=%#x vmid=%#x\n",
526 DPRINTF(
SMMUv3,
"Config hit sid=%#x ssid=%#x ttb=%#08x asid=%#x\n",
608 panic(
"Bad or unimplemented STE config %d\n",
621 tc.
httb = 0xdeadbeef;
639 tc.
ttb0 = 0xcafebabe;
640 tc.
ttb1 = 0xcafed00d;
654 unsigned stage,
unsigned level)
656 const char *indent = stage==2 ?
" " :
"";
664 unsigned walkCacheLevels =
669 if ((1 << level) & walkCacheLevels) {
678 "base=%#x (S%d, L%d)\n",
679 indent, addr, asid, vmid, walkEntry->
pa, stage, level);
683 indent, addr, asid, vmid, stage, level);
693 unsigned stage,
unsigned level,
694 bool leaf, uint8_t permissions)
696 unsigned walkCacheLevels =
714 DPRINTF(
SMMUv3,
"%sWalkCache upd va=%#x mask=%#x asid=%#x vmid=%#x " 715 "tpa=%#x leaf=%s (S%d, L%d)\n",
716 e.
stage==2 ?
" " :
"",
742 for (; level <= pt_ops->
lastLevel(); level++) {
743 Addr pte_addr = walkPtr + pt_ops->
index(addr, level);
748 doReadPTE(yield, addr, pte_addr, &pte, 1, level);
751 level, pte, pte_addr);
757 bool valid = pt_ops->
isValid(pte, level);
758 bool leaf = pt_ops->
isLeaf(pte, level);
797 tr.addrMask = pt_ops->
pageMask(pte, level);
798 tr.addr = walkPtr + (addr & ~tr.addrMask);
799 tr.writable = pt_ops->
isWritable(pte, level,
false);
810 1, level,
true, tr.writable);
826 for (; level <= pt_ops->
lastLevel(); level++) {
827 Addr pte_addr = walkPtr + pt_ops->
index(addr, level);
832 doReadPTE(yield, addr, pte_addr, &pte, 2, level);
835 level, pte, pte_addr);
841 bool valid = pt_ops->
isValid(pte, level);
842 bool leaf = pt_ops->
isLeaf(pte, level);
867 leaf ? pt_ops->
isWritable(pte, level,
true) : 0);
923 table_addr = s2tr.
addr;
996 tr =
walkStage2(yield, addr, final_tr, pt_ops,
997 level + 1, walk_ep->
pa);
1000 tr =
walkStage2(yield, addr, final_tr, pt_ops,
1053 Addr other4k = (*it)->request.addr & ~0xfff
ULL;
1054 if (addr4k == other4k)
1064 DPRINTF(SMMUv3Hazard,
"4kReg: p=%p a4k=%#x\n",
1078 found_hazard =
false;
1084 Addr other4k = (*it)->request.addr & ~0xfff
ULL;
1086 DPRINTF(SMMUv3Hazard,
"4kHold: p=%p a4k=%#x Q: p=%p a4k=%#x\n",
1087 this, addr4k, *it, other4k);
1089 if (addr4k == other4k) {
1091 "4kHold: p=%p a4k=%#x WAIT on p=%p a4k=%#x\n",
1092 this, addr4k, *it, other4k);
1096 DPRINTF(SMMUv3Hazard,
"4kHold: p=%p a4k=%#x RESUME\n",
1101 found_hazard =
true;
1105 }
while (found_hazard);
1111 DPRINTF(SMMUv3Hazard,
"4kRel: p=%p a4k=%#x\n",
1121 panic(
"hazard4kRelease: request not found");
1140 depReqs.push_back(
this);
1158 found_hazard =
false;
1160 for (
auto it = depReqs.begin(); it!=depReqs.end() && *it!=
this; ++it) {
1161 DPRINTF(SMMUv3Hazard,
"IdHold: p=%p oid=%d Q: %p\n",
1165 DPRINTF(SMMUv3Hazard,
"IdHold: p=%p oid=%d WAIT on=%p\n",
1170 DPRINTF(SMMUv3Hazard,
"IdHold: p=%p oid=%d RESUME\n",
1175 found_hazard =
true;
1179 }
while (found_hazard);
1194 for (it = depReqs.begin(); it != depReqs.end(); ++it) {
1199 if (it == depReqs.end())
1200 panic(
"hazardIdRelease: request not found");
1260 panic(
"Not in atomic or timing mode");
1307 panic(
"Event queue full - aborting\n");
1313 DPRINTF(
SMMUv3,
"Sending event to addr=%#08x (pos=%d): type=%#x stag=%#x " 1314 "flags=%#x sid=%#x ssid=%#x va=%#08x ipa=%#x\n",
1321 doWrite(yield, event_addr, &ev,
sizeof(ev));
1324 panic(
"eventq msi not enabled\n");
1337 panic(
"SID %#x out of range, max=%#x", sid, max_sid);
1345 if (split!= 7 && split!=8 && split!=16)
1346 panic(
"Invalid stream table split %d", split);
1351 bits(sid, 32, split) *
sizeof(l2_ptr);
1355 doReadConfig(yield, l2_addr, &l2_ptr,
sizeof(l2_ptr), sid, 0);
1357 DPRINTF(
SMMUv3,
"Got L1STE L1 at %#x: 0x%016x\n", l2_addr, l2_ptr);
1361 panic(
"Invalid level 1 stream table descriptor");
1364 if (index >= (1 << span))
1365 panic(
"StreamID %d out of level 1 descriptor range %d",
1375 panic(
"Invalid stream table format");
1380 doReadConfig(yield, ste_addr, &ste,
sizeof(ste), sid, 0);
1382 DPRINTF(
SMMUv3,
"Got STE at %#x [0]: 0x%016x\n", ste_addr, ste.dw0);
1383 DPRINTF(
SMMUv3,
" STE at %#x [1]: 0x%016x\n", ste_addr, ste.dw1);
1384 DPRINTF(
SMMUv3,
" STE at %#x [2]: 0x%016x\n", ste_addr, ste.dw2);
1385 DPRINTF(
SMMUv3,
" STE at %#x [3]: 0x%016x\n", ste_addr, ste.dw3);
1392 panic(
"STE @ %#x not valid\n", ste_addr);
1401 uint32_t sid, uint32_t ssid)
1408 unsigned max_ssid = 1 << ste.dw0.
s1cdmax;
1409 if (ssid >= max_ssid)
1410 panic(
"SSID %#x out of range, max=%#x", ssid, max_ssid);
1419 bits(ssid, 24, split) *
sizeof(l2_ptr);
1426 doReadConfig(yield, l2_addr, &l2_ptr,
sizeof(l2_ptr), sid, ssid);
1428 DPRINTF(
SMMUv3,
"Got L1CD at %#x: 0x%016x\n", l2_addr, l2_ptr);
1430 cd_addr = l2_ptr +
bits(ssid, split-1, 0) *
sizeof(
cd);
1443 doReadConfig(yield, cd_addr, &cd,
sizeof(cd), sid, ssid);
1445 DPRINTF(
SMMUv3,
"Got CD at %#x [0]: 0x%016x\n", cd_addr, cd.dw0);
1446 DPRINTF(
SMMUv3,
" CD at %#x [1]: 0x%016x\n", cd_addr, cd.dw1);
1447 DPRINTF(
SMMUv3,
" CD at %#x [2]: 0x%016x\n", cd_addr, cd.dw2);
1456 panic(
"CD @ %#x not valid\n", cd_addr);
1463 void *ptr,
size_t size,
1464 uint32_t sid, uint32_t ssid)
1466 doRead(yield, addr, ptr, size);
1471 void *ptr,
unsigned stage,
1479 doRead(yield, base, ptr, pte_size);
#define panic(...)
This implements a cprintf based panic() function.
static SMMUTranslRequest prefetch(Addr addr, uint32_t sid, uint32_t ssid)
void sendEvent(Yield &yield, const SMMUEvent &ev)
void ifcTLBUpdate(Yield &yield, const TranslResult &tr)
void store(const Entry &incoming, AllocPolicy alloc)
void doDelay(Yield &yield, Cycles cycles)
void walkCacheLookup(Yield &yield, const WalkCache::Entry *&walkEntry, Addr addr, uint16_t asid, uint16_t vmid, unsigned stage, unsigned level)
Cycles is a wrapper class for representing cycle counts, i.e.
void doReadSTE(Yield &yield, StreamTableEntry &ste, uint32_t sid)
void completePrefetch(Yield &yield)
Stats::Distribution translationTimeDist
const std::string & name()
void hazard4kHold(Yield &yield)
virtual void main(Yield &yield)
const Entry * lookup(uint32_t sid, uint32_t ssid, Addr va, bool updStats=true)
void smmuTLBUpdate(Yield &yield, const TranslResult &tr)
const Entry * lookup(Addr ipa, uint16_t vmid, bool updStats=true)
void store(const Entry &incoming)
void makeTimingResponse()
void hazardIdHold(Yield &yield)
virtual Addr index(Addr va, unsigned level) const =0
void doReadConfig(Yield &yield, Addr addr, void *ptr, size_t size, uint32_t sid, uint32_t ssid)
SMMUSignal dependentReqRemoved
uint8_t stage2TranslGranule
void scheduleSlaveRetries()
void signalDrainDone() const
Signal that an object is drained.
const unsigned walkCacheS1Levels
unsigned pendingMemAccesses
const unsigned masterPortWidth
SMMUv3SlaveInterface * ifc
Stats::Scalar steL1Fetches
TranslResult translateStage1And2(Yield &yield, Addr addr)
unsigned wrBufSlotsRemaining
TranslResult bypass(Addr addr) const
const bool microTLBEnable
virtual Addr walkMask(unsigned level) const =0
bool microTLBLookup(Yield &yield, TranslResult &tr)
virtual bool isWritable(pte_t pte, unsigned level, bool stage2) const =0
void doBroadcastSignal(SMMUSignal &sig)
void walkCacheUpdate(Yield &yield, Addr va, Addr vaMask, Addr pa, unsigned stage, unsigned level, bool leaf, uint8_t permissions)
std::list< SMMUTranslationProcess * > dependentReads[SMMU_MAX_TRANS_ID]
std::list< SMMUTranslationProcess * > dependentWrites[SMMU_MAX_TRANS_ID]
bool smmuTLBLookup(Yield &yield, TranslResult &tr)
SMMUSemaphore microTLBSem
virtual unsigned lastLevel() const =0
CallerType: A reference to an object of this class will be passed to the coroutine task...
unsigned xlateSlotsRemaining
Stats::Scalar cdL1Fetches
const bool prefetchReserveLastWay
void hazardIdRegister()
Used to force ordering on transactions with the same orderId.
RequestPtr req
A pointer to the original request.
Bitfield< 51, 6 > s1ctxptr
uint8_t stage1TranslGranule
void doRead(Yield &yield, Addr addr, void *ptr, size_t size)
TranslResult combineTranslations(const TranslResult &s1tr, const TranslResult &s2tr) const
bool isAtomicMode() const
Is the system in atomic mode?
Tick curTick()
The current simulated tick.
void beginTransaction(const SMMUTranslRequest &req)
std::string csprintf(const char *format, const Args &...args)
void doWrite(Yield &yield, Addr addr, const void *ptr, size_t size)
virtual Addr nextLevelPointer(pte_t pte, unsigned level) const =0
TranslResult smmuTranslation(Yield &yield)
void makeAtomicResponse()
uint64_t Tick
Tick count type.
Stats::Distribution ptwTimeDist
void doSemaphoreUp(SMMUSemaphore &sem)
void scheduleWakeup(Tick when)
SMMUTranslationProcess(const std::string &name, SMMUv3 &_smmu, SMMUv3SlaveInterface &_ifc)
virtual bool isValid(pte_t pte, unsigned level) const =0
const Entry * lookup(Addr va, uint16_t asid, uint16_t vmid, bool updStats=true)
static SMMUTranslRequest fromPacket(PacketPtr pkt, bool ats=false)
void store(const Entry &incoming)
void completeTransaction(Yield &yield, const TranslResult &tr)
Bitfield< 63, 59 > s1cdmax
virtual bool isLeaf(pte_t pte, unsigned level) const =0
SMMUSignal duplicateReqRemoved
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
SMMUSemaphore masterPortSem
static OrderID orderId(PacketPtr pkt)
#define ULL(N)
uint64_t constant
void doReadCD(Yield &yield, ContextDescriptor &cd, const StreamTableEntry &ste, uint32_t sid, uint32_t ssid)
Bitfield< 37, 32 > s2t0sz
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
void store(const Entry &incoming)
SMMUv3SlaveInterface & ifc
This is an implementation of the SMMUv3 architecture.
TranslResult walkStage1And2(Yield &yield, Addr addr, const PageTableOps *pt_ops, unsigned level, Addr walkPtr)
const Entry * lookup(uint32_t sid, uint32_t ssid, bool updStats=true)
bool ifcTLBLookup(Yield &yield, TranslResult &tr, bool &wasPrefetched)
void setAddr(Addr _addr)
Update the address of this packet mid-transaction.
TranslResult walkStage2(Yield &yield, Addr addr, bool final_tr, const PageTableOps *pt_ops, unsigned level, Addr walkPtr)
SMMUAction runProcessTiming(SMMUProcess *proc, PacketPtr pkt)
void doReadPTE(Yield &yield, Addr va, Addr addr, void *ptr, unsigned stage, unsigned level)
void doWaitForSignal(Yield &yield, SMMUSignal &sig)
void store(const Entry &incoming)
const Entry * lookup(Addr va, Addr vaMask, uint16_t asid, uint16_t vmid, unsigned stage, unsigned level, bool updStats=true)
void issuePrefetch(Addr addr)
const PageTableOps * getPageTableOps(uint8_t trans_granule)
const bool walkCacheNonfinalEnable
std::enable_if<!std::is_same< T, void >::value, T >::type get()
get() is the way we can extrapolate arguments from the coroutine caller.
const bool walkCacheEnable
void doSemaphoreDown(Yield &yield, SMMUSemaphore &sem)
SMMUTranslRequest request
const bool ipaCacheEnable
void microTLBUpdate(Yield &yield, const TranslResult &tr)
const unsigned walkCacheS2Levels
void configCacheUpdate(Yield &yield, const TranslContext &tc)
virtual ~SMMUTranslationProcess()
bool isTimingMode() const
Is the system in timing mode?
bool configCacheLookup(Yield &yield, TranslContext &tc)
const std::string name() const
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
const bool prefetchEnable
const bool configCacheEnable
virtual Addr pageMask(pte_t pte, unsigned level) const =0
bool findConfig(Yield &yield, TranslContext &tc, TranslResult &tr)
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
std::list< SMMUTranslationProcess * > duplicateReqs
virtual unsigned firstLevel(uint8_t tsz) const =0
SMMUSemaphore slavePortSem
TranslResult translateStage2(Yield &yield, Addr addr, bool final_tr)
bool hazard4kCheck()
Used to force ordering on transactions with same (SID, SSID, 4k page) to avoid multiple identical pag...