mmu_helper.c (af44a1423691b6c93327fccfef20a5c5cbf8e517) mmu_helper.c (51806b545834e0902dd2d17d1f66c7a2d83422f3)
1/*
2 * PowerPC MMU, TLB, SLB and BAT emulation helpers for QEMU.
3 *
4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either

--- 2885 unchanged lines hidden (view full) ---

2894void helper_check_tlb_flush_global(CPUPPCState *env)
2895{
2896 check_tlb_flush(env, true);
2897}
2898#endif /* CONFIG_TCG */
2899
2900/*****************************************************************************/
2901
1/*
2 * PowerPC MMU, TLB, SLB and BAT emulation helpers for QEMU.
3 *
4 * Copyright (c) 2003-2007 Jocelyn Mayer
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either

--- 2885 unchanged lines hidden (view full) ---

2894void helper_check_tlb_flush_global(CPUPPCState *env)
2895{
2896 check_tlb_flush(env, true);
2897}
2898#endif /* CONFIG_TCG */
2899
2900/*****************************************************************************/
2901
2902static int cpu_ppc_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,
2903 MMUAccessType access_type, int mmu_idx)
2902static bool ppc_xlate(PowerPCCPU *cpu, vaddr eaddr, MMUAccessType access_type,
2903 hwaddr *raddrp, int *psizep, int *protp,
2904 int mmu_idx, bool guest_visible)
2904{
2905{
2905 CPUState *cs = CPU(cpu);
2906 int page_size, prot;
2907 hwaddr raddr;
2908
2909 if (!ppc_jumbo_xlate(cpu, eaddr, access_type, &raddr,
2910 &page_size, &prot, mmu_idx, true)) {
2911 return 1;
2912 }
2913
2914 tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
2915 prot, mmu_idx, 1UL << page_size);
2916 return 0;
2917}
2918
2919hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
2920{
2921 PowerPCCPU *cpu = POWERPC_CPU(cs);
2922 CPUPPCState *env = &cpu->env;
2923 hwaddr raddr;
2924 int s, p;
2925
2926 switch (env->mmu_model) {
2906 switch (cpu->env.mmu_model) {
2927#if defined(TARGET_PPC64)
2907#if defined(TARGET_PPC64)
2908 case POWERPC_MMU_3_00:
2909 if (ppc64_v3_radix(cpu)) {
2910 return ppc_radix64_xlate(cpu, eaddr, access_type,
2911 raddrp, psizep, protp, guest_visible);
2912 }
2913 /* fall through */
2928 case POWERPC_MMU_64B:
2929 case POWERPC_MMU_2_03:
2930 case POWERPC_MMU_2_06:
2931 case POWERPC_MMU_2_07:
2914 case POWERPC_MMU_64B:
2915 case POWERPC_MMU_2_03:
2916 case POWERPC_MMU_2_06:
2917 case POWERPC_MMU_2_07:
2932 return ppc_hash64_get_phys_page_debug(cpu, addr);
2933 case POWERPC_MMU_3_00:
2934 return ppc64_v3_get_phys_page_debug(cpu, addr);
2918 return ppc_hash64_xlate(cpu, eaddr, access_type,
2919 raddrp, psizep, protp, guest_visible);
2935#endif
2936
2937 case POWERPC_MMU_32B:
2938 case POWERPC_MMU_601:
2920#endif
2921
2922 case POWERPC_MMU_32B:
2923 case POWERPC_MMU_601:
2939 return ppc_hash32_get_phys_page_debug(cpu, addr);
2924 return ppc_hash32_xlate(cpu, eaddr, access_type,
2925 raddrp, psizep, protp, guest_visible);
2940
2941 default:
2926
2927 default:
2942 ;
2928 return ppc_jumbo_xlate(cpu, eaddr, access_type, raddrp,
2929 psizep, protp, mmu_idx, guest_visible);
2943 }
2930 }
2931}
2944
2932
2933hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr)
2934{
2935 PowerPCCPU *cpu = POWERPC_CPU(cs);
2936 hwaddr raddr;
2937 int s, p;
2938
2945 /*
2946 * Some MMUs have separate TLBs for code and data. If we only
2947 * try an MMU_DATA_LOAD, we may not be able to read instructions
2948 * mapped by code TLBs, so we also try a MMU_INST_FETCH.
2949 */
2939 /*
2940 * Some MMUs have separate TLBs for code and data. If we only
2941 * try an MMU_DATA_LOAD, we may not be able to read instructions
2942 * mapped by code TLBs, so we also try a MMU_INST_FETCH.
2943 */
2950 if (ppc_jumbo_xlate(cpu, addr, MMU_DATA_LOAD, &raddr, &s, &p, 0, false) ||
2951 ppc_jumbo_xlate(cpu, addr, MMU_INST_FETCH, &raddr, &s, &p, 0, false)) {
2944 if (ppc_xlate(cpu, addr, MMU_DATA_LOAD, &raddr, &s, &p, 0, false) ||
2945 ppc_xlate(cpu, addr, MMU_INST_FETCH, &raddr, &s, &p, 0, false)) {
2952 return raddr & TARGET_PAGE_MASK;
2953 }
2954 return -1;
2955}
2956
2946 return raddr & TARGET_PAGE_MASK;
2947 }
2948 return -1;
2949}
2950
2957
2958bool ppc_cpu_tlb_fill(CPUState *cs, vaddr addr, int size,
2951bool ppc_cpu_tlb_fill(CPUState *cs, vaddr eaddr, int size,
2959 MMUAccessType access_type, int mmu_idx,
2960 bool probe, uintptr_t retaddr)
2961{
2962 PowerPCCPU *cpu = POWERPC_CPU(cs);
2952 MMUAccessType access_type, int mmu_idx,
2953 bool probe, uintptr_t retaddr)
2954{
2955 PowerPCCPU *cpu = POWERPC_CPU(cs);
2963 CPUPPCState *env = &cpu->env;
2964 int ret;
2956 hwaddr raddr;
2957 int page_size, prot;
2965
2958
2966 switch (env->mmu_model) {
2967#if defined(TARGET_PPC64)
2968 case POWERPC_MMU_64B:
2969 case POWERPC_MMU_2_03:
2970 case POWERPC_MMU_2_06:
2971 case POWERPC_MMU_2_07:
2972 ret = ppc_hash64_handle_mmu_fault(cpu, addr, access_type, mmu_idx);
2973 break;
2974 case POWERPC_MMU_3_00:
2975 ret = ppc64_v3_handle_mmu_fault(cpu, addr, access_type, mmu_idx);
2976 break;
2977#endif
2978
2979 case POWERPC_MMU_32B:
2980 case POWERPC_MMU_601:
2981 ret = ppc_hash32_handle_mmu_fault(cpu, addr, access_type, mmu_idx);
2982 break;
2983
2984 default:
2985 ret = cpu_ppc_handle_mmu_fault(cpu, addr, access_type, mmu_idx);
2986 break;
2959 if (ppc_xlate(cpu, eaddr, access_type, &raddr,
2960 &page_size, &prot, mmu_idx, !probe)) {
2961 tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,
2962 prot, mmu_idx, 1UL << page_size);
2963 return true;
2987 }
2964 }
2988 if (unlikely(ret != 0)) {
2989 if (probe) {
2990 return false;
2991 }
2992 raise_exception_err_ra(env, cs->exception_index, env->error_code,
2993 retaddr);
2965 if (probe) {
2966 return false;
2994 }
2967 }
2995 return true;
2968 raise_exception_err_ra(&cpu->env, cs->exception_index,
2969 cpu->env.error_code, retaddr);
2996}
2970}