63 #include "debug/PageTableWalker.hh"
117 bool walkComplete = senderWalk->
recvPacket(pkt);
123 if (walkerState == senderWalk) {
142 walker->recvReqRetry();
152 walkerState->
retry();
176 if (if_name ==
"port")
186 assert(
state == Ready);
193 pmode = walker->tlb->getMemPriv(tc,
mode);
195 assert(satp.mode == AddrXlateMode::SV39);
201 unsigned num_squashed = 0;
208 DPRINTF(PageTableWalker,
"Squashing table walk for address %#x\n",
209 currState->
req->getVaddr());
213 std::make_shared<UnimpFault>(
"Squashed Inst"),
214 currState->
req, currState->
tc, currState->
mode);
241 setupWalk(req->getVaddr());
249 walker->port.sendAtomic(read);
251 fault = stepWalk(write);
252 assert(fault ==
NoFault || read == NULL);
256 walker->port.sendAtomic(write);
273 walker->port.sendFunctional(read);
277 fault = stepWalk(write);
278 assert(fault ==
NoFault || read == NULL);
282 logBytes = entry.logBytes;
294 PTESv39 pte = read->
getLE<uint64_t>();
296 bool doWrite =
false;
297 bool doTLBInsert =
false;
298 bool doEndWalk =
false;
300 DPRINTF(PageTableWalker,
"Got level%d PTE: %#x\n",
level, pte);
305 walker->pma->check(read->req);
313 if (!pte.v || (!pte.r && pte.w)) {
315 DPRINTF(PageTableWalker,
"PTE invalid, raising PF\n");
316 fault = pageFault(pte.v);
320 if (pte.r || pte.x) {
323 fault = walker->tlb->checkPermissions(
status, pmode,
324 entry.vaddr,
mode, pte);
328 if (
level >= 1 && pte.ppn0 != 0) {
330 "PTE has misaligned PPN, raising PF\n");
331 fault = pageFault(
true);
333 else if (
level == 2 && pte.ppn1 != 0) {
335 "PTE has misaligned PPN, raising PF\n");
336 fault = pageFault(
true);
357 walker->pma->check(read->req);
359 fault = walker->pmp->pmpCheck(read->req,
368 entry.paddr = pte.ppn;
369 entry.vaddr &= ~((1 << entry.logBytes) - 1);
382 DPRINTF(PageTableWalker,
"No leaf PTE found,"
385 fault = pageFault(
true);
389 nextRead = (pte.ppn <<
PageShift) + (idx *
sizeof(pte));
390 nextState = Translate;
403 if (!functional && doWrite) {
404 DPRINTF(PageTableWalker,
"Writing level%d PTE to %#x: %#x\n",
407 write->
setLE<uint64_t>(pte);
416 walker->tlb->insert(entry.vaddr, entry);
418 DPRINTF(PageTableWalker,
"Translated %#x -> %#x\n",
420 (entry.vaddr &
mask(entry.logBytes)));
427 RequestPtr request = std::make_shared<Request>(
428 nextRead, oldRead->
getSize(),
flags, walker->requestorId);
437 "Loading level%d PTE from %#x\n",
level, nextRead);
458 Addr topAddr = (satp.ppn <<
PageShift) + (idx *
sizeof(PTESv39));
461 DPRINTF(PageTableWalker,
"Performing table walk for address %#x\n",
vaddr);
462 DPRINTF(PageTableWalker,
"Loading level%d PTE from %#x\n",
level, topAddr);
467 entry.asid = satp.asid;
470 RequestPtr request = std::make_shared<Request>(
471 topAddr,
sizeof(PTESv39),
flags, walker->requestorId);
482 assert(
state == Waiting);
487 return (inflight == 0);
500 timingFault = stepWalk(write);
502 assert(timingFault ==
NoFault || read == NULL);
504 writes.push_back(write);
512 if (inflight == 0 && read == NULL && writes.size() == 0) {
525 Addr paddr = walker->tlb->translateWithTLB(
vaddr, satp.asid,
mode);
526 req->setPaddr(paddr);
527 walker->pma->check(req);
532 timingFault = walker->pmp->pmpCheck(req,
mode, pmode, tc);
535 translation->finish(timingFault, req, tc,
mode);
538 translation->finish(timingFault, req, tc,
mode);
558 if (!walker->sendTiming(
this, pkt)) {
566 while (writes.size()) {
570 if (!walker->sendTiming(
this, write)) {
572 writes.push_back(write);
619 DPRINTF(PageTableWalker,
"Raising page fault.\n");
620 return walker->tlb->createPagefault(entry.vaddr,
mode);
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...
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.
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.
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)
bool recvPacket(PacketPtr pkt)
void setupWalk(Addr vaddr)
Fault stepWalk(PacketPtr &write)
BaseMMU::Translation * translation
Fault pageFault(bool present)
unsigned numInflight() const
void initState(ThreadContext *_tc, BaseMMU::Mode _mode, bool _isTiming=false)
Fault startFunctional(ThreadContext *_tc, Addr &addr, unsigned &logBytes, BaseMMU::Mode mode)
EventFunctionWrapper startWalkWrapperEvent
Event used to call startWalkWrapper.
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
Fault start(ThreadContext *_tc, BaseMMU::Translation *translation, const RequestPtr &req, BaseMMU::Mode mode)
bool isTimingMode() const
Is the system in timing mode?
ThreadContext is the external interface to all thread state for anything outside of the CPU.
bool scheduled() const
Determine if the current event is scheduled.
void schedule(Event &event, Tick when)
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
ProbePointArg< PacketInfo > Packet
Packet probe point.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
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 ...