gem5 v25.0.0.1
Loading...
Searching...
No Matches
tlb.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2001-2005 The Regents of The University of Michigan
3 * Copyright (c) 2007 MIPS Technologies, Inc.
4 * Copyright (c) 2020 Barkhausen Institut
5 * Copyright (c) 2021 Huawei International
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met: redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer;
12 * redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution;
15 * neither the name of the copyright holders nor the names of its
16 * contributors may be used to endorse or promote products derived from
17 * this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32#include "arch/riscv/tlb.hh"
33
34#include <string>
35#include <vector>
36
37#include "arch/riscv/faults.hh"
39#include "arch/riscv/mmu.hh"
43#include "arch/riscv/pmp.hh"
45#include "arch/riscv/utility.hh"
46#include "base/inifile.hh"
47#include "base/str.hh"
48#include "base/trace.hh"
49#include "cpu/thread_context.hh"
50#include "debug/TLB.hh"
51#include "debug/TLBVerbose.hh"
52#include "mem/page_table.hh"
53#include "params/RiscvTLB.hh"
54#include "sim/full_system.hh"
55#include "sim/process.hh"
56#include "sim/system.hh"
57
58namespace gem5
59{
60
61using namespace RiscvISA;
62
64//
65// RISC-V TLB
66//
67
68static Addr
69buildKey(Addr vpn, uint16_t asid)
70{
71 // Note ASID is 16 bits
72 // The VPN in sv39 is up to 39-12=27 bits
73 // The VPN in sv48 is up to 48-12=36 bits
74 // The VPN in sv57 is up to 57-12=45 bits
75 // So, shifting the ASID into the top 16 bits is safe.
76 assert(bits(vpn, 63, 48) == 0);
77 return (static_cast<Addr>(asid) << 48) | vpn;
78}
79
80TLB::TLB(const Params &p) :
81 BaseTLB(p), size(p.size), tlb(size),
82 lruSeq(0), stats(this), pma(p.pma_checker),
83 pmp(p.pmp)
84{
85 for (size_t x = 0; x < size; x++) {
86 tlb[x].trieHandle = NULL;
87 freeList.push_back(&tlb[x]);
88 }
89
90 walker = p.walker;
91 walker->setTLB(this);
92}
93
94Walker *
96{
97 return walker;
98}
99
100void
102{
103 // Find the entry with the lowest (and hence least recently updated)
104 // sequence number.
105
106 size_t lru = 0;
107 for (size_t i = 1; i < size; i++) {
108 if (tlb[i].lruSeq < tlb[lru].lruSeq)
109 lru = i;
110 }
111
112 remove(lru);
113}
114
115TlbEntry *
116TLB::lookup(Addr vpn, uint16_t asid, BaseMMU::Mode mode, bool hidden)
117{
118 TlbEntry *entry = trie.lookup(buildKey(vpn, asid));
119
120 DPRINTF(TLBVerbose, "lookup(vpn=%#x, asid=%#x, key=%#x): "
121 "%s ppn=%#x (%#x) %s\n",
122 vpn, asid, buildKey(vpn, asid), entry ? "hit" : "miss",
123 entry ? entry->paddr : 0, entry ? entry->size() : 0,
124 hidden ? "hidden" : "");
125
126 if (!hidden) {
127 if (entry)
128 entry->lruSeq = nextSeq();
129
130 if (mode == BaseMMU::Write)
131 stats.writeAccesses++;
132 else
133 stats.readAccesses++;
134
135 if (!entry) {
136 if (mode == BaseMMU::Write)
137 stats.writeMisses++;
138 else
139 stats.readMisses++;
140 }
141 else {
142 if (mode == BaseMMU::Write)
143 stats.writeHits++;
144 else
145 stats.readHits++;
146 }
147 }
148
149 return entry;
150}
151
152TlbEntry *
153TLB::insert(Addr vpn, const TlbEntry &entry)
154{
155 DPRINTF(TLB, "insert(vpn=%#x, asid=%#x, key=%#x): "
156 "vaddr=%#x paddr=%#x pte=%#x size=%#x\n",
157 vpn, entry.asid, buildKey(vpn, entry.asid), entry.vaddr, entry.paddr,
158 entry.pte, entry.size());
159
160 // If somebody beat us to it, just use that existing entry.
161 TlbEntry *newEntry = lookup(vpn, entry.asid, BaseMMU::Read, true);
162 if (newEntry) {
163 // update PTE flags (maybe we set the dirty/writable flag)
164 newEntry->pte = entry.pte;
165 assert(newEntry->vaddr == entry.vaddr);
166 assert(newEntry->asid == entry.asid);
167 assert(newEntry->logBytes == entry.logBytes);
168 return newEntry;
169 }
170
171 if (freeList.empty())
172 evictLRU();
173
174 newEntry = freeList.front();
175 freeList.pop_front();
176
177 Addr key = buildKey(vpn, entry.asid);
178 *newEntry = entry;
179 newEntry->lruSeq = nextSeq();
180 newEntry->trieHandle = trie.insert(
181 key, TlbEntryTrie::MaxBits - entry.logBytes + PageShift, newEntry
182 );
183 return newEntry;
184}
185
186void
187TLB::demapPage(Addr vaddr, uint64_t asid)
188{
189 // Note: vaddr is Reg[rs1] and asid is Reg[rs2]
190 // The definition of this instruction is
191 // if vaddr=x0 and asid=x0, then flush all
192 // if vaddr=x0 and asid!=x0 then flush all with matching asid
193 // if vaddr!=x0 and asid=x0 then flush all leaf PTEs that match vaddr
194 // if vaddr!=x0 and asid!=x0 then flush the leaf PTE that matches vaddr
195 // in the given asid.
196 // No effect if vaddr is not valid
197 // Currently, we assume if the values of the registers are 0 then it was
198 // referencing x0.
199
200 asid &= 0xFFFF;
201
202 DPRINTF(TLB, "flush(vaddr=%#x, asid=%#x)\n", vaddr, asid);
203 if (vaddr == 0 && asid == 0) {
204 DPRINTF(TLB, "Flushing all TLB entries\n");
205 flushAll();
206 } else {
207 if (vaddr != 0 && asid != 0) {
208 // TODO: When supporting other address translation modes, fix this
209 Addr vpn = getVPNFromVAddr(vaddr, AddrXlateMode::SV39);
210 TlbEntry *entry = lookup(vpn, asid, BaseMMU::Read, true);
211 if (entry) {
212 remove(entry - tlb.data());
213 }
214 }
215 else {
216 for (size_t i = 0; i < size; i++) {
217 if (tlb[i].trieHandle) {
218 Addr mask = ~(tlb[i].size() - 1);
219 if ((vaddr == 0 || (vaddr & mask) == tlb[i].vaddr) &&
220 (asid == 0 || tlb[i].asid == asid))
221 remove(i);
222 }
223 }
224 }
225 }
226}
227
228void
229TLB::flushAll()
230{
231 DPRINTF(TLB, "flushAll()\n");
232 for (size_t i = 0; i < size; i++) {
233 if (tlb[i].trieHandle)
234 remove(i);
235 }
236}
237
238void
239TLB::remove(size_t idx)
240{
241 DPRINTF(TLB, "remove(vpn=%#x, asid=%#x): ppn=%#x pte=%#x size=%#x\n",
242 tlb[idx].vaddr, tlb[idx].asid, tlb[idx].paddr, tlb[idx].pte,
243 tlb[idx].size());
244
245 assert(tlb[idx].trieHandle);
246 trie.remove(tlb[idx].trieHandle);
247 tlb[idx].trieHandle = NULL;
248 freeList.push_back(&tlb[idx]);
249}
250
251Fault
253 BaseMMU::Mode mode, PTESv39 pte, Addr gvaddr, XlateStage stage)
254{
255 MISA misa = tc->readMiscReg(MISCREG_ISA);
256 STATUS status = tc->readMiscReg(MISCREG_STATUS);
258 PRV_U : mem_access.priv;
259
260 bool sum = status.sum;
261 bool mxr = status.mxr;
262 bool gpf = stage == GSTAGE;
263 bool virt = mem_access.virt;
264
265 bool pf = false;
266
267 if (misa.rvh && mem_access.virt && stage == FIRST_STAGE) {
268 STATUS vsstatus = tc->readMiscReg(MISCREG_VSSTATUS);
269 sum = vsstatus.sum;
270 mxr |= vsstatus.mxr;
271 }
272
273
274 if (mem_access.hlvx) {
275 if (!pte.x) {
276 pf = true; DPRINTF(TLB, "HLVX with no exec perm, raising PF\n");
277 }
278 }
279 else if (mode == BaseMMU::Read && !pte.r) {
280 if (mxr && pte.x) {
281 DPRINTF(TLBVerbose, "MXR bit on, load from exec page success\n");
282 }
283 else {
284 pf = true; DPRINTF(TLB, "PTE has no read perm, raising PF\n");
285 }
286 }
287 else if (mode == BaseMMU::Write && !pte.w) {
288 pf = true; DPRINTF(TLB, "PTE has no write perm, raising PF\n");
289 }
290 else if (mode == BaseMMU::Execute && !pte.x) {
291 pf = true; DPRINTF(TLB, "PTE has no exec perm, raising PF\n");
292 }
293
294 if (!pf) {
295 // check pte.u
296 if (priv == PRV_U && !pte.u) {
297 pf = true; DPRINTF(TLB, "PTE not user accessible, raising PF\n");
298 }
299 else if (priv == PRV_S && pte.u &&
300 (mode == BaseMMU::Execute || sum == 0)) {
301 pf = true; DPRINTF(TLB, "PTE only user accessible, raising PF\n");
302 }
303 }
304
305 return pf ? createPagefault(vaddr, mode, gvaddr, gpf, virt) : NoFault;
306}
307
308Fault
310 Addr gvaddr, bool gpf, bool virt)
311{
312 ExceptionCode code;
313 if (mode == BaseMMU::Read) {
314 code = gpf ? ExceptionCode::LOAD_GUEST_PAGE :
316 }
317 else if (mode == BaseMMU::Write) {
320 }
321 else {
322 code = gpf ? ExceptionCode::INST_GUEST_PAGE :
324 }
325
326 if (gpf) { assert(virt); }
327 return std::make_shared<AddressFault>(vaddr, code, gvaddr, virt);
328}
329
330Addr
333{
334 TlbEntry *e = lookup(getVPNFromVAddr(vaddr, xmode), asid, mode, true);
335 assert(e != nullptr);
336 return e->paddr << PageShift | (vaddr & mask(e->logBytes));
337}
338
339Fault
342 bool &delayed)
343{
344 delayed = false;
345
346 MemAccessInfo memaccess = getMemAccessInfo(tc, mode, req->getArchFlags());
347 Addr vaddr = req->getVaddr();
348
349 MISA misa = tc->readMiscReg(MISCREG_ISA);
350
351 SATP satp = (misa.rvh && memaccess.virt) ?
354
355 Addr vpn = getVPNFromVAddr(vaddr, satp.mode);
356
357 TlbEntry *e = nullptr;
358 if (!memaccess.bypassTLB()) {
359 e = lookup(vpn, satp.asid, mode, false);
360 if (!e) {
361 Fault fault = walker->start(tc, translation, req, mode);
362 // Atomic translations have translation == nullptr
363 // so the if body is reachable only in timing
364 if (translation != nullptr) {
365 // If there has been a fault already, do not
366 // mark the translation as delayed as that
367 // will block its deletion
368 if (fault != NoFault) {
369 delayed = false;
370 } else {
371 delayed = true;
372 }
373 return fault;
374 }
375 else if (fault != NoFault) {
376 return fault;
377 }
378 e = lookup(vpn, satp.asid, mode, true);
379 assert(e != nullptr);
380 }
381 }
382 else {
383 // Don't lookup and don't insert when bypassing the TLB.
384 // We get the translation result back in memory pointed to by
385 // TlbEntry *e which is not inserted!
386 e = new TlbEntry();
387 Fault fault = walker->start(tc, translation, req, mode, e);
388
389 if (translation != nullptr || fault != NoFault) {
390 // This gets ignored in atomic mode.
391 delayed = true;
392 return fault;
393 }
394 }
395
396 Fault fault;
397 if (memaccess.bypassTLB()) {
398 fault = NoFault;
399 }
400 else {
401 if (memaccess.virt) {
402 if (e->gpte != 0) {
403 fault = checkPermissions(
404 tc, memaccess, vaddr, mode, e->gpte);
405 } else {
406 fault = NoFault;
407 }
408 }
409 else {
410 fault = checkPermissions(
411 tc, memaccess, vaddr, mode, e->pte);
412 }
413 }
414
415 // if we want to write and it isn't writable, do a page table walk
416 // again to update the dirty flag.
417 if (e && (mode == BaseMMU::Write) && !e->pte.w) {
418 DPRINTF(TLB, "Dirty bit not set, repeating PT walk\n");
419 fault = walker->start(tc, translation, req, mode);
420 // Atomic translations have translation == nullptr
421 // so the if body is reachable only in timing
422 if (translation != nullptr) {
423 // If there has been a fault already, do not
424 // mark the translation as delayed as that
425 // will block its deletion
426 if (fault != NoFault) {
427 delayed = false;
428 } else {
429 delayed = true;
430 }
431
432 if (memaccess.bypassTLB())
433 delete e;
434 return fault;
435 }
436 else if (fault != NoFault) {
437 if (memaccess.bypassTLB())
438 delete e;
439 return fault;
440 }
441 }
442
443 if (fault != NoFault) {
444 if (memaccess.bypassTLB())
445 delete e;
446 return fault;
447 }
448
449 Addr paddr = ((e->paddr >> (e->logBytes - PageShift)) << e->logBytes)
450 | (vaddr & mask(e->logBytes));
451
452 DPRINTF(TLBVerbose, "translate(vaddr=%#x, vpn=%#x, asid=%#x): %#x\n",
453 vaddr, vpn, satp.asid, paddr);
454 req->setPaddr(paddr);
455
456 if (memaccess.bypassTLB())
457 delete e;
458
459 return NoFault;
460}
461
464 const Request::ArchFlagsType arch_flags)
465{
466 MISA misa = tc->readMiscReg(MISCREG_ISA);
467 STATUS status = tc->readMiscReg(MISCREG_STATUS);
468 HSTATUS hstatus = tc->readMiscReg(MISCREG_HSTATUS);
470
471 bool virt = misa.rvh ? virtualizationEnabled(tc) : false;
472 bool force_virt = false;
473 bool hlvx = false;
474 bool lr = false;
475
476 if (mode != BaseMMU::Execute && status.mprv == 1) {
478 if (misa.rvh && status.mpv && priv != PRV_M) {
479 virt = true;
480 }
481 }
482
483 if (misa.rva) {
484 if (arch_flags & XlateFlags::LR) {
485 lr = true;
486 }
487 }
488
489 if (misa.rvh) {
490 if (arch_flags & XlateFlags::FORCE_VIRT) {
491 priv = (PrivilegeMode)(RegVal)hstatus.spvp;
492 virt = true;
493 force_virt = true;
494 }
495 if (arch_flags & XlateFlags::HLVX) {
496 hlvx = true;
497 }
498 }
499 return MemAccessInfo(priv, virt, force_virt, hlvx, lr);
500}
501
502Fault
505 bool &delayed)
506{
507 delayed = false;
508
509 if (FullSystem) {
511 tc, mode, req->getArchFlags());
512 PrivilegeMode pmode = memaccess.priv;
513 MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA);
514 SATP satp = (misa.rvh && memaccess.virt) ?
517
518 Fault fault = NoFault;
519
520 fault = pma->checkVAddrAlignment(req, mode);
521
522 if (!misa.rvs || pmode == PrivilegeMode::PRV_M ||
523 satp.mode == AddrXlateMode::BARE) {
524
525 // In H-Extension there is the case for VS mode
526 // that SATP's mode is BARE but we still have
527 // to check if we need to perform G-stage (2nd stage)
528 // translation. The request is PHYSICAL only if
529 // HGATP's mode is also BARE, else we perform
530 // the G-stage translation.
531 if (misa.rvh && memaccess.virt) {
532 SATP hgatp = tc->readMiscReg(MISCREG_HGATP);
533 if (hgatp.mode == AddrXlateMode::BARE) {
534 req->setFlags(Request::PHYSICAL);
535 }
536 }
537 else {
538 req->setFlags(Request::PHYSICAL);
539 }
540 }
541
542 if (fault == NoFault) {
543 if (req->getFlags() & Request::PHYSICAL) {
547 req->setPaddr(getValidAddr(req->getVaddr(), tc, mode));
548 } else {
549 fault = doTranslate(req, tc, translation, mode, delayed);
550 }
551 }
552
553 // according to the RISC-V tests, negative physical addresses trigger
554 // an illegal address exception.
555 // TODO where is that written in the manual?
556 if (!delayed && fault == NoFault && bits(req->getPaddr(), 63)) {
557 ExceptionCode code;
558 if (mode == BaseMMU::Read)
560 else if (mode == BaseMMU::Write)
562 else
564 fault = std::make_shared<AddressFault>(req->getVaddr(), code);
565 }
566
567 if (!delayed && fault == NoFault) {
568 // do pmp check if any checking condition is met.
569 // timingFault will be NoFault if pmp checks are
570 // passed, otherwise an address fault will be returned.
571 fault = pmp->pmpCheck(req, mode, pmode, tc);
572 }
573
574 if (!delayed && fault == NoFault) {
575 fault = pma->check(req, mode);
576 }
577 return fault;
578 } else {
579 // In the O3 CPU model, sometimes a memory access will be speculatively
580 // executed along a branch that will end up not being taken where the
581 // address is invalid. In that case, return a fault rather than trying
582 // to translate it (which will cause a panic). Since RISC-V allows
583 // unaligned memory accesses, this should only happen if the request's
584 // length is long enough to wrap around from the end of the memory to
585 // the start.
586 assert(req->getSize() > 0);
587 if (req->getVaddr() + req->getSize() - 1 < req->getVaddr())
588 return std::make_shared<GenericPageTableFault>(req->getVaddr());
589
590 Process * p = tc->getProcessPtr();
591
592 /*
593 * In RV32 Linux, as vaddr >= 0x80000000 is legal in userspace
594 * (except for COMPAT mode for RV32 Userspace in RV64 Linux), we
595 * need to ignore the upper bits beyond 32 bits.
596 */
597 Addr vaddr = getValidAddr(req->getVaddr(), tc, mode);
598 Addr paddr;
599
600 if (!p->pTable->translate(vaddr, paddr))
601 return std::make_shared<GenericPageTableFault>(req->getVaddr());
602
603 req->setPaddr(paddr);
604
605 return NoFault;
606 }
607}
608
609Fault
612{
613 bool delayed;
614 return translate(req, tc, nullptr, mode, delayed);
615}
616
617void
620{
621 bool delayed;
622 assert(translation);
623 Fault fault = translate(req, tc, translation, mode, delayed);
624 if (!delayed)
625 translation->finish(fault, req, tc, mode);
626 else
627 translation->markDelayed();
628}
629
630Fault
631TLB::translateFunctional(const RequestPtr &req, ThreadContext *tc,
632 BaseMMU::Mode mode)
633{
634 const Addr vaddr = getValidAddr(req->getVaddr(), tc, mode);
635 Addr paddr = vaddr;
636
637 if (FullSystem) {
638 MMU *mmu = static_cast<MMU *>(tc->getMMUPtr());
639
640 MemAccessInfo memaccess = getMemAccessInfo(
641 tc, mode, req->getArchFlags());
642 PrivilegeMode pmode = memaccess.priv;
643 MISA misa = tc->readMiscRegNoEffect(MISCREG_ISA);
644 SATP satp = tc->readMiscReg(MISCREG_SATP);
645 if (misa.rvs && pmode != PrivilegeMode::PRV_M &&
646 satp.mode != AddrXlateMode::BARE) {
647 Walker *walker = mmu->getDataWalker();
648 unsigned logBytes;
649 Fault fault = walker->startFunctional(
650 tc, paddr, logBytes, mode);
651 if (fault != NoFault)
652 return fault;
653
654 Addr masked_addr = vaddr & mask(logBytes);
655 paddr |= masked_addr;
656 }
657 }
658 else {
659 Process *process = tc->getProcessPtr();
660 const auto *pte = process->pTable->lookup(vaddr);
661
662 if (!pte && mode != BaseMMU::Execute) {
663 // Check if we just need to grow the stack.
664 if (process->fixupFault(vaddr)) {
665 // If we did, lookup the entry for the new page.
666 pte = process->pTable->lookup(vaddr);
667 }
668 }
669
670 if (!pte)
671 return std::make_shared<GenericPageTableFault>(req->getVaddr());
672
673 paddr = pte->paddr | process->pTable->pageOffset(vaddr);
674 }
675
676 DPRINTF(TLB, "Translated (functional) %#x -> %#x.\n", vaddr, paddr);
677 req->setPaddr(paddr);
678 return NoFault;
679}
680
681Fault
682TLB::finalizePhysical(const RequestPtr &req,
683 ThreadContext *tc, BaseMMU::Mode mode) const
684{
685 return NoFault;
686}
687
688void
689TLB::serialize(CheckpointOut &cp) const
690{
691 // Only store the entries in use.
692 uint32_t _size = size - freeList.size();
693 SERIALIZE_SCALAR(_size);
694 SERIALIZE_SCALAR(lruSeq);
695
696 uint32_t _count = 0;
697 for (uint32_t x = 0; x < size; x++) {
698 if (tlb[x].trieHandle != NULL)
699 tlb[x].serializeSection(cp, csprintf("Entry%d", _count++));
700 }
701}
702
703void
704TLB::unserialize(CheckpointIn &cp)
705{
706 // Do not allow to restore with a smaller tlb.
707 uint32_t _size;
708 UNSERIALIZE_SCALAR(_size);
709 if (_size > size) {
710 fatal("TLB size less than the one in checkpoint!");
711 }
712
713 UNSERIALIZE_SCALAR(lruSeq);
714
715 for (uint32_t x = 0; x < _size; x++) {
716 TlbEntry *newEntry = freeList.front();
717 freeList.pop_front();
718
719 newEntry->unserializeSection(cp, csprintf("Entry%d", x));
720 // TODO: When supporting other addressing modes fix this
721 Addr vpn = getVPNFromVAddr(newEntry->vaddr, AddrXlateMode::SV39);
722 Addr key = buildKey(vpn, newEntry->asid);
723 newEntry->trieHandle = trie.insert(key,
724 TlbEntryTrie::MaxBits - newEntry->logBytes + PageShift, newEntry);
725 }
726}
727
729 : statistics::Group(parent),
730 ADD_STAT(readHits, statistics::units::Count::get(), "read hits"),
731 ADD_STAT(readMisses, statistics::units::Count::get(), "read misses"),
732 ADD_STAT(readAccesses, statistics::units::Count::get(), "read accesses"),
733 ADD_STAT(writeHits, statistics::units::Count::get(), "write hits"),
734 ADD_STAT(writeMisses, statistics::units::Count::get(), "write misses"),
735 ADD_STAT(writeAccesses, statistics::units::Count::get(), "write accesses"),
736 ADD_STAT(hits, statistics::units::Count::get(),
737 "Total TLB (read and write) hits", readHits + writeHits),
738 ADD_STAT(misses, statistics::units::Count::get(),
739 "Total TLB (read and write) misses", readMisses + writeMisses),
740 ADD_STAT(accesses, statistics::units::Count::get(),
741 "Total TLB (read and write) accesses",
742 readAccesses + writeAccesses)
743{
744}
745
746Port *
748{
749 return &walker->getPort("port");
750}
751
752} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
TLB(const Params &p)
Definition tlb.cc:101
void translateTiming(const RequestPtr &req, ThreadContext *tc, BaseMMU::Translation *translation, BaseMMU::Mode mode) override
Definition tlb.hh:259
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode)=0
virtual void markDelayed()=0
Signal that the translation has been delayed due to a hw page table walk.
Ports are used to interface objects to each other.
Definition port.hh:62
uint8_t ArchFlagsType
Definition request.hh:101
@ PHYSICAL
The virtual address is also the physical address.
Definition request.hh:117
bool bypassTLB() const
Definition tlb.hh:72
void remove(size_t idx)
Definition tlb.cc:239
TLB(const Params &p)
Fault checkPermissions(ThreadContext *tc, MemAccessInfo mem_access, Addr vaddr, BaseMMU::Mode mode, PTESv39 pte, Addr gvaddr=0x0, XlateStage stage=XlateStage::FIRST_STAGE)
Definition tlb.cc:252
Walker * walker
Definition tlb.hh:97
BasePMAChecker * pma
Definition tlb.hh:116
Addr hiddenTranslateWithTLB(Addr vaddr, uint16_t asid, Addr xmode, BaseMMU::Mode mode)
Definition tlb.cc:331
gem5::RiscvISA::TLB::TlbStats stats
TlbEntry * insert(Addr vpn, const TlbEntry &entry)
Insert an entry into the TLB.
Definition tlb.cc:153
EntryList freeList
Definition tlb.hh:94
uint64_t nextSeq()
Definition tlb.hh:207
std::vector< TlbEntry > tlb
Definition tlb.hh:92
Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode) override
MemAccessInfo getMemAccessInfo(ThreadContext *tc, BaseMMU::Mode mode, const Request::ArchFlagsType arch_flags)
Definition tlb.cc:463
TlbEntryTrie trie
Definition tlb.hh:93
TlbEntry * lookup(Addr vpn, uint16_t asid, BaseMMU::Mode mode, bool hidden)
Perform the tlb lookup.
Definition tlb.cc:116
Addr getValidAddr(Addr vaddr, ThreadContext *tc, BaseMMU::Mode mode)
Definition tlb.hh:180
Fault doTranslate(const RequestPtr &req, ThreadContext *tc, BaseMMU::Translation *translation, BaseMMU::Mode mode, bool &delayed)
Definition tlb.cc:340
Fault translate(const RequestPtr &req, ThreadContext *tc, BaseMMU::Translation *translation, BaseMMU::Mode mode, bool &delayed)
Definition tlb.cc:503
Fault createPagefault(Addr vaddr, BaseMMU::Mode mode, Addr gvaddr=0x0, bool gpf=false, bool virt=false)
Definition tlb.cc:309
void demapPage(Addr vaddr, uint64_t asn) override
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
virtual Process * getProcessPtr()=0
Walker * walker
Definition tlb.hh:89
uint32_t size
Definition tlb.hh:101
uint64_t lruSeq
Definition tlb.hh:108
void evictLRU()
Definition tlb.cc:101
Walker * getWalker()
Definition tlb.cc:95
Port * getTableWalkerPort() override
Get the table walker port.
Definition tlb.cc:630
std::vector< TlbEntry > tlb
Definition tlb.hh:103
Statistics container.
Definition group.hh:93
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Definition group.hh:75
static const unsigned MaxBits
Definition trie.hh:127
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:79
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:232
Declaration of IniFile object.
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
Bitfield< 4, 0 > mode
Definition misc_types.hh:74
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 9 > e
Definition misc_types.hh:65
Bitfield< 5, 0 > status
Bitfield< 59, 56 > tlb
Bitfield< 0 > p
Bitfield< 0 > p
Bitfield< 18 > sum
Definition misc.hh:1346
Addr getVPNFromVAddr(Addr vaddr, Addr mode)
Definition pagetable.cc:64
const Addr PageShift
Definition page_size.hh:53
Bitfield< 59, 44 > asid
Definition pagetable.hh:47
@ FIRST_STAGE
Definition tlb.hh:80
Bitfield< 3 > x
Definition pagetable.hh:78
bool virtualizationEnabled(ExecContext *xc)
Definition isa.cc:1331
@ MISCREG_HSTATUS
Definition misc.hh:213
@ MISCREG_STATUS
Definition misc.hh:78
@ MISCREG_VSSTATUS
Definition misc.hh:227
Bitfield< 19 > mxr
Definition misc.hh:1345
Bitfield< 2 > priv
Definition misc.hh:131
Bitfield< 4 > x
Definition pagetable.hh:61
Bitfield< 2 > pf
Definition misc.hh:565
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
static Addr buildKey(Addr vpn, uint16_t asid)
Definition tlb.cc:69
std::shared_ptr< Request > RequestPtr
Definition request.hh:94
uint64_t RegVal
Definition types.hh:173
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition root.cc:220
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
constexpr decltype(nullptr) NoFault
Definition types.hh:253
Declarations of a non-full system Page Table.
PMP header file.
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568
TlbEntryTrie::Handle trieHandle
Definition pagetable.hh:110
TlbStats(statistics::Group *parent)
Definition tlb.cc:728

Generated on Sat Oct 18 2025 08:06:40 for gem5 by doxygen 1.14.0