Revision bb593904

b/monitor.c
3462 3462
    { "asr", offsetof(CPUState, asr) },
3463 3463
#endif
3464 3464
    /* Segment registers */
3465
    { "sdr1", offsetof(CPUState, sdr1) },
3465
    { "sdr1", offsetof(CPUState, spr[SPR_SDR1]) },
3466 3466
    { "sr0", offsetof(CPUState, sr[0]) },
3467 3467
    { "sr1", offsetof(CPUState, sr[1]) },
3468 3468
    { "sr2", offsetof(CPUState, sr[2]) },
b/target-ppc/cpu.h
359 359
};
360 360
#endif
361 361

  
362
#define SDR_32_HTABORG         0xFFFF0000UL
363
#define SDR_32_HTABMASK        0x000001FFUL
364

  
365
#if defined(TARGET_PPC64)
366
#define SDR_64_HTABORG         0xFFFFFFFFFFFC0000ULL
367
#define SDR_64_HTABSIZE        0x000000000000001FULL
368
#endif /* defined(TARGET_PPC64 */
369

  
362 370
typedef struct ppc_slb_t ppc_slb_t;
363 371
struct ppc_slb_t {
364 372
    uint64_t esid;
......
642 650
    int slb_nr;
643 651
#endif
644 652
    /* segment registers */
645
    target_ulong sdr1;
653
    target_phys_addr_t htab_base;
654
    target_phys_addr_t htab_mask;
646 655
    target_ulong sr[32];
647 656
    /* BATs */
648 657
    int nb_BATs;
b/target-ppc/helper.c
788 788
#endif /* defined(TARGET_PPC64) */
789 789

  
790 790
/* Perform segment based translation */
791
static inline target_phys_addr_t get_pgaddr(target_phys_addr_t sdr1,
792
                                            int sdr_sh,
793
                                            target_phys_addr_t hash,
794
                                            target_phys_addr_t mask)
791
static inline target_phys_addr_t get_pgaddr(target_phys_addr_t htab_base,
792
                                            target_phys_addr_t htab_mask,
793
                                            target_phys_addr_t hash)
795 794
{
796
    return (sdr1 & ((target_phys_addr_t)(-1ULL) << sdr_sh)) | (hash & mask);
795
    return htab_base | (hash & htab_mask);
797 796
}
798 797

  
799 798
static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
800 799
                              target_ulong eaddr, int rw, int type)
801 800
{
802
    target_phys_addr_t sdr, hash, mask, sdr_mask, htab_mask;
801
    target_phys_addr_t hash;
803 802
    target_ulong sr, vsid, vsid_mask, pgidx, page_mask;
804
    int ds, vsid_sh, sdr_sh, pr, target_page_bits;
803
    int ds, vsid_sh, pr, target_page_bits;
805 804
    int ret, ret2;
806 805

  
807 806
    pr = msr_pr;
......
826 825
        ctx->eaddr = eaddr;
827 826
        vsid_mask = 0x00003FFFFFFFFF80ULL;
828 827
        vsid_sh = 7;
829
        sdr_sh = 18;
830
        sdr_mask = 0x3FF80;
831 828
    } else
832 829
#endif /* defined(TARGET_PPC64) */
833 830
    {
......
840 837
        vsid = sr & 0x00FFFFFF;
841 838
        vsid_mask = 0x01FFFFC0;
842 839
        vsid_sh = 6;
843
        sdr_sh = 16;
844
        sdr_mask = 0xFFC0;
845 840
        target_page_bits = TARGET_PAGE_BITS;
846 841
        LOG_MMU("Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx " nip="
847 842
                TARGET_FMT_lx " lr=" TARGET_FMT_lx
......
857 852
        if (type != ACCESS_CODE || ctx->nx == 0) {
858 853
            /* Page address translation */
859 854
            /* Primary table address */
860
            sdr = env->sdr1;
861 855
            pgidx = (eaddr & page_mask) >> target_page_bits;
862 856
#if defined(TARGET_PPC64)
863 857
            if (env->mmu_model & POWERPC_MMU_64) {
864
                htab_mask = 0x0FFFFFFF >> (28 - (sdr & 0x1F));
865 858
                /* XXX: this is false for 1 TB segments */
866 859
                hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
867 860
            } else
868 861
#endif
869 862
            {
870
                htab_mask = sdr & 0x000001FF;
871 863
                hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask;
872 864
            }
873
            mask = (htab_mask << sdr_sh) | sdr_mask;
874
            LOG_MMU("sdr " TARGET_FMT_plx " sh %d hash " TARGET_FMT_plx
875
                    " mask " TARGET_FMT_plx " " TARGET_FMT_lx "\n",
876
                    sdr, sdr_sh, hash, mask, page_mask);
877
            ctx->pg_addr[0] = get_pgaddr(sdr, sdr_sh, hash, mask);
865
            LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
866
                    " hash " TARGET_FMT_plx "\n",
867
                    env->htab_base, env->htab_mask, hash);
868
            ctx->pg_addr[0] = get_pgaddr(env->htab_base, env->htab_mask, hash);
878 869
            /* Secondary table address */
879 870
            hash = (~hash) & vsid_mask;
880
            LOG_MMU("sdr " TARGET_FMT_plx " sh %d hash " TARGET_FMT_plx
881
                    " mask " TARGET_FMT_plx "\n", sdr, sdr_sh, hash, mask);
882
            ctx->pg_addr[1] = get_pgaddr(sdr, sdr_sh, hash, mask);
871
            LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx
872
                    " hash " TARGET_FMT_plx "\n",
873
                    env->htab_base, env->htab_mask, hash);
874
            ctx->pg_addr[1] = get_pgaddr(env->htab_base, env->htab_mask, hash);
883 875
#if defined(TARGET_PPC64)
884 876
            if (env->mmu_model & POWERPC_MMU_64) {
885 877
                /* Only 5 bits of the page index are used in the AVPN */
......
901 893
                /* Software TLB search */
902 894
                ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type);
903 895
            } else {
904
                LOG_MMU("0 sdr1=" TARGET_FMT_plx " vsid=" TARGET_FMT_lx " "
905
                        "api=" TARGET_FMT_lx " hash=" TARGET_FMT_plx
906
                        " pg_addr=" TARGET_FMT_plx "\n",
907
                        sdr, vsid, pgidx, hash, ctx->pg_addr[0]);
896
                LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
897
                        " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
898
                        " hash=" TARGET_FMT_plx " pg_addr=" TARGET_FMT_plx "\n",
899
                        env->htab_base, env->htab_mask, vsid, pgidx, hash,
900
                        ctx->pg_addr[0]);
908 901
                /* Primary table lookup */
909 902
                ret = find_pte(env, ctx, 0, rw, type, target_page_bits);
910 903
                if (ret < 0) {
911 904
                    /* Secondary table lookup */
912 905
                    if (eaddr != 0xEFFFFFFF)
913
                        LOG_MMU("1 sdr1=" TARGET_FMT_plx " vsid=" TARGET_FMT_lx " "
914
                                "api=" TARGET_FMT_lx " hash=" TARGET_FMT_plx
915
                                " pg_addr=" TARGET_FMT_plx "\n", sdr, vsid,
916
                                pgidx, hash, ctx->pg_addr[1]);
906
                        LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx
907
                                " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx
908
                                " hash=" TARGET_FMT_plx " pg_addr="
909
                                TARGET_FMT_plx "\n", env->htab_base,
910
                                env->htab_mask, vsid, pgidx, hash,
911
                                ctx->pg_addr[1]);
917 912
                    ret2 = find_pte(env, ctx, 1, rw, type,
918 913
                                    target_page_bits);
919 914
                    if (ret2 != -1)
......
1919 1914
void ppc_store_sdr1 (CPUPPCState *env, target_ulong value)
1920 1915
{
1921 1916
    LOG_MMU("%s: " TARGET_FMT_lx "\n", __func__, value);
1922
    if (env->sdr1 != value) {
1923
        /* XXX: for PowerPC 64, should check that the HTABSIZE value
1924
         *      is <= 28
1925
         */
1926
        env->sdr1 = value;
1917
    if (env->spr[SPR_SDR1] != value) {
1918
        env->spr[SPR_SDR1] = value;
1919
#if defined(TARGET_PPC64)
1920
        if (env->mmu_model & POWERPC_MMU_64) {
1921
            target_ulong htabsize = value & SDR_64_HTABSIZE;
1922

  
1923
            if (htabsize > 28) {
1924
                fprintf(stderr, "Invalid HTABSIZE 0x" TARGET_FMT_lx
1925
                        " stored in SDR1\n", htabsize);
1926
                htabsize = 28;
1927
            }
1928
            env->htab_mask = (1ULL << (htabsize + 18)) - 1;
1929
            env->htab_base = value & SDR_64_HTABORG;
1930
        } else
1931
#endif /* defined(TARGET_PPC64) */
1932
        {
1933
            /* FIXME: Should check for valid HTABMASK values */
1934
            env->htab_mask = ((value & SDR_32_HTABMASK) << 16) | 0xFFFF;
1935
            env->htab_base = value & SDR_32_HTABORG;
1936
        }
1927 1937
        tlb_flush(env, 1);
1928 1938
    }
1929 1939
}
b/target-ppc/kvm.c
169 169

  
170 170
#ifdef KVM_CAP_PPC_SEGSTATE
171 171
    if (kvm_check_extension(env->kvm_state, KVM_CAP_PPC_SEGSTATE)) {
172
        env->sdr1 = sregs.u.s.sdr1;
172
        ppc_store_sdr1(env, sregs.u.s.sdr1);
173 173

  
174 174
        /* Sync SLB */
175 175
#ifdef TARGET_PPC64
b/target-ppc/machine.c
37 37
    qemu_put_betls(f, &env->asr);
38 38
    qemu_put_sbe32s(f, &env->slb_nr);
39 39
#endif
40
    qemu_put_betls(f, &env->sdr1);
40
    qemu_put_betls(f, &env->spr[SPR_SDR1]);
41 41
    for (i = 0; i < 32; i++)
42 42
        qemu_put_betls(f, &env->sr[i]);
43 43
    for (i = 0; i < 2; i++)
......
93 93
{
94 94
    CPUState *env = (CPUState *)opaque;
95 95
    unsigned int i, j;
96
    target_ulong sdr1;
96 97

  
97 98
    for (i = 0; i < 32; i++)
98 99
        qemu_get_betls(f, &env->gpr[i]);
......
124 125
    qemu_get_betls(f, &env->asr);
125 126
    qemu_get_sbe32s(f, &env->slb_nr);
126 127
#endif
127
    qemu_get_betls(f, &env->sdr1);
128
    qemu_get_betls(f, &sdr1);
128 129
    for (i = 0; i < 32; i++)
129 130
        qemu_get_betls(f, &env->sr[i]);
130 131
    for (i = 0; i < 2; i++)
......
152 153
#endif
153 154
    for (i = 0; i < 1024; i++)
154 155
        qemu_get_betls(f, &env->spr[i]);
156
    ppc_store_sdr1(env, sdr1);
155 157
    qemu_get_be32s(f, &env->vscr);
156 158
    qemu_get_be64s(f, &env->spe_acc);
157 159
    qemu_get_be32s(f, &env->spe_fscr);
b/target-ppc/translate.c
9126 9126
#if !defined(CONFIG_USER_ONLY)
9127 9127
    cpu_fprintf(f, "SRR0 " TARGET_FMT_lx " SRR1 " TARGET_FMT_lx " SDR1 "
9128 9128
                TARGET_FMT_lx "\n", env->spr[SPR_SRR0], env->spr[SPR_SRR1],
9129
                env->sdr1);
9129
                env->spr[SPR_SDR1]);
9130 9130
#endif
9131 9131

  
9132 9132
#undef RGPL
b/target-ppc/translate_init.c
343 343
}
344 344

  
345 345
/* SDR1 */
346
static void spr_read_sdr1 (void *opaque, int gprn, int sprn)
347
{
348
    tcg_gen_ld_tl(cpu_gpr[gprn], cpu_env, offsetof(CPUState, sdr1));
349
}
350

  
351 346
static void spr_write_sdr1 (void *opaque, int sprn, int gprn)
352 347
{
353 348
    gen_helper_store_sdr1(cpu_gpr[gprn]);
......
671 666
    /* Memory management */
672 667
    spr_register(env, SPR_SDR1, "SDR1",
673 668
                 SPR_NOACCESS, SPR_NOACCESS,
674
                 &spr_read_sdr1, &spr_write_sdr1,
669
                 &spr_read_generic, &spr_write_sdr1,
675 670
                 0x00000000);
676 671
}
677 672

  

Also available in: Unified diff