Revision daf4f96e
b/target-ppc/cpu.h | ||
---|---|---|
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 |
b/target-ppc/exec.h | ||
---|---|---|
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 |
{ |
b/target-ppc/helper.c | ||
---|---|---|
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 | 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 | 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 | 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 | 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 | 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 | 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 | 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) |
b/target-ppc/op.c | ||
---|---|---|
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 | 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 | 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 | 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 |
|
b/target-ppc/op_helper.c | ||
---|---|---|
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 | 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 | 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 | 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; |
b/target-ppc/translate.c | ||
---|---|---|
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 | 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 |
} |
Also available in: Unified diff