gem5  v22.1.0.0
pagetable.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013, 2018-2019, 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  * 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 
38 #include "arch/arm/pagetable.hh"
39 
40 #include "base/bitfield.hh"
41 #include "base/logging.hh"
42 
43 namespace gem5
44 {
45 
46 namespace ArmISA
47 {
48 
53 
54 Addr
56 {
57  return ~mask(walkBits(level));
58 }
59 
60 bool
61 V7LPageTableOps::isValid(pte_t pte, unsigned level) const
62 {
63  switch (level) {
64  case 1: return pte & 0x1;
65  case 2: return pte & 0x1;
66  case 3: return (pte & 0x1) && (pte & 0x2);
67  default: panic("bad level %d", level);
68  }
69 }
70 
71 bool
72 V7LPageTableOps::isLeaf(pte_t pte, unsigned level) const
73 {
74  switch (level) {
75  case 1: return !(pte & 0x2);
76  case 2: return !(pte & 0x2);
77  case 3: return true;
78  default: panic("bad level %d", level);
79  }
80 }
81 
82 bool
83 V7LPageTableOps::isWritable(pte_t pte, unsigned level, bool stage2) const
84 {
85  return stage2 ? bits(pte, 7, 6)==3 : bits(pte, 7)==0;
86 }
87 
88 Addr
90 {
91  if (isLeaf(pte, level)) {
92  switch (level) {
93  case 1: return mbits(pte, 39, 30);
94  case 2: return mbits(pte, 39, 21);
95  case 3: return mbits(pte, 39, 12);
96  default: panic("bad level %d", level);
97  }
98  } else {
99  return mbits(pte, 39, 12);
100  }
101 }
102 
103 Addr
104 V7LPageTableOps::index(Addr va, unsigned level, int tsz) const
105 {
106  // In theory this should be configurable...
107  const int n = 12;
108 
109  switch (level) {
110  case 1: return bits(va, std::min(26+n, tsz - 1), 30) << 3; break;
111  case 2: return bits(va, std::min(29, tsz - 1), 21) << 3; break;
112  case 3: return bits(va, std::min(20, tsz - 1), 12) << 3; break;
113  default: panic("bad level %d", level);
114  }
115 }
116 
117 Addr
119 {
120  switch (level) {
121  case 1: return ~mask(30);
122  case 2: return ~mask(21);
123  case 3: return bits(pte, 52) ? ~mask(16) : ~mask(12);
124  default: panic("bad level %d", level);
125  }
126 }
127 
128 unsigned
130 {
131  switch (level) {
132  case 1: return 30;
133  case 2: return 21;
134  case 3: return 12;
135  default: panic("bad level %d", level);
136  }
137 }
138 
140 V7LPageTableOps::firstLevel(uint8_t tsz) const
141 {
142  return LookupLevel::L1;
143 }
144 
147 {
148  return LookupLevel::L3;
149 }
150 
151 bool
153 {
154  switch (level) {
155  case 0: return pte & 0x1;
156  case 1: return pte & 0x1;
157  case 2: return pte & 0x1;
158  case 3: return (pte & 0x1) && (pte & 0x2);
159  default: panic("bad level %d", level);
160  }
161 }
162 
163 bool
165 {
166  switch (level) {
167  case 0: return false;
168  case 1: return !(pte & 0x2);
169  case 2: return !(pte & 0x2);
170  case 3: return true;
171  default: panic("bad level %d", level);
172  }
173 }
174 
175 bool
176 V8PageTableOps4k::isWritable(pte_t pte, unsigned level, bool stage2) const
177 {
178  return stage2 ? bits(pte, 7, 6)==3 : bits(pte, 7)==0;
179 }
180 
181 Addr
183 {
184  if (isLeaf(pte, level)) {
185  switch (level) {
186  // no level 0 here
187  case 1: return mbits(pte, 47, 30);
188  case 2: return mbits(pte, 47, 21);
189  case 3: return mbits(pte, 47, 12);
190  default: panic("bad level %d", level);
191  }
192  } else {
193  return mbits(pte, 47, 12);
194  }
195 }
196 
197 Addr
198 V8PageTableOps4k::index(Addr va, unsigned level, int tsz) const
199 {
200  switch (level) {
201  case 0: return bits(va, std::min(47, tsz - 1), 39) << 3; break;
202  case 1: return bits(va, std::min(38, tsz - 1), 30) << 3; break;
203  case 2: return bits(va, std::min(29, tsz - 1), 21) << 3; break;
204  case 3: return bits(va, std::min(20, tsz - 1), 12) << 3; break;
205  default: panic("bad level %d", level);
206  }
207 }
208 
209 Addr
211 {
212  switch (level) {
213  // no level 0 here
214  case 1: return ~mask(30);
215  case 2: return ~mask(21);
216  case 3: return bits(pte, 52) ? ~mask(16) : ~mask(12);
217  default: panic("bad level %d", level);
218  }
219 }
220 
221 unsigned
223 {
224  switch (level) {
225  case 0: return 39;
226  case 1: return 30;
227  case 2: return 21;
228  case 3: return 12;
229  default: panic("bad level %d", level);
230  }
231 }
232 
235 {
236  if (tsz >= 16 && tsz <= 24) return LookupLevel::L0;
237  if (tsz >= 25 && tsz <= 33) return LookupLevel::L1;
238  if (tsz >= 34 && tsz <= 39) return LookupLevel::L2;
239 
240  panic("Unsupported TnSZ: %d\n", tsz);
241 }
242 
245 {
246  switch (sl0) {
247  case 0: return LookupLevel::L2;
248  case 1: return LookupLevel::L1;
249  case 2: return LookupLevel::L0;
250  default: panic("Unsupported VTCR_EL2.SL0: %d", sl0);
251  }
252 }
253 
256 {
257  return LookupLevel::L3;
258 }
259 
260 bool
262 {
263  switch (level) {
264  case 0: return pte & 0x1;
265  case 1: return pte & 0x1;
266  case 2: return pte & 0x1;
267  case 3: return (pte & 0x1) && (pte & 0x2);
268  default: panic("bad level %d", level);
269  }
270 }
271 
272 bool
274 {
275  switch (level) {
276  case 0: return false;
277  case 1: return false;
278  case 2: return !(pte & 0x2);
279  case 3: return true;
280  default: panic("bad level %d", level);
281  }
282 }
283 
284 bool
285 V8PageTableOps16k::isWritable(pte_t pte, unsigned level, bool stage2) const
286 {
287  return stage2 ? bits(pte, 7, 6) == 3 : bits(pte, 7) == 0;
288 }
289 
290 Addr
292 {
293  if (isLeaf(pte, level)) {
294  switch (level) {
295  // no level 0 here
296  case 1: return mbits(pte, 47, 36);
297  case 2: return mbits(pte, 47, 25);
298  case 3: return mbits(pte, 47, 14);
299  default: panic("bad level %d", level);
300  }
301  } else {
302  return mbits(pte, 47, 14);
303  }
304 }
305 
306 Addr
307 V8PageTableOps16k::index(Addr va, unsigned level, int tsz) const
308 {
309  switch (level) {
310  case 0: return bits(va, std::min(47, tsz - 1), 47) << 3; break;
311  case 1: return bits(va, std::min(46, tsz - 1), 36) << 3; break;
312  case 2: return bits(va, std::min(35, tsz - 1), 25) << 3; break;
313  case 3: return bits(va, std::min(24, tsz - 1), 14) << 3; break;
314  default: panic("bad level %d", level);
315  }
316 }
317 
318 Addr
320 {
321  switch (level) {
322  // no level 0 here
323  case 1: return ~mask(36);
324  // 16K granule supports contiguous entries also at L2; - 1G
325  case 2: return bits(pte, 52) ? ~mask(30) : ~mask(25);
326  // as well as at L3; - 2M
327  case 3: return bits(pte, 52) ? ~mask(21) : ~mask(14);
328  default: panic("bad level %d", level);
329  }
330 }
331 
332 unsigned
334 {
335  switch (level) {
336  case 0: return 47;
337  case 1: return 36;
338  case 2: return 25;
339  case 3: return 14;
340  default: panic("bad level %d", level);
341  }
342 }
343 
346 {
347  if (tsz == 16) return LookupLevel::L0;
348  if (tsz >= 17 && tsz <= 27) return LookupLevel::L1;
349  if (tsz >= 28 && tsz <= 38) return LookupLevel::L2;
350  if (tsz == 39) return LookupLevel::L3;
351 
352  panic("Unsupported TnSZ: %d\n", tsz);
353 }
354 
357 {
358  switch (sl0) {
359  case 0: return LookupLevel::L3;
360  case 1: return LookupLevel::L2;
361  case 2: return LookupLevel::L1;
362  default: panic("Unsupported VTCR_EL2.SL0: %d", sl0);
363  }
364 }
365 
368 {
369  return LookupLevel::L3;
370 }
371 
372 bool
374 {
375  switch (level) {
376  case 1: return pte & 0x1;
377  case 2: return pte & 0x1;
378  case 3: return (pte & 0x1) && (pte & 0x2);
379  default: panic("bad level %d", level);
380  }
381 }
382 
383 bool
385 {
386  switch (level) {
387  case 1: return false;
388  case 2: return !(pte & 0x2);
389  case 3: return true;
390  default: panic("bad level %d", level);
391  }
392 }
393 
394 bool
395 V8PageTableOps64k::isWritable(pte_t pte, unsigned level, bool stage2) const
396 {
397  return stage2 ? bits(pte, 7, 6)==3 : bits(pte, 7)==0;
398 }
399 
400 Addr
402 {
403  if (isLeaf(pte, level)) {
404  switch (level) {
405  // no level 1 here
406  case 2: return mbits(pte, 47, 29);
407  case 3: return mbits(pte, 47, 16);
408  default: panic("bad level %d", level);
409  }
410  } else {
411  return mbits(pte, 47, 16);
412  }
413 }
414 
415 Addr
416 V8PageTableOps64k::index(Addr va, unsigned level, int tsz) const
417 {
418  switch (level) {
419  case 1: return bits(va, std::min(47, tsz - 1), 42) << 3; break;
420  case 2: return bits(va, std::min(41, tsz - 1), 29) << 3; break;
421  case 3: return bits(va, std::min(28, tsz - 1), 16) << 3; break;
422  default: panic("bad level %d", level);
423  }
424 }
425 
426 Addr
428 {
429  switch (level) {
430  // no level 1 here
431  case 2: return ~mask(29);
432  case 3: return bits(pte, 52) ? ~mask(21) : ~mask(16);
433  default: panic("bad level %d", level);
434  }
435 }
436 
437 unsigned
439 {
440  switch (level) {
441  case 1: return 42;
442  case 2: return 29;
443  case 3: return 16;
444  default: panic("bad level %d", level);
445  }
446 }
447 
450 {
451  if (tsz >= 12 && tsz <= 21) return LookupLevel::L1;
452  if (tsz >= 22 && tsz <= 34) return LookupLevel::L2;
453  if (tsz >= 35 && tsz <= 39) return LookupLevel::L3;
454 
455  panic("Unsupported TnSZ: %d\n", tsz);
456 }
457 
460 {
461  switch (sl0) {
462  case 0: return LookupLevel::L3;
463  case 1: return LookupLevel::L2;
464  case 2: return LookupLevel::L1;
465  default: panic("Unsupported VTCR_EL2.SL0: %d", sl0);
466  }
467 }
468 
471 {
472  return LookupLevel::L3;
473 }
474 
475 const PageTableOps *
477 {
478  static V8PageTableOps4k ptOps4k;
479  static V8PageTableOps16k ptOps16k;
480  static V8PageTableOps64k ptOps64k;
481 
482  switch (trans_granule) {
483  case Grain4KB: return &ptOps4k;
484  case Grain16KB: return &ptOps16k;
485  case Grain64KB: return &ptOps64k;
486  default:
487  panic("Unknown translation granule size %d", trans_granule);
488  }
489 }
490 
491 } // namespace ArmISA
492 } // namespace gem5
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:76
constexpr T mbits(T val, unsigned first, unsigned last)
Mask off the given bits in place like bits() but without shifting.
Definition: bitfield.hh:103
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
const PageTableOps * getPageTableOps(GrainSize trans_granule)
Definition: pagetable.cc:476
Bitfield< 31 > n
Definition: misc_types.hh:462
Bitfield< 3, 0 > mask
Definition: pcstate.hh:63
const GrainSize GrainMap_tg1[]
Definition: pagetable.cc:51
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 L2
Definition: int.hh:113
constexpr RegId L1
Definition: int.hh:112
constexpr RegId L0
Definition: int.hh:111
constexpr RegId L3
Definition: int.hh:114
Bitfield< 20 > level
Definition: intmessage.hh:51
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
enums::ArmLookupLevel LookupLevel
Definition: pagetable.hh:92
Addr walkMask(unsigned level) const
Definition: pagetable.cc:55
virtual unsigned walkBits(unsigned level) const =0
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