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,
771 DPRINTF(
TLB,
"Beginning table walk for address %#llx, TCR: %#llx\n",
805 DPRINTF(
TLB,
" - Selecting TTBR0 (AArch64)\n");
816 DPRINTF(
TLB,
" - Selecting TTBR1 (AArch64)\n");
836 DPRINTF(
TLB,
" - Selecting VSTTBR_EL2 (AArch64 stage 2)\n");
839 DPRINTF(
TLB,
" - Selecting VTTBR_EL2 (AArch64 stage 2)\n");
855 start_lookup_level = SLL[sl_tg];
857 "Cannot discern lookup level from vtcr.{sl0,tg0}");
863 DPRINTF(
TLB,
" - Selecting TTBR0 (AArch64)\n");
874 DPRINTF(
TLB,
" - Selecting TTBR1 (AArch64)\n");
894 DPRINTF(
TLB,
" - Selecting TTBR0_EL2 (AArch64)\n");
904 DPRINTF(
TLB,
" - Selecting TTBR1_EL2 (AArch64)\n");
924 DPRINTF(
TLB,
" - Selecting TTBR0_EL3 (AArch64)\n");
944 f = std::make_shared<PrefetchAbort>(
949 f = std::make_shared<DataAbort>(
969 warn_once(
"Reserved granule size requested; gem5's IMPLEMENTATION "
970 "DEFINED behavior takes this to mean 4KB granules\n");
985 static const GrainMap GM[] = {
991 const unsigned *lookup = NULL;
993 for (
unsigned i = 0;
i < 3; ++
i) {
994 if (tg == GM[
i].grain_size) {
995 lookup = GM[
i].lookup_level_cutoff;
1002 if (tsz > lookup[
L]) {
1008 "Table walker couldn't find lookup level\n");
1014 int base_addr_lo = 3 + tsz -
stride * (3 - start_lookup_level) - tg;
1015 Addr base_addr =
mbits(ttbr, 47, base_addr_lo);
1026 DPRINTF(
TLB,
"Address size fault before any lookup\n");
1029 f = std::make_shared<PrefetchAbort>(
1035 f = std::make_shared<DataAbort>(
1057 Addr desc_addr = base_addr |
1059 stride * (3 - start_lookup_level) + tg) << 3);
1092 sizeof(uint64_t), flag, start_lookup_level,
1096 sizeof(uint64_t), flag, -1, NULL,
1106 uint8_t texcb,
bool s)
1110 DPRINTF(TLBVerbose,
"memAttrs texcb:%d s:%d\n", texcb,
s);
1111 te.shareable =
false;
1112 te.nonCacheable =
false;
1113 te.outerShareable =
false;
1117 te.nonCacheable =
true;
1119 te.shareable =
true;
1124 te.nonCacheable =
true;
1126 te.shareable =
true;
1134 te.outerAttrs =
bits(texcb, 1, 0);
1140 te.outerAttrs =
bits(texcb, 1, 0);
1143 te.nonCacheable =
true;
1147 te.outerAttrs =
bits(texcb, 1, 0);
1150 panic(
"Reserved texcb value!\n");
1153 panic(
"Implementation-defined texcb value!\n");
1162 te.nonCacheable =
true;
1164 te.shareable =
false;
1169 panic(
"Reserved texcb value!\n");
1174 if (
bits(texcb, 1,0) == 0 ||
bits(texcb, 3,2) == 0)
1175 te.nonCacheable =
true;
1176 te.innerAttrs =
bits(texcb, 1, 0);
1177 te.outerAttrs =
bits(texcb, 3, 2);
1180 panic(
"More than 32 states for 5 bits?\n");
1188 DPRINTF(TLBVerbose,
"memAttrs PRRR:%08x NMRR:%08x\n", prrr, nmrr);
1189 uint8_t curr_tr = 0, curr_ir = 0, curr_or = 0;
1190 switch(
bits(texcb, 2,0)) {
1195 te.outerShareable = (prrr.nos0 == 0);
1201 te.outerShareable = (prrr.nos1 == 0);
1207 te.outerShareable = (prrr.nos2 == 0);
1213 te.outerShareable = (prrr.nos3 == 0);
1219 te.outerShareable = (prrr.nos4 == 0);
1225 te.outerShareable = (prrr.nos5 == 0);
1228 panic(
"Imp defined type\n");
1233 te.outerShareable = (prrr.nos7 == 0);
1239 DPRINTF(TLBVerbose,
"StronglyOrdered\n");
1241 te.nonCacheable =
true;
1244 te.shareable =
true;
1247 DPRINTF(TLBVerbose,
"Device ds1:%d ds0:%d s:%d\n",
1248 prrr.ds1, prrr.ds0,
s);
1250 te.nonCacheable =
true;
1254 te.shareable =
true;
1256 te.shareable =
true;
1259 DPRINTF(TLBVerbose,
"Normal ns1:%d ns0:%d s:%d\n",
1260 prrr.ns1, prrr.ns0,
s);
1263 te.shareable =
true;
1265 te.shareable =
true;
1268 panic(
"Reserved type");
1274 te.nonCacheable =
true;
1290 te.nonCacheable =
true;
1305 DPRINTF(TLBVerbose,
"memAttrs: shareable: %d, innerAttrs: %d, "
1307 te.shareable,
te.innerAttrs,
te.outerAttrs);
1308 te.setAttributes(
false);
1318 uint8_t
sh = lDescriptor.
sh();
1323 uint8_t attr_3_2 = (
attr >> 2) & 0x3;
1324 uint8_t attr_1_0 =
attr & 0x3;
1326 DPRINTF(TLBVerbose,
"memAttrsLPAE MemAttr:%#x sh:%#x\n",
attr,
sh);
1328 if (attr_3_2 == 0) {
1332 te.innerAttrs = attr_1_0 == 0 ? 1 : 3;
1333 te.nonCacheable =
true;
1336 te.outerAttrs = attr_3_2 == 1 ? 0 :
1337 attr_3_2 == 2 ? 2 : 1;
1338 te.innerAttrs = attr_1_0 == 1 ? 0 :
1339 attr_1_0 == 2 ? 6 : 5;
1340 te.nonCacheable = (attr_3_2 == 1) || (attr_1_0 == 1);
1343 uint8_t attrIndx = lDescriptor.
attrIndx();
1351 attr = (mair >> (8 * (attrIndx % 4))) & 0xff;
1352 uint8_t attr_7_4 =
bits(
attr, 7, 4);
1353 uint8_t attr_3_0 =
bits(
attr, 3, 0);
1354 DPRINTF(TLBVerbose,
"memAttrsLPAE AttrIndx:%#x sh:%#x, attr %#x\n", attrIndx,
sh,
attr);
1359 te.nonCacheable =
false;
1364 if (attr_3_0 == 0x0)
1366 else if (attr_3_0 == 0x4)
1369 panic(
"Unpredictable behavior\n");
1370 te.nonCacheable =
true;
1377 if (attr_3_0 == 0x4)
1379 te.nonCacheable =
true;
1380 else if (attr_3_0 < 0x8)
1381 panic(
"Unpredictable behavior\n");
1391 if (attr_7_4 & 0x4) {
1392 te.outerAttrs = (attr_7_4 & 1) ? 1 : 3;
1394 te.outerAttrs = 0x2;
1398 if (attr_3_0 != 0x4 && attr_3_0 < 0x8)
1399 panic(
"Unpredictable behavior\n");
1402 panic(
"Unpredictable behavior\n");
1408 te.innerAttrs = 0x1;
1411 te.innerAttrs = attr_7_4 == 0 ? 0x3 : 0;
1423 te.innerAttrs = attr_3_0 & 1 ? 0x5 : 0x7;
1426 panic(
"Unpredictable behavior\n");
1431 te.outerShareable =
sh == 2;
1432 te.shareable = (
sh & 0x2) ?
true :
false;
1433 te.setAttributes(
true);
1434 te.attributes |= (uint64_t)
attr << 56;
1444 uint8_t
sh = lDescriptor.
sh();
1448 uint8_t attr_hi = (
attr >> 2) & 0x3;
1449 uint8_t attr_lo =
attr & 0x3;
1451 DPRINTF(TLBVerbose,
"memAttrsAArch64 MemAttr:%#x sh:%#x\n",
attr,
sh);
1457 te.innerAttrs = attr_lo == 0 ? 1 : 3;
1458 te.nonCacheable =
true;
1461 te.outerAttrs = attr_hi == 1 ? 0 :
1462 attr_hi == 2 ? 2 : 1;
1463 te.innerAttrs = attr_lo == 1 ? 0 :
1464 attr_lo == 2 ? 6 : 5;
1467 te.nonCacheable = (attr_hi == 1) || (attr_hi == 2) ||
1468 (attr_lo == 1) || (attr_lo == 2);
1471 uint8_t attrIndx = lDescriptor.
attrIndx();
1473 DPRINTF(TLBVerbose,
"memAttrsAArch64 AttrIndx:%#x sh:%#x\n", attrIndx,
sh);
1490 panic(
"Invalid exception level");
1495 attr =
bits(mair, 8 * attrIndx + 7, 8 * attrIndx);
1503 te.nonCacheable =
false;
1505 te.nonCacheable =
true;
1513 te.nonCacheable =
true;
1518 warn_if(!attr_hi,
"Unpredictable behavior");
1524 te.nonCacheable =
true;
1527 te.shareable =
sh == 2;
1528 te.outerShareable = (
sh & 0x2) ?
true :
false;
1530 te.attributes = ((uint64_t)
attr << 56) |
1547 DPRINTF(
TLB,
"L1 descriptor for %#x is %#x\n",
1560 DPRINTF(
TLB,
"L1 Descriptor Reserved/Ignore, causing fault\n");
1563 std::make_shared<PrefetchAbort>(
1570 std::make_shared<DataAbort>(
1593 panic(
"Haven't implemented supersections\n");
1602 DPRINTF(
TLB,
"L1 descriptor points to page table at: %#x (%s)\n",
1638 panic(
"A new type in a 2 bit field?\n");
1646 return std::make_shared<PrefetchAbort>(
1652 return std::make_shared<DataAbort>(
1672 DPRINTF(
TLB,
"L%d descriptor for %#llx is %#llx (%s)\n",
1679 DPRINTF(TLBVerbose,
"Analyzing L%d descriptor: %#llx, pxn: %d, "
1680 "xn: %d, ap: %d, af: %d, type: %d\n",
1689 DPRINTF(TLBVerbose,
"Analyzing L%d descriptor: %#llx, type: %d\n",
1699 DPRINTF(
TLB,
"L%d descriptor Invalid, causing fault type %d\n",
1720 DPRINTF(
TLB,
"L%d descriptor causing Address Size Fault\n",
1727 DPRINTF(
TLB,
"L%d descriptor causing Access Fault\n",
1757 DPRINTF(
TLB,
"L%d descriptor points to L%d descriptor at: %#x (%s)\n",
1766 DPRINTF(
TLB,
"L%d descriptor causing Address Size Fault\n",
1797 Event *
event = NULL;
1806 panic(
"Wrong lookup level in table walk\n");
1812 sizeof(uint64_t), flag, -1,
event,
1820 panic(
"A new type in a 2 bit field?\n");
1834 DPRINTF(
TLB,
"L2 descriptor for %#x is %#x\n",
1841 DPRINTF(
TLB,
"L2 descriptor invalid, causing fault\n");
1866 DPRINTF(
TLB,
"Generating access fault at L2, afe: %d, ap: %d\n",
1917 DPRINTF(TLBVerbose,
"calling translateTiming again\n");
1947 DPRINTF(TLBVerbose,
"calling doL2Descriptor for vaddr:%#x\n",
1958 DPRINTF(TLBVerbose,
"calling translateTiming again\n");
2014 DPRINTF(TLBVerbose,
"calling doLongDescriptor for vaddr:%#x\n",
2034 DPRINTF(TLBVerbose,
"calling translateTiming again\n");
2049 panic(
"Max. number of lookups already reached in table walk\n");
2073 DPRINTF(TLBVerbose,
"Fetching descriptor at address: 0x%x stage2Req: %d\n",
2089 fault = tran->
fault;
2100 if (queueIndex >= 0) {
2101 DPRINTF(TLBVerbose,
"Adding to walker fifo: queue size before adding: %d\n",
2107 (this->*doDescriptor)();
2113 if (queueIndex >= 0) {
2114 DPRINTF(TLBVerbose,
"Adding to walker fifo: queue size before adding: %d\n",
2122 (this->*doDescriptor)();
2131 (this->*doDescriptor)();
2145 te.longDescFormat = longDescriptor;
2151 te.size = (1<<
te.N) - 1;
2152 te.pfn = descriptor.
pfn();
2157 te.xn = descriptor.
xn();
2169 if (longDescriptor) {
2178 te.hap = lDescriptor.
ap();
2188 te.ap = descriptor.
ap();
2195 DPRINTF(
TLB,
" - N:%d pfn:%#x size:%#x global:%d valid:%d\n",
2197 DPRINTF(
TLB,
" - vpn:%#x xn:%d pxn:%d ap:%d domain:%d asid:%d "
2198 "vmid:%d hyp:%d nc:%d ns:%d\n",
te.vpn,
te.xn,
te.pxn,
2199 te.ap,
static_cast<uint8_t
>(
te.domain),
te.asid,
te.vmid,
te.isHyp,
2200 te.nonCacheable,
te.ns);
2201 DPRINTF(
TLB,
" - domain from L%d desc:%d data:%#x\n",
2214 ArmTableWalkerParams::create()
2222 switch (lookup_level_as_int) {
2230 panic(
"Invalid lookup level conversion");
2276 panic(
"unknown page size");
2283 :
Stats::Group(parent),
2284 ADD_STAT(walks,
"Table walker walks requested"),
2285 ADD_STAT(walksShortDescriptor,
"Table walker walks initiated with"
2286 " short descriptors"),
2287 ADD_STAT(walksLongDescriptor,
"Table walker walks initiated with"
2288 " long descriptors"),
2289 ADD_STAT(walksShortTerminatedAtLevel,
"Level at which table walker"
2290 " walks with short descriptors terminate"),
2291 ADD_STAT(walksLongTerminatedAtLevel,
"Level at which table walker"
2292 " walks with long descriptors terminate"),
2293 ADD_STAT(squashedBefore,
"Table walks squashed before starting"),
2294 ADD_STAT(squashedAfter,
"Table walks squashed after completion"),
2295 ADD_STAT(walkWaitTime,
"Table walker wait (enqueue to first request)"
2297 ADD_STAT(walkServiceTime,
"Table walker service (enqueue to completion)"
2299 ADD_STAT(pendingWalks,
"Table walker pending requests distribution"),
2300 ADD_STAT(pageSizes,
"Table walker page sizes translated"),
2301 ADD_STAT(requestOrigin,
"Table walker requests started/completed,"
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
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
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 (16MB)?
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
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.
const Params * params() const
virtual bool xn() const =0
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.
T mbits(T val, int first, int last)
Mask off the given bits in place like bits() but without shifting.
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.
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.
@ SECURE
The request targets the secure memory space.
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.
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)
const unsigned MaxPhysAddrRange
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.
ArmTableWalkerParams Params
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.
TableWalker(const Params *p)
VTCR_t vtcr
Cached copy of the vtcr as it existed when translation began.
static bool checkAddrSizeFaultAArch64(Addr addr, int currPhysAddrRange)
Returns true if the address exceeds the range permitted by the system-wide setting or by the TCR_ELx ...
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Get a port with a given name and index.
void doL2LongDescriptorWrapper()
@ UNCACHEABLE
The request is to an uncacheable address.
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?
RequestPtr dmaAction(Packet::Command cmd, Addr addr, int size, Event *event, uint8_t *data, Tick delay, Request::Flags flag=0)
Stats::Vector walksShortTerminatedAtLevel
Fault generateLongDescFault(ArmFault::FaultSource src)
uint8_t offsetBits() const
Return the bit width of the page/block offset.
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.
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...
@ PT_WALK
The request is a page table walk.
TLB * tlb
TLB that is initiating these table walks.
uint8_t sh() const
2-bit shareability field
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....
virtual RegVal readMiscReg(RegIndex misc_reg)=0
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)
static unsigned adjustTableSizeAArch64(unsigned tsz)
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.
static const unsigned COMPLETED
void doL1LongDescriptorWrapper()
bool xnTable() const
Is execution allowed on subsequent lookup levels?
EventFunctionWrapper doL1DescEvent
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.
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.
Tick curTick()
The current simulated tick.
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
void insert(Addr vaddr, TlbEntry &pte)
Generated on Wed Sep 30 2020 14:02:01 for gem5 by doxygen 1.8.17