129 |
129 |
/* SPARC reference MMU table walk: Context table->L1->L2->PTE */
|
130 |
130 |
/* Context base + context number */
|
131 |
131 |
pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4);
|
132 |
|
cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
|
133 |
|
bswap32s(&pde);
|
|
132 |
pde = ldl_phys(pde_ptr);
|
134 |
133 |
|
135 |
134 |
/* Ctx pde */
|
136 |
135 |
switch (pde & PTE_ENTRYTYPE_MASK) {
|
... | ... | |
142 |
141 |
return 4;
|
143 |
142 |
case 1: /* L0 PDE */
|
144 |
143 |
pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
|
145 |
|
cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
|
146 |
|
bswap32s(&pde);
|
|
144 |
pde = ldl_phys(pde_ptr);
|
147 |
145 |
|
148 |
146 |
switch (pde & PTE_ENTRYTYPE_MASK) {
|
149 |
147 |
default:
|
... | ... | |
153 |
151 |
return 4;
|
154 |
152 |
case 1: /* L1 PDE */
|
155 |
153 |
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
|
156 |
|
cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
|
157 |
|
bswap32s(&pde);
|
|
154 |
pde = ldl_phys(pde_ptr);
|
158 |
155 |
|
159 |
156 |
switch (pde & PTE_ENTRYTYPE_MASK) {
|
160 |
157 |
default:
|
... | ... | |
164 |
161 |
return 4;
|
165 |
162 |
case 1: /* L2 PDE */
|
166 |
163 |
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
|
167 |
|
cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
|
168 |
|
bswap32s(&pde);
|
|
164 |
pde = ldl_phys(pde_ptr);
|
169 |
165 |
|
170 |
166 |
switch (pde & PTE_ENTRYTYPE_MASK) {
|
171 |
167 |
default:
|
... | ... | |
193 |
189 |
/* update page modified and dirty bits */
|
194 |
190 |
is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
|
195 |
191 |
if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
|
196 |
|
uint32_t tmppde;
|
197 |
192 |
pde |= PG_ACCESSED_MASK;
|
198 |
193 |
if (is_dirty)
|
199 |
194 |
pde |= PG_MODIFIED_MASK;
|
200 |
|
tmppde = bswap32(pde);
|
201 |
|
cpu_physical_memory_write(pde_ptr, (uint8_t *)&tmppde, 4);
|
|
195 |
stl_phys_notdirty(pde_ptr, pde);
|
202 |
196 |
}
|
203 |
197 |
/* check access */
|
204 |
198 |
*access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1);
|
... | ... | |
356 |
350 |
|
357 |
351 |
/* Context base + context number */
|
358 |
352 |
pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4);
|
359 |
|
cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
|
360 |
|
bswap32s(&pde);
|
|
353 |
pde = ldl_phys(pde_ptr);
|
|
354 |
|
361 |
355 |
switch (pde & PTE_ENTRYTYPE_MASK) {
|
362 |
356 |
default:
|
363 |
357 |
case 0: /* Invalid */
|
... | ... | |
368 |
362 |
if (mmulev == 3)
|
369 |
363 |
return pde;
|
370 |
364 |
pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
|
371 |
|
cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
|
372 |
|
bswap32s(&pde);
|
|
365 |
pde = ldl_phys(pde_ptr);
|
373 |
366 |
|
374 |
367 |
switch (pde & PTE_ENTRYTYPE_MASK) {
|
375 |
368 |
default:
|
... | ... | |
382 |
375 |
if (mmulev == 2)
|
383 |
376 |
return pde;
|
384 |
377 |
pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
|
385 |
|
cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
|
386 |
|
bswap32s(&pde);
|
|
378 |
pde = ldl_phys(pde_ptr);
|
387 |
379 |
|
388 |
380 |
switch (pde & PTE_ENTRYTYPE_MASK) {
|
389 |
381 |
default:
|
... | ... | |
396 |
388 |
if (mmulev == 1)
|
397 |
389 |
return pde;
|
398 |
390 |
pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
|
399 |
|
cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
|
400 |
|
bswap32s(&pde);
|
|
391 |
pde = ldl_phys(pde_ptr);
|
401 |
392 |
|
402 |
393 |
switch (pde & PTE_ENTRYTYPE_MASK) {
|
403 |
394 |
default:
|
... | ... | |
424 |
415 |
|
425 |
416 |
printf("MMU dump:\n");
|
426 |
417 |
pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4);
|
427 |
|
cpu_physical_memory_read(pde_ptr, (uint8_t *)&pde, 4);
|
428 |
|
bswap32s(&pde);
|
|
418 |
pde = ldl_phys(pde_ptr);
|
429 |
419 |
printf("Root ptr: 0x%08x, ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]);
|
430 |
420 |
for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
|
431 |
421 |
pde_ptr = mmu_probe(va, 2);
|