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