232 |
232 |
return ret;
|
233 |
233 |
}
|
234 |
234 |
|
235 |
|
static int pte32_check (mmu_ctx_t *ctx, target_ulong pte0, target_ulong pte1,
|
236 |
|
int h, int rw, int type)
|
|
235 |
static always_inline int pte32_check (mmu_ctx_t *ctx,
|
|
236 |
target_ulong pte0, target_ulong pte1,
|
|
237 |
int h, int rw, int type)
|
237 |
238 |
{
|
238 |
239 |
return _pte_check(ctx, 0, pte0, pte1, h, rw, type);
|
239 |
240 |
}
|
240 |
241 |
|
241 |
242 |
#if defined(TARGET_PPC64)
|
242 |
|
static int pte64_check (mmu_ctx_t *ctx, target_ulong pte0, target_ulong pte1,
|
243 |
|
int h, int rw, int type)
|
|
243 |
static always_inline int pte64_check (mmu_ctx_t *ctx,
|
|
244 |
target_ulong pte0, target_ulong pte1,
|
|
245 |
int h, int rw, int type)
|
244 |
246 |
{
|
245 |
247 |
return _pte_check(ctx, 1, pte0, pte1, h, rw, type);
|
246 |
248 |
}
|
247 |
249 |
#endif
|
248 |
250 |
|
249 |
|
static int pte_update_flags (mmu_ctx_t *ctx, target_ulong *pte1p,
|
250 |
|
int ret, int rw)
|
|
251 |
static always_inline int pte_update_flags (mmu_ctx_t *ctx, target_ulong *pte1p,
|
|
252 |
int ret, int rw)
|
251 |
253 |
{
|
252 |
254 |
int store = 0;
|
253 |
255 |
|
... | ... | |
272 |
274 |
}
|
273 |
275 |
|
274 |
276 |
/* Software driven TLB helpers */
|
275 |
|
static int ppc6xx_tlb_getnum (CPUState *env, target_ulong eaddr,
|
276 |
|
int way, int is_code)
|
|
277 |
static always_inline int ppc6xx_tlb_getnum (CPUState *env, target_ulong eaddr,
|
|
278 |
int way, int is_code)
|
277 |
279 |
{
|
278 |
280 |
int nr;
|
279 |
281 |
|
... | ... | |
288 |
290 |
return nr;
|
289 |
291 |
}
|
290 |
292 |
|
291 |
|
static void ppc6xx_tlb_invalidate_all (CPUState *env)
|
|
293 |
static always_inline void ppc6xx_tlb_invalidate_all (CPUState *env)
|
292 |
294 |
{
|
293 |
295 |
ppc6xx_tlb_t *tlb;
|
294 |
296 |
int nr, max;
|
... | ... | |
339 |
341 |
#endif
|
340 |
342 |
}
|
341 |
343 |
|
342 |
|
static void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
|
343 |
|
int is_code)
|
|
344 |
static always_inline void ppc6xx_tlb_invalidate_virt (CPUState *env,
|
|
345 |
target_ulong eaddr,
|
|
346 |
int is_code)
|
344 |
347 |
{
|
345 |
348 |
__ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0);
|
346 |
349 |
}
|
... | ... | |
368 |
371 |
env->last_way = way;
|
369 |
372 |
}
|
370 |
373 |
|
371 |
|
static int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx,
|
372 |
|
target_ulong eaddr, int rw, int access_type)
|
|
374 |
static always_inline int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx,
|
|
375 |
target_ulong eaddr, int rw,
|
|
376 |
int access_type)
|
373 |
377 |
{
|
374 |
378 |
ppc6xx_tlb_t *tlb;
|
375 |
379 |
int nr, best, way;
|
... | ... | |
444 |
448 |
}
|
445 |
449 |
|
446 |
450 |
/* Perform BAT hit & translation */
|
447 |
|
static int get_bat (CPUState *env, mmu_ctx_t *ctx,
|
448 |
|
target_ulong virtual, int rw, int type)
|
|
451 |
static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
|
|
452 |
target_ulong virtual, int rw, int type)
|
449 |
453 |
{
|
450 |
454 |
target_ulong *BATlt, *BATut, *BATu, *BATl;
|
451 |
455 |
target_ulong base, BEPIl, BEPIu, bl;
|
... | ... | |
635 |
639 |
return ret;
|
636 |
640 |
}
|
637 |
641 |
|
638 |
|
static int find_pte32 (mmu_ctx_t *ctx, int h, int rw, int type)
|
|
642 |
static always_inline int find_pte32 (mmu_ctx_t *ctx, int h, int rw, int type)
|
639 |
643 |
{
|
640 |
644 |
return _find_pte(ctx, 0, h, rw, type);
|
641 |
645 |
}
|
642 |
646 |
|
643 |
647 |
#if defined(TARGET_PPC64)
|
644 |
|
static int find_pte64 (mmu_ctx_t *ctx, int h, int rw, int type)
|
|
648 |
static always_inline int find_pte64 (mmu_ctx_t *ctx, int h, int rw, int type)
|
645 |
649 |
{
|
646 |
650 |
return _find_pte(ctx, 1, h, rw, type);
|
647 |
651 |
}
|
... | ... | |
659 |
663 |
}
|
660 |
664 |
|
661 |
665 |
#if defined(TARGET_PPC64)
|
662 |
|
static inline int slb_is_valid (uint64_t slb64)
|
|
666 |
static always_inline int slb_is_valid (uint64_t slb64)
|
663 |
667 |
{
|
664 |
668 |
return slb64 & 0x0000000008000000ULL ? 1 : 0;
|
665 |
669 |
}
|
666 |
670 |
|
667 |
|
static inline void slb_invalidate (uint64_t *slb64)
|
|
671 |
static always_inline void slb_invalidate (uint64_t *slb64)
|
668 |
672 |
{
|
669 |
673 |
*slb64 &= ~0x0000000008000000ULL;
|
670 |
674 |
}
|
671 |
675 |
|
672 |
|
static int slb_lookup (CPUPPCState *env, target_ulong eaddr,
|
673 |
|
target_ulong *vsid, target_ulong *page_mask, int *attr)
|
|
676 |
static always_inline int slb_lookup (CPUPPCState *env, target_ulong eaddr,
|
|
677 |
target_ulong *vsid,
|
|
678 |
target_ulong *page_mask, int *attr)
|
674 |
679 |
{
|
675 |
680 |
target_phys_addr_t sr_base;
|
676 |
681 |
target_ulong mask;
|
... | ... | |
847 |
852 |
return (sdr1 & ((target_ulong)(-1ULL) << sdr_sh)) | (hash & mask);
|
848 |
853 |
}
|
849 |
854 |
|
850 |
|
static int get_segment (CPUState *env, mmu_ctx_t *ctx,
|
851 |
|
target_ulong eaddr, int rw, int type)
|
|
855 |
static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
|
|
856 |
target_ulong eaddr, int rw, int type)
|
852 |
857 |
{
|
853 |
858 |
target_phys_addr_t sdr, hash, mask, sdr_mask, htab_mask;
|
854 |
859 |
target_ulong sr, vsid, vsid_mask, pgidx, page_mask;
|
... | ... | |
1063 |
1068 |
}
|
1064 |
1069 |
|
1065 |
1070 |
/* Generic TLB check function for embedded PowerPC implementations */
|
1066 |
|
static int ppcemb_tlb_check (CPUState *env, ppcemb_tlb_t *tlb,
|
1067 |
|
target_phys_addr_t *raddrp,
|
1068 |
|
target_ulong address,
|
1069 |
|
uint32_t pid, int ext, int i)
|
|
1071 |
static always_inline int ppcemb_tlb_check (CPUState *env, ppcemb_tlb_t *tlb,
|
|
1072 |
target_phys_addr_t *raddrp,
|
|
1073 |
target_ulong address,
|
|
1074 |
uint32_t pid, int ext, int i)
|
1070 |
1075 |
{
|
1071 |
1076 |
target_ulong mask;
|
1072 |
1077 |
|
... | ... | |
1122 |
1127 |
}
|
1123 |
1128 |
|
1124 |
1129 |
/* Helpers specific to PowerPC 40x implementations */
|
1125 |
|
static void ppc4xx_tlb_invalidate_all (CPUState *env)
|
|
1130 |
static always_inline void ppc4xx_tlb_invalidate_all (CPUState *env)
|
1126 |
1131 |
{
|
1127 |
1132 |
ppcemb_tlb_t *tlb;
|
1128 |
1133 |
int i;
|
... | ... | |
1134 |
1139 |
tlb_flush(env, 1);
|
1135 |
1140 |
}
|
1136 |
1141 |
|
1137 |
|
static void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr,
|
1138 |
|
uint32_t pid)
|
|
1142 |
static always_inline void ppc4xx_tlb_invalidate_virt (CPUState *env,
|
|
1143 |
target_ulong eaddr,
|
|
1144 |
uint32_t pid)
|
1139 |
1145 |
{
|
1140 |
1146 |
#if !defined(FLUSH_ALL_TLBS)
|
1141 |
1147 |
ppcemb_tlb_t *tlb;
|
... | ... | |
1286 |
1292 |
return ret;
|
1287 |
1293 |
}
|
1288 |
1294 |
|
1289 |
|
static int check_physical (CPUState *env, mmu_ctx_t *ctx,
|
1290 |
|
target_ulong eaddr, int rw)
|
|
1295 |
static always_inline int check_physical (CPUState *env, mmu_ctx_t *ctx,
|
|
1296 |
target_ulong eaddr, int rw)
|
1291 |
1297 |
{
|
1292 |
1298 |
int in_plb, ret;
|
1293 |
1299 |
|
... | ... | |
1986 |
1992 |
env->error_code = 0;
|
1987 |
1993 |
}
|
1988 |
1994 |
#else /* defined (CONFIG_USER_ONLY) */
|
1989 |
|
static void dump_syscall (CPUState *env)
|
|
1995 |
static always_inline void dump_syscall (CPUState *env)
|
1990 |
1996 |
{
|
1991 |
1997 |
fprintf(logfile, "syscall r0=0x" REGX " r3=0x" REGX " r4=0x" REGX
|
1992 |
1998 |
" r5=0x" REGX " r6=0x" REGX " nip=0x" ADDRX "\n",
|