Revision a8dea12f target-ppc/helper.c

b/target-ppc/helper.c
549 549
            if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
550 550
                /* Software TLB search */
551 551
                ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
552
            } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
553
                /* XXX: TODO */
554 552
            } else {
555 553
#if defined (DEBUG_MMU)
556 554
                if (loglevel > 0) {
......
632 630
    return ret;
633 631
}
634 632

  
633
int mmu4xx_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
634
                                 uint32_t address, int rw, int access_type)
635
{
636
    ppcemb_tlb_t *tlb;
637
    target_phys_addr_t raddr;
638
    target_ulong mask;
639
    int i, ret, zsel, zpr;
640
            
641
    ret = -6;
642
    for (i = 0; i < env->nb_tlb; i++) {
643
        tlb = &env->tlb[i].tlbe;
644
        /* Check valid flag */
645
        if (!(tlb->prot & PAGE_VALID)) {
646
            if (loglevel)
647
                fprintf(logfile, "%s: TLB %d not valid\n", __func__, i);
648
            continue;
649
        }
650
        mask = ~(tlb->size - 1);
651
        if (loglevel) {
652
            fprintf(logfile, "%s: TLB %d address %08x PID %04x <=> "
653
                    "%08x %08x %04x\n",
654
                    __func__, i, address, env->spr[SPR_40x_PID],
655
                    tlb->EPN, mask, tlb->PID);
656
        }
657
        /* Check PID */
658
        if (tlb->PID != 0 && tlb->PID != env->spr[SPR_40x_PID])
659
            continue;
660
        /* Check effective address */
661
        if ((address & mask) != tlb->EPN)
662
            continue;
663
        raddr = (tlb->RPN & mask) | (address & ~mask);
664
        zsel = (tlb->attr >> 4) & 0xF;
665
        zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3;
666
        if (loglevel) {
667
            fprintf(logfile, "%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",
668
                    __func__, i, zsel, zpr, rw, tlb->attr);
669
        }
670
        if (access_type == ACCESS_CODE) {
671
            /* Check execute enable bit */
672
            switch (zpr) {
673
            case 0x0:
674
                if (msr_pr) {
675
                    ret = -3;
676
                    ctx->prot = 0;
677
                    break;
678
                }
679
                /* No break here */
680
            case 0x1:
681
            case 0x2:
682
                /* Check from TLB entry */
683
                if (!(tlb->prot & PAGE_EXEC)) {
684
                    ret = -3;
685
                } else {
686
                    if (tlb->prot & PAGE_WRITE)
687
                        ctx->prot = PAGE_READ | PAGE_WRITE;
688
                    else
689
                        ctx->prot = PAGE_READ;
690
                    ret = 0;
691
                }
692
                break;
693
            case 0x3:
694
                /* All accesses granted */
695
                ret = 0;
696
                ctx->prot = PAGE_READ | PAGE_WRITE;
697
                break;
698
            }
699
        } else {
700
            switch (zpr) {
701
            case 0x0:
702
                if (msr_pr) {
703
                    ret = -2;
704
                    ctx->prot = 0;
705
                    break;
706
                }
707
                /* No break here */
708
            case 0x1:
709
            case 0x2:
710
                /* Check from TLB entry */
711
                /* Check write protection bit */
712
                if (rw && !(tlb->prot & PAGE_WRITE)) {
713
                    ret = -2;
714
                } else {
715
                    ret = 2;
716
                    if (tlb->prot & PAGE_WRITE)
717
                        ctx->prot = PAGE_READ | PAGE_WRITE;
718
                    else
719
                        ctx->prot = PAGE_READ;
720
                }
721
                break;
722
            case 0x3:
723
                /* All accesses granted */
724
                ret = 2;
725
                ctx->prot = PAGE_READ | PAGE_WRITE;
726
                break;
727
            }
728
        }
729
        if (ret >= 0) {
730
            ctx->raddr = raddr;
731
            if (loglevel) {
732
                fprintf(logfile, "%s: access granted " ADDRX " => " REGX
733
                        " %d\n", __func__, address, ctx->raddr, ctx->prot);
734
            }
735
            return i;
736
        }
737
    }
738
    
739
    return ret;
740
}
741

  
635 742
static int check_physical (CPUState *env, mmu_ctx_t *ctx,
636 743
                           target_ulong eaddr, int rw)
637 744
{
......
682 789
        /* No address translation */
683 790
        ret = check_physical(env, ctx, eaddr, rw);
684 791
    } else {
685
        /* Try to find a BAT */
686
        ret = -1;
687
        if (check_BATs)
688
            ret = get_bat(env, ctx, eaddr, rw, access_type);
689
        if (ret < 0) {
690
            /* We didn't match any BAT entry */
691
            ret = get_segment(env, ctx, eaddr, rw, access_type);
792
        switch (PPC_MMU(env)) {
793
        case PPC_FLAGS_MMU_32B:
794
        case PPC_FLAGS_MMU_SOFT_6xx:
795
            /* Try to find a BAT */
796
            ret = -1;
797
            if (check_BATs)
798
                ret = get_bat(env, ctx, eaddr, rw, access_type);
799
            if (ret < 0) {
800
                /* We didn't match any BAT entry */
801
                ret = get_segment(env, ctx, eaddr, rw, access_type);
802
            }
803
            break;
804
        case PPC_FLAGS_MMU_SOFT_4xx:
805
            ret = mmu4xx_get_physical_address(env, ctx, eaddr,
806
                                              rw, access_type);
807
            break;
808
        default:
809
            /* XXX: TODO */
810
            cpu_abort(env, "MMU model not implemented\n");
811
            return -1;
692 812
        }
693 813
    }
694 814
#if 0
......
753 873
                    error_code = 1 << 18;
754 874
                    goto tlb_miss;
755 875
                } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
756
                    /* XXX: TODO */
876
                    exception = EXCP_40x_ITLBMISS;
877
                    error_code = 0;
878
                    env->spr[SPR_40x_DEAR] = address;
879
                    env->spr[SPR_40x_ESR] = 0x00000000;
757 880
                } else {
758 881
                    error_code = 0x40000000;
759 882
                }
......
799 922
                    /* Do not alter DAR nor DSISR */
800 923
                    goto out;
801 924
                } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
802
                    /* XXX: TODO */
925
                    exception = EXCP_40x_DTLBMISS;
926
                    error_code = 0;
927
                    env->spr[SPR_40x_DEAR] = address;
928
                    if (rw)
929
                        env->spr[SPR_40x_ESR] = 0x00800000;
930
                    else
931
                        env->spr[SPR_40x_ESR] = 0x00000000;
803 932
                } else {
804 933
                    error_code = 0x40000000;
805 934
                }
......
1518 1647
        switch (PPC_EXCP(env)) {
1519 1648
        case PPC_FLAGS_EXCP_40x:
1520 1649
            /* DTLBMISS on 4xx */
1521
            /* XXX: TODO */
1522
            cpu_abort(env,
1523
                      "40x DTLBMISS exception is not implemented yet !\n");
1650
            msr &= ~0xFFFF0000;
1524 1651
            goto store_next;
1525 1652
        case PPC_FLAGS_EXCP_602:
1526 1653
        case PPC_FLAGS_EXCP_603:
......
1538 1665
        switch (PPC_EXCP(env)) {
1539 1666
        case PPC_FLAGS_EXCP_40x:
1540 1667
            /* ITLBMISS on 4xx */
1541
            /* XXX: TODO */
1542
            cpu_abort(env,
1543
                      "40x ITLBMISS exception is not implemented yet !\n");
1668
            msr &= ~0xFFFF0000;
1544 1669
            goto store_next;
1545 1670
        case PPC_FLAGS_EXCP_602:
1546 1671
        case PPC_FLAGS_EXCP_603:

Also available in: Unified diff