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,
308 timingFault = currState->
walk();
339 if (guest_paddr & ~maxgpa) {
371 walker->port.sendAtomic(write);
442 if (msbs != 0 && msbs != mask_for_msbs) {
457 panic_if(misa.rvh,
"Timing walks are not supported with h extension");
485 walker->port.sendAtomic(write);
507 if (msbs != 0 && msbs != mask_for_msbs) {
524 panic_if(misa.rvh,
"Timing walks are not supported with h extension");
539 Addr guest_paddr = pte_addr;
543 if (fault !=
NoFault) {
return fault; }
544 pte_addr = host_paddr;
567 pte_addr =
read->req->getPaddr();
577 walker->port.sendAtomic(write);
616 Addr host_page_address;
618 if (fault !=
NoFault) {
return fault; }
649 logBytes =
entry.logBytes;
662 if (!pte.v || (!pte.r && pte.w)) {
668 if (pte.r || pte.x) {
682 if (
level >= 1 && pte.ppn0 != 0)
686 else if (
level == 2 && pte.ppn1 != 0)
693 "SVNAPOT PTE has wrong encoding, \
719 PTESv39 pte =
read->getLE<uint64_t>();
725 DPRINTF(PageTableWalker,
"Got level%d PTE: %#x\n",
level, pte);
770 assert(!(pte.n) ||
level == 0);
772 entry.paddr = (pte.n) ?
776 entry.logBytes = (pte.n) ?
805 walker->pagewalkerstats.num_2mb_walks++;
808 walker->pagewalkerstats.num_4kb_walks++;
811 "#1 leaf node at level %d, with vpn %#x\n",
827 nextRead = (pte.ppn <<
PageShift) + (idx *
sizeof(pte));
845 write->
setLE<uint64_t>(pte);
862 RequestPtr request = std::make_shared<Request>(
882 PTESv39 pte =
read->getLE<uint64_t>();
888 DPRINTF(PageTableWalker,
"[GSTAGE]: Got level%d PTE: %#x\n",
glevel, pte);
933 assert(!(pte.n) ||
glevel == 0);
935 entry.paddr = (pte.n) ?
939 entry.logBytes = (pte.n) ?
965 walker->pagewalkerstats.num_2mb_walks++;
969 walker->pagewalkerstats.num_64kb_walks++;
972 walker->pagewalkerstats.num_4kb_walks++;
976 "[GSTAGE] #1 leaf node at level %d, with vpn %#x\n",
991 nextRead = (pte.ppn <<
PageShift) + (idx *
sizeof(pte));
1008 write->
setLE<uint64_t>(pte);
1030 RequestPtr request = std::make_shared<Request>(
1062 pte_addr = (
satp.ppn <<
PageShift) + (idx *
sizeof(PTESv39));
1071 (idx *
sizeof(PTESv39));
1076 panic(
"Unknown translation stage!");
1133 req->setPaddr(paddr);
1168 if (!
walker->sendTiming(
this, pkt)) {
1180 if (!
walker->sendTiming(
this, write)) {
1193 RequestPtr request = std::make_shared<Request>(
1194 paddr, bytes, flags,
walker->requestorId);
1247 "Completed page walks with 4KB pages"),
1249 "Completed page walks with 64KB pages"),
1251 "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