smmu_v3_ptops.cc (14098:f4b9024d1a96) smmu_v3_ptops.cc (14100:6ef1220dc6da)
1/*
2 * Copyright (c) 2013, 2018-2019 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: Stan Czerniawski
38 */
39
40#include "dev/arm/smmu_v3_ptops.hh"
41
42#include "base/bitfield.hh"
43#include "base/logging.hh"
44
45bool
46V7LPageTableOps::isValid(pte_t pte, unsigned level) const
47{
48 switch (level) {
49 case 1: return pte & 0x1;
50 case 2: return pte & 0x1;
51 case 3: return (pte & 0x1) && (pte & 0x2);
52 default: panic("bad level %d", level);
53 }
54}
55
56bool
57V7LPageTableOps::isLeaf(pte_t pte, unsigned level) const
58{
59 switch (level) {
60 case 1: return !(pte & 0x2);
61 case 2: return !(pte & 0x2);
62 case 3: return true;
63 default: panic("bad level %d", level);
64 }
65}
66
67bool
68V7LPageTableOps::isWritable(pte_t pte, unsigned level, bool stage2) const
69{
70 return stage2 ? bits(pte, 7, 6)==3 : bits(pte, 7)==0;
71}
72
73Addr
74V7LPageTableOps::nextLevelPointer(pte_t pte, unsigned level) const
75{
76 if (isLeaf(pte, level)) {
77 switch (level) {
78 case 1: return mbits(pte, 39, 30);
79 case 2: return mbits(pte, 39, 21);
80 case 3: return mbits(pte, 39, 12);
81 default: panic("bad level %d", level);
82 }
83 } else {
84 return mbits(pte, 39, 12);
85 }
86}
87
88Addr
89V7LPageTableOps::index(Addr va, unsigned level) const
90{
91 // In theory this should be configurable...
92 const int n = 12;
93
94 switch (level) {
95 case 1: return bits(va, 26+n, 30) << 3; break;
96 case 2: return bits(va, 29, 21) << 3; break;
97 case 3: return bits(va, 20, 12) << 3; break;
98 default: panic("bad level %d", level);
99 }
100}
101
102Addr
103V7LPageTableOps::pageMask(pte_t pte, unsigned level) const
104{
105 switch (level) {
106 case 1: return ~mask(30);
107 case 2: return ~mask(21);
108 case 3: return bits(pte, 52) ? ~mask(16) : ~mask(12);
109 default: panic("bad level %d", level);
110 }
111}
112
113Addr
114V7LPageTableOps::walkMask(unsigned level) const
115{
116 switch (level) {
117 case 1: return mask(39, 30);
118 case 2: return mask(39, 21);
119 case 3: return mask(39, 12);
120 default: panic("bad level %d", level);
121 }
122}
123
124unsigned
1/*
2 * Copyright (c) 2013, 2018-2019 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: Stan Czerniawski
38 */
39
40#include "dev/arm/smmu_v3_ptops.hh"
41
42#include "base/bitfield.hh"
43#include "base/logging.hh"
44
45bool
46V7LPageTableOps::isValid(pte_t pte, unsigned level) const
47{
48 switch (level) {
49 case 1: return pte & 0x1;
50 case 2: return pte & 0x1;
51 case 3: return (pte & 0x1) && (pte & 0x2);
52 default: panic("bad level %d", level);
53 }
54}
55
56bool
57V7LPageTableOps::isLeaf(pte_t pte, unsigned level) const
58{
59 switch (level) {
60 case 1: return !(pte & 0x2);
61 case 2: return !(pte & 0x2);
62 case 3: return true;
63 default: panic("bad level %d", level);
64 }
65}
66
67bool
68V7LPageTableOps::isWritable(pte_t pte, unsigned level, bool stage2) const
69{
70 return stage2 ? bits(pte, 7, 6)==3 : bits(pte, 7)==0;
71}
72
73Addr
74V7LPageTableOps::nextLevelPointer(pte_t pte, unsigned level) const
75{
76 if (isLeaf(pte, level)) {
77 switch (level) {
78 case 1: return mbits(pte, 39, 30);
79 case 2: return mbits(pte, 39, 21);
80 case 3: return mbits(pte, 39, 12);
81 default: panic("bad level %d", level);
82 }
83 } else {
84 return mbits(pte, 39, 12);
85 }
86}
87
88Addr
89V7LPageTableOps::index(Addr va, unsigned level) const
90{
91 // In theory this should be configurable...
92 const int n = 12;
93
94 switch (level) {
95 case 1: return bits(va, 26+n, 30) << 3; break;
96 case 2: return bits(va, 29, 21) << 3; break;
97 case 3: return bits(va, 20, 12) << 3; break;
98 default: panic("bad level %d", level);
99 }
100}
101
102Addr
103V7LPageTableOps::pageMask(pte_t pte, unsigned level) const
104{
105 switch (level) {
106 case 1: return ~mask(30);
107 case 2: return ~mask(21);
108 case 3: return bits(pte, 52) ? ~mask(16) : ~mask(12);
109 default: panic("bad level %d", level);
110 }
111}
112
113Addr
114V7LPageTableOps::walkMask(unsigned level) const
115{
116 switch (level) {
117 case 1: return mask(39, 30);
118 case 2: return mask(39, 21);
119 case 3: return mask(39, 12);
120 default: panic("bad level %d", level);
121 }
122}
123
124unsigned
125V7LPageTableOps::firstLevel() const
125V7LPageTableOps::firstLevel(uint8_t tsz) const
126{
127 return 1;
128}
129
130unsigned
131V7LPageTableOps::lastLevel() const
132{
133 return 3;
134}
135
136bool
137V8PageTableOps4k::isValid(pte_t pte, unsigned level) const
138{
139 switch (level) {
140 case 0: return pte & 0x1;
141 case 1: return pte & 0x1;
142 case 2: return pte & 0x1;
143 case 3: return (pte & 0x1) && (pte & 0x2);
144 default: panic("bad level %d", level);
145 }
146}
147
148bool
149V8PageTableOps4k::isLeaf(pte_t pte, unsigned level) const
150{
151 switch (level) {
152 case 0: return false;
153 case 1: return !(pte & 0x2);
154 case 2: return !(pte & 0x2);
155 case 3: return true;
156 default: panic("bad level %d", level);
157 }
158}
159
160bool
161V8PageTableOps4k::isWritable(pte_t pte, unsigned level, bool stage2) const
162{
163 return stage2 ? bits(pte, 7, 6)==3 : bits(pte, 7)==0;
164}
165
166Addr
167V8PageTableOps4k::nextLevelPointer(pte_t pte, unsigned level) const
168{
169 if (isLeaf(pte, level)) {
170 switch (level) {
171 // no level 0 here
172 case 1: return mbits(pte, 47, 30);
173 case 2: return mbits(pte, 47, 21);
174 case 3: return mbits(pte, 47, 12);
175 default: panic("bad level %d", level);
176 }
177 } else {
178 return mbits(pte, 47, 12);
179 }
180}
181
182Addr
183V8PageTableOps4k::index(Addr va, unsigned level) const
184{
185 switch (level) {
186 case 0: return bits(va, 47, 39) << 3; break;
187 case 1: return bits(va, 38, 30) << 3; break;
188 case 2: return bits(va, 29, 21) << 3; break;
189 case 3: return bits(va, 20, 12) << 3; break;
190 default: panic("bad level %d", level);
191 }
192}
193
194Addr
195V8PageTableOps4k::pageMask(pte_t pte, unsigned level) const
196{
197 switch (level) {
198 // no level 0 here
199 case 1: return ~mask(30);
200 case 2: return ~mask(21);
201 case 3: return bits(pte, 52) ? ~mask(16) : ~mask(12);
202 default: panic("bad level %d", level);
203 }
204}
205
206Addr
207V8PageTableOps4k::walkMask(unsigned level) const
208{
209 switch (level) {
210 case 0: return mask(47, 39);
211 case 1: return mask(47, 30);
212 case 2: return mask(47, 21);
213 case 3: return mask(47, 12);
214 default: panic("bad level %d", level);
215 }
216}
217
218unsigned
126{
127 return 1;
128}
129
130unsigned
131V7LPageTableOps::lastLevel() const
132{
133 return 3;
134}
135
136bool
137V8PageTableOps4k::isValid(pte_t pte, unsigned level) const
138{
139 switch (level) {
140 case 0: return pte & 0x1;
141 case 1: return pte & 0x1;
142 case 2: return pte & 0x1;
143 case 3: return (pte & 0x1) && (pte & 0x2);
144 default: panic("bad level %d", level);
145 }
146}
147
148bool
149V8PageTableOps4k::isLeaf(pte_t pte, unsigned level) const
150{
151 switch (level) {
152 case 0: return false;
153 case 1: return !(pte & 0x2);
154 case 2: return !(pte & 0x2);
155 case 3: return true;
156 default: panic("bad level %d", level);
157 }
158}
159
160bool
161V8PageTableOps4k::isWritable(pte_t pte, unsigned level, bool stage2) const
162{
163 return stage2 ? bits(pte, 7, 6)==3 : bits(pte, 7)==0;
164}
165
166Addr
167V8PageTableOps4k::nextLevelPointer(pte_t pte, unsigned level) const
168{
169 if (isLeaf(pte, level)) {
170 switch (level) {
171 // no level 0 here
172 case 1: return mbits(pte, 47, 30);
173 case 2: return mbits(pte, 47, 21);
174 case 3: return mbits(pte, 47, 12);
175 default: panic("bad level %d", level);
176 }
177 } else {
178 return mbits(pte, 47, 12);
179 }
180}
181
182Addr
183V8PageTableOps4k::index(Addr va, unsigned level) const
184{
185 switch (level) {
186 case 0: return bits(va, 47, 39) << 3; break;
187 case 1: return bits(va, 38, 30) << 3; break;
188 case 2: return bits(va, 29, 21) << 3; break;
189 case 3: return bits(va, 20, 12) << 3; break;
190 default: panic("bad level %d", level);
191 }
192}
193
194Addr
195V8PageTableOps4k::pageMask(pte_t pte, unsigned level) const
196{
197 switch (level) {
198 // no level 0 here
199 case 1: return ~mask(30);
200 case 2: return ~mask(21);
201 case 3: return bits(pte, 52) ? ~mask(16) : ~mask(12);
202 default: panic("bad level %d", level);
203 }
204}
205
206Addr
207V8PageTableOps4k::walkMask(unsigned level) const
208{
209 switch (level) {
210 case 0: return mask(47, 39);
211 case 1: return mask(47, 30);
212 case 2: return mask(47, 21);
213 case 3: return mask(47, 12);
214 default: panic("bad level %d", level);
215 }
216}
217
218unsigned
219V8PageTableOps4k::firstLevel() const
219V8PageTableOps4k::firstLevel(uint8_t tsz) const
220{
220{
221 return 0;
221 if (tsz >= 16 && tsz <= 24) return 0;
222 if (tsz >= 25 && tsz <= 33) return 1;
223 if (tsz >= 34 && tsz <= 39) return 2;
224
225 panic("Unsupported TnSZ: %d\n", tsz);
222}
223
224unsigned
225V8PageTableOps4k::lastLevel() const
226{
227 return 3;
228}
229
230bool
231V8PageTableOps16k::isValid(pte_t pte, unsigned level) const
232{
233 switch (level) {
234 case 0: return pte & 0x1;
235 case 1: return pte & 0x1;
236 case 2: return pte & 0x1;
237 case 3: return (pte & 0x1) && (pte & 0x2);
238 default: panic("bad level %d", level);
239 }
240}
241
242bool
243V8PageTableOps16k::isLeaf(pte_t pte, unsigned level) const
244{
245 switch (level) {
246 case 0: return false;
247 case 1: return false;
248 case 2: return !(pte & 0x2);
249 case 3: return true;
250 default: panic("bad level %d", level);
251 }
252}
253
254bool
255V8PageTableOps16k::isWritable(pte_t pte, unsigned level, bool stage2) const
256{
257 return stage2 ? bits(pte, 7, 6) == 3 : bits(pte, 7) == 0;
258}
259
260Addr
261V8PageTableOps16k::nextLevelPointer(pte_t pte, unsigned level) const
262{
263 if (isLeaf(pte, level)) {
264 switch (level) {
265 // no level 0 here
266 case 1: return mbits(pte, 47, 36);
267 case 2: return mbits(pte, 47, 25);
268 case 3: return mbits(pte, 47, 14);
269 default: panic("bad level %d", level);
270 }
271 } else {
272 return mbits(pte, 47, 12);
273 }
274}
275
276Addr
277V8PageTableOps16k::index(Addr va, unsigned level) const
278{
279 switch (level) {
280 case 0: return bits(va, 47, 47) << 3; break;
281 case 1: return bits(va, 46, 36) << 3; break;
282 case 2: return bits(va, 35, 25) << 3; break;
283 case 3: return bits(va, 24, 14) << 3; break;
284 default: panic("bad level %d", level);
285 }
286}
287
288Addr
289V8PageTableOps16k::pageMask(pte_t pte, unsigned level) const
290{
291 switch (level) {
292 // no level 0 here
293 case 1: return ~mask(36);
294 // 16K granule supports contiguous entries also at L2; - 1G
295 case 2: return bits(pte, 52) ? ~mask(30) : ~mask(25);
296 // as well as at L3; - 2M
297 case 3: return bits(pte, 52) ? ~mask(21) : ~mask(14);
298 default: panic("bad level %d", level);
299 }
300}
301
302Addr
303V8PageTableOps16k::walkMask(unsigned level) const
304{
305 switch (level) {
306 case 0: return ~mask(47);
307 case 1: return ~mask(36);
308 case 2: return ~mask(25);
309 case 3: return ~mask(14);
310 default: panic("bad level %d", level);
311 }
312}
313
314unsigned
226}
227
228unsigned
229V8PageTableOps4k::lastLevel() const
230{
231 return 3;
232}
233
234bool
235V8PageTableOps16k::isValid(pte_t pte, unsigned level) const
236{
237 switch (level) {
238 case 0: return pte & 0x1;
239 case 1: return pte & 0x1;
240 case 2: return pte & 0x1;
241 case 3: return (pte & 0x1) && (pte & 0x2);
242 default: panic("bad level %d", level);
243 }
244}
245
246bool
247V8PageTableOps16k::isLeaf(pte_t pte, unsigned level) const
248{
249 switch (level) {
250 case 0: return false;
251 case 1: return false;
252 case 2: return !(pte & 0x2);
253 case 3: return true;
254 default: panic("bad level %d", level);
255 }
256}
257
258bool
259V8PageTableOps16k::isWritable(pte_t pte, unsigned level, bool stage2) const
260{
261 return stage2 ? bits(pte, 7, 6) == 3 : bits(pte, 7) == 0;
262}
263
264Addr
265V8PageTableOps16k::nextLevelPointer(pte_t pte, unsigned level) const
266{
267 if (isLeaf(pte, level)) {
268 switch (level) {
269 // no level 0 here
270 case 1: return mbits(pte, 47, 36);
271 case 2: return mbits(pte, 47, 25);
272 case 3: return mbits(pte, 47, 14);
273 default: panic("bad level %d", level);
274 }
275 } else {
276 return mbits(pte, 47, 12);
277 }
278}
279
280Addr
281V8PageTableOps16k::index(Addr va, unsigned level) const
282{
283 switch (level) {
284 case 0: return bits(va, 47, 47) << 3; break;
285 case 1: return bits(va, 46, 36) << 3; break;
286 case 2: return bits(va, 35, 25) << 3; break;
287 case 3: return bits(va, 24, 14) << 3; break;
288 default: panic("bad level %d", level);
289 }
290}
291
292Addr
293V8PageTableOps16k::pageMask(pte_t pte, unsigned level) const
294{
295 switch (level) {
296 // no level 0 here
297 case 1: return ~mask(36);
298 // 16K granule supports contiguous entries also at L2; - 1G
299 case 2: return bits(pte, 52) ? ~mask(30) : ~mask(25);
300 // as well as at L3; - 2M
301 case 3: return bits(pte, 52) ? ~mask(21) : ~mask(14);
302 default: panic("bad level %d", level);
303 }
304}
305
306Addr
307V8PageTableOps16k::walkMask(unsigned level) const
308{
309 switch (level) {
310 case 0: return ~mask(47);
311 case 1: return ~mask(36);
312 case 2: return ~mask(25);
313 case 3: return ~mask(14);
314 default: panic("bad level %d", level);
315 }
316}
317
318unsigned
315V8PageTableOps16k::firstLevel() const
319V8PageTableOps16k::firstLevel(uint8_t tsz) const
316{
320{
317 return 0;
321 if (tsz == 16) return 0;
322 if (tsz >= 17 && tsz <= 27) return 1;
323 if (tsz >= 28 && tsz <= 38) return 2;
324 if (tsz == 39) return 3;
325
326 panic("Unsupported TnSZ: %d\n", tsz);
318}
319
320unsigned
321V8PageTableOps16k::lastLevel() const
322{
323 return 3;
324}
325
326bool
327V8PageTableOps64k::isValid(pte_t pte, unsigned level) const
328{
329 switch (level) {
330 case 1: return pte & 0x1;
331 case 2: return pte & 0x1;
332 case 3: return (pte & 0x1) && (pte & 0x2);
333 default: panic("bad level %d", level);
334 }
335}
336
337bool
338V8PageTableOps64k::isLeaf(pte_t pte, unsigned level) const
339{
340 switch (level) {
341 case 1: return false;
342 case 2: return !(pte & 0x2);
343 case 3: return true;
344 default: panic("bad level %d", level);
345 }
346}
347
348bool
349V8PageTableOps64k::isWritable(pte_t pte, unsigned level, bool stage2) const
350{
351 return stage2 ? bits(pte, 7, 6)==3 : bits(pte, 7)==0;
352}
353
354Addr
355V8PageTableOps64k::nextLevelPointer(pte_t pte, unsigned level) const
356{
357 if (isLeaf(pte, level)) {
358 switch (level) {
359 // no level 1 here
360 case 2: return mbits(pte, 47, 29);
361 case 3: return mbits(pte, 47, 16);
362 default: panic("bad level %d", level);
363 }
364 } else {
365 return mbits(pte, 47, 16);
366 }
367}
368
369Addr
370V8PageTableOps64k::index(Addr va, unsigned level) const
371{
372 switch (level) {
373 case 1: return bits(va, 47, 42) << 3; break;
374 case 2: return bits(va, 41, 29) << 3; break;
375 case 3: return bits(va, 28, 16) << 3; break;
376 default: panic("bad level %d", level);
377 }
378}
379
380Addr
381V8PageTableOps64k::pageMask(pte_t pte, unsigned level) const
382{
383 switch (level) {
384 // no level 1 here
385 case 2: return ~mask(29);
386 case 3: return bits(pte, 52) ? ~mask(21) : ~mask(16);
387 default: panic("bad level %d", level);
388 }
389}
390
391Addr
392V8PageTableOps64k::walkMask(unsigned level) const
393{
394 switch (level) {
395 case 1: return mask(47, 42);
396 case 2: return mask(47, 29);
397 case 3: return mask(47, 16);
398 default: panic("bad level %d", level);
399 }
400}
401
402unsigned
327}
328
329unsigned
330V8PageTableOps16k::lastLevel() const
331{
332 return 3;
333}
334
335bool
336V8PageTableOps64k::isValid(pte_t pte, unsigned level) const
337{
338 switch (level) {
339 case 1: return pte & 0x1;
340 case 2: return pte & 0x1;
341 case 3: return (pte & 0x1) && (pte & 0x2);
342 default: panic("bad level %d", level);
343 }
344}
345
346bool
347V8PageTableOps64k::isLeaf(pte_t pte, unsigned level) const
348{
349 switch (level) {
350 case 1: return false;
351 case 2: return !(pte & 0x2);
352 case 3: return true;
353 default: panic("bad level %d", level);
354 }
355}
356
357bool
358V8PageTableOps64k::isWritable(pte_t pte, unsigned level, bool stage2) const
359{
360 return stage2 ? bits(pte, 7, 6)==3 : bits(pte, 7)==0;
361}
362
363Addr
364V8PageTableOps64k::nextLevelPointer(pte_t pte, unsigned level) const
365{
366 if (isLeaf(pte, level)) {
367 switch (level) {
368 // no level 1 here
369 case 2: return mbits(pte, 47, 29);
370 case 3: return mbits(pte, 47, 16);
371 default: panic("bad level %d", level);
372 }
373 } else {
374 return mbits(pte, 47, 16);
375 }
376}
377
378Addr
379V8PageTableOps64k::index(Addr va, unsigned level) const
380{
381 switch (level) {
382 case 1: return bits(va, 47, 42) << 3; break;
383 case 2: return bits(va, 41, 29) << 3; break;
384 case 3: return bits(va, 28, 16) << 3; break;
385 default: panic("bad level %d", level);
386 }
387}
388
389Addr
390V8PageTableOps64k::pageMask(pte_t pte, unsigned level) const
391{
392 switch (level) {
393 // no level 1 here
394 case 2: return ~mask(29);
395 case 3: return bits(pte, 52) ? ~mask(21) : ~mask(16);
396 default: panic("bad level %d", level);
397 }
398}
399
400Addr
401V8PageTableOps64k::walkMask(unsigned level) const
402{
403 switch (level) {
404 case 1: return mask(47, 42);
405 case 2: return mask(47, 29);
406 case 3: return mask(47, 16);
407 default: panic("bad level %d", level);
408 }
409}
410
411unsigned
403V8PageTableOps64k::firstLevel() const
412V8PageTableOps64k::firstLevel(uint8_t tsz) const
404{
413{
405 return 1;
414 if (tsz >= 12 && tsz <= 21) return 1;
415 if (tsz >= 22 && tsz <= 34) return 2;
416 if (tsz >= 35 && tsz <= 39) return 3;
417
418 panic("Unsupported TnSZ: %d\n", tsz);
406}
407
408unsigned
409V8PageTableOps64k::lastLevel() const
410{
411 return 3;
412}
419}
420
421unsigned
422V8PageTableOps64k::lastLevel() const
423{
424 return 3;
425}