Revision c55e9aef

b/target-ppc/cpu.h
581 581

  
582 582
typedef struct ppcemb_tlb_t ppcemb_tlb_t;
583 583
struct ppcemb_tlb_t {
584
    target_ulong RPN;
584
    target_phys_addr_t RPN;
585 585
    target_ulong EPN;
586 586
    target_ulong PID;
587
    int size;
588
    int prot;
589
    int attr; /* Storage attributes */
587
    target_ulong size;
588
    uint32_t prot;
589
    uint32_t attr; /* Storage attributes */
590 590
};
591 591

  
592 592
union ppc_tlb_t {
......
765 765
    int id_tlbs;     /* If 1, MMU has separated TLBs for instructions & data */
766 766
    int nb_pids;     /* Number of available PID registers                    */
767 767
    ppc_tlb_t *tlb;  /* TLB is optional. Allocate them only if needed        */
768
    /* Callbacks for specific checks on some implementations */
769
    int (*tlb_check_more)(CPUPPCState *env, ppc_tlb_t *tlb, int *prot,
770
                          target_ulong vaddr, int rw, int acc_type,
771
                          int is_user);
772 768
    /* 403 dedicated access protection registers */
773 769
    target_ulong pb[4];
774 770

  
b/target-ppc/helper.c
657 657
    target_ulong mask;
658 658
    int i, ret, zsel, zpr;
659 659
            
660
    ret = -6;
660
    ret = -1;
661
    raddr = -1;
661 662
    for (i = 0; i < env->nb_tlb; i++) {
662 663
        tlb = &env->tlb[i].tlbe;
663 664
        /* Check valid flag */
......
691 692
            switch (zpr) {
692 693
            case 0x0:
693 694
                if (msr_pr) {
694
                    ret = -3;
695 695
                    ctx->prot = 0;
696
                    ret = -3;
696 697
                    break;
697 698
                }
698 699
                /* No break here */
......
702 703
                if (!(tlb->prot & PAGE_EXEC)) {
703 704
                    ret = -3;
704 705
                } else {
705
                    if (tlb->prot & PAGE_WRITE)
706
                    if (tlb->prot & PAGE_WRITE) {
706 707
                        ctx->prot = PAGE_READ | PAGE_WRITE;
707
                    else
708
                    } else {
708 709
                        ctx->prot = PAGE_READ;
710
                    }
709 711
                    ret = 0;
710 712
                }
711 713
                break;
712 714
            case 0x3:
713 715
                /* All accesses granted */
714
                ret = 0;
715 716
                ctx->prot = PAGE_READ | PAGE_WRITE;
717
                ret = 0;
716 718
                break;
717 719
            }
718 720
        } else {
719 721
            switch (zpr) {
720 722
            case 0x0:
721 723
                if (msr_pr) {
722
                    ret = -2;
723 724
                    ctx->prot = 0;
725
                    ret = -2;
724 726
                    break;
725 727
                }
726 728
                /* No break here */
......
728 730
            case 0x2:
729 731
                /* Check from TLB entry */
730 732
                /* Check write protection bit */
731
                if (rw && !(tlb->prot & PAGE_WRITE)) {
732
                    ret = -2;
733
                if (tlb->prot & PAGE_WRITE) {
734
                    ctx->prot = PAGE_READ | PAGE_WRITE;
735
                    ret = 0;
733 736
                } else {
734
                    ret = 2;
735
                    if (tlb->prot & PAGE_WRITE)
736
                        ctx->prot = PAGE_READ | PAGE_WRITE;
737
                    ctx->prot = PAGE_READ;
738
                    if (rw)
739
                        ret = -2;
737 740
                    else
738
                        ctx->prot = PAGE_READ;
741
                        ret = 0;
739 742
                }
740 743
                break;
741 744
            case 0x3:
742 745
                /* All accesses granted */
743
                ret = 2;
744 746
                ctx->prot = PAGE_READ | PAGE_WRITE;
747
                ret = 0;
745 748
                break;
746 749
            }
747 750
        }
......
749 752
            ctx->raddr = raddr;
750 753
            if (loglevel) {
751 754
                fprintf(logfile, "%s: access granted " ADDRX " => " REGX
752
                        " %d\n", __func__, address, ctx->raddr, ctx->prot);
755
                        " %d %d\n", __func__, address, ctx->raddr, ctx->prot,
756
                        ret);
753 757
            }
754
            return i;
758
            return 0;
755 759
        }
756 760
    }
761
    if (loglevel) {
762
        fprintf(logfile, "%s: access refused " ADDRX " => " REGX
763
                " %d %d\n", __func__, address, raddr, ctx->prot,
764
                ret);
765
    }
757 766
    
758 767
    return ret;
759 768
}
......
808 817
        /* No address translation */
809 818
        ret = check_physical(env, ctx, eaddr, rw);
810 819
    } else {
820
        ret = -1;
811 821
        switch (PPC_MMU(env)) {
812 822
        case PPC_FLAGS_MMU_32B:
813 823
        case PPC_FLAGS_MMU_SOFT_6xx:
814 824
            /* Try to find a BAT */
815
            ret = -1;
816 825
            if (check_BATs)
817 826
                ret = get_bat(env, ctx, eaddr, rw, access_type);
827
            /* No break here */
828
#if defined(TARGET_PPC64)
829
        case PPC_FLAGS_MMU_64B:
830
        case PPC_FLAGS_MMU_64BRIDGE:
831
#endif
818 832
            if (ret < 0) {
819
                /* We didn't match any BAT entry */
833
                /* We didn't match any BAT entry or don't have BATs */
820 834
                ret = get_segment(env, ctx, eaddr, rw, access_type);
821 835
            }
822 836
            break;
823 837
        case PPC_FLAGS_MMU_SOFT_4xx:
838
        case PPC_FLAGS_MMU_403:
824 839
            ret = mmu4xx_get_physical_address(env, ctx, eaddr,
825 840
                                              rw, access_type);
826 841
            break;
827
        default:
842
        case PPC_FLAGS_MMU_601:
843
            /* XXX: TODO */
844
            cpu_abort(env, "601 MMU model not implemented\n");
845
            return -1;
846
        case PPC_FLAGS_MMU_BOOKE:
828 847
            /* XXX: TODO */
829
            cpu_abort(env, "MMU model not implemented\n");
848
            cpu_abort(env, "BookeE MMU model not implemented\n");
849
            return -1;
850
        case PPC_FLAGS_MMU_BOOKE_FSL:
851
            /* XXX: TODO */
852
            cpu_abort(env, "BookE FSL MMU model not implemented\n");
853
            return -1;
854
        default:
855
            cpu_abort(env, "Unknown or invalid MMU model\n");
830 856
            return -1;
831 857
        }
832 858
    }
833 859
#if 0
834 860
    if (loglevel > 0) {
835
        fprintf(logfile, "%s address " ADDRX " => " ADDRX "\n",
836
                __func__, eaddr, ctx->raddr);
861
        fprintf(logfile, "%s address " ADDRX " => %d " ADDRX "\n",
862
                __func__, eaddr, ret, ctx->raddr);
837 863
    }
838 864
#endif
839 865

  
......
885 911
            switch (ret) {
886 912
            case -1:
887 913
                /* No matches in page tables or TLB */
888
                if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
914
                switch (PPC_MMU(env)) {
915
                case PPC_FLAGS_MMU_SOFT_6xx:
889 916
                    exception = EXCP_I_TLBMISS;
890 917
                    env->spr[SPR_IMISS] = address;
891 918
                    env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;
892 919
                    error_code = 1 << 18;
893 920
                    goto tlb_miss;
894
                } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
921
                case PPC_FLAGS_MMU_SOFT_4xx:
922
                case PPC_FLAGS_MMU_403:
895 923
                    exception = EXCP_40x_ITLBMISS;
896 924
                    error_code = 0;
897 925
                    env->spr[SPR_40x_DEAR] = address;
898 926
                    env->spr[SPR_40x_ESR] = 0x00000000;
899
                } else {
927
                    break;
928
                case PPC_FLAGS_MMU_32B:
900 929
                    error_code = 0x40000000;
930
                    break;
931
#if defined(TARGET_PPC64)
932
                case PPC_FLAGS_MMU_64B:
933
                    /* XXX: TODO */
934
                    cpu_abort(env, "MMU model not implemented\n");
935
                    return -1;
936
                case PPC_FLAGS_MMU_64BRIDGE:
937
                    /* XXX: TODO */
938
                    cpu_abort(env, "MMU model not implemented\n");
939
                    return -1;
940
#endif
941
                case PPC_FLAGS_MMU_601:
942
                    /* XXX: TODO */
943
                    cpu_abort(env, "MMU model not implemented\n");
944
                    return -1;
945
                case PPC_FLAGS_MMU_BOOKE:
946
                    /* XXX: TODO */
947
                    cpu_abort(env, "MMU model not implemented\n");
948
                    return -1;
949
                case PPC_FLAGS_MMU_BOOKE_FSL:
950
                    /* XXX: TODO */
951
                    cpu_abort(env, "MMU model not implemented\n");
952
                    return -1;
953
                default:
954
                    cpu_abort(env, "Unknown or invalid MMU model\n");
955
                    return -1;
901 956
                }
902 957
                break;
903 958
            case -2:
......
924 979
            switch (ret) {
925 980
            case -1:
926 981
                /* No matches in page tables or TLB */
927
                if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_6xx)) {
982
                switch (PPC_MMU(env)) {
983
                case PPC_FLAGS_MMU_SOFT_6xx:
928 984
                    if (rw == 1) {
929 985
                        exception = EXCP_DS_TLBMISS;
930 986
                        error_code = 1 << 16;
......
940 996
                    env->spr[SPR_HASH2] = ctx.pg_addr[1];
941 997
                    /* Do not alter DAR nor DSISR */
942 998
                    goto out;
943
                } else if (unlikely(PPC_MMU(env) == PPC_FLAGS_MMU_SOFT_4xx)) {
999
                case PPC_FLAGS_MMU_SOFT_4xx:
1000
                case PPC_FLAGS_MMU_403:
944 1001
                    exception = EXCP_40x_DTLBMISS;
945 1002
                    error_code = 0;
946 1003
                    env->spr[SPR_40x_DEAR] = address;
......
948 1005
                        env->spr[SPR_40x_ESR] = 0x00800000;
949 1006
                    else
950 1007
                        env->spr[SPR_40x_ESR] = 0x00000000;
951
                } else {
1008
                    break;
1009
                case PPC_FLAGS_MMU_32B:
952 1010
                    error_code = 0x40000000;
1011
                    break;
1012
#if defined(TARGET_PPC64)
1013
                case PPC_FLAGS_MMU_64B:
1014
                    /* XXX: TODO */
1015
                    cpu_abort(env, "MMU model not implemented\n");
1016
                    return -1;
1017
                case PPC_FLAGS_MMU_64BRIDGE:
1018
                    /* XXX: TODO */
1019
                    cpu_abort(env, "MMU model not implemented\n");
1020
                    return -1;
1021
#endif
1022
                case PPC_FLAGS_MMU_601:
1023
                    /* XXX: TODO */
1024
                    cpu_abort(env, "MMU model not implemented\n");
1025
                    return -1;
1026
                case PPC_FLAGS_MMU_BOOKE:
1027
                    /* XXX: TODO */
1028
                    cpu_abort(env, "MMU model not implemented\n");
1029
                    return -1;
1030
                case PPC_FLAGS_MMU_BOOKE_FSL:
1031
                    /* XXX: TODO */
1032
                    cpu_abort(env, "MMU model not implemented\n");
1033
                    return -1;
1034
                default:
1035
                    cpu_abort(env, "Unknown or invalid MMU model\n");
1036
                    return -1;
953 1037
                }
954 1038
                break;
955 1039
            case -2:
b/target-ppc/op_helper.c
2537 2537
    env->crf[0] = tmp;
2538 2538
}
2539 2539

  
2540
void do_4xx_tlbwe_lo (void)
2540
void do_4xx_tlbwe_hi (void)
2541 2541
{
2542 2542
    ppcemb_tlb_t *tlb;
2543 2543
    target_ulong page, end;
2544 2544

  
2545
#if defined (DEBUG_SOFTWARE_TLB)
2546
    if (loglevel) {
2547
        fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1);
2548
    }
2549
#endif
2545 2550
    T0 &= 0x3F;
2546 2551
    tlb = &env->tlb[T0].tlbe;
2547 2552
    /* Invalidate previous TLB (if it's valid) */
2548 2553
    if (tlb->prot & PAGE_VALID) {
2549 2554
        end = tlb->EPN + tlb->size;
2555
#if defined (DEBUG_SOFTWARE_TLB)
2556
        if (loglevel) {
2557
            fprintf(logfile, "%s: invalidate old TLB %d start " ADDRX
2558
                    " end " ADDRX "\n", __func__, (int)T0, tlb->EPN, end);
2559
        }
2560
#endif
2550 2561
        for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
2551 2562
            tlb_flush_page(env, page);
2552 2563
    }
2553 2564
    tlb->size = booke_tlb_to_page_size((T1 >> 7) & 0x7);
2554 2565
    tlb->EPN = (T1 & 0xFFFFFC00) & ~(tlb->size - 1);
2555
    if (T1 & 0x400)
2566
    if (T1 & 0x40)
2556 2567
        tlb->prot |= PAGE_VALID;
2557 2568
    else
2558 2569
        tlb->prot &= ~PAGE_VALID;
2559
    tlb->PID = env->spr[SPR_BOOKE_PID]; /* PID */
2570
    tlb->PID = env->spr[SPR_40x_PID]; /* PID */
2560 2571
    tlb->attr = T1 & 0xFF;
2572
#if defined (DEBUG_SOFTWARE_TLB)
2573
    if (loglevel) {
2574
        fprintf(logfile, "%s: set up TLB %d RPN " ADDRX " EPN " ADDRX
2575
                " size " ADDRX " prot %c%c%c%c PID %d\n", __func__,
2576
                (int)T0, tlb->RPN, tlb->EPN, tlb->size, 
2577
                tlb->prot & PAGE_READ ? 'r' : '-',
2578
                tlb->prot & PAGE_WRITE ? 'w' : '-',
2579
                tlb->prot & PAGE_EXEC ? 'x' : '-',
2580
                tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID);
2581
    }
2582
#endif
2561 2583
    /* Invalidate new TLB (if valid) */
2562 2584
    if (tlb->prot & PAGE_VALID) {
2563 2585
        end = tlb->EPN + tlb->size;
2586
#if defined (DEBUG_SOFTWARE_TLB)
2587
        if (loglevel) {
2588
            fprintf(logfile, "%s: invalidate TLB %d start " ADDRX
2589
                    " end " ADDRX "\n", __func__, (int)T0, tlb->EPN, end);
2590
        }
2591
#endif
2564 2592
        for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
2565 2593
            tlb_flush_page(env, page);
2566 2594
    }
2567 2595
}
2568 2596

  
2569
void do_4xx_tlbwe_hi (void)
2597
void do_4xx_tlbwe_lo (void)
2570 2598
{
2571 2599
    ppcemb_tlb_t *tlb;
2572 2600

  
2601
#if defined (DEBUG_SOFTWARE_TLB)
2602
    if (loglevel) {
2603
        fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1);
2604
    }
2605
#endif
2573 2606
    T0 &= 0x3F;
2574 2607
    tlb = &env->tlb[T0].tlbe;
2575 2608
    tlb->RPN = T1 & 0xFFFFFC00;
......
2578 2611
        tlb->prot |= PAGE_EXEC;
2579 2612
    if (T1 & 0x100)
2580 2613
        tlb->prot |= PAGE_WRITE;
2614
#if defined (DEBUG_SOFTWARE_TLB)
2615
    if (loglevel) {
2616
        fprintf(logfile, "%s: set up TLB %d RPN " ADDRX " EPN " ADDRX
2617
                " size " ADDRX " prot %c%c%c%c PID %d\n", __func__,
2618
                (int)T0, tlb->RPN, tlb->EPN, tlb->size, 
2619
                tlb->prot & PAGE_READ ? 'r' : '-',
2620
                tlb->prot & PAGE_WRITE ? 'w' : '-',
2621
                tlb->prot & PAGE_EXEC ? 'x' : '-',
2622
                tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID);
2623
    }
2624
#endif
2581 2625
}
2582 2626
#endif /* !CONFIG_USER_ONLY */

Also available in: Unified diff