table_walker.hh (9342:6fec8f26e56d) table_walker.hh (10037:5cac77888310)
1/*
1/*
2 * Copyright (c) 2010-2012 ARM Limited
2 * Copyright (c) 2010-2013 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

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

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
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

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

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
38 */
39
40#ifndef __ARCH_ARM_TABLE_WALKER_HH__
41#define __ARCH_ARM_TABLE_WALKER_HH__
42
43#include <list>
44
45#include "arch/arm/miscregs.hh"
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"
46#include "arch/arm/tlb.hh"
47#include "dev/dma_device.hh"
48#include "mem/mem_object.hh"
49#include "mem/request.hh"
50#include "params/ArmTableWalker.hh"
51#include "sim/eventq.hh"
52#include "sim/fault_fwd.hh"
53
54class ThreadContext;
55
56namespace ArmISA {
57class Translation;
58class TLB;
48#include "arch/arm/tlb.hh"
49#include "dev/dma_device.hh"
50#include "mem/mem_object.hh"
51#include "mem/request.hh"
52#include "params/ArmTableWalker.hh"
53#include "sim/eventq.hh"
54#include "sim/fault_fwd.hh"
55
56class ThreadContext;
57
58namespace ArmISA {
59class Translation;
60class TLB;
61class Stage2MMU;
59
60class TableWalker : public MemObject
61{
62 public:
62
63class TableWalker : public MemObject
64{
65 public:
63 struct L1Descriptor {
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:
64 /** Type of page table entry ARM DDI 0406B: B3-8*/
65 enum EntryType {
66 Ignore,
67 PageTable,
68 Section,
69 Reserved
70 };
71
72 /** The raw bits of the entry */
73 uint32_t data;
74
75 /** This entry has been modified (access flag set) and needs to be
76 * written back to memory */
77 bool _dirty;
78
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()
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
79 EntryType type() const
80 {
81 return (EntryType)(data & 0x3);
82 }
83
84 /** Is the page a Supersection (16MB)?*/
85 bool supersection() const
86 {

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

107 Addr pfn() const
108 {
109 if (supersection())
110 panic("Super sections not implemented\n");
111 return bits(data, 31, 20);
112 }
113
114 /** Is the translation global (no asid used)? */
130 EntryType type() const
131 {
132 return (EntryType)(data & 0x3);
133 }
134
135 /** Is the page a Supersection (16MB)?*/
136 bool supersection() const
137 {

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

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)? */
115 bool global() const
166 bool global(WalkerState *currState) const
116 {
167 {
117 return bits(data, 17);
168 return !bits(data, 17);
118 }
119
120 /** Is the translation not allow execution? */
121 bool xn() const
122 {
123 return bits(data, 4);
124 }
125
126 /** Three bit access protection flags */
127 uint8_t ap() const
128 {
129 return (bits(data, 15) << 2) | bits(data, 11, 10);
130 }
131
132 /** Domain Client/Manager: ARM DDI 0406B: B3-31 */
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 */
133 uint8_t domain() const
184 TlbEntry::DomainType domain() const
134 {
185 {
135 return bits(data, 8, 5);
186 return static_cast<TlbEntry::DomainType>(bits(data, 8, 5));
136 }
137
138 /** Address of L2 descriptor if it exists */
139 Addr l2Addr() const
140 {
141 return mbits(data, 31, 10);
142 }
143

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

166 _dirty = true;
167 }
168
169 /** This entry needs to be written back to memory */
170 bool dirty() const
171 {
172 return _dirty;
173 }
187 }
188
189 /** Address of L2 descriptor if it exists */
190 Addr l2Addr() const
191 {
192 return mbits(data, 31, 10);
193 }
194

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

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 }
174 };
175
176 /** Level 2 page table descriptor */
240 };
241
242 /** Level 2 page table descriptor */
177 struct L2Descriptor {
178
243 class L2Descriptor : public DescriptorBase {
244 public:
179 /** The raw bits of the entry. */
245 /** The raw bits of the entry. */
180 uint32_t data;
246 uint32_t data;
247 L1Descriptor *l1Parent;
181
182 /** This entry has been modified (access flag set) and needs to be
183 * written back to memory */
184 bool _dirty;
185
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()
255 {
256 lookupLevel = L2;
257 }
258
259 L2Descriptor(L1Descriptor &parent) : l1Parent(&parent)
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
186 /** Is the entry invalid */
187 bool invalid() const
188 {
189 return bits(data, 1, 0) == 0;
190 }
191
192 /** What is the size of the mapping? */
193 bool large() const
194 {
195 return bits(data, 1) == 0;
196 }
197
198 /** Is execution allowed on this mapping? */
199 bool xn() const
200 {
201 return large() ? bits(data, 15) : bits(data, 0);
202 }
203
204 /** Is the translation global (no asid used)? */
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)? */
205 bool global() const
308 bool global(WalkerState *currState) const
206 {
207 return !bits(data, 11);
208 }
209
210 /** Three bit access protection flags */
211 uint8_t ap() const
212 {
213 return bits(data, 5, 4) | (bits(data, 9) << 2);

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

254 /** This entry needs to be written back to memory */
255 bool dirty() const
256 {
257 return _dirty;
258 }
259
260 };
261
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);

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

357 /** This entry needs to be written back to memory */
358 bool dirty() const
359 {
360 return _dirty;
361 }
362
363 };
364
262 protected:
365 /** Long-descriptor format (LPAE) */
366 class LongDescriptor : public DescriptorBase {
367 public:
368 /** Descriptor type */
369 enum EntryType {
370 Invalid,
371 Table,
372 Block,
373 Page
374 };
263
375
264 /**
265 * A snooping DMA port that currently does nothing besides
266 * extending the DMA port to accept snoops without complaining.
267 */
268 class SnoopingDmaPort : public DmaPort
269 {
376 /** The raw bits of the entry */
377 uint64_t data;
270
378
271 protected:
379 /** This entry has been modified (access flag set) and needs to be
380 * written back to memory */
381 bool _dirty;
272
382
273 virtual void recvTimingSnoopReq(PacketPtr pkt)
274 { }
383 virtual uint64_t getRawData() const
384 {
385 return (data);
386 }
275
387
276 virtual Tick recvAtomicSnoop(PacketPtr pkt)
277 { return 0; }
388 virtual std::string dbgHeader() const
389 {
390 if (type() == LongDescriptor::Page) {
391 assert(lookupLevel == L3);
392 return "Inserting Page descriptor into TLB\n";
393 } else {
394 assert(lookupLevel < L3);
395 return "Inserting Block descriptor into TLB\n";
396 }
397 }
278
398
279 virtual void recvFunctionalSnoop(PacketPtr pkt)
280 { }
399 /**
400 * Returns true if this entry targets the secure physical address
401 * map.
402 */
403 bool secure(bool have_security, WalkerState *currState) const
404 {
405 assert(type() == Block || type() == Page);
406 return have_security && (currState->secureLookup && !bits(data, 5));
407 }
281
408
282 virtual bool isSnooping() const { return true; }
409 /** True if the current lookup is performed in AArch64 state */
410 bool aarch64;
283
411
284 public:
412 /** True if the granule size is 64 KB (AArch64 only) */
413 bool largeGrain;
285
414
286 /**
287 * A snooping DMA port merely calls the construtor of the DMA
288 * port.
289 */
290 SnoopingDmaPort(MemObject *dev, System *s) :
291 DmaPort(dev, s)
292 { }
415 /** Width of the granule size in bits */
416 int grainSize;
417
418 /** Return the descriptor type */
419 EntryType type() const
420 {
421 switch (bits(data, 1, 0)) {
422 case 0x1:
423 // In AArch64 blocks are not allowed at L0 for the 4 KB granule
424 // and at L1 for the 64 KB granule
425 if (largeGrain)
426 return lookupLevel == L2 ? Block : Invalid;
427 return lookupLevel == L0 || lookupLevel == L3 ? Invalid : Block;
428 case 0x3:
429 return lookupLevel == L3 ? Page : Table;
430 default:
431 return Invalid;
432 }
433 }
434
435 /** Return the bit width of the page/block offset */
436 uint8_t offsetBits() const
437 {
438 assert(type() == Block || type() == Page);
439 if (largeGrain) {
440 if (type() == Block)
441 return 29 /* 512 MB */;
442 return 16 /* 64 KB */; // type() == Page
443 } else {
444 if (type() == Block)
445 return lookupLevel == L1 ? 30 /* 1 GB */ : 21 /* 2 MB */;
446 return 12 /* 4 KB */; // type() == Page
447 }
448 }
449
450 /** Return the physical frame, bits shifted right */
451 Addr pfn() const
452 {
453 if (aarch64)
454 return bits(data, 47, offsetBits());
455 return bits(data, 39, offsetBits());
456 }
457
458 /** Return the complete physical address given a VA */
459 Addr paddr(Addr va) const
460 {
461 int n = offsetBits();
462 if (aarch64)
463 return mbits(data, 47, n) | mbits(va, n - 1, 0);
464 return mbits(data, 39, n) | mbits(va, n - 1, 0);
465 }
466
467 /** Return the physical address of the entry */
468 Addr paddr() const
469 {
470 if (aarch64)
471 return mbits(data, 47, offsetBits());
472 return mbits(data, 39, offsetBits());
473 }
474
475 /** Return the address of the next page table */
476 Addr nextTableAddr() const
477 {
478 assert(type() == Table);
479 if (aarch64)
480 return mbits(data, 47, grainSize);
481 else
482 return mbits(data, 39, 12);
483 }
484
485 /** Return the address of the next descriptor */
486 Addr nextDescAddr(Addr va) const
487 {
488 assert(type() == Table);
489 Addr pa = 0;
490 if (aarch64) {
491 int stride = grainSize - 3;
492 int va_lo = stride * (3 - (lookupLevel + 1)) + grainSize;
493 int va_hi = va_lo + stride - 1;
494 pa = nextTableAddr() | (bits(va, va_hi, va_lo) << 3);
495 } else {
496 if (lookupLevel == L1)
497 pa = nextTableAddr() | (bits(va, 29, 21) << 3);
498 else // lookupLevel == L2
499 pa = nextTableAddr() | (bits(va, 20, 12) << 3);
500 }
501 return pa;
502 }
503
504 /** Is execution allowed on this mapping? */
505 bool xn() const
506 {
507 assert(type() == Block || type() == Page);
508 return bits(data, 54);
509 }
510
511 /** Is privileged execution allowed on this mapping? (LPAE only) */
512 bool pxn() const
513 {
514 assert(type() == Block || type() == Page);
515 return bits(data, 53);
516 }
517
518 /** Contiguous hint bit. */
519 bool contiguousHint() const
520 {
521 assert(type() == Block || type() == Page);
522 return bits(data, 52);
523 }
524
525 /** Is the translation global (no asid used)? */
526 bool global(WalkerState *currState) const
527 {
528 assert(currState && (type() == Block || type() == Page));
529 if (!currState->aarch64 && (currState->isSecure &&
530 !currState->secureLookup)) {
531 return false; // ARM ARM issue C B3.6.3
532 } else if (currState->aarch64) {
533 if (currState->el == EL2 || currState->el == EL3) {
534 return true; // By default translations are treated as global
535 // in AArch64 EL2 and EL3
536 } else if (currState->isSecure && !currState->secureLookup) {
537 return false;
538 }
539 }
540 return !bits(data, 11);
541 }
542
543 /** Returns true if the access flag (AF) is set. */
544 bool af() const
545 {
546 assert(type() == Block || type() == Page);
547 return bits(data, 10);
548 }
549
550 /** 2-bit shareability field */
551 uint8_t sh() const
552 {
553 assert(type() == Block || type() == Page);
554 return bits(data, 9, 8);
555 }
556
557 /** 2-bit access protection flags */
558 uint8_t ap() const
559 {
560 assert(type() == Block || type() == Page);
561 // Long descriptors only support the AP[2:1] scheme
562 return bits(data, 7, 6);
563 }
564
565 /** Read/write access protection flag */
566 bool rw() const
567 {
568 assert(type() == Block || type() == Page);
569 return !bits(data, 7);
570 }
571
572 /** User/privileged level access protection flag */
573 bool user() const
574 {
575 assert(type() == Block || type() == Page);
576 return bits(data, 6);
577 }
578
579 /** Return the AP bits as compatible with the AP[2:0] format. Utility
580 * function used to simplify the code in the TLB for performing
581 * permission checks. */
582 static uint8_t ap(bool rw, bool user)
583 {
584 return ((!rw) << 2) | (user << 1);
585 }
586
587 TlbEntry::DomainType domain() const
588 {
589 // Long-desc. format only supports Client domain
590 assert(type() == Block || type() == Page);
591 return TlbEntry::DomainType::Client;
592 }
593
594 /** Attribute index */
595 uint8_t attrIndx() const
596 {
597 assert(type() == Block || type() == Page);
598 return bits(data, 4, 2);
599 }
600
601 /** Memory attributes, only used by stage 2 translations */
602 uint8_t memAttr() const
603 {
604 assert(type() == Block || type() == Page);
605 return bits(data, 5, 2);
606 }
607
608 /** Set access flag that this entry has been touched. Mark the entry as
609 * requiring a writeback, in the future. */
610 void setAf()
611 {
612 data |= 1 << 10;
613 _dirty = true;
614 }
615
616 /** This entry needs to be written back to memory */
617 bool dirty() const
618 {
619 return _dirty;
620 }
621
622 /** Whether the subsequent levels of lookup are secure */
623 bool secureTable() const
624 {
625 assert(type() == Table);
626 return !bits(data, 63);
627 }
628
629 /** Two bit access protection flags for subsequent levels of lookup */
630 uint8_t apTable() const
631 {
632 assert(type() == Table);
633 return bits(data, 62, 61);
634 }
635
636 /** R/W protection flag for subsequent levels of lookup */
637 uint8_t rwTable() const
638 {
639 assert(type() == Table);
640 return !bits(data, 62);
641 }
642
643 /** User/privileged mode protection flag for subsequent levels of
644 * lookup */
645 uint8_t userTable() const
646 {
647 assert(type() == Table);
648 return !bits(data, 61);
649 }
650
651 /** Is execution allowed on subsequent lookup levels? */
652 bool xnTable() const
653 {
654 assert(type() == Table);
655 return bits(data, 60);
656 }
657
658 /** Is privileged execution allowed on subsequent lookup levels? */
659 bool pxnTable() const
660 {
661 assert(type() == Table);
662 return bits(data, 59);
663 }
293 };
294
664 };
665
295 struct WalkerState //: public SimObject
666 class WalkerState
296 {
667 {
668 public:
297 /** Thread context that we're doing the walk for */
298 ThreadContext *tc;
299
669 /** Thread context that we're doing the walk for */
670 ThreadContext *tc;
671
672 /** If the access is performed in AArch64 state */
673 bool aarch64;
674
675 /** Current exception level */
676 ExceptionLevel el;
677
678 /** Current physical address range in bits */
679 int physAddrRange;
680
300 /** Request that is currently being serviced */
301 RequestPtr req;
302
681 /** Request that is currently being serviced */
682 RequestPtr req;
683
303 /** Context ID that we're servicing the request under */
304 uint8_t contextId;
684 /** ASID that we're servicing the request under */
685 uint16_t asid;
686 uint8_t vmid;
687 bool isHyp;
305
306 /** Translation state for delayed requests */
307 TLB::Translation *transState;
308
309 /** The fault that we are going to return */
310 Fault fault;
311
688
689 /** Translation state for delayed requests */
690 TLB::Translation *transState;
691
692 /** The fault that we are going to return */
693 Fault fault;
694
312 /** The virtual address that is being translated */
695 /** The virtual address that is being translated with tagging removed.*/
313 Addr vaddr;
314
696 Addr vaddr;
697
698 /** The virtual address that is being translated */
699 Addr vaddr_tainted;
700
315 /** Cached copy of the sctlr as it existed when translation began */
316 SCTLR sctlr;
317
701 /** Cached copy of the sctlr as it existed when translation began */
702 SCTLR sctlr;
703
318 /** Width of the base address held in TTRB0 */
319 uint32_t N;
704 /** Cached copy of the scr as it existed when translation began */
705 SCR scr;
320
706
707 /** Cached copy of the cpsr as it existed when translation began */
708 CPSR cpsr;
709
710 /** Cached copy of the ttbcr as it existed when translation began. */
711 TTBCR ttbcr;
712
713 /** Cached copy of the htcr as it existed when translation began. */
714 HTCR htcr;
715
716 /** Cached copy of the htcr as it existed when translation began. */
717 HCR hcr;
718
719 /** Cached copy of the vtcr as it existed when translation began. */
720 VTCR_t vtcr;
721
321 /** If the access is a write */
322 bool isWrite;
323
324 /** If the access is a fetch (for execution, and no-exec) must be checked?*/
325 bool isFetch;
326
722 /** If the access is a write */
723 bool isWrite;
724
725 /** If the access is a fetch (for execution, and no-exec) must be checked?*/
726 bool isFetch;
727
728 /** If the access comes from the secure state. */
729 bool isSecure;
730
731 /** Helper variables used to implement hierarchical access permissions
732 * when the long-desc. format is used (LPAE only) */
733 bool secureLookup;
734 bool rwTable;
735 bool userTable;
736 bool xnTable;
737 bool pxnTable;
738
739 /** Flag indicating if a second stage of lookup is required */
740 bool stage2Req;
741
742 /** Indicates whether the translation has been passed onto the second
743 * stage mmu, and no more work is required from the first stage.
744 */
745 bool doingStage2;
746
747 /** A pointer to the stage 2 translation that's in progress */
748 TLB::Translation *stage2Tran;
749
327 /** If the mode is timing or atomic */
328 bool timing;
329
330 /** If the atomic mode should be functional */
331 bool functional;
332
333 /** Save mode for use in delayed response */
334 BaseTLB::Mode mode;
335
750 /** If the mode is timing or atomic */
751 bool timing;
752
753 /** If the atomic mode should be functional */
754 bool functional;
755
756 /** Save mode for use in delayed response */
757 BaseTLB::Mode mode;
758
759 /** The translation type that has been requested */
760 TLB::ArmTranslationType tranType;
761
762 /** Short-format descriptors */
336 L1Descriptor l1Desc;
337 L2Descriptor l2Desc;
338
763 L1Descriptor l1Desc;
764 L2Descriptor l2Desc;
765
339 /** Whether L1/L2 descriptor response is delayed in timing mode */
766 /** Long-format descriptor (LPAE and AArch64) */
767 LongDescriptor longDesc;
768
769 /** Whether the response is delayed in timing mode due to additional
770 * lookups */
340 bool delayed;
341
342 TableWalker *tableWalker;
343
344 void doL1Descriptor();
345 void doL2Descriptor();
346
771 bool delayed;
772
773 TableWalker *tableWalker;
774
775 void doL1Descriptor();
776 void doL2Descriptor();
777
347 std::string name() const {return tableWalker->name();}
778 void doLongDescriptor();
779
780 WalkerState();
781
782 std::string name() const { return tableWalker->name(); }
348 };
349
783 };
784
785 protected:
350
786
351 /** Queue of requests that need processing first level translation */
352 std::list<WalkerState *> stateQueueL1;
787 /**
788 * A snooping DMA port that currently does nothing besides
789 * extending the DMA port to accept snoops without complaining.
790 */
791 class SnoopingDmaPort : public DmaPort
792 {
353
793
354 /** Queue of requests that have passed first level translation and
355 * require an additional level. */
356 std::list<WalkerState *> stateQueueL2;
794 protected:
357
795
796 virtual void recvTimingSnoopReq(PacketPtr pkt)
797 { }
798
799 virtual Tick recvAtomicSnoop(PacketPtr pkt)
800 { return 0; }
801
802 virtual void recvFunctionalSnoop(PacketPtr pkt)
803 { }
804
805 virtual bool isSnooping() const { return true; }
806
807 public:
808
809 /**
810 * A snooping DMA port merely calls the construtor of the DMA
811 * port.
812 */
813 SnoopingDmaPort(MemObject *dev, System *s) :
814 DmaPort(dev, s)
815 { }
816 };
817
818 /** Queues of requests for all the different lookup levels */
819 std::list<WalkerState *> stateQueues[MAX_LOOKUP_LEVELS];
820
358 /** Queue of requests that have passed are waiting because the walker is
359 * currently busy. */
360 std::list<WalkerState *> pendingQueue;
361
362
363 /** Port to issue translation requests from */
364 SnoopingDmaPort port;
365
366 /** If we're draining keep the drain event around until we're drained */
367 DrainManager *drainManager;
368
821 /** Queue of requests that have passed are waiting because the walker is
822 * currently busy. */
823 std::list<WalkerState *> pendingQueue;
824
825
826 /** Port to issue translation requests from */
827 SnoopingDmaPort port;
828
829 /** If we're draining keep the drain event around until we're drained */
830 DrainManager *drainManager;
831
832 /** The MMU to forward second stage look upts to */
833 Stage2MMU *stage2Mmu;
834
835 /** Indicates whether this table walker is part of the stage 2 mmu */
836 const bool isStage2;
837
369 /** TLB that is initiating these table walks */
370 TLB *tlb;
371
372 /** Cached copy of the sctlr as it existed when translation began */
373 SCTLR sctlr;
374
375 WalkerState *currState;
376
377 /** If a timing translation is currently in progress */
378 bool pending;
379
380 /** Request id for requests generated by this walker */
381 MasterID masterId;
382
383 /** The number of walks belonging to squashed instructions that can be
384 * removed from the pendingQueue per cycle. */
385 unsigned numSquashable;
386
838 /** TLB that is initiating these table walks */
839 TLB *tlb;
840
841 /** Cached copy of the sctlr as it existed when translation began */
842 SCTLR sctlr;
843
844 WalkerState *currState;
845
846 /** If a timing translation is currently in progress */
847 bool pending;
848
849 /** Request id for requests generated by this walker */
850 MasterID masterId;
851
852 /** The number of walks belonging to squashed instructions that can be
853 * removed from the pendingQueue per cycle. */
854 unsigned numSquashable;
855
856 /** Cached copies of system-level properties */
857 bool haveSecurity;
858 bool _haveLPAE;
859 bool _haveVirtualization;
860 uint8_t physAddrRange;
861 bool _haveLargeAsid64;
862 ArmSystem *armSys;
863
387 public:
864 public:
388 typedef ArmTableWalkerParams Params;
865 typedef ArmTableWalkerParams Params;
389 TableWalker(const Params *p);
390 virtual ~TableWalker();
391
392 const Params *
393 params() const
394 {
395 return dynamic_cast<const Params *>(_params);
396 }
397
866 TableWalker(const Params *p);
867 virtual ~TableWalker();
868
869 const Params *
870 params() const
871 {
872 return dynamic_cast<const Params *>(_params);
873 }
874
875 bool haveLPAE() const { return _haveLPAE; }
876 bool haveVirtualization() const { return _haveVirtualization; }
877 bool haveLargeAsid64() const { return _haveLargeAsid64; }
398 /** Checks if all state is cleared and if so, completes drain */
399 void completeDrain();
400 unsigned int drain(DrainManager *dm);
878 /** Checks if all state is cleared and if so, completes drain */
879 void completeDrain();
880 unsigned int drain(DrainManager *dm);
401 void drainResume();
881 virtual void drainResume();
402 virtual BaseMasterPort& getMasterPort(const std::string &if_name,
403 PortID idx = InvalidPortID);
404
882 virtual BaseMasterPort& getMasterPort(const std::string &if_name,
883 PortID idx = InvalidPortID);
884
405 Fault walk(RequestPtr req, ThreadContext *tc, uint8_t cid, TLB::Mode mode,
406 TLB::Translation *_trans, bool timing, bool functional = false);
885 /**
886 * Allow the MMU (overseeing both stage 1 and stage 2 TLBs) to
887 * access the table walker port through the TLB so that it can
888 * orchestrate staged translations.
889 *
890 * @return Our DMA port
891 */
892 DmaPort& getWalkerPort() { return port; }
407
893
894 Fault walk(RequestPtr req, ThreadContext *tc, uint16_t asid, uint8_t _vmid,
895 bool _isHyp, TLB::Mode mode, TLB::Translation *_trans,
896 bool timing, bool functional, bool secure,
897 TLB::ArmTranslationType tranType);
898
408 void setTlb(TLB *_tlb) { tlb = _tlb; }
899 void setTlb(TLB *_tlb) { tlb = _tlb; }
900 TLB* getTlb() { return tlb; }
901 void setMMU(Stage2MMU *m) { stage2Mmu = m; }
409 void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr,
410 uint8_t texcb, bool s);
902 void memAttrs(ThreadContext *tc, TlbEntry &te, SCTLR sctlr,
903 uint8_t texcb, bool s);
904 void memAttrsLPAE(ThreadContext *tc, TlbEntry &te,
905 LongDescriptor &lDescriptor);
906 void memAttrsAArch64(ThreadContext *tc, TlbEntry &te, uint8_t attrIndx,
907 uint8_t sh);
411
908
909 static LookupLevel toLookupLevel(uint8_t lookup_level_as_int);
910
412 private:
413
414 void doL1Descriptor();
415 void doL1DescriptorWrapper();
911 private:
912
913 void doL1Descriptor();
914 void doL1DescriptorWrapper();
416 EventWrapper<TableWalker, &TableWalker::doL1DescriptorWrapper> doL1DescEvent;
915 EventWrapper916 &TableWalker::doL1DescriptorWrapper> doL1DescEvent;
417
418 void doL2Descriptor();
419 void doL2DescriptorWrapper();
917
918 void doL2Descriptor();
919 void doL2DescriptorWrapper();
420 EventWrapper<TableWalker, &TableWalker::doL2DescriptorWrapper> doL2DescEvent;
920 EventWrapper921 &TableWalker::doL2DescriptorWrapper> doL2DescEvent;
421
922
923 void doLongDescriptor();
924
925 void doL0LongDescriptorWrapper();
926 EventWrapper<TableWalker,
927 &TableWalker::doL0LongDescriptorWrapper> doL0LongDescEvent;
928 void doL1LongDescriptorWrapper();
929 EventWrapper<TableWalker,
930 &TableWalker::doL1LongDescriptorWrapper> doL1LongDescEvent;
931 void doL2LongDescriptorWrapper();
932 EventWrapper<TableWalker,
933 &TableWalker::doL2LongDescriptorWrapper> doL2LongDescEvent;
934 void doL3LongDescriptorWrapper();
935 EventWrapper<TableWalker,
936 &TableWalker::doL3LongDescriptorWrapper> doL3LongDescEvent;
937
938 void doLongDescriptorWrapper(LookupLevel curr_lookup_level);
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
422 Fault processWalk();
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();
423 void processWalkWrapper();
424 EventWrapper<TableWalker, &TableWalker::processWalkWrapper> doProcessEvent;
425
426 void nextWalk(ThreadContext *tc);
427};
428
953 void processWalkWrapper();
954 EventWrapper<TableWalker, &TableWalker::processWalkWrapper> doProcessEvent;
955
956 void nextWalk(ThreadContext *tc);
957};
958
429
430} // namespace ArmISA
431
432#endif //__ARCH_ARM_TABLE_WALKER_HH__
433
959} // namespace ArmISA
960
961#endif //__ARCH_ARM_TABLE_WALKER_HH__
962