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);
247 if (pde.blockFragmentSize) {
249 "blockFragmentSize: %d, pde: %#016lx, state: %d\n",
250 pde.blockFragmentSize, pde,
state);
256 assert(pde.blockFragmentSize == 9);
262 DPRINTF(GPUPTWalker,
"Treating PDE2 as PTE: %#016x frag: %d\n",
263 (uint64_t)pte, pte.fragment);
268 entry.vaddr = entry.vaddr & ~mask(entry.logBytes);
273 part1 = ((((uint64_t)pte) >> 6) << 3);
274 part2 = offsetFunc(
vaddr, 3*9, 2*9);
275 nextRead = ((part1 + part2) << 3) &
mask(48);
277 "Got PDE2 entry %#016x. write:%s->%#016x va:%#016x\n",
278 (uint64_t)pte, pte.w == 0 ?
"yes" :
"no", nextRead,
vaddr);
283 DPRINTF(GPUPTWalker,
"Treating PDE1 as PTE: %#016x frag: %d\n",
284 (uint64_t)pte, pte.fragment);
289 entry.vaddr = entry.vaddr & ~mask(entry.logBytes);
294 part1 = ((((uint64_t)pte) >> 6) << 3);
295 part2 = offsetFunc(
vaddr, 2*9, 9);
296 nextRead = ((part1 + part2) << 3) &
mask(48);
298 "Got PDE1 entry %#016x. write:%s->%#016x va: %#016x\n",
299 (uint64_t)pte, pte.w == 0 ?
"yes" :
"no", nextRead,
vaddr);
304 DPRINTF(GPUPTWalker,
"Treating PDE0 as PTE: %#016x frag: %d\n",
305 (uint64_t)pte, pte.fragment);
310 entry.vaddr = entry.vaddr & ~mask(entry.logBytes);
314 part1 = ((((uint64_t)pte) >> 6) << 3);
318 part2 = offsetFunc(
vaddr,
320 pde.blockFragmentSize);
322 part2 = offsetFunc(
vaddr, 9, 0);
324 nextRead = ((part1 + part2) << 3) &
mask(48);
326 "Got PDE0 entry %#016x. write:%s->%#016x va:%#016x\n",
327 (uint64_t)pte, pte.w == 0 ?
"yes" :
"no", nextRead,
vaddr);
332 " PTE entry %#016x. write: %s va: %#016x\n",
333 (uint64_t)pte, pte.w == 0 ?
"yes" :
"no",
vaddr);
337 entry.vaddr = entry.vaddr & ~mask(entry.logBytes);
341 panic(
"Unknown page table walker state %d!\n");
344 if (badNX || !pte.v) {
346 fault = pageFault(pte.v);
357 walker->currStates.remove(
this);
370 if (!walker->sendTiming(
this, read)) {
371 DPRINTF(GPUPTWalker,
"Timing request for %#lx failed\n",
376 DPRINTF(GPUPTWalker,
"Timing request for %#lx successful\n",
387 DPRINTF(GPUPTWalker,
"Sending timing read to %#lx from walker %p\n",
388 pkt->
getAddr(), sending_walker);
402 walker->recvTimingResp(pkt);
413 DPRINTF(GPUPTWalker,
"Got response for %#lx from walker %p -- %#lx\n",
423 walker->recvReqRetry();
433 walkerState->
retry();
466 DPRINTF(GPUPTWalker,
"Raising page fault.\n");
476 return std::make_shared<PageFault>(entry.vaddr, code,
present,
mode,
true);
484 return ((logicalAddr & ((1 <<
top) - 1)) >> lsb);
494 if (if_name ==
"port")
AbstractMemory declaration.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
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.
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
Ports are used to interface objects to each other.
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
@ PHYSICAL
The virtual address is also the physical address.
@ UNCACHEABLE
The request is to an uncacheable address.
memory::AbstractMemory * getDeviceMemory(const PacketPtr &pkt) const
Return a pointer to the device memory.
void walkerResponse(VegaTlbEntry &entry, PacketPtr pkt)
bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
Fault pageFault(bool present)
Fault startFunctional(Addr base, Addr vaddr, PageTableEntry &pte, unsigned &logBytes)
void initState(BaseMMU::Mode _mode, Addr baseAddr, Addr vaddr, bool is_functional=false)
uint64_t offsetFunc(Addr logicalAddr, int top, int lsb)
Walker * getWalker() const
void walkStateMachine(PageTableEntry &pte, Addr &nextRead, bool &doEndWalk, Fault &fault)
void sendPackets()
Port related methods.
void recvTimingResp(PacketPtr pkt)
void walkerResponse(WalkerState *state, VegaTlbEntry &entry, PacketPtr pkt)
bool sendTiming(WalkerState *sendingState, PacketPtr pkt)
Fault startFunctional(Addr base, Addr vaddr, PageTableEntry &pte, unsigned &logBytes, BaseMMU::Mode mode)
std::list< WalkerState * > currStates
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
gem5 methods
void startTiming(PacketPtr pkt, Addr base, Addr vaddr, BaseMMU::Mode mode)
#define panic(...)
This implements a cprintf based panic() function.
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Bitfield< 11, 7 > fragment
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
std::shared_ptr< FaultBase > Fault
T safe_cast(U &&ref_or_ptr)
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