Go to the documentation of this file.
47 #include "debug/Checkpoint.hh"
48 #include "debug/Drain.hh"
49 #include "debug/TLB.hh"
50 #include "debug/TLBVerbose.hh"
58 stage2Mmu(NULL), port(NULL), requestorId(
Request::invldRequestorId),
59 isStage2(
p.is_stage2),
tlb(NULL),
60 currState(NULL), pending(false),
61 numSquashable(
p.num_squash_per_cycle),
66 doL2DescEvent([
this]{ doL2DescriptorWrapper(); },
name()),
67 doL0LongDescEvent([
this]{ doL0LongDescriptorWrapper(); },
name()),
68 doL1LongDescEvent([
this]{ doL1LongDescriptorWrapper(); },
name()),
69 doL2LongDescEvent([
this]{ doL2LongDescriptorWrapper(); },
name()),
70 doL3LongDescEvent([
this]{ doL3LongDescriptorWrapper(); },
name()),
71 LongDescEventByLevel { &doL0LongDescEvent, &doL1LongDescEvent,
72 &doL2LongDescEvent, &doL3LongDescEvent },
73 doProcessEvent([
this]{ processWalkWrapper(); },
name())
87 haveSecurity = _haveLPAE = _haveVirtualization =
false;
88 _haveLargeAsid64 =
false;
103 port = &
m->getDMAPort();
111 fatal_if(!
port,
"Table walker must have a valid port\n");
112 fatal_if(!
tlb,
"Table walker must have a valid TLB\n");
118 if (if_name ==
"port") {
122 fatal(
"Cannot access table walker port through stage-two walker\n");
129 tc(nullptr),
aarch64(false),
el(
EL0), physAddrRange(0), req(nullptr),
130 asid(0), vmid(0), isHyp(false), transState(nullptr),
131 vaddr(0), vaddr_tainted(0),
132 sctlr(0), scr(0), cpsr(0), tcr(0),
133 htcr(0), hcr(0), vtcr(0),
134 isWrite(false), isFetch(false),
isSecure(false),
135 isUncacheable(false),
136 secureLookup(false), rwTable(false), userTable(false), xnTable(false),
137 pxnTable(false),
hpd(false), stage2Req(false),
138 stage2Tran(nullptr), timing(false), functional(false),
140 delayed(false), tableWalker(nullptr)
152 DPRINTF(Drain,
"TableWalker done draining, processing drain event\n");
160 bool state_queues_not_empty =
false;
164 state_queues_not_empty =
true;
170 DPRINTF(Drain,
"TableWalker not drained\n");
173 DPRINTF(Drain,
"TableWalker free, no need to drain\n");
190 uint8_t _vmid,
bool _isHyp,
TLB::Mode _mode,
195 assert(!(_functional && _timing));
204 DPRINTF(TLBVerbose,
"creating new instance of WalkerState\n");
208 }
else if (_functional) {
212 DPRINTF(TLBVerbose,
"creating functional instance of WalkerState\n");
216 }
else if (_timing) {
225 return std::make_shared<ReExec>();
304 panic(
"Invalid exception level");
328 if (long_desc_format) {
345 else if (long_desc_format)
368 else if (long_desc_format)
413 curr_state_copy->
tc, curr_state_copy->
mode);
415 delete curr_state_copy;
423 unsigned num_squashed = 0;
431 DPRINTF(
TLB,
"Squashing table walk for address %#x\n",
437 std::make_shared<UnimpFault>(
"Squashed Inst"),
478 const auto irgn0_mask = 0x1;
479 const auto irgn1_mask = 0x40;
486 DPRINTF(
TLB,
"Beginning table walk for address %#x, TTBCR: %#x, bits:%#x\n",
498 return std::make_shared<PrefetchAbort>(
504 return std::make_shared<DataAbort>(
518 return std::make_shared<PrefetchAbort>(
524 return std::make_shared<DataAbort>(
537 DPRINTF(
TLB,
" - Descriptor at address %#x (%s)\n", l1desc_addr,
542 f =
testWalk(l1desc_addr,
sizeof(uint32_t),
580 Addr ttbr, ttbr0_max, ttbr1_min, desc_addr;
584 DPRINTF(
TLB,
"Beginning table walk for address %#x, TTBCR: %#x\n",
596 DPRINTF(
TLB,
" - Selecting VTTBR (long-desc.)\n");
602 DPRINTF(
TLB,
" - Selecting HTTBR (long-desc.)\n");
613 ttbr0_max = (1
ULL << 32) -
616 ttbr0_max = (1
ULL << 32) - 1;
629 DPRINTF(
TLB,
" - Selecting TTBR0 (long-desc.)\n");
633 return std::make_shared<PrefetchAbort>(
639 return std::make_shared<DataAbort>(
651 if (ttbr0_max < (1
ULL << 30))
652 start_lookup_level =
L2;
654 DPRINTF(
TLB,
" - Selecting TTBR1 (long-desc.)\n");
658 return std::make_shared<PrefetchAbort>(
664 return std::make_shared<DataAbort>(
677 if (ttbr1_min >= (1
ULL << 31) + (1
ULL << 30))
678 start_lookup_level =
L2;
682 return std::make_shared<PrefetchAbort>(
688 return std::make_shared<DataAbort>(
699 if (start_lookup_level ==
L1) {
701 desc_addr =
mbits(ttbr, 39,
n) |
703 DPRINTF(
TLB,
" - Descriptor at address %#x (%s) (long-desc.)\n",
707 n = (tsz >= 2 ? 14 - tsz : 12);
708 desc_addr =
mbits(ttbr, 39,
n) |
710 DPRINTF(
TLB,
" - Descriptor at address %#x (%s) (long-desc.)\n",
739 sizeof(uint64_t), flag, start_lookup_level,
759 int in_min = 64 - (tg ==
Grain64KB ? 47 : 48);
761 return tsz > in_max || tsz < in_min || (low_range ?
778 DPRINTF(
TLB,
"Beginning table walk for address %#llx, TCR: %#llx\n",
801 bool vaddr_fault =
false;
818 DPRINTF(
TLB,
" - Selecting TTBR0 (AArch64)\n");
825 top_bit, tg, tsz,
true);
831 DPRINTF(
TLB,
" - Selecting TTBR1 (AArch64)\n");
838 top_bit, tg, tsz,
false);
853 DPRINTF(
TLB,
" - Selecting VSTTBR_EL2 (AArch64 stage 2)\n");
856 DPRINTF(
TLB,
" - Selecting VTTBR_EL2 (AArch64 stage 2)\n");
872 start_lookup_level = SLL[sl_tg];
874 "Cannot discern lookup level from vtcr.{sl0,tg0}");
880 DPRINTF(
TLB,
" - Selecting TTBR0_EL1 (AArch64)\n");
887 top_bit, tg, tsz,
true);
893 DPRINTF(
TLB,
" - Selecting TTBR1_EL1 (AArch64)\n");
900 top_bit, tg, tsz,
false);
915 DPRINTF(
TLB,
" - Selecting TTBR0_EL2 (AArch64)\n");
923 top_bit, tg, tsz,
true);
930 DPRINTF(
TLB,
" - Selecting TTBR1_EL2 (AArch64)\n");
937 top_bit, tg, tsz,
false);
952 DPRINTF(
TLB,
" - Selecting TTBR0_EL3 (AArch64)\n");
959 top_bit, tg, tsz,
true);
977 f = std::make_shared<PrefetchAbort>(
982 f = std::make_shared<DataAbort>(
1002 warn_once(
"Reserved granule size requested; gem5's IMPLEMENTATION "
1003 "DEFINED behavior takes this to mean 4KB granules\n");
1018 static const GrainMap GM[] = {
1024 const unsigned *lookup = NULL;
1026 for (
unsigned i = 0;
i < 3; ++
i) {
1027 if (tg == GM[
i].grain_size) {
1028 lookup = GM[
i].lookup_level_cutoff;
1035 if (tsz > lookup[
L]) {
1041 "Table walker couldn't find lookup level\n");
1054 int base_addr_lo = 3 + tsz -
stride * (3 - start_lookup_level) - tg;
1057 if (pa_range == 52) {
1058 int z = (base_addr_lo < 6) ? 6 : base_addr_lo;
1059 base_addr =
mbits(ttbr, 47,
z);
1060 base_addr |= (
bits(ttbr, 5, 2) << 48);
1062 base_addr =
mbits(ttbr, 47, base_addr_lo);
1068 DPRINTF(
TLB,
"Address size fault before any lookup\n");
1071 f = std::make_shared<PrefetchAbort>(
1077 f = std::make_shared<DataAbort>(
1099 Addr desc_addr = base_addr |
1101 stride * (3 - start_lookup_level) + tg) << 3);
1135 sizeof(uint64_t), flag, start_lookup_level,
1139 sizeof(uint64_t), flag, -1, NULL,
1149 uint8_t texcb,
bool s)
1153 DPRINTF(TLBVerbose,
"memAttrs texcb:%d s:%d\n", texcb,
s);
1154 te.shareable =
false;
1155 te.nonCacheable =
false;
1156 te.outerShareable =
false;
1160 te.nonCacheable =
true;
1162 te.shareable =
true;
1167 te.nonCacheable =
true;
1169 te.shareable =
true;
1177 te.outerAttrs =
bits(texcb, 1, 0);
1183 te.outerAttrs =
bits(texcb, 1, 0);
1186 te.nonCacheable =
true;
1190 te.outerAttrs =
bits(texcb, 1, 0);
1193 panic(
"Reserved texcb value!\n");
1196 panic(
"Implementation-defined texcb value!\n");
1205 te.nonCacheable =
true;
1207 te.shareable =
false;
1212 panic(
"Reserved texcb value!\n");
1217 if (
bits(texcb, 1,0) == 0 ||
bits(texcb, 3,2) == 0)
1218 te.nonCacheable =
true;
1219 te.innerAttrs =
bits(texcb, 1, 0);
1220 te.outerAttrs =
bits(texcb, 3, 2);
1223 panic(
"More than 32 states for 5 bits?\n");
1231 DPRINTF(TLBVerbose,
"memAttrs PRRR:%08x NMRR:%08x\n", prrr, nmrr);
1232 uint8_t curr_tr = 0, curr_ir = 0, curr_or = 0;
1233 switch(
bits(texcb, 2,0)) {
1238 te.outerShareable = (prrr.nos0 == 0);
1244 te.outerShareable = (prrr.nos1 == 0);
1250 te.outerShareable = (prrr.nos2 == 0);
1256 te.outerShareable = (prrr.nos3 == 0);
1262 te.outerShareable = (prrr.nos4 == 0);
1268 te.outerShareable = (prrr.nos5 == 0);
1271 panic(
"Imp defined type\n");
1276 te.outerShareable = (prrr.nos7 == 0);
1282 DPRINTF(TLBVerbose,
"StronglyOrdered\n");
1284 te.nonCacheable =
true;
1287 te.shareable =
true;
1290 DPRINTF(TLBVerbose,
"Device ds1:%d ds0:%d s:%d\n",
1291 prrr.ds1, prrr.ds0,
s);
1293 te.nonCacheable =
true;
1297 te.shareable =
true;
1299 te.shareable =
true;
1302 DPRINTF(TLBVerbose,
"Normal ns1:%d ns0:%d s:%d\n",
1303 prrr.ns1, prrr.ns0,
s);
1306 te.shareable =
true;
1308 te.shareable =
true;
1311 panic(
"Reserved type");
1317 te.nonCacheable =
true;
1333 te.nonCacheable =
true;
1348 DPRINTF(TLBVerbose,
"memAttrs: shareable: %d, innerAttrs: %d, "
1350 te.shareable,
te.innerAttrs,
te.outerAttrs);
1351 te.setAttributes(
false);
1361 uint8_t
sh = lDescriptor.
sh();
1366 uint8_t attr_3_2 = (
attr >> 2) & 0x3;
1367 uint8_t attr_1_0 =
attr & 0x3;
1369 DPRINTF(TLBVerbose,
"memAttrsLPAE MemAttr:%#x sh:%#x\n",
attr,
sh);
1371 if (attr_3_2 == 0) {
1375 te.innerAttrs = attr_1_0 == 0 ? 1 : 3;
1376 te.nonCacheable =
true;
1379 te.outerAttrs = attr_3_2 == 1 ? 0 :
1380 attr_3_2 == 2 ? 2 : 1;
1381 te.innerAttrs = attr_1_0 == 1 ? 0 :
1382 attr_1_0 == 2 ? 6 : 5;
1383 te.nonCacheable = (attr_3_2 == 1) || (attr_1_0 == 1);
1386 uint8_t attrIndx = lDescriptor.
attrIndx();
1394 attr = (mair >> (8 * (attrIndx % 4))) & 0xff;
1395 uint8_t attr_7_4 =
bits(
attr, 7, 4);
1396 uint8_t attr_3_0 =
bits(
attr, 3, 0);
1397 DPRINTF(TLBVerbose,
"memAttrsLPAE AttrIndx:%#x sh:%#x, attr %#x\n", attrIndx,
sh,
attr);
1402 te.nonCacheable =
false;
1407 if (attr_3_0 == 0x0)
1409 else if (attr_3_0 == 0x4)
1412 panic(
"Unpredictable behavior\n");
1413 te.nonCacheable =
true;
1420 if (attr_3_0 == 0x4)
1422 te.nonCacheable =
true;
1423 else if (attr_3_0 < 0x8)
1424 panic(
"Unpredictable behavior\n");
1434 if (attr_7_4 & 0x4) {
1435 te.outerAttrs = (attr_7_4 & 1) ? 1 : 3;
1437 te.outerAttrs = 0x2;
1441 if (attr_3_0 != 0x4 && attr_3_0 < 0x8)
1442 panic(
"Unpredictable behavior\n");
1445 panic(
"Unpredictable behavior\n");
1451 te.innerAttrs = 0x1;
1454 te.innerAttrs = attr_7_4 == 0 ? 0x3 : 0;
1466 te.innerAttrs = attr_3_0 & 1 ? 0x5 : 0x7;
1469 panic(
"Unpredictable behavior\n");
1474 te.outerShareable =
sh == 2;
1475 te.shareable = (
sh & 0x2) ?
true :
false;
1476 te.setAttributes(
true);
1477 te.attributes |= (uint64_t)
attr << 56;
1487 uint8_t
sh = lDescriptor.
sh();
1491 uint8_t attr_hi = (
attr >> 2) & 0x3;
1492 uint8_t attr_lo =
attr & 0x3;
1494 DPRINTF(TLBVerbose,
"memAttrsAArch64 MemAttr:%#x sh:%#x\n",
attr,
sh);
1500 te.innerAttrs = attr_lo == 0 ? 1 : 3;
1501 te.nonCacheable =
true;
1504 te.outerAttrs = attr_hi == 1 ? 0 :
1505 attr_hi == 2 ? 2 : 1;
1506 te.innerAttrs = attr_lo == 1 ? 0 :
1507 attr_lo == 2 ? 6 : 5;
1510 te.nonCacheable = (attr_hi == 1) || (attr_hi == 2) ||
1511 (attr_lo == 1) || (attr_lo == 2);
1514 uint8_t attrIndx = lDescriptor.
attrIndx();
1516 DPRINTF(TLBVerbose,
"memAttrsAArch64 AttrIndx:%#x sh:%#x\n", attrIndx,
sh);
1533 panic(
"Invalid exception level");
1538 attr =
bits(mair, 8 * attrIndx + 7, 8 * attrIndx);
1546 te.nonCacheable =
false;
1548 te.nonCacheable =
true;
1556 te.nonCacheable =
true;
1561 warn_if(!attr_hi,
"Unpredictable behavior");
1567 te.nonCacheable =
true;
1570 te.shareable =
sh == 2;
1571 te.outerShareable = (
sh & 0x2) ?
true :
false;
1573 te.attributes = ((uint64_t)
attr << 56) |
1590 DPRINTF(
TLB,
"L1 descriptor for %#x is %#x\n",
1603 DPRINTF(
TLB,
"L1 Descriptor Reserved/Ignore, causing fault\n");
1606 std::make_shared<PrefetchAbort>(
1613 std::make_shared<DataAbort>(
1636 panic(
"Haven't implemented supersections\n");
1645 DPRINTF(
TLB,
"L1 descriptor points to page table at: %#x (%s)\n",
1681 panic(
"A new type in a 2 bit field?\n");
1689 return std::make_shared<PrefetchAbort>(
1695 return std::make_shared<DataAbort>(
1715 DPRINTF(
TLB,
"L%d descriptor for %#llx is %#llx (%s)\n",
1722 DPRINTF(TLBVerbose,
"Analyzing L%d descriptor: %#llx, pxn: %d, "
1723 "xn: %d, ap: %d, af: %d, type: %d\n",
1732 DPRINTF(TLBVerbose,
"Analyzing L%d descriptor: %#llx, type: %d\n",
1742 DPRINTF(
TLB,
"L%d descriptor Invalid, causing fault type %d\n",
1761 DPRINTF(
TLB,
"L%d descriptor causing Address Size Fault\n",
1768 DPRINTF(
TLB,
"L%d descriptor causing Access Fault\n",
1798 DPRINTF(
TLB,
"L%d descriptor points to L%d descriptor at: %#x (%s)\n",
1807 DPRINTF(
TLB,
"L%d descriptor causing Address Size Fault\n",
1838 Event *
event = NULL;
1847 panic(
"Wrong lookup level in table walk\n");
1853 sizeof(uint64_t), flag, -1,
event,
1861 panic(
"A new type in a 2 bit field?\n");
1875 DPRINTF(
TLB,
"L2 descriptor for %#x is %#x\n",
1882 DPRINTF(
TLB,
"L2 descriptor invalid, causing fault\n");
1907 DPRINTF(
TLB,
"Generating access fault at L2, afe: %d, ap: %d\n",
1958 DPRINTF(TLBVerbose,
"calling translateTiming again\n");
1988 DPRINTF(TLBVerbose,
"calling doL2Descriptor for vaddr:%#x\n",
1999 DPRINTF(TLBVerbose,
"calling translateTiming again\n");
2055 DPRINTF(TLBVerbose,
"calling doLongDescriptor for vaddr:%#x\n",
2075 DPRINTF(TLBVerbose,
"calling translateTiming again\n");
2090 panic(
"Max. number of lookups already reached in table walk\n");
2114 DPRINTF(TLBVerbose,
"Fetching descriptor at address: 0x%x stage2Req: %d\n",
2130 fault = tran->
fault;
2141 if (queueIndex >= 0) {
2142 DPRINTF(TLBVerbose,
"Adding to walker fifo: queue size before adding: %d\n",
2148 (this->*doDescriptor)();
2154 if (queueIndex >= 0) {
2155 DPRINTF(TLBVerbose,
"Adding to walker fifo: queue size before adding: %d\n",
2163 (this->*doDescriptor)();
2172 (this->*doDescriptor)();
2186 te.longDescFormat = longDescriptor;
2192 te.size = (1<<
te.N) - 1;
2193 te.pfn = descriptor.
pfn();
2198 te.xn = descriptor.
xn();
2210 if (longDescriptor) {
2219 te.hap = lDescriptor.
ap();
2229 te.ap = descriptor.
ap();
2236 DPRINTF(
TLB,
" - N:%d pfn:%#x size:%#x global:%d valid:%d\n",
2238 DPRINTF(
TLB,
" - vpn:%#x xn:%d pxn:%d ap:%d domain:%d asid:%d "
2239 "vmid:%d hyp:%d nc:%d ns:%d\n",
te.vpn,
te.xn,
te.pxn,
2240 te.ap,
static_cast<uint8_t
>(
te.domain),
te.asid,
te.vmid,
te.isHyp,
2241 te.nonCacheable,
te.ns);
2242 DPRINTF(
TLB,
" - domain from L%d desc:%d data:%#x\n",
2257 switch (lookup_level_as_int) {
2265 panic(
"Invalid lookup level conversion");
2312 panic(
"unknown page size");
2319 :
Stats::Group(parent),
2322 "Table walker walks initiated with short descriptors"),
2324 "Table walker walks initiated with long descriptors"),
2326 "Level at which table walker walks with short descriptors "
2329 "Level at which table walker walks with long descriptors "
2332 "Table walks squashed before starting"),
2334 "Table walks squashed after completion"),
2336 "Table walker wait (enqueue to first request) latency"),
2338 "Table walker service (enqueue to completion) latency"),
2340 "Table walker pending requests distribution"),
2342 "Table walker page sizes translated"),
2344 "Table walker requests started/completed, data/inst")
Addr l2Addr() const
Address of L2 descriptor if it exists.
Stats::Histogram walkWaitTime
#define fatal(...)
This implements a cprintf based fatal() function.
bool stage2Req
Flag indicating if a second stage of lookup is required.
BaseTLB::Mode mode
Save mode for use in delayed response.
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, Mode mode)=0
bool checkAddrSizeFaultAArch64(Addr addr, int pa_range)
Returns true if the address exceeds the range permitted by the system-wide setting or by the TCR_ELx ...
virtual bool squashed() const
This function is used by the page table walker to determine if it should translate the a pending requ...
bool af() const
Returns true if the access flag (AF) is set.
ExceptionLevel el
Current exception level.
GrainSize grainSize
Width of the granule size in bits.
Fault walk(const RequestPtr &req, ThreadContext *tc, uint16_t asid, uint8_t _vmid, bool _isHyp, TLB::Mode mode, TLB::Translation *_trans, bool timing, bool functional, bool secure, TLB::ArmTranslationType tranType, bool _stage2Req)
void drainResume() override
Resume execution after a successful drain.
bool functional
If the atomic mode should be functional.
Stats::Scalar walksShortDescriptor
int computeAddrTop(ThreadContext *tc, bool selbit, bool isInstr, TCR tcr, ExceptionLevel el)
void memAttrsAArch64(ThreadContext *tc, TlbEntry &te, LongDescriptor &lDescriptor)
virtual bool secure(bool have_security, WalkerState *currState) const =0
bool supersection() const
Is the page a Supersection (16 MiB)?
@ SECURE
The request targets the secure memory space.
TLB::ArmTranslationType tranType
The translation type that has been requested.
uint16_t asid
ASID that we're servicing the request under.
TableWalkerStats(Stats::Group *parent)
bool HaveVirtHostExt(ThreadContext *tc)
virtual bool global(WalkerState *currState) const =0
bool HaveLVA(ThreadContext *tc)
uint8_t rwTable() const
R/W protection flag for subsequent levels of lookup.
void doL0LongDescriptorWrapper()
virtual bool shareable() const
Fault testWalk(Addr pa, Addr size, TlbEntry::DomainType domain, LookupLevel lookup_level)
TlbEntry * lookup(Addr vpn, uint16_t asn, uint8_t vmid, bool hyp, bool secure, bool functional, bool ignore_asn, ExceptionLevel target_el, bool in_host)
Lookup an entry in the TLB.
uint8_t physAddrRange() const
Returns the supported physical address range in bits.
ByteOrder byteOrder(const ThreadContext *tc)
RequestPtr req
Request that is currently being serviced.
SCTLR sctlr
Cached copy of the sctlr as it existed when translation began.
LookupLevel lookupLevel
Current lookup level for this descriptor.
Stage2MMU * stage2Mmu
The MMU to forward second stage look upts to.
virtual std::string dbgHeader() const =0
int snsBankedIndex(MiscRegIndex reg, ThreadContext *tc)
const bool isStage2
Indicates whether this table walker is part of the stage 2 mmu.
Addr nextDescAddr(Addr va) const
Return the address of the next descriptor.
void doLongDescriptorWrapper(LookupLevel curr_lookup_level)
unsigned numSquashable
The number of walks belonging to squashed instructions that can be removed from the pendingQueue per ...
int physAddrRange
Current physical address range in bits.
ThreadContext * tc
Thread context that we're doing the walk for.
virtual bool xn() const =0
TableWalker(const Params &p)
Derived & ysubname(off_type index, const std::string &subname)
uint64_t Tick
Tick count type.
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
EventFunctionWrapper doProcessEvent
std::shared_ptr< Request > RequestPtr
Tick startTime
Timestamp for calculating elapsed time in service (for stats)
int decodePhysAddrRange64(uint8_t pa_enc)
Returns the n.
HCR hcr
Cached copy of the htcr as it existed when translation began.
void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr, uint8_t texcb, bool s)
static uint8_t pageSizeNtoStatBin(uint8_t N)
Stats::Scalar walksLongDescriptor
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
bool pxnTable() const
Is privileged execution allowed on subsequent lookup levels?
void doL2DescriptorWrapper()
void sendFunctional(PacketPtr pkt) const
Send a functional request packet, where the data is instantly updated everywhere in the memory system...
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
TlbEntry::DomainType domain() const
Domain Client/Manager: ARM DDI 0406B: B3-31.
This translation class is used to trigger the data fetch once a timing translation returns the transl...
EntryType type() const
Return the descriptor type.
static const unsigned REQUESTED
FaultSource
Generic fault source enums used to index into {short/long/aarch64}DescFaultSources[] to get the actua...
uint8_t ap() const
Three bit access protection flags.
virtual uint8_t offsetBits() const =0
uint8_t userTable() const
User/privileged mode protection flag for subsequent levels of lookup.
TableWalker * tableWalker
bool isWrite
If the access is a write.
uint8_t ap() const
2-bit access protection flags
bool haveVirtualization() const
Returns true if this system implements the virtualization Extensions.
bool isSecure
If the access comes from the secure state.
void nextWalk(ThreadContext *tc)
bool invalid() const
Is the entry invalid.
L1Descriptor l1Desc
Short-format descriptors.
uint32_t data
The raw bits of the entry.
@ PT_WALK
The request is a page table walk.
bool timing
If the mode is timing or atomic.
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
LongDescriptor longDesc
Long-format descriptor (LPAE and AArch64)
bool secureLookup
Helper variables used to implement hierarchical access permissions when the long-desc.
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
@ Drained
Buffers drained, ready for serialization/handover.
virtual Addr pfn() const =0
static LookupLevel toLookupLevel(uint8_t lookup_level_as_int)
TLB::Translation * stage2Tran
A pointer to the stage 2 translation that's in progress.
Fault processWalkAArch64()
DrainState
Object drain/handover states.
RequestorID requestorId
Requestor id assigned by the MMU.
void doL3LongDescriptorWrapper()
uint8_t ap() const
Three bit access protection flags.
uint64_t data
The raw bits of the entry.
void schedule(Event &event, Tick when)
bool aarch64
If the access is performed in AArch64 state.
uint8_t attrIndx() const
Attribute index.
bool haveSecurity() const
Returns true if this system implements the Security Extensions.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
ClockedObjectParams Params
Parameters of ClockedObject.
bool fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes, Request::Flags flags, int queueIndex, Event *event, void(TableWalker::*doDescriptor)())
bool haveLPAE() const
Returns true if this system implements the Large Physical Address Extension.
virtual uint64_t getRawData() const =0
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
std::shared_ptr< FaultBase > Fault
ArmISA::TableWalker::TableWalkerStats stats
T htog(T value, ByteOrder guest_byte_order)
bool haveSecurity
Cached copies of system-level properties.
std::list< WalkerState * > stateQueues[MAX_LOOKUP_LEVELS]
Queues of requests for all the different lookup levels.
Ports are used to interface objects to each other.
bool secureTable() const
Whether the subsequent levels of lookup are secure.
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...
uint8_t memAttr() const
Memory attributes, only used by stage 2 translations.
void set(Type mask)
Set all flag's bits matching the given mask.
void signalDrainDone() const
Signal that an object is drained.
static ExceptionLevel tranTypeEL(CPSR cpsr, ArmTranslationType type)
Determine the EL to use for the purpose of a translation given a specific translation type.
VTCR_t vtcr
Cached copy of the vtcr as it existed when translation began.
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
void doL2LongDescriptorWrapper()
bool aarch64
True if the current lookup is performed in AArch64 state.
bool delayed
Whether the response is delayed in timing mode due to additional lookups.
ExceptionLevel s1TranslationRegime(ThreadContext *tc, ExceptionLevel el)
bool longDescFormatInUse(ThreadContext *tc)
DmaPort * port
Port shared by the two table walkers.
uint32_t data
The raw bits of the entry.
constexpr decltype(nullptr) NoFault
virtual uint8_t ap() const =0
Fault testWalk(Addr pa, Addr size, Addr va, bool is_secure, Mode mode, TlbEntry::DomainType domain, LookupLevel lookup_level)
ProbePointArg< PacketInfo > Packet
Packet probe point.
Event * LongDescEventByLevel[4]
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Stats::Histogram walkServiceTime
Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, TCR tcr, bool isInstr)
Removes the tag from tagged addresses if that mode is enabled.
Stats::Vector walksLongTerminatedAtLevel
const FlagsType dist
Print the distribution.
const std::string & name()
Derived & init(size_type size)
Set this vector to have the given size.
bool isFetch
If the access is a fetch (for execution, and no-exec) must be checked?
Stats::Vector walksShortTerminatedAtLevel
Fault generateLongDescFault(ArmFault::FaultSource src)
void memAttrsLPAE(ThreadContext *tc, TlbEntry &te, LongDescriptor &lDescriptor)
HTCR htcr
Cached copy of the htcr as it existed when translation began.
const FlagsType nozero
Don't print if this is zero.
DrainState drainState() const
Return the current drain state of an object.
void completeDrain()
Checks if all state is cleared and if so, completes drain.
void dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
bool hpd
Hierarchical access permission disable.
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
Addr vaddr_tainted
The virtual address that is being translated.
Addr vaddr
The virtual address that is being translated with tagging removed.
void setMMU(Stage2MMU *m, RequestorID requestor_id)
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
void doL1DescriptorWrapper()
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
TLB * tlb
TLB that is initiating these table walks.
uint8_t sh() const
2-bit shareability field
Addr paddr() const
Return the physical address of the entry.
Stats::Vector2d requestOrigin
bool isUncacheable
True if table walks are uncacheable (for table descriptors)
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
const FlagsType pdf
Print the percent of the total that this entry represents.
std::list< WalkerState * > pendingQueue
Queue of requests that have passed are waiting because the walker is currently busy.
void readDataTimed(ThreadContext *tc, Addr descAddr, Stage2Translation *translation, int numBytes, Request::Flags flags)
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
@ UNCACHEABLE
The request is to an uncacheable address.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
bool checkVAddrSizeFaultAArch64(Addr addr, int top_bit, GrainSize granule, int tsz, bool low_range)
virtual TlbEntry::DomainType domain() const =0
bool xn() const
Is execution allowed on this mapping?
Fault readDataUntimed(ThreadContext *tc, Addr oVAddr, Addr descAddr, uint8_t *data, int numBytes, Request::Flags flags, bool isFunctional)
Derived & init(size_type _x, size_type _y)
Bitfield< 21, 20 > stride
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Cycles is a wrapper class for representing cycle counts, i.e.
SCTLR sctlr
Cached copy of the sctlr as it existed when translation began.
Derived & subname(off_type index, const std::string &name)
Set the subfield name for the given index, and marks this stat to print at the end of simulation.
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
static const unsigned COMPLETED
void doL1LongDescriptorWrapper()
bool xnTable() const
Is execution allowed on subsequent lookup levels?
EventFunctionWrapper doL1DescEvent
Tick curTick()
The universal simulation clock.
bool pxn() const
Is privileged execution allowed on this mapping? (LPAE only)
EventFunctionWrapper doL2DescEvent
Histogram & init(size_type size)
Set the parameters of this histogram.
const Params & params() const
void processWalkWrapper()
Long-descriptor format (LPAE)
TLB::Translation * transState
Translation state for delayed requests.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
const FlagsType total
Print the total.
Fault fault
The fault that we are going to return.
Stats::Scalar squashedAfter
virtual BaseCPU * getCpuPtr()=0
Stats::Scalar squashedBefore
virtual uint8_t texcb() const
void translateTiming(const RequestPtr &req, ThreadContext *tc, Translation *translation, Mode mode, ArmTranslationType tranType)
#define ULL(N)
uint64_t constant
const FlagsType nonan
Don't print if this is NAN.
void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor)
Stats::Histogram pendingWalks
@ Draining
Draining buffers pending serialization/handover.
bool isSecure(ThreadContext *tc)
bool pending
If a timing translation is currently in progress.
bool haveLargeAsid64() const
Returns true if ASID is 16 bits in AArch64 (ARMv8)
#define panic(...)
This implements a cprintf based panic() function.
void insert(Addr vaddr, TlbEntry &pte)
Generated on Tue Jun 22 2021 15:28:21 for gem5 by doxygen 1.8.17