Commit daf4f96ece7dc4abdfe29c9a7fdd694ffd8969bb
1 parent
035feb88
Avoid op helpers that would just call helpers for TLB & SLB management:
call the helpers directly from the micro-ops. Avoid duplicated code for tlbsx. implementation. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3302 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
6 changed files
with
119 additions
and
198 deletions
target-ppc/cpu.h
| ... | ... | @@ -656,6 +656,11 @@ void store_40x_sler (CPUPPCState *env, uint32_t val); |
| 656 | 656 | void store_booke_tcr (CPUPPCState *env, target_ulong val); |
| 657 | 657 | void store_booke_tsr (CPUPPCState *env, target_ulong val); |
| 658 | 658 | void ppc_tlb_invalidate_all (CPUPPCState *env); |
| 659 | +void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr); | |
| 660 | +#if defined(TARGET_PPC64) | |
| 661 | +void ppc_slb_invalidate_all (CPUPPCState *env); | |
| 662 | +void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0); | |
| 663 | +#endif | |
| 659 | 664 | int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid); |
| 660 | 665 | #endif |
| 661 | 666 | #endif | ... | ... |
target-ppc/exec.h
| ... | ... | @@ -100,14 +100,8 @@ void do_raise_exception (uint32_t exception); |
| 100 | 100 | int get_physical_address (CPUState *env, mmu_ctx_t *ctx, target_ulong vaddr, |
| 101 | 101 | int rw, int access_type, int check_BATs); |
| 102 | 102 | |
| 103 | -void ppc6xx_tlb_invalidate_all (CPUState *env); | |
| 104 | -void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr, | |
| 105 | - int is_code); | |
| 106 | 103 | void ppc6xx_tlb_store (CPUState *env, target_ulong EPN, int way, int is_code, |
| 107 | 104 | target_ulong pte0, target_ulong pte1); |
| 108 | -void ppc4xx_tlb_invalidate_all (CPUState *env); | |
| 109 | -void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr, | |
| 110 | - uint32_t pid); | |
| 111 | 105 | |
| 112 | 106 | static inline void env_to_regs (void) |
| 113 | 107 | { | ... | ... |
target-ppc/helper.c
| ... | ... | @@ -237,7 +237,7 @@ static int ppc6xx_tlb_getnum (CPUState *env, target_ulong eaddr, |
| 237 | 237 | return nr; |
| 238 | 238 | } |
| 239 | 239 | |
| 240 | -void ppc6xx_tlb_invalidate_all (CPUState *env) | |
| 240 | +static void ppc6xx_tlb_invalidate_all (CPUState *env) | |
| 241 | 241 | { |
| 242 | 242 | ppc6xx_tlb_t *tlb; |
| 243 | 243 | int nr, max; |
| ... | ... | @@ -253,14 +253,9 @@ void ppc6xx_tlb_invalidate_all (CPUState *env) |
| 253 | 253 | max *= 2; |
| 254 | 254 | for (nr = 0; nr < max; nr++) { |
| 255 | 255 | tlb = &env->tlb[nr].tlb6; |
| 256 | -#if !defined(FLUSH_ALL_TLBS) | |
| 257 | - tlb_flush_page(env, tlb->EPN); | |
| 258 | -#endif | |
| 259 | 256 | pte_invalidate(&tlb->pte0); |
| 260 | 257 | } |
| 261 | -#if defined(FLUSH_ALL_TLBS) | |
| 262 | 258 | tlb_flush(env, 1); |
| 263 | -#endif | |
| 264 | 259 | } |
| 265 | 260 | |
| 266 | 261 | static inline void __ppc6xx_tlb_invalidate_virt (CPUState *env, |
| ... | ... | @@ -292,8 +287,8 @@ static inline void __ppc6xx_tlb_invalidate_virt (CPUState *env, |
| 292 | 287 | #endif |
| 293 | 288 | } |
| 294 | 289 | |
| 295 | -void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr, | |
| 296 | - int is_code) | |
| 290 | +static void ppc6xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr, | |
| 291 | + int is_code) | |
| 297 | 292 | { |
| 298 | 293 | __ppc6xx_tlb_invalidate_virt(env, eaddr, is_code, 0); |
| 299 | 294 | } |
| ... | ... | @@ -834,11 +829,13 @@ static int ppcemb_tlb_check (CPUState *env, ppcemb_tlb_t *tlb, |
| 834 | 829 | return -1; |
| 835 | 830 | } |
| 836 | 831 | mask = ~(tlb->size - 1); |
| 832 | +#if defined (DEBUG_SOFTWARE_TLB) | |
| 837 | 833 | if (loglevel != 0) { |
| 838 | 834 | fprintf(logfile, "%s: TLB %d address " ADDRX " PID %d <=> " |
| 839 | 835 | ADDRX " " ADDRX " %d\n", |
| 840 | 836 | __func__, i, address, pid, tlb->EPN, mask, (int)tlb->PID); |
| 841 | 837 | } |
| 838 | +#endif | |
| 842 | 839 | /* Check PID */ |
| 843 | 840 | if (tlb->PID != 0 && tlb->PID != pid) |
| 844 | 841 | return -1; |
| ... | ... | @@ -876,44 +873,41 @@ int ppcemb_tlb_search (CPUPPCState *env, target_ulong address, uint32_t pid) |
| 876 | 873 | return ret; |
| 877 | 874 | } |
| 878 | 875 | |
| 879 | -void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr, | |
| 880 | - uint32_t pid) | |
| 876 | +/* Helpers specific to PowerPC 40x implementations */ | |
| 877 | +static void ppc4xx_tlb_invalidate_all (CPUState *env) | |
| 881 | 878 | { |
| 882 | 879 | ppcemb_tlb_t *tlb; |
| 883 | - target_phys_addr_t raddr; | |
| 884 | - target_ulong page, end; | |
| 885 | 880 | int i; |
| 886 | 881 | |
| 887 | 882 | for (i = 0; i < env->nb_tlb; i++) { |
| 888 | 883 | tlb = &env->tlb[i].tlbe; |
| 889 | - if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) { | |
| 890 | - end = tlb->EPN + tlb->size; | |
| 891 | - for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) | |
| 892 | - tlb_flush_page(env, page); | |
| 893 | - tlb->prot &= ~PAGE_VALID; | |
| 894 | - break; | |
| 895 | - } | |
| 884 | + tlb->prot &= ~PAGE_VALID; | |
| 896 | 885 | } |
| 886 | + tlb_flush(env, 1); | |
| 897 | 887 | } |
| 898 | 888 | |
| 899 | -/* Helpers specific to PowerPC 40x implementations */ | |
| 900 | -void ppc4xx_tlb_invalidate_all (CPUState *env) | |
| 889 | +static void ppc4xx_tlb_invalidate_virt (CPUState *env, target_ulong eaddr, | |
| 890 | + uint32_t pid) | |
| 901 | 891 | { |
| 892 | +#if !defined(FLUSH_ALL_TLBS) | |
| 902 | 893 | ppcemb_tlb_t *tlb; |
| 894 | + target_phys_addr_t raddr; | |
| 895 | + target_ulong page, end; | |
| 903 | 896 | int i; |
| 904 | 897 | |
| 905 | 898 | for (i = 0; i < env->nb_tlb; i++) { |
| 906 | 899 | tlb = &env->tlb[i].tlbe; |
| 907 | - if (tlb->prot & PAGE_VALID) { | |
| 908 | -#if 0 // XXX: TLB have variable sizes then we flush all Qemu TLB. | |
| 900 | + if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) { | |
| 909 | 901 | end = tlb->EPN + tlb->size; |
| 910 | 902 | for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) |
| 911 | 903 | tlb_flush_page(env, page); |
| 912 | -#endif | |
| 913 | 904 | tlb->prot &= ~PAGE_VALID; |
| 905 | + break; | |
| 914 | 906 | } |
| 915 | 907 | } |
| 916 | - tlb_flush(env, 1); | |
| 908 | +#else | |
| 909 | + ppc4xx_tlb_invalidate_all(env); | |
| 910 | +#endif | |
| 917 | 911 | } |
| 918 | 912 | |
| 919 | 913 | int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx, |
| ... | ... | @@ -932,10 +926,12 @@ int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx, |
| 932 | 926 | continue; |
| 933 | 927 | zsel = (tlb->attr >> 4) & 0xF; |
| 934 | 928 | zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3; |
| 929 | +#if defined (DEBUG_SOFTWARE_TLB) | |
| 935 | 930 | if (loglevel != 0) { |
| 936 | 931 | fprintf(logfile, "%s: TLB %d zsel %d zpr %d rw %d attr %08x\n", |
| 937 | 932 | __func__, i, zsel, zpr, rw, tlb->attr); |
| 938 | 933 | } |
| 934 | +#endif | |
| 939 | 935 | if (access_type == ACCESS_CODE) { |
| 940 | 936 | /* Check execute enable bit */ |
| 941 | 937 | switch (zpr) { |
| ... | ... | @@ -1009,19 +1005,23 @@ int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx, |
| 1009 | 1005 | } |
| 1010 | 1006 | if (ret >= 0) { |
| 1011 | 1007 | ctx->raddr = raddr; |
| 1008 | +#if defined (DEBUG_SOFTWARE_TLB) | |
| 1012 | 1009 | if (loglevel != 0) { |
| 1013 | 1010 | fprintf(logfile, "%s: access granted " ADDRX " => " REGX |
| 1014 | 1011 | " %d %d\n", __func__, address, ctx->raddr, ctx->prot, |
| 1015 | 1012 | ret); |
| 1016 | 1013 | } |
| 1014 | +#endif | |
| 1017 | 1015 | return 0; |
| 1018 | 1016 | } |
| 1019 | 1017 | } |
| 1018 | +#if defined (DEBUG_SOFTWARE_TLB) | |
| 1020 | 1019 | if (loglevel != 0) { |
| 1021 | 1020 | fprintf(logfile, "%s: access refused " ADDRX " => " REGX |
| 1022 | 1021 | " %d %d\n", __func__, address, raddr, ctx->prot, |
| 1023 | 1022 | ret); |
| 1024 | 1023 | } |
| 1024 | +#endif | |
| 1025 | 1025 | |
| 1026 | 1026 | return ret; |
| 1027 | 1027 | } |
| ... | ... | @@ -1569,15 +1569,77 @@ void do_store_dbatl (CPUPPCState *env, int nr, target_ulong value) |
| 1569 | 1569 | /* TLB management */ |
| 1570 | 1570 | void ppc_tlb_invalidate_all (CPUPPCState *env) |
| 1571 | 1571 | { |
| 1572 | - if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) { | |
| 1572 | + switch (env->mmu_model) { | |
| 1573 | + case POWERPC_MMU_SOFT_6xx: | |
| 1573 | 1574 | ppc6xx_tlb_invalidate_all(env); |
| 1574 | - } else if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_4xx)) { | |
| 1575 | + break; | |
| 1576 | + case POWERPC_MMU_SOFT_4xx: | |
| 1577 | + case POWERPC_MMU_SOFT_4xx_Z: | |
| 1575 | 1578 | ppc4xx_tlb_invalidate_all(env); |
| 1576 | - } else { | |
| 1579 | + break; | |
| 1580 | + default: | |
| 1577 | 1581 | tlb_flush(env, 1); |
| 1582 | + break; | |
| 1583 | + } | |
| 1584 | +} | |
| 1585 | + | |
| 1586 | +void ppc_tlb_invalidate_one (CPUPPCState *env, target_ulong addr) | |
| 1587 | +{ | |
| 1588 | +#if !defined(FLUSH_ALL_TLBS) | |
| 1589 | + addr &= TARGET_PAGE_MASK; | |
| 1590 | + switch (env->mmu_model) { | |
| 1591 | + case POWERPC_MMU_SOFT_6xx: | |
| 1592 | + ppc6xx_tlb_invalidate_virt(env, addr, 0); | |
| 1593 | + if (env->id_tlbs == 1) | |
| 1594 | + ppc6xx_tlb_invalidate_virt(env, addr, 1); | |
| 1595 | + break; | |
| 1596 | + case POWERPC_MMU_SOFT_4xx: | |
| 1597 | + case POWERPC_MMU_SOFT_4xx_Z: | |
| 1598 | + ppc4xx_tlb_invalidate_virt(env, addr, env->spr[SPR_40x_PID]); | |
| 1599 | + break; | |
| 1600 | + default: | |
| 1601 | + /* tlbie invalidate TLBs for all segments */ | |
| 1602 | + addr &= ~((target_ulong)-1 << 28); | |
| 1603 | + /* XXX: this case should be optimized, | |
| 1604 | + * giving a mask to tlb_flush_page | |
| 1605 | + */ | |
| 1606 | + tlb_flush_page(env, addr | (0x0 << 28)); | |
| 1607 | + tlb_flush_page(env, addr | (0x1 << 28)); | |
| 1608 | + tlb_flush_page(env, addr | (0x2 << 28)); | |
| 1609 | + tlb_flush_page(env, addr | (0x3 << 28)); | |
| 1610 | + tlb_flush_page(env, addr | (0x4 << 28)); | |
| 1611 | + tlb_flush_page(env, addr | (0x5 << 28)); | |
| 1612 | + tlb_flush_page(env, addr | (0x6 << 28)); | |
| 1613 | + tlb_flush_page(env, addr | (0x7 << 28)); | |
| 1614 | + tlb_flush_page(env, addr | (0x8 << 28)); | |
| 1615 | + tlb_flush_page(env, addr | (0x9 << 28)); | |
| 1616 | + tlb_flush_page(env, addr | (0xA << 28)); | |
| 1617 | + tlb_flush_page(env, addr | (0xB << 28)); | |
| 1618 | + tlb_flush_page(env, addr | (0xC << 28)); | |
| 1619 | + tlb_flush_page(env, addr | (0xD << 28)); | |
| 1620 | + tlb_flush_page(env, addr | (0xE << 28)); | |
| 1621 | + tlb_flush_page(env, addr | (0xF << 28)); | |
| 1578 | 1622 | } |
| 1623 | +#else | |
| 1624 | + ppc_tlb_invalidate_all(env); | |
| 1625 | +#endif | |
| 1579 | 1626 | } |
| 1580 | 1627 | |
| 1628 | +#if defined(TARGET_PPC64) | |
| 1629 | +void ppc_slb_invalidate_all (CPUPPCState *env) | |
| 1630 | +{ | |
| 1631 | + /* XXX: TODO */ | |
| 1632 | + tlb_flush(env, 1); | |
| 1633 | +} | |
| 1634 | + | |
| 1635 | +void ppc_slb_invalidate_one (CPUPPCState *env, uint64_t T0) | |
| 1636 | +{ | |
| 1637 | + /* XXX: TODO */ | |
| 1638 | + tlb_flush(env, 1); | |
| 1639 | +} | |
| 1640 | +#endif | |
| 1641 | + | |
| 1642 | + | |
| 1581 | 1643 | /*****************************************************************************/ |
| 1582 | 1644 | /* Special registers manipulation */ |
| 1583 | 1645 | #if defined(TARGET_PPC64) | ... | ... |
target-ppc/op.c
| ... | ... | @@ -1985,21 +1985,21 @@ void OPPROTO op_td (void) |
| 1985 | 1985 | /* tlbia */ |
| 1986 | 1986 | void OPPROTO op_tlbia (void) |
| 1987 | 1987 | { |
| 1988 | - do_tlbia(); | |
| 1988 | + ppc_tlb_invalidate_all(env); | |
| 1989 | 1989 | RETURN(); |
| 1990 | 1990 | } |
| 1991 | 1991 | |
| 1992 | 1992 | /* tlbie */ |
| 1993 | 1993 | void OPPROTO op_tlbie (void) |
| 1994 | 1994 | { |
| 1995 | - do_tlbie(); | |
| 1995 | + ppc_tlb_invalidate_one(env, (uint32_t)T0); | |
| 1996 | 1996 | RETURN(); |
| 1997 | 1997 | } |
| 1998 | 1998 | |
| 1999 | 1999 | #if defined(TARGET_PPC64) |
| 2000 | 2000 | void OPPROTO op_tlbie_64 (void) |
| 2001 | 2001 | { |
| 2002 | - do_tlbie_64(); | |
| 2002 | + ppc_tlb_invalidate_one(env, T0); | |
| 2003 | 2003 | RETURN(); |
| 2004 | 2004 | } |
| 2005 | 2005 | #endif |
| ... | ... | @@ -2007,13 +2007,19 @@ void OPPROTO op_tlbie_64 (void) |
| 2007 | 2007 | #if defined(TARGET_PPC64) |
| 2008 | 2008 | void OPPROTO op_slbia (void) |
| 2009 | 2009 | { |
| 2010 | - do_slbia(); | |
| 2010 | + ppc_slb_invalidate_all(env); | |
| 2011 | 2011 | RETURN(); |
| 2012 | 2012 | } |
| 2013 | 2013 | |
| 2014 | 2014 | void OPPROTO op_slbie (void) |
| 2015 | 2015 | { |
| 2016 | - do_slbie(); | |
| 2016 | + ppc_slb_invalidate_one(env, (uint32_t)T0); | |
| 2017 | + RETURN(); | |
| 2018 | +} | |
| 2019 | + | |
| 2020 | +void OPPROTO op_slbie_64 (void) | |
| 2021 | +{ | |
| 2022 | + ppc_slb_invalidate_one(env, T0); | |
| 2017 | 2023 | RETURN(); |
| 2018 | 2024 | } |
| 2019 | 2025 | #endif |
| ... | ... | @@ -2487,13 +2493,18 @@ void OPPROTO op_440_tlbre (void) |
| 2487 | 2493 | |
| 2488 | 2494 | void OPPROTO op_440_tlbsx (void) |
| 2489 | 2495 | { |
| 2490 | - do_440_tlbsx(); | |
| 2496 | + T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF); | |
| 2491 | 2497 | RETURN(); |
| 2492 | 2498 | } |
| 2493 | 2499 | |
| 2494 | -void OPPROTO op_440_tlbsx_ (void) | |
| 2500 | +void OPPROTO op_4xx_tlbsx_check (void) | |
| 2495 | 2501 | { |
| 2496 | - do_440_tlbsx_(); | |
| 2502 | + int tmp; | |
| 2503 | + | |
| 2504 | + tmp = xer_so; | |
| 2505 | + if (T0 != -1) | |
| 2506 | + tmp |= 0x02; | |
| 2507 | + env->crf[0] = tmp; | |
| 2497 | 2508 | RETURN(); |
| 2498 | 2509 | } |
| 2499 | 2510 | |
| ... | ... | @@ -2517,13 +2528,7 @@ void OPPROTO op_4xx_tlbre_hi (void) |
| 2517 | 2528 | |
| 2518 | 2529 | void OPPROTO op_4xx_tlbsx (void) |
| 2519 | 2530 | { |
| 2520 | - do_4xx_tlbsx(); | |
| 2521 | - RETURN(); | |
| 2522 | -} | |
| 2523 | - | |
| 2524 | -void OPPROTO op_4xx_tlbsx_ (void) | |
| 2525 | -{ | |
| 2526 | - do_4xx_tlbsx_(); | |
| 2531 | + T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]); | |
| 2527 | 2532 | RETURN(); |
| 2528 | 2533 | } |
| 2529 | 2534 | ... | ... |
target-ppc/op_helper.c
| ... | ... | @@ -36,7 +36,6 @@ |
| 36 | 36 | //#define DEBUG_OP |
| 37 | 37 | //#define DEBUG_EXCEPTIONS |
| 38 | 38 | //#define DEBUG_SOFTWARE_TLB |
| 39 | -//#define FLUSH_ALL_TLBS | |
| 40 | 39 | |
| 41 | 40 | /*****************************************************************************/ |
| 42 | 41 | /* Exceptions processing helpers */ |
| ... | ... | @@ -2336,118 +2335,6 @@ void tlb_fill (target_ulong addr, int is_write, int is_user, void *retaddr) |
| 2336 | 2335 | env = saved_env; |
| 2337 | 2336 | } |
| 2338 | 2337 | |
| 2339 | -/* TLB invalidation helpers */ | |
| 2340 | -void do_tlbia (void) | |
| 2341 | -{ | |
| 2342 | - ppc_tlb_invalidate_all(env); | |
| 2343 | -} | |
| 2344 | - | |
| 2345 | -void do_tlbie (void) | |
| 2346 | -{ | |
| 2347 | - T0 = (uint32_t)T0; | |
| 2348 | -#if !defined(FLUSH_ALL_TLBS) | |
| 2349 | - /* XXX: Remove thoses tests */ | |
| 2350 | - if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) { | |
| 2351 | - ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 0); | |
| 2352 | - if (env->id_tlbs == 1) | |
| 2353 | - ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 1); | |
| 2354 | - } else if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_4xx)) { | |
| 2355 | - ppc4xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, | |
| 2356 | - env->spr[SPR_40x_PID]); | |
| 2357 | - } else { | |
| 2358 | - /* tlbie invalidate TLBs for all segments */ | |
| 2359 | - T0 &= TARGET_PAGE_MASK; | |
| 2360 | - T0 &= ~((target_ulong)-1 << 28); | |
| 2361 | - /* XXX: this case should be optimized, | |
| 2362 | - * giving a mask to tlb_flush_page | |
| 2363 | - */ | |
| 2364 | - tlb_flush_page(env, T0 | (0x0 << 28)); | |
| 2365 | - tlb_flush_page(env, T0 | (0x1 << 28)); | |
| 2366 | - tlb_flush_page(env, T0 | (0x2 << 28)); | |
| 2367 | - tlb_flush_page(env, T0 | (0x3 << 28)); | |
| 2368 | - tlb_flush_page(env, T0 | (0x4 << 28)); | |
| 2369 | - tlb_flush_page(env, T0 | (0x5 << 28)); | |
| 2370 | - tlb_flush_page(env, T0 | (0x6 << 28)); | |
| 2371 | - tlb_flush_page(env, T0 | (0x7 << 28)); | |
| 2372 | - tlb_flush_page(env, T0 | (0x8 << 28)); | |
| 2373 | - tlb_flush_page(env, T0 | (0x9 << 28)); | |
| 2374 | - tlb_flush_page(env, T0 | (0xA << 28)); | |
| 2375 | - tlb_flush_page(env, T0 | (0xB << 28)); | |
| 2376 | - tlb_flush_page(env, T0 | (0xC << 28)); | |
| 2377 | - tlb_flush_page(env, T0 | (0xD << 28)); | |
| 2378 | - tlb_flush_page(env, T0 | (0xE << 28)); | |
| 2379 | - tlb_flush_page(env, T0 | (0xF << 28)); | |
| 2380 | - } | |
| 2381 | -#else | |
| 2382 | - do_tlbia(); | |
| 2383 | -#endif | |
| 2384 | -} | |
| 2385 | - | |
| 2386 | -#if defined(TARGET_PPC64) | |
| 2387 | -void do_tlbie_64 (void) | |
| 2388 | -{ | |
| 2389 | - T0 = (uint64_t)T0; | |
| 2390 | -#if !defined(FLUSH_ALL_TLBS) | |
| 2391 | - if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx)) { | |
| 2392 | - ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 0); | |
| 2393 | - if (env->id_tlbs == 1) | |
| 2394 | - ppc6xx_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, 1); | |
| 2395 | - } else if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_4xx)) { | |
| 2396 | - /* XXX: TODO */ | |
| 2397 | -#if 0 | |
| 2398 | - ppcbooke_tlb_invalidate_virt(env, T0 & TARGET_PAGE_MASK, | |
| 2399 | - env->spr[SPR_BOOKE_PID]); | |
| 2400 | -#endif | |
| 2401 | - } else { | |
| 2402 | - /* tlbie invalidate TLBs for all segments | |
| 2403 | - * As we have 2^36 segments, invalidate all qemu TLBs | |
| 2404 | - */ | |
| 2405 | -#if 0 | |
| 2406 | - T0 &= TARGET_PAGE_MASK; | |
| 2407 | - T0 &= ~((target_ulong)-1 << 28); | |
| 2408 | - /* XXX: this case should be optimized, | |
| 2409 | - * giving a mask to tlb_flush_page | |
| 2410 | - */ | |
| 2411 | - tlb_flush_page(env, T0 | (0x0 << 28)); | |
| 2412 | - tlb_flush_page(env, T0 | (0x1 << 28)); | |
| 2413 | - tlb_flush_page(env, T0 | (0x2 << 28)); | |
| 2414 | - tlb_flush_page(env, T0 | (0x3 << 28)); | |
| 2415 | - tlb_flush_page(env, T0 | (0x4 << 28)); | |
| 2416 | - tlb_flush_page(env, T0 | (0x5 << 28)); | |
| 2417 | - tlb_flush_page(env, T0 | (0x6 << 28)); | |
| 2418 | - tlb_flush_page(env, T0 | (0x7 << 28)); | |
| 2419 | - tlb_flush_page(env, T0 | (0x8 << 28)); | |
| 2420 | - tlb_flush_page(env, T0 | (0x9 << 28)); | |
| 2421 | - tlb_flush_page(env, T0 | (0xA << 28)); | |
| 2422 | - tlb_flush_page(env, T0 | (0xB << 28)); | |
| 2423 | - tlb_flush_page(env, T0 | (0xC << 28)); | |
| 2424 | - tlb_flush_page(env, T0 | (0xD << 28)); | |
| 2425 | - tlb_flush_page(env, T0 | (0xE << 28)); | |
| 2426 | - tlb_flush_page(env, T0 | (0xF << 28)); | |
| 2427 | -#else | |
| 2428 | - tlb_flush(env, 1); | |
| 2429 | -#endif | |
| 2430 | - } | |
| 2431 | -#else | |
| 2432 | - do_tlbia(); | |
| 2433 | -#endif | |
| 2434 | -} | |
| 2435 | -#endif | |
| 2436 | - | |
| 2437 | -#if defined(TARGET_PPC64) | |
| 2438 | -void do_slbia (void) | |
| 2439 | -{ | |
| 2440 | - /* XXX: TODO */ | |
| 2441 | - tlb_flush(env, 1); | |
| 2442 | -} | |
| 2443 | - | |
| 2444 | -void do_slbie (void) | |
| 2445 | -{ | |
| 2446 | - /* XXX: TODO */ | |
| 2447 | - tlb_flush(env, 1); | |
| 2448 | -} | |
| 2449 | -#endif | |
| 2450 | - | |
| 2451 | 2338 | /* Software driven TLBs management */ |
| 2452 | 2339 | /* PowerPC 602/603 software TLB load instructions helpers */ |
| 2453 | 2340 | void do_load_6xx_tlb (int is_code) |
| ... | ... | @@ -2575,21 +2462,6 @@ void do_4xx_tlbre_hi (void) |
| 2575 | 2462 | T0 |= 0x100; |
| 2576 | 2463 | } |
| 2577 | 2464 | |
| 2578 | -void do_4xx_tlbsx (void) | |
| 2579 | -{ | |
| 2580 | - T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]); | |
| 2581 | -} | |
| 2582 | - | |
| 2583 | -void do_4xx_tlbsx_ (void) | |
| 2584 | -{ | |
| 2585 | - int tmp = xer_so; | |
| 2586 | - | |
| 2587 | - T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_40x_PID]); | |
| 2588 | - if (T0 != -1) | |
| 2589 | - tmp |= 0x02; | |
| 2590 | - env->crf[0] = tmp; | |
| 2591 | -} | |
| 2592 | - | |
| 2593 | 2465 | void do_4xx_tlbwe_hi (void) |
| 2594 | 2466 | { |
| 2595 | 2467 | ppcemb_tlb_t *tlb; |
| ... | ... | @@ -2757,21 +2629,6 @@ void do_440_tlbwe (int word) |
| 2757 | 2629 | } |
| 2758 | 2630 | } |
| 2759 | 2631 | |
| 2760 | -void do_440_tlbsx (void) | |
| 2761 | -{ | |
| 2762 | - T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF); | |
| 2763 | -} | |
| 2764 | - | |
| 2765 | -void do_440_tlbsx_ (void) | |
| 2766 | -{ | |
| 2767 | - int tmp = xer_so; | |
| 2768 | - | |
| 2769 | - T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR] & 0xFF); | |
| 2770 | - if (T0 != -1) | |
| 2771 | - tmp |= 0x02; | |
| 2772 | - env->crf[0] = tmp; | |
| 2773 | -} | |
| 2774 | - | |
| 2775 | 2632 | void do_440_tlbre (int word) |
| 2776 | 2633 | { |
| 2777 | 2634 | ppcemb_tlb_t *tlb; | ... | ... |
target-ppc/translate.c
| ... | ... | @@ -4991,10 +4991,9 @@ GEN_HANDLER(tlbsx_40x, 0x1F, 0x12, 0x1C, 0x00000000, PPC_40x_TLB) |
| 4991 | 4991 | return; |
| 4992 | 4992 | } |
| 4993 | 4993 | gen_addr_reg_index(ctx); |
| 4994 | + gen_op_4xx_tlbsx(); | |
| 4994 | 4995 | if (Rc(ctx->opcode)) |
| 4995 | - gen_op_4xx_tlbsx_(); | |
| 4996 | - else | |
| 4997 | - gen_op_4xx_tlbsx(); | |
| 4996 | + gen_op_4xx_tlbsx_check(); | |
| 4998 | 4997 | gen_op_store_T0_gpr(rD(ctx->opcode)); |
| 4999 | 4998 | #endif |
| 5000 | 4999 | } |
| ... | ... | @@ -5064,10 +5063,9 @@ GEN_HANDLER(tlbsx_440, 0x1F, 0x12, 0x1C, 0x00000000, PPC_BOOKE) |
| 5064 | 5063 | return; |
| 5065 | 5064 | } |
| 5066 | 5065 | gen_addr_reg_index(ctx); |
| 5066 | + gen_op_440_tlbsx(); | |
| 5067 | 5067 | if (Rc(ctx->opcode)) |
| 5068 | - gen_op_440_tlbsx_(); | |
| 5069 | - else | |
| 5070 | - gen_op_440_tlbsx(); | |
| 5068 | + gen_op_4xx_tlbsx_check(); | |
| 5071 | 5069 | gen_op_store_T0_gpr(rD(ctx->opcode)); |
| 5072 | 5070 | #endif |
| 5073 | 5071 | } | ... | ... |