table_walker.hh (10717:4f8c1bd6fdb8) table_walker.hh (10873:7c972b9aea16)
1/*
2 * Copyright (c) 2010-2015 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
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Ali Saidi
38 * Giacomo Gabrielli
39 */
40
41#ifndef __ARCH_ARM_TABLE_WALKER_HH__
42#define __ARCH_ARM_TABLE_WALKER_HH__
43
44#include <list>
45
46#include "arch/arm/miscregs.hh"
47#include "arch/arm/system.hh"
48#include "arch/arm/tlb.hh"
1/*
2 * Copyright (c) 2010-2015 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
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Ali Saidi
38 * Giacomo Gabrielli
39 */
40
41#ifndef __ARCH_ARM_TABLE_WALKER_HH__
42#define __ARCH_ARM_TABLE_WALKER_HH__
43
44#include <list>
45
46#include "arch/arm/miscregs.hh"
47#include "arch/arm/system.hh"
48#include "arch/arm/tlb.hh"
49#include "dev/dma_device.hh"
50#include "mem/request.hh"
51#include "params/ArmTableWalker.hh"
52#include "sim/eventq.hh"
53
54class ThreadContext;
55
49#include "mem/request.hh"
50#include "params/ArmTableWalker.hh"
51#include "sim/eventq.hh"
52
53class ThreadContext;
54
55class DmaPort;
56
56namespace ArmISA {
57class Translation;
58class TLB;
59class Stage2MMU;
60
61class TableWalker : public MemObject
62{
63 public:
64 class WalkerState;
65
66 class DescriptorBase {
67 public:
68 /** Current lookup level for this descriptor */
69 LookupLevel lookupLevel;
70
71 virtual Addr pfn() const = 0;
72 virtual TlbEntry::DomainType domain() const = 0;
73 virtual bool xn() const = 0;
74 virtual uint8_t ap() const = 0;
75 virtual bool global(WalkerState *currState) const = 0;
76 virtual uint8_t offsetBits() const = 0;
77 virtual bool secure(bool have_security, WalkerState *currState) const = 0;
78 virtual std::string dbgHeader() const = 0;
79 virtual uint64_t getRawData() const = 0;
80 virtual uint8_t texcb() const
81 {
82 panic("texcb() not implemented for this class\n");
83 }
84 virtual bool shareable() const
85 {
86 panic("shareable() not implemented for this class\n");
87 }
88 };
89
90 class L1Descriptor : public DescriptorBase {
91 public:
92 /** Type of page table entry ARM DDI 0406B: B3-8*/
93 enum EntryType {
94 Ignore,
95 PageTable,
96 Section,
97 Reserved
98 };
99
100 /** The raw bits of the entry */
101 uint32_t data;
102
103 /** This entry has been modified (access flag set) and needs to be
104 * written back to memory */
105 bool _dirty;
106
107 /** Default ctor */
108 L1Descriptor() : data(0), _dirty(false)
109 {
110 lookupLevel = L1;
111 }
112
113 virtual uint64_t getRawData() const
114 {
115 return (data);
116 }
117
118 virtual std::string dbgHeader() const
119 {
120 return "Inserting Section Descriptor into TLB\n";
121 }
122
123 virtual uint8_t offsetBits() const
124 {
125 return 20;
126 }
127
128 EntryType type() const
129 {
130 return (EntryType)(data & 0x3);
131 }
132
133 /** Is the page a Supersection (16MB)?*/
134 bool supersection() const
135 {
136 return bits(data, 18);
137 }
138
139 /** Return the physcal address of the entry, bits in position*/
140 Addr paddr() const
141 {
142 if (supersection())
143 panic("Super sections not implemented\n");
144 return mbits(data, 31, 20);
145 }
146 /** Return the physcal address of the entry, bits in position*/
147 Addr paddr(Addr va) const
148 {
149 if (supersection())
150 panic("Super sections not implemented\n");
151 return mbits(data, 31, 20) | mbits(va, 19, 0);
152 }
153
154
155 /** Return the physical frame, bits shifted right */
156 Addr pfn() const
157 {
158 if (supersection())
159 panic("Super sections not implemented\n");
160 return bits(data, 31, 20);
161 }
162
163 /** Is the translation global (no asid used)? */
164 bool global(WalkerState *currState) const
165 {
166 return !bits(data, 17);
167 }
168
169 /** Is the translation not allow execution? */
170 bool xn() const
171 {
172 return bits(data, 4);
173 }
174
175 /** Three bit access protection flags */
176 uint8_t ap() const
177 {
178 return (bits(data, 15) << 2) | bits(data, 11, 10);
179 }
180
181 /** Domain Client/Manager: ARM DDI 0406B: B3-31 */
182 TlbEntry::DomainType domain() const
183 {
184 return static_cast<TlbEntry::DomainType>(bits(data, 8, 5));
185 }
186
187 /** Address of L2 descriptor if it exists */
188 Addr l2Addr() const
189 {
190 return mbits(data, 31, 10);
191 }
192
193 /** Memory region attributes: ARM DDI 0406B: B3-32.
194 * These bits are largly ignored by M5 and only used to
195 * provide the illusion that the memory system cares about
196 * anything but cachable vs. uncachable.
197 */
198 uint8_t texcb() const
199 {
200 return bits(data, 2) | bits(data, 3) << 1 | bits(data, 14, 12) << 2;
201 }
202
203 /** If the section is shareable. See texcb() comment. */
204 bool shareable() const
205 {
206 return bits(data, 16);
207 }
208
209 /** Set access flag that this entry has been touched. Mark
210 * the entry as requiring a writeback, in the future.
211 */
212 void setAp0()
213 {
214 data |= 1 << 10;
215 _dirty = true;
216 }
217
218 /** This entry needs to be written back to memory */
219 bool dirty() const
220 {
221 return _dirty;
222 }
223
224 /**
225 * Returns true if this entry targets the secure physical address
226 * map.
227 */
228 bool secure(bool have_security, WalkerState *currState) const
229 {
230 if (have_security) {
231 if (type() == PageTable)
232 return !bits(data, 3);
233 else
234 return !bits(data, 19);
235 }
236 return false;
237 }
238 };
239
240 /** Level 2 page table descriptor */
241 class L2Descriptor : public DescriptorBase {
242 public:
243 /** The raw bits of the entry. */
244 uint32_t data;
245 L1Descriptor *l1Parent;
246
247 /** This entry has been modified (access flag set) and needs to be
248 * written back to memory */
249 bool _dirty;
250
251 /** Default ctor */
252 L2Descriptor() : data(0), l1Parent(nullptr), _dirty(false)
253 {
254 lookupLevel = L2;
255 }
256
257 L2Descriptor(L1Descriptor &parent) : data(0), l1Parent(&parent),
258 _dirty(false)
259 {
260 lookupLevel = L2;
261 }
262
263 virtual uint64_t getRawData() const
264 {
265 return (data);
266 }
267
268 virtual std::string dbgHeader() const
269 {
270 return "Inserting L2 Descriptor into TLB\n";
271 }
272
273 virtual TlbEntry::DomainType domain() const
274 {
275 return l1Parent->domain();
276 }
277
278 bool secure(bool have_security, WalkerState *currState) const
279 {
280 return l1Parent->secure(have_security, currState);
281 }
282
283 virtual uint8_t offsetBits() const
284 {
285 return large() ? 16 : 12;
286 }
287
288 /** Is the entry invalid */
289 bool invalid() const
290 {
291 return bits(data, 1, 0) == 0;
292 }
293
294 /** What is the size of the mapping? */
295 bool large() const
296 {
297 return bits(data, 1) == 0;
298 }
299
300 /** Is execution allowed on this mapping? */
301 bool xn() const
302 {
303 return large() ? bits(data, 15) : bits(data, 0);
304 }
305
306 /** Is the translation global (no asid used)? */
307 bool global(WalkerState *currState) const
308 {
309 return !bits(data, 11);
310 }
311
312 /** Three bit access protection flags */
313 uint8_t ap() const
314 {
315 return bits(data, 5, 4) | (bits(data, 9) << 2);
316 }
317
318 /** Memory region attributes: ARM DDI 0406B: B3-32 */
319 uint8_t texcb() const
320 {
321 return large() ?
322 (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 14, 12) << 2)) :
323 (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 8, 6) << 2));
324 }
325
326 /** Return the physical frame, bits shifted right */
327 Addr pfn() const
328 {
329 return large() ? bits(data, 31, 16) : bits(data, 31, 12);
330 }
331
332 /** Return complete physical address given a VA */
333 Addr paddr(Addr va) const
334 {
335 if (large())
336 return mbits(data, 31, 16) | mbits(va, 15, 0);
337 else
338 return mbits(data, 31, 12) | mbits(va, 11, 0);
339 }
340
341 /** If the section is shareable. See texcb() comment. */
342 bool shareable() const
343 {
344 return bits(data, 10);
345 }
346
347 /** Set access flag that this entry has been touched. Mark
348 * the entry as requiring a writeback, in the future.
349 */
350 void setAp0()
351 {
352 data |= 1 << 4;
353 _dirty = true;
354 }
355
356 /** This entry needs to be written back to memory */
357 bool dirty() const
358 {
359 return _dirty;
360 }
361
362 };
363
364 // Granule sizes for AArch64 long descriptors
365 enum GrainSize {
366 Grain4KB = 12,
367 Grain16KB = 14,
368 Grain64KB = 16,
369 ReservedGrain = 0
370 };
371
372 /** Long-descriptor format (LPAE) */
373 class LongDescriptor : public DescriptorBase {
374 public:
375 /** Descriptor type */
376 enum EntryType {
377 Invalid,
378 Table,
379 Block,
380 Page
381 };
382
383 /** The raw bits of the entry */
384 uint64_t data;
385
386 /** This entry has been modified (access flag set) and needs to be
387 * written back to memory */
388 bool _dirty;
389
390 virtual uint64_t getRawData() const
391 {
392 return (data);
393 }
394
395 virtual std::string dbgHeader() const
396 {
397 if (type() == LongDescriptor::Page) {
398 assert(lookupLevel == L3);
399 return "Inserting Page descriptor into TLB\n";
400 } else {
401 assert(lookupLevel < L3);
402 return "Inserting Block descriptor into TLB\n";
403 }
404 }
405
406 /**
407 * Returns true if this entry targets the secure physical address
408 * map.
409 */
410 bool secure(bool have_security, WalkerState *currState) const
411 {
412 assert(type() == Block || type() == Page);
413 return have_security && (currState->secureLookup && !bits(data, 5));
414 }
415
416 /** True if the current lookup is performed in AArch64 state */
417 bool aarch64;
418
419 /** Width of the granule size in bits */
420 GrainSize grainSize;
421
422 /** Return the descriptor type */
423 EntryType type() const
424 {
425 switch (bits(data, 1, 0)) {
426 case 0x1:
427 // In AArch64 blocks are not allowed at L0 for the 4 KB granule
428 // and at L1 for 16/64 KB granules
429 if (grainSize > Grain4KB)
430 return lookupLevel == L2 ? Block : Invalid;
431 return lookupLevel == L0 || lookupLevel == L3 ? Invalid : Block;
432 case 0x3:
433 return lookupLevel == L3 ? Page : Table;
434 default:
435 return Invalid;
436 }
437 }
438
439 /** Return the bit width of the page/block offset */
440 uint8_t offsetBits() const
441 {
442 if (type() == Block) {
443 switch (grainSize) {
444 case Grain4KB:
445 return lookupLevel == L1 ? 30 /* 1 GB */
446 : 21 /* 2 MB */;
447 case Grain16KB:
448 return 25 /* 32 MB */;
449 case Grain64KB:
450 return 29 /* 512 MB */;
451 default:
452 panic("Invalid AArch64 VM granule size\n");
453 }
454 } else if (type() == Page) {
455 switch (grainSize) {
456 case Grain4KB:
457 case Grain16KB:
458 case Grain64KB:
459 return grainSize; /* enum -> uint okay */
460 default:
461 panic("Invalid AArch64 VM granule size\n");
462 }
463 } else {
464 panic("AArch64 page table entry must be block or page\n");
465 }
466 }
467
468 /** Return the physical frame, bits shifted right */
469 Addr pfn() const
470 {
471 if (aarch64)
472 return bits(data, 47, offsetBits());
473 return bits(data, 39, offsetBits());
474 }
475
476 /** Return the complete physical address given a VA */
477 Addr paddr(Addr va) const
478 {
479 int n = offsetBits();
480 if (aarch64)
481 return mbits(data, 47, n) | mbits(va, n - 1, 0);
482 return mbits(data, 39, n) | mbits(va, n - 1, 0);
483 }
484
485 /** Return the physical address of the entry */
486 Addr paddr() const
487 {
488 if (aarch64)
489 return mbits(data, 47, offsetBits());
490 return mbits(data, 39, offsetBits());
491 }
492
493 /** Return the address of the next page table */
494 Addr nextTableAddr() const
495 {
496 assert(type() == Table);
497 if (aarch64)
498 return mbits(data, 47, grainSize);
499 else
500 return mbits(data, 39, 12);
501 }
502
503 /** Return the address of the next descriptor */
504 Addr nextDescAddr(Addr va) const
505 {
506 assert(type() == Table);
507 Addr pa = 0;
508 if (aarch64) {
509 int stride = grainSize - 3;
510 int va_lo = stride * (3 - (lookupLevel + 1)) + grainSize;
511 int va_hi = va_lo + stride - 1;
512 pa = nextTableAddr() | (bits(va, va_hi, va_lo) << 3);
513 } else {
514 if (lookupLevel == L1)
515 pa = nextTableAddr() | (bits(va, 29, 21) << 3);
516 else // lookupLevel == L2
517 pa = nextTableAddr() | (bits(va, 20, 12) << 3);
518 }
519 return pa;
520 }
521
522 /** Is execution allowed on this mapping? */
523 bool xn() const
524 {
525 assert(type() == Block || type() == Page);
526 return bits(data, 54);
527 }
528
529 /** Is privileged execution allowed on this mapping? (LPAE only) */
530 bool pxn() const
531 {
532 assert(type() == Block || type() == Page);
533 return bits(data, 53);
534 }
535
536 /** Contiguous hint bit. */
537 bool contiguousHint() const
538 {
539 assert(type() == Block || type() == Page);
540 return bits(data, 52);
541 }
542
543 /** Is the translation global (no asid used)? */
544 bool global(WalkerState *currState) const
545 {
546 assert(currState && (type() == Block || type() == Page));
547 if (!currState->aarch64 && (currState->isSecure &&
548 !currState->secureLookup)) {
549 return false; // ARM ARM issue C B3.6.3
550 } else if (currState->aarch64) {
551 if (currState->el == EL2 || currState->el == EL3) {
552 return true; // By default translations are treated as global
553 // in AArch64 EL2 and EL3
554 } else if (currState->isSecure && !currState->secureLookup) {
555 return false;
556 }
557 }
558 return !bits(data, 11);
559 }
560
561 /** Returns true if the access flag (AF) is set. */
562 bool af() const
563 {
564 assert(type() == Block || type() == Page);
565 return bits(data, 10);
566 }
567
568 /** 2-bit shareability field */
569 uint8_t sh() const
570 {
571 assert(type() == Block || type() == Page);
572 return bits(data, 9, 8);
573 }
574
575 /** 2-bit access protection flags */
576 uint8_t ap() const
577 {
578 assert(type() == Block || type() == Page);
579 // Long descriptors only support the AP[2:1] scheme
580 return bits(data, 7, 6);
581 }
582
583 /** Read/write access protection flag */
584 bool rw() const
585 {
586 assert(type() == Block || type() == Page);
587 return !bits(data, 7);
588 }
589
590 /** User/privileged level access protection flag */
591 bool user() const
592 {
593 assert(type() == Block || type() == Page);
594 return bits(data, 6);
595 }
596
597 /** Return the AP bits as compatible with the AP[2:0] format. Utility
598 * function used to simplify the code in the TLB for performing
599 * permission checks. */
600 static uint8_t ap(bool rw, bool user)
601 {
602 return ((!rw) << 2) | (user << 1);
603 }
604
605 TlbEntry::DomainType domain() const
606 {
607 // Long-desc. format only supports Client domain
608 assert(type() == Block || type() == Page);
609 return TlbEntry::DomainType::Client;
610 }
611
612 /** Attribute index */
613 uint8_t attrIndx() const
614 {
615 assert(type() == Block || type() == Page);
616 return bits(data, 4, 2);
617 }
618
619 /** Memory attributes, only used by stage 2 translations */
620 uint8_t memAttr() const
621 {
622 assert(type() == Block || type() == Page);
623 return bits(data, 5, 2);
624 }
625
626 /** Set access flag that this entry has been touched. Mark the entry as
627 * requiring a writeback, in the future. */
628 void setAf()
629 {
630 data |= 1 << 10;
631 _dirty = true;
632 }
633
634 /** This entry needs to be written back to memory */
635 bool dirty() const
636 {
637 return _dirty;
638 }
639
640 /** Whether the subsequent levels of lookup are secure */
641 bool secureTable() const
642 {
643 assert(type() == Table);
644 return !bits(data, 63);
645 }
646
647 /** Two bit access protection flags for subsequent levels of lookup */
648 uint8_t apTable() const
649 {
650 assert(type() == Table);
651 return bits(data, 62, 61);
652 }
653
654 /** R/W protection flag for subsequent levels of lookup */
655 uint8_t rwTable() const
656 {
657 assert(type() == Table);
658 return !bits(data, 62);
659 }
660
661 /** User/privileged mode protection flag for subsequent levels of
662 * lookup */
663 uint8_t userTable() const
664 {
665 assert(type() == Table);
666 return !bits(data, 61);
667 }
668
669 /** Is execution allowed on subsequent lookup levels? */
670 bool xnTable() const
671 {
672 assert(type() == Table);
673 return bits(data, 60);
674 }
675
676 /** Is privileged execution allowed on subsequent lookup levels? */
677 bool pxnTable() const
678 {
679 assert(type() == Table);
680 return bits(data, 59);
681 }
682 };
683
684 class WalkerState
685 {
686 public:
687 /** Thread context that we're doing the walk for */
688 ThreadContext *tc;
689
690 /** If the access is performed in AArch64 state */
691 bool aarch64;
692
693 /** Current exception level */
694 ExceptionLevel el;
695
696 /** Current physical address range in bits */
697 int physAddrRange;
698
699 /** Request that is currently being serviced */
700 RequestPtr req;
701
702 /** ASID that we're servicing the request under */
703 uint16_t asid;
704 uint8_t vmid;
705 bool isHyp;
706
707 /** Translation state for delayed requests */
708 TLB::Translation *transState;
709
710 /** The fault that we are going to return */
711 Fault fault;
712
713 /** The virtual address that is being translated with tagging removed.*/
714 Addr vaddr;
715
716 /** The virtual address that is being translated */
717 Addr vaddr_tainted;
718
719 /** Cached copy of the sctlr as it existed when translation began */
720 SCTLR sctlr;
721
722 /** Cached copy of the scr as it existed when translation began */
723 SCR scr;
724
725 /** Cached copy of the cpsr as it existed when translation began */
726 CPSR cpsr;
727
728 /** Cached copy of ttbcr/tcr as it existed when translation began */
729 union {
730 TTBCR ttbcr; // AArch32 translations
731 TCR tcr; // AArch64 translations
732 };
733
734 /** Cached copy of the htcr as it existed when translation began. */
735 HTCR htcr;
736
737 /** Cached copy of the htcr as it existed when translation began. */
738 HCR hcr;
739
740 /** Cached copy of the vtcr as it existed when translation began. */
741 VTCR_t vtcr;
742
743 /** If the access is a write */
744 bool isWrite;
745
746 /** If the access is a fetch (for execution, and no-exec) must be checked?*/
747 bool isFetch;
748
749 /** If the access comes from the secure state. */
750 bool isSecure;
751
752 /** Helper variables used to implement hierarchical access permissions
753 * when the long-desc. format is used (LPAE only) */
754 bool secureLookup;
755 bool rwTable;
756 bool userTable;
757 bool xnTable;
758 bool pxnTable;
759
760 /** Flag indicating if a second stage of lookup is required */
761 bool stage2Req;
762
763 /** Indicates whether the translation has been passed onto the second
764 * stage mmu, and no more work is required from the first stage.
765 */
766 bool doingStage2;
767
768 /** A pointer to the stage 2 translation that's in progress */
769 TLB::Translation *stage2Tran;
770
771 /** If the mode is timing or atomic */
772 bool timing;
773
774 /** If the atomic mode should be functional */
775 bool functional;
776
777 /** Save mode for use in delayed response */
778 BaseTLB::Mode mode;
779
780 /** The translation type that has been requested */
781 TLB::ArmTranslationType tranType;
782
783 /** Short-format descriptors */
784 L1Descriptor l1Desc;
785 L2Descriptor l2Desc;
786
787 /** Long-format descriptor (LPAE and AArch64) */
788 LongDescriptor longDesc;
789
790 /** Whether the response is delayed in timing mode due to additional
791 * lookups */
792 bool delayed;
793
794 TableWalker *tableWalker;
795
796 /** Timestamp for calculating elapsed time in service (for stats) */
797 Tick startTime;
798
799 /** Page entries walked during service (for stats) */
800 unsigned levels;
801
802 void doL1Descriptor();
803 void doL2Descriptor();
804
805 void doLongDescriptor();
806
807 WalkerState();
808
809 std::string name() const { return tableWalker->name(); }
810 };
811
812 protected:
813
814 /** Queues of requests for all the different lookup levels */
815 std::list<WalkerState *> stateQueues[MAX_LOOKUP_LEVELS];
816
817 /** Queue of requests that have passed are waiting because the walker is
818 * currently busy. */
819 std::list<WalkerState *> pendingQueue;
820
821 /** If we're draining keep the drain event around until we're drained */
822 DrainManager *drainManager;
823
824 /** The MMU to forward second stage look upts to */
825 Stage2MMU *stage2Mmu;
826
827 /** Port shared by the two table walkers. */
828 DmaPort* port;
829
830 /** Master id assigned by the MMU. */
831 MasterID masterId;
832
833 /** Indicates whether this table walker is part of the stage 2 mmu */
834 const bool isStage2;
835
836 /** TLB that is initiating these table walks */
837 TLB *tlb;
838
839 /** Cached copy of the sctlr as it existed when translation began */
840 SCTLR sctlr;
841
842 WalkerState *currState;
843
844 /** If a timing translation is currently in progress */
845 bool pending;
846
847 /** The number of walks belonging to squashed instructions that can be
848 * removed from the pendingQueue per cycle. */
849 unsigned numSquashable;
850
851 /** Cached copies of system-level properties */
852 bool haveSecurity;
853 bool _haveLPAE;
854 bool _haveVirtualization;
855 uint8_t physAddrRange;
856 bool _haveLargeAsid64;
857
858 /** Statistics */
859 Stats::Scalar statWalks;
860 Stats::Scalar statWalksShortDescriptor;
861 Stats::Scalar statWalksLongDescriptor;
862 Stats::Vector statWalksShortTerminatedAtLevel;
863 Stats::Vector statWalksLongTerminatedAtLevel;
864 Stats::Scalar statSquashedBefore;
865 Stats::Scalar statSquashedAfter;
866 Stats::Histogram statWalkWaitTime;
867 Stats::Histogram statWalkServiceTime;
868 Stats::Histogram statPendingWalks; // essentially "L" of queueing theory
869 Stats::Vector statPageSizes;
870 Stats::Vector2d statRequestOrigin;
871
872 mutable unsigned pendingReqs;
873 mutable Tick pendingChangeTick;
874
875 static const unsigned REQUESTED = 0;
876 static const unsigned COMPLETED = 1;
877
878 public:
879 typedef ArmTableWalkerParams Params;
880 TableWalker(const Params *p);
881 virtual ~TableWalker();
882
883 const Params *
884 params() const
885 {
886 return dynamic_cast<const Params *>(_params);
887 }
888
889 virtual void init();
890
891 bool haveLPAE() const { return _haveLPAE; }
892 bool haveVirtualization() const { return _haveVirtualization; }
893 bool haveLargeAsid64() const { return _haveLargeAsid64; }
894 /** Checks if all state is cleared and if so, completes drain */
895 void completeDrain();
896 unsigned int drain(DrainManager *dm);
897 virtual void drainResume();
898
899 virtual BaseMasterPort& getMasterPort(const std::string &if_name,
900 PortID idx = InvalidPortID);
901
902 void regStats();
903
904 Fault walk(RequestPtr req, ThreadContext *tc, uint16_t asid, uint8_t _vmid,
905 bool _isHyp, TLB::Mode mode, TLB::Translation *_trans,
906 bool timing, bool functional, bool secure,
907 TLB::ArmTranslationType tranType);
908
909 void setTlb(TLB *_tlb) { tlb = _tlb; }
910 TLB* getTlb() { return tlb; }
911 void setMMU(Stage2MMU *m, MasterID master_id);
912 void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr,
913 uint8_t texcb, bool s);
914 void memAttrsLPAE(ThreadContext *tc, TlbEntry &te,
915 LongDescriptor &lDescriptor);
916 void memAttrsAArch64(ThreadContext *tc, TlbEntry &te, uint8_t attrIndx,
917 uint8_t sh);
918
919 static LookupLevel toLookupLevel(uint8_t lookup_level_as_int);
920
921 private:
922
923 void doL1Descriptor();
924 void doL1DescriptorWrapper();
925 EventWrapper<TableWalker,
926 &TableWalker::doL1DescriptorWrapper> doL1DescEvent;
927
928 void doL2Descriptor();
929 void doL2DescriptorWrapper();
930 EventWrapper<TableWalker,
931 &TableWalker::doL2DescriptorWrapper> doL2DescEvent;
932
933 void doLongDescriptor();
934
935 void doL0LongDescriptorWrapper();
936 EventWrapper<TableWalker,
937 &TableWalker::doL0LongDescriptorWrapper> doL0LongDescEvent;
938 void doL1LongDescriptorWrapper();
939 EventWrapper<TableWalker,
940 &TableWalker::doL1LongDescriptorWrapper> doL1LongDescEvent;
941 void doL2LongDescriptorWrapper();
942 EventWrapper<TableWalker,
943 &TableWalker::doL2LongDescriptorWrapper> doL2LongDescEvent;
944 void doL3LongDescriptorWrapper();
945 EventWrapper<TableWalker,
946 &TableWalker::doL3LongDescriptorWrapper> doL3LongDescEvent;
947
948 void doLongDescriptorWrapper(LookupLevel curr_lookup_level);
949
950 bool fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes,
951 Request::Flags flags, int queueIndex, Event *event,
952 void (TableWalker::*doDescriptor)());
953
954 void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor);
955
956 Fault processWalk();
957 Fault processWalkLPAE();
958 static unsigned adjustTableSizeAArch64(unsigned tsz);
959 /// Returns true if the address exceeds the range permitted by the
960 /// system-wide setting or by the TCR_ELx IPS/PS setting
961 static bool checkAddrSizeFaultAArch64(Addr addr, int currPhysAddrRange);
962 Fault processWalkAArch64();
963 void processWalkWrapper();
964 EventWrapper<TableWalker, &TableWalker::processWalkWrapper> doProcessEvent;
965
966 void nextWalk(ThreadContext *tc);
967
968 void pendingChange();
969
970 static uint8_t pageSizeNtoStatBin(uint8_t N);
971};
972
973} // namespace ArmISA
974
975#endif //__ARCH_ARM_TABLE_WALKER_HH__
976
57namespace ArmISA {
58class Translation;
59class TLB;
60class Stage2MMU;
61
62class TableWalker : public MemObject
63{
64 public:
65 class WalkerState;
66
67 class DescriptorBase {
68 public:
69 /** Current lookup level for this descriptor */
70 LookupLevel lookupLevel;
71
72 virtual Addr pfn() const = 0;
73 virtual TlbEntry::DomainType domain() const = 0;
74 virtual bool xn() const = 0;
75 virtual uint8_t ap() const = 0;
76 virtual bool global(WalkerState *currState) const = 0;
77 virtual uint8_t offsetBits() const = 0;
78 virtual bool secure(bool have_security, WalkerState *currState) const = 0;
79 virtual std::string dbgHeader() const = 0;
80 virtual uint64_t getRawData() const = 0;
81 virtual uint8_t texcb() const
82 {
83 panic("texcb() not implemented for this class\n");
84 }
85 virtual bool shareable() const
86 {
87 panic("shareable() not implemented for this class\n");
88 }
89 };
90
91 class L1Descriptor : public DescriptorBase {
92 public:
93 /** Type of page table entry ARM DDI 0406B: B3-8*/
94 enum EntryType {
95 Ignore,
96 PageTable,
97 Section,
98 Reserved
99 };
100
101 /** The raw bits of the entry */
102 uint32_t data;
103
104 /** This entry has been modified (access flag set) and needs to be
105 * written back to memory */
106 bool _dirty;
107
108 /** Default ctor */
109 L1Descriptor() : data(0), _dirty(false)
110 {
111 lookupLevel = L1;
112 }
113
114 virtual uint64_t getRawData() const
115 {
116 return (data);
117 }
118
119 virtual std::string dbgHeader() const
120 {
121 return "Inserting Section Descriptor into TLB\n";
122 }
123
124 virtual uint8_t offsetBits() const
125 {
126 return 20;
127 }
128
129 EntryType type() const
130 {
131 return (EntryType)(data & 0x3);
132 }
133
134 /** Is the page a Supersection (16MB)?*/
135 bool supersection() const
136 {
137 return bits(data, 18);
138 }
139
140 /** Return the physcal address of the entry, bits in position*/
141 Addr paddr() const
142 {
143 if (supersection())
144 panic("Super sections not implemented\n");
145 return mbits(data, 31, 20);
146 }
147 /** Return the physcal address of the entry, bits in position*/
148 Addr paddr(Addr va) const
149 {
150 if (supersection())
151 panic("Super sections not implemented\n");
152 return mbits(data, 31, 20) | mbits(va, 19, 0);
153 }
154
155
156 /** Return the physical frame, bits shifted right */
157 Addr pfn() const
158 {
159 if (supersection())
160 panic("Super sections not implemented\n");
161 return bits(data, 31, 20);
162 }
163
164 /** Is the translation global (no asid used)? */
165 bool global(WalkerState *currState) const
166 {
167 return !bits(data, 17);
168 }
169
170 /** Is the translation not allow execution? */
171 bool xn() const
172 {
173 return bits(data, 4);
174 }
175
176 /** Three bit access protection flags */
177 uint8_t ap() const
178 {
179 return (bits(data, 15) << 2) | bits(data, 11, 10);
180 }
181
182 /** Domain Client/Manager: ARM DDI 0406B: B3-31 */
183 TlbEntry::DomainType domain() const
184 {
185 return static_cast<TlbEntry::DomainType>(bits(data, 8, 5));
186 }
187
188 /** Address of L2 descriptor if it exists */
189 Addr l2Addr() const
190 {
191 return mbits(data, 31, 10);
192 }
193
194 /** Memory region attributes: ARM DDI 0406B: B3-32.
195 * These bits are largly ignored by M5 and only used to
196 * provide the illusion that the memory system cares about
197 * anything but cachable vs. uncachable.
198 */
199 uint8_t texcb() const
200 {
201 return bits(data, 2) | bits(data, 3) << 1 | bits(data, 14, 12) << 2;
202 }
203
204 /** If the section is shareable. See texcb() comment. */
205 bool shareable() const
206 {
207 return bits(data, 16);
208 }
209
210 /** Set access flag that this entry has been touched. Mark
211 * the entry as requiring a writeback, in the future.
212 */
213 void setAp0()
214 {
215 data |= 1 << 10;
216 _dirty = true;
217 }
218
219 /** This entry needs to be written back to memory */
220 bool dirty() const
221 {
222 return _dirty;
223 }
224
225 /**
226 * Returns true if this entry targets the secure physical address
227 * map.
228 */
229 bool secure(bool have_security, WalkerState *currState) const
230 {
231 if (have_security) {
232 if (type() == PageTable)
233 return !bits(data, 3);
234 else
235 return !bits(data, 19);
236 }
237 return false;
238 }
239 };
240
241 /** Level 2 page table descriptor */
242 class L2Descriptor : public DescriptorBase {
243 public:
244 /** The raw bits of the entry. */
245 uint32_t data;
246 L1Descriptor *l1Parent;
247
248 /** This entry has been modified (access flag set) and needs to be
249 * written back to memory */
250 bool _dirty;
251
252 /** Default ctor */
253 L2Descriptor() : data(0), l1Parent(nullptr), _dirty(false)
254 {
255 lookupLevel = L2;
256 }
257
258 L2Descriptor(L1Descriptor &parent) : data(0), l1Parent(&parent),
259 _dirty(false)
260 {
261 lookupLevel = L2;
262 }
263
264 virtual uint64_t getRawData() const
265 {
266 return (data);
267 }
268
269 virtual std::string dbgHeader() const
270 {
271 return "Inserting L2 Descriptor into TLB\n";
272 }
273
274 virtual TlbEntry::DomainType domain() const
275 {
276 return l1Parent->domain();
277 }
278
279 bool secure(bool have_security, WalkerState *currState) const
280 {
281 return l1Parent->secure(have_security, currState);
282 }
283
284 virtual uint8_t offsetBits() const
285 {
286 return large() ? 16 : 12;
287 }
288
289 /** Is the entry invalid */
290 bool invalid() const
291 {
292 return bits(data, 1, 0) == 0;
293 }
294
295 /** What is the size of the mapping? */
296 bool large() const
297 {
298 return bits(data, 1) == 0;
299 }
300
301 /** Is execution allowed on this mapping? */
302 bool xn() const
303 {
304 return large() ? bits(data, 15) : bits(data, 0);
305 }
306
307 /** Is the translation global (no asid used)? */
308 bool global(WalkerState *currState) const
309 {
310 return !bits(data, 11);
311 }
312
313 /** Three bit access protection flags */
314 uint8_t ap() const
315 {
316 return bits(data, 5, 4) | (bits(data, 9) << 2);
317 }
318
319 /** Memory region attributes: ARM DDI 0406B: B3-32 */
320 uint8_t texcb() const
321 {
322 return large() ?
323 (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 14, 12) << 2)) :
324 (bits(data, 2) | (bits(data, 3) << 1) | (bits(data, 8, 6) << 2));
325 }
326
327 /** Return the physical frame, bits shifted right */
328 Addr pfn() const
329 {
330 return large() ? bits(data, 31, 16) : bits(data, 31, 12);
331 }
332
333 /** Return complete physical address given a VA */
334 Addr paddr(Addr va) const
335 {
336 if (large())
337 return mbits(data, 31, 16) | mbits(va, 15, 0);
338 else
339 return mbits(data, 31, 12) | mbits(va, 11, 0);
340 }
341
342 /** If the section is shareable. See texcb() comment. */
343 bool shareable() const
344 {
345 return bits(data, 10);
346 }
347
348 /** Set access flag that this entry has been touched. Mark
349 * the entry as requiring a writeback, in the future.
350 */
351 void setAp0()
352 {
353 data |= 1 << 4;
354 _dirty = true;
355 }
356
357 /** This entry needs to be written back to memory */
358 bool dirty() const
359 {
360 return _dirty;
361 }
362
363 };
364
365 // Granule sizes for AArch64 long descriptors
366 enum GrainSize {
367 Grain4KB = 12,
368 Grain16KB = 14,
369 Grain64KB = 16,
370 ReservedGrain = 0
371 };
372
373 /** Long-descriptor format (LPAE) */
374 class LongDescriptor : public DescriptorBase {
375 public:
376 /** Descriptor type */
377 enum EntryType {
378 Invalid,
379 Table,
380 Block,
381 Page
382 };
383
384 /** The raw bits of the entry */
385 uint64_t data;
386
387 /** This entry has been modified (access flag set) and needs to be
388 * written back to memory */
389 bool _dirty;
390
391 virtual uint64_t getRawData() const
392 {
393 return (data);
394 }
395
396 virtual std::string dbgHeader() const
397 {
398 if (type() == LongDescriptor::Page) {
399 assert(lookupLevel == L3);
400 return "Inserting Page descriptor into TLB\n";
401 } else {
402 assert(lookupLevel < L3);
403 return "Inserting Block descriptor into TLB\n";
404 }
405 }
406
407 /**
408 * Returns true if this entry targets the secure physical address
409 * map.
410 */
411 bool secure(bool have_security, WalkerState *currState) const
412 {
413 assert(type() == Block || type() == Page);
414 return have_security && (currState->secureLookup && !bits(data, 5));
415 }
416
417 /** True if the current lookup is performed in AArch64 state */
418 bool aarch64;
419
420 /** Width of the granule size in bits */
421 GrainSize grainSize;
422
423 /** Return the descriptor type */
424 EntryType type() const
425 {
426 switch (bits(data, 1, 0)) {
427 case 0x1:
428 // In AArch64 blocks are not allowed at L0 for the 4 KB granule
429 // and at L1 for 16/64 KB granules
430 if (grainSize > Grain4KB)
431 return lookupLevel == L2 ? Block : Invalid;
432 return lookupLevel == L0 || lookupLevel == L3 ? Invalid : Block;
433 case 0x3:
434 return lookupLevel == L3 ? Page : Table;
435 default:
436 return Invalid;
437 }
438 }
439
440 /** Return the bit width of the page/block offset */
441 uint8_t offsetBits() const
442 {
443 if (type() == Block) {
444 switch (grainSize) {
445 case Grain4KB:
446 return lookupLevel == L1 ? 30 /* 1 GB */
447 : 21 /* 2 MB */;
448 case Grain16KB:
449 return 25 /* 32 MB */;
450 case Grain64KB:
451 return 29 /* 512 MB */;
452 default:
453 panic("Invalid AArch64 VM granule size\n");
454 }
455 } else if (type() == Page) {
456 switch (grainSize) {
457 case Grain4KB:
458 case Grain16KB:
459 case Grain64KB:
460 return grainSize; /* enum -> uint okay */
461 default:
462 panic("Invalid AArch64 VM granule size\n");
463 }
464 } else {
465 panic("AArch64 page table entry must be block or page\n");
466 }
467 }
468
469 /** Return the physical frame, bits shifted right */
470 Addr pfn() const
471 {
472 if (aarch64)
473 return bits(data, 47, offsetBits());
474 return bits(data, 39, offsetBits());
475 }
476
477 /** Return the complete physical address given a VA */
478 Addr paddr(Addr va) const
479 {
480 int n = offsetBits();
481 if (aarch64)
482 return mbits(data, 47, n) | mbits(va, n - 1, 0);
483 return mbits(data, 39, n) | mbits(va, n - 1, 0);
484 }
485
486 /** Return the physical address of the entry */
487 Addr paddr() const
488 {
489 if (aarch64)
490 return mbits(data, 47, offsetBits());
491 return mbits(data, 39, offsetBits());
492 }
493
494 /** Return the address of the next page table */
495 Addr nextTableAddr() const
496 {
497 assert(type() == Table);
498 if (aarch64)
499 return mbits(data, 47, grainSize);
500 else
501 return mbits(data, 39, 12);
502 }
503
504 /** Return the address of the next descriptor */
505 Addr nextDescAddr(Addr va) const
506 {
507 assert(type() == Table);
508 Addr pa = 0;
509 if (aarch64) {
510 int stride = grainSize - 3;
511 int va_lo = stride * (3 - (lookupLevel + 1)) + grainSize;
512 int va_hi = va_lo + stride - 1;
513 pa = nextTableAddr() | (bits(va, va_hi, va_lo) << 3);
514 } else {
515 if (lookupLevel == L1)
516 pa = nextTableAddr() | (bits(va, 29, 21) << 3);
517 else // lookupLevel == L2
518 pa = nextTableAddr() | (bits(va, 20, 12) << 3);
519 }
520 return pa;
521 }
522
523 /** Is execution allowed on this mapping? */
524 bool xn() const
525 {
526 assert(type() == Block || type() == Page);
527 return bits(data, 54);
528 }
529
530 /** Is privileged execution allowed on this mapping? (LPAE only) */
531 bool pxn() const
532 {
533 assert(type() == Block || type() == Page);
534 return bits(data, 53);
535 }
536
537 /** Contiguous hint bit. */
538 bool contiguousHint() const
539 {
540 assert(type() == Block || type() == Page);
541 return bits(data, 52);
542 }
543
544 /** Is the translation global (no asid used)? */
545 bool global(WalkerState *currState) const
546 {
547 assert(currState && (type() == Block || type() == Page));
548 if (!currState->aarch64 && (currState->isSecure &&
549 !currState->secureLookup)) {
550 return false; // ARM ARM issue C B3.6.3
551 } else if (currState->aarch64) {
552 if (currState->el == EL2 || currState->el == EL3) {
553 return true; // By default translations are treated as global
554 // in AArch64 EL2 and EL3
555 } else if (currState->isSecure && !currState->secureLookup) {
556 return false;
557 }
558 }
559 return !bits(data, 11);
560 }
561
562 /** Returns true if the access flag (AF) is set. */
563 bool af() const
564 {
565 assert(type() == Block || type() == Page);
566 return bits(data, 10);
567 }
568
569 /** 2-bit shareability field */
570 uint8_t sh() const
571 {
572 assert(type() == Block || type() == Page);
573 return bits(data, 9, 8);
574 }
575
576 /** 2-bit access protection flags */
577 uint8_t ap() const
578 {
579 assert(type() == Block || type() == Page);
580 // Long descriptors only support the AP[2:1] scheme
581 return bits(data, 7, 6);
582 }
583
584 /** Read/write access protection flag */
585 bool rw() const
586 {
587 assert(type() == Block || type() == Page);
588 return !bits(data, 7);
589 }
590
591 /** User/privileged level access protection flag */
592 bool user() const
593 {
594 assert(type() == Block || type() == Page);
595 return bits(data, 6);
596 }
597
598 /** Return the AP bits as compatible with the AP[2:0] format. Utility
599 * function used to simplify the code in the TLB for performing
600 * permission checks. */
601 static uint8_t ap(bool rw, bool user)
602 {
603 return ((!rw) << 2) | (user << 1);
604 }
605
606 TlbEntry::DomainType domain() const
607 {
608 // Long-desc. format only supports Client domain
609 assert(type() == Block || type() == Page);
610 return TlbEntry::DomainType::Client;
611 }
612
613 /** Attribute index */
614 uint8_t attrIndx() const
615 {
616 assert(type() == Block || type() == Page);
617 return bits(data, 4, 2);
618 }
619
620 /** Memory attributes, only used by stage 2 translations */
621 uint8_t memAttr() const
622 {
623 assert(type() == Block || type() == Page);
624 return bits(data, 5, 2);
625 }
626
627 /** Set access flag that this entry has been touched. Mark the entry as
628 * requiring a writeback, in the future. */
629 void setAf()
630 {
631 data |= 1 << 10;
632 _dirty = true;
633 }
634
635 /** This entry needs to be written back to memory */
636 bool dirty() const
637 {
638 return _dirty;
639 }
640
641 /** Whether the subsequent levels of lookup are secure */
642 bool secureTable() const
643 {
644 assert(type() == Table);
645 return !bits(data, 63);
646 }
647
648 /** Two bit access protection flags for subsequent levels of lookup */
649 uint8_t apTable() const
650 {
651 assert(type() == Table);
652 return bits(data, 62, 61);
653 }
654
655 /** R/W protection flag for subsequent levels of lookup */
656 uint8_t rwTable() const
657 {
658 assert(type() == Table);
659 return !bits(data, 62);
660 }
661
662 /** User/privileged mode protection flag for subsequent levels of
663 * lookup */
664 uint8_t userTable() const
665 {
666 assert(type() == Table);
667 return !bits(data, 61);
668 }
669
670 /** Is execution allowed on subsequent lookup levels? */
671 bool xnTable() const
672 {
673 assert(type() == Table);
674 return bits(data, 60);
675 }
676
677 /** Is privileged execution allowed on subsequent lookup levels? */
678 bool pxnTable() const
679 {
680 assert(type() == Table);
681 return bits(data, 59);
682 }
683 };
684
685 class WalkerState
686 {
687 public:
688 /** Thread context that we're doing the walk for */
689 ThreadContext *tc;
690
691 /** If the access is performed in AArch64 state */
692 bool aarch64;
693
694 /** Current exception level */
695 ExceptionLevel el;
696
697 /** Current physical address range in bits */
698 int physAddrRange;
699
700 /** Request that is currently being serviced */
701 RequestPtr req;
702
703 /** ASID that we're servicing the request under */
704 uint16_t asid;
705 uint8_t vmid;
706 bool isHyp;
707
708 /** Translation state for delayed requests */
709 TLB::Translation *transState;
710
711 /** The fault that we are going to return */
712 Fault fault;
713
714 /** The virtual address that is being translated with tagging removed.*/
715 Addr vaddr;
716
717 /** The virtual address that is being translated */
718 Addr vaddr_tainted;
719
720 /** Cached copy of the sctlr as it existed when translation began */
721 SCTLR sctlr;
722
723 /** Cached copy of the scr as it existed when translation began */
724 SCR scr;
725
726 /** Cached copy of the cpsr as it existed when translation began */
727 CPSR cpsr;
728
729 /** Cached copy of ttbcr/tcr as it existed when translation began */
730 union {
731 TTBCR ttbcr; // AArch32 translations
732 TCR tcr; // AArch64 translations
733 };
734
735 /** Cached copy of the htcr as it existed when translation began. */
736 HTCR htcr;
737
738 /** Cached copy of the htcr as it existed when translation began. */
739 HCR hcr;
740
741 /** Cached copy of the vtcr as it existed when translation began. */
742 VTCR_t vtcr;
743
744 /** If the access is a write */
745 bool isWrite;
746
747 /** If the access is a fetch (for execution, and no-exec) must be checked?*/
748 bool isFetch;
749
750 /** If the access comes from the secure state. */
751 bool isSecure;
752
753 /** Helper variables used to implement hierarchical access permissions
754 * when the long-desc. format is used (LPAE only) */
755 bool secureLookup;
756 bool rwTable;
757 bool userTable;
758 bool xnTable;
759 bool pxnTable;
760
761 /** Flag indicating if a second stage of lookup is required */
762 bool stage2Req;
763
764 /** Indicates whether the translation has been passed onto the second
765 * stage mmu, and no more work is required from the first stage.
766 */
767 bool doingStage2;
768
769 /** A pointer to the stage 2 translation that's in progress */
770 TLB::Translation *stage2Tran;
771
772 /** If the mode is timing or atomic */
773 bool timing;
774
775 /** If the atomic mode should be functional */
776 bool functional;
777
778 /** Save mode for use in delayed response */
779 BaseTLB::Mode mode;
780
781 /** The translation type that has been requested */
782 TLB::ArmTranslationType tranType;
783
784 /** Short-format descriptors */
785 L1Descriptor l1Desc;
786 L2Descriptor l2Desc;
787
788 /** Long-format descriptor (LPAE and AArch64) */
789 LongDescriptor longDesc;
790
791 /** Whether the response is delayed in timing mode due to additional
792 * lookups */
793 bool delayed;
794
795 TableWalker *tableWalker;
796
797 /** Timestamp for calculating elapsed time in service (for stats) */
798 Tick startTime;
799
800 /** Page entries walked during service (for stats) */
801 unsigned levels;
802
803 void doL1Descriptor();
804 void doL2Descriptor();
805
806 void doLongDescriptor();
807
808 WalkerState();
809
810 std::string name() const { return tableWalker->name(); }
811 };
812
813 protected:
814
815 /** Queues of requests for all the different lookup levels */
816 std::list<WalkerState *> stateQueues[MAX_LOOKUP_LEVELS];
817
818 /** Queue of requests that have passed are waiting because the walker is
819 * currently busy. */
820 std::list<WalkerState *> pendingQueue;
821
822 /** If we're draining keep the drain event around until we're drained */
823 DrainManager *drainManager;
824
825 /** The MMU to forward second stage look upts to */
826 Stage2MMU *stage2Mmu;
827
828 /** Port shared by the two table walkers. */
829 DmaPort* port;
830
831 /** Master id assigned by the MMU. */
832 MasterID masterId;
833
834 /** Indicates whether this table walker is part of the stage 2 mmu */
835 const bool isStage2;
836
837 /** TLB that is initiating these table walks */
838 TLB *tlb;
839
840 /** Cached copy of the sctlr as it existed when translation began */
841 SCTLR sctlr;
842
843 WalkerState *currState;
844
845 /** If a timing translation is currently in progress */
846 bool pending;
847
848 /** The number of walks belonging to squashed instructions that can be
849 * removed from the pendingQueue per cycle. */
850 unsigned numSquashable;
851
852 /** Cached copies of system-level properties */
853 bool haveSecurity;
854 bool _haveLPAE;
855 bool _haveVirtualization;
856 uint8_t physAddrRange;
857 bool _haveLargeAsid64;
858
859 /** Statistics */
860 Stats::Scalar statWalks;
861 Stats::Scalar statWalksShortDescriptor;
862 Stats::Scalar statWalksLongDescriptor;
863 Stats::Vector statWalksShortTerminatedAtLevel;
864 Stats::Vector statWalksLongTerminatedAtLevel;
865 Stats::Scalar statSquashedBefore;
866 Stats::Scalar statSquashedAfter;
867 Stats::Histogram statWalkWaitTime;
868 Stats::Histogram statWalkServiceTime;
869 Stats::Histogram statPendingWalks; // essentially "L" of queueing theory
870 Stats::Vector statPageSizes;
871 Stats::Vector2d statRequestOrigin;
872
873 mutable unsigned pendingReqs;
874 mutable Tick pendingChangeTick;
875
876 static const unsigned REQUESTED = 0;
877 static const unsigned COMPLETED = 1;
878
879 public:
880 typedef ArmTableWalkerParams Params;
881 TableWalker(const Params *p);
882 virtual ~TableWalker();
883
884 const Params *
885 params() const
886 {
887 return dynamic_cast<const Params *>(_params);
888 }
889
890 virtual void init();
891
892 bool haveLPAE() const { return _haveLPAE; }
893 bool haveVirtualization() const { return _haveVirtualization; }
894 bool haveLargeAsid64() const { return _haveLargeAsid64; }
895 /** Checks if all state is cleared and if so, completes drain */
896 void completeDrain();
897 unsigned int drain(DrainManager *dm);
898 virtual void drainResume();
899
900 virtual BaseMasterPort& getMasterPort(const std::string &if_name,
901 PortID idx = InvalidPortID);
902
903 void regStats();
904
905 Fault walk(RequestPtr req, ThreadContext *tc, uint16_t asid, uint8_t _vmid,
906 bool _isHyp, TLB::Mode mode, TLB::Translation *_trans,
907 bool timing, bool functional, bool secure,
908 TLB::ArmTranslationType tranType);
909
910 void setTlb(TLB *_tlb) { tlb = _tlb; }
911 TLB* getTlb() { return tlb; }
912 void setMMU(Stage2MMU *m, MasterID master_id);
913 void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr,
914 uint8_t texcb, bool s);
915 void memAttrsLPAE(ThreadContext *tc, TlbEntry &te,
916 LongDescriptor &lDescriptor);
917 void memAttrsAArch64(ThreadContext *tc, TlbEntry &te, uint8_t attrIndx,
918 uint8_t sh);
919
920 static LookupLevel toLookupLevel(uint8_t lookup_level_as_int);
921
922 private:
923
924 void doL1Descriptor();
925 void doL1DescriptorWrapper();
926 EventWrapper<TableWalker,
927 &TableWalker::doL1DescriptorWrapper> doL1DescEvent;
928
929 void doL2Descriptor();
930 void doL2DescriptorWrapper();
931 EventWrapper<TableWalker,
932 &TableWalker::doL2DescriptorWrapper> doL2DescEvent;
933
934 void doLongDescriptor();
935
936 void doL0LongDescriptorWrapper();
937 EventWrapper<TableWalker,
938 &TableWalker::doL0LongDescriptorWrapper> doL0LongDescEvent;
939 void doL1LongDescriptorWrapper();
940 EventWrapper<TableWalker,
941 &TableWalker::doL1LongDescriptorWrapper> doL1LongDescEvent;
942 void doL2LongDescriptorWrapper();
943 EventWrapper<TableWalker,
944 &TableWalker::doL2LongDescriptorWrapper> doL2LongDescEvent;
945 void doL3LongDescriptorWrapper();
946 EventWrapper<TableWalker,
947 &TableWalker::doL3LongDescriptorWrapper> doL3LongDescEvent;
948
949 void doLongDescriptorWrapper(LookupLevel curr_lookup_level);
950
951 bool fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes,
952 Request::Flags flags, int queueIndex, Event *event,
953 void (TableWalker::*doDescriptor)());
954
955 void insertTableEntry(DescriptorBase &descriptor, bool longDescriptor);
956
957 Fault processWalk();
958 Fault processWalkLPAE();
959 static unsigned adjustTableSizeAArch64(unsigned tsz);
960 /// Returns true if the address exceeds the range permitted by the
961 /// system-wide setting or by the TCR_ELx IPS/PS setting
962 static bool checkAddrSizeFaultAArch64(Addr addr, int currPhysAddrRange);
963 Fault processWalkAArch64();
964 void processWalkWrapper();
965 EventWrapper<TableWalker, &TableWalker::processWalkWrapper> doProcessEvent;
966
967 void nextWalk(ThreadContext *tc);
968
969 void pendingChange();
970
971 static uint8_t pageSizeNtoStatBin(uint8_t N);
972};
973
974} // namespace ArmISA
975
976#endif //__ARCH_ARM_TABLE_WALKER_HH__
977