Revision 99a0949b target-ppc/helper.c
b/target-ppc/helper.c | ||
---|---|---|
97 | 97 |
return 1; |
98 | 98 |
} |
99 | 99 |
|
100 |
target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
|
|
100 |
a_target_phys_addr cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
|
|
101 | 101 |
{ |
102 | 102 |
return addr; |
103 | 103 |
} |
... | ... | |
197 | 197 |
return ret; |
198 | 198 |
} |
199 | 199 |
|
200 |
static inline int _pte_check(mmu_ctx_t *ctx, int is_64b, target_ulong pte0,
|
|
200 |
static inline int _pte_check(a_mmu_ctx *ctx, int is_64b, target_ulong pte0,
|
|
201 | 201 |
target_ulong pte1, int h, int rw, int type) |
202 | 202 |
{ |
203 | 203 |
target_ulong ptem, mmask; |
... | ... | |
233 | 233 |
pp = pte1 & 0x00000003; |
234 | 234 |
} |
235 | 235 |
if (ptem == ctx->ptem) { |
236 |
if (ctx->raddr != (target_phys_addr_t)-1ULL) {
|
|
236 |
if (ctx->raddr != (a_target_phys_addr)-1ULL) {
|
|
237 | 237 |
/* all matches should have equal RPN, WIMG & PP */ |
238 | 238 |
if ((ctx->raddr & mmask) != (pte1 & mmask)) { |
239 | 239 |
qemu_log("Bad RPN/WIMG/PP\n"); |
... | ... | |
259 | 259 |
return ret; |
260 | 260 |
} |
261 | 261 |
|
262 |
static inline int pte32_check(mmu_ctx_t *ctx, target_ulong pte0,
|
|
262 |
static inline int pte32_check(a_mmu_ctx *ctx, target_ulong pte0,
|
|
263 | 263 |
target_ulong pte1, int h, int rw, int type) |
264 | 264 |
{ |
265 | 265 |
return _pte_check(ctx, 0, pte0, pte1, h, rw, type); |
266 | 266 |
} |
267 | 267 |
|
268 | 268 |
#if defined(TARGET_PPC64) |
269 |
static inline int pte64_check(mmu_ctx_t *ctx, target_ulong pte0,
|
|
269 |
static inline int pte64_check(a_mmu_ctx *ctx, target_ulong pte0,
|
|
270 | 270 |
target_ulong pte1, int h, int rw, int type) |
271 | 271 |
{ |
272 | 272 |
return _pte_check(ctx, 1, pte0, pte1, h, rw, type); |
273 | 273 |
} |
274 | 274 |
#endif |
275 | 275 |
|
276 |
static inline int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
|
|
276 |
static inline int pte_update_flags(a_mmu_ctx *ctx, target_ulong *pte1p,
|
|
277 | 277 |
int ret, int rw) |
278 | 278 |
{ |
279 | 279 |
int store = 0; |
... | ... | |
317 | 317 |
|
318 | 318 |
static inline void ppc6xx_tlb_invalidate_all(CPUState *env) |
319 | 319 |
{ |
320 |
ppc6xx_tlb_t *tlb;
|
|
320 |
a_ppc6xx_tlb *tlb;
|
|
321 | 321 |
int nr, max; |
322 | 322 |
|
323 | 323 |
//LOG_SWTLB("Invalidate all TLBs\n"); |
... | ... | |
337 | 337 |
int is_code, int match_epn) |
338 | 338 |
{ |
339 | 339 |
#if !defined(FLUSH_ALL_TLBS) |
340 |
ppc6xx_tlb_t *tlb;
|
|
340 |
a_ppc6xx_tlb *tlb;
|
|
341 | 341 |
int way, nr; |
342 | 342 |
|
343 | 343 |
/* Invalidate ITLB + DTLB, all ways */ |
... | ... | |
366 | 366 |
void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code, |
367 | 367 |
target_ulong pte0, target_ulong pte1) |
368 | 368 |
{ |
369 |
ppc6xx_tlb_t *tlb;
|
|
369 |
a_ppc6xx_tlb *tlb;
|
|
370 | 370 |
int nr; |
371 | 371 |
|
372 | 372 |
nr = ppc6xx_tlb_getnum(env, EPN, way, is_code); |
... | ... | |
382 | 382 |
env->last_way = way; |
383 | 383 |
} |
384 | 384 |
|
385 |
static inline int ppc6xx_tlb_check(CPUState *env, mmu_ctx_t *ctx,
|
|
385 |
static inline int ppc6xx_tlb_check(CPUState *env, a_mmu_ctx *ctx,
|
|
386 | 386 |
target_ulong eaddr, int rw, int access_type) |
387 | 387 |
{ |
388 |
ppc6xx_tlb_t *tlb;
|
|
388 |
a_ppc6xx_tlb *tlb;
|
|
389 | 389 |
int nr, best, way; |
390 | 390 |
int ret; |
391 | 391 |
|
... | ... | |
494 | 494 |
*protp = prot; |
495 | 495 |
} |
496 | 496 |
|
497 |
static inline int get_bat(CPUState *env, mmu_ctx_t *ctx, target_ulong virtual,
|
|
497 |
static inline int get_bat(CPUState *env, a_mmu_ctx *ctx, target_ulong virtual,
|
|
498 | 498 |
int rw, int type) |
499 | 499 |
{ |
500 | 500 |
target_ulong *BATlt, *BATut, *BATu, *BATl; |
... | ... | |
571 | 571 |
} |
572 | 572 |
|
573 | 573 |
/* PTE table lookup */ |
574 |
static inline int _find_pte(mmu_ctx_t *ctx, int is_64b, int h, int rw,
|
|
574 |
static inline int _find_pte(a_mmu_ctx *ctx, int is_64b, int h, int rw,
|
|
575 | 575 |
int type, int target_page_bits) |
576 | 576 |
{ |
577 | 577 |
target_ulong base, pte0, pte1; |
... | ... | |
653 | 653 |
return ret; |
654 | 654 |
} |
655 | 655 |
|
656 |
static inline int find_pte32(mmu_ctx_t *ctx, int h, int rw, int type,
|
|
656 |
static inline int find_pte32(a_mmu_ctx *ctx, int h, int rw, int type,
|
|
657 | 657 |
int target_page_bits) |
658 | 658 |
{ |
659 | 659 |
return _find_pte(ctx, 0, h, rw, type, target_page_bits); |
660 | 660 |
} |
661 | 661 |
|
662 | 662 |
#if defined(TARGET_PPC64) |
663 |
static inline int find_pte64(mmu_ctx_t *ctx, int h, int rw, int type,
|
|
663 |
static inline int find_pte64(a_mmu_ctx *ctx, int h, int rw, int type,
|
|
664 | 664 |
int target_page_bits) |
665 | 665 |
{ |
666 | 666 |
return _find_pte(ctx, 1, h, rw, type, target_page_bits); |
667 | 667 |
} |
668 | 668 |
#endif |
669 | 669 |
|
670 |
static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw,
|
|
670 |
static inline int find_pte(CPUState *env, a_mmu_ctx *ctx, int h, int rw,
|
|
671 | 671 |
int type, int target_page_bits) |
672 | 672 |
{ |
673 | 673 |
#if defined(TARGET_PPC64) |
... | ... | |
679 | 679 |
} |
680 | 680 |
|
681 | 681 |
#if defined(TARGET_PPC64) |
682 |
static ppc_slb_t *slb_get_entry(CPUPPCState *env, int nr)
|
|
682 |
static a_ppc_slb *slb_get_entry(CPUPPCState *env, int nr)
|
|
683 | 683 |
{ |
684 |
ppc_slb_t *retval = &env->slb[nr];
|
|
684 |
a_ppc_slb *retval = &env->slb[nr];
|
|
685 | 685 |
|
686 | 686 |
#if 0 // XXX implement bridge mode? |
687 | 687 |
if (env->spr[SPR_ASR] & 1) { |
688 |
target_phys_addr_t sr_base;
|
|
688 |
a_target_phys_addr sr_base;
|
|
689 | 689 |
|
690 | 690 |
sr_base = env->spr[SPR_ASR] & 0xfffffffffffff000; |
691 | 691 |
sr_base += (12 * nr); |
... | ... | |
698 | 698 |
return retval; |
699 | 699 |
} |
700 | 700 |
|
701 |
static void slb_set_entry(CPUPPCState *env, int nr, ppc_slb_t *slb)
|
|
701 |
static void slb_set_entry(CPUPPCState *env, int nr, a_ppc_slb *slb)
|
|
702 | 702 |
{ |
703 |
ppc_slb_t *entry = &env->slb[nr];
|
|
703 |
a_ppc_slb *entry = &env->slb[nr];
|
|
704 | 704 |
|
705 | 705 |
if (slb == entry) |
706 | 706 |
return; |
... | ... | |
709 | 709 |
entry->tmp = slb->tmp; |
710 | 710 |
} |
711 | 711 |
|
712 |
static inline int slb_is_valid(ppc_slb_t *slb)
|
|
712 |
static inline int slb_is_valid(a_ppc_slb *slb)
|
|
713 | 713 |
{ |
714 | 714 |
return (int)(slb->tmp64 & 0x0000000008000000ULL); |
715 | 715 |
} |
716 | 716 |
|
717 |
static inline void slb_invalidate(ppc_slb_t *slb)
|
|
717 |
static inline void slb_invalidate(a_ppc_slb *slb)
|
|
718 | 718 |
{ |
719 | 719 |
slb->tmp64 &= ~0x0000000008000000ULL; |
720 | 720 |
} |
... | ... | |
730 | 730 |
LOG_SLB("%s: eaddr " TARGET_FMT_lx "\n", __func__, eaddr); |
731 | 731 |
mask = 0x0000000000000000ULL; /* Avoid gcc warning */ |
732 | 732 |
for (n = 0; n < env->slb_nr; n++) { |
733 |
ppc_slb_t *slb = slb_get_entry(env, n);
|
|
733 |
a_ppc_slb *slb = slb_get_entry(env, n);
|
|
734 | 734 |
|
735 | 735 |
LOG_SLB("%s: seg %d %016" PRIx64 " %08" |
736 | 736 |
PRIx32 "\n", __func__, n, slb->tmp64, slb->tmp); |
... | ... | |
768 | 768 |
do_invalidate = 0; |
769 | 769 |
/* XXX: Warning: slbia never invalidates the first segment */ |
770 | 770 |
for (n = 1; n < env->slb_nr; n++) { |
771 |
ppc_slb_t *slb = slb_get_entry(env, n);
|
|
771 |
a_ppc_slb *slb = slb_get_entry(env, n);
|
|
772 | 772 |
|
773 | 773 |
if (slb_is_valid(slb)) { |
774 | 774 |
slb_invalidate(slb); |
... | ... | |
792 | 792 |
|
793 | 793 |
n = slb_lookup(env, T0, &vsid, &page_mask, &attr, NULL); |
794 | 794 |
if (n >= 0) { |
795 |
ppc_slb_t *slb = slb_get_entry(env, n);
|
|
795 |
a_ppc_slb *slb = slb_get_entry(env, n);
|
|
796 | 796 |
|
797 | 797 |
if (slb_is_valid(slb)) { |
798 | 798 |
slb_invalidate(slb); |
... | ... | |
809 | 809 |
target_ulong ppc_load_slb (CPUPPCState *env, int slb_nr) |
810 | 810 |
{ |
811 | 811 |
target_ulong rt; |
812 |
ppc_slb_t *slb = slb_get_entry(env, slb_nr);
|
|
812 |
a_ppc_slb *slb = slb_get_entry(env, slb_nr);
|
|
813 | 813 |
|
814 | 814 |
if (slb_is_valid(slb)) { |
815 | 815 |
/* SLB entry is valid */ |
... | ... | |
829 | 829 |
|
830 | 830 |
void ppc_store_slb (CPUPPCState *env, target_ulong rb, target_ulong rs) |
831 | 831 |
{ |
832 |
ppc_slb_t *slb;
|
|
832 |
a_ppc_slb *slb;
|
|
833 | 833 |
|
834 | 834 |
uint64_t vsid; |
835 | 835 |
uint64_t esid; |
... | ... | |
855 | 855 |
#endif /* defined(TARGET_PPC64) */ |
856 | 856 |
|
857 | 857 |
/* Perform segment based translation */ |
858 |
static inline target_phys_addr_t get_pgaddr(target_phys_addr_t sdr1,
|
|
858 |
static inline a_target_phys_addr get_pgaddr(a_target_phys_addr sdr1,
|
|
859 | 859 |
int sdr_sh, |
860 |
target_phys_addr_t hash,
|
|
861 |
target_phys_addr_t mask)
|
|
860 |
a_target_phys_addr hash,
|
|
861 |
a_target_phys_addr mask)
|
|
862 | 862 |
{ |
863 |
return (sdr1 & ((target_phys_addr_t)(-1ULL) << sdr_sh)) | (hash & mask);
|
|
863 |
return (sdr1 & ((a_target_phys_addr)(-1ULL) << sdr_sh)) | (hash & mask);
|
|
864 | 864 |
} |
865 | 865 |
|
866 |
static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
|
|
866 |
static inline int get_segment(CPUState *env, a_mmu_ctx *ctx,
|
|
867 | 867 |
target_ulong eaddr, int rw, int type) |
868 | 868 |
{ |
869 |
target_phys_addr_t sdr, hash, mask, sdr_mask, htab_mask;
|
|
869 |
a_target_phys_addr sdr, hash, mask, sdr_mask, htab_mask;
|
|
870 | 870 |
target_ulong sr, vsid, vsid_mask, pgidx, page_mask; |
871 | 871 |
#if defined(TARGET_PPC64) |
872 | 872 |
int attr; |
... | ... | |
958 | 958 |
ctx->ptem = (vsid << 7) | (pgidx >> 10); |
959 | 959 |
} |
960 | 960 |
/* Initialize real address with an invalid value */ |
961 |
ctx->raddr = (target_phys_addr_t)-1ULL;
|
|
961 |
ctx->raddr = (a_target_phys_addr)-1ULL;
|
|
962 | 962 |
if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx || |
963 | 963 |
env->mmu_model == POWERPC_MMU_SOFT_74xx)) { |
964 | 964 |
/* Software TLB search */ |
... | ... | |
985 | 985 |
} |
986 | 986 |
#if defined (DUMP_PAGE_TABLES) |
987 | 987 |
if (qemu_log_enabled()) { |
988 |
target_phys_addr_t curaddr;
|
|
988 |
a_target_phys_addr curaddr;
|
|
989 | 989 |
uint32_t a0, a1, a2, a3; |
990 | 990 |
qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx |
991 | 991 |
"\n", sdr, mask + 0x80); |
... | ... | |
1049 | 1049 |
} |
1050 | 1050 |
|
1051 | 1051 |
/* Generic TLB check function for embedded PowerPC implementations */ |
1052 |
static inline int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb,
|
|
1053 |
target_phys_addr_t *raddrp,
|
|
1052 |
static inline int ppcemb_tlb_check(CPUState *env, a_ppcemb_tlb *tlb,
|
|
1053 |
a_target_phys_addr *raddrp,
|
|
1054 | 1054 |
target_ulong address, uint32_t pid, int ext, |
1055 | 1055 |
int i) |
1056 | 1056 |
{ |
... | ... | |
1075 | 1075 |
#if (TARGET_PHYS_ADDR_BITS >= 36) |
1076 | 1076 |
if (ext) { |
1077 | 1077 |
/* Extend the physical address to 36 bits */ |
1078 |
*raddrp |= (target_phys_addr_t)(tlb->RPN & 0xF) << 32;
|
|
1078 |
*raddrp |= (a_target_phys_addr)(tlb->RPN & 0xF) << 32;
|
|
1079 | 1079 |
} |
1080 | 1080 |
#endif |
1081 | 1081 |
|
... | ... | |
1085 | 1085 |
/* Generic TLB search function for PowerPC embedded implementations */ |
1086 | 1086 |
int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid) |
1087 | 1087 |
{ |
1088 |
ppcemb_tlb_t *tlb;
|
|
1089 |
target_phys_addr_t raddr;
|
|
1088 |
a_ppcemb_tlb *tlb;
|
|
1089 |
a_target_phys_addr raddr;
|
|
1090 | 1090 |
int i, ret; |
1091 | 1091 |
|
1092 | 1092 |
/* Default return value is no match */ |
... | ... | |
1105 | 1105 |
/* Helpers specific to PowerPC 40x implementations */ |
1106 | 1106 |
static inline void ppc4xx_tlb_invalidate_all(CPUState *env) |
1107 | 1107 |
{ |
1108 |
ppcemb_tlb_t *tlb;
|
|
1108 |
a_ppcemb_tlb *tlb;
|
|
1109 | 1109 |
int i; |
1110 | 1110 |
|
1111 | 1111 |
for (i = 0; i < env->nb_tlb; i++) { |
... | ... | |
1119 | 1119 |
target_ulong eaddr, uint32_t pid) |
1120 | 1120 |
{ |
1121 | 1121 |
#if !defined(FLUSH_ALL_TLBS) |
1122 |
ppcemb_tlb_t *tlb;
|
|
1123 |
target_phys_addr_t raddr;
|
|
1122 |
a_ppcemb_tlb *tlb;
|
|
1123 |
a_target_phys_addr raddr;
|
|
1124 | 1124 |
target_ulong page, end; |
1125 | 1125 |
int i; |
1126 | 1126 |
|
... | ... | |
1139 | 1139 |
#endif |
1140 | 1140 |
} |
1141 | 1141 |
|
1142 |
static int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
|
|
1142 |
static int mmu40x_get_physical_address (CPUState *env, a_mmu_ctx *ctx,
|
|
1143 | 1143 |
target_ulong address, int rw, int access_type) |
1144 | 1144 |
{ |
1145 |
ppcemb_tlb_t *tlb;
|
|
1146 |
target_phys_addr_t raddr;
|
|
1145 |
a_ppcemb_tlb *tlb;
|
|
1146 |
a_target_phys_addr raddr;
|
|
1147 | 1147 |
int i, ret, zsel, zpr, pr; |
1148 | 1148 |
|
1149 | 1149 |
ret = -1; |
1150 |
raddr = (target_phys_addr_t)-1ULL;
|
|
1150 |
raddr = (a_target_phys_addr)-1ULL;
|
|
1151 | 1151 |
pr = msr_pr; |
1152 | 1152 |
for (i = 0; i < env->nb_tlb; i++) { |
1153 | 1153 |
tlb = &env->tlb[i].tlbe; |
... | ... | |
1208 | 1208 |
env->spr[SPR_405_SLER] = val; |
1209 | 1209 |
} |
1210 | 1210 |
|
1211 |
static int mmubooke_get_physical_address (CPUState *env, mmu_ctx_t *ctx,
|
|
1211 |
static int mmubooke_get_physical_address (CPUState *env, a_mmu_ctx *ctx,
|
|
1212 | 1212 |
target_ulong address, int rw, |
1213 | 1213 |
int access_type) |
1214 | 1214 |
{ |
1215 |
ppcemb_tlb_t *tlb;
|
|
1216 |
target_phys_addr_t raddr;
|
|
1215 |
a_ppcemb_tlb *tlb;
|
|
1216 |
a_target_phys_addr raddr;
|
|
1217 | 1217 |
int i, prot, ret; |
1218 | 1218 |
|
1219 | 1219 |
ret = -1; |
1220 |
raddr = (target_phys_addr_t)-1ULL;
|
|
1220 |
raddr = (a_target_phys_addr)-1ULL;
|
|
1221 | 1221 |
for (i = 0; i < env->nb_tlb; i++) { |
1222 | 1222 |
tlb = &env->tlb[i].tlbe; |
1223 | 1223 |
if (ppcemb_tlb_check(env, tlb, &raddr, address, |
... | ... | |
1254 | 1254 |
return ret; |
1255 | 1255 |
} |
1256 | 1256 |
|
1257 |
static inline int check_physical(CPUState *env, mmu_ctx_t *ctx,
|
|
1257 |
static inline int check_physical(CPUState *env, a_mmu_ctx *ctx,
|
|
1258 | 1258 |
target_ulong eaddr, int rw) |
1259 | 1259 |
{ |
1260 | 1260 |
int in_plb, ret; |
... | ... | |
1320 | 1320 |
return ret; |
1321 | 1321 |
} |
1322 | 1322 |
|
1323 |
int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr,
|
|
1323 |
int get_physical_address (CPUState *env, a_mmu_ctx *ctx, target_ulong eaddr,
|
|
1324 | 1324 |
int rw, int access_type) |
1325 | 1325 |
{ |
1326 | 1326 |
int ret; |
... | ... | |
1384 | 1384 |
return ret; |
1385 | 1385 |
} |
1386 | 1386 |
|
1387 |
target_phys_addr_t cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
|
|
1387 |
a_target_phys_addr cpu_get_phys_page_debug (CPUState *env, target_ulong addr)
|
|
1388 | 1388 |
{ |
1389 |
mmu_ctx_t ctx;
|
|
1389 |
a_mmu_ctx ctx;
|
|
1390 | 1390 |
|
1391 | 1391 |
if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0)) |
1392 | 1392 |
return -1; |
... | ... | |
1398 | 1398 |
int cpu_ppc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
1399 | 1399 |
int mmu_idx, int is_softmmu) |
1400 | 1400 |
{ |
1401 |
mmu_ctx_t ctx;
|
|
1401 |
a_mmu_ctx ctx;
|
|
1402 | 1402 |
int access_type; |
1403 | 1403 |
int ret = 0; |
1404 | 1404 |
|
... | ... | |
2800 | 2800 |
CPUPPCState *cpu_ppc_init (const char *cpu_model) |
2801 | 2801 |
{ |
2802 | 2802 |
CPUPPCState *env; |
2803 |
const ppc_def_t *def;
|
|
2803 |
const a_ppc_def *def;
|
|
2804 | 2804 |
|
2805 | 2805 |
def = cpu_ppc_find_by_name(cpu_model); |
2806 | 2806 |
if (!def) |
Also available in: Unified diff