gem5  v22.1.0.0
pagetable.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010, 2012-2013, 2021 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  * Copyright (c) 2002-2005 The Regents of The University of Michigan
15  * All rights reserved.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions are
19  * met: redistributions of source code must retain the above copyright
20  * notice, this list of conditions and the following disclaimer;
21  * redistributions in binary form must reproduce the above copyright
22  * notice, this list of conditions and the following disclaimer in the
23  * documentation and/or other materials provided with the distribution;
24  * neither the name of the copyright holders nor the names of its
25  * contributors may be used to endorse or promote products derived from
26  * this software without specific prior written permission.
27  *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39  */
40 
41 #ifndef __ARCH_ARM_PAGETABLE_H__
42 #define __ARCH_ARM_PAGETABLE_H__
43 
44 #include <cstdint>
45 
46 #include "arch/arm/page_size.hh"
47 #include "arch/arm/types.hh"
48 #include "arch/arm/utility.hh"
49 #include "arch/generic/mmu.hh"
50 #include "enums/TypeTLB.hh"
51 #include "enums/ArmLookupLevel.hh"
52 #include "sim/serialize.hh"
53 
54 namespace gem5
55 {
56 
57 namespace ArmISA
58 {
59 
60 // Granule sizes
62 {
63  Grain4KB = 12,
64  Grain16KB = 14,
65  Grain64KB = 16,
66  ReservedGrain = 0
67 };
68 
69 extern const GrainSize GrainMap_tg0[];
70 extern const GrainSize GrainMap_tg1[];
71 
72 // Max. physical address range in bits supported by the architecture
73 const unsigned MaxPhysAddrRange = 52;
74 
75 // ITB/DTB page table entry
76 struct PTE
77 {
78  void serialize(CheckpointOut &cp) const
79  {
80  panic("Need to implement PTE serialization\n");
81  }
82 
84  {
85  panic("Need to implement PTE serialization\n");
86  }
87 
88 };
89 
91 {
92  typedef enums::ArmLookupLevel LookupLevel;
93  typedef int64_t pte_t;
94 
95  virtual bool isValid(pte_t pte, unsigned level) const = 0;
96  virtual bool isLeaf(pte_t pte, unsigned level) const = 0;
97  virtual bool isWritable(pte_t pte, unsigned level, bool stage2) const = 0;
98  virtual Addr nextLevelPointer(pte_t pte, unsigned level) const = 0;
99  virtual Addr index(Addr va, unsigned level, int tsz) const = 0;
100  virtual Addr pageMask(pte_t pte, unsigned level) const = 0;
101  virtual unsigned walkBits(unsigned level) const = 0;
102  virtual LookupLevel firstLevel(uint8_t tsz) const = 0;
103  virtual LookupLevel firstS2Level(uint8_t sl0) const = 0;
104  virtual LookupLevel lastLevel() const = 0;
105 
106  Addr walkMask(unsigned level) const;
107 };
108 
110 {
111  bool isValid(pte_t pte, unsigned level) const override;
112  bool isLeaf(pte_t pte, unsigned level) const override;
113  bool isWritable(pte_t pte, unsigned level, bool stage2) const override;
114  Addr nextLevelPointer(pte_t pte, unsigned level) const override;
115  Addr index(Addr va, unsigned level, int tsz) const override;
116  Addr pageMask(pte_t pte, unsigned level) const override;
117  unsigned walkBits(unsigned level) const override;
118  LookupLevel firstLevel(uint8_t tsz) const override;
119  LookupLevel lastLevel() const override;
120 };
121 
123 {
124  bool isValid(pte_t pte, unsigned level) const override;
125  bool isLeaf(pte_t pte, unsigned level) const override;
126  bool isWritable(pte_t pte, unsigned level, bool stage2) const override;
127  Addr nextLevelPointer(pte_t pte, unsigned level) const override;
128  Addr index(Addr va, unsigned level, int tsz) const override;
129  Addr pageMask(pte_t pte, unsigned level) const override;
130  unsigned walkBits(unsigned level) const override;
131  LookupLevel firstLevel(uint8_t tsz) const override;
132  LookupLevel firstS2Level(uint8_t sl0) const override;
133  LookupLevel lastLevel() const override;
134 };
135 
137 {
138  bool isValid(pte_t pte, unsigned level) const override;
139  bool isLeaf(pte_t pte, unsigned level) const override;
140  bool isWritable(pte_t pte, unsigned level, bool stage2) const override;
141  Addr nextLevelPointer(pte_t pte, unsigned level) const override;
142  Addr index(Addr va, unsigned level, int tsz) const override;
143  Addr pageMask(pte_t pte, unsigned level) const override;
144  unsigned walkBits(unsigned level) const override;
145  LookupLevel firstLevel(uint8_t tsz) const override;
146  LookupLevel firstS2Level(uint8_t sl0) const override;
147  LookupLevel lastLevel() const override;
148 };
149 
151 {
152  bool isValid(pte_t pte, unsigned level) const override;
153  bool isLeaf(pte_t pte, unsigned level) const override;
154  bool isWritable(pte_t pte, unsigned level, bool stage2) const override;
155  Addr nextLevelPointer(pte_t pte, unsigned level) const override;
156  Addr index(Addr va, unsigned level, int tsz) const override;
157  Addr pageMask(pte_t pte, unsigned level) const override;
158  unsigned walkBits(unsigned level) const override;
159  LookupLevel firstLevel(uint8_t tsz) const override;
160  LookupLevel firstS2Level(uint8_t sl0) const override;
161  LookupLevel lastLevel() const override;
162 };
163 
164 // ITB/DTB table entry
165 struct TlbEntry : public Serializable
166 {
167  public:
168  typedef enums::ArmLookupLevel LookupLevel;
169 
170  enum class MemoryType : std::uint8_t
171  {
173  Device,
174  Normal
175  };
176 
177  enum class DomainType : std::uint8_t
178  {
179  NoAccess = 0,
180  Client,
181  Reserved,
182  Manager
183  };
184 
185  struct Lookup
186  {
187  // virtual address
188  Addr va = 0;
189  // context id/address space id to use
190  uint16_t asn = 0;
191  // if on lookup asn should be ignored
192  bool ignoreAsn = false;
193  // The virtual machine ID used for stage 2 translation
195  // if the lookup is done from hyp mode
196  bool hyp = false;
197  // if the lookup is secure
198  bool secure = false;
199  // if the lookup should modify state
200  bool functional = false;
201  // selecting the translation regime
203  // if we are in host (EL2&0 regime)
204  bool inHost = false;
205  // mode to differentiate between read/writes/fetches.
207  };
208 
209  // Matching variables
211  Addr size; // Size of this entry, == Type of TLB Rec
212  Addr vpn; // Virtual Page Number
213  uint64_t attributes; // Memory attributes formatted for PAR
214 
215  LookupLevel lookupLevel; // Lookup level where the descriptor was fetched
216  // from. Used to set the FSR for faults
217  // occurring while the long desc. format is in
218  // use (AArch32 w/ LPAE and AArch64)
219 
220  uint16_t asid; // Address Space Identifier
221  vmid_t vmid; // Virtual machine Identifier
222  uint8_t N; // Number of bits in pagesize
223  uint8_t innerAttrs;
224  uint8_t outerAttrs;
225  uint8_t ap; // Access permissions bits
226  uint8_t hap; // Hyp access permissions bits
227  DomainType domain; // Access Domain
228 
230 
231  // True if the long descriptor format is used for this entry (LPAE only)
232  bool longDescFormat; // @todo use this in the update attribute bethod
233 
234  bool isHyp;
235  bool global;
236  bool valid;
237 
238  // True if the entry targets the non-secure physical address space
239  bool ns;
240  // True if the entry was brought in from a non-secure page table
241  bool nstid;
242  // Exception level on insert, AARCH64 EL0&1, AARCH32 -> el=1
244  // This is used to distinguish between instruction and data entries
245  // in unified TLBs
246  TypeTLB type;
247  // True if the entry is caching a partial translation (a table walk)
248  bool partial;
249 
250  // Type of memory
251  bool nonCacheable; // Can we wrap this in mtype?
252 
253  // Memory Attributes
254  bool shareable;
256 
257  // Access permissions
258  bool xn; // Execute Never
259  bool pxn; // Privileged Execute Never (LPAE only)
260 
261  //Construct an entry that maps to physical address addr for SE mode
262  TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr,
263  bool uncacheable, bool read_only) :
264  pfn(_paddr >> PageShift), size(PageBytes - 1), vpn(_vaddr >> PageShift),
266  asid(_asn), vmid(0), N(0),
267  innerAttrs(0), outerAttrs(0), ap(read_only ? 0x3 : 0), hap(0x3),
268  domain(DomainType::Client), mtype(MemoryType::StronglyOrdered),
269  longDescFormat(false), isHyp(false), global(false), valid(true),
270  ns(true), nstid(true), el(EL0), type(TypeTLB::unified),
271  partial(false),
272  nonCacheable(uncacheable),
273  shareable(false), outerShareable(false), xn(0), pxn(0)
274  {
275  // no restrictions by default, hap = 0x3
276 
277  // @todo Check the memory type
278  if (read_only)
279  warn("ARM TlbEntry does not support read-only mappings\n");
280  }
281 
283  pfn(0), size(0), vpn(0), attributes(0), lookupLevel(LookupLevel::L1),
284  asid(0), vmid(0), N(0),
285  innerAttrs(0), outerAttrs(0), ap(0), hap(0x3),
286  domain(DomainType::Client), mtype(MemoryType::StronglyOrdered),
287  longDescFormat(false), isHyp(false), global(false), valid(false),
288  ns(true), nstid(true), el(EL0), type(TypeTLB::unified),
289  partial(false), nonCacheable(false),
290  shareable(false), outerShareable(false), xn(0), pxn(0)
291  {
292  // no restrictions by default, hap = 0x3
293 
294  // @todo Check the memory type
295  }
296 
297  void
298  updateVaddr(Addr new_vaddr)
299  {
300  vpn = new_vaddr >> PageShift;
301  }
302 
303  Addr
304  pageStart() const
305  {
306  return pfn << PageShift;
307  }
308 
309  bool
310  match(const Lookup &lookup) const
311  {
312  bool match = false;
313  Addr v = vpn << N;
314  if (valid && lookup.va >= v && lookup.va <= v + size &&
315  (lookup.secure == !nstid) && (lookup.hyp == isHyp))
316  {
317  match = checkELMatch(lookup.targetEL, lookup.inHost);
318 
319  if (match && !lookup.ignoreAsn) {
320  match = global || (lookup.asn == asid);
321  }
322  if (match && nstid) {
323  match = isHyp || (lookup.vmid == vmid);
324  }
325  }
326  return match;
327  }
328 
329  bool
330  checkELMatch(ExceptionLevel target_el, bool in_host) const
331  {
332  switch (target_el) {
333  case EL3:
334  return el == EL3;
335  case EL2:
336  {
337  return el == EL2 || (el == EL0 && in_host);
338  }
339  case EL1:
340  case EL0:
341  return (el == EL0) || (el == EL1);
342  default:
343  return false;
344  }
345  }
346 
347  Addr
348  pAddr(Addr va) const
349  {
350  return (pfn << N) | (va & size);
351  }
352 
353  void
355  {
356  uint64_t mask;
357  uint64_t newBits;
358 
359  // chec bit 11 to determine if its currently LPAE or VMSA format.
360  if ( attributes & (1 << 11) ) {
361  newBits = ((outerShareable ? 0x2 :
362  shareable ? 0x3 : 0) << 7);
363  mask = 0x180;
364  } else {
380  newBits = ((outerShareable ? 0:1) << 10) |
381  ((shareable ? 1:0) << 7) |
382  (innerAttrs << 4) |
383  (outerAttrs << 2);
384  // TODO: Supersection bit
385  mask = 0x4FC;
386  }
387  // common bits
388  newBits |= ns << 9; // NS bit
389  mask |= 1 << 9;
390  // add in the new bits
391  attributes &= ~mask;
392  attributes |= newBits;
393  }
394 
395  void
397  {
398  attributes = lpae ? (1 << 11) : 0;
400  }
401 
402  std::string
403  print() const
404  {
405  return csprintf("%#x, asn %d vmn %d hyp %d ppn %#x size: %#x ap:%d "
406  "ns:%d nstid:%d g:%d el:%d", vpn << N, asid, vmid,
407  isHyp, pfn << N, size, ap, ns, nstid, global, el);
408  }
409 
410  void
411  serialize(CheckpointOut &cp) const override
412  {
438  uint8_t domain_ = static_cast<uint8_t>(domain);
439  paramOut(cp, "domain", domain_);
440  }
441  void
442  unserialize(CheckpointIn &cp) override
443  {
469  uint8_t domain_;
470  paramIn(cp, "domain", domain_);
471  domain = static_cast<DomainType>(domain_);
472  }
473 
474 };
475 
476 const PageTableOps *getPageTableOps(GrainSize trans_granule);
477 
478 } // namespace ArmISA
479 } // namespace gem5
480 
481 #endif // __ARCH_ARM_PAGETABLE_H__
Basic support for object serialization.
Definition: serialize.hh:170
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
#define SERIALIZE_ENUM(scalar)
Definition: serialize.hh:591
#define UNSERIALIZE_ENUM(scalar)
Definition: serialize.hh:598
#define warn(...)
Definition: logging.hh:246
Bitfield< 28 > v
Definition: misc_types.hh:54
const PageTableOps * getPageTableOps(GrainSize trans_granule)
Definition: pagetable.cc:476
Bitfield< 3, 0 > mask
Definition: pcstate.hh:63
Bitfield< 9 > lpae
Definition: misc_types.hh:431
const GrainSize GrainMap_tg1[]
Definition: pagetable.cc:51
const unsigned MaxPhysAddrRange
Definition: pagetable.hh:73
const Addr PageShift
Definition: page_size.hh:52
uint16_t vmid_t
Definition: types.hh:57
const Addr PageBytes
Definition: page_size.hh:53
const GrainSize GrainMap_tg0[]
Definition: pagetable.cc:49
Bitfield< 8 > va
Definition: misc_types.hh:282
Bitfield< 7, 6 > sl0
Definition: misc_types.hh:570
constexpr RegId L1
Definition: int.hh:112
Bitfield< 20 > level
Definition: intmessage.hh:51
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::ostream CheckpointOut
Definition: serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
Definition: types.cc:40
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
Definition: types.cc:72
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:161
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568
void serialize(CheckpointOut &cp) const
Definition: pagetable.hh:78
void unserialize(CheckpointIn &cp)
Definition: pagetable.hh:83
virtual bool isWritable(pte_t pte, unsigned level, bool stage2) const =0
enums::ArmLookupLevel LookupLevel
Definition: pagetable.hh:92
Addr walkMask(unsigned level) const
Definition: pagetable.cc:55
virtual LookupLevel firstS2Level(uint8_t sl0) const =0
virtual LookupLevel lastLevel() const =0
virtual Addr nextLevelPointer(pte_t pte, unsigned level) const =0
virtual unsigned walkBits(unsigned level) const =0
virtual bool isValid(pte_t pte, unsigned level) const =0
virtual LookupLevel firstLevel(uint8_t tsz) const =0
virtual Addr pageMask(pte_t pte, unsigned level) const =0
virtual Addr index(Addr va, unsigned level, int tsz) const =0
virtual bool isLeaf(pte_t pte, unsigned level) const =0
TlbEntry(Addr _asn, Addr _vaddr, Addr _paddr, bool uncacheable, bool read_only)
Definition: pagetable.hh:262
void updateVaddr(Addr new_vaddr)
Definition: pagetable.hh:298
ExceptionLevel el
Definition: pagetable.hh:243
LookupLevel lookupLevel
Definition: pagetable.hh:215
void setAttributes(bool lpae)
Definition: pagetable.hh:396
bool match(const Lookup &lookup) const
Definition: pagetable.hh:310
bool checkELMatch(ExceptionLevel target_el, bool in_host) const
Definition: pagetable.hh:330
std::string print() const
Definition: pagetable.hh:403
enums::ArmLookupLevel LookupLevel
Definition: pagetable.hh:168
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: pagetable.hh:442
Addr pAddr(Addr va) const
Definition: pagetable.hh:348
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: pagetable.hh:411
Addr pageStart() const
Definition: pagetable.hh:304
Addr pageMask(pte_t pte, unsigned level) const override
Definition: pagetable.cc:118
bool isValid(pte_t pte, unsigned level) const override
Definition: pagetable.cc:61
bool isLeaf(pte_t pte, unsigned level) const override
Definition: pagetable.cc:72
bool isWritable(pte_t pte, unsigned level, bool stage2) const override
Definition: pagetable.cc:83
Addr nextLevelPointer(pte_t pte, unsigned level) const override
Definition: pagetable.cc:89
Addr index(Addr va, unsigned level, int tsz) const override
Definition: pagetable.cc:104
unsigned walkBits(unsigned level) const override
Definition: pagetable.cc:129
LookupLevel firstLevel(uint8_t tsz) const override
Definition: pagetable.cc:140
LookupLevel lastLevel() const override
Definition: pagetable.cc:146
Addr index(Addr va, unsigned level, int tsz) const override
Definition: pagetable.cc:307
LookupLevel firstS2Level(uint8_t sl0) const override
Definition: pagetable.cc:356
unsigned walkBits(unsigned level) const override
Definition: pagetable.cc:333
Addr pageMask(pte_t pte, unsigned level) const override
Definition: pagetable.cc:319
bool isLeaf(pte_t pte, unsigned level) const override
Definition: pagetable.cc:273
LookupLevel firstLevel(uint8_t tsz) const override
Definition: pagetable.cc:345
bool isValid(pte_t pte, unsigned level) const override
Definition: pagetable.cc:261
LookupLevel lastLevel() const override
Definition: pagetable.cc:367
Addr nextLevelPointer(pte_t pte, unsigned level) const override
Definition: pagetable.cc:291
bool isWritable(pte_t pte, unsigned level, bool stage2) const override
Definition: pagetable.cc:285
unsigned walkBits(unsigned level) const override
Definition: pagetable.cc:222
Addr pageMask(pte_t pte, unsigned level) const override
Definition: pagetable.cc:210
LookupLevel firstS2Level(uint8_t sl0) const override
Definition: pagetable.cc:244
bool isWritable(pte_t pte, unsigned level, bool stage2) const override
Definition: pagetable.cc:176
Addr index(Addr va, unsigned level, int tsz) const override
Definition: pagetable.cc:198
Addr nextLevelPointer(pte_t pte, unsigned level) const override
Definition: pagetable.cc:182
LookupLevel lastLevel() const override
Definition: pagetable.cc:255
bool isValid(pte_t pte, unsigned level) const override
Definition: pagetable.cc:152
bool isLeaf(pte_t pte, unsigned level) const override
Definition: pagetable.cc:164
LookupLevel firstLevel(uint8_t tsz) const override
Definition: pagetable.cc:234
Addr nextLevelPointer(pte_t pte, unsigned level) const override
Definition: pagetable.cc:401
LookupLevel lastLevel() const override
Definition: pagetable.cc:470
bool isValid(pte_t pte, unsigned level) const override
Definition: pagetable.cc:373
unsigned walkBits(unsigned level) const override
Definition: pagetable.cc:438
Addr index(Addr va, unsigned level, int tsz) const override
Definition: pagetable.cc:416
LookupLevel firstLevel(uint8_t tsz) const override
Definition: pagetable.cc:449
Addr pageMask(pte_t pte, unsigned level) const override
Definition: pagetable.cc:427
bool isWritable(pte_t pte, unsigned level, bool stage2) const override
Definition: pagetable.cc:395
LookupLevel firstS2Level(uint8_t sl0) const override
Definition: pagetable.cc:459
bool isLeaf(pte_t pte, unsigned level) const override
Definition: pagetable.cc:384

Generated on Wed Dec 21 2022 10:22:24 for gem5 by doxygen 1.9.1