[gem5-dev] Change in gem5/gem5[develop]: arch-arm: Allowing table descriptor to be inserted in TLB
Bobby Bruce has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/52125 ) Change subject: arch-arm: Allowing table descriptor to be inserted in TLB .. arch-arm: Allowing table descriptor to be inserted in TLB This patch is modifying both TableWalker and MMU to effectively store/use partial translations * TableWalker changes: If there is a TLB supporting partial translations (implemented with previous patch), the TableWalker will craft partial entries and forward them to the TLB as walks are performed * MMU changes: We now instruct the table walker to start a page table traversal even if we hit in the TLB, if the matching entry holds a partial translation JIRA: https://gem5.atlassian.net/browse/GEM5-1108 Change-Id: Id20aaf4ea02960d50d8345f3e174c698af21ad1c Signed-off-by: Giacomo Travaglini Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/52125 Reviewed-by: Andreas Sandberg Maintainer: Andreas Sandberg Tested-by: kokoro --- M src/arch/arm/mmu.cc M src/arch/arm/table_walker.cc M src/arch/arm/table_walker.hh 3 files changed, 176 insertions(+), 45 deletions(-) Approvals: Andreas Sandberg: Looks good to me, approved; Looks good to me, approved Giacomo Travaglini: Looks good to me, approved; Looks good to me, approved kokoro: Regressions pass diff --git a/src/arch/arm/mmu.cc b/src/arch/arm/mmu.cc index f4a2114..79a5240 100644 --- a/src/arch/arm/mmu.cc +++ b/src/arch/arm/mmu.cc @@ -1471,7 +1471,7 @@ fault = getTableWalker(mode, state.isStage2)->walk( req, tc, state.asid, state.vmid, state.isHyp, mode, translation, timing, functional, is_secure, -tran_type, state.stage2DescReq); +tran_type, state.stage2DescReq, *te); // for timing mode, return and wait for table walk, if (timing || fault != NoFault) { diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc index c70d856..f94e765 100644 --- a/src/arch/arm/table_walker.cc +++ b/src/arch/arm/table_walker.cc @@ -290,7 +290,7 @@ vmid_t _vmid, bool _isHyp, MMU::Mode _mode, MMU::Translation *_trans, bool _timing, bool _functional, bool secure, MMU::ArmTranslationType tranType, - bool _stage2Req) + bool _stage2Req, const TlbEntry *walk_entry) { assert(!(_functional && _timing)); ++stats.walks; @@ -344,6 +344,11 @@ } currState->transState = _trans; currState->req = _req; +if (walk_entry) { +currState->walkEntry = *walk_entry; +} else { +currState->walkEntry = TlbEntry(); +} currState->fault = NoFault; currState->asid = _asid; currState->vmid = _vmid; @@ -494,11 +499,15 @@ // a match, we just want to get rid of the walk. The latter could happen // when there are multiple outstanding misses to a single page and a // previous request has been successfully translated. -if (!currState->transState->squashed() && !te) { +if (!currState->transState->squashed() && (!te || te->partial)) { // We've got a valid request, lets process it pending = true; pendingQueue.pop_front(); // Keep currState in case one of the processWalk... calls NULLs it + +if (te && te->partial) { +currState->walkEntry = *te; +} WalkerState *curr_state_copy = currState; Fault f; if (currState->aarch64) @@ -897,7 +906,6 @@ currState->tcr, currState->el); -LookupLevel start_lookup_level = LookupLevel::Num_ArmLookupLevel; bool vaddr_fault = false; switch (currState->el) { case EL0: @@ -959,11 +967,6 @@ tsz = 64 - currState->vtcr.t0sz64; tg = GrainMap_tg0[currState->vtcr.tg0]; -start_lookup_level = getPageTableOps(tg)->firstS2Level( -currState->vtcr.sl0); - -panic_if(start_lookup_level == LookupLevel::Num_ArmLookupLevel, - "Cannot discern lookup level from vtcr.{sl0,tg0}"); ps = currState->vtcr.ps; currState->isUncacheable = currState->vtcr.irgn0 == 0; } else { @@ -1096,15 +1099,6 @@ tg = Grain4KB; } -// Determine starting lookup level -if (start_lookup_level == LookupLevel::Num_ArmLookupLevel) { -const auto* ptops = getPageTableOps(tg); - -start_lookup_level = ptops->firstLevel(64 - tsz); -panic_if(start_lookup_level == LookupLevel::Num_ArmLookupLevel, - "Table walker couldn't find lookup level\n"); -} - // Clamp to lower limit int pa_range = decodePhysAddrRange64(ps); if (pa_range > _physAddrRange) { @@ -1113,22 +1107,12 @@ currState->physAddrRange = pa_range; } -// Determine table base address -int stride = tg - 3; -int base_addr_lo = 3 + tsz -
[gem5-dev] Change in gem5/gem5[develop]: arch-arm: Allowing table descriptor to be inserted in TLB
Giacomo Travaglini has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/52125 ) Change subject: arch-arm: Allowing table descriptor to be inserted in TLB .. arch-arm: Allowing table descriptor to be inserted in TLB This patch is modifying both TableWalker and MMU to effectively store/use partial translations * TableWalker changes: If there is a TLB supporting partial translations (implemented with previous patch), the TableWalker will craft partial entries and forward them to the TLB as walks are performed * MMU changes: We now instruct the table walker to start a page table traversal even if we hit in the TLB, if the matching entry holds a partial translation JIRA: https://gem5.atlassian.net/browse/GEM5-1108 Change-Id: Id20aaf4ea02960d50d8345f3e174c698af21ad1c Signed-off-by: Giacomo Travaglini --- M src/arch/arm/mmu.cc M src/arch/arm/table_walker.cc M src/arch/arm/table_walker.hh 3 files changed, 167 insertions(+), 45 deletions(-) diff --git a/src/arch/arm/mmu.cc b/src/arch/arm/mmu.cc index 6b6d10c..f35f665 100644 --- a/src/arch/arm/mmu.cc +++ b/src/arch/arm/mmu.cc @@ -1449,7 +1449,7 @@ *te = lookup(vaddr, state.asid, state.vmid, state.isHyp, is_secure, false, false, target_el, false, state.isStage2, mode); -if (*te == NULL) { +if (*te == nullptr || (*te)->partial) { if (req->isPrefetch()) { // if the request is a prefetch don't attempt to fill the TLB or go // any further with the memory access (here we can safely use the @@ -1469,7 +1469,7 @@ fault = getTableWalker(mode, state.isStage2)->walk( req, tc, state.asid, state.vmid, state.isHyp, mode, translation, timing, functional, is_secure, -tran_type, state.stage2DescReq); +tran_type, state.stage2DescReq, *te); // for timing mode, return and wait for table walk, if (timing || fault != NoFault) { diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc index 96170d3..271f672 100644 --- a/src/arch/arm/table_walker.cc +++ b/src/arch/arm/table_walker.cc @@ -286,7 +286,7 @@ vmid_t _vmid, bool _isHyp, MMU::Mode _mode, MMU::Translation *_trans, bool _timing, bool _functional, bool secure, MMU::ArmTranslationType tranType, - bool _stage2Req) + bool _stage2Req, const TlbEntry *walk_entry) { assert(!(_functional && _timing)); ++stats.walks; @@ -340,6 +340,11 @@ } currState->transState = _trans; currState->req = _req; +if (walk_entry) { +currState->walkEntry = *walk_entry; +} else { +currState->walkEntry = TlbEntry(); +} currState->fault = NoFault; currState->asid = _asid; currState->vmid = _vmid; @@ -892,7 +897,6 @@ currState->tcr, currState->el); -LookupLevel start_lookup_level = LookupLevel::Num_ArmLookupLevel; bool vaddr_fault = false; switch (currState->el) { case EL0: @@ -954,11 +958,6 @@ tsz = 64 - currState->vtcr.t0sz64; tg = GrainMap_tg0[currState->vtcr.tg0]; -start_lookup_level = getPageTableOps(tg)->firstS2Level( -currState->vtcr.sl0); - -panic_if(start_lookup_level == LookupLevel::Num_ArmLookupLevel, - "Cannot discern lookup level from vtcr.{sl0,tg0}"); ps = currState->vtcr.ps; currState->isUncacheable = currState->vtcr.irgn0 == 0; } else { @@ -1091,15 +1090,6 @@ tg = Grain4KB; } -// Determine starting lookup level -if (start_lookup_level == LookupLevel::Num_ArmLookupLevel) { -const auto* ptops = getPageTableOps(tg); - -start_lookup_level = ptops->firstLevel(64 - tsz); -panic_if(start_lookup_level == LookupLevel::Num_ArmLookupLevel, - "Table walker couldn't find lookup level\n"); -} - // Clamp to lower limit int pa_range = decodePhysAddrRange64(ps); if (pa_range > _physAddrRange) { @@ -1108,22 +1098,12 @@ currState->physAddrRange = pa_range; } -// Determine table base address -int stride = tg - 3; -int base_addr_lo = 3 + tsz - stride * (3 - start_lookup_level) - tg; -Addr base_addr = 0; - -if (pa_range == 52) { -int z = (base_addr_lo < 6) ? 6 : base_addr_lo; -base_addr = mbits(ttbr, 47, z); -base_addr |= (bits(ttbr, 5, 2) << 48); -} else { -base_addr = mbits(ttbr, 47, base_addr_lo); -} +auto [table_addr, desc_addr, start_lookup_level] = walkAddresses( +ttbr, tg, tsz, pa_range); // Determine physical address size and raise an Address Size Fault if // necessary -if (checkAddrSizeFaultAArch64(base_addr, currState->physAddrRange)) { +if