diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc index 57e0d9230b..395f13c2e4 100644 --- a/src/arch/arm/table_walker.cc +++ b/src/arch/arm/table_walker.cc @@ -134,7 +134,7 @@ TableWalker::WalkerState::WalkerState() : isWrite(false), isFetch(false), isSecure(false), isUncacheable(false), secureLookup(false), rwTable(false), userTable(false), xnTable(false), - pxnTable(false), hpd(false), stage2Req(false), + pxnTable(false), hpd(false), sh(0), irgn(0), orgn(0), stage2Req(false), stage2Tran(nullptr), timing(false), functional(false), mode(BaseMMU::Read), tranType(MMU::NormalTran), l2Desc(l1Desc), delayed(false), tableWalker(nullptr) @@ -907,8 +907,9 @@ TableWalker::processWalkAArch64() tg = GrainMap_tg0[currState->vtcr.tg0]; ps = currState->vtcr.ps; - currState->isUncacheable = currState->vtcr.irgn0 == 0 || - currState->vtcr.orgn0 == 0; + currState->sh = currState->vtcr.sh0; + currState->irgn = currState->vtcr.irgn0; + currState->orgn = currState->vtcr.orgn0; } else { switch (bits(currState->vaddr, top_bit)) { case 0: @@ -917,8 +918,9 @@ TableWalker::processWalkAArch64() tsz = 64 - currState->tcr.t0sz; tg = GrainMap_tg0[currState->tcr.tg0]; currState->hpd = currState->tcr.hpd0; - currState->isUncacheable = currState->tcr.irgn0 == 0 || - currState->tcr.orgn0 == 0; + currState->sh = currState->tcr.sh0; + currState->irgn = currState->tcr.irgn0; + currState->orgn = currState->tcr.orgn0; vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr, top_bit, tg, tsz, true); @@ -931,8 +933,9 @@ TableWalker::processWalkAArch64() tsz = 64 - currState->tcr.t1sz; tg = GrainMap_tg1[currState->tcr.tg1]; currState->hpd = currState->tcr.hpd1; - currState->isUncacheable = currState->tcr.irgn1 == 0 || - currState->tcr.orgn1 == 0; + currState->sh = currState->tcr.sh1; + currState->irgn = currState->tcr.irgn1; + currState->orgn = currState->tcr.orgn1; vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr, top_bit, tg, tsz, false); @@ -956,8 +959,9 @@ TableWalker::processWalkAArch64() tg = GrainMap_tg0[currState->tcr.tg0]; currState->hpd = currState->hcr.e2h ? currState->tcr.hpd0 : currState->tcr.hpd; - currState->isUncacheable = currState->tcr.irgn0 == 0 || - currState->tcr.orgn0 == 0; + currState->sh = currState->tcr.sh0; + currState->irgn = currState->tcr.irgn0; + currState->orgn = currState->tcr.orgn0; vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr, top_bit, tg, tsz, true); @@ -971,8 +975,9 @@ TableWalker::processWalkAArch64() tsz = 64 - currState->tcr.t1sz; tg = GrainMap_tg1[currState->tcr.tg1]; currState->hpd = currState->tcr.hpd1; - currState->isUncacheable = currState->tcr.irgn1 == 0 || - currState->tcr.orgn1 == 0; + currState->sh = currState->tcr.sh1; + currState->irgn = currState->tcr.irgn1; + currState->orgn = currState->tcr.orgn1; vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr, top_bit, tg, tsz, false); @@ -994,8 +999,9 @@ TableWalker::processWalkAArch64() tsz = 64 - currState->tcr.t0sz; tg = GrainMap_tg0[currState->tcr.tg0]; currState->hpd = currState->tcr.hpd; - currState->isUncacheable = currState->tcr.irgn0 == 0 || - currState->tcr.orgn0 == 0; + currState->sh = currState->tcr.sh0; + currState->irgn = currState->tcr.irgn0; + currState->orgn = currState->tcr.orgn0; vaddr_fault = checkVAddrSizeFaultAArch64(currState->vaddr, top_bit, tg, tsz, true); @@ -1010,6 +1016,9 @@ TableWalker::processWalkAArch64() break; } + currState->isUncacheable = currState->irgn == 0 || + currState->orgn == 0; + const bool is_atomic = currState->req->isAtomic(); if (fault) { @@ -1567,6 +1576,24 @@ TableWalker::memAttrsAArch64(ThreadContext *tc, TlbEntry &te, } } +void +TableWalker::memAttrsWalkAArch64(TlbEntry &te) +{ + te.mtype = TlbEntry::MemoryType::Normal; + if (uncacheableWalk()) { + te.shareable = 3; + te.outerAttrs = 0; + te.innerAttrs = 0; + te.nonCacheable = true; + } else { + te.shareable = currState->sh; + te.outerAttrs = currState->orgn; + te.innerAttrs = currState->irgn; + te.nonCacheable = (te.outerAttrs == 0 || te.outerAttrs == 2) && + (te.innerAttrs == 0 || te.innerAttrs == 2); + } +} + void TableWalker::doL1Descriptor() { @@ -2198,6 +2225,8 @@ TableWalker::insertPartialTableEntry(LongDescriptor &descriptor) te.pxn = currState->pxnTable; te.ap = (currState->rwTable << 1) | (currState->userTable); + memAttrsWalkAArch64(te); + // Debug output DPRINTF(TLB, descriptor.dbgHeader().c_str()); DPRINTF(TLB, " - N:%d pfn:%#x size:%#x global:%d valid:%d\n", diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh index bc25b62dab..2cb845caa8 100644 --- a/src/arch/arm/table_walker.hh +++ b/src/arch/arm/table_walker.hh @@ -905,6 +905,10 @@ class TableWalker : public ClockedObject /** Hierarchical access permission disable */ bool hpd; + uint8_t sh; + uint8_t irgn; + uint8_t orgn; + /** Flag indicating if a second stage of lookup is required */ bool stage2Req; @@ -1133,6 +1137,7 @@ class TableWalker : public ClockedObject LongDescriptor &lDescriptor); void memAttrsAArch64(ThreadContext *tc, TlbEntry &te, LongDescriptor &lDescriptor); + void memAttrsWalkAArch64(TlbEntry &te); static LookupLevel toLookupLevel(uint8_t lookup_level_as_int);