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