gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
pagetable_walker.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012 ARM Limited
3 * Copyright (c) 2020 Barkhausen Institut
4 * All rights reserved.
5 *
6 * The license below extends only to copyright in the software and shall
7 * not be construed as granting a license to any other intellectual
8 * property including but not limited to intellectual property relating
9 * to a hardware implementation of the functionality of the software
10 * licensed hereunder. You may use the software subject to the license
11 * terms below provided that you ensure that this notice is replicated
12 * unmodified and in its entirety in all distributions of the software,
13 * modified or unmodified, in source code or in binary form.
14 *
15 * Copyright (c) 2007 The Hewlett-Packard Development Company
16 * All rights reserved.
17 *
18 * The license below extends only to copyright in the software and shall
19 * not be construed as granting a license to any other intellectual
20 * property including but not limited to intellectual property relating
21 * to a hardware implementation of the functionality of the software
22 * licensed hereunder. You may use the software subject to the license
23 * terms below provided that you ensure that this notice is replicated
24 * unmodified and in its entirety in all distributions of the software,
25 * modified or unmodified, in source code or in binary form.
26 *
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions are
29 * met: redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer;
31 * redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution;
34 * neither the name of the copyright holders nor the names of its
35 * contributors may be used to endorse or promote products derived from
36 * this software without specific prior written permission.
37 *
38 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
39 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
40 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
41 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
42 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
44 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
45 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
46 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
47 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
48 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49 */
50
52
53#include <memory>
54
55#include "arch/riscv/faults.hh"
58#include "arch/riscv/tlb.hh"
59#include "base/bitfield.hh"
60#include "base/trie.hh"
61#include "cpu/base.hh"
62#include "cpu/thread_context.hh"
63#include "debug/PageTableWalker.hh"
64#include "mem/packet_access.hh"
65#include "mem/request.hh"
66
67namespace gem5
68{
69
70namespace RiscvISA {
71
74 const RequestPtr &_req, BaseMMU::Mode _mode)
75{
76 // TODO: in timing mode, instead of blocking when there are other
77 // outstanding requests, see if this request can be coalesced with
78 // another one (i.e. either coalesce or start walk)
79 WalkerState * newState = new WalkerState(this, _translation, _req);
80 newState->initState(_tc, _mode, sys->isTimingMode());
81 if (currStates.size()) {
82 assert(newState->isTiming());
83 DPRINTF(PageTableWalker, "Walks in progress: %d\n", currStates.size());
84 currStates.push_back(newState);
85 return NoFault;
86 } else {
87 currStates.push_back(newState);
88 Fault fault = newState->startWalk();
89 if (!newState->isTiming()) {
90 currStates.pop_front();
91 delete newState;
92 }
93 return fault;
94 }
95}
96
98Walker::startFunctional(ThreadContext * _tc, Addr &addr, unsigned &logBytes,
99 BaseMMU::Mode _mode)
100{
101 funcState.initState(_tc, _mode);
102 return funcState.startFunctional(addr, logBytes);
103}
104
105bool
107{
108 return walker->recvTimingResp(pkt);
109}
110
111bool
113{
114 WalkerSenderState * senderState =
115 dynamic_cast<WalkerSenderState *>(pkt->popSenderState());
116 WalkerState * senderWalk = senderState->senderWalk;
117 bool walkComplete = senderWalk->recvPacket(pkt);
118 delete senderState;
119 if (walkComplete) {
121 for (iter = currStates.begin(); iter != currStates.end(); iter++) {
122 WalkerState * walkerState = *(iter);
123 if (walkerState == senderWalk) {
124 iter = currStates.erase(iter);
125 break;
126 }
127 }
128 delete senderWalk;
129 // Since we block requests when another is outstanding, we
130 // need to check if there is a waiting request to be serviced
131 if (currStates.size() && !startWalkWrapperEvent.scheduled())
132 // delay sending any new requests until we are finished
133 // with the responses
135 }
136 return true;
137}
138
139void
141{
142 walker->recvReqRetry();
143}
144
145void
147{
149 for (iter = currStates.begin(); iter != currStates.end(); iter++) {
150 WalkerState * walkerState = *(iter);
151 if (walkerState->isRetrying()) {
152 walkerState->retry();
153 }
154 }
155}
156
158{
159 WalkerSenderState* walker_state = new WalkerSenderState(sendingState);
160 pkt->pushSenderState(walker_state);
161 if (port.sendTimingReq(pkt)) {
162 return true;
163 } else {
164 // undo the adding of the sender state and delete it, as we
165 // will do it again the next time we attempt to send it
166 pkt->popSenderState();
167 delete walker_state;
168 return false;
169 }
170
171}
172
173Port &
174Walker::getPort(const std::string &if_name, PortID idx)
175{
176 if (if_name == "port")
177 return port;
178 else
179 return ClockedObject::getPort(if_name, idx);
180}
181
182void
184 BaseMMU::Mode _mode, bool _isTiming)
185{
186 assert(state == Ready);
187 started = false;
188 tc = _tc;
189 mode = _mode;
190 timing = _isTiming;
191 // fetch these now in case they change during the walk
192 status = tc->readMiscReg(MISCREG_STATUS);
193 pmode = walker->tlb->getMemPriv(tc, mode);
194 satp = tc->readMiscReg(MISCREG_SATP);
195 assert(satp.mode == AddrXlateMode::SV39);
196}
197
198void
200{
201 unsigned num_squashed = 0;
202 WalkerState *currState = currStates.front();
203
204 // check if we get a tlb hit to skip the walk
205 Addr vaddr = Addr(sext<VADDR_BITS>(currState->req->getVaddr()));
206 Addr vpn = getVPNFromVAddr(vaddr, currState->satp.mode);
207 TlbEntry *e = tlb->lookup(vpn, currState->satp.asid, currState->mode,
208 true);
209 Fault fault = NoFault;
210 if (e) {
211 fault = tlb->checkPermissions(currState->status, currState->pmode,
212 vaddr, currState->mode, e->pte);
213 }
214
215 while ((num_squashed < numSquashable) && currState &&
216 (currState->translation->squashed() || (e && fault == NoFault))) {
217 currStates.pop_front();
218 num_squashed++;
219
220 DPRINTF(PageTableWalker, "Squashing table walk for address %#x\n",
221 currState->req->getVaddr());
222
223 // finish the translation which will delete the translation object
224 if (currState->translation->squashed()) {
225 currState->translation->finish(
226 std::make_shared<UnimpFault>("Squashed Inst"),
227 currState->req, currState->tc, currState->mode);
228 } else {
229 tlb->translateTiming(currState->req, currState->tc,
230 currState->translation, currState->mode);
231 }
232
233 // delete the current request if there are no inflight packets.
234 // if there is something in flight, delete when the packets are
235 // received and inflight is zero.
236 if (currState->numInflight() == 0) {
237 delete currState;
238 } else {
239 currState->squash();
240 }
241
242 // check the next translation request, if it exists
243 if (currStates.size()) {
244 currState = currStates.front();
245 vaddr = Addr(sext<VADDR_BITS>(currState->req->getVaddr()));
246 Addr vpn = getVPNFromVAddr(vaddr, currState->satp.mode);
247 e = tlb->lookup(vpn, currState->satp.asid, currState->mode,
248 true);
249 if (e) {
250 fault = tlb->checkPermissions(currState->status,
251 currState->pmode, vaddr,
252 currState->mode, e->pte);
253 }
254 } else {
255 currState = NULL;
256 }
257 }
258 if (currState && !currState->wasStarted()) {
259 if (!e || fault != NoFault)
260 currState->startWalk();
261 else
263 }
264}
265
266Fault
268{
269 Fault fault = NoFault;
270 assert(!started);
271 started = true;
272 setupWalk(req->getVaddr());
273 if (timing) {
275 state = Waiting;
277 sendPackets();
278 } else {
279 do {
280 walker->port.sendAtomic(read);
281 PacketPtr write = NULL;
282 fault = stepWalk(write);
283 assert(fault == NoFault || read == NULL);
286 if (write)
287 walker->port.sendAtomic(write);
288 } while (read);
289 state = Ready;
291 }
292 return fault;
293}
294
295Fault
297{
298 Fault fault = NoFault;
299 assert(!started);
300 started = true;
302
303 do {
304 walker->port.sendFunctional(read);
305 // On a functional access (page table lookup), writes should
306 // not happen so this pointer is ignored after stepWalk
307 PacketPtr write = NULL;
308 fault = stepWalk(write);
309 assert(fault == NoFault || read == NULL);
312 } while (read);
313 logBytes = entry.logBytes;
314 addr = entry.paddr << PageShift;
315
316 return fault;
317}
318
319Fault
321{
322 assert(state != Ready && state != Waiting);
323 Fault fault = NoFault;
324 write = NULL;
325 PTESv39 pte = read->getLE<uint64_t>();
326 Addr nextRead = 0;
327 bool doWrite = false;
328 bool doTLBInsert = false;
329 bool doEndWalk = false;
330
331 DPRINTF(PageTableWalker, "Got level%d PTE: %#x\n", level, pte);
332
333 // step 2:
334 // Performing PMA/PMP checks on physical address of PTE
335
336 // Effective privilege mode for pmp checks for page table
337 // walks is S mode according to specs
338 fault = walker->pmp->pmpCheck(read->req, BaseMMU::Read,
340
341 if (fault == NoFault) {
342 fault = walker->pma->check(read->req, BaseMMU::Read, entry.vaddr);
343 }
344
345 if (fault == NoFault) {
346 // step 3:
347 if (!pte.v || (!pte.r && pte.w)) {
348 doEndWalk = true;
349 DPRINTF(PageTableWalker, "PTE invalid, raising PF\n");
350 fault = pageFault(pte.v);
351 }
352 else {
353 // step 4:
354 if (pte.r || pte.x) {
355 // step 5: leaf PTE
356 doEndWalk = true;
357 fault = walker->tlb->checkPermissions(status, pmode,
358 entry.vaddr, mode, pte);
359
360 // step 6
361 if (fault == NoFault) {
362 if (level >= 1 && pte.ppn0 != 0) {
363 DPRINTF(PageTableWalker,
364 "PTE has misaligned PPN, raising PF\n");
365 fault = pageFault(true);
366 }
367 else if (level == 2 && pte.ppn1 != 0) {
368 DPRINTF(PageTableWalker,
369 "PTE has misaligned PPN, raising PF\n");
370 fault = pageFault(true);
371 }
372 if (pte.n && (pte.ppn0 & mask(NapotShift)) != 8) {
373 DPRINTF(PageTableWalker,
374 "SVNAPOT PTE has wrong encoding, \
375 raising PF\n");
376 fault = pageFault(true);
377 }
378 }
379
380 if (fault == NoFault) {
381 // step 7
382 if (!pte.a) {
383 pte.a = 1;
384 doWrite = true;
385 }
386 if (!pte.d && mode == BaseMMU::Write) {
387 pte.d = 1;
388 doWrite = true;
389 }
390 // Performing PMA/PMP checks
391
392 if (doWrite) {
393
394 // this read will eventually become write
395 // if doWrite is True
396
397 fault = walker->pmp->pmpCheck(read->req,
398 BaseMMU::Write, pmode, tc, entry.vaddr);
399
400 if (fault == NoFault) {
401 fault = walker->pma->check(read->req,
402 BaseMMU::Write, entry.vaddr);
403 }
404
405 }
406 // perform step 8 only if pmp checks pass
407 if (fault == NoFault) {
408 DPRINTF(PageTableWalker,
409 "#0 leaf node at level %d, with vpn %#x\n",
410 level, entry.vaddr);
411
412 // step 8
413 // Check if N (contig bit) is set, if yes we have
414 // a 64K page mapping (SVNAPOT Extension)
415 assert(!(pte.n) || level == 0);
416 entry.logBytes = (pte.n) ? PageShift + NapotShift :
418 entry.paddr = (pte.n) ? pte.ppn & ~mask(NapotShift) :
419 pte.ppn;
420 entry.vaddr &= ~((1 << entry.logBytes) - 1);
421 entry.pte = pte;
422 // put it non-writable into the TLB to detect
423 // writes and redo the page table walk in order
424 // to update the dirty flag.
425 if (!pte.d && mode != BaseMMU::Write)
426 entry.pte.w = 0;
427 doTLBInsert = true;
428
429 // Update statistics for completed page walks
430 if (level == 1) {
431 walker->pagewalkerstats.num_2mb_walks++;
432 }
433 if (level == 0) {
434 if (pte.n)
435 walker->pagewalkerstats.num_64kb_walks++;
436 else
437 walker->pagewalkerstats.num_4kb_walks++;
438 }
439 DPRINTF(PageTableWalker,
440 "#1 leaf node at level %d, with vpn %#x\n",
441 level, entry.vaddr);
442 }
443 }
444 } else {
445 level--;
446 if (level < 0) {
447 DPRINTF(PageTableWalker, "No leaf PTE found,"
448 "raising PF\n");
449 doEndWalk = true;
450 fault = pageFault(true);
451 } else {
453 Addr idx = (entry.vaddr >> shift) & LEVEL_MASK;
454 nextRead = (pte.ppn << PageShift) + (idx * sizeof(pte));
456 }
457 }
458 }
459 } else {
460 doEndWalk = true;
461 }
462 PacketPtr oldRead = read;
463 Request::Flags flags = oldRead->req->getFlags();
464
465 if (doEndWalk) {
466 // If we need to write, adjust the read packet to write the modified
467 // value back to memory.
468 if (!functional && doWrite) {
469 DPRINTF(PageTableWalker, "Writing level%d PTE to %#x: %#x\n",
470 level, oldRead->getAddr(), pte);
471 write = oldRead;
472 write->setLE<uint64_t>(pte);
473 write->cmd = MemCmd::WriteReq;
474 read = NULL;
475 } else {
476 write = NULL;
477 }
478
479 if (doTLBInsert) {
480 if (!functional) {
481 Addr vpn = getVPNFromVAddr(entry.vaddr, satp.mode);
482 walker->tlb->insert(vpn, entry);
483 } else {
484 DPRINTF(PageTableWalker, "Translated %#x -> %#x\n",
485 entry.vaddr, entry.paddr << PageShift |
486 (entry.vaddr & mask(entry.logBytes)));
487 }
488 }
489 endWalk();
490 }
491 else {
492 //If we didn't return, we're setting up another read.
493 RequestPtr request = std::make_shared<Request>(
494 nextRead, oldRead->getSize(), flags, walker->requestorId);
495
496 delete oldRead;
497 oldRead = nullptr;
498
499 read = new Packet(request, MemCmd::ReadReq);
500 read->allocate();
501
502 DPRINTF(PageTableWalker,
503 "Loading level%d PTE from %#x\n", level, nextRead);
504 }
505
506 return fault;
507}
508
509void
511{
513 delete read;
514 read = NULL;
515}
516
517void
519{
521
523 Addr idx = (vaddr >> shift) & LEVEL_MASK;
524 Addr topAddr = (satp.ppn << PageShift) + (idx * sizeof(PTESv39));
525 level = 2;
526
527 DPRINTF(PageTableWalker, "Performing table walk for address %#x\n", vaddr);
528 DPRINTF(PageTableWalker, "Loading level%d PTE from %#x\n", level, topAddr);
529
532 entry.vaddr = vaddr;
533 entry.asid = satp.asid;
534
536 RequestPtr request = std::make_shared<Request>(
537 topAddr, sizeof(PTESv39), flags, walker->requestorId);
538
539 read = new Packet(request, MemCmd::ReadReq);
540 read->allocate();
541}
542
543bool
545{
546 assert(pkt->isResponse());
547 assert(inflight);
548 assert(state == Waiting);
549 inflight--;
550 if (squashed) {
551 // if were were squashed, return true once inflight is zero and
552 // this WalkerState will be freed there.
553 return (inflight == 0);
554 }
555 if (pkt->isRead()) {
556 // should not have a pending read it we also had one outstanding
557 assert(!read);
558
559 // @todo someone should pay for this
560 pkt->headerDelay = pkt->payloadDelay = 0;
561
564 PacketPtr write = NULL;
565 read = pkt;
566 timingFault = stepWalk(write);
567 state = Waiting;
568 assert(timingFault == NoFault || read == NULL);
569 if (write) {
570 writes.push_back(write);
571 }
572 sendPackets();
573 } else {
574 delete pkt;
575
576 sendPackets();
577 }
578 if (inflight == 0 && read == NULL && writes.size() == 0) {
579 state = Ready;
581 if (timingFault == NoFault) {
582 /*
583 * Finish the translation. Now that we know the right entry is
584 * in the TLB, this should work with no memory accesses.
585 * There could be new faults unrelated to the table walk like
586 * permissions violations, so we'll need the return value as
587 * well.
588 */
589 Addr vaddr = req->getVaddr();
591 Addr paddr = walker->tlb->hiddenTranslateWithTLB(vaddr, satp.asid,
592 satp.mode, mode);
593 req->setPaddr(paddr);
594
595 // do pmp check if any checking condition is met.
596 // timingFault will be NoFault if pmp checks are
597 // passed, otherwise an address fault will be returned.
598 timingFault = walker->pmp->pmpCheck(req, mode, pmode, tc);
599
600 if (timingFault == NoFault) {
601 timingFault = walker->pma->check(req, mode);
602 }
603
604 // Let the CPU continue.
605 translation->finish(timingFault, req, tc, mode);
606 } else {
607 // There was a fault during the walk. Let the CPU know.
608 translation->finish(timingFault, req, tc, mode);
609 }
610 return true;
611 }
612
613 return false;
614}
615
616void
618{
619 //If we're already waiting for the port to become available, just return.
620 if (retrying)
621 return;
622
623 //Reads always have priority
624 if (read) {
625 PacketPtr pkt = read;
626 read = NULL;
627 inflight++;
628 if (!walker->sendTiming(this, pkt)) {
629 retrying = true;
630 read = pkt;
631 inflight--;
632 return;
633 }
634 }
635 //Send off as many of the writes as we can.
636 while (writes.size()) {
637 PacketPtr write = writes.back();
638 writes.pop_back();
639 inflight++;
640 if (!walker->sendTiming(this, write)) {
641 retrying = true;
642 writes.push_back(write);
643 inflight--;
644 return;
645 }
646 }
647}
648
649unsigned
651{
652 return inflight;
653}
654
655bool
660
661bool
663{
664 return timing;
665}
666
667bool
672
673void
675{
676 squashed = true;
677}
678
679void
681{
682 retrying = false;
683 sendPackets();
684}
685
686Fault
688{
689 DPRINTF(PageTableWalker, "Raising page fault.\n");
690 return walker->tlb->createPagefault(entry.vaddr, mode);
691}
692
694 : statistics::Group(parent),
695 ADD_STAT(num_4kb_walks, statistics::units::Count::get(),
696 "Completed page walks with 4KB pages"),
697 ADD_STAT(num_64kb_walks, statistics::units::Count::get(),
698 "Completed page walks with 64KB pages"),
699 ADD_STAT(num_2mb_walks, statistics::units::Count::get(),
700 "Completed page walks with 2MB pages")
701{
702}
703
704} // namespace RiscvISA
705} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
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
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...
Cycles is a wrapper class for representing cycle counts, i.e.
Definition types.hh:79
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
bool isRead() const
Definition packet.hh:593
Addr getAddr() const
Definition packet.hh:807
void setLE(T v)
Set the value in the data pointer to v as little endian.
bool isResponse() const
Definition packet.hh:598
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
uint32_t headerDelay
The extra delay from seeing the packet until the header is transmitted.
Definition packet.hh:431
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:377
unsigned getSize() const
Definition packet.hh:817
MemCmd cmd
The command field of the packet.
Definition packet.hh:372
Ports are used to interface objects to each other.
Definition port.hh:62
@ PHYSICAL
The virtual address is also the physical address.
Definition request.hh:117
gem5::Flags< FlagsType > Flags
Definition request.hh:102
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)
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)
ThreadContext is the external interface to all thread state for anything outside of the CPU.
Statistics container.
Definition group.hh:93
STL list class.
Definition stl.hh:51
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition group.hh:75
constexpr uint64_t sext(uint64_t val)
Sign-extend an N-bit value to 64 bits.
Definition bitfield.hh:129
void schedule(Event &event, Tick when)
Definition eventq.hh:1012
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Bitfield< 9 > e
Definition misc_types.hh:65
Bitfield< 6, 5 > shift
Definition types.hh:117
const Addr LEVEL_BITS
Definition pagetable.hh:61
const Addr NapotShift
Definition page_size.hh:55
Addr getVPNFromVAddr(Addr vaddr, Addr mode)
Definition pagetable.cc:64
const Addr PageShift
Definition page_size.hh:53
const Addr LEVEL_MASK
Definition pagetable.hh:62
@ MISCREG_STATUS
Definition misc.hh:76
Bitfield< 7 > present
Definition misc.hh:1027
Bitfield< 3 > addr
Definition types.hh:84
Units for Stats.
Definition units.hh:113
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
std::shared_ptr< FaultBase > Fault
Definition types.hh:249
std::shared_ptr< Request > RequestPtr
Definition request.hh:94
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
Packet * PacketPtr
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 ...
PagewalkerStats(statistics::Group *parent)

Generated on Mon May 26 2025 09:19:06 for gem5 by doxygen 1.13.2