gem5  v22.1.0.0
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
#define DPRINTF(x,...)
Definition: trace.hh:186
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
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode)=0
@ Execute
Definition: mmu.hh:56
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....
Definition: packet.hh:294
bool isRead() const
Definition: packet.hh:592
void setLE(T v)
Set the value in the data pointer to v as little endian.
bool isResponse() const
Definition: packet.hh:597
uint32_t payloadDelay
The extra pipelining delay from seeing the packet until the end of payload is transmitted by the comp...
Definition: packet.hh:448
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition: packet.hh:430
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
SenderState * popSenderState()
Pop the top of the state stack and return a pointer to it.
Definition: packet.cc:342
RequestPtr req
A pointer to the original request.
Definition: packet.hh:376
unsigned getSize() const
Definition: packet.hh:815
MemCmd cmd
The command field of the packet.
Definition: packet.hh:371
Ports are used to interface objects to each other.
Definition: port.hh:62
bool sendTimingReq(PacketPtr pkt)
Attempt to send a timing request to the responder port by calling its corresponding receive function.
Definition: port.hh:495
@ PHYSICAL
The virtual address is also the physical address.
Definition: request.hh:117
@ UNCACHEABLE
The request is to an uncacheable address.
Definition: request.hh:125
bool isTimingMode() const
Is the system in timing mode?
Definition: system.hh:273
ThreadContext is the external interface to all thread state for anything outside of the CPU.
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.
void initState(ThreadContext *_tc, BaseMMU::Mode _mode, bool _isTiming=false)
Fault stepWalk(PacketPtr &write)
Fault startFunctional(Addr &addr, unsigned &logBytes)
BaseMMU::Translation * translation
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
bool recvTimingResp(PacketPtr pkt)
bool sendTiming(WalkerState *sendingState, PacketPtr pkt)
Fault start(ThreadContext *_tc, BaseMMU::Translation *translation, const RequestPtr &req, BaseMMU::Mode mode)
EventFunctionWrapper startWalkWrapperEvent
Event used to call startWalkWrapper.
std::list< WalkerState * > currStates
Fault startFunctional(ThreadContext *_tc, Addr &addr, unsigned &logBytes, BaseMMU::Mode mode)
STL list class.
Definition: stl.hh:51
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
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
bool scheduled() const
Determine if the current event is scheduled.
Definition: eventq.hh:465
void schedule(Event &event, Tick when)
Definition: eventq.hh:1019
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Definition: sim_object.cc:126
atomic_var_t state
Definition: helpers.cc:188
uint8_t flags
Definition: helpers.cc:66
Bitfield< 7 > present
Definition: misc.hh:999
Bitfield< 3 > addr
Definition: types.hh:84
Bitfield< 3 > mode
Definition: types.hh:192
ProbePointArg< PacketInfo > Packet
Packet probe point.
Definition: mem.hh:109
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
std::shared_ptr< Request > RequestPtr
Definition: request.hh:92
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:245
constexpr decltype(nullptr) NoFault
Definition: types.hh:253
Declaration of a request, the overall memory request consisting of the parts of the request that are ...

Generated on Wed Dec 21 2022 10:22:24 for gem5 by doxygen 1.9.1