Go to the documentation of this file.
62 #include "debug/PageTableWalker.hh"
113 bool walkComplete = senderWalk->
recvPacket(pkt);
119 if (walkerState == senderWalk) {
138 walker->recvReqRetry();
148 walkerState->
retry();
172 if (if_name ==
"port")
182 assert(state == Ready);
189 pmode = walker->tlb->getMemPriv(tc,
mode);
191 assert(satp.mode == AddrXlateMode::SV39);
197 unsigned num_squashed = 0;
204 DPRINTF(PageTableWalker,
"Squashing table walk for address %#x\n",
205 currState->
req->getVaddr());
209 std::make_shared<UnimpFault>(
"Squashed Inst"),
210 currState->
req, currState->
tc, currState->
mode);
237 setupWalk(req->getVaddr());
245 walker->port.sendAtomic(read);
247 fault = stepWalk(write);
248 assert(fault ==
NoFault || read == NULL);
252 walker->port.sendAtomic(write);
269 walker->port.sendFunctional(read);
273 fault = stepWalk(write);
274 assert(fault ==
NoFault || read == NULL);
278 logBytes = entry.logBytes;
287 assert(state != Ready && state != Waiting);
290 PTESv39 pte = read->
getLE<uint64_t>();
292 bool doWrite =
false;
293 bool doTLBInsert =
false;
294 bool doEndWalk =
false;
296 DPRINTF(PageTableWalker,
"Got level%d PTE: %#x\n",
level, pte);
301 if (!pte.v || (!pte.r && pte.w)) {
303 DPRINTF(PageTableWalker,
"PTE invalid, raising PF\n");
304 fault = pageFault(pte.v);
308 if (pte.r || pte.x) {
311 fault = walker->tlb->checkPermissions(
status, pmode,
312 entry.vaddr,
mode, pte);
316 if (
level >= 1 && pte.ppn0 != 0) {
318 "PTE has misaligned PPN, raising PF\n");
319 fault = pageFault(
true);
321 else if (
level == 2 && pte.ppn1 != 0) {
323 "PTE has misaligned PPN, raising PF\n");
324 fault = pageFault(
true);
342 entry.paddr = pte.ppn;
343 entry.vaddr &= ~((1 << entry.logBytes) - 1);
355 DPRINTF(PageTableWalker,
"No leaf PTE found, raising PF\n");
357 fault = pageFault(
true);
362 nextRead = (pte.ppn <<
PageShift) + (idx *
sizeof(pte));
363 nextState = Translate;
374 if (!functional && doWrite) {
375 DPRINTF(PageTableWalker,
"Writing level%d PTE to %#x: %#x\n",
378 write->
setLE<uint64_t>(pte);
387 walker->tlb->insert(entry.vaddr, entry);
389 DPRINTF(PageTableWalker,
"Translated %#x -> %#x\n",
391 (entry.vaddr &
mask(entry.logBytes)));
398 RequestPtr request = std::make_shared<Request>(
399 nextRead, oldRead->
getSize(), flags, walker->requestorId);
404 "Loading level%d PTE from %#x\n",
level, nextRead);
425 Addr topAddr = (satp.ppn <<
PageShift) + (idx *
sizeof(PTESv39));
428 DPRINTF(PageTableWalker,
"Performing table walk for address %#x\n",
vaddr);
429 DPRINTF(PageTableWalker,
"Loading level%d PTE from %#x\n",
level, topAddr);
434 entry.asid = satp.asid;
437 RequestPtr request = std::make_shared<Request>(
438 topAddr,
sizeof(PTESv39), flags, walker->requestorId);
449 assert(state == Waiting);
454 return (inflight == 0);
467 timingFault = stepWalk(write);
469 assert(timingFault ==
NoFault || read == NULL);
471 writes.push_back(write);
477 if (inflight == 0 && read == NULL && writes.size() == 0) {
490 Addr paddr = walker->tlb->translateWithTLB(
vaddr, satp.asid,
mode);
491 req->setPaddr(paddr);
496 translation->finish(timingFault, req, tc,
mode);
516 if (!walker->sendTiming(
this, pkt)) {
524 while (writes.size()) {
528 if (!walker->sendTiming(
this, write)) {
530 writes.push_back(write);
577 DPRINTF(PageTableWalker,
"Raising page fault.\n");
578 return walker->tlb->createPagefault(entry.vaddr,
mode);
584 RiscvPagetableWalkerParams::create()
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, Mode mode)=0
virtual bool squashed() const
This function is used by the page table walker to determine if it should translate the a pending requ...
bool scheduled() const
Determine if the current event is scheduled.
bool isTimingMode() const
Is the system in timing mode?
void setupWalk(Addr vaddr)
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
bool sendTiming(WalkerState *sendingState, PacketPtr pkt)
std::shared_ptr< Request > RequestPtr
RequestPtr req
A pointer to the original request.
bool recvTimingResp(PacketPtr pkt)
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Fault start(ThreadContext *_tc, BaseTLB::Translation *translation, const RequestPtr &req, BaseTLB::Mode mode)
@ PHYSICAL
The virtual address is also the physical address.
void schedule(Event &event, Tick when)
void initState(ThreadContext *_tc, BaseTLB::Mode _mode, bool _isTiming=false)
ThreadContext is the external interface to all thread state for anything outside of the CPU.
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
std::shared_ptr< FaultBase > Fault
Ports are used to interface objects to each other.
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...
Fault pageFault(bool present)
constexpr decltype(nullptr) NoFault
ProbePointArg< PacketInfo > Packet
Packet probe point.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Fault stepWalk(PacketPtr &write)
bool recvPacket(PacketPtr pkt)
MemCmd cmd
The command field of the packet.
unsigned numInflight() const
TLB::Translation * translation
T getLE() const
Get the data in the packet byte swapped from little endian to host 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...
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
void setLE(T v)
Set the value in the data pointer to v as little endian.
EventFunctionWrapper startWalkWrapperEvent
Event used to call startWalkWrapper.
void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
Fault startFunctional(ThreadContext *_tc, Addr &addr, unsigned &logBytes, BaseTLB::Mode mode)
std::list< WalkerState * > currStates
Fault startFunctional(Addr &addr, unsigned &logBytes)
Generated on Wed Sep 30 2020 14:02:07 for gem5 by doxygen 1.8.17