Revision 999fa40e target-ppc/op_helper.c

b/target-ppc/op_helper.c
3929 3929
}
3930 3930

  
3931 3931
/* Helpers for 4xx TLB management */
3932
target_ulong helper_4xx_tlbre_lo (target_ulong entry)
3932
#define PPC4XX_TLB_ENTRY_MASK       0x0000003f  /* Mask for 64 TLB entries */
3933

  
3934
#define PPC4XX_TLBHI_V              0x00000040
3935
#define PPC4XX_TLBHI_E              0x00000020
3936
#define PPC4XX_TLBHI_SIZE_MIN       0
3937
#define PPC4XX_TLBHI_SIZE_MAX       7
3938
#define PPC4XX_TLBHI_SIZE_DEFAULT   1
3939
#define PPC4XX_TLBHI_SIZE_SHIFT     7
3940
#define PPC4XX_TLBHI_SIZE_MASK      0x00000007
3941

  
3942
#define PPC4XX_TLBLO_EX             0x00000200
3943
#define PPC4XX_TLBLO_WR             0x00000100
3944
#define PPC4XX_TLBLO_ATTR_MASK      0x000000FF
3945
#define PPC4XX_TLBLO_RPN_MASK       0xFFFFFC00
3946

  
3947
target_ulong helper_4xx_tlbre_hi (target_ulong entry)
3933 3948
{
3934 3949
    ppcemb_tlb_t *tlb;
3935 3950
    target_ulong ret;
3936 3951
    int size;
3937 3952

  
3938
    entry &= 0x3F;
3953
    entry &= PPC4XX_TLB_ENTRY_MASK;
3939 3954
    tlb = &env->tlb[entry].tlbe;
3940 3955
    ret = tlb->EPN;
3941
    if (tlb->prot & PAGE_VALID)
3942
        ret |= 0x400;
3956
    if (tlb->prot & PAGE_VALID) {
3957
        ret |= PPC4XX_TLBHI_V;
3958
    }
3943 3959
    size = booke_page_size_to_tlb(tlb->size);
3944
    if (size < 0 || size > 0x7)
3945
        size = 1;
3946
    ret |= size << 7;
3960
    if (size < PPC4XX_TLBHI_SIZE_MIN || size > PPC4XX_TLBHI_SIZE_MAX) {
3961
        size = PPC4XX_TLBHI_SIZE_DEFAULT;
3962
    }
3963
    ret |= size << PPC4XX_TLBHI_SIZE_SHIFT;
3947 3964
    env->spr[SPR_40x_PID] = tlb->PID;
3948 3965
    return ret;
3949 3966
}
3950 3967

  
3951
target_ulong helper_4xx_tlbre_hi (target_ulong entry)
3968
target_ulong helper_4xx_tlbre_lo (target_ulong entry)
3952 3969
{
3953 3970
    ppcemb_tlb_t *tlb;
3954 3971
    target_ulong ret;
3955 3972

  
3956
    entry &= 0x3F;
3973
    entry &= PPC4XX_TLB_ENTRY_MASK;
3957 3974
    tlb = &env->tlb[entry].tlbe;
3958 3975
    ret = tlb->RPN;
3959
    if (tlb->prot & PAGE_EXEC)
3960
        ret |= 0x200;
3961
    if (tlb->prot & PAGE_WRITE)
3962
        ret |= 0x100;
3976
    if (tlb->prot & PAGE_EXEC) {
3977
        ret |= PPC4XX_TLBLO_EX;
3978
    }
3979
    if (tlb->prot & PAGE_WRITE) {
3980
        ret |= PPC4XX_TLBLO_WR;
3981
    }
3963 3982
    return ret;
3964 3983
}
3965 3984

  
......
3970 3989

  
3971 3990
    LOG_SWTLB("%s entry %d val " TARGET_FMT_lx "\n", __func__, (int)entry,
3972 3991
              val);
3973
    entry &= 0x3F;
3992
    entry &= PPC4XX_TLB_ENTRY_MASK;
3974 3993
    tlb = &env->tlb[entry].tlbe;
3975 3994
    /* Invalidate previous TLB (if it's valid) */
3976 3995
    if (tlb->prot & PAGE_VALID) {
3977 3996
        end = tlb->EPN + tlb->size;
3978 3997
        LOG_SWTLB("%s: invalidate old TLB %d start " TARGET_FMT_lx " end "
3979 3998
                  TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end);
3980
        for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
3999
        for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) {
3981 4000
            tlb_flush_page(env, page);
4001
        }
3982 4002
    }
3983
    tlb->size = booke_tlb_to_page_size((val >> 7) & 0x7);
4003
    tlb->size = booke_tlb_to_page_size((val >> PPC4XX_TLBHI_SIZE_SHIFT)
4004
                                       & PPC4XX_TLBHI_SIZE_MASK);
3984 4005
    /* We cannot handle TLB size < TARGET_PAGE_SIZE.
3985 4006
     * If this ever occurs, one should use the ppcemb target instead
3986 4007
     * of the ppc or ppc64 one
3987 4008
     */
3988
    if ((val & 0x40) && tlb->size < TARGET_PAGE_SIZE) {
4009
    if ((val & PPC4XX_TLBHI_V) && tlb->size < TARGET_PAGE_SIZE) {
3989 4010
        cpu_abort(env, "TLB size " TARGET_FMT_lu " < %u "
3990 4011
                  "are not supported (%d)\n",
3991 4012
                  tlb->size, TARGET_PAGE_SIZE, (int)((val >> 7) & 0x7));
3992 4013
    }
3993 4014
    tlb->EPN = val & ~(tlb->size - 1);
3994
    if (val & 0x40) {
4015
    if (val & PPC4XX_TLBHI_V) {
3995 4016
        tlb->prot |= PAGE_VALID;
3996
        if (val & 0x20) {
4017
        if (val & PPC4XX_TLBHI_E) {
3997 4018
            /* XXX: TO BE FIXED */
3998 4019
            cpu_abort(env,
3999 4020
                      "Little-endian TLB entries are not supported by now\n");
......
4014 4035
        end = tlb->EPN + tlb->size;
4015 4036
        LOG_SWTLB("%s: invalidate TLB %d start " TARGET_FMT_lx " end "
4016 4037
                  TARGET_FMT_lx "\n", __func__, (int)entry, tlb->EPN, end);
4017
        for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE)
4038
        for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) {
4018 4039
            tlb_flush_page(env, page);
4040
        }
4019 4041
    }
4020 4042
}
4021 4043

  
......
4025 4047

  
4026 4048
    LOG_SWTLB("%s entry %i val " TARGET_FMT_lx "\n", __func__, (int)entry,
4027 4049
              val);
4028
    entry &= 0x3F;
4050
    entry &= PPC4XX_TLB_ENTRY_MASK;
4029 4051
    tlb = &env->tlb[entry].tlbe;
4030
    tlb->attr = val & 0xFF;
4031
    tlb->RPN = val & 0xFFFFFC00;
4052
    tlb->attr = val & PPC4XX_TLBLO_ATTR_MASK;
4053
    tlb->RPN = val & PPC4XX_TLBLO_RPN_MASK;
4032 4054
    tlb->prot = PAGE_READ;
4033
    if (val & 0x200)
4055
    if (val & PPC4XX_TLBLO_EX) {
4034 4056
        tlb->prot |= PAGE_EXEC;
4035
    if (val & 0x100)
4057
    }
4058
    if (val & PPC4XX_TLBLO_WR) {
4036 4059
        tlb->prot |= PAGE_WRITE;
4060
    }
4037 4061
    LOG_SWTLB("%s: set up TLB %d RPN " TARGET_FMT_plx " EPN " TARGET_FMT_lx
4038 4062
              " size " TARGET_FMT_lx " prot %c%c%c%c PID %d\n", __func__,
4039 4063
              (int)entry, tlb->RPN, tlb->EPN, tlb->size,

Also available in: Unified diff