From 78f23ad2dfe2b80ed48900f400d5157e0d92e768 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Adserias?= <33020671+saul44203@users.noreply.github.com> Date: Mon, 11 Dec 2023 19:14:40 +0100 Subject: [PATCH] arch-riscv: squash walks with tlb hits in startWalkWrapper Change-Id: I1bdfd7b2ee02ddee5a2d4c13bafc8c472f555f61 --- src/arch/riscv/pagetable_walker.cc | 45 ++++++++++++++++++++++++------ src/arch/riscv/tlb.hh | 3 +- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/src/arch/riscv/pagetable_walker.cc b/src/arch/riscv/pagetable_walker.cc index cbd5bd2b22..3700a48706 100644 --- a/src/arch/riscv/pagetable_walker.cc +++ b/src/arch/riscv/pagetable_walker.cc @@ -200,8 +200,19 @@ Walker::startWalkWrapper() { unsigned num_squashed = 0; WalkerState *currState = currStates.front(); + + // check if we get a tlb hit to skip the walk + Addr vaddr = Addr(sext(currState->req->getVaddr())); + TlbEntry *e = tlb->lookup(vaddr, currState->satp.asid, currState->mode, + true); + Fault fault = NoFault; + if (e) { + fault = tlb->checkPermissions(currState->status, currState->pmode, + vaddr, currState->mode, e->pte); + } + while ((num_squashed < numSquashable) && currState && - currState->translation->squashed()) { + (currState->translation->squashed() || (e && fault == NoFault))) { currStates.pop_front(); num_squashed++; @@ -209,9 +220,14 @@ Walker::startWalkWrapper() currState->req->getVaddr()); // finish the translation which will delete the translation object - currState->translation->finish( - std::make_shared("Squashed Inst"), - currState->req, currState->tc, currState->mode); + if (currState->translation->squashed()) { + currState->translation->finish( + std::make_shared("Squashed Inst"), + currState->req, currState->tc, currState->mode); + } else { + tlb->translateTiming(currState->req, currState->tc, + currState->translation, currState->mode); + } // delete the current request if there are no inflight packets. // if there is something in flight, delete when the packets are @@ -223,13 +239,26 @@ Walker::startWalkWrapper() } // check the next translation request, if it exists - if (currStates.size()) + if (currStates.size()) { currState = currStates.front(); - else + vaddr = Addr(sext(currState->req->getVaddr())); + e = tlb->lookup(vaddr, currState->satp.asid, currState->mode, + true); + if (e) { + fault = tlb->checkPermissions(currState->status, + currState->pmode, vaddr, + currState->mode, e->pte); + } + } else { currState = NULL; + } + } + if (currState && !currState->wasStarted()) { + if (!e || fault != NoFault) + currState->startWalk(); + else + schedule(startWalkWrapperEvent, clockEdge(Cycles(1))); } - if (currState && !currState->wasStarted()) - currState->startWalk(); } Fault diff --git a/src/arch/riscv/tlb.hh b/src/arch/riscv/tlb.hh index f37143dfb7..10a0512c90 100644 --- a/src/arch/riscv/tlb.hh +++ b/src/arch/riscv/tlb.hh @@ -134,12 +134,11 @@ class TLB : public BaseTLB BaseMMU::Mode mode) override; Fault finalizePhysical(const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode) const override; + TlbEntry *lookup(Addr vpn, uint16_t asid, BaseMMU::Mode mode, bool hidden); private: uint64_t nextSeq() { return ++lruSeq; } - TlbEntry *lookup(Addr vpn, uint16_t asid, BaseMMU::Mode mode, bool hidden); - void evictLRU(); void remove(size_t idx);