Revision daf4f96e target-ppc/op_helper.c
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; |
Also available in: Unified diff