X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Farch%2Friscv%2Fpagetable_walker.cc;h=786cb8193ed623f6591338eb0eefc4b11d2e281f;hb=187ba10c922f82c80c38c44557802a222c5da07e;hp=02d2d945b28b2b050f9d7341f13e010637c53618;hpb=2527c6c9da9b6585495a5b8dd0ca05fdaeb57f21;p=gem5.git diff --git a/src/arch/riscv/pagetable_walker.cc b/src/arch/riscv/pagetable_walker.cc index 02d2d945b..786cb8193 100644 --- a/src/arch/riscv/pagetable_walker.cc +++ b/src/arch/riscv/pagetable_walker.cc @@ -184,6 +184,11 @@ Walker::WalkerState::initState(ThreadContext * _tc, tc = _tc; mode = _mode; timing = _isTiming; + // fetch these now in case they change during the walk + status = tc->readMiscReg(MISCREG_STATUS); + pmode = walker->tlb->getMemPriv(tc, mode); + satp = tc->readMiscReg(MISCREG_SATP); + assert(satp.mode == AddrXlateMode::SV39); } void @@ -303,7 +308,8 @@ Walker::WalkerState::stepWalk(PacketPtr &write) if (pte.r || pte.x) { // step 5: leaf PTE doEndWalk = true; - fault = walker->tlb->checkPermissions(tc, entry.vaddr, mode, pte); + fault = walker->tlb->checkPermissions(status, pmode, + entry.vaddr, mode, pte); // step 6 if (fault == NoFault) { @@ -380,10 +386,9 @@ Walker::WalkerState::stepWalk(PacketPtr &write) if (!functional) walker->tlb->insert(entry.vaddr, entry); else { - Addr offset = entry.vaddr & mask(entry.logBytes); - Addr paddr = entry.paddr << PageShift | offset; DPRINTF(PageTableWalker, "Translated %#x -> %#x\n", - entry.vaddr, paddr); + entry.vaddr, entry.paddr << PageShift | + (entry.vaddr & mask(entry.logBytes))); } } endWalk(); @@ -413,10 +418,7 @@ Walker::WalkerState::endWalk() void Walker::WalkerState::setupWalk(Addr vaddr) { - vaddr &= ((static_cast(1) << VADDR_BITS) - 1); - - SATP satp = tc->readMiscReg(MISCREG_SATP); - assert(satp.mode == AddrXlateMode::SV39); + vaddr &= (static_cast(1) << VADDR_BITS) - 1; Addr shift = PageShift + LEVEL_BITS * 2; Addr idx = (vaddr >> shift) & LEVEL_MASK; @@ -483,12 +485,12 @@ Walker::WalkerState::recvPacket(PacketPtr pkt) * permissions violations, so we'll need the return value as * well. */ - bool delayedResponse; - Fault fault = walker->tlb->doTranslate(req, tc, NULL, mode, - delayedResponse); - assert(!delayedResponse); + Addr vaddr = req->getVaddr(); + vaddr &= (static_cast(1) << VADDR_BITS) - 1; + Addr paddr = walker->tlb->translateWithTLB(vaddr, satp.asid, mode); + req->setPaddr(paddr); // Let the CPU continue. - translation->finish(fault, req, tc, mode); + translation->finish(NoFault, req, tc, mode); } else { // There was a fault during the walk. Let the CPU know. translation->finish(timingFault, req, tc, mode);