Deleted Added
sdiff udiff text old ( 10579:e622a3e2ed14 ) new ( 10621:b7bc5b1084a4 )
full compact
1/*
2 * Copyright (c) 2010, 2012-2014 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software

--- 46 unchanged lines hidden (view full) ---

55
56using namespace ArmISA;
57
58TableWalker::TableWalker(const Params *p)
59 : MemObject(p), port(this, p->sys), drainManager(NULL),
60 stage2Mmu(NULL), isStage2(p->is_stage2), tlb(NULL),
61 currState(NULL), pending(false), masterId(p->sys->getMasterId(name())),
62 numSquashable(p->num_squash_per_cycle),
63 doL1DescEvent(this), doL2DescEvent(this),
64 doL0LongDescEvent(this), doL1LongDescEvent(this), doL2LongDescEvent(this),
65 doL3LongDescEvent(this),
66 doProcessEvent(this)
67{
68 sctlr = 0;
69
70 // Cache system-level properties

--- 75 unchanged lines hidden (view full) ---

146
147void
148TableWalker::drainResume()
149{
150 Drainable::drainResume();
151 if (params()->sys->isTimingMode() && currState) {
152 delete currState;
153 currState = NULL;
154 }
155}
156
157BaseMasterPort&
158TableWalker::getMasterPort(const std::string &if_name, PortID idx)
159{
160 if (if_name == "port") {
161 return port;
162 }
163 return MemObject::getMasterPort(if_name, idx);
164}
165
166Fault
167TableWalker::walk(RequestPtr _req, ThreadContext *_tc, uint16_t _asid,
168 uint8_t _vmid, bool _isHyp, TLB::Mode _mode,
169 TLB::Translation *_trans, bool _timing, bool _functional,
170 bool secure, TLB::ArmTranslationType tranType)
171{
172 assert(!(_functional && _timing));
173 WalkerState *savedCurrState = NULL;
174
175 if (!currState && !_functional) {
176 // For atomic mode, a new WalkerState instance should be only created
177 // once per TLB. For timing mode, a new instance is generated for every
178 // TLB miss.
179 DPRINTF(TLBVerbose, "creating new instance of WalkerState\n");
180

--- 10 unchanged lines hidden (view full) ---

191 } else if (_timing) {
192 // This is a translation that was completed and then faulted again
193 // because some underlying parameters that affect the translation
194 // changed out from under us (e.g. asid). It will either be a
195 // misprediction, in which case nothing will happen or we'll use
196 // this fault to re-execute the faulting instruction which should clean
197 // up everything.
198 if (currState->vaddr_tainted == _req->getVaddr()) {
199 return std::make_shared<ReExec>();
200 }
201 }
202
203 currState->tc = _tc;
204 currState->aarch64 = opModeIs64(currOpMode(_tc));
205 currState->el = currEL(_tc);
206 currState->transState = _trans;
207 currState->req = _req;
208 currState->fault = NoFault;
209 currState->asid = _asid;
210 currState->vmid = _vmid;

--- 45 unchanged lines hidden (view full) ---

256 currState->hcr = currState->tc->readMiscReg(MISCREG_HCR);
257 currState->vtcr = currState->tc->readMiscReg(MISCREG_VTCR);
258 }
259 sctlr = currState->sctlr;
260
261 currState->isFetch = (currState->mode == TLB::Execute);
262 currState->isWrite = (currState->mode == TLB::Write);
263
264 // We only do a second stage of translation if we're not secure, or in
265 // hyp mode, the second stage MMU is enabled, and this table walker
266 // instance is the first stage.
267 currState->doingStage2 = false;
268 // @todo: for now disable this in AArch64 (HCR is not set)
269 currState->stage2Req = !currState->aarch64 && currState->hcr.vm &&
270 !isStage2 && !currState->isSecure && !currState->isHyp;
271
272 bool long_desc_format = currState->aarch64 ||
273 (_haveLPAE && currState->ttbcr.eae) ||
274 _isHyp || isStage2;
275
276 if (long_desc_format) {
277 // Helper variables used for hierarchical permissions
278 currState->secureLookup = currState->isSecure;
279 currState->rwTable = true;
280 currState->userTable = true;
281 currState->xnTable = false;
282 currState->pxnTable = false;
283 }
284
285 if (!currState->timing) {
286 Fault fault = NoFault;
287 if (currState->aarch64)
288 fault = processWalkAArch64();
289 else if (long_desc_format)
290 fault = processWalkLPAE();

--- 7 unchanged lines hidden (view full) ---

298 currState = savedCurrState;
299 }
300 return fault;
301 }
302
303 if (pending || pendingQueue.size()) {
304 pendingQueue.push_back(currState);
305 currState = NULL;
306 } else {
307 pending = true;
308 if (currState->aarch64)
309 return processWalkAArch64();
310 else if (long_desc_format)
311 return processWalkLPAE();
312 else
313 return processWalk();
314 }
315
316 return NoFault;
317}
318
319void
320TableWalker::processWalkWrapper()
321{
322 assert(!currState);
323 assert(pendingQueue.size());
324 currState = pendingQueue.front();
325
326 ExceptionLevel target_el = EL0;
327 if (currState->aarch64)
328 target_el = currEL(currState->tc);
329 else
330 target_el = EL1;
331

--- 35 unchanged lines hidden (view full) ---

367 // If the instruction that we were translating for has been
368 // squashed we shouldn't bother.
369 unsigned num_squashed = 0;
370 ThreadContext *tc = currState->tc;
371 while ((num_squashed < numSquashable) && currState &&
372 (currState->transState->squashed() || te)) {
373 pendingQueue.pop_front();
374 num_squashed++;
375
376 DPRINTF(TLB, "Squashing table walk for address %#x\n",
377 currState->vaddr_tainted);
378
379 if (currState->transState->squashed()) {
380 // finish the translation which will delete the translation object
381 currState->transState->finish(
382 std::make_shared<UnimpFault>("Squashed Inst"),
383 currState->req, currState->tc, currState->mode);
384 } else {
385 // translate the request now that we know it will work
386 tlb->translateTiming(currState->req, currState->tc,
387 currState->transState, currState->mode);
388
389 }
390
391 // delete the current request
392 delete currState;
393
394 // peak at the next one
395 if (pendingQueue.size()) {
396 currState = pendingQueue.front();
397 te = tlb->lookup(currState->vaddr, currState->asid,
398 currState->vmid, currState->isHyp, currState->isSecure, true,
399 false, target_el);
400 } else {
401 // Terminate the loop, nothing more to do
402 currState = NULL;
403 }
404 }
405
406 // if we've still got pending translations schedule more work
407 nextWalk(tc);
408 currState = NULL;
409}
410
411Fault
412TableWalker::processWalk()
413{
414 Addr ttbr = 0;
415
416 // If translation isn't enabled, we shouldn't be here
417 assert(currState->sctlr.m || isStage2);
418
419 DPRINTF(TLB, "Beginning table walk for address %#x, TTBCR: %#x, bits:%#x\n",
420 currState->vaddr_tainted, currState->ttbcr, mbits(currState->vaddr, 31,
421 32 - currState->ttbcr.n));
422
423 if (currState->ttbcr.n == 0 || !mbits(currState->vaddr, 31,
424 32 - currState->ttbcr.n)) {
425 DPRINTF(TLB, " - Selecting TTBR0\n");
426 // Check if table walk is allowed when Security Extensions are enabled
427 if (haveSecurity && currState->ttbcr.pd0) {
428 if (currState->isFetch)
429 return std::make_shared<PrefetchAbort>(
430 currState->vaddr_tainted,

--- 75 unchanged lines hidden (view full) ---

506{
507 Addr ttbr, ttbr0_max, ttbr1_min, desc_addr;
508 int tsz, n;
509 LookupLevel start_lookup_level = L1;
510
511 DPRINTF(TLB, "Beginning table walk for address %#x, TTBCR: %#x\n",
512 currState->vaddr_tainted, currState->ttbcr);
513
514 Request::Flags flag = 0;
515 if (currState->isSecure)
516 flag.set(Request::SECURE);
517
518 // work out which base address register to use, if in hyp mode we always
519 // use HTTBR
520 if (isStage2) {
521 DPRINTF(TLB, " - Selecting VTTBR (long-desc.)\n");

--- 173 unchanged lines hidden (view full) ---

695 DPRINTF(TLB, "Beginning table walk for address %#llx, TCR: %#llx\n",
696 currState->vaddr_tainted, currState->tcr);
697
698 static const GrainSize GrainMapDefault[] =
699 { Grain4KB, Grain64KB, Grain16KB, ReservedGrain };
700 static const GrainSize GrainMap_EL1_tg1[] =
701 { ReservedGrain, Grain16KB, Grain4KB, Grain64KB };
702
703 // Determine TTBR, table size, granule size and phys. address range
704 Addr ttbr = 0;
705 int tsz = 0, ps = 0;
706 GrainSize tg = Grain4KB; // grain size computed from tg* field
707 bool fault = false;
708 switch (currState->el) {
709 case EL0:
710 case EL1:

--- 204 unchanged lines hidden (view full) ---

915 break;
916 case L3:
917 event = (Event *) &doL3LongDescEvent;
918 break;
919 default:
920 panic("Invalid table lookup level");
921 break;
922 }
923 port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t), event,
924 (uint8_t*) &currState->longDesc.data,
925 currState->tc->getCpuPtr()->clockPeriod(), flag);
926 DPRINTF(TLBVerbose,
927 "Adding to walker fifo: queue size before adding: %d\n",
928 stateQueues[start_lookup_level].size());
929 stateQueues[start_lookup_level].push_back(currState);
930 currState = NULL;
931 } else if (!currState->functional) {
932 port.dmaAction(MemCmd::ReadReq, desc_addr, sizeof(uint64_t),

--- 760 unchanged lines hidden (view full) ---

1693 DPRINTF(TLBVerbose, "calling doL1Descriptor for vaddr:%#x\n", currState->vaddr_tainted);
1694 doL1Descriptor();
1695
1696 stateQueues[L1].pop_front();
1697 // Check if fault was generated
1698 if (currState->fault != NoFault) {
1699 currState->transState->finish(currState->fault, currState->req,
1700 currState->tc, currState->mode);
1701
1702 pending = false;
1703 nextWalk(currState->tc);
1704
1705 currState->req = NULL;
1706 currState->tc = NULL;
1707 currState->delayed = false;
1708 delete currState;
1709 }
1710 else if (!currState->delayed) {
1711 // delay is not set so there is no L2 to do
1712 // Don't finish the translation if a stage 2 look up is underway
1713 if (!currState->doingStage2) {
1714 DPRINTF(TLBVerbose, "calling translateTiming again\n");
1715 currState->fault = tlb->translateTiming(currState->req, currState->tc,
1716 currState->transState, currState->mode);
1717 }
1718
1719 pending = false;
1720 nextWalk(currState->tc);
1721
1722 currState->req = NULL;
1723 currState->tc = NULL;
1724 currState->delayed = false;

--- 19 unchanged lines hidden (view full) ---

1744 DPRINTF(TLBVerbose, "calling doL2Descriptor for vaddr:%#x\n",
1745 currState->vaddr_tainted);
1746 doL2Descriptor();
1747
1748 // Check if fault was generated
1749 if (currState->fault != NoFault) {
1750 currState->transState->finish(currState->fault, currState->req,
1751 currState->tc, currState->mode);
1752 }
1753 else {
1754 // Don't finish the translation if a stage 2 look up is underway
1755 if (!currState->doingStage2) {
1756 DPRINTF(TLBVerbose, "calling translateTiming again\n");
1757 currState->fault = tlb->translateTiming(currState->req,
1758 currState->tc, currState->transState, currState->mode);
1759 }
1760 }
1761
1762
1763 stateQueues[L2].pop_front();
1764 pending = false;
1765 nextWalk(currState->tc);
1766

--- 60 unchanged lines hidden (view full) ---

1827 currState->tc = NULL;
1828 currState->delayed = false;
1829 delete currState;
1830 } else if (!currState->delayed) {
1831 // No additional lookups required
1832 // Don't finish the translation if a stage 2 look up is underway
1833 if (!currState->doingStage2) {
1834 DPRINTF(TLBVerbose, "calling translateTiming again\n");
1835 currState->fault = tlb->translateTiming(currState->req, currState->tc,
1836 currState->transState,
1837 currState->mode);
1838 }
1839
1840 pending = false;
1841 nextWalk(currState->tc);
1842
1843 currState->req = NULL;
1844 currState->tc = NULL;
1845 currState->delayed = false;

--- 55 unchanged lines hidden (view full) ---

1901 currState = NULL;
1902 }
1903 } else {
1904 (this->*doDescriptor)();
1905 }
1906 } else {
1907 if (isTiming) {
1908 port.dmaAction(MemCmd::ReadReq, descAddr, numBytes, event, data,
1909 currState->tc->getCpuPtr()->clockPeriod(), flags);
1910 if (queueIndex >= 0) {
1911 DPRINTF(TLBVerbose, "Adding to walker fifo: queue size before adding: %d\n",
1912 stateQueues[queueIndex].size());
1913 stateQueues[queueIndex].push_back(currState);
1914 currState = NULL;
1915 }
1916 } else if (!currState->functional) {
1917 port.dmaAction(MemCmd::ReadReq, descAddr, numBytes, NULL, data,

--- 33 unchanged lines hidden (view full) ---

1951 te.ns = !descriptor.secure(haveSecurity, currState) || isStage2;
1952 te.nstid = !currState->isSecure;
1953 te.xn = descriptor.xn();
1954 if (currState->aarch64)
1955 te.el = currState->el;
1956 else
1957 te.el = 1;
1958
1959 // ASID has no meaning for stage 2 TLB entries, so mark all stage 2 entries
1960 // as global
1961 te.global = descriptor.global(currState) || isStage2;
1962 if (longDescriptor) {
1963 LongDescriptor lDescriptor =
1964 dynamic_cast<LongDescriptor &>(descriptor);
1965
1966 te.xn |= currState->xnTable;

--- 52 unchanged lines hidden (view full) ---

2019 case L2:
2020 return L2;
2021 case L3:
2022 return L3;
2023 default:
2024 panic("Invalid lookup level conversion");
2025 }
2026}