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