Revision b8e9fc06 target-sparc/helper.c

b/target-sparc/helper.c
30 30
//#define DEBUG_MMU
31 31
//#define DEBUG_FEATURES
32 32

  
33
#ifdef DEBUG_MMU
34
#define DPRINTF_MMU(fmt, ...) \
35
    do { printf("MMU: " fmt , ## __VA_ARGS__); } while (0)
36
#else
37
#define DPRINTF_MMU(fmt, ...) do {} while (0)
38
#endif
39

  
33 40
static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);
34 41

  
35 42
/* Sparc MMU emulation */
......
451 458

  
452 459
    for (i = 0; i < 64; i++) {
453 460
        // ctx match, vaddr match, valid?
454
        if (ultrasparc_tag_match(&env->dtlb[i],
455
                                 address, context, physical)) {
461
        if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) {
462

  
463
            uint8_t fault_type = 0;
464

  
456 465
            // access ok?
457
            if (((env->dtlb[i].tte & 0x4) && is_user) ||
458
                (!(env->dtlb[i].tte & 0x2) && (rw == 1))) {
459
                uint8_t fault_type = 0;
466
            if ((env->dtlb[i].tte & 0x4) && is_user) {
467
                fault_type |= 1; /* privilege violation */
468
                env->exception_index = TT_DFAULT;
460 469

  
461
                if ((env->dtlb[i].tte & 0x4) && is_user) {
462
                    fault_type |= 1; /* privilege violation */
463
                }
470
                DPRINTF_MMU("DFAULT at %" PRIx64 " context %" PRIx64
471
                            " mmu_idx=%d tl=%d\n",
472
                            address, context, mmu_idx, env->tl);
473
            } else if (!(env->dtlb[i].tte & 0x2) && (rw == 1)) {
474
                env->exception_index = TT_DPROT;
464 475

  
465
                if (env->dmmu.sfsr & 1) /* Fault status register */
466
                    env->dmmu.sfsr = 2; /* overflow (not read before
476
                DPRINTF_MMU("DPROT at %" PRIx64 " context %" PRIx64
477
                            " mmu_idx=%d tl=%d\n",
478
                            address, context, mmu_idx, env->tl);
479
            } else {
480
                *prot = PAGE_READ;
481
                if (env->dtlb[i].tte & 0x2)
482
                    *prot |= PAGE_WRITE;
483

  
484
                TTE_SET_USED(env->dtlb[i].tte);
485

  
486
                return 0;
487
            }
488

  
489
            if (env->dmmu.sfsr & 1) /* Fault status register */
490
                env->dmmu.sfsr = 2; /* overflow (not read before
467 491
                                             another fault) */
468 492

  
469
                env->dmmu.sfsr |= (is_user << 3) | ((rw == 1) << 2) | 1;
493
            env->dmmu.sfsr |= (is_user << 3) | ((rw == 1) << 2) | 1;
470 494

  
471
                env->dmmu.sfsr |= (fault_type << 7);
495
            env->dmmu.sfsr |= (fault_type << 7);
472 496

  
473
                env->dmmu.sfar = address; /* Fault address register */
474
                env->exception_index = TT_DFAULT;
475
#ifdef DEBUG_MMU
476
                printf("DFAULT at 0x%" PRIx64 "\n", address);
477
#endif
478
                return 1;
479
            }
480
            *prot = PAGE_READ;
481
            if (env->dtlb[i].tte & 0x2)
482
                *prot |= PAGE_WRITE;
483
            TTE_SET_USED(env->dtlb[i].tte);
484
            return 0;
497
            env->dmmu.sfar = address; /* Fault address register */
498
            return 1;
485 499
        }
486 500
    }
487
#ifdef DEBUG_MMU
488
    printf("DMISS at 0x%" PRIx64 "\n", address);
489
#endif
501

  
502
    DPRINTF_MMU("DMISS at %" PRIx64 " context %" PRIx64 "\n",
503
                address, context);
504

  
490 505
    env->dmmu.tag_access = (address & ~0x1fffULL) | context;
491 506
    env->exception_index = TT_DMISS;
492 507
    return 1;
......
528 543
                                             another fault) */
529 544
                env->immu.sfsr |= (is_user << 3) | 1;
530 545
                env->exception_index = TT_TFAULT;
531
#ifdef DEBUG_MMU
532
                printf("TFAULT at 0x%" PRIx64 "\n", address);
533
#endif
546

  
547
                DPRINTF_MMU("TFAULT at %" PRIx64 " context %" PRIx64 "\n",
548
                            address, context);
549

  
534 550
                return 1;
535 551
            }
536 552
            *prot = PAGE_EXEC;
......
538 554
            return 0;
539 555
        }
540 556
    }
541
#ifdef DEBUG_MMU
542
    printf("TMISS at 0x%" PRIx64 "\n", address);
543
#endif
557

  
558
    DPRINTF_MMU("TMISS at %" PRIx64 " context %" PRIx64 "\n",
559
                address, context);
560

  
544 561
    /* Context is stored in DMMU (dmmuregs[1]) also for IMMU */
545 562
    env->immu.tag_access = (address & ~0x1fffULL) | context;
546 563
    env->exception_index = TT_TMISS;
......
578 595
        virt_addr = address & TARGET_PAGE_MASK;
579 596
        vaddr = virt_addr + ((address & TARGET_PAGE_MASK) &
580 597
                             (TARGET_PAGE_SIZE - 1));
581
#ifdef DEBUG_MMU
582
        printf("Translate at 0x%" PRIx64 " -> 0x%" PRIx64 ", vaddr 0x%" PRIx64
583
               "\n", address, paddr, vaddr);
584
#endif
598

  
599
        DPRINTF_MMU("Translate at %" PRIx64 " -> %" PRIx64 ","
600
                    " vaddr %" PRIx64
601
                    " mmu_idx=%d"
602
                    " tl=%d"
603
                    " primary context=%" PRIx64
604
                    " secondary context=%" PRIx64
605
                    "\n",
606
                    address, paddr, vaddr, mmu_idx, env->tl,
607
                    env->dmmu.mmu_primary_context,
608
                    env->dmmu.mmu_secondary_context);
609

  
585 610
        tlb_set_page(env, vaddr, paddr, prot, mmu_idx, page_size);
586 611
        return 0;
587 612
    }

Also available in: Unified diff