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