Revision 74d37793 target-ppc/op_helper.c

b/target-ppc/op_helper.c
2552 2552
    env = saved_env;
2553 2553
}
2554 2554

  
2555
/* Segment registers load and store */
2556
target_ulong helper_load_sr (target_ulong sr_num)
2557
{
2558
    return env->sr[sr_num];
2559
}
2560

  
2561
void helper_store_sr (target_ulong sr_num, target_ulong val)
2562
{
2563
    do_store_sr(env, sr_num, val);
2564
}
2565

  
2566
/* SLB management */
2567
#if defined(TARGET_PPC64)
2568
target_ulong helper_load_slb (target_ulong slb_nr)
2569
{
2570
    return ppc_load_slb(env, slb_nr);
2571
}
2572

  
2573
void helper_store_slb (target_ulong slb_nr, target_ulong rs)
2574
{
2575
    ppc_store_slb(env, slb_nr, rs);
2576
}
2577

  
2578
void helper_slbia (void)
2579
{
2580
    ppc_slb_invalidate_all(env);
2581
}
2582

  
2583
void helper_slbie (target_ulong addr)
2584
{
2585
    ppc_slb_invalidate_one(env, addr);
2586
}
2587

  
2588
#endif /* defined(TARGET_PPC64) */
2589

  
2590
/* TLB management */
2591
void helper_tlbia (void)
2592
{
2593
    ppc_tlb_invalidate_all(env);
2594
}
2595

  
2596
void helper_tlbie (target_ulong addr)
2597
{
2598
    ppc_tlb_invalidate_one(env, addr);
2599
}
2600

  
2555 2601
/* Software driven TLBs management */
2556 2602
/* PowerPC 602/603 software TLB load instructions helpers */
2557
static void helper_load_6xx_tlb (target_ulong new_EPN, int is_code)
2603
static void do_6xx_tlb (target_ulong new_EPN, int is_code)
2558 2604
{
2559 2605
    target_ulong RPN, CMP, EPN;
2560 2606
    int way;
......
2580 2626
                     way, is_code, CMP, RPN);
2581 2627
}
2582 2628

  
2583
void helper_load_6xx_tlbd (target_ulong EPN)
2629
void helper_6xx_tlbd (target_ulong EPN)
2584 2630
{
2585
    helper_load_6xx_tlb(EPN, 0);
2631
    do_6xx_tlb(EPN, 0);
2586 2632
}
2587 2633

  
2588
void helper_load_6xx_tlbi (target_ulong EPN)
2634
void helper_6xx_tlbi (target_ulong EPN)
2589 2635
{
2590
    helper_load_6xx_tlb(EPN, 1);
2636
    do_6xx_tlb(EPN, 1);
2591 2637
}
2592 2638

  
2593 2639
/* PowerPC 74xx software TLB load instructions helpers */
2594
static void helper_load_74xx_tlb (target_ulong new_EPN, int is_code)
2640
static void do_74xx_tlb (target_ulong new_EPN, int is_code)
2595 2641
{
2596 2642
    target_ulong RPN, CMP, EPN;
2597 2643
    int way;
......
2612 2658
                     way, is_code, CMP, RPN);
2613 2659
}
2614 2660

  
2615
void helper_load_74xx_tlbd (target_ulong EPN)
2661
void helper_74xx_tlbd (target_ulong EPN)
2616 2662
{
2617
    helper_load_74xx_tlb(EPN, 0);
2663
    do_74xx_tlb(EPN, 0);
2618 2664
}
2619 2665

  
2620
void helper_load_74xx_tlbi (target_ulong EPN)
2666
void helper_74xx_tlbi (target_ulong EPN)
2621 2667
{
2622
    helper_load_74xx_tlb(EPN, 1);
2668
    do_74xx_tlb(EPN, 1);
2623 2669
}
2624 2670

  
2625 2671
static always_inline target_ulong booke_tlb_to_page_size (int size)
......
2691 2737
}
2692 2738

  
2693 2739
/* Helpers for 4xx TLB management */
2694
void do_4xx_tlbre_lo (void)
2740
target_ulong helper_4xx_tlbre_lo (target_ulong entry)
2695 2741
{
2696 2742
    ppcemb_tlb_t *tlb;
2743
    target_ulong ret;
2697 2744
    int size;
2698 2745

  
2699
    T0 &= 0x3F;
2700
    tlb = &env->tlb[T0].tlbe;
2701
    T0 = tlb->EPN;
2746
    entry &= 0x3F;
2747
    tlb = &env->tlb[entry].tlbe;
2748
    ret = tlb->EPN;
2702 2749
    if (tlb->prot & PAGE_VALID)
2703
        T0 |= 0x400;
2750
        ret |= 0x400;
2704 2751
    size = booke_page_size_to_tlb(tlb->size);
2705 2752
    if (size < 0 || size > 0x7)
2706 2753
        size = 1;
2707
    T0 |= size << 7;
2754
    ret |= size << 7;
2708 2755
    env->spr[SPR_40x_PID] = tlb->PID;
2756
    return ret;
2709 2757
}
2710 2758

  
2711
void do_4xx_tlbre_hi (void)
2759
target_ulong helper_4xx_tlbre_hi (target_ulong entry)
2712 2760
{
2713 2761
    ppcemb_tlb_t *tlb;
2762
    target_ulong ret;
2714 2763

  
2715
    T0 &= 0x3F;
2716
    tlb = &env->tlb[T0].tlbe;
2717
    T0 = tlb->RPN;
2764
    entry &= 0x3F;
2765
    tlb = &env->tlb[entry].tlbe;
2766
    ret = tlb->RPN;
2718 2767
    if (tlb->prot & PAGE_EXEC)
2719
        T0 |= 0x200;
2768
        ret |= 0x200;
2720 2769
    if (tlb->prot & PAGE_WRITE)
2721
        T0 |= 0x100;
2770
        ret |= 0x100;
2771
    return ret;
2722 2772
}
2723 2773

  
2724
void do_4xx_tlbwe_hi (void)
2774
void helper_4xx_tlbwe_hi (target_ulong entry, target_ulong val)
2725 2775
{
2726 2776
    ppcemb_tlb_t *tlb;
2727 2777
    target_ulong page, end;
2728 2778

  
2729 2779
#if defined (DEBUG_SOFTWARE_TLB)
2730 2780
    if (loglevel != 0) {
2731
        fprintf(logfile, "%s T0 " TDX " T1 " TDX "\n", __func__, T0, T1);
2781
        fprintf(logfile, "%s entry " TDX " val " TDX "\n", __func__, entry, val);
2732 2782
    }
2733 2783
#endif
2734
    T0 &= 0x3F;
2735
    tlb = &env->tlb[T0].tlbe;
2784
    entry &= 0x3F;
2785
    tlb = &env->tlb[entry].tlbe;
2736 2786
    /* Invalidate previous TLB (if it's valid) */
2737 2787
    if (tlb->prot & PAGE_VALID) {
2738 2788
        end = tlb->EPN + tlb->size;
2739 2789
#if defined (DEBUG_SOFTWARE_TLB)
2740 2790
        if (loglevel != 0) {
2741 2791
            fprintf(logfile, "%s: invalidate old TLB %d start " ADDRX
2742
                    " end " ADDRX "\n", __func__, (int)T0, tlb->EPN, end);
2792
                    " end " ADDRX "\n", __func__, (int)entry, tlb->EPN, end);
2743 2793
        }
2744 2794
#endif
2745 2795
        for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
2746 2796
            tlb_flush_page(env, page);
2747 2797
    }
2748
    tlb->size = booke_tlb_to_page_size((T1 >> 7) & 0x7);
2798
    tlb->size = booke_tlb_to_page_size((val >> 7) & 0x7);
2749 2799
    /* We cannot handle TLB size < TARGET_PAGE_SIZE.
2750 2800
     * If this ever occurs, one should use the ppcemb target instead
2751 2801
     * of the ppc or ppc64 one
2752 2802
     */
2753
    if ((T1 & 0x40) && tlb->size < TARGET_PAGE_SIZE) {
2803
    if ((val & 0x40) && tlb->size < TARGET_PAGE_SIZE) {
2754 2804
        cpu_abort(env, "TLB size " TARGET_FMT_lu " < %u "
2755 2805
                  "are not supported (%d)\n",
2756
                  tlb->size, TARGET_PAGE_SIZE, (int)((T1 >> 7) & 0x7));
2806
                  tlb->size, TARGET_PAGE_SIZE, (int)((val >> 7) & 0x7));
2757 2807
    }
2758
    tlb->EPN = T1 & ~(tlb->size - 1);
2759
    if (T1 & 0x40)
2808
    tlb->EPN = val & ~(tlb->size - 1);
2809
    if (val & 0x40)
2760 2810
        tlb->prot |= PAGE_VALID;
2761 2811
    else
2762 2812
        tlb->prot &= ~PAGE_VALID;
2763
    if (T1 & 0x20) {
2813
    if (val & 0x20) {
2764 2814
        /* XXX: TO BE FIXED */
2765 2815
        cpu_abort(env, "Little-endian TLB entries are not supported by now\n");
2766 2816
    }
2767 2817
    tlb->PID = env->spr[SPR_40x_PID]; /* PID */
2768
    tlb->attr = T1 & 0xFF;
2818
    tlb->attr = val & 0xFF;
2769 2819
#if defined (DEBUG_SOFTWARE_TLB)
2770 2820
    if (loglevel != 0) {
2771 2821
        fprintf(logfile, "%s: set up TLB %d RPN " PADDRX " EPN " ADDRX
......
2791 2841
    }
2792 2842
}
2793 2843

  
2794
void do_4xx_tlbwe_lo (void)
2844
void helper_4xx_tlbwe_lo (target_ulong entry, target_ulong val)
2795 2845
{
2796 2846
    ppcemb_tlb_t *tlb;
2797 2847

  
2798 2848
#if defined (DEBUG_SOFTWARE_TLB)
2799 2849
    if (loglevel != 0) {
2800
        fprintf(logfile, "%s T0 " TDX " T1 " TDX "\n", __func__, T0, T1);
2850
        fprintf(logfile, "%s entry " TDX " val " TDX "\n", __func__, entry, val);
2801 2851
    }
2802 2852
#endif
2803
    T0 &= 0x3F;
2804
    tlb = &env->tlb[T0].tlbe;
2805
    tlb->RPN = T1 & 0xFFFFFC00;
2853
    entry &= 0x3F;
2854
    tlb = &env->tlb[entry].tlbe;
2855
    tlb->RPN = val & 0xFFFFFC00;
2806 2856
    tlb->prot = PAGE_READ;
2807
    if (T1 & 0x200)
2857
    if (val & 0x200)
2808 2858
        tlb->prot |= PAGE_EXEC;
2809
    if (T1 & 0x100)
2859
    if (val & 0x100)
2810 2860
        tlb->prot |= PAGE_WRITE;
2811 2861
#if defined (DEBUG_SOFTWARE_TLB)
2812 2862
    if (loglevel != 0) {
2813 2863
        fprintf(logfile, "%s: set up TLB %d RPN " PADDRX " EPN " ADDRX
2814 2864
                " size " ADDRX " prot %c%c%c%c PID %d\n", __func__,
2815
                (int)T0, tlb->RPN, tlb->EPN, tlb->size,
2865
                (int)entry, tlb->RPN, tlb->EPN, tlb->size,
2816 2866
                tlb->prot & PAGE_READ ? 'r' : '-',
2817 2867
                tlb->prot & PAGE_WRITE ? 'w' : '-',
2818 2868
                tlb->prot & PAGE_EXEC ? 'x' : '-',
......
2821 2871
#endif
2822 2872
}
2823 2873

  
2874
target_ulong helper_4xx_tlbsx (target_ulong address)
2875
{
2876
    return ppcemb_tlb_search(env, address, env->spr[SPR_40x_PID]);
2877
}
2878

  
2824 2879
/* PowerPC 440 TLB management */
2825
void do_440_tlbwe (int word)
2880
void helper_440_tlbwe (uint32_t word, target_ulong entry, target_ulong value)
2826 2881
{
2827 2882
    ppcemb_tlb_t *tlb;
2828 2883
    target_ulong EPN, RPN, size;
......
2830 2885

  
2831 2886
#if defined (DEBUG_SOFTWARE_TLB)
2832 2887
    if (loglevel != 0) {
2833
        fprintf(logfile, "%s word %d T0 " TDX " T1 " TDX "\n",
2834
                __func__, word, T0, T1);
2888
        fprintf(logfile, "%s word %d entry " TDX " value " TDX "\n",
2889
                __func__, word, entry, value);
2835 2890
    }
2836 2891
#endif
2837 2892
    do_flush_tlbs = 0;
2838
    T0 &= 0x3F;
2839
    tlb = &env->tlb[T0].tlbe;
2893
    entry &= 0x3F;
2894
    tlb = &env->tlb[entry].tlbe;
2840 2895
    switch (word) {
2841 2896
    default:
2842 2897
        /* Just here to please gcc */
2843 2898
    case 0:
2844
        EPN = T1 & 0xFFFFFC00;
2899
        EPN = value & 0xFFFFFC00;
2845 2900
        if ((tlb->prot & PAGE_VALID) && EPN != tlb->EPN)
2846 2901
            do_flush_tlbs = 1;
2847 2902
        tlb->EPN = EPN;
2848
        size = booke_tlb_to_page_size((T1 >> 4) & 0xF);
2903
        size = booke_tlb_to_page_size((value >> 4) & 0xF);
2849 2904
        if ((tlb->prot & PAGE_VALID) && tlb->size < size)
2850 2905
            do_flush_tlbs = 1;
2851 2906
        tlb->size = size;
2852 2907
        tlb->attr &= ~0x1;
2853
        tlb->attr |= (T1 >> 8) & 1;
2854
        if (T1 & 0x200) {
2908
        tlb->attr |= (value >> 8) & 1;
2909
        if (value & 0x200) {
2855 2910
            tlb->prot |= PAGE_VALID;
2856 2911
        } else {
2857 2912
            if (tlb->prot & PAGE_VALID) {
......
2864 2919
            tlb_flush(env, 1);
2865 2920
        break;
2866 2921
    case 1:
2867
        RPN = T1 & 0xFFFFFC0F;
2922
        RPN = value & 0xFFFFFC0F;
2868 2923
        if ((tlb->prot & PAGE_VALID) && tlb->RPN != RPN)
2869 2924
            tlb_flush(env, 1);
2870 2925
        tlb->RPN = RPN;
2871 2926
        break;
2872 2927
    case 2:
2873
        tlb->attr = (tlb->attr & 0x1) | (T1 & 0x0000FF00);
2928
        tlb->attr = (tlb->attr & 0x1) | (value & 0x0000FF00);
2874 2929
        tlb->prot = tlb->prot & PAGE_VALID;
2875
        if (T1 & 0x1)
2930
        if (value & 0x1)
2876 2931
            tlb->prot |= PAGE_READ << 4;
2877
        if (T1 & 0x2)
2932
        if (value & 0x2)
2878 2933
            tlb->prot |= PAGE_WRITE << 4;
2879
        if (T1 & 0x4)
2934
        if (value & 0x4)
2880 2935
            tlb->prot |= PAGE_EXEC << 4;
2881
        if (T1 & 0x8)
2936
        if (value & 0x8)
2882 2937
            tlb->prot |= PAGE_READ;
2883
        if (T1 & 0x10)
2938
        if (value & 0x10)
2884 2939
            tlb->prot |= PAGE_WRITE;
2885
        if (T1 & 0x20)
2940
        if (value & 0x20)
2886 2941
            tlb->prot |= PAGE_EXEC;
2887 2942
        break;
2888 2943
    }
2889 2944
}
2890 2945

  
2891
void do_440_tlbre (int word)
2946
target_ulong helper_440_tlbre (uint32_t word, target_ulong entry)
2892 2947
{
2893 2948
    ppcemb_tlb_t *tlb;
2949
    target_ulong ret;
2894 2950
    int size;
2895 2951

  
2896
    T0 &= 0x3F;
2897
    tlb = &env->tlb[T0].tlbe;
2952
    entry &= 0x3F;
2953
    tlb = &env->tlb[entry].tlbe;
2898 2954
    switch (word) {
2899 2955
    default:
2900 2956
        /* Just here to please gcc */
2901 2957
    case 0:
2902
        T0 = tlb->EPN;
2958
        ret = tlb->EPN;
2903 2959
        size = booke_page_size_to_tlb(tlb->size);
2904 2960
        if (size < 0 || size > 0xF)
2905 2961
            size = 1;
2906
        T0 |= size << 4;
2962
        ret |= size << 4;
2907 2963
        if (tlb->attr & 0x1)
2908
            T0 |= 0x100;
2964
            ret |= 0x100;
2909 2965
        if (tlb->prot & PAGE_VALID)
2910
            T0 |= 0x200;
2966
            ret |= 0x200;
2911 2967
        env->spr[SPR_440_MMUCR] &= ~0x000000FF;
2912 2968
        env->spr[SPR_440_MMUCR] |= tlb->PID;
2913 2969
        break;
2914 2970
    case 1:
2915
        T0 = tlb->RPN;
2971
        ret = tlb->RPN;
2916 2972
        break;
2917 2973
    case 2:
2918
        T0 = tlb->attr & ~0x1;
2974
        ret = tlb->attr & ~0x1;
2919 2975
        if (tlb->prot & (PAGE_READ << 4))
2920
            T0 |= 0x1;
2976
            ret |= 0x1;
2921 2977
        if (tlb->prot & (PAGE_WRITE << 4))
2922
            T0 |= 0x2;
2978
            ret |= 0x2;
2923 2979
        if (tlb->prot & (PAGE_EXEC << 4))
2924
            T0 |= 0x4;
2980
            ret |= 0x4;
2925 2981
        if (tlb->prot & PAGE_READ)
2926
            T0 |= 0x8;
2982
            ret |= 0x8;
2927 2983
        if (tlb->prot & PAGE_WRITE)
2928
            T0 |= 0x10;
2984
            ret |= 0x10;
2929 2985
        if (tlb->prot & PAGE_EXEC)
2930
            T0 |= 0x20;
2986
            ret |= 0x20;
2931 2987
        break;
2932 2988
    }
2989
    return ret;
2933 2990
}
2991

  
2992
target_ulong helper_440_tlbsx (target_ulong address)
2993
{
2994
    return ppcemb_tlb_search(env, address, env->spr[SPR_440_MMUCR] & 0xFF);
2995
}
2996

  
2934 2997
#endif /* !CONFIG_USER_ONLY */

Also available in: Unified diff