Go to the documentation of this file.
49 #include "debug/Checkpoint.hh"
50 #include "debug/Drain.hh"
51 #include "debug/PageTableWalker.hh"
52 #include "debug/TLB.hh"
53 #include "debug/TLBVerbose.hh"
59 using namespace ArmISA;
63 requestorId(
p.sys->getRequestorId(this)),
65 isStage2(
p.is_stage2),
tlb(NULL),
66 currState(NULL), pending(false),
67 numSquashable(
p.num_squash_per_cycle),
72 doL2DescEvent([
this]{ doL2DescriptorWrapper(); },
name()),
73 doL0LongDescEvent([
this]{ doL0LongDescriptorWrapper(); },
name()),
74 doL1LongDescEvent([
this]{ doL1LongDescriptorWrapper(); },
name()),
75 doL2LongDescEvent([
this]{ doL2LongDescriptorWrapper(); },
name()),
76 doL3LongDescEvent([
this]{ doL3LongDescriptorWrapper(); },
name()),
77 LongDescEventByLevel { &doL0LongDescEvent, &doL1LongDescEvent,
78 &doL2LongDescEvent, &doL3LongDescEvent },
79 doProcessEvent([
this]{ processWalkWrapper(); },
name())
85 ArmSystem *armSys =
dynamic_cast<ArmSystem *
>(
p.sys);
87 haveSecurity = armSys->haveSecurity();
88 _haveLPAE = armSys->haveLPAE();
89 _haveVirtualization = armSys->haveVirtualization();
90 _physAddrRange = armSys->physAddrRange();
91 _haveLargeAsid64 = armSys->haveLargeAsid64();
93 haveSecurity = _haveLPAE = _haveVirtualization =
false;
94 _haveLargeAsid64 =
false;
114 if (if_name ==
"port") {
121 tc(nullptr),
aarch64(false),
el(
EL0), physAddrRange(0), req(nullptr),
122 asid(0), vmid(0), isHyp(false), transState(nullptr),
123 vaddr(0), vaddr_tainted(0),
124 sctlr(0), scr(0), cpsr(0), tcr(0),
125 htcr(0), hcr(0), vtcr(0),
126 isWrite(false), isFetch(false),
isSecure(false),
127 isUncacheable(false),
128 secureLookup(false), rwTable(false), userTable(false), xnTable(false),
129 pxnTable(false),
hpd(false), stage2Req(false),
130 stage2Tran(nullptr), timing(false), functional(false),
132 delayed(false), tableWalker(nullptr)
138 reqQueue, snoopRespQueue),
139 reqQueue(*_walker, *this), snoopRespQueue(*_walker, *this),
146 Addr desc_addr,
int size,
159 state->delay = delay;
167 Addr desc_addr,
int size,
170 auto pkt = createPacket(desc_addr, size,
data, flags, 0,
nullptr);
174 handleRespPacket(pkt);
179 Addr desc_addr,
int size,
182 auto pkt = createPacket(desc_addr, size,
data, flags, delay,
nullptr);
184 Tick lat = sendAtomic(pkt);
186 handleRespPacket(pkt, lat);
191 Addr desc_addr,
int size,
195 auto pkt = createPacket(desc_addr, size,
data, flags, delay,
event);
197 schedTimingReq(pkt,
curTick());
204 assert(pkt->
req->isUncacheable() ||
207 handleRespPacket(pkt);
222 handleResp(state, pkt->
getAddr(), pkt->
req->getSize(), delay);
245 DPRINTF(Drain,
"TableWalker done draining, processing drain event\n");
253 bool state_queues_not_empty =
false;
257 state_queues_not_empty =
true;
263 DPRINTF(Drain,
"TableWalker not drained\n");
266 DPRINTF(Drain,
"TableWalker free, no need to drain\n");
288 assert(!(_functional && _timing));
297 DPRINTF(PageTableWalker,
"creating new instance of WalkerState\n");
301 }
else if (_functional) {
306 "creating functional instance of WalkerState\n");
310 }
else if (_timing) {
319 return std::make_shared<ReExec>();
398 panic(
"Invalid exception level");
422 if (long_desc_format) {
439 else if (long_desc_format)
462 else if (long_desc_format)
507 curr_state_copy->
tc, curr_state_copy->
mode);
509 delete curr_state_copy;
517 unsigned num_squashed = 0;
525 DPRINTF(
TLB,
"Squashing table walk for address %#x\n",
531 std::make_shared<UnimpFault>(
"Squashed Inst"),
572 const auto irgn0_mask = 0x1;
573 const auto irgn1_mask = 0x40;
580 DPRINTF(
TLB,
"Beginning table walk for address %#x, TTBCR: %#x, bits:%#x\n",
592 return std::make_shared<PrefetchAbort>(
598 return std::make_shared<DataAbort>(
612 return std::make_shared<PrefetchAbort>(
618 return std::make_shared<DataAbort>(
631 DPRINTF(
TLB,
" - Descriptor at address %#x (%s)\n", l1desc_addr,
636 f =
testWalk(l1desc_addr,
sizeof(uint32_t),
674 Addr ttbr, ttbr0_max, ttbr1_min, desc_addr;
678 DPRINTF(
TLB,
"Beginning table walk for address %#x, TTBCR: %#x\n",
690 DPRINTF(
TLB,
" - Selecting VTTBR (long-desc.)\n");
696 DPRINTF(
TLB,
" - Selecting HTTBR (long-desc.)\n");
707 ttbr0_max = (1ULL << 32) -
710 ttbr0_max = (1ULL << 32) - 1;
712 ttbr1_min = (1ULL << 32) - (1ULL << (32 -
currState->
ttbcr.t1sz));
723 DPRINTF(
TLB,
" - Selecting TTBR0 (long-desc.)\n");
727 return std::make_shared<PrefetchAbort>(
733 return std::make_shared<DataAbort>(
745 if (ttbr0_max < (1ULL << 30))
746 start_lookup_level =
L2;
748 DPRINTF(
TLB,
" - Selecting TTBR1 (long-desc.)\n");
752 return std::make_shared<PrefetchAbort>(
758 return std::make_shared<DataAbort>(
771 if (ttbr1_min >= (1ULL << 31) + (1ULL << 30))
772 start_lookup_level =
L2;
776 return std::make_shared<PrefetchAbort>(
782 return std::make_shared<DataAbort>(
793 if (start_lookup_level ==
L1) {
795 desc_addr =
mbits(ttbr, 39,
n) |
797 DPRINTF(
TLB,
" - Descriptor at address %#x (%s) (long-desc.)\n",
801 n = (tsz >= 2 ? 14 - tsz : 12);
802 desc_addr =
mbits(ttbr, 39,
n) |
804 DPRINTF(
TLB,
" - Descriptor at address %#x (%s) (long-desc.)\n",
833 sizeof(uint64_t), flag, start_lookup_level,
853 int in_min = 64 - (tg ==
Grain64KB ? 47 : 48);
855 return tsz > in_max || tsz < in_min || (low_range ?
872 DPRINTF(
TLB,
"Beginning table walk for address %#llx, TCR: %#llx\n",
895 bool vaddr_fault =
false;
912 DPRINTF(
TLB,
" - Selecting TTBR0 (AArch64)\n");
919 top_bit, tg, tsz,
true);
925 DPRINTF(
TLB,
" - Selecting TTBR1 (AArch64)\n");
932 top_bit, tg, tsz,
false);
947 DPRINTF(
TLB,
" - Selecting VSTTBR_EL2 (AArch64 stage 2)\n");
950 DPRINTF(
TLB,
" - Selecting VTTBR_EL2 (AArch64 stage 2)\n");
966 start_lookup_level = SLL[sl_tg];
968 "Cannot discern lookup level from vtcr.{sl0,tg0}");
974 DPRINTF(
TLB,
" - Selecting TTBR0_EL1 (AArch64)\n");
981 top_bit, tg, tsz,
true);
987 DPRINTF(
TLB,
" - Selecting TTBR1_EL1 (AArch64)\n");
994 top_bit, tg, tsz,
false);
1009 DPRINTF(
TLB,
" - Selecting TTBR0_EL2 (AArch64)\n");
1017 top_bit, tg, tsz,
true);
1024 DPRINTF(
TLB,
" - Selecting TTBR1_EL2 (AArch64)\n");
1031 top_bit, tg, tsz,
false);
1046 DPRINTF(
TLB,
" - Selecting TTBR0_EL3 (AArch64)\n");
1053 top_bit, tg, tsz,
true);
1071 f = std::make_shared<PrefetchAbort>(
1076 f = std::make_shared<DataAbort>(
1096 warn_once(
"Reserved granule size requested; gem5's IMPLEMENTATION "
1097 "DEFINED behavior takes this to mean 4KB granules\n");
1113 static const GrainMap GM[] = {
1119 const unsigned *lookup = NULL;
1121 for (
unsigned i = 0;
i < 3; ++
i) {
1122 if (tg == GM[
i].grain_size) {
1123 lookup = GM[
i].lookup_level_cutoff;
1130 if (tsz > lookup[
L]) {
1136 "Table walker couldn't find lookup level\n");
1149 int base_addr_lo = 3 + tsz -
stride * (3 - start_lookup_level) - tg;
1152 if (pa_range == 52) {
1153 int z = (base_addr_lo < 6) ? 6 : base_addr_lo;
1154 base_addr =
mbits(ttbr, 47,
z);
1155 base_addr |= (
bits(ttbr, 5, 2) << 48);
1157 base_addr =
mbits(ttbr, 47, base_addr_lo);
1163 DPRINTF(TLB,
"Address size fault before any lookup\n");
1166 f = std::make_shared<PrefetchAbort>(
1172 f = std::make_shared<DataAbort>(
1194 Addr desc_addr = base_addr |
1196 stride * (3 - start_lookup_level) + tg) << 3);
1230 sizeof(uint64_t), flag, start_lookup_level,
1234 sizeof(uint64_t), flag, -1, NULL,
1244 uint8_t texcb,
bool s)
1248 DPRINTF(TLBVerbose,
"memAttrs texcb:%d s:%d\n", texcb,
s);
1249 te.shareable =
false;
1250 te.nonCacheable =
false;
1251 te.outerShareable =
false;
1255 te.nonCacheable =
true;
1257 te.shareable =
true;
1262 te.nonCacheable =
true;
1264 te.shareable =
true;
1272 te.outerAttrs =
bits(texcb, 1, 0);
1278 te.outerAttrs =
bits(texcb, 1, 0);
1281 te.nonCacheable =
true;
1285 te.outerAttrs =
bits(texcb, 1, 0);
1288 panic(
"Reserved texcb value!\n");
1291 panic(
"Implementation-defined texcb value!\n");
1300 te.nonCacheable =
true;
1302 te.shareable =
false;
1307 panic(
"Reserved texcb value!\n");
1312 if (
bits(texcb, 1,0) == 0 ||
bits(texcb, 3,2) == 0)
1313 te.nonCacheable =
true;
1314 te.innerAttrs =
bits(texcb, 1, 0);
1315 te.outerAttrs =
bits(texcb, 3, 2);
1318 panic(
"More than 32 states for 5 bits?\n");
1326 DPRINTF(TLBVerbose,
"memAttrs PRRR:%08x NMRR:%08x\n", prrr, nmrr);
1327 uint8_t curr_tr = 0, curr_ir = 0, curr_or = 0;
1328 switch(
bits(texcb, 2,0)) {
1333 te.outerShareable = (prrr.nos0 == 0);
1339 te.outerShareable = (prrr.nos1 == 0);
1345 te.outerShareable = (prrr.nos2 == 0);
1351 te.outerShareable = (prrr.nos3 == 0);
1357 te.outerShareable = (prrr.nos4 == 0);
1363 te.outerShareable = (prrr.nos5 == 0);
1366 panic(
"Imp defined type\n");
1371 te.outerShareable = (prrr.nos7 == 0);
1377 DPRINTF(TLBVerbose,
"StronglyOrdered\n");
1379 te.nonCacheable =
true;
1382 te.shareable =
true;
1385 DPRINTF(TLBVerbose,
"Device ds1:%d ds0:%d s:%d\n",
1386 prrr.ds1, prrr.ds0,
s);
1388 te.nonCacheable =
true;
1392 te.shareable =
true;
1394 te.shareable =
true;
1397 DPRINTF(TLBVerbose,
"Normal ns1:%d ns0:%d s:%d\n",
1398 prrr.ns1, prrr.ns0,
s);
1401 te.shareable =
true;
1403 te.shareable =
true;
1406 panic(
"Reserved type");
1412 te.nonCacheable =
true;
1428 te.nonCacheable =
true;
1443 DPRINTF(TLBVerbose,
"memAttrs: shareable: %d, innerAttrs: %d, "
1445 te.shareable,
te.innerAttrs,
te.outerAttrs);
1446 te.setAttributes(
false);
1456 uint8_t
sh = lDescriptor.
sh();
1461 uint8_t attr_3_2 = (
attr >> 2) & 0x3;
1462 uint8_t attr_1_0 =
attr & 0x3;
1464 DPRINTF(TLBVerbose,
"memAttrsLPAE MemAttr:%#x sh:%#x\n",
attr,
sh);
1466 if (attr_3_2 == 0) {
1470 te.innerAttrs = attr_1_0 == 0 ? 1 : 3;
1471 te.nonCacheable =
true;
1474 te.outerAttrs = attr_3_2 == 1 ? 0 :
1475 attr_3_2 == 2 ? 2 : 1;
1476 te.innerAttrs = attr_1_0 == 1 ? 0 :
1477 attr_1_0 == 2 ? 6 : 5;
1478 te.nonCacheable = (attr_3_2 == 1) || (attr_1_0 == 1);
1481 uint8_t attrIndx = lDescriptor.
attrIndx();
1489 attr = (mair >> (8 * (attrIndx % 4))) & 0xff;
1490 uint8_t attr_7_4 =
bits(
attr, 7, 4);
1491 uint8_t attr_3_0 =
bits(
attr, 3, 0);
1492 DPRINTF(TLBVerbose,
"memAttrsLPAE AttrIndx:%#x sh:%#x, attr %#x\n", attrIndx,
sh,
attr);
1497 te.nonCacheable =
false;
1502 if (attr_3_0 == 0x0)
1504 else if (attr_3_0 == 0x4)
1507 panic(
"Unpredictable behavior\n");
1508 te.nonCacheable =
true;
1515 if (attr_3_0 == 0x4)
1517 te.nonCacheable =
true;
1518 else if (attr_3_0 < 0x8)
1519 panic(
"Unpredictable behavior\n");
1529 if (attr_7_4 & 0x4) {
1530 te.outerAttrs = (attr_7_4 & 1) ? 1 : 3;
1532 te.outerAttrs = 0x2;
1536 if (attr_3_0 != 0x4 && attr_3_0 < 0x8)
1537 panic(
"Unpredictable behavior\n");
1540 panic(
"Unpredictable behavior\n");
1546 te.innerAttrs = 0x1;
1549 te.innerAttrs = attr_7_4 == 0 ? 0x3 : 0;
1561 te.innerAttrs = attr_3_0 & 1 ? 0x5 : 0x7;
1564 panic(
"Unpredictable behavior\n");
1569 te.outerShareable =
sh == 2;
1570 te.shareable = (
sh & 0x2) ?
true :
false;
1571 te.setAttributes(
true);
1572 te.attributes |= (uint64_t)
attr << 56;
1582 uint8_t
sh = lDescriptor.
sh();
1586 uint8_t attr_hi = (
attr >> 2) & 0x3;
1587 uint8_t attr_lo =
attr & 0x3;
1589 DPRINTF(TLBVerbose,
"memAttrsAArch64 MemAttr:%#x sh:%#x\n",
attr,
sh);
1595 te.innerAttrs = attr_lo == 0 ? 1 : 3;
1596 te.nonCacheable =
true;
1599 te.outerAttrs = attr_hi == 1 ? 0 :
1600 attr_hi == 2 ? 2 : 1;
1601 te.innerAttrs = attr_lo == 1 ? 0 :
1602 attr_lo == 2 ? 6 : 5;
1605 te.nonCacheable = (attr_hi == 1) || (attr_hi == 2) ||
1606 (attr_lo == 1) || (attr_lo == 2);
1609 uint8_t attrIndx = lDescriptor.
attrIndx();
1611 DPRINTF(TLBVerbose,
"memAttrsAArch64 AttrIndx:%#x sh:%#x\n", attrIndx,
sh);
1628 panic(
"Invalid exception level");
1633 attr =
bits(mair, 8 * attrIndx + 7, 8 * attrIndx);
1641 te.nonCacheable =
false;
1643 te.nonCacheable =
true;
1651 te.nonCacheable =
true;
1656 warn_if(!attr_hi,
"Unpredictable behavior");
1662 te.nonCacheable =
true;
1665 te.shareable =
sh == 2;
1666 te.outerShareable = (
sh & 0x2) ?
true :
false;
1668 te.attributes = ((uint64_t)
attr << 56) |
1685 DPRINTF(
TLB,
"L1 descriptor for %#x is %#x\n",
1698 DPRINTF(
TLB,
"L1 Descriptor Reserved/Ignore, causing fault\n");
1701 std::make_shared<PrefetchAbort>(
1708 std::make_shared<DataAbort>(
1731 panic(
"Haven't implemented supersections\n");
1740 DPRINTF(
TLB,
"L1 descriptor points to page table at: %#x (%s)\n",
1776 panic(
"A new type in a 2 bit field?\n");
1784 return std::make_shared<PrefetchAbort>(
1790 return std::make_shared<DataAbort>(
1810 DPRINTF(
TLB,
"L%d descriptor for %#llx is %#llx (%s)\n",
1817 DPRINTF(PageTableWalker,
"Analyzing L%d descriptor: %#llx, pxn: %d, "
1818 "xn: %d, ap: %d, af: %d, type: %d\n",
1827 DPRINTF(PageTableWalker,
"Analyzing L%d descriptor: %#llx, type: %d\n",
1837 DPRINTF(
TLB,
"L%d descriptor Invalid, causing fault type %d\n",
1856 DPRINTF(
TLB,
"L%d descriptor causing Address Size Fault\n",
1863 DPRINTF(
TLB,
"L%d descriptor causing Access Fault\n",
1893 DPRINTF(
TLB,
"L%d descriptor points to L%d descriptor at: %#x (%s)\n",
1902 DPRINTF(
TLB,
"L%d descriptor causing Address Size Fault\n",
1933 Event *
event = NULL;
1942 panic(
"Wrong lookup level in table walk\n");
1948 sizeof(uint64_t), flag, -1,
event,
1956 panic(
"A new type in a 2 bit field?\n");
1970 DPRINTF(
TLB,
"L2 descriptor for %#x is %#x\n",
1977 DPRINTF(
TLB,
"L2 descriptor invalid, causing fault\n");
2002 DPRINTF(
TLB,
"Generating access fault at L2, afe: %d, ap: %d\n",
2028 DPRINTF(PageTableWalker,
"L1 Desc object host addr: %p\n",
2030 DPRINTF(PageTableWalker,
"L1 Desc object data: %08x\n",
2033 DPRINTF(PageTableWalker,
"calling doL1Descriptor for vaddr:%#x\n",
2056 DPRINTF(PageTableWalker,
"calling translateTiming again\n");
2086 DPRINTF(PageTableWalker,
"calling doL2Descriptor for vaddr:%#x\n",
2097 DPRINTF(PageTableWalker,
"calling translateTiming again\n");
2153 DPRINTF(PageTableWalker,
"calling doLongDescriptor for vaddr:%#x\n",
2173 DPRINTF(PageTableWalker,
"calling translateTiming again\n");
2188 panic(
"Max. number of lookups already reached in table walk\n");
2213 "Fetching descriptor at address: 0x%x stage2Req: %d\n",
2227 fault = tran->fault;
2238 if (queueIndex >= 0) {
2239 DPRINTF(PageTableWalker,
"Adding to walker fifo: "
2240 "queue size before adding: %d\n",
2246 (this->*doDescriptor)();
2253 if (queueIndex >= 0) {
2254 DPRINTF(PageTableWalker,
"Adding to walker fifo: "
2255 "queue size before adding: %d\n",
2264 (this->*doDescriptor)();
2267 (this->*doDescriptor)();
2280 te.longDescFormat = longDescriptor;
2286 te.size = (1<<
te.N) - 1;
2287 te.pfn = descriptor.
pfn();
2292 te.xn = descriptor.
xn();
2304 if (longDescriptor) {
2313 te.hap = lDescriptor.
ap();
2323 te.ap = descriptor.
ap();
2330 DPRINTF(
TLB,
" - N:%d pfn:%#x size:%#x global:%d valid:%d\n",
2332 DPRINTF(
TLB,
" - vpn:%#x xn:%d pxn:%d ap:%d domain:%d asid:%d "
2333 "vmid:%d hyp:%d nc:%d ns:%d\n",
te.vpn,
te.xn,
te.pxn,
2334 te.ap,
static_cast<uint8_t
>(
te.domain),
te.asid,
te.vmid,
te.isHyp,
2335 te.nonCacheable,
te.ns);
2336 DPRINTF(
TLB,
" - domain from L%d desc:%d data:%#x\n",
2351 switch (lookup_level_as_int) {
2359 panic(
"Invalid lookup level conversion");
2406 panic(
"unknown page size");
2418 auto req = std::make_shared<Request>();
2463 :
data(_data), numBytes(0),
event(_event), parent(_parent),
2466 req = std::make_shared<Request>();
2485 parent.getTableWalkerPort().sendTimingReq(
2486 req->getPaddr(), numBytes,
data, req->getFlags(),
2498 parent.mmu->translateTiming(req, tc,
this,
BaseMMU::Read,
true);
2502 : Stats::
Group(parent),
2503 ADD_STAT(walks, statistics::units::Count::get(),
2504 "Table walker walks requested"),
2505 ADD_STAT(walksShortDescriptor, statistics::units::Count::get(),
2506 "Table walker walks initiated with short descriptors"),
2507 ADD_STAT(walksLongDescriptor, statistics::units::Count::get(),
2508 "Table walker walks initiated with long descriptors"),
2509 ADD_STAT(walksShortTerminatedAtLevel, statistics::units::Count::get(),
2510 "Level at which table walker walks with short descriptors "
2512 ADD_STAT(walksLongTerminatedAtLevel, statistics::units::Count::get(),
2513 "Level at which table walker walks with long descriptors "
2515 ADD_STAT(squashedBefore, statistics::units::Count::get(),
2516 "Table walks squashed before starting"),
2517 ADD_STAT(squashedAfter, statistics::units::Count::get(),
2518 "Table walks squashed after completion"),
2520 "Table walker wait (enqueue to first request) latency"),
2521 ADD_STAT(walkServiceTime, statistics::units::
Tick::get(),
2522 "Table walker service (enqueue to completion) latency"),
2524 "Table walker pending requests distribution"),
2525 ADD_STAT(pageSizes, statistics::units::Count::get(),
2526 "Table walker page sizes translated"),
2527 ADD_STAT(requestOrigin, statistics::units::Count::get(),
2528 "Table walker requests started/completed, data/inst")
EventFunctionWrapper doL1DescEvent
Tick curTick()
The universal simulation clock.
virtual std::string dbgHeader() const =0
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
virtual bool squashed() const
This function is used by the page table walker to determine if it should translate the a pending requ...
void doLongDescriptorWrapper(LookupLevel curr_lookup_level)
Derived & ysubname(off_type index, const std::string &subname)
bool isSecure
If the access comes from the secure state.
virtual Port & getPort(const std::string &if_name, PortID idx=InvalidPortID)
Get a port with a given name and index.
Event * LongDescEventByLevel[4]
statistics::Scalar walksLongDescriptor
virtual RegVal readMiscReg(RegIndex misc_reg)=0
constexpr decltype(nullptr) NoFault
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
bool pxnTable() const
Is privileged execution allowed on subsequent lookup levels?
SCTLR sctlr
Cached copy of the sctlr as it existed when translation began.
Fault walk(const RequestPtr &req, ThreadContext *tc, uint16_t asid, vmid_t _vmid, bool _isHyp, BaseMMU::Mode mode, BaseMMU::Translation *_trans, bool timing, bool functional, bool secure, TLB::ArmTranslationType tranType, bool _stage2Req)
ExceptionLevel el
Current exception level.
Fault translateAtomic(const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode, bool stage2)
void sendAtomicReq(Addr desc_addr, int size, uint8_t *data, Request::Flags flag, Tick delay)
LongDescriptor longDesc
Long-format descriptor (LPAE and AArch64)
EventFunctionWrapper doProcessEvent
void readDataTimed(ThreadContext *tc, Addr desc_addr, Stage2Walk *translation, int num_bytes, Request::Flags flags)
void completeDrain()
Checks if all state is cleared and if so, completes drain.
void memAttrsAArch64(ThreadContext *tc, TlbEntry &te, LongDescriptor &lDescriptor)
statistics::Vector walksLongTerminatedAtLevel
void doL1LongDescriptorWrapper()
std::list< WalkerState * > pendingQueue
Queue of requests that have passed are waiting because the walker is currently busy.
Addr vaddr
The virtual address that is being translated with tagging removed.
DrainState drainState() const
Return the current drain state of an object.
RequestorID requestorId
Requestor id assigned by the MMU.
Port & getTableWalkerPort()
void nextWalk(ThreadContext *tc)
Derived & init(size_type _x, size_type _y)
The QueuedRequestPort combines two queues, a request queue and a snoop response queue,...
int decodePhysAddrRange64(uint8_t pa_enc)
Returns the n.
Addr paddr() const
Return the physical address of the entry.
void set(Type mask)
Set all flag's bits matching the given mask.
@ UNCACHEABLE
The request is to an uncacheable address.
RequestPtr req
A pointer to the original request.
@ PT_WALK
The request is a page table walk.
This translation class is used to trigger the data fetch once a timing translation returns the transl...
statistics::Vector2d requestOrigin
virtual bool xn() const =0
Tick sendAtomic(PacketPtr pkt)
Send an atomic request packet, where the data is moved and the state is updated in zero time,...
Addr nextDescAddr(Addr va) const
Return the address of the next descriptor.
const FlagsType nozero
Don't print if this is zero.
virtual uint8_t texcb() const
bool secureLookup
Helper variables used to implement hierarchical access permissions when the long-desc.
statistics::Scalar squashedAfter
bool cacheResponding() const
static LookupLevel toLookupLevel(uint8_t lookup_level_as_int)
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.
uint32_t data
The raw bits of the entry.
ByteOrder byteOrder(const ThreadContext *tc)
void schedule(Event &event, Tick when)
uint32_t data
The raw bits of the entry.
const FlagsType nonan
Don't print if this is NAN.
bool fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes, Request::Flags flags, int queueIndex, Event *event, void(TableWalker::*doDescriptor)())
statistics::Histogram walkServiceTime
void handleResp(TableWalkerState *state, Addr addr, Addr size, Tick delay=0)
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
void setVirt(Addr vaddr, int size, Request::Flags flags, int requestorId)
BaseMMU::Translation * stage2Tran
A pointer to the stage 2 translation that's in progress.
TlbEntry * lookup(Addr vpn, uint16_t asn, vmid_t vmid, bool hyp, bool secure, bool functional, bool ignore_asn, ExceptionLevel target_el, bool in_host, BaseMMU::Mode mode)
Lookup an entry in the TLB.
Addr vaddr_tainted
The virtual address that is being translated.
void sample(const U &v, int n=1)
Add a value to the distribtion n times.
Port(TableWalker *_walker, RequestorID id)
gem5::Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
const FlagsType dist
Print the distribution.
bool HaveLVA(ThreadContext *tc)
static const unsigned COMPLETED
bool functional
If the atomic mode should be functional.
statistics::Scalar walksShortDescriptor
Cycles is a wrapper class for representing cycle counts, i.e.
static const unsigned REQUESTED
uint8_t ap() const
2-bit access protection flags
uint8_t ap() const
Three bit access protection flags.
const FlagsType pdf
Print the percent of the total that this entry represents.
Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, TCR tcr, bool isInstr)
Removes the tag from tagged addresses if that mode is enabled.
Fault testWalk(Addr pa, Addr size, TlbEntry::DomainType domain, LookupLevel lookup_level)
TableWalkerStats(statistics::Group *parent)
void handleRespPacket(PacketPtr pkt, Tick delay=0)
uint16_t asid
ASID that we're servicing the request under.
void dataStatic(T *p)
Set the data pointer to the following value that should not be freed.
bool xnTable() const
Is execution allowed on subsequent lookup levels?
bool haveSecurity
Cached copies of system-level properties.
gem5::Flags< FlagsType > Flags
bool secureTable() const
Whether the subsequent levels of lookup are secure.
DrainState
Object drain/handover states.
SCTLR sctlr
Cached copy of the sctlr as it existed when translation began.
uint64_t data
The raw bits of the entry.
void sendFunctional(PacketPtr pkt) const
Send a functional request packet, where the data is instantly updated everywhere in the memory system...
uint8_t sh() const
2-bit shareability field
ThreadContext is the external interface to all thread state for anything outside of the CPU.
@ SECURE
The request targets the secure memory space.
virtual std::string name() const
void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode)
std::shared_ptr< FaultBase > Fault
bool HaveVirtHostExt(ThreadContext *tc)
void sendFunctionalReq(Addr desc_addr, int size, uint8_t *data, Request::Flags flag)
FaultSource
Generic fault source enums used to index into {short/long/aarch64}DescFaultSources[] to get the actua...
const Params & params() const
#define ADD_STAT(n,...)
Convenience macro to add a stat to a statistics group.
Fault processWalkAArch64()
static uint8_t pageSizeNtoStatBin(uint8_t N)
bool delayed
Whether the response is delayed in timing mode due to additional lookups.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void doL0LongDescriptorWrapper()
ThreadContext * tc
Thread context that we're doing the walk for.
int physAddrRange
Current physical address range in bits.
ProbePointArg< PacketInfo > Packet
Packet probe point.
uint64_t Tick
Tick count type.
int computeAddrTop(ThreadContext *tc, bool selbit, bool isInstr, TCR tcr, ExceptionLevel el)
Tick startTime
Timestamp for calculating elapsed time in service (for stats)
Addr l2Addr() const
Address of L2 descriptor if it exists.
EntryType type() const
Return the descriptor type.
std::shared_ptr< Request > RequestPtr
virtual Addr pfn() const =0
EventFunctionWrapper doL2DescEvent
virtual uint8_t offsetBits() const =0
TlbEntry::DomainType domain() const
Domain Client/Manager: ARM DDI 0406B: B3-31.
statistics::Vector pageSizes
bool isFetch
If the access is a fetch (for execution, and no-exec) must be checked?
Port * port
Port shared by the two table walkers.
virtual uint64_t getRawData() const =0
void translateTiming(ThreadContext *tc)
void doL2LongDescriptorWrapper()
void doL1DescriptorWrapper()
RequestPtr req
Request that is currently being serviced.
T htog(T value, ByteOrder guest_byte_order)
void translateTiming(const RequestPtr &req, ThreadContext *tc, BaseMMU::Translation *translation, BaseMMU::Mode mode, ArmTranslationType tranType)
void processWalkWrapper()
unsigned numSquashable
The number of walks belonging to squashed instructions that can be removed from the pendingQueue per ...
BaseMMU::Translation * transState
Translation state for delayed requests.
virtual bool secure(bool have_security, WalkerState *currState) const =0
bool translateFunctional(ThreadContext *tc, Addr vaddr, Addr &paddr)
GrainSize grainSize
Width of the granule size in bits.
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
TableWalker * tableWalker
HTCR htcr
Cached copy of the htcr as it existed when translation began.
@ Drained
Buffers drained, ready for serialization/handover.
bool isWrite
If the access is a write.
bool checkVAddrSizeFaultAArch64(Addr addr, int top_bit, GrainSize granule, int tsz, bool low_range)
VTCR_t vtcr
Cached copy of the vtcr as it existed when translation began.
ExceptionLevel s1TranslationRegime(ThreadContext *tc, ExceptionLevel el)
Fault generateLongDescFault(ArmFault::FaultSource src)
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Long-descriptor format (LPAE)
Histogram & init(size_type size)
Set the parameters of this histogram.
SenderState * senderState
This packet's sender state.
Stage2Walk(TableWalker &_parent, uint8_t *_data, Event *_event, Addr vaddr)
const std::string & name()
Fault testWalk(Addr pa, Addr size, Addr va, bool is_secure, BaseMMU::Mode mode, TlbEntry::DomainType domain, LookupLevel lookup_level)
statistics::Histogram pendingWalks
static ExceptionLevel tranTypeEL(CPSR cpsr, ArmTranslationType type)
Determine the EL to use for the purpose of a translation given a specific translation type.
bool isSecure(ThreadContext *tc)
statistics::Histogram walkWaitTime
The ClockedObject class extends the SimObject with a clock and accessor functions to relate ticks to ...
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...
LookupLevel lookupLevel
Current lookup level for this descriptor.
virtual bool global(WalkerState *currState) const =0
bool supersection() const
Is the page a Supersection (16 MiB)?
bool aarch64
True if the current lookup is performed in AArch64 state.
bool af() const
Returns true if the access flag (AF) is set.
void signalDrainDone() const
Signal that an object is drained.
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
bool stage2Req
Flag indicating if a second stage of lookup is required.
std::list< WalkerState * > stateQueues[MAX_LOOKUP_LEVELS]
Queues of requests for all the different lookup levels.
void sendTimingReq(Addr desc_addr, int size, uint8_t *data, Request::Flags flag, Tick delay, Event *event)
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
uint8_t rwTable() const
R/W protection flag for subsequent levels of lookup.
TableWalker(const Params &p)
Ports are used to interface objects to each other.
bool hpd
Hierarchical access permission disable.
uint8_t memAttr() const
Memory attributes, only used by stage 2 translations.
bool xn() const
Is execution allowed on this mapping?
DrainState drain() override
Draining is the process of clearing out the states of SimObjects.These are the SimObjects that are pa...
void drainResume() override
Resume execution after a successful drain.
void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr, uint8_t texcb, bool s)
MMU * mmu
The MMU to forward second stage look upts to.
void doL2DescriptorWrapper()
uint8_t attrIndx() const
Attribute index.
void memAttrsLPAE(ThreadContext *tc, TlbEntry &te, LongDescriptor &lDescriptor)
bool isUncacheable
True if table walks are uncacheable (for table descriptors)
bool longDescFormatInUse(ThreadContext *tc)
virtual void annotate(AnnotationIDs id, uint64_t val)
@ NO_ACCESS
The request should not cause a memory access.
void insert(Addr vaddr, TlbEntry &pte)
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 ...
uint8_t ap() const
Three bit access protection flags.
int snsBankedIndex(MiscRegIndex reg, ThreadContext *tc)
virtual BaseCPU * getCpuPtr()=0
bool invalid() const
Is the entry invalid.
const bool isStage2
Indicates whether this table walker is part of the stage 2 mmu.
bool recvTimingResp(PacketPtr pkt) override
Receive a timing response from the peer.
ClockedObjectParams Params
Parameters of ClockedObject.
Derived & flags(Flags _flags)
Set the flags and marks this stat to print at the end of simulation.
void doL3LongDescriptorWrapper()
gem5::ArmISA::TableWalker::TableWalkerStats stats
virtual uint8_t ap() const =0
HCR hcr
Cached copy of the htcr as it existed when translation began.
Fault readDataUntimed(ThreadContext *tc, Addr vaddr, Addr desc_addr, uint8_t *data, int num_bytes, Request::Flags flags, bool functional)
bool aarch64
If the access is performed in AArch64 state.
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
bool timing
If the mode is timing or atomic.
const FlagsType total
Print the total.
virtual bool shareable() const
Derived & init(size_type size)
Set this vector to have the given size.
Bitfield< 21, 20 > stride
uint8_t userTable() const
User/privileged mode protection flag for subsequent levels of lookup.
virtual void finish(const Fault &fault, const RequestPtr &req, ThreadContext *tc, BaseMMU::Mode mode)=0
virtual TlbEntry::DomainType domain() const =0
Fault fault
The fault that we are going to return.
TLB * tlb
TLB that is initiating these table walks.
TLB::ArmTranslationType tranType
The translation type that has been requested.
@ Draining
Draining buffers pending serialization/handover.
L1Descriptor l1Desc
Short-format descriptors.
statistics::Vector walksShortTerminatedAtLevel
PacketPtr createPacket(Addr desc_addr, int size, uint8_t *data, Request::Flags flag, Tick delay, Event *event)
BaseMMU::Mode mode
Save mode for use in delayed response.
bool pxn() const
Is privileged execution allowed on this mapping? (LPAE only)
#define panic(...)
This implements a cprintf based panic() function.
bool pending
If a timing translation is currently in progress.
void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor)
statistics::Scalar squashedBefore
Generated on Tue Sep 7 2021 14:53:42 for gem5 by doxygen 1.8.17