Revision 5eb7995e target-ppc/op_helper.c

b/target-ppc/op_helper.c
2605 2605
    }
2606 2606
#endif
2607 2607
}
2608

  
2609
/* BookE TLB management */
2610
void do_booke_tlbwe0 (void)
2611
{
2612
    ppcemb_tlb_t *tlb;
2613
    target_ulong EPN, size;
2614
    int do_flush_tlbs;
2615

  
2616
#if defined (DEBUG_SOFTWARE_TLB)
2617
    if (loglevel != 0) {
2618
        fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1);
2619
    }
2620
#endif
2621
    do_flush_tlbs = 0;
2622
    T0 &= 0x3F;
2623
    tlb = &env->tlb[T0].tlbe;
2624
    EPN = T1 & 0xFFFFFC00;
2625
    if ((tlb->prot & PAGE_VALID) && EPN != tlb->EPN)
2626
        do_flush_tlbs = 1;
2627
    tlb->EPN = EPN;
2628
    size = booke_tlb_to_page_size((T1 >> 4) & 0xF);
2629
    if ((tlb->prot & PAGE_VALID) && tlb->size < size)
2630
        do_flush_tlbs = 1;
2631
    tlb->size = size;
2632
    tlb->attr &= ~0x1;
2633
    tlb->attr |= (T1 >> 8) & 1;
2634
    if (T1 & 0x200) {
2635
        tlb->prot |= PAGE_VALID;
2636
    } else {
2637
        if (tlb->prot & PAGE_VALID) {
2638
            tlb->prot &= ~PAGE_VALID;
2639
            do_flush_tlbs = 1;
2640
        }
2641
    }
2642
    tlb->PID = env->spr[SPR_BOOKE_PID];
2643
    if (do_flush_tlbs)
2644
        tlb_flush(env, 1);
2645
}
2646

  
2647
void do_booke_tlbwe1 (void)
2648
{
2649
    ppcemb_tlb_t *tlb;
2650
    target_phys_addr_t RPN;
2651

  
2652
#if defined (DEBUG_SOFTWARE_TLB)
2653
    if (loglevel != 0) {
2654
        fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1);
2655
    }
2656
#endif
2657
    T0 &= 0x3F;
2658
    tlb = &env->tlb[T0].tlbe;
2659
    RPN = T1 & 0xFFFFFC0F;
2660
    if ((tlb->prot & PAGE_VALID) && tlb->RPN != RPN)
2661
        tlb_flush(env, 1);
2662
    tlb->RPN = RPN;
2663
}
2664

  
2665
void do_booke_tlbwe2 (void)
2666
{
2667
    ppcemb_tlb_t *tlb;
2668

  
2669
#if defined (DEBUG_SOFTWARE_TLB)
2670
    if (loglevel != 0) {
2671
        fprintf(logfile, "%s T0 " REGX " T1 " REGX "\n", __func__, T0, T1);
2672
    }
2673
#endif
2674
    T0 &= 0x3F;
2675
    tlb = &env->tlb[T0].tlbe;
2676
    tlb->attr = (tlb->attr & 0x1) | (T1 & 0x0000FF00);
2677
    tlb->prot = tlb->prot & PAGE_VALID;
2678
    if (T1 & 0x1)
2679
        tlb->prot |= PAGE_READ << 4;
2680
    if (T1 & 0x2)
2681
        tlb->prot |= PAGE_WRITE << 4;
2682
    if (T1 & 0x4)
2683
        tlb->prot |= PAGE_EXEC << 4;
2684
    if (T1 & 0x8)
2685
        tlb->prot |= PAGE_READ;
2686
    if (T1 & 0x10)
2687
        tlb->prot |= PAGE_WRITE;
2688
    if (T1 & 0x20)
2689
        tlb->prot |= PAGE_EXEC;
2690
}
2691

  
2692
void do_booke_tlbsx (void)
2693
{
2694
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR]);
2695
}
2696

  
2697
void do_booke_tlbsx_ (void)
2698
{
2699
    int tmp = xer_so;
2700

  
2701
    T0 = ppcemb_tlb_search(env, T0, env->spr[SPR_440_MMUCR]);
2702
    if (T0 != -1)
2703
        tmp |= 0x02;
2704
    env->crf[0] = tmp;
2705
}
2706

  
2707
void do_booke_tlbre0 (void)
2708
{
2709
    ppcemb_tlb_t *tlb;
2710
    int size;
2711

  
2712
    T0 &= 0x3F;
2713
    tlb = &env->tlb[T0].tlbe;
2714
    T0 = tlb->EPN;
2715
    size = booke_page_size_to_tlb(tlb->size);
2716
    if (size < 0 || size > 0xF)
2717
        size = 1;
2718
    T0 |= size << 4;
2719
    if (tlb->attr & 0x1)
2720
        T0 |= 0x100;
2721
    if (tlb->prot & PAGE_VALID)
2722
        T0 |= 0x200;
2723
    env->spr[SPR_BOOKE_PID] = tlb->PID;
2724
}
2725

  
2726
void do_booke_tlbre1 (void)
2727
{
2728
    ppcemb_tlb_t *tlb;
2729

  
2730
    T0 &= 0x3F;
2731
    tlb = &env->tlb[T0].tlbe;
2732
    T0 = tlb->RPN;
2733
}
2734

  
2735
void do_booke_tlbre2 (void)
2736
{
2737
    ppcemb_tlb_t *tlb;
2738

  
2739
    T0 &= 0x3F;
2740
    tlb = &env->tlb[T0].tlbe;
2741
    T0 = tlb->attr & ~0x1;
2742
    if (tlb->prot & (PAGE_READ << 4))
2743
        T0 |= 0x1;
2744
    if (tlb->prot & (PAGE_WRITE << 4))
2745
        T0 |= 0x2;
2746
    if (tlb->prot & (PAGE_EXEC << 4))
2747
        T0 |= 0x4;
2748
    if (tlb->prot & PAGE_READ)
2749
        T0 |= 0x8;
2750
    if (tlb->prot & PAGE_WRITE)
2751
        T0 |= 0x10;
2752
    if (tlb->prot & PAGE_EXEC)
2753
        T0 |= 0x20;
2754
}
2608 2755
#endif /* !CONFIG_USER_ONLY */

Also available in: Unified diff