[gem5-dev] Change in gem5/gem5[develop]: arch-arm: Provide support for a multilevel-TLB in the ArmMMU

2021-08-05 Thread Giacomo Travaglini (Gerrit) via gem5-dev
Giacomo Travaglini has submitted this change. (  
https://gem5-review.googlesource.com/c/public/gem5/+/48149 )


Change subject: arch-arm: Provide support for a multilevel-TLB in the ArmMMU
..

arch-arm: Provide support for a multilevel-TLB in the ArmMMU

This is an initial implementation. It adapts the current MMU code
to account for extra levels of TLBs but it is still missing the
configurability we are looking for (to select the associativity
of the TLB and the replacement policy as an example)

JIRA: https://gem5.atlassian.net/browse/GEM5-790

Change-Id: I938ec38183337cd0e839bf3e3cd03594126128cd
Signed-off-by: Giacomo Travaglini 
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/48149
Tested-by: kokoro 
Reviewed-by: Andreas Sandberg 
Maintainer: Andreas Sandberg 
---
M src/arch/arm/mmu.cc
M src/arch/arm/mmu.hh
M src/arch/arm/table_walker.cc
M src/arch/arm/tlb.cc
M src/arch/arm/tlb.hh
5 files changed, 148 insertions(+), 22 deletions(-)

Approvals:
  Andreas Sandberg: 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 257b3e6..d2fc706 100644
--- a/src/arch/arm/mmu.cc
+++ b/src/arch/arm/mmu.cc
@@ -1089,8 +1089,16 @@

 itbStage2->setVMID(state.vmid);
 dtbStage2->setVMID(state.vmid);
-getITBPtr()->setVMID(state.vmid);
-getDTBPtr()->setVMID(state.vmid);
+
+for (auto tlb : instruction) {
+static_cast(tlb)->setVMID(state.vmid);
+}
+for (auto tlb : data) {
+static_cast(tlb)->setVMID(state.vmid);
+}
+for (auto tlb : unified) {
+static_cast(tlb)->setVMID(state.vmid);
+}

 miscRegContext = tc->contextId();
 }
@@ -1309,6 +1317,16 @@
 is_secure, tran_type, stage2 ? s2State : s1State);
 }

+TlbEntry*
+MMU::lookup(Addr va, uint16_t asid, vmid_t vmid, bool hyp, bool secure,
+bool functional, bool ignore_asn, ExceptionLevel target_el,
+bool in_host, bool stage2, BaseMMU::Mode mode)
+{
+TLB *tlb = getTlb(mode, stage2);
+return tlb->multiLookup(va, asid, vmid, hyp, secure, functional,
+ignore_asn, target_el, in_host, mode);
+}
+
 Fault
 MMU::getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, Mode  
mode,

 Translation *translation, bool timing, bool functional,
@@ -1331,9 +1349,9 @@
 vaddr = vaddr_tainted;
 }

-auto tlb = getTlb(mode, state.isStage2);
-*te = tlb->lookup(vaddr, state.asid, state.vmid, state.isHyp,  
is_secure,

-  false, false, target_el, false, mode);
+*te = lookup(vaddr, state.asid, state.vmid, state.isHyp, is_secure,  
false,

+ false, target_el, false, state.isStage2, mode);
+
 if (*te == NULL) {
 if (req->isPrefetch()) {
 // if the request is a prefetch don't attempt to fill the TLB  
or go

@@ -1361,10 +1379,8 @@
 return fault;
 }

-*te = tlb->lookup(vaddr, state.asid, state.vmid, state.isHyp,  
is_secure,

-  true, false, target_el, false, mode);
-if (!*te)
-tlb->printTlb();
+*te = lookup(vaddr, state.asid, state.vmid, state.isHyp, is_secure,
+ true, false, target_el, false, state.isStage2, mode);
 assert(*te);
 }
 return NoFault;
diff --git a/src/arch/arm/mmu.hh b/src/arch/arm/mmu.hh
index fddaa1f..0e1fd87 100644
--- a/src/arch/arm/mmu.hh
+++ b/src/arch/arm/mmu.hh
@@ -269,8 +269,15 @@
 void
 flushStage1(const OP &tlbi_op)
 {
-iflush(tlbi_op);
-dflush(tlbi_op);
+for (auto tlb : instruction) {
+static_cast(tlb)->flush(tlbi_op);
+}
+for (auto tlb : data) {
+static_cast(tlb)->flush(tlbi_op);
+}
+for (auto tlb : unified) {
+static_cast(tlb)->flush(tlbi_op);
+}
 }

 template 
@@ -285,14 +292,24 @@
 void
 iflush(const OP &tlbi_op)
 {
-getITBPtr()->flush(tlbi_op);
+for (auto tlb : instruction) {
+static_cast(tlb)->flush(tlbi_op);
+}
+for (auto tlb : unified) {
+static_cast(tlb)->flush(tlbi_op);
+}
 }

 template 
 void
 dflush(const OP &tlbi_op)
 {
-getDTBPtr()->flush(tlbi_op);
+for (auto tlb : data) {
+static_cast(tlb)->flush(tlbi_op);
+}
+for (auto tlb : unified) {
+static_cast(tlb)->flush(tlbi_op);
+}
 }

 void
@@ -325,6 +342,24 @@
 static ExceptionLevel tranTypeEL(CPSR cpsr, ArmTranslationType type);

   public:
+/** Lookup an entry in the TLB
+ * @param vpn virtual address
+ * @param asn context id/address space id to use
+ * @param vmid The virtual machine ID used for stage 2 translation
+ * @param secure if the

[gem5-dev] Change in gem5/gem5[develop]: arch-arm: Provide support for a multilevel-TLB in the ArmMMU

2021-07-15 Thread Giacomo Travaglini (Gerrit) via gem5-dev
Giacomo Travaglini has uploaded this change for review. (  
https://gem5-review.googlesource.com/c/public/gem5/+/48149 )



Change subject: arch-arm: Provide support for a multilevel-TLB in the ArmMMU
..

arch-arm: Provide support for a multilevel-TLB in the ArmMMU

This is an initial implementation. It adapts the current MMU code
to account for extra levels of TLBs but it is still missing the
configurability we are looking for (to select the associativity
of the TLB and the replacement policy as an example)

JIRA: https://gem5.atlassian.net/browse/GEM5-790

Change-Id: I938ec38183337cd0e839bf3e3cd03594126128cd
Signed-off-by: Giacomo Travaglini 
---
M src/arch/arm/mmu.cc
M src/arch/arm/mmu.hh
M src/arch/arm/tlb.cc
3 files changed, 65 insertions(+), 12 deletions(-)



diff --git a/src/arch/arm/mmu.cc b/src/arch/arm/mmu.cc
index 2ed38b5..e04df89 100644
--- a/src/arch/arm/mmu.cc
+++ b/src/arch/arm/mmu.cc
@@ -1307,6 +1307,22 @@
 is_secure, tran_type, stage2 ? s2State : s1State);
 }

+TlbEntry*
+MMU::lookup(Addr va, uint16_t asid, vmid_t vmid, bool hyp, bool secure,
+bool functional, bool ignore_asn, ExceptionLevel target_el,
+bool in_host, bool stage2, BaseMMU::Mode mode)
+{
+TLB *tlb = getTlb(mode, stage2);
+TlbEntry* te = nullptr;
+while (!te && tlb) {
+te = tlb->lookup(va, asid, vmid, hyp, secure, functional,
+ ignore_asn, target_el, in_host, mode);
+tlb = static_cast(tlb->getNextLevel());
+}
+
+return te;
+}
+
 Fault
 MMU::getTE(TlbEntry **te, const RequestPtr &req, ThreadContext *tc, Mode  
mode,

 Translation *translation, bool timing, bool functional,
@@ -1329,9 +1345,9 @@
 vaddr = vaddr_tainted;
 }

-auto tlb = getTlb(mode, state.isStage2);
-*te = tlb->lookup(vaddr, state.asid, state.vmid, state.isHyp,  
is_secure,

-  false, false, target_el, false, mode);
+*te = lookup(vaddr, state.asid, state.vmid, state.isHyp, is_secure,  
false,

+ false, target_el, false, state.isStage2, mode);
+
 if (*te == NULL) {
 if (req->isPrefetch()) {
 // if the request is a prefetch don't attempt to fill the TLB  
or go

@@ -1359,10 +1375,8 @@
 return fault;
 }

-*te = tlb->lookup(vaddr, state.asid, state.vmid, state.isHyp,  
is_secure,

-  true, false, target_el, false, mode);
-if (!*te)
-tlb->printTlb();
+*te = lookup(vaddr, state.asid, state.vmid, state.isHyp, is_secure,
+ true, false, target_el, false, state.isStage2, mode);
 assert(*te);
 }
 return NoFault;
diff --git a/src/arch/arm/mmu.hh b/src/arch/arm/mmu.hh
index b11e156..61d9c9e 100644
--- a/src/arch/arm/mmu.hh
+++ b/src/arch/arm/mmu.hh
@@ -267,8 +267,15 @@
 void
 flushStage1(const OP &tlbi_op)
 {
-iflush(tlbi_op);
-dflush(tlbi_op);
+for (auto tlb : instruction) {
+static_cast(tlb)->flush(tlbi_op);
+}
+for (auto tlb : data) {
+static_cast(tlb)->flush(tlbi_op);
+}
+for (auto tlb : unified) {
+static_cast(tlb)->flush(tlbi_op);
+}
 }

 template 
@@ -283,14 +290,24 @@
 void
 iflush(const OP &tlbi_op)
 {
-getITBPtr()->flush(tlbi_op);
+for (auto tlb : instruction) {
+static_cast(tlb)->flush(tlbi_op);
+}
+for (auto tlb : unified) {
+static_cast(tlb)->flush(tlbi_op);
+}
 }

 template 
 void
 dflush(const OP &tlbi_op)
 {
-getDTBPtr()->flush(tlbi_op);
+for (auto tlb : data) {
+static_cast(tlb)->flush(tlbi_op);
+}
+for (auto tlb : unified) {
+static_cast(tlb)->flush(tlbi_op);
+}
 }

 void
@@ -323,6 +340,24 @@
 static ExceptionLevel tranTypeEL(CPSR cpsr, ArmTranslationType type);

   public:
+/** Lookup an entry in the TLB
+ * @param vpn virtual address
+ * @param asn context id/address space id to use
+ * @param vmid The virtual machine ID used for stage 2 translation
+ * @param secure if the lookup is secure
+ * @param hyp if the lookup is done from hyp mode
+ * @param functional if the lookup should modify state
+ * @param ignore_asn if on lookup asn should be ignored
+ * @param target_el selecting the translation regime
+ * @param in_host if we are in host (EL2&0 regime)
+ * @param mode to differentiate between read/writes/fetches.
+ * @return pointer to TLB entry if it exists
+ */
+TlbEntry *lookup(Addr vpn, uint16_t asn, vmid_t vmid, bool hyp,
+ bool secure, bool functional,
+ bool ignore_asn, ExceptionLevel target_el,
+ bool in_host, bool stage2, BaseMMU::Mode mode);
+
 Fault getTE(TlbEntry **te, const