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",
87 auto devmem =
walker->system->getDeviceMemory(
read);
97 logBytes =
entry.logBytes;
109 DPRINTF(GPUPTWalker,
"Vega walker starting with addr: %#lx "
125 DPRINTF(GPUPTWalker,
"Walker::WalkerState::initState\n");
126 DPRINTF(GPUPTWalker,
"Walker::WalkerState::initState %p\n",
this);
127 DPRINTF(GPUPTWalker,
"Walker::WalkerState::initState %d\n",
state);
143 Addr pde2Addr = (((
baseAddr >> 6) << 3) + (logical_addr >> 3*9)) << 3;
144 DPRINTF(GPUPTWalker,
"Walk PDE2 address is %#lx\n", pde2Addr);
147 entry.vaddr = logical_addr;
152 RequestPtr request = std::make_shared<Request>(
164 DPRINTF(GPUPTWalker,
"Sending timing read to %#lx\n",
178 DPRINTF(GPUPTWalker,
"Sending timing read to %#lx\n",
204 bool uncacheable = !pte.c;
206 bool doEndWalk =
false;
211 DPRINTF(GPUPTWalker,
"ending walk\n");
219 RequestPtr request = std::make_shared<Request>(
220 nextRead, oldRead->
getSize(), flags,
walker->deviceRequestorId);
233 bool &doEndWalk,
Fault &fault)
239 PageDirectoryEntry pde =
static_cast<PageDirectoryEntry
>(pte);
246 if (pde.blockFragmentSize) {
248 "blockFragmentSize: %d, pde: %#016lx, state: %d\n",
249 pde.blockFragmentSize, pde,
state);
255 assert(pde.blockFragmentSize == 9);
261 DPRINTF(GPUPTWalker,
"Treating PDE2 as PTE: %#016x frag: %d\n",
262 (uint64_t)pte, pte.fragment);
272 part1 = ((((uint64_t)pte) >> 6) << 3);
274 nextRead = ((part1 + part2) << 3) &
mask(48);
276 "Got PDE2 entry %#016x. write:%s->%#016x va:%#016x\n",
277 (uint64_t)pte, pte.w == 0 ?
"yes" :
"no", nextRead,
vaddr);
282 DPRINTF(GPUPTWalker,
"Treating PDE1 as PTE: %#016x frag: %d\n",
283 (uint64_t)pte, pte.fragment);
293 part1 = ((((uint64_t)pte) >> 6) << 3);
295 nextRead = ((part1 + part2) << 3) &
mask(48);
297 "Got PDE1 entry %#016x. write:%s->%#016x va: %#016x\n",
298 (uint64_t)pte, pte.w == 0 ?
"yes" :
"no", nextRead,
vaddr);
303 DPRINTF(GPUPTWalker,
"Treating PDE0 as PTE: %#016x frag: %d\n",
304 (uint64_t)pte, pte.fragment);
313 part1 = ((((uint64_t)pte) >> 6) << 3);
319 pde.blockFragmentSize);
323 nextRead = ((part1 + part2) << 3) &
mask(48);
325 "Got PDE0 entry %#016x. write:%s->%#016x va:%#016x\n",
326 (uint64_t)pte, pte.w == 0 ?
"yes" :
"no", nextRead,
vaddr);
331 " PTE entry %#016x. write: %s va: %#016x\n",
332 (uint64_t)pte, pte.w == 0 ?
"yes" :
"no",
vaddr);
340 panic(
"Unknown page table walker state %d!\n");
343 if (badNX || !pte.v) {
356 walker->currStates.remove(
this);
368 [[maybe_unused]]
auto addr =
read->getAddr();
370 DPRINTF(GPUPTWalker,
"Timing request for %#lx failed\n",
389 if (entry !=
nullptr) {
390 DPRINTF(GPUPTWalker,
"PTE found in buffer, skipping timing request.");
398 if (
port.sendTimingReq(pkt)) {
399 DPRINTF(GPUPTWalker,
"Sending timing read to %#lx from walker %p\n",
400 pkt->
getAddr(), sending_walker);
414 walker->recvTimingResp(pkt);
425 DPRINTF(GPUPTWalker,
"Got response for %#lx from walker %p -- %#lx\n",
440 for (
auto &
i :
pwc) {
463 walkerState->
retry();
471 tlb->walkerResponse(entry, pkt);
496 DPRINTF(GPUPTWalker,
"Raising page fault.\n");
514 return ((logicalAddr & ((1 <<
top) - 1)) >> lsb);
524 if (if_name ==
"port")
AbstractMemory declaration.
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.
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.
@ PHYSICAL
The virtual address is also the physical address.
@ UNCACHEABLE
The request is to an uncacheable address.
gem5::Flags< FlagsType > Flags
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)
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)
void set(Type mask)
Set all flag's bits matching the given mask.
#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.
classes that represnt vector/scalar operands in VEGA ISA.
Bitfield< 11, 7 > fragment
Copyright (c) 2024 Arm Limited 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