Statistics
| Branch: | Revision:

root / target-sparc / helper.c @ 3475187d

History | View | Annotate | Download (17 kB)

1
/*
2
 *  sparc helpers
3
 * 
4
 *  Copyright (c) 2003 Fabrice Bellard
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU Lesser General Public
8
 * License as published by the Free Software Foundation; either
9
 * version 2 of the License, or (at your option) any later version.
10
 *
11
 * This library is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 * Lesser General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Lesser General Public
17
 * License along with this library; if not, write to the Free Software
18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 */
20
#include "exec.h"
21

    
22
//#define DEBUG_PCALL
23
//#define DEBUG_MMU
24

    
25
/* Sparc MMU emulation */
26

    
27
/* thread support */
28

    
29
spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED;
30

    
31
void cpu_lock(void)
32
{
33
    spin_lock(&global_cpu_lock);
34
}
35

    
36
void cpu_unlock(void)
37
{
38
    spin_unlock(&global_cpu_lock);
39
}
40

    
41
#if defined(CONFIG_USER_ONLY) 
42

    
43
int cpu_sparc_handle_mmu_fault(CPUState *env, target_ulong address, int rw,
44
                               int is_user, int is_softmmu)
45
{
46
    if (rw & 2)
47
        env->exception_index = TT_TFAULT;
48
    else
49
        env->exception_index = TT_DFAULT;
50
    return 1;
51
}
52

    
53
#else
54

    
55
#define MMUSUFFIX _mmu
56
#define GETPC() (__builtin_return_address(0))
57

    
58
#define SHIFT 0
59
#include "softmmu_template.h"
60

    
61
#define SHIFT 1
62
#include "softmmu_template.h"
63

    
64
#define SHIFT 2
65
#include "softmmu_template.h"
66

    
67
#define SHIFT 3
68
#include "softmmu_template.h"
69

    
70

    
71
/* try to fill the TLB and return an exception if error. If retaddr is
72
   NULL, it means that the function was called in C code (i.e. not
73
   from generated code or from helper.c) */
74
/* XXX: fix it to restore all registers */
75
void tlb_fill(target_ulong addr, int is_write, int is_user, void *retaddr)
76
{
77
    TranslationBlock *tb;
78
    int ret;
79
    unsigned long pc;
80
    CPUState *saved_env;
81

    
82
    /* XXX: hack to restore env in all cases, even if not called from
83
       generated code */
84
    saved_env = env;
85
    env = cpu_single_env;
86

    
87
    ret = cpu_sparc_handle_mmu_fault(env, addr, is_write, is_user, 1);
88
    if (ret) {
89
        if (retaddr) {
90
            /* now we have a real cpu fault */
91
            pc = (unsigned long)retaddr;
92
            tb = tb_find_pc(pc);
93
            if (tb) {
94
                /* the PC is inside the translated code. It means that we have
95
                   a virtual CPU fault */
96
                cpu_restore_state(tb, env, pc, (void *)T2);
97
            }
98
        }
99
        cpu_loop_exit();
100
    }
101
    env = saved_env;
102
}
103

    
104
#ifndef TARGET_SPARC64
105
static const int access_table[8][8] = {
106
    { 0, 0, 0, 0, 2, 0, 3, 3 },
107
    { 0, 0, 0, 0, 2, 0, 0, 0 },
108
    { 2, 2, 0, 0, 0, 2, 3, 3 },
109
    { 2, 2, 0, 0, 0, 2, 0, 0 },
110
    { 2, 0, 2, 0, 2, 2, 3, 3 },
111
    { 2, 0, 2, 0, 2, 0, 2, 0 },
112
    { 2, 2, 2, 0, 2, 2, 3, 3 },
113
    { 2, 2, 2, 0, 2, 2, 2, 0 }
114
};
115

    
116
/* 1 = write OK */
117
static const int rw_table[2][8] = {
118
    { 0, 1, 0, 1, 0, 1, 0, 1 },
119
    { 0, 1, 0, 1, 0, 0, 0, 0 }
120
};
121

    
122
int get_physical_address (CPUState *env, target_phys_addr_t *physical, int *prot,
123
                          int *access_index, target_ulong address, int rw,
124
                          int is_user)
125
{
126
    int access_perms = 0;
127
    target_phys_addr_t pde_ptr;
128
    uint32_t pde;
129
    target_ulong virt_addr;
130
    int error_code = 0, is_dirty;
131
    unsigned long page_offset;
132

    
133
    virt_addr = address & TARGET_PAGE_MASK;
134
    if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */
135
        *physical = address;
136
        *prot = PAGE_READ | PAGE_WRITE;
137
        return 0;
138
    }
139

    
140
    *access_index = ((rw & 1) << 2) | (rw & 2) | (is_user? 0 : 1);
141
    *physical = 0xfffff000;
142

    
143
    /* SPARC reference MMU table walk: Context table->L1->L2->PTE */
144
    /* Context base + context number */
145
    pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
146
    pde = ldl_phys(pde_ptr);
147

    
148
    /* Ctx pde */
149
    switch (pde & PTE_ENTRYTYPE_MASK) {
150
    default:
151
    case 0: /* Invalid */
152
        return 1 << 2;
153
    case 2: /* L0 PTE, maybe should not happen? */
154
    case 3: /* Reserved */
155
        return 4 << 2;
156
    case 1: /* L0 PDE */
157
        pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
158
        pde = ldl_phys(pde_ptr);
159

    
160
        switch (pde & PTE_ENTRYTYPE_MASK) {
161
        default:
162
        case 0: /* Invalid */
163
            return (1 << 8) | (1 << 2);
164
        case 3: /* Reserved */
165
            return (1 << 8) | (4 << 2);
166
        case 1: /* L1 PDE */
167
            pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
168
            pde = ldl_phys(pde_ptr);
169

    
170
            switch (pde & PTE_ENTRYTYPE_MASK) {
171
            default:
172
            case 0: /* Invalid */
173
                return (2 << 8) | (1 << 2);
174
            case 3: /* Reserved */
175
                return (2 << 8) | (4 << 2);
176
            case 1: /* L2 PDE */
177
                pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
178
                pde = ldl_phys(pde_ptr);
179

    
180
                switch (pde & PTE_ENTRYTYPE_MASK) {
181
                default:
182
                case 0: /* Invalid */
183
                    return (3 << 8) | (1 << 2);
184
                case 1: /* PDE, should not happen */
185
                case 3: /* Reserved */
186
                    return (3 << 8) | (4 << 2);
187
                case 2: /* L3 PTE */
188
                    virt_addr = address & TARGET_PAGE_MASK;
189
                    page_offset = (address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1);
190
                }
191
                break;
192
            case 2: /* L2 PTE */
193
                virt_addr = address & ~0x3ffff;
194
                page_offset = address & 0x3ffff;
195
            }
196
            break;
197
        case 2: /* L1 PTE */
198
            virt_addr = address & ~0xffffff;
199
            page_offset = address & 0xffffff;
200
        }
201
    }
202

    
203
    /* update page modified and dirty bits */
204
    is_dirty = (rw & 1) && !(pde & PG_MODIFIED_MASK);
205
    if (!(pde & PG_ACCESSED_MASK) || is_dirty) {
206
        pde |= PG_ACCESSED_MASK;
207
        if (is_dirty)
208
            pde |= PG_MODIFIED_MASK;
209
        stl_phys_notdirty(pde_ptr, pde);
210
    }
211
    /* check access */
212
    access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;
213
    error_code = access_table[*access_index][access_perms];
214
    if (error_code && !(env->mmuregs[0] & MMU_NF))
215
        return error_code;
216

    
217
    /* the page can be put in the TLB */
218
    *prot = PAGE_READ;
219
    if (pde & PG_MODIFIED_MASK) {
220
        /* only set write access if already dirty... otherwise wait
221
           for dirty access */
222
        if (rw_table[is_user][access_perms])
223
                *prot |= PAGE_WRITE;
224
    }
225

    
226
    /* Even if large ptes, we map only one 4KB page in the cache to
227
       avoid filling it too fast */
228
    *physical = ((pde & PTE_ADDR_MASK) << 4) + page_offset;
229
    return error_code;
230
}
231

    
232
/* Perform address translation */
233
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
234
                              int is_user, int is_softmmu)
235
{
236
    target_ulong virt_addr;
237
    target_phys_addr_t paddr;
238
    unsigned long vaddr;
239
    int error_code = 0, prot, ret = 0, access_index;
240

    
241
    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
242
    if (error_code == 0) {
243
        virt_addr = address & TARGET_PAGE_MASK;
244
        vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
245
        ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);
246
        return ret;
247
    }
248

    
249
    if (env->mmuregs[3]) /* Fault status register */
250
        env->mmuregs[3] = 1; /* overflow (not read before another fault) */
251
    env->mmuregs[3] |= (access_index << 5) | error_code | 2;
252
    env->mmuregs[4] = address; /* Fault address register */
253

    
254
    if ((env->mmuregs[0] & MMU_NF) || env->psret == 0)  {
255
        // No fault mode: if a mapping is available, just override
256
        // permissions. If no mapping is available, redirect accesses to
257
        // neverland. Fake/overridden mappings will be flushed when
258
        // switching to normal mode.
259
        vaddr = address & TARGET_PAGE_MASK;
260
        prot = PAGE_READ | PAGE_WRITE;
261
        ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);
262
        return ret;
263
    } else {
264
        if (rw & 2)
265
            env->exception_index = TT_TFAULT;
266
        else
267
            env->exception_index = TT_DFAULT;
268
        return 1;
269
    }
270
}
271
#else
272
static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical, int *prot,
273
                          int *access_index, target_ulong address, int rw,
274
                          int is_user)
275
{
276
    target_ulong mask;
277
    unsigned int i;
278

    
279
    if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */
280
        *physical = address & 0xffffffff;
281
        *prot = PAGE_READ | PAGE_WRITE;
282
        return 0;
283
    }
284

    
285
    for (i = 0; i < 64; i++) {
286
        if ((env->dtlb_tte[i] & 0x8000000000000000ULL) != 0) {
287
            switch (env->dtlb_tte[i] >> 60) {
288
            default:
289
            case 0x4: // 8k
290
                mask = 0xffffffffffffe000ULL;
291
                break;
292
            case 0x5: // 64k
293
                mask = 0xffffffffffff0000ULL;
294
                break;
295
            case 0x6: // 512k
296
                mask = 0xfffffffffff80000ULL;
297
                break;
298
            case 0x7: // 4M
299
                mask = 0xffffffffffc00000ULL;
300
                break;
301
            }
302
            // ctx match, vaddr match?
303
            if (env->dmmuregs[1] == (env->dtlb_tag[i] & 0x1fff) &&
304
                (address & mask) == (env->dtlb_tag[i] & ~0x1fffULL)) {
305
                // access ok?
306
                if (((env->dtlb_tte[i] & 0x4) && !(env->pstate & PS_PRIV)) ||
307
                    (!(env->dtlb_tte[i] & 0x2) && (rw == 1))) {
308
                    env->exception_index = TT_DFAULT;
309
                    return 1;
310
                }
311
                *physical = env->dtlb_tte[i] & 0xffffe000;
312
                *prot = PAGE_READ;
313
                if (env->dtlb_tte[i] & 0x2)
314
                    *prot |= PAGE_WRITE;
315
                return 0;
316
            }
317
        }
318
    }
319
    env->exception_index = TT_DFAULT;
320
    return 1;
321
}
322

    
323
static int get_physical_address_code(CPUState *env, target_phys_addr_t *physical, int *prot,
324
                          int *access_index, target_ulong address, int rw,
325
                          int is_user)
326
{
327
    target_ulong mask;
328
    unsigned int i;
329

    
330
    if ((env->lsu & IMMU_E) == 0) { /* IMMU disabled */
331
        *physical = address & 0xffffffff;
332
        *prot = PAGE_READ;
333
        return 0;
334
    }
335
    for (i = 0; i < 64; i++) {
336
        if ((env->itlb_tte[i] & 0x8000000000000000ULL) != 0) {
337
            switch (env->itlb_tte[i] >> 60) {
338
            default:
339
            case 0x4: // 8k
340
                mask = 0xffffffffffffe000ULL;
341
                break;
342
            case 0x5: // 64k
343
                mask = 0xffffffffffff0000ULL;
344
                break;
345
            case 0x6: // 512k
346
                mask = 0xfffffffffff80000ULL;
347
                break;
348
            case 0x7: // 4M
349
                mask = 0xffffffffffc00000ULL;
350
                break;
351
            }
352
            // ctx match, vaddr match?
353
            if (env->immuregs[1] == (env->itlb_tag[i] & 0x1fff) &&
354
                (address & mask) == (env->itlb_tag[i] & ~0x1fffULL)) {
355
                // access ok?
356
                if ((env->itlb_tte[i] & 0x4) && !(env->pstate & PS_PRIV)) {
357
                    env->exception_index = TT_TFAULT;
358
                    return 1;
359
                }
360
                *physical = env->itlb_tte[i] & 0xffffe000;
361
                *prot = PAGE_READ;
362
                return 0;
363
            }
364
        }
365
    }
366
    env->exception_index = TT_TFAULT;
367
    return 1;
368
}
369

    
370
int get_physical_address(CPUState *env, target_phys_addr_t *physical, int *prot,
371
                          int *access_index, target_ulong address, int rw,
372
                          int is_user)
373
{
374
    if (rw == 2)
375
        return get_physical_address_code(env, physical, prot, access_index, address, rw, is_user);
376
    else
377
        return get_physical_address_data(env, physical, prot, access_index, address, rw, is_user);
378
}
379

    
380
/* Perform address translation */
381
int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
382
                              int is_user, int is_softmmu)
383
{
384
    target_ulong virt_addr;
385
    target_phys_addr_t paddr;
386
    unsigned long vaddr;
387
    int error_code = 0, prot, ret = 0, access_index;
388

    
389
    error_code = get_physical_address(env, &paddr, &prot, &access_index, address, rw, is_user);
390
    if (error_code == 0) {
391
        virt_addr = address & TARGET_PAGE_MASK;
392
        vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));
393
        ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);
394
        return ret;
395
    }
396
    // XXX
397
    return 1;
398
}
399

    
400
#endif
401
#endif
402

    
403
void memcpy32(target_ulong *dst, const target_ulong *src)
404
{
405
    dst[0] = src[0];
406
    dst[1] = src[1];
407
    dst[2] = src[2];
408
    dst[3] = src[3];
409
    dst[4] = src[4];
410
    dst[5] = src[5];
411
    dst[6] = src[6];
412
    dst[7] = src[7];
413
}
414

    
415
void set_cwp(int new_cwp)
416
{
417
    /* put the modified wrap registers at their proper location */
418
    if (env->cwp == (NWINDOWS - 1))
419
        memcpy32(env->regbase, env->regbase + NWINDOWS * 16);
420
    env->cwp = new_cwp;
421
    /* put the wrap registers at their temporary location */
422
    if (new_cwp == (NWINDOWS - 1))
423
        memcpy32(env->regbase + NWINDOWS * 16, env->regbase);
424
    env->regwptr = env->regbase + (new_cwp * 16);
425
    REGWPTR = env->regwptr;
426
}
427

    
428
void cpu_set_cwp(CPUState *env1, int new_cwp)
429
{
430
    CPUState *saved_env;
431
#ifdef reg_REGWPTR
432
    target_ulong *saved_regwptr;
433
#endif
434

    
435
    saved_env = env;
436
#ifdef reg_REGWPTR
437
    saved_regwptr = REGWPTR;
438
#endif
439
    env = env1;
440
    set_cwp(new_cwp);
441
    env = saved_env;
442
#ifdef reg_REGWPTR
443
    REGWPTR = saved_regwptr;
444
#endif
445
}
446

    
447
#ifdef TARGET_SPARC64
448
void do_interrupt(int intno)
449
{
450
#ifdef DEBUG_PCALL
451
    if (loglevel & CPU_LOG_INT) {
452
        static int count;
453
        fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
454
                count, intno,
455
                env->pc,
456
                env->npc, env->regwptr[6]);
457
        cpu_dump_state(env, logfile, fprintf, 0);
458
#if 0
459
        {
460
            int i;
461
            uint8_t *ptr;
462

463
            fprintf(logfile, "       code=");
464
            ptr = (uint8_t *)env->pc;
465
            for(i = 0; i < 16; i++) {
466
                fprintf(logfile, " %02x", ldub(ptr + i));
467
            }
468
            fprintf(logfile, "\n");
469
        }
470
#endif
471
        count++;
472
    }
473
#endif
474
#if !defined(CONFIG_USER_ONLY) 
475
    if (env->pstate & PS_IE) {
476
        cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
477
        return;
478
    }
479
#endif
480
    env->tstate[env->tl] = ((uint64_t)GET_CCR(env) << 32) | ((env->asi & 0xff) << 24) |
481
        ((env->pstate & 0xfff) << 8) | (env->cwp & 0xff);
482
    env->tpc[env->tl] = env->pc;
483
    env->tnpc[env->tl] = env->npc;
484
    env->tt[env->tl] = intno;
485
    env->tbr = env->tbr | (env->tl > 1) ? 1 << 14 : 0 | (intno << 4);
486
    env->tl++;
487
    env->pc = env->tbr;
488
    env->npc = env->pc + 4;
489
    env->exception_index = 0;
490
}
491
#else
492
void do_interrupt(int intno)
493
{
494
    int cwp;
495

    
496
#ifdef DEBUG_PCALL
497
    if (loglevel & CPU_LOG_INT) {
498
        static int count;
499
        fprintf(logfile, "%6d: v=%02x pc=%08x npc=%08x SP=%08x\n",
500
                count, intno,
501
                env->pc,
502
                env->npc, env->regwptr[6]);
503
        cpu_dump_state(env, logfile, fprintf, 0);
504
#if 0
505
        {
506
            int i;
507
            uint8_t *ptr;
508

509
            fprintf(logfile, "       code=");
510
            ptr = (uint8_t *)env->pc;
511
            for(i = 0; i < 16; i++) {
512
                fprintf(logfile, " %02x", ldub(ptr + i));
513
            }
514
            fprintf(logfile, "\n");
515
        }
516
#endif
517
        count++;
518
    }
519
#endif
520
#if !defined(CONFIG_USER_ONLY) 
521
    if (env->psret == 0) {
522
        cpu_abort(cpu_single_env, "Trap 0x%02x while interrupts disabled, Error state", env->exception_index);
523
        return;
524
    }
525
#endif
526
    env->psret = 0;
527
    cwp = (env->cwp - 1) & (NWINDOWS - 1); 
528
    set_cwp(cwp);
529
    env->regwptr[9] = env->pc;
530
    env->regwptr[10] = env->npc;
531
    env->psrps = env->psrs;
532
    env->psrs = 1;
533
    env->tbr = (env->tbr & TBR_BASE_MASK) | (intno << 4);
534
    env->pc = env->tbr;
535
    env->npc = env->pc + 4;
536
    env->exception_index = 0;
537
}
538

    
539
target_ulong mmu_probe(target_ulong address, int mmulev)
540
{
541
    target_phys_addr_t pde_ptr;
542
    uint32_t pde;
543

    
544
    /* Context base + context number */
545
    pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
546
    pde = ldl_phys(pde_ptr);
547

    
548
    switch (pde & PTE_ENTRYTYPE_MASK) {
549
    default:
550
    case 0: /* Invalid */
551
    case 2: /* PTE, maybe should not happen? */
552
    case 3: /* Reserved */
553
        return 0;
554
    case 1: /* L1 PDE */
555
        if (mmulev == 3)
556
            return pde;
557
        pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4);
558
        pde = ldl_phys(pde_ptr);
559

    
560
        switch (pde & PTE_ENTRYTYPE_MASK) {
561
        default:
562
        case 0: /* Invalid */
563
        case 3: /* Reserved */
564
            return 0;
565
        case 2: /* L1 PTE */
566
            return pde;
567
        case 1: /* L2 PDE */
568
            if (mmulev == 2)
569
                return pde;
570
            pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);
571
            pde = ldl_phys(pde_ptr);
572

    
573
            switch (pde & PTE_ENTRYTYPE_MASK) {
574
            default:
575
            case 0: /* Invalid */
576
            case 3: /* Reserved */
577
                return 0;
578
            case 2: /* L2 PTE */
579
                return pde;
580
            case 1: /* L3 PDE */
581
                if (mmulev == 1)
582
                    return pde;
583
                pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);
584
                pde = ldl_phys(pde_ptr);
585

    
586
                switch (pde & PTE_ENTRYTYPE_MASK) {
587
                default:
588
                case 0: /* Invalid */
589
                case 1: /* PDE, should not happen */
590
                case 3: /* Reserved */
591
                    return 0;
592
                case 2: /* L3 PTE */
593
                    return pde;
594
                }
595
            }
596
        }
597
    }
598
    return 0;
599
}
600

    
601
#ifdef DEBUG_MMU
602
void dump_mmu(void)
603
{
604
     target_ulong va, va1, va2;
605
     unsigned int n, m, o;
606
     target_phys_addr_t pde_ptr, pa;
607
    uint32_t pde;
608

    
609
    printf("MMU dump:\n");
610
    pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2);
611
    pde = ldl_phys(pde_ptr);
612
    printf("Root ptr: " TARGET_FMT_lx ", ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]);
613
    for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) {
614
        pde_ptr = mmu_probe(va, 2);
615
        if (pde_ptr) {
616
            pa = cpu_get_phys_page_debug(env, va);
617
             printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va, pa, pde_ptr);
618
            for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) {
619
                pde_ptr = mmu_probe(va1, 1);
620
                if (pde_ptr) {
621
                    pa = cpu_get_phys_page_debug(env, va1);
622
                     printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va1, pa, pde_ptr);
623
                    for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) {
624
                        pde_ptr = mmu_probe(va2, 0);
625
                        if (pde_ptr) {
626
                            pa = cpu_get_phys_page_debug(env, va2);
627
                             printf("  VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PTE: " TARGET_FMT_lx "\n", va2, pa, pde_ptr);
628
                        }
629
                    }
630
                }
631
            }
632
        }
633
    }
634
    printf("MMU dump ends\n");
635
}
636
#endif
637
#endif