gem5  [DEVELOP-FOR-23.0]
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
pagetable_walker.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012 ARM Limited
3  * All rights reserved.
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2007 The Hewlett-Packard Development Company
15  * All rights reserved.
16  *
17  * The license below extends only to copyright in the software and shall
18  * not be construed as granting a license to any other intellectual
19  * property including but not limited to intellectual property relating
20  * to a hardware implementation of the functionality of the software
21  * licensed hereunder. You may use the software subject to the license
22  * terms below provided that you ensure that this notice is replicated
23  * unmodified and in its entirety in all distributions of the software,
24  * modified or unmodified, in source code or in binary form.
25  *
26  * Redistribution and use in source and binary forms, with or without
27  * modification, are permitted provided that the following conditions are
28  * met: redistributions of source code must retain the above copyright
29  * notice, this list of conditions and the following disclaimer;
30  * redistributions in binary form must reproduce the above copyright
31  * notice, this list of conditions and the following disclaimer in the
32  * documentation and/or other materials provided with the distribution;
33  * neither the name of the copyright holders nor the names of its
34  * contributors may be used to endorse or promote products derived from
35  * this software without specific prior written permission.
36  *
37  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
38  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
39  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
40  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
41  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
43  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
44  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
45  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48  */
49 
51 
52 #include <memory>
53 
54 #include "arch/x86/faults.hh"
55 #include "arch/x86/pagetable.hh"
56 #include "arch/x86/regs/misc.hh"
57 #include "arch/x86/tlb.hh"
58 #include "base/bitfield.hh"
59 #include "base/trie.hh"
60 #include "cpu/base.hh"
61 #include "cpu/thread_context.hh"
62 #include "debug/PageTableWalker.hh"
63 #include "mem/packet_access.hh"
64 #include "mem/request.hh"
65 
66 namespace gem5
67 {
68 
69 namespace X86ISA {
70 
71 Fault
73  const RequestPtr &_req, BaseMMU::Mode _mode)
74 {
75  // TODO: in timing mode, instead of blocking when there are other
76  // outstanding requests, see if this request can be coalesced with
77  // another one (i.e. either coalesce or start walk)
78  WalkerState * newState = new WalkerState(this, _translation, _req);
79  newState->initState(_tc, _mode, sys->isTimingMode());
80  if (currStates.size()) {
81  assert(newState->isTiming());
82  DPRINTF(PageTableWalker, "Walks in progress: %d\n", currStates.size());
83  currStates.push_back(newState);
84  return NoFault;
85  } else {
86  currStates.push_back(newState);
87  Fault fault = newState->startWalk();
88  if (!newState->isTiming()) {
89  currStates.pop_front();
90  delete newState;
91  }
92  return fault;
93  }
94 }
95 
96 Fault
97 Walker::startFunctional(ThreadContext * _tc, Addr &addr, unsigned &logBytes,
98  BaseMMU::Mode _mode)
99 {
100  funcState.initState(_tc, _mode);
101  return funcState.startFunctional(addr, logBytes);
102 }
103 
104 bool
106 {
107  return walker->recvTimingResp(pkt);
108 }
109 
110 bool
112 {
113  WalkerSenderState * senderState =
114  dynamic_cast<WalkerSenderState *>(pkt->popSenderState());
115  WalkerState * senderWalk = senderState->senderWalk;
116  bool walkComplete = senderWalk->recvPacket(pkt);
117  delete senderState;
118  if (walkComplete) {
120  for (iter = currStates.begin(); iter != currStates.end(); iter++) {
121  WalkerState * walkerState = *(iter);
122  if (walkerState == senderWalk) {
123  iter = currStates.erase(iter);
124  break;
125  }
126  }
127  delete senderWalk;
128  // Since we block requests when another is outstanding, we
129  // need to check if there is a waiting request to be serviced
130  if (currStates.size() && !startWalkWrapperEvent.scheduled())
131  // delay sending any new requests until we are finished
132  // with the responses
134  }
135  return true;
136 }
137 
138 void
140 {
141  walker->recvReqRetry();
142 }
143 
144 void
146 {
148  for (iter = currStates.begin(); iter != currStates.end(); iter++) {
149  WalkerState * walkerState = *(iter);
150  if (walkerState->isRetrying()) {
151  walkerState->retry();
152  }
153  }
154 }
155 
156 bool Walker::sendTiming(WalkerState* sendingState, PacketPtr pkt)
157 {
158  WalkerSenderState* walker_state = new WalkerSenderState(sendingState);
159  pkt->pushSenderState(walker_state);
160  if (port.sendTimingReq(pkt)) {
161  return true;
162  } else {
163  // undo the adding of the sender state and delete it, as we
164  // will do it again the next time we attempt to send it
165  pkt->popSenderState();
166  delete walker_state;
167  return false;
168  }
169 
170 }
171 
172 Port &
173 Walker::getPort(const std::string &if_name, PortID idx)
174 {
175  if (if_name == "port")
176  return port;
177  else
178  return ClockedObject::getPort(if_name, idx);
179 }
180 
181 void
183  BaseMMU::Mode _mode, bool _isTiming)
184 {
185  assert(state == Ready);
186  started = false;
187  tc = _tc;
188  mode = _mode;
189  timing = _isTiming;
190 }
191 
192 void
194 {
195  unsigned num_squashed = 0;
196  WalkerState *currState = currStates.front();
197  while ((num_squashed < numSquashable) && currState &&
198  currState->translation->squashed()) {
199  currStates.pop_front();
200  num_squashed++;
201 
202  DPRINTF(PageTableWalker, "Squashing table walk for address %#x\n",
203  currState->req->getVaddr());
204 
205  // finish the translation which will delete the translation object
206  currState->translation->finish(
207  std::make_shared<UnimpFault>("Squashed Inst"),
208  currState->req, currState->tc, currState->mode);
209 
210  // delete the current request if there are no inflight packets.
211  // if there is something in flight, delete when the packets are
212  // received and inflight is zero.
213  if (currState->numInflight() == 0) {
214  delete currState;
215  } else {
216  currState->squash();
217  }
218 
219  // check the next translation request, if it exists
220  if (currStates.size())
221  currState = currStates.front();
222  else
223  currState = NULL;
224  }
225  if (currState && !currState->wasStarted())
226  currState->startWalk();
227 }
228 
229 Fault
231 {
232  Fault fault = NoFault;
233  assert(!started);
234  started = true;
235  setupWalk(req->getVaddr());
236  if (timing) {
237  nextState = state;
238  state = Waiting;
239  timingFault = NoFault;
240  sendPackets();
241  } else {
242  do {
243  walker->port.sendAtomic(read);
244  PacketPtr write = NULL;
245  fault = stepWalk(write);
246  assert(fault == NoFault || read == NULL);
247  state = nextState;
248  nextState = Ready;
249  if (write)
250  walker->port.sendAtomic(write);
251  } while (read);
252  state = Ready;
253  nextState = Waiting;
254  }
255  return fault;
256 }
257 
258 Fault
260 {
261  Fault fault = NoFault;
262  assert(!started);
263  started = true;
264  setupWalk(addr);
265 
266  do {
267  walker->port.sendFunctional(read);
268  // On a functional access (page table lookup), writes should
269  // not happen so this pointer is ignored after stepWalk
270  PacketPtr write = NULL;
271  fault = stepWalk(write);
272  assert(fault == NoFault || read == NULL);
273  state = nextState;
274  nextState = Ready;
275  } while (read);
276  logBytes = entry.logBytes;
277  addr = entry.paddr;
278 
279  return fault;
280 }
281 
282 Fault
284 {
285  assert(state != Ready && state != Waiting);
286  Fault fault = NoFault;
287  write = NULL;
288  PageTableEntry pte;
289  if (dataSize == 8)
290  pte = read->getLE<uint64_t>();
291  else
292  pte = read->getLE<uint32_t>();
293  VAddr vaddr = entry.vaddr;
294  bool uncacheable = pte.pcd;
295  Addr nextRead = 0;
296  bool doWrite = false;
297  bool doTLBInsert = false;
298  bool doEndWalk = false;
299  bool badNX = pte.nx && mode == BaseMMU::Execute && enableNX;
300  switch(state) {
301  case LongPML4:
302  DPRINTF(PageTableWalker, "Got long mode PML4 entry %#016x.\n", pte);
303  nextRead = mbits(pte, 51, 12) + vaddr.longl3 * dataSize;
304  doWrite = !pte.a;
305  pte.a = 1;
306  entry.writable = pte.w;
307  entry.user = pte.u;
308  if (badNX || !pte.p) {
309  doEndWalk = true;
310  fault = pageFault(pte.p);
311  break;
312  }
313  entry.noExec = pte.nx;
314  nextState = LongPDP;
315  break;
316  case LongPDP:
317  DPRINTF(PageTableWalker, "Got long mode PDP entry %#016x.\n", pte);
318  nextRead = mbits(pte, 51, 12) + vaddr.longl2 * dataSize;
319  doWrite = !pte.a;
320  pte.a = 1;
321  entry.writable = entry.writable && pte.w;
322  entry.user = entry.user && pte.u;
323  if (badNX || !pte.p) {
324  doEndWalk = true;
325  fault = pageFault(pte.p);
326  break;
327  }
328  nextState = LongPD;
329  break;
330  case LongPD:
331  DPRINTF(PageTableWalker, "Got long mode PD entry %#016x.\n", pte);
332  doWrite = !pte.a;
333  pte.a = 1;
334  entry.writable = entry.writable && pte.w;
335  entry.user = entry.user && pte.u;
336  if (badNX || !pte.p) {
337  doEndWalk = true;
338  fault = pageFault(pte.p);
339  break;
340  }
341  if (!pte.ps) {
342  // 4 KB page
343  entry.logBytes = 12;
344  nextRead = mbits(pte, 51, 12) + vaddr.longl1 * dataSize;
345  nextState = LongPTE;
346  break;
347  } else {
348  // 2 MB page
349  entry.logBytes = 21;
350  entry.paddr = mbits(pte, 51, 21);
351  entry.uncacheable = uncacheable;
352  entry.global = pte.g;
353  entry.patBit = bits(pte, 12);
354  entry.vaddr = mbits(entry.vaddr, 63, 21);
355  doTLBInsert = true;
356  doEndWalk = true;
357  break;
358  }
359  case LongPTE:
360  DPRINTF(PageTableWalker, "Got long mode PTE entry %#016x.\n", pte);
361  doWrite = !pte.a;
362  pte.a = 1;
363  entry.writable = entry.writable && pte.w;
364  entry.user = entry.user && pte.u;
365  if (badNX || !pte.p) {
366  doEndWalk = true;
367  fault = pageFault(pte.p);
368  break;
369  }
370  entry.paddr = mbits(pte, 51, 12);
371  entry.uncacheable = uncacheable;
372  entry.global = pte.g;
373  entry.patBit = bits(pte, 12);
374  entry.vaddr = mbits(entry.vaddr, 63, 12);
375  doTLBInsert = true;
376  doEndWalk = true;
377  break;
378  case PAEPDP:
379  DPRINTF(PageTableWalker,
380  "Got legacy mode PAE PDP entry %#08x.\n", pte);
381  nextRead = mbits(pte, 51, 12) + vaddr.pael2 * dataSize;
382  if (!pte.p) {
383  doEndWalk = true;
384  fault = pageFault(pte.p);
385  break;
386  }
387  nextState = PAEPD;
388  break;
389  case PAEPD:
390  DPRINTF(PageTableWalker, "Got legacy mode PAE PD entry %#08x.\n", pte);
391  doWrite = !pte.a;
392  pte.a = 1;
393  entry.writable = pte.w;
394  entry.user = pte.u;
395  if (badNX || !pte.p) {
396  doEndWalk = true;
397  fault = pageFault(pte.p);
398  break;
399  }
400  if (!pte.ps) {
401  // 4 KB page
402  entry.logBytes = 12;
403  nextRead = mbits(pte, 51, 12) + vaddr.pael1 * dataSize;
404  nextState = PAEPTE;
405  break;
406  } else {
407  // 2 MB page
408  entry.logBytes = 21;
409  entry.paddr = mbits(pte, 51, 21);
410  entry.uncacheable = uncacheable;
411  entry.global = pte.g;
412  entry.patBit = bits(pte, 12);
413  entry.vaddr = mbits(entry.vaddr, 63, 21);
414  doTLBInsert = true;
415  doEndWalk = true;
416  break;
417  }
418  case PAEPTE:
419  DPRINTF(PageTableWalker,
420  "Got legacy mode PAE PTE entry %#08x.\n", pte);
421  doWrite = !pte.a;
422  pte.a = 1;
423  entry.writable = entry.writable && pte.w;
424  entry.user = entry.user && pte.u;
425  if (badNX || !pte.p) {
426  doEndWalk = true;
427  fault = pageFault(pte.p);
428  break;
429  }
430  entry.paddr = mbits(pte, 51, 12);
431  entry.uncacheable = uncacheable;
432  entry.global = pte.g;
433  entry.patBit = bits(pte, 7);
434  entry.vaddr = mbits(entry.vaddr, 63, 12);
435  doTLBInsert = true;
436  doEndWalk = true;
437  break;
438  case PSEPD:
439  DPRINTF(PageTableWalker, "Got legacy mode PSE PD entry %#08x.\n", pte);
440  doWrite = !pte.a;
441  pte.a = 1;
442  entry.writable = pte.w;
443  entry.user = pte.u;
444  if (!pte.p) {
445  doEndWalk = true;
446  fault = pageFault(pte.p);
447  break;
448  }
449  if (!pte.ps) {
450  // 4 KB page
451  entry.logBytes = 12;
452  nextRead = mbits(pte, 31, 12) + vaddr.norml2 * dataSize;
453  nextState = PTE;
454  break;
455  } else {
456  // 4 MB page
457  entry.logBytes = 21;
458  entry.paddr = bits(pte, 20, 13) << 32 | mbits(pte, 31, 22);
459  entry.uncacheable = uncacheable;
460  entry.global = pte.g;
461  entry.patBit = bits(pte, 12);
462  entry.vaddr = mbits(entry.vaddr, 63, 22);
463  doTLBInsert = true;
464  doEndWalk = true;
465  break;
466  }
467  case PD:
468  DPRINTF(PageTableWalker, "Got legacy mode PD entry %#08x.\n", pte);
469  doWrite = !pte.a;
470  pte.a = 1;
471  entry.writable = pte.w;
472  entry.user = pte.u;
473  if (!pte.p) {
474  doEndWalk = true;
475  fault = pageFault(pte.p);
476  break;
477  }
478  // 4 KB page
479  entry.logBytes = 12;
480  nextRead = mbits(pte, 31, 12) + vaddr.norml1 * dataSize;
481  nextState = PTE;
482  break;
483  case PTE:
484  DPRINTF(PageTableWalker, "Got legacy mode PTE entry %#08x.\n", pte);
485  doWrite = !pte.a;
486  pte.a = 1;
487  entry.writable = pte.w;
488  entry.user = pte.u;
489  if (!pte.p) {
490  doEndWalk = true;
491  fault = pageFault(pte.p);
492  break;
493  }
494  entry.paddr = mbits(pte, 31, 12);
495  entry.uncacheable = uncacheable;
496  entry.global = pte.g;
497  entry.patBit = bits(pte, 7);
498  entry.vaddr = mbits(entry.vaddr, 31, 12);
499  doTLBInsert = true;
500  doEndWalk = true;
501  break;
502  default:
503  panic("Unknown page table walker state %d!\n");
504  }
505  if (doEndWalk) {
506  if (doTLBInsert)
507  if (!functional) {
508 
509  // Check if PCIDE is set in CR4
510  CR4 cr4 = tc->readMiscRegNoEffect(misc_reg::Cr4);
511  if (cr4.pcide){
512  CR3 cr3 = tc->readMiscRegNoEffect(misc_reg::Cr3);
513  walker->tlb->insert(entry.vaddr, entry, cr3.pcid);
514  }
515  else{
516  // The current PCID is always 000H if PCIDE
517  // is not set [sec 4.10.1 of Intel's Software
518  // Developer Manual]
519  walker->tlb->insert(entry.vaddr, entry, 0x000);
520  }
521  }
522 
523  endWalk();
524  } else {
525  PacketPtr oldRead = read;
526  //If we didn't return, we're setting up another read.
527  Request::Flags flags = oldRead->req->getFlags();
528  flags.set(Request::UNCACHEABLE, uncacheable);
529  RequestPtr request = std::make_shared<Request>(
530  nextRead, oldRead->getSize(), flags, walker->requestorId);
531  read = new Packet(request, MemCmd::ReadReq);
532  read->allocate();
533  // If we need to write, adjust the read packet to write the modified
534  // value back to memory.
535  if (doWrite) {
536  write = oldRead;
537  if (dataSize == 8)
538  write->setLE<uint64_t>(pte);
539  else
540  write->setLE<uint32_t>(pte);
541  write->cmd = MemCmd::WriteReq;
542  } else {
543  write = NULL;
544  delete oldRead;
545  }
546  }
547  return fault;
548 }
549 
550 void
552 {
553  nextState = Ready;
554  delete read;
555  read = NULL;
556 }
557 
558 void
560 {
561  VAddr addr = vaddr;
562  CR3 cr3 = tc->readMiscRegNoEffect(misc_reg::Cr3);
563  CR4 cr4 = tc->readMiscRegNoEffect(misc_reg::Cr4);
564  // Check if we're in long mode or not
565  Efer efer = tc->readMiscRegNoEffect(misc_reg::Efer);
566  dataSize = 8;
567  Addr topAddr;
568  if (efer.lma) {
569  // Do long mode.
570  state = LongPML4;
571  topAddr = (cr3.longPdtb << 12) + addr.longl4 * dataSize;
572  enableNX = efer.nxe;
573  } else {
574  // We're in some flavor of legacy mode.
575  if (cr4.pae) {
576  // Do legacy PAE.
577  state = PAEPDP;
578  topAddr = (cr3.paePdtb << 5) + addr.pael3 * dataSize;
579  enableNX = efer.nxe;
580  } else {
581  dataSize = 4;
582  topAddr = (cr3.pdtb << 12) + addr.norml2 * dataSize;
583  if (cr4.pse) {
584  // Do legacy PSE.
585  state = PSEPD;
586  } else {
587  // Do legacy non PSE.
588  state = PD;
589  }
590  enableNX = false;
591  }
592  }
593 
594  nextState = Ready;
595  entry.vaddr = vaddr;
596 
598 
599  // PCD can't be used if CR4.PCIDE=1 [sec 2.5
600  // of Intel's Software Developer's manual]
601  if (!cr4.pcide && cr3.pcd)
603 
604  RequestPtr request = std::make_shared<Request>(
605  topAddr, dataSize, flags, walker->requestorId);
606 
607  read = new Packet(request, MemCmd::ReadReq);
608  read->allocate();
609 }
610 
611 bool
613 {
614  assert(pkt->isResponse());
615  assert(inflight);
616  assert(state == Waiting);
617  inflight--;
618  if (squashed) {
619  // if were were squashed, return true once inflight is zero and
620  // this WalkerState will be freed there.
621  return (inflight == 0);
622  }
623  if (pkt->isRead()) {
624  // should not have a pending read it we also had one outstanding
625  assert(!read);
626 
627  // @todo someone should pay for this
628  pkt->headerDelay = pkt->payloadDelay = 0;
629 
630  state = nextState;
631  nextState = Ready;
632  PacketPtr write = NULL;
633  read = pkt;
634  timingFault = stepWalk(write);
635  state = Waiting;
636  assert(timingFault == NoFault || read == NULL);
637  if (write) {
638  writes.push_back(write);
639  }
640  sendPackets();
641  } else {
642  sendPackets();
643  }
644  if (inflight == 0 && read == NULL && writes.size() == 0) {
645  state = Ready;
646  nextState = Waiting;
647  if (timingFault == NoFault) {
648  /*
649  * Finish the translation. Now that we know the right entry is
650  * in the TLB, this should work with no memory accesses.
651  * There could be new faults unrelated to the table walk like
652  * permissions violations, so we'll need the return value as
653  * well.
654  */
655  bool delayedResponse;
656  Fault fault = walker->tlb->translate(req, tc, NULL, mode,
657  delayedResponse, true);
658  assert(!delayedResponse);
659  // Let the CPU continue.
660  translation->finish(fault, req, tc, mode);
661  } else {
662  // There was a fault during the walk. Let the CPU know.
663  translation->finish(timingFault, req, tc, mode);
664  }
665  return true;
666  }
667 
668  return false;
669 }
670 
671 void
673 {
674  //If we're already waiting for the port to become available, just return.
675  if (retrying)
676  return;
677 
678  //Reads always have priority
679  if (read) {
680  PacketPtr pkt = read;
681  read = NULL;
682  inflight++;
683  if (!walker->sendTiming(this, pkt)) {
684  retrying = true;
685  read = pkt;
686  inflight--;
687  return;
688  }
689  }
690  //Send off as many of the writes as we can.
691  while (writes.size()) {
692  PacketPtr write = writes.back();
693  writes.pop_back();
694  inflight++;
695  if (!walker->sendTiming(this, write)) {
696  retrying = true;
697  writes.push_back(write);
698  inflight--;
699  return;
700  }
701  }
702 }
703 
704 unsigned
706 {
707  return inflight;
708 }
709 
710 bool
712 {
713  return retrying;
714 }
715 
716 bool
718 {
719  return timing;
720 }
721 
722 bool
724 {
725  return started;
726 }
727 
728 void
730 {
731  squashed = true;
732 }
733 
734 void
736 {
737  retrying = false;
738  sendPackets();
739 }
740 
741 Fault
743 {
744  DPRINTF(PageTableWalker, "Raising page fault.\n");
745  HandyM5Reg m5reg = tc->readMiscRegNoEffect(misc_reg::M5Reg);
746  if (mode == BaseMMU::Execute && !enableNX)
748  return std::make_shared<PageFault>(entry.vaddr, present, mode,
749  m5reg.cpl == 3, false);
750 }
751 
752 } // namespace X86ISA
753 } // namespace gem5
gem5::X86ISA::Walker::WalkerSenderState
Definition: pagetable_walker.hh:156
gem5::PortID
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:245
pagetable.hh
gem5::BaseMMU::Translation::squashed
virtual bool squashed() const
This function is used by the page table walker to determine if it should translate the a pending requ...
Definition: mmu.hh:84
gem5::SimObject::getPort
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Definition: sim_object.cc:123
gem5::BaseMMU::Read
@ Read
Definition: mmu.hh:56
gem5::NoFault
constexpr decltype(nullptr) NoFault
Definition: types.hh:253
gem5::X86ISA::Walker::WalkerState::startWalk
Fault startWalk()
Definition: pagetable_walker.cc:230
gem5::RequestPort::sendTimingReq
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
Definition: port.hh:587
gem5::X86ISA::mode
Bitfield< 3 > mode
Definition: types.hh:192
gem5::X86ISA::Walker::WalkerState::translation
BaseMMU::Translation * translation
Definition: pagetable_walker.hh:111
gem5::X86ISA::Walker::WalkerState::isTiming
bool isTiming()
Definition: pagetable_walker.cc:717
gem5::X86ISA::Walker::recvReqRetry
void recvReqRetry()
Definition: pagetable_walker.cc:145
gem5::Packet::pushSenderState
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...
Definition: packet.cc:334
gem5::BaseMMU::Mode
Mode
Definition: mmu.hh:56
gem5::Packet::req
RequestPtr req
A pointer to the original request.
Definition: packet.hh:377
gem5::X86ISA::Walker::recvTimingResp
bool recvTimingResp(PacketPtr pkt)
Definition: pagetable_walker.cc:111
gem5::X86ISA::Walker::WalkerState::tc
ThreadContext * tc
Definition: pagetable_walker.hh:100
gem5::X86ISA::Walker::getPort
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
Definition: pagetable_walker.cc:173
gem5::X86ISA::Walker::WalkerState::startFunctional
Fault startFunctional(Addr &addr, unsigned &logBytes)
Definition: pagetable_walker.cc:259
gem5::X86ISA::Walker::WalkerState
Definition: pagetable_walker.hh:82
gem5::X86ISA::Walker::WalkerSenderState::senderWalk
WalkerState * senderWalk
Definition: pagetable_walker.hh:158
gem5::X86ISA::Walker::WalkerState::sendPackets
void sendPackets()
Definition: pagetable_walker.cc:672
gem5::X86ISA::Walker::start
Fault start(ThreadContext *_tc, BaseMMU::Translation *translation, const RequestPtr &req, BaseMMU::Mode mode)
Definition: pagetable_walker.cc:72
pagetable_walker.hh
gem5::EventManager::schedule
void schedule(Event &event, Tick when)
Definition: eventq.hh:1012
gem5::X86ISA::Walker::currStates
std::list< WalkerState * > currStates
Definition: pagetable_walker.hh:152
gem5::mbits
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
Definition: bitfield.hh:103
gem5::X86ISA::misc_reg::Cr3
@ Cr3
Definition: misc.hh:119
gem5::Packet::headerDelay
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition: packet.hh:431
faults.hh
gem5::X86ISA::Walker::port
WalkerPort port
Definition: pagetable_walker.hh:79
gem5::X86ISA::Walker::WalkerState::setupWalk
void setupWalk(Addr vaddr)
Definition: pagetable_walker.cc:559
request.hh
gem5::BaseMMU::Execute
@ Execute
Definition: mmu.hh:56
gem5::X86ISA::Walker::WalkerState::recvPacket
bool recvPacket(PacketPtr pkt)
Definition: pagetable_walker.cc:612
gem5::X86ISA::Walker::WalkerState::endWalk
void endWalk()
Definition: pagetable_walker.cc:551
gem5::X86ISA::misc_reg::Efer
@ Efer
Definition: misc.hh:256
gem5::Packet::payloadDelay
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Definition: packet.hh:449
gem5::X86ISA::present
Bitfield< 7 > present
Definition: misc.hh:999
gem5::Flags< FlagsType >
gem5::X86ISA::Walker::WalkerState::retry
void retry()
Definition: pagetable_walker.cc:735
gem5::Packet::isRead
bool isRead() const
Definition: packet.hh:593
bitfield.hh
gem5::ThreadContext
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Definition: thread_context.hh:88
gem5::Fault
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:210
gem5::Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
gem5::X86ISA::Walker::sendTiming
bool sendTiming(WalkerState *sendingState, PacketPtr pkt)
Definition: pagetable_walker.cc:156
gem5::probing::Packet
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:108
gem5::RequestPtr
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
gem5::MemCmd::ReadReq
@ ReadReq
Definition: packet.hh:87
gem5::X86ISA::Walker::WalkerState
friend class WalkerState
Definition: pagetable_walker.hh:149
gem5::SparcISA::PageTableEntry
Definition: pagetable.hh:68
gem5::bits
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:76
flags
uint8_t flags
Definition: helpers.cc:66
gem5::System::isTimingMode
bool isTimingMode() const
Is the system in timing mode?
Definition: system.hh:270
gem5::X86ISA::Walker::funcState
WalkerState funcState
Definition: pagetable_walker.hh:154
gem5::Request::UNCACHEABLE
@ UNCACHEABLE
The request is to an uncacheable address.
Definition: request.hh:125
gem5::Packet::cmd
MemCmd cmd
The command field of the packet.
Definition: packet.hh:372
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::X86ISA::Walker::numSquashable
unsigned numSquashable
Definition: pagetable_walker.hh:179
packet_access.hh
gem5::Clocked::clockEdge
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...
Definition: clocked_object.hh:177
gem5::Packet::popSenderState
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
Definition: packet.cc:342
gem5::X86ISA::misc_reg::Cr4
@ Cr4
Definition: misc.hh:120
gem5::BaseMMU::Translation
Definition: mmu.hh:58
state
atomic_var_t state
Definition: helpers.cc:188
gem5::X86ISA::Walker::WalkerPort::recvReqRetry
void recvReqRetry()
Called by the peer if sendTimingReq was called on this peer (causing recvTimingReq to be called on th...
Definition: pagetable_walker.cc:139
gem5::X86ISA::Walker::startFunctional
Fault startFunctional(ThreadContext *_tc, Addr &addr, unsigned &logBytes, BaseMMU::Mode mode)
Definition: pagetable_walker.cc:97
base.hh
gem5::Port
Ports are used to interface objects to each other.
Definition: port.hh:61
gem5::X86ISA::Walker::WalkerState::isRetrying
bool isRetrying()
Definition: pagetable_walker.cc:711
gem5::X86ISA::Walker::WalkerState::req
RequestPtr req
Definition: pagetable_walker.hh:101
gem5::X86ISA::Walker::WalkerState::wasStarted
bool wasStarted()
Definition: pagetable_walker.cc:723
gem5::MemCmd::WriteReq
@ WriteReq
Definition: packet.hh:90
gem5::X86ISA::Walker::WalkerState::numInflight
unsigned numInflight() const
Definition: pagetable_walker.cc:705
gem5::X86ISA::Walker::WalkerState::mode
BaseMMU::Mode mode
Definition: pagetable_walker.hh:112
gem5::Packet::setLE
void setLE(T v)
Set the value in the data pointer to v as little endian.
Definition: packet_access.hh:108
gem5::Request::PHYSICAL
@ PHYSICAL
The virtual address is also the physical address.
Definition: request.hh:117
gem5::MipsISA::vaddr
vaddr
Definition: pra_constants.hh:278
tlb.hh
std::list
STL list class.
Definition: stl.hh:51
gem5::X86ISA::Walker::startWalkWrapperEvent
EventFunctionWrapper startWalkWrapperEvent
Event used to call startWalkWrapper.
Definition: pagetable_walker.hh:187
gem5::X86ISA::Walker::WalkerState::stepWalk
Fault stepWalk(PacketPtr &write)
Definition: pagetable_walker.cc:283
gem5::X86ISA::Walker::WalkerPort::walker
Walker * walker
Definition: pagetable_walker.hh:72
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::X86ISA::Walker::WalkerState::pageFault
Fault pageFault(bool present)
Definition: pagetable_walker.cc:742
gem5::X86ISA::misc_reg::M5Reg
@ M5Reg
Definition: misc.hh:148
gem5::X86ISA::Walker::WalkerState::initState
void initState(ThreadContext *_tc, BaseMMU::Mode _mode, bool _isTiming=false)
Definition: pagetable_walker.cc:182
misc.hh
gem5::BaseMMU::Translation::finish
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode)=0
gem5::X86ISA::Walker::startWalkWrapper
void startWalkWrapper()
Definition: pagetable_walker.cc:193
gem5::X86ISA::Walker::WalkerState::squash
void squash()
Definition: pagetable_walker.cc:729
gem5::ArmISA::PTE
Definition: pagetable.hh:76
gem5::Packet::isResponse
bool isResponse() const
Definition: packet.hh:598
thread_context.hh
gem5::Packet::getSize
unsigned getSize() const
Definition: packet.hh:817
trie.hh
gem5::Event::scheduled
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:458
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:188
gem5::X86ISA::Walker::sys
System * sys
Definition: pagetable_walker.hh:175
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84
gem5::X86ISA::Walker::WalkerPort::recvTimingResp
bool recvTimingResp(PacketPtr pkt)
Receive a timing response from the peer.
Definition: pagetable_walker.cc:105

Generated on Sun Jul 30 2023 01:56:47 for gem5 by doxygen 1.8.17