63#include "debug/PageTableWalker.hh"
94 *result_entry = newState->
entry;
118 return walker->recvTimingResp(pkt);
127 bool walkComplete = senderWalk->
recvPacket(pkt);
133 if (walkerState == senderWalk) {
162 walkerState->
retry();
171 if (
port.sendTimingReq(pkt)) {
186 if (if_name ==
"port")
239 unsigned num_squashed = 0;
249 fault =
tlb->checkPermissions(currState->
tc, currState->
memaccess,
250 e->vaddr, currState->
mode,
e->pte);
258 DPRINTF(PageTableWalker,
"Squashing table walk for address %#x\n",
259 currState->
req->getVaddr());
264 std::make_shared<UnimpFault>(
"Squashed Inst"),
265 currState->
req, currState->
tc, currState->
mode);
267 tlb->translateTiming(currState->
req, currState->
tc,
285 e =
tlb->lookup(vpn, currState->
satp.asid, currState->
mode,
288 fault =
tlb->checkPermissions(currState->
tc,
331 if (guest_paddr & ~maxgpa) {
363 walker->port.sendAtomic(write);
434 if (msbs != 0 && msbs != mask_for_msbs) {
449 panic_if(misa.rvh,
"Timing walks are not supported with h extension");
477 walker->port.sendAtomic(write);
499 if (msbs != 0 && msbs != mask_for_msbs) {
516 panic_if(misa.rvh,
"Timing walks are not supported with h extension");
531 Addr guest_paddr = pte_addr;
535 if (fault !=
NoFault) {
return fault; }
536 pte_addr = host_paddr;
559 pte_addr =
read->req->getPaddr();
569 walker->port.sendAtomic(write);
608 Addr host_page_address;
610 if (fault !=
NoFault) {
return fault; }
641 logBytes =
entry.logBytes;
654 if (!pte.v || (!pte.r && pte.w)) {
660 if (pte.r || pte.x) {
674 if (
level >= 1 && pte.ppn0 != 0)
678 else if (
level == 2 && pte.ppn1 != 0)
685 "SVNAPOT PTE has wrong encoding, \
711 PTESv39 pte =
read->getLE<uint64_t>();
717 DPRINTF(PageTableWalker,
"Got level%d PTE: %#x\n",
level, pte);
762 assert(!(pte.n) ||
level == 0);
764 entry.paddr = (pte.n) ?
768 entry.logBytes = (pte.n) ?
797 walker->pagewalkerstats.num_2mb_walks++;
800 walker->pagewalkerstats.num_4kb_walks++;
803 "#1 leaf node at level %d, with vpn %#x\n",
819 nextRead = (pte.ppn <<
PageShift) + (idx *
sizeof(pte));
837 write->
setLE<uint64_t>(pte);
854 RequestPtr request = std::make_shared<Request>(
874 PTESv39 pte =
read->getLE<uint64_t>();
880 DPRINTF(PageTableWalker,
"[GSTAGE]: Got level%d PTE: %#x\n",
glevel, pte);
925 assert(!(pte.n) ||
glevel == 0);
927 entry.paddr = (pte.n) ?
931 entry.logBytes = (pte.n) ?
957 walker->pagewalkerstats.num_2mb_walks++;
961 walker->pagewalkerstats.num_64kb_walks++;
964 walker->pagewalkerstats.num_4kb_walks++;
968 "[GSTAGE] #1 leaf node at level %d, with vpn %#x\n",
983 nextRead = (pte.ppn <<
PageShift) + (idx *
sizeof(pte));
1000 write->
setLE<uint64_t>(pte);
1022 RequestPtr request = std::make_shared<Request>(
1054 pte_addr = (
satp.ppn <<
PageShift) + (idx *
sizeof(PTESv39));
1063 (idx *
sizeof(PTESv39));
1068 panic(
"Unknown translation stage!");
1125 req->setPaddr(paddr);
1160 if (!
walker->sendTiming(
this, pkt)) {
1172 if (!
walker->sendTiming(
this, write)) {
1185 RequestPtr request = std::make_shared<Request>(
1186 paddr, bytes, flags,
walker->requestorId);
1239 "Completed page walks with 4KB pages"),
1241 "Completed page walks with 64KB pages"),
1243 "Completed page walks with 2MB pages")
virtual bool squashed() const
This function is used by the page table walker to determine if it should translate the a pending requ...
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode)=0
Tick clockEdge(Cycles cycles=Cycles(0)) const
Determine the tick when a cycle begins, by default the current one, but the argument also enables the...
Cycles is a wrapper class for representing cycle counts, i.e.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void setLE(T v)
Set the value in the data pointer to v as little endian.
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
void pushSenderState(SenderState *sender_state)
Push a new sender state to the packet and make the current sender state the predecessor of the new on...
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
RequestPtr req
A pointer to the original request.
MemCmd cmd
The command field of the packet.
void allocate()
Allocate memory for the packet.
Ports are used to interface objects to each other.
@ PHYSICAL
The virtual address is also the physical address.
gem5::Flags< FlagsType > Flags
void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
Fault startFunctional(Addr &addr, unsigned &logBytes)
PacketPtr createReqPacket(Addr paddr, MemCmd cmd, size_t bytes)
bool recvPacket(PacketPtr pkt)
std::vector< PacketPtr > writes
Fault walkTwoStage(Addr vaddr)
Fault guestToHostPage(Addr vaddr)
Fault stepWalkGStage(PacketPtr &write)
Fault stepWalk(PacketPtr &write)
Fault checkPTEPermissions(PTESv39 pte, WalkFlags &stepWalkFlags, int level)
BaseMMU::Translation * translation
Fault walkOneStage(Addr vaddr)
Fault walkGStage(Addr guest_paddr, Addr &host_paddr)
unsigned numInflight() const
void initState(ThreadContext *_tc, BaseMMU::Mode _mode, bool _isTiming=false)
Addr setupWalk(Addr vaddr)
Fault startFunctional(ThreadContext *_tc, Addr &addr, unsigned &logBytes, BaseMMU::Mode mode)
EventFunctionWrapper startWalkWrapperEvent
Event used to call startWalkWrapper.
Fault start(ThreadContext *_tc, BaseMMU::Translation *translation, const RequestPtr &req, BaseMMU::Mode mode, TlbEntry *result_entry=nullptr)
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
bool sendTiming(WalkerState *sendingState, PacketPtr pkt)
bool recvTimingResp(PacketPtr pkt)
std::list< WalkerState * > currStates
ThreadContext is the external interface to all thread state for anything outside of the CPU.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
constexpr uint64_t sext(uint64_t val)
Sign-extend an N-bit value to 64 bits.
void schedule(Event &event, Tick when)
#define panic(...)
This implements a cprintf based panic() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
const Addr SV39X4_WIDENED_BITS
const Addr SV39_VADDR_BITS
Addr getVPNFromVAddr(Addr vaddr, Addr mode)
const Addr SV39_LEVEL_BITS
Copyright (c) 2024 Arm Limited All rights reserved.
std::shared_ptr< FaultBase > Fault
std::shared_ptr< Request > RequestPtr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
constexpr decltype(nullptr) NoFault
Declaration of a request, the overall memory request consisting of the parts of the request that are ...
PagewalkerStats(statistics::Group *parent)
statistics::Scalar num_64kb_walks
statistics::Scalar num_4kb_walks
statistics::Scalar num_2mb_walks