Revision 256cebe5

b/target-ppc/cpu.h
386 386
#define SLB_VSID_B              0xc000000000000000ULL
387 387
#define SLB_VSID_B_256M         0x0000000000000000ULL
388 388
#define SLB_VSID_VSID           0x3FFFFFFFFFFFF000ULL
389
#define SLB_VSID_PTEM           (SLB_VSID_B | SLB_VSID_VSID)
389 390
#define SLB_VSID_KS             0x0000000000000800ULL
390 391
#define SLB_VSID_KP             0x0000000000000400ULL
391 392
#define SLB_VSID_N              0x0000000000000200ULL /* no-execute */
b/target-ppc/helper.c
661 661
    return ret;
662 662
}
663 663

  
664
static inline int find_pte32(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
665
                             int type, int target_page_bits)
666
{
667
    return _find_pte(env, ctx, 0, h, rw, type, target_page_bits);
668
}
669

  
670
#if defined(TARGET_PPC64)
671
static inline int find_pte64(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
672
                             int type, int target_page_bits)
673
{
674
    return _find_pte(env, ctx, 1, h, rw, type, target_page_bits);
675
}
676
#endif
677

  
678 664
static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
679 665
                           int type, int target_page_bits)
680 666
{
681 667
#if defined(TARGET_PPC64)
682 668
    if (env->mmu_model & POWERPC_MMU_64)
683
        return find_pte64(env, ctx, h, rw, type, target_page_bits);
669
        return _find_pte(env, ctx, 1, h, rw, type, target_page_bits);
684 670
#endif
685 671

  
686
    return find_pte32(env, ctx, h, rw, type, target_page_bits);
672
    return _find_pte(env, ctx, 0, h, rw, type, target_page_bits);
687 673
}
688 674

  
689 675
#if defined(TARGET_PPC64)
......
803 789
                              target_ulong eaddr, int rw, int type)
804 790
{
805 791
    target_phys_addr_t hash;
806
    target_ulong sr, vsid, pgidx, page_mask;
792
    target_ulong vsid;
807 793
    int ds, pr, target_page_bits;
808 794
    int ret, ret2;
809 795

  
810 796
    pr = msr_pr;
797
    ctx->eaddr = eaddr;
811 798
#if defined(TARGET_PPC64)
812 799
    if (env->mmu_model & POWERPC_MMU_64) {
813 800
        ppc_slb_t *slb;
801
        target_ulong pageaddr;
814 802

  
815 803
        LOG_MMU("Check SLBs\n");
816 804
        slb = slb_lookup(env, eaddr);
......
819 807
        }
820 808

  
821 809
        vsid = (slb->vsid & SLB_VSID_VSID) >> SLB_VSID_SHIFT;
822
        page_mask = ~SEGMENT_MASK_256M;
823 810
        target_page_bits = (slb->vsid & SLB_VSID_L)
824 811
            ? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
825 812
        ctx->key = !!(pr ? (slb->vsid & SLB_VSID_KP)
826 813
                      : (slb->vsid & SLB_VSID_KS));
827 814
        ds = 0;
828 815
        ctx->nx = !!(slb->vsid & SLB_VSID_N);
829
        ctx->eaddr = eaddr;
816

  
817
        pageaddr = eaddr & ((1ULL << 28) - (1ULL << target_page_bits));
818
        /* XXX: this is false for 1 TB segments */
819
        hash = vsid ^ (pageaddr >> target_page_bits);
820
        /* Only 5 bits of the page index are used in the AVPN */
821
        ctx->ptem = (slb->vsid & SLB_VSID_PTEM) | ((pageaddr >> 16) & 0x0F80);
830 822
    } else
831 823
#endif /* defined(TARGET_PPC64) */
832 824
    {
825
        target_ulong sr, pgidx;
826

  
833 827
        sr = env->sr[eaddr >> 28];
834
        page_mask = 0x0FFFFFFF;
835 828
        ctx->key = (((sr & 0x20000000) && (pr != 0)) ||
836 829
                    ((sr & 0x40000000) && (pr == 0))) ? 1 : 0;
837 830
        ds = sr & 0x80000000 ? 1 : 0;
......
843 836
                " ir=%d dr=%d pr=%d %d t=%d\n",
844 837
                eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir,
845 838
                (int)msr_dr, pr != 0 ? 1 : 0, rw, type);
839
        pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits;
840
        hash = vsid ^ pgidx;
841
        ctx->ptem = (vsid << 7) | (pgidx >> 10);
846 842
    }
847 843
    LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n",
848 844
            ctx->key, ds, ctx->nx, vsid);
......
851 847
        /* Check if instruction fetch is allowed, if needed */
852 848
        if (type != ACCESS_CODE || ctx->nx == 0) {
853 849
            /* Page address translation */
854
            pgidx = (eaddr & page_mask) >> target_page_bits;
855
#if defined(TARGET_PPC64)
856
            if (env->mmu_model & POWERPC_MMU_64) {
857
                /* XXX: this is false for 1 TB segments */
858
                hash = vsid ^ pgidx;
859
            } else
860
#endif
861
            {
862
                hash = vsid ^ pgidx;
863
            }
864 850
            LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
865 851
                    " hash " TARGET_FMT_plx "\n",
866 852
                    env->htab_base, env->htab_mask, hash);
867 853
            ctx->hash[0] = hash;
868 854
            ctx->hash[1] = ~hash;
869 855

  
870
#if defined(TARGET_PPC64)
871
            if (env->mmu_model & POWERPC_MMU_64) {
872
                /* Only 5 bits of the page index are used in the AVPN */
873
                if (target_page_bits > 23) {
874
                    ctx->ptem = (vsid << 12) |
875
                                ((pgidx << (target_page_bits - 16)) & 0xF80);
876
                } else {
877
                    ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80);
878
                }
879
            } else
880
#endif
881
            {
882
                ctx->ptem = (vsid << 7) | (pgidx >> 10);
883
            }
884 856
            /* Initialize real address with an invalid value */
885 857
            ctx->raddr = (target_phys_addr_t)-1ULL;
886 858
            if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx ||
......
889 861
                ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
890 862
            } else {
891 863
                LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
892
                        " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
864
                        " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx
893 865
                        " hash=" TARGET_FMT_plx "\n",
894
                        env->htab_base, env->htab_mask, vsid, pgidx,
866
                        env->htab_base, env->htab_mask, vsid, ctx->ptem,
895 867
                        ctx->hash[0]);
896 868
                /* Primary table lookup */
897 869
                ret = find_pte(env, ctx, 0, rw, type, target_page_bits);
......
902 874
                                " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
903 875
                                " hash=" TARGET_FMT_plx " pg_addr="
904 876
                                TARGET_FMT_plx "\n", env->htab_base,
905
                                env->htab_mask, vsid, pgidx, hash,
906
                                ctx->hash[1]);
877
                                env->htab_mask, vsid, ctx->ptem, ctx->hash[1]);
907 878
                    ret2 = find_pte(env, ctx, 1, rw, type,
908 879
                                    target_page_bits);
909 880
                    if (ret2 != -1)

Also available in: Unified diff