gem5 v24.0.0.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
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
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
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 TlbEntry *e = tlb->lookup(vaddr, currState->satp.asid, currState->mode,
207 true);
208 Fault fault = NoFault;
209 if (e) {
210 fault = tlb->checkPermissions(currState->status, currState->pmode,
211 vaddr, currState->mode, e->pte);
212 }
213
214 while ((num_squashed < numSquashable) && currState &&
215 (currState->translation->squashed() || (e && fault == NoFault))) {
216 currStates.pop_front();
217 num_squashed++;
218
219 DPRINTF(PageTableWalker, "Squashing table walk for address %#x\n",
220 currState->req->getVaddr());
221
222 // finish the translation which will delete the translation object
223 if (currState->translation->squashed()) {
224 currState->translation->finish(
225 std::make_shared<UnimpFault>("Squashed Inst"),
226 currState->req, currState->tc, currState->mode);
227 } else {
228 tlb->translateTiming(currState->req, currState->tc,
229 currState->translation, currState->mode);
230 }
231
232 // delete the current request if there are no inflight packets.
233 // if there is something in flight, delete when the packets are
234 // received and inflight is zero.
235 if (currState->numInflight() == 0) {
236 delete currState;
237 } else {
238 currState->squash();
239 }
240
241 // check the next translation request, if it exists
242 if (currStates.size()) {
243 currState = currStates.front();
244 vaddr = Addr(sext<VADDR_BITS>(currState->req->getVaddr()));
245 e = tlb->lookup(vaddr, currState->satp.asid, currState->mode,
246 true);
247 if (e) {
248 fault = tlb->checkPermissions(currState->status,
249 currState->pmode, vaddr,
250 currState->mode, e->pte);
251 }
252 } else {
253 currState = NULL;
254 }
255 }
256 if (currState && !currState->wasStarted()) {
257 if (!e || fault != NoFault)
258 currState->startWalk();
259 else
261 }
262}
263
264Fault
266{
267 Fault fault = NoFault;
268 assert(!started);
269 started = true;
270 setupWalk(req->getVaddr());
271 if (timing) {
272 nextState = state;
273 state = Waiting;
274 timingFault = NoFault;
275 sendPackets();
276 } else {
277 do {
278 walker->port.sendAtomic(read);
279 PacketPtr write = NULL;
280 fault = stepWalk(write);
281 assert(fault == NoFault || read == NULL);
282 state = nextState;
283 nextState = Ready;
284 if (write)
285 walker->port.sendAtomic(write);
286 } while (read);
287 state = Ready;
288 nextState = Waiting;
289 }
290 return fault;
291}
292
293Fault
295{
296 Fault fault = NoFault;
297 assert(!started);
298 started = true;
299 setupWalk(addr);
300
301 do {
302 walker->port.sendFunctional(read);
303 // On a functional access (page table lookup), writes should
304 // not happen so this pointer is ignored after stepWalk
305 PacketPtr write = NULL;
306 fault = stepWalk(write);
307 assert(fault == NoFault || read == NULL);
308 state = nextState;
309 nextState = Ready;
310 } while (read);
311 logBytes = entry.logBytes;
312 addr = entry.paddr << PageShift;
313
314 return fault;
315}
316
317Fault
319{
320 assert(state != Ready && state != Waiting);
321 Fault fault = NoFault;
322 write = NULL;
323 PTESv39 pte = read->getLE<uint64_t>();
324 Addr nextRead = 0;
325 bool doWrite = false;
326 bool doTLBInsert = false;
327 bool doEndWalk = false;
328
329 DPRINTF(PageTableWalker, "Got level%d PTE: %#x\n", level, pte);
330
331 // step 2:
332 // Performing PMA/PMP checks on physical address of PTE
333
334 // Effective privilege mode for pmp checks for page table
335 // walks is S mode according to specs
336 fault = walker->pmp->pmpCheck(read->req, BaseMMU::Read,
337 RiscvISA::PrivilegeMode::PRV_S, tc, entry.vaddr);
338
339 if (fault == NoFault) {
340 fault = walker->pma->check(read->req, BaseMMU::Read, entry.vaddr);
341 }
342
343 if (fault == NoFault) {
344 // step 3:
345 if (!pte.v || (!pte.r && pte.w)) {
346 doEndWalk = true;
347 DPRINTF(PageTableWalker, "PTE invalid, raising PF\n");
348 fault = pageFault(pte.v);
349 }
350 else {
351 // step 4:
352 if (pte.r || pte.x) {
353 // step 5: leaf PTE
354 doEndWalk = true;
355 fault = walker->tlb->checkPermissions(status, pmode,
356 entry.vaddr, mode, pte);
357
358 // step 6
359 if (fault == NoFault) {
360 if (level >= 1 && pte.ppn0 != 0) {
361 DPRINTF(PageTableWalker,
362 "PTE has misaligned PPN, raising PF\n");
363 fault = pageFault(true);
364 }
365 else if (level == 2 && pte.ppn1 != 0) {
366 DPRINTF(PageTableWalker,
367 "PTE has misaligned PPN, raising PF\n");
368 fault = pageFault(true);
369 }
370 }
371
372 if (fault == NoFault) {
373 // step 7
374 if (!pte.a) {
375 pte.a = 1;
376 doWrite = true;
377 }
378 if (!pte.d && mode == BaseMMU::Write) {
379 pte.d = 1;
380 doWrite = true;
381 }
382 // Performing PMA/PMP checks
383
384 if (doWrite) {
385
386 // this read will eventually become write
387 // if doWrite is True
388
389 fault = walker->pmp->pmpCheck(read->req,
390 BaseMMU::Write, pmode, tc, entry.vaddr);
391
392 if (fault == NoFault) {
393 fault = walker->pma->check(read->req,
394 BaseMMU::Write, entry.vaddr);
395 }
396
397 }
398 // perform step 8 only if pmp checks pass
399 if (fault == NoFault) {
400 DPRINTF(PageTableWalker,
401 "#0 leaf node at level %d, with vpn %#x\n",
402 level, entry.vaddr);
403
404 // step 8
405 entry.logBytes = PageShift + (level * LEVEL_BITS);
406 entry.paddr = pte.ppn;
407 entry.vaddr &= ~((1 << entry.logBytes) - 1);
408 entry.pte = pte;
409 // put it non-writable into the TLB to detect
410 // writes and redo the page table walk in order
411 // to update the dirty flag.
412 if (!pte.d && mode != BaseMMU::Write)
413 entry.pte.w = 0;
414 doTLBInsert = true;
415
416 // Update statistics for completed page walks
417 if (level == 1) {
418 walker->pagewalkerstats.num_2mb_walks++;
419 }
420 if (level == 0) {
421 walker->pagewalkerstats.num_4kb_walks++;
422 }
423 DPRINTF(PageTableWalker,
424 "#1 leaf node at level %d, with vpn %#x\n",
425 level, entry.vaddr);
426 }
427 }
428 } else {
429 level--;
430 if (level < 0) {
431 DPRINTF(PageTableWalker, "No leaf PTE found,"
432 "raising PF\n");
433 doEndWalk = true;
434 fault = pageFault(true);
435 } else {
437 Addr idx = (entry.vaddr >> shift) & LEVEL_MASK;
438 nextRead = (pte.ppn << PageShift) + (idx * sizeof(pte));
439 nextState = Translate;
440 }
441 }
442 }
443 } else {
444 doEndWalk = true;
445 }
446 PacketPtr oldRead = read;
447 Request::Flags flags = oldRead->req->getFlags();
448
449 if (doEndWalk) {
450 // If we need to write, adjust the read packet to write the modified
451 // value back to memory.
452 if (!functional && doWrite) {
453 DPRINTF(PageTableWalker, "Writing level%d PTE to %#x: %#x\n",
454 level, oldRead->getAddr(), pte);
455 write = oldRead;
456 write->setLE<uint64_t>(pte);
457 write->cmd = MemCmd::WriteReq;
458 read = NULL;
459 } else {
460 write = NULL;
461 }
462
463 if (doTLBInsert) {
464 if (!functional)
465 walker->tlb->insert(entry.vaddr, entry);
466 else {
467 DPRINTF(PageTableWalker, "Translated %#x -> %#x\n",
468 entry.vaddr, entry.paddr << PageShift |
469 (entry.vaddr & mask(entry.logBytes)));
470 }
471 }
472 endWalk();
473 }
474 else {
475 //If we didn't return, we're setting up another read.
476 RequestPtr request = std::make_shared<Request>(
477 nextRead, oldRead->getSize(), flags, walker->requestorId);
478
479 delete oldRead;
480 oldRead = nullptr;
481
482 read = new Packet(request, MemCmd::ReadReq);
483 read->allocate();
484
485 DPRINTF(PageTableWalker,
486 "Loading level%d PTE from %#x\n", level, nextRead);
487 }
488
489 return fault;
490}
491
492void
494{
495 nextState = Ready;
496 delete read;
497 read = NULL;
498}
499
500void
502{
504
506 Addr idx = (vaddr >> shift) & LEVEL_MASK;
507 Addr topAddr = (satp.ppn << PageShift) + (idx * sizeof(PTESv39));
508 level = 2;
509
510 DPRINTF(PageTableWalker, "Performing table walk for address %#x\n", vaddr);
511 DPRINTF(PageTableWalker, "Loading level%d PTE from %#x\n", level, topAddr);
512
513 state = Translate;
514 nextState = Ready;
515 entry.vaddr = vaddr;
516 entry.asid = satp.asid;
517
519 RequestPtr request = std::make_shared<Request>(
520 topAddr, sizeof(PTESv39), flags, walker->requestorId);
521
522 read = new Packet(request, MemCmd::ReadReq);
523 read->allocate();
524}
525
526bool
528{
529 assert(pkt->isResponse());
530 assert(inflight);
531 assert(state == Waiting);
532 inflight--;
533 if (squashed) {
534 // if were were squashed, return true once inflight is zero and
535 // this WalkerState will be freed there.
536 return (inflight == 0);
537 }
538 if (pkt->isRead()) {
539 // should not have a pending read it we also had one outstanding
540 assert(!read);
541
542 // @todo someone should pay for this
543 pkt->headerDelay = pkt->payloadDelay = 0;
544
545 state = nextState;
546 nextState = Ready;
547 PacketPtr write = NULL;
548 read = pkt;
549 timingFault = stepWalk(write);
550 state = Waiting;
551 assert(timingFault == NoFault || read == NULL);
552 if (write) {
553 writes.push_back(write);
554 }
555 sendPackets();
556 } else {
557 delete pkt;
558
559 sendPackets();
560 }
561 if (inflight == 0 && read == NULL && writes.size() == 0) {
562 state = Ready;
563 nextState = Waiting;
564 if (timingFault == NoFault) {
565 /*
566 * Finish the translation. Now that we know the right entry is
567 * in the TLB, this should work with no memory accesses.
568 * There could be new faults unrelated to the table walk like
569 * permissions violations, so we'll need the return value as
570 * well.
571 */
572 Addr vaddr = req->getVaddr();
574 Addr paddr = walker->tlb->translateWithTLB(vaddr, satp.asid, mode);
575 req->setPaddr(paddr);
576
577 // do pmp check if any checking condition is met.
578 // timingFault will be NoFault if pmp checks are
579 // passed, otherwise an address fault will be returned.
580 timingFault = walker->pmp->pmpCheck(req, mode, pmode, tc);
581
582 if (timingFault == NoFault) {
583 timingFault = walker->pma->check(req, mode);
584 }
585
586 // Let the CPU continue.
587 translation->finish(timingFault, req, tc, mode);
588 } else {
589 // There was a fault during the walk. Let the CPU know.
590 translation->finish(timingFault, req, tc, mode);
591 }
592 return true;
593 }
594
595 return false;
596}
597
598void
600{
601 //If we're already waiting for the port to become available, just return.
602 if (retrying)
603 return;
604
605 //Reads always have priority
606 if (read) {
607 PacketPtr pkt = read;
608 read = NULL;
609 inflight++;
610 if (!walker->sendTiming(this, pkt)) {
611 retrying = true;
612 read = pkt;
613 inflight--;
614 return;
615 }
616 }
617 //Send off as many of the writes as we can.
618 while (writes.size()) {
619 PacketPtr write = writes.back();
620 writes.pop_back();
621 inflight++;
622 if (!walker->sendTiming(this, write)) {
623 retrying = true;
624 writes.push_back(write);
625 inflight--;
626 return;
627 }
628 }
629}
630
631unsigned
633{
634 return inflight;
635}
636
637bool
639{
640 return retrying;
641}
642
643bool
645{
646 return timing;
647}
648
649bool
651{
652 return started;
653}
654
655void
657{
658 squashed = true;
659}
660
661void
663{
664 retrying = false;
665 sendPackets();
666}
667
668Fault
670{
671 DPRINTF(PageTableWalker, "Raising page fault.\n");
672 return walker->tlb->createPagefault(entry.vaddr, mode);
673}
674
676 : statistics::Group(parent),
677 ADD_STAT(num_4kb_walks, statistics::units::Count::get(),
678 "Completed page walks with 4KB pages"),
679 ADD_STAT(num_2mb_walks, statistics::units::Count::get(),
680 "Completed page walks with 2MB pages")
681{
682}
683
684} // namespace RiscvISA
685} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
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
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.
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:603
@ PHYSICAL
The virtual address is also the physical address.
Definition request.hh:117
void translateTiming(const RequestPtr &req, ThreadContext *tc, BaseMMU::Translation *translation, BaseMMU::Mode mode) override
TlbEntry * lookup(Addr vpn, uint16_t asid, BaseMMU::Mode mode, bool hidden)
Definition tlb.cc:109
Fault checkPermissions(STATUS status, PrivilegeMode pmode, Addr vaddr, BaseMMU::Mode mode, PTESv39 pte)
Definition tlb.cc:223
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)
bool isTimingMode() const
Is the system in timing mode?
Definition system.hh:270
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
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
bool scheduled() const
Determine if the current event is scheduled.
Definition eventq.hh:458
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.
atomic_var_t state
Definition helpers.cc:211
uint8_t flags
Definition helpers.cc:87
Bitfield< 9 > e
Definition misc_types.hh:65
Bitfield< 5, 0 > status
Bitfield< 6, 5 > shift
Definition types.hh:117
const Addr LEVEL_BITS
Definition pagetable.hh:60
const Addr PageShift
Definition page_size.hh:53
const Addr LEVEL_MASK
Definition pagetable.hh:61
@ MISCREG_STATUS
Definition misc.hh:76
Bitfield< 20 > level
Definition intmessage.hh:51
Bitfield< 7 > present
Definition misc.hh:1027
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria 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
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 Tue Jun 18 2024 16:24:00 for gem5 by doxygen 1.11.0