Revision 636aa200 target-ppc/helper.c
b/target-ppc/helper.c | ||
---|---|---|
104 | 104 |
|
105 | 105 |
#else |
106 | 106 |
/* Common routines used by software and hardware TLBs emulation */ |
107 |
static always_inline int pte_is_valid (target_ulong pte0)
|
|
107 |
static inline int pte_is_valid(target_ulong pte0)
|
|
108 | 108 |
{ |
109 | 109 |
return pte0 & 0x80000000 ? 1 : 0; |
110 | 110 |
} |
111 | 111 |
|
112 |
static always_inline void pte_invalidate (target_ulong *pte0)
|
|
112 |
static inline void pte_invalidate(target_ulong *pte0)
|
|
113 | 113 |
{ |
114 | 114 |
*pte0 &= ~0x80000000; |
115 | 115 |
} |
116 | 116 |
|
117 | 117 |
#if defined(TARGET_PPC64) |
118 |
static always_inline int pte64_is_valid (target_ulong pte0)
|
|
118 |
static inline int pte64_is_valid(target_ulong pte0)
|
|
119 | 119 |
{ |
120 | 120 |
return pte0 & 0x0000000000000001ULL ? 1 : 0; |
121 | 121 |
} |
122 | 122 |
|
123 |
static always_inline void pte64_invalidate (target_ulong *pte0)
|
|
123 |
static inline void pte64_invalidate(target_ulong *pte0)
|
|
124 | 124 |
{ |
125 | 125 |
*pte0 &= ~0x0000000000000001ULL; |
126 | 126 |
} |
... | ... | |
133 | 133 |
#define PTE64_CHECK_MASK (TARGET_PAGE_MASK | 0x7F) |
134 | 134 |
#endif |
135 | 135 |
|
136 |
static always_inline int pp_check (int key, int pp, int nx)
|
|
136 |
static inline int pp_check(int key, int pp, int nx)
|
|
137 | 137 |
{ |
138 | 138 |
int access; |
139 | 139 |
|
... | ... | |
173 | 173 |
return access; |
174 | 174 |
} |
175 | 175 |
|
176 |
static always_inline int check_prot (int prot, int rw, int access_type)
|
|
176 |
static inline int check_prot(int prot, int rw, int access_type)
|
|
177 | 177 |
{ |
178 | 178 |
int ret; |
179 | 179 |
|
... | ... | |
197 | 197 |
return ret; |
198 | 198 |
} |
199 | 199 |
|
200 |
static always_inline int _pte_check (mmu_ctx_t *ctx, int is_64b, |
|
201 |
target_ulong pte0, target_ulong pte1, |
|
202 |
int h, int rw, int type) |
|
200 |
static inline int _pte_check(mmu_ctx_t *ctx, int is_64b, target_ulong pte0, |
|
201 |
target_ulong pte1, int h, int rw, int type) |
|
203 | 202 |
{ |
204 | 203 |
target_ulong ptem, mmask; |
205 | 204 |
int access, ret, pteh, ptev, pp; |
... | ... | |
260 | 259 |
return ret; |
261 | 260 |
} |
262 | 261 |
|
263 |
static always_inline int pte32_check (mmu_ctx_t *ctx, |
|
264 |
target_ulong pte0, target_ulong pte1, |
|
265 |
int h, int rw, int type) |
|
262 |
static inline int pte32_check(mmu_ctx_t *ctx, target_ulong pte0, |
|
263 |
target_ulong pte1, int h, int rw, int type) |
|
266 | 264 |
{ |
267 | 265 |
return _pte_check(ctx, 0, pte0, pte1, h, rw, type); |
268 | 266 |
} |
269 | 267 |
|
270 | 268 |
#if defined(TARGET_PPC64) |
271 |
static always_inline int pte64_check (mmu_ctx_t *ctx, |
|
272 |
target_ulong pte0, target_ulong pte1, |
|
273 |
int h, int rw, int type) |
|
269 |
static inline int pte64_check(mmu_ctx_t *ctx, target_ulong pte0, |
|
270 |
target_ulong pte1, int h, int rw, int type) |
|
274 | 271 |
{ |
275 | 272 |
return _pte_check(ctx, 1, pte0, pte1, h, rw, type); |
276 | 273 |
} |
277 | 274 |
#endif |
278 | 275 |
|
279 |
static always_inline int pte_update_flags (mmu_ctx_t *ctx, target_ulong *pte1p,
|
|
280 |
int ret, int rw)
|
|
276 |
static inline int pte_update_flags(mmu_ctx_t *ctx, target_ulong *pte1p,
|
|
277 |
int ret, int rw) |
|
281 | 278 |
{ |
282 | 279 |
int store = 0; |
283 | 280 |
|
... | ... | |
302 | 299 |
} |
303 | 300 |
|
304 | 301 |
/* Software driven TLB helpers */ |
305 |
static always_inline int ppc6xx_tlb_getnum (CPUState *env, target_ulong eaddr,
|
|
306 |
int way, int is_code)
|
|
302 |
static inline int ppc6xx_tlb_getnum(CPUState *env, target_ulong eaddr, int way,
|
|
303 |
int is_code) |
|
307 | 304 |
{ |
308 | 305 |
int nr; |
309 | 306 |
|
... | ... | |
318 | 315 |
return nr; |
319 | 316 |
} |
320 | 317 |
|
321 |
static always_inline void ppc6xx_tlb_invalidate_all (CPUState *env)
|
|
318 |
static inline void ppc6xx_tlb_invalidate_all(CPUState *env)
|
|
322 | 319 |
{ |
323 | 320 |
ppc6xx_tlb_t *tlb; |
324 | 321 |
int nr, max; |
... | ... | |
335 | 332 |
tlb_flush(env, 1); |
336 | 333 |
} |
337 | 334 |
|
338 |
static always_inline void __ppc6xx_tlb_invalidate_virt (CPUState *env, |
|
339 |
target_ulong eaddr, |
|
340 |
int is_code, |
|
341 |
int match_epn) |
|
335 |
static inline void __ppc6xx_tlb_invalidate_virt(CPUState *env, |
|
336 |
target_ulong eaddr, |
|
337 |
int is_code, int match_epn) |
|
342 | 338 |
{ |
343 | 339 |
#if !defined(FLUSH_ALL_TLBS) |
344 | 340 |
ppc6xx_tlb_t *tlb; |
... | ... | |
361 | 357 |
#endif |
362 | 358 |
} |
363 | 359 |
|
364 |
static always_inline void ppc6xx_tlb_invalidate_virt (CPUState *env, |
|
365 |
target_ulong eaddr, |
|
366 |
int is_code) |
|
360 |
static inline void ppc6xx_tlb_invalidate_virt(CPUState *env, |
|
361 |
target_ulong eaddr, int is_code) |
|
367 | 362 |
{ |
368 | 363 |
__ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0); |
369 | 364 |
} |
... | ... | |
387 | 382 |
env->last_way = way; |
388 | 383 |
} |
389 | 384 |
|
390 |
static always_inline int ppc6xx_tlb_check (CPUState *env, mmu_ctx_t *ctx, |
|
391 |
target_ulong eaddr, int rw, |
|
392 |
int access_type) |
|
385 |
static inline int ppc6xx_tlb_check(CPUState *env, mmu_ctx_t *ctx, |
|
386 |
target_ulong eaddr, int rw, int access_type) |
|
393 | 387 |
{ |
394 | 388 |
ppc6xx_tlb_t *tlb; |
395 | 389 |
int nr, best, way; |
... | ... | |
452 | 446 |
} |
453 | 447 |
|
454 | 448 |
/* Perform BAT hit & translation */ |
455 |
static always_inline void bat_size_prot (CPUState *env, target_ulong *blp,
|
|
456 |
int *validp, int *protp,
|
|
457 |
target_ulong *BATu, target_ulong *BATl)
|
|
449 |
static inline void bat_size_prot(CPUState *env, target_ulong *blp, int *validp,
|
|
450 |
int *protp, target_ulong *BATu,
|
|
451 |
target_ulong *BATl) |
|
458 | 452 |
{ |
459 | 453 |
target_ulong bl; |
460 | 454 |
int pp, valid, prot; |
... | ... | |
477 | 471 |
*protp = prot; |
478 | 472 |
} |
479 | 473 |
|
480 |
static always_inline void bat_601_size_prot (CPUState *env,target_ulong *blp, |
|
481 |
int *validp, int *protp, |
|
482 |
target_ulong *BATu, |
|
483 |
target_ulong *BATl) |
|
474 |
static inline void bat_601_size_prot(CPUState *env, target_ulong *blp, |
|
475 |
int *validp, int *protp, |
|
476 |
target_ulong *BATu, target_ulong *BATl) |
|
484 | 477 |
{ |
485 | 478 |
target_ulong bl; |
486 | 479 |
int key, pp, valid, prot; |
... | ... | |
503 | 496 |
*protp = prot; |
504 | 497 |
} |
505 | 498 |
|
506 |
static always_inline int get_bat (CPUState *env, mmu_ctx_t *ctx,
|
|
507 |
target_ulong virtual, int rw, int type)
|
|
499 |
static inline int get_bat(CPUState *env, mmu_ctx_t *ctx, target_ulong virtual,
|
|
500 |
int rw, int type) |
|
508 | 501 |
{ |
509 | 502 |
target_ulong *BATlt, *BATut, *BATu, *BATl; |
510 | 503 |
target_ulong base, BEPIl, BEPIu, bl; |
... | ... | |
579 | 572 |
} |
580 | 573 |
|
581 | 574 |
/* PTE table lookup */ |
582 |
static always_inline int _find_pte (mmu_ctx_t *ctx, int is_64b, int h, |
|
583 |
int rw, int type, |
|
584 |
int target_page_bits) |
|
575 |
static inline int _find_pte(mmu_ctx_t *ctx, int is_64b, int h, int rw, |
|
576 |
int type, int target_page_bits) |
|
585 | 577 |
{ |
586 | 578 |
target_ulong base, pte0, pte1; |
587 | 579 |
int i, good = -1; |
... | ... | |
664 | 656 |
return ret; |
665 | 657 |
} |
666 | 658 |
|
667 |
static always_inline int find_pte32 (mmu_ctx_t *ctx, int h, int rw,
|
|
668 |
int type, int target_page_bits)
|
|
659 |
static inline int find_pte32(mmu_ctx_t *ctx, int h, int rw, int type,
|
|
660 |
int target_page_bits) |
|
669 | 661 |
{ |
670 | 662 |
return _find_pte(ctx, 0, h, rw, type, target_page_bits); |
671 | 663 |
} |
672 | 664 |
|
673 | 665 |
#if defined(TARGET_PPC64) |
674 |
static always_inline int find_pte64 (mmu_ctx_t *ctx, int h, int rw,
|
|
675 |
int type, int target_page_bits)
|
|
666 |
static inline int find_pte64(mmu_ctx_t *ctx, int h, int rw, int type,
|
|
667 |
int target_page_bits) |
|
676 | 668 |
{ |
677 | 669 |
return _find_pte(ctx, 1, h, rw, type, target_page_bits); |
678 | 670 |
} |
679 | 671 |
#endif |
680 | 672 |
|
681 |
static always_inline int find_pte (CPUState *env, mmu_ctx_t *ctx, |
|
682 |
int h, int rw, int type, |
|
683 |
int target_page_bits) |
|
673 |
static inline int find_pte(CPUState *env, mmu_ctx_t *ctx, int h, int rw, |
|
674 |
int type, int target_page_bits) |
|
684 | 675 |
{ |
685 | 676 |
#if defined(TARGET_PPC64) |
686 | 677 |
if (env->mmu_model & POWERPC_MMU_64) |
... | ... | |
721 | 712 |
entry->tmp = slb->tmp; |
722 | 713 |
} |
723 | 714 |
|
724 |
static always_inline int slb_is_valid (ppc_slb_t *slb)
|
|
715 |
static inline int slb_is_valid(ppc_slb_t *slb)
|
|
725 | 716 |
{ |
726 | 717 |
return (int)(slb->tmp64 & 0x0000000008000000ULL); |
727 | 718 |
} |
728 | 719 |
|
729 |
static always_inline void slb_invalidate (ppc_slb_t *slb)
|
|
720 |
static inline void slb_invalidate(ppc_slb_t *slb)
|
|
730 | 721 |
{ |
731 | 722 |
slb->tmp64 &= ~0x0000000008000000ULL; |
732 | 723 |
} |
733 | 724 |
|
734 |
static always_inline int slb_lookup (CPUPPCState *env, target_ulong eaddr, |
|
735 |
target_ulong *vsid, |
|
736 |
target_ulong *page_mask, int *attr, |
|
737 |
int *target_page_bits) |
|
725 |
static inline int slb_lookup(CPUPPCState *env, target_ulong eaddr, |
|
726 |
target_ulong *vsid, target_ulong *page_mask, |
|
727 |
int *attr, int *target_page_bits) |
|
738 | 728 |
{ |
739 | 729 |
target_ulong mask; |
740 | 730 |
int n, ret; |
... | ... | |
868 | 858 |
#endif /* defined(TARGET_PPC64) */ |
869 | 859 |
|
870 | 860 |
/* Perform segment based translation */ |
871 |
static always_inline target_phys_addr_t get_pgaddr (target_phys_addr_t sdr1,
|
|
872 |
int sdr_sh,
|
|
873 |
target_phys_addr_t hash,
|
|
874 |
target_phys_addr_t mask)
|
|
861 |
static inline target_phys_addr_t get_pgaddr(target_phys_addr_t sdr1,
|
|
862 |
int sdr_sh, |
|
863 |
target_phys_addr_t hash, |
|
864 |
target_phys_addr_t mask) |
|
875 | 865 |
{ |
876 | 866 |
return (sdr1 & ((target_phys_addr_t)(-1ULL) << sdr_sh)) | (hash & mask); |
877 | 867 |
} |
878 | 868 |
|
879 |
static always_inline int get_segment (CPUState *env, mmu_ctx_t *ctx,
|
|
880 |
target_ulong eaddr, int rw, int type)
|
|
869 |
static inline int get_segment(CPUState *env, mmu_ctx_t *ctx,
|
|
870 |
target_ulong eaddr, int rw, int type) |
|
881 | 871 |
{ |
882 | 872 |
target_phys_addr_t sdr, hash, mask, sdr_mask, htab_mask; |
883 | 873 |
target_ulong sr, vsid, vsid_mask, pgidx, page_mask; |
... | ... | |
1063 | 1053 |
} |
1064 | 1054 |
|
1065 | 1055 |
/* Generic TLB check function for embedded PowerPC implementations */ |
1066 |
static always_inline 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)
|
|
1056 |
static inline int ppcemb_tlb_check(CPUState *env, ppcemb_tlb_t *tlb,
|
|
1057 |
target_phys_addr_t *raddrp, |
|
1058 |
target_ulong address, uint32_t pid, int ext,
|
|
1059 |
int i) |
|
1070 | 1060 |
{ |
1071 | 1061 |
target_ulong mask; |
1072 | 1062 |
|
... | ... | |
1117 | 1107 |
} |
1118 | 1108 |
|
1119 | 1109 |
/* Helpers specific to PowerPC 40x implementations */ |
1120 |
static always_inline void ppc4xx_tlb_invalidate_all (CPUState *env)
|
|
1110 |
static inline void ppc4xx_tlb_invalidate_all(CPUState *env)
|
|
1121 | 1111 |
{ |
1122 | 1112 |
ppcemb_tlb_t *tlb; |
1123 | 1113 |
int i; |
... | ... | |
1129 | 1119 |
tlb_flush(env, 1); |
1130 | 1120 |
} |
1131 | 1121 |
|
1132 |
static always_inline void ppc4xx_tlb_invalidate_virt (CPUState *env, |
|
1133 |
target_ulong eaddr, |
|
1134 |
uint32_t pid) |
|
1122 |
static inline void ppc4xx_tlb_invalidate_virt(CPUState *env, |
|
1123 |
target_ulong eaddr, uint32_t pid) |
|
1135 | 1124 |
{ |
1136 | 1125 |
#if !defined(FLUSH_ALL_TLBS) |
1137 | 1126 |
ppcemb_tlb_t *tlb; |
... | ... | |
1270 | 1259 |
return ret; |
1271 | 1260 |
} |
1272 | 1261 |
|
1273 |
static always_inline int check_physical (CPUState *env, mmu_ctx_t *ctx,
|
|
1274 |
target_ulong eaddr, int rw)
|
|
1262 |
static inline int check_physical(CPUState *env, mmu_ctx_t *ctx,
|
|
1263 |
target_ulong eaddr, int rw) |
|
1275 | 1264 |
{ |
1276 | 1265 |
int in_plb, ret; |
1277 | 1266 |
|
... | ... | |
1674 | 1663 |
/*****************************************************************************/ |
1675 | 1664 |
/* BATs management */ |
1676 | 1665 |
#if !defined(FLUSH_ALL_TLBS) |
1677 |
static always_inline void do_invalidate_BAT (CPUPPCState *env, |
|
1678 |
target_ulong BATu, |
|
1679 |
target_ulong mask) |
|
1666 |
static inline void do_invalidate_BAT(CPUPPCState *env, target_ulong BATu, |
|
1667 |
target_ulong mask) |
|
1680 | 1668 |
{ |
1681 | 1669 |
target_ulong base, end, page; |
1682 | 1670 |
|
... | ... | |
1690 | 1678 |
} |
1691 | 1679 |
#endif |
1692 | 1680 |
|
1693 |
static always_inline void dump_store_bat (CPUPPCState *env, char ID,
|
|
1694 |
int ul, int nr, target_ulong value)
|
|
1681 |
static inline void dump_store_bat(CPUPPCState *env, char ID, int ul, int nr,
|
|
1682 |
target_ulong value) |
|
1695 | 1683 |
{ |
1696 | 1684 |
LOG_BATS("Set %cBAT%d%c to " ADDRX " (" ADDRX ")\n", |
1697 | 1685 |
ID, nr, ul == 0 ? 'u' : 'l', value, env->nip); |
... | ... | |
2046 | 2034 |
env->error_code = 0; |
2047 | 2035 |
} |
2048 | 2036 |
#else /* defined (CONFIG_USER_ONLY) */ |
2049 |
static always_inline void dump_syscall (CPUState *env)
|
|
2037 |
static inline void dump_syscall(CPUState *env)
|
|
2050 | 2038 |
{ |
2051 | 2039 |
qemu_log_mask(CPU_LOG_INT, "syscall r0=" REGX " r3=" REGX " r4=" REGX |
2052 | 2040 |
" r5=" REGX " r6=" REGX " nip=" ADDRX "\n", |
... | ... | |
2057 | 2045 |
/* Note that this function should be greatly optimized |
2058 | 2046 |
* when called with a constant excp, from ppc_hw_interrupt |
2059 | 2047 |
*/ |
2060 |
static always_inline void powerpc_excp (CPUState *env, |
|
2061 |
int excp_model, int excp) |
|
2048 |
static inline void powerpc_excp(CPUState *env, int excp_model, int excp) |
|
2062 | 2049 |
{ |
2063 | 2050 |
target_ulong msr, new_msr, vector; |
2064 | 2051 |
int srr0, srr1, asrr0, asrr1; |
Also available in: Unified diff