Go to the documentation of this file.
65 DPRINTF(GPUPTWalker,
"Vega walker walker: %p funcState: %p "
66 "funcState->walker %p\n",
77 DPRINTF(GPUPTWalker,
"Vega walker starting with addr: %#lx "
84 DPRINTF(GPUPTWalker,
"Sending functional read to %#lx\n",
97 logBytes =
entry.logBytes;
110 DPRINTF(GPUPTWalker,
"Vega walker starting with addr: %#lx "
126 DPRINTF(GPUPTWalker,
"Walker::WalkerState::initState\n");
127 DPRINTF(GPUPTWalker,
"Walker::WalkerState::initState %p\n",
this);
128 DPRINTF(GPUPTWalker,
"Walker::WalkerState::initState %d\n",
state);
129 assert(
state == Ready);
133 timing = !is_functional;
144 Addr pde2Addr = (((
baseAddr >> 6) << 3) + (logical_addr >> 3*9)) << 3;
145 DPRINTF(GPUPTWalker,
"Walk PDE2 address is %#lx\n", pde2Addr);
148 entry.vaddr = logical_addr;
153 RequestPtr request = std::make_shared<Request>(
154 pde2Addr, dataSize,
flags, walker->deviceRequestorId);
165 DPRINTF(GPUPTWalker,
"Sending timing read to %#lx\n",
173 timingFault = stepWalk();
174 assert(timingFault ==
NoFault || read == NULL);
179 DPRINTF(GPUPTWalker,
"Sending timing read to %#lx\n",
184 entry.paddr = entry.pte.ppn <<
PageShift;
185 entry.paddr += entry.vaddr &
mask(entry.logBytes);
190 walker->tlb->insert(entry.vaddr, entry);
193 walker->walkerResponse(
this, entry, tlbPkt);
201 assert(
state != Ready &&
state != Waiting && read);
205 bool uncacheable = !pte.c;
207 bool doEndWalk =
false;
209 walkStateMachine(pte, nextRead, doEndWalk, fault);
212 DPRINTF(GPUPTWalker,
"ending walk\n");
220 RequestPtr request = std::make_shared<Request>(
221 nextRead, oldRead->
getSize(),
flags, walker->deviceRequestorId);
234 bool &doEndWalk,
Fault &fault)
240 PageDirectoryEntry pde =
static_cast<PageDirectoryEntry
>(pte);
244 panic_if(pde.blockFragmentSize,
"PDE blockFragmentSize must be 0");
249 DPRINTF(GPUPTWalker,
"Treating PDE2 as PTE: %#016x frag: %d\n",
250 (uint64_t)pte, pte.fragment);
255 entry.vaddr = entry.vaddr & ~
mask(entry.logBytes);
260 part1 = ((((uint64_t)pte) >> 6) << 3);
261 part2 = offsetFunc(
vaddr, 3*9, 2*9);
262 nextRead = ((part1 + part2) << 3) &
mask(48);
264 "Got PDE2 entry %#016x. write:%s->%#016x va:%#016x\n",
265 (uint64_t)pte, pte.w == 0 ?
"yes" :
"no", nextRead,
vaddr);
270 DPRINTF(GPUPTWalker,
"Treating PDE1 as PTE: %#016x frag: %d\n",
271 (uint64_t)pte, pte.fragment);
276 entry.vaddr = entry.vaddr & ~
mask(entry.logBytes);
281 part1 = ((((uint64_t)pte) >> 6) << 3);
282 part2 = offsetFunc(
vaddr, 2*9, 9);
283 nextRead = ((part1 + part2) << 3) &
mask(48);
285 "Got PDE1 entry %#016x. write:%s->%#016x va: %#016x\n",
286 (uint64_t)pte, pte.w == 0 ?
"yes" :
"no", nextRead,
vaddr);
291 DPRINTF(GPUPTWalker,
"Treating PDE0 as PTE: %#016x frag: %d\n",
292 (uint64_t)pte, pte.fragment);
297 entry.vaddr = entry.vaddr & ~
mask(entry.logBytes);
301 part1 = ((((uint64_t)pte) >> 6) << 3);
302 part2 = offsetFunc(
vaddr, 9, 0);
303 nextRead = ((part1 + part2) << 3) &
mask(48);
305 "Got PDE0 entry %#016x. write:%s->%#016x va:%#016x\n",
306 (uint64_t)pte, pte.w == 0 ?
"yes" :
"no", nextRead,
vaddr);
311 " PTE entry %#016x. write: %s va: %#016x\n",
312 (uint64_t)pte, pte.w == 0 ?
"yes" :
"no",
vaddr);
316 entry.vaddr = entry.vaddr & ~
mask(entry.logBytes);
320 panic(
"Unknown page table walker state %d!\n");
323 if (badNX || !pte.v) {
325 fault = pageFault(pte.v);
336 walker->currStates.remove(
this);
349 if (!walker->sendTiming(
this, read)) {
350 DPRINTF(GPUPTWalker,
"Timing request for %#lx failed\n",
355 DPRINTF(GPUPTWalker,
"Timing request for %#lx successful\n",
366 DPRINTF(GPUPTWalker,
"Sending timing read to %#lx from walker %p\n",
367 pkt->
getAddr(), sending_walker);
380 walker->recvTimingResp(pkt);
391 DPRINTF(GPUPTWalker,
"Got response for %#lx from walker %p -- %#lx\n",
401 walker->recvReqRetry();
411 walkerState->
retry();
444 DPRINTF(GPUPTWalker,
"Raising page fault.\n");
454 return std::make_shared<PageFault>(entry.vaddr, code,
present,
mode,
true);
462 return ((logicalAddr & ((1 <<
top) - 1)) >> lsb);
472 if (if_name ==
"port")
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
constexpr decltype(nullptr) NoFault
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
Walker * getWalker() const
Fault pageFault(bool present)
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...
RequestPtr req
A pointer to the original request.
void recvTimingResp(PacketPtr pkt)
Fault startFunctional(Addr base, Addr vaddr, PageTableEntry &pte, unsigned &logBytes)
void startTiming(PacketPtr pkt, Addr base, Addr vaddr, BaseMMU::Mode mode)
void walkerResponse(VegaTlbEntry &entry, PacketPtr pkt)
memory::AbstractMemory * getDeviceMemory(const PacketPtr &pkt) const
Return a pointer to the device memory.
bool sendTiming(WalkerState *sendingState, PacketPtr pkt)
constexpr uint64_t mask(unsigned nbits)
Generate a 64-bit mask of 'nbits' 1s, right justified.
Bitfield< 11, 7 > fragment
Fault startFunctional(Addr base, Addr vaddr, PageTableEntry &pte, unsigned &logBytes, BaseMMU::Mode mode)
void walkerResponse(WalkerState *state, VegaTlbEntry &entry, PacketPtr pkt)
std::shared_ptr< FaultBase > Fault
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
ProbePointArg< PacketInfo > Packet
Packet probe point.
uint64_t offsetFunc(Addr logicalAddr, int top, int lsb)
std::shared_ptr< Request > RequestPtr
@ UNCACHEABLE
The request is to an uncacheable address.
std::list< WalkerState * > currStates
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
gem5 methods
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
Ports are used to interface objects to each other.
void initState(BaseMMU::Mode _mode, Addr baseAddr, Addr vaddr, bool is_functional=false)
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
@ PHYSICAL
The virtual address is also the physical address.
void sendPackets()
Port related methods.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
void walkStateMachine(PageTableEntry &pte, Addr &nextRead, bool &doEndWalk, Fault &fault)
#define panic(...)
This implements a cprintf based panic() function.
Generated on Sun Jul 30 2023 01:56:47 for gem5 by doxygen 1.8.17