[gem5-dev] Change in gem5/gem5[develop]: arch-arm: Provide support for a multilevel-TLB in the ArmMMU
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
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