[gem5-dev] Change in gem5/gem5[develop]: arch-arm: Allowing table descriptor to be inserted in TLB

2021-12-11 Thread Bobby Bruce (Gerrit) via gem5-dev
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

2021-10-27 Thread Giacomo Travaglini (Gerrit) via gem5-dev
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