int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,

                             int mmu_idx)

{

    mmu_ctx_t ctx;

    int access_type;

    int ret = 0;



    if (rw == 2) {

        /* code access */

        rw = 0;

        access_type = ACCESS_CODE;

    } else {

        /* data access */

        access_type = env->access_type;

    }

    ret = get_physical_address(env, &ctx, address, rw, access_type);

    if (ret == 0) {

        tlb_set_page(env, address & TARGET_PAGE_MASK,

                     ctx.raddr & TARGET_PAGE_MASK, ctx.prot,

                     mmu_idx, TARGET_PAGE_SIZE);

        ret = 0;

    } else if (ret < 0) {

        LOG_MMU_STATE(env);

        if (access_type == ACCESS_CODE) {

            switch (ret) {

            case -1:

                /* No matches in page tables or TLB */

                switch (env->mmu_model) {

                case POWERPC_MMU_SOFT_6xx:

                    env->exception_index = POWERPC_EXCP_IFTLB;

                    env->error_code = 1 << 18;

                    env->spr[SPR_IMISS] = address;

                    env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;

                    goto tlb_miss;

                case POWERPC_MMU_SOFT_74xx:

                    env->exception_index = POWERPC_EXCP_IFTLB;

                    goto tlb_miss_74xx;

                case POWERPC_MMU_SOFT_4xx:

                case POWERPC_MMU_SOFT_4xx_Z:

                    env->exception_index = POWERPC_EXCP_ITLB;

                    env->error_code = 0;

                    env->spr[SPR_40x_DEAR] = address;

                    env->spr[SPR_40x_ESR] = 0x00000000;

                    break;

                case POWERPC_MMU_32B:

                case POWERPC_MMU_601:

#if defined(TARGET_PPC64)

                case POWERPC_MMU_620:

                case POWERPC_MMU_64B:

                case POWERPC_MMU_2_06:


#endif

                    env->exception_index = POWERPC_EXCP_ISI;

                    env->error_code = 0x40000000;

                    break;

                case POWERPC_MMU_BOOKE206:

                    booke206_update_mas_tlb_miss(env, address, rw);

                    /* fall through */

                case POWERPC_MMU_BOOKE:

                    env->exception_index = POWERPC_EXCP_ITLB;

                    env->error_code = 0;

                    env->spr[SPR_BOOKE_DEAR] = address;

                    return -1;

                case POWERPC_MMU_MPC8xx:

                    /* XXX: TODO */

                    cpu_abort(env, "MPC8xx MMU model is not implemented\n");

                    break;

                case POWERPC_MMU_REAL:

                    cpu_abort(env, "PowerPC in real mode should never raise "

                              "any MMU exceptions\n");

                    return -1;

                default:

                    cpu_abort(env, "Unknown or invalid MMU model\n");

                    return -1;

                }

                break;

            case -2:

                /* Access rights violation */

                env->exception_index = POWERPC_EXCP_ISI;

                env->error_code = 0x08000000;

                break;

            case -3:

                /* No execute protection violation */

                if ((env->mmu_model == POWERPC_MMU_BOOKE) ||

                    (env->mmu_model == POWERPC_MMU_BOOKE206)) {

                    env->spr[SPR_BOOKE_ESR] = 0x00000000;

                }

                env->exception_index = POWERPC_EXCP_ISI;

                env->error_code = 0x10000000;

                break;

            case -4:

                /* Direct store exception */

                /* No code fetch is allowed in direct-store areas */

                env->exception_index = POWERPC_EXCP_ISI;

                env->error_code = 0x10000000;

                break;

#if defined(TARGET_PPC64)

            case -5:

                /* No match in segment table */

                if (env->mmu_model == POWERPC_MMU_620) {

                    env->exception_index = POWERPC_EXCP_ISI;

                    /* XXX: this might be incorrect */

                    env->error_code = 0x40000000;

                } else {

                    env->exception_index = POWERPC_EXCP_ISEG;

                    env->error_code = 0;

                }

                break;

#endif

            }

        } else {

            switch (ret) {

            case -1:

                /* No matches in page tables or TLB */

                switch (env->mmu_model) {

                case POWERPC_MMU_SOFT_6xx:

                    if (rw == 1) {

                        env->exception_index = POWERPC_EXCP_DSTLB;

                        env->error_code = 1 << 16;

                    } else {

                        env->exception_index = POWERPC_EXCP_DLTLB;

                        env->error_code = 0;

                    }

                    env->spr[SPR_DMISS] = address;

                    env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;

                tlb_miss:

                    env->error_code |= ctx.key << 19;

                    env->spr[SPR_HASH1] = env->htab_base +

                        get_pteg_offset(env, ctx.hash[0], HASH_PTE_SIZE_32);

                    env->spr[SPR_HASH2] = env->htab_base +

                        get_pteg_offset(env, ctx.hash[1], HASH_PTE_SIZE_32);

                    break;

                case POWERPC_MMU_SOFT_74xx:

                    if (rw == 1) {

                        env->exception_index = POWERPC_EXCP_DSTLB;

                    } else {

                        env->exception_index = POWERPC_EXCP_DLTLB;

                    }

                tlb_miss_74xx:

                    /* Implement LRU algorithm */

                    env->error_code = ctx.key << 19;

                    env->spr[SPR_TLBMISS] = (address & ~((target_ulong)0x3)) |

                        ((env->last_way + 1) & (env->nb_ways - 1));

                    env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem;

                    break;

                case POWERPC_MMU_SOFT_4xx:

                case POWERPC_MMU_SOFT_4xx_Z:

                    env->exception_index = POWERPC_EXCP_DTLB;

                    env->error_code = 0;

                    env->spr[SPR_40x_DEAR] = address;

                    if (rw) {

                        env->spr[SPR_40x_ESR] = 0x00800000;

                    } else {

                        env->spr[SPR_40x_ESR] = 0x00000000;

                    }

                    break;

                case POWERPC_MMU_32B:

                case POWERPC_MMU_601:

#if defined(TARGET_PPC64)

                case POWERPC_MMU_620:

                case POWERPC_MMU_64B:

                case POWERPC_MMU_2_06:


#endif

                    env->exception_index = POWERPC_EXCP_DSI;

                    env->error_code = 0;

                    env->spr[SPR_DAR] = address;

                    if (rw == 1) {

                        env->spr[SPR_DSISR] = 0x42000000;

                    } else {

                        env->spr[SPR_DSISR] = 0x40000000;

                    }

                    break;

                case POWERPC_MMU_MPC8xx:

                    /* XXX: TODO */

                    cpu_abort(env, "MPC8xx MMU model is not implemented\n");

                    break;

                case POWERPC_MMU_BOOKE206:

                    booke206_update_mas_tlb_miss(env, address, rw);

                    /* fall through */

                case POWERPC_MMU_BOOKE:

                    env->exception_index = POWERPC_EXCP_DTLB;

                    env->error_code = 0;

                    env->spr[SPR_BOOKE_DEAR] = address;

                    env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0;

                    return -1;

                case POWERPC_MMU_REAL:

                    cpu_abort(env, "PowerPC in real mode should never raise "

                              "any MMU exceptions\n");

                    return -1;

                default:

                    cpu_abort(env, "Unknown or invalid MMU model\n");

                    return -1;

                }

                break;

            case -2:

                /* Access rights violation */

                env->exception_index = POWERPC_EXCP_DSI;

                env->error_code = 0;

                if (env->mmu_model == POWERPC_MMU_SOFT_4xx

                    || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) {

                    env->spr[SPR_40x_DEAR] = address;

                    if (rw) {

                        env->spr[SPR_40x_ESR] |= 0x00800000;

                    }

                } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||

                           (env->mmu_model == POWERPC_MMU_BOOKE206)) {

                    env->spr[SPR_BOOKE_DEAR] = address;

                    env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0;

                } else {

                    env->spr[SPR_DAR] = address;

                    if (rw == 1) {

                        env->spr[SPR_DSISR] = 0x0A000000;

                    } else {

                        env->spr[SPR_DSISR] = 0x08000000;

                    }

                }

                break;

            case -4:

                /* Direct store exception */

                switch (access_type) {

                case ACCESS_FLOAT:

                    /* Floating point load/store */

                    env->exception_index = POWERPC_EXCP_ALIGN;

                    env->error_code = POWERPC_EXCP_ALIGN_FP;

                    env->spr[SPR_DAR] = address;

                    break;

                case ACCESS_RES:

                    /* lwarx, ldarx or stwcx. */

                    env->exception_index = POWERPC_EXCP_DSI;

                    env->error_code = 0;

                    env->spr[SPR_DAR] = address;

                    if (rw == 1) {

                        env->spr[SPR_DSISR] = 0x06000000;

                    } else {

                        env->spr[SPR_DSISR] = 0x04000000;

                    }

                    break;

                case ACCESS_EXT:

                    /* eciwx or ecowx */

                    env->exception_index = POWERPC_EXCP_DSI;

                    env->error_code = 0;

                    env->spr[SPR_DAR] = address;

                    if (rw == 1) {

                        env->spr[SPR_DSISR] = 0x06100000;

                    } else {

                        env->spr[SPR_DSISR] = 0x04100000;

                    }

                    break;

                default:

                    printf("DSI: invalid exception (%d)\n", ret);

                    env->exception_index = POWERPC_EXCP_PROGRAM;

                    env->error_code =

                        POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;

                    env->spr[SPR_DAR] = address;

                    break;

                }

                break;

#if defined(TARGET_PPC64)

            case -5:

                /* No match in segment table */

                if (env->mmu_model == POWERPC_MMU_620) {

                    env->exception_index = POWERPC_EXCP_DSI;

                    env->error_code = 0;

                    env->spr[SPR_DAR] = address;

                    /* XXX: this might be incorrect */

                    if (rw == 1) {

                        env->spr[SPR_DSISR] = 0x42000000;

                    } else {

                        env->spr[SPR_DSISR] = 0x40000000;

                    }

                } else {

                    env->exception_index = POWERPC_EXCP_DSEG;

                    env->error_code = 0;

                    env->spr[SPR_DAR] = address;

                }

                break;

#endif

            }

        }

#if 0

        printf("%s: set exception to %d %02x\n", __func__,

               env->exception, env->error_code);

#endif

        ret = 1;

    }



    return ret;

}
int cpu_ppc_handle_mmu_fault(CPUPPCState *env, target_ulong address, int rw,

                             int mmu_idx)

{

    mmu_ctx_t ctx;

    int access_type;

    int ret = 0;



    if (rw == 2) {

        

        rw = 0;

        access_type = ACCESS_CODE;

    } else {

        

        access_type = env->access_type;

    }

    ret = get_physical_address(env, &ctx, address, rw, access_type);

    if (ret == 0) {

        tlb_set_page(env, address & TARGET_PAGE_MASK,

                     ctx.raddr & TARGET_PAGE_MASK, ctx.prot,

                     mmu_idx, TARGET_PAGE_SIZE);

        ret = 0;

    } else if (ret < 0) {

        LOG_MMU_STATE(env);

        if (access_type == ACCESS_CODE) {

            switch (ret) {

            case -1:

                

                switch (env->mmu_model) {

                case POWERPC_MMU_SOFT_6xx:

                    env->exception_index = POWERPC_EXCP_IFTLB;

                    env->error_code = 1 << 18;

                    env->spr[SPR_IMISS] = address;

                    env->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;

                    goto tlb_miss;

                case POWERPC_MMU_SOFT_74xx:

                    env->exception_index = POWERPC_EXCP_IFTLB;

                    goto tlb_miss_74xx;

                case POWERPC_MMU_SOFT_4xx:

                case POWERPC_MMU_SOFT_4xx_Z:

                    env->exception_index = POWERPC_EXCP_ITLB;

                    env->error_code = 0;

                    env->spr[SPR_40x_DEAR] = address;

                    env->spr[SPR_40x_ESR] = 0x00000000;

                    break;

                case POWERPC_MMU_32B:

                case POWERPC_MMU_601:

#if defined(TARGET_PPC64)

                case POWERPC_MMU_620:

                case POWERPC_MMU_64B:

                case POWERPC_MMU_2_06:


#endif

                    env->exception_index = POWERPC_EXCP_ISI;

                    env->error_code = 0x40000000;

                    break;

                case POWERPC_MMU_BOOKE206:

                    booke206_update_mas_tlb_miss(env, address, rw);

                    

                case POWERPC_MMU_BOOKE:

                    env->exception_index = POWERPC_EXCP_ITLB;

                    env->error_code = 0;

                    env->spr[SPR_BOOKE_DEAR] = address;

                    return -1;

                case POWERPC_MMU_MPC8xx:

                    

                    cpu_abort(env, "MPC8xx MMU model is not implemented\n");

                    break;

                case POWERPC_MMU_REAL:

                    cpu_abort(env, "PowerPC in real mode should never raise "

                              "any MMU exceptions\n");

                    return -1;

                default:

                    cpu_abort(env, "Unknown or invalid MMU model\n");

                    return -1;

                }

                break;

            case -2:

                

                env->exception_index = POWERPC_EXCP_ISI;

                env->error_code = 0x08000000;

                break;

            case -3:

                

                if ((env->mmu_model == POWERPC_MMU_BOOKE) ||

                    (env->mmu_model == POWERPC_MMU_BOOKE206)) {

                    env->spr[SPR_BOOKE_ESR] = 0x00000000;

                }

                env->exception_index = POWERPC_EXCP_ISI;

                env->error_code = 0x10000000;

                break;

            case -4:

                

                

                env->exception_index = POWERPC_EXCP_ISI;

                env->error_code = 0x10000000;

                break;

#if defined(TARGET_PPC64)

            case -5:

                

                if (env->mmu_model == POWERPC_MMU_620) {

                    env->exception_index = POWERPC_EXCP_ISI;

                    

                    env->error_code = 0x40000000;

                } else {

                    env->exception_index = POWERPC_EXCP_ISEG;

                    env->error_code = 0;

                }

                break;

#endif

            }

        } else {

            switch (ret) {

            case -1:

                

                switch (env->mmu_model) {

                case POWERPC_MMU_SOFT_6xx:

                    if (rw == 1) {

                        env->exception_index = POWERPC_EXCP_DSTLB;

                        env->error_code = 1 << 16;

                    } else {

                        env->exception_index = POWERPC_EXCP_DLTLB;

                        env->error_code = 0;

                    }

                    env->spr[SPR_DMISS] = address;

                    env->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;

                tlb_miss:

                    env->error_code |= ctx.key << 19;

                    env->spr[SPR_HASH1] = env->htab_base +

                        get_pteg_offset(env, ctx.hash[0], HASH_PTE_SIZE_32);

                    env->spr[SPR_HASH2] = env->htab_base +

                        get_pteg_offset(env, ctx.hash[1], HASH_PTE_SIZE_32);

                    break;

                case POWERPC_MMU_SOFT_74xx:

                    if (rw == 1) {

                        env->exception_index = POWERPC_EXCP_DSTLB;

                    } else {

                        env->exception_index = POWERPC_EXCP_DLTLB;

                    }

                tlb_miss_74xx:

                    

                    env->error_code = ctx.key << 19;

                    env->spr[SPR_TLBMISS] = (address & ~((target_ulong)0x3)) |

                        ((env->last_way + 1) & (env->nb_ways - 1));

                    env->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem;

                    break;

                case POWERPC_MMU_SOFT_4xx:

                case POWERPC_MMU_SOFT_4xx_Z:

                    env->exception_index = POWERPC_EXCP_DTLB;

                    env->error_code = 0;

                    env->spr[SPR_40x_DEAR] = address;

                    if (rw) {

                        env->spr[SPR_40x_ESR] = 0x00800000;

                    } else {

                        env->spr[SPR_40x_ESR] = 0x00000000;

                    }

                    break;

                case POWERPC_MMU_32B:

                case POWERPC_MMU_601:

#if defined(TARGET_PPC64)

                case POWERPC_MMU_620:

                case POWERPC_MMU_64B:

                case POWERPC_MMU_2_06:


#endif

                    env->exception_index = POWERPC_EXCP_DSI;

                    env->error_code = 0;

                    env->spr[SPR_DAR] = address;

                    if (rw == 1) {

                        env->spr[SPR_DSISR] = 0x42000000;

                    } else {

                        env->spr[SPR_DSISR] = 0x40000000;

                    }

                    break;

                case POWERPC_MMU_MPC8xx:

                    

                    cpu_abort(env, "MPC8xx MMU model is not implemented\n");

                    break;

                case POWERPC_MMU_BOOKE206:

                    booke206_update_mas_tlb_miss(env, address, rw);

                    

                case POWERPC_MMU_BOOKE:

                    env->exception_index = POWERPC_EXCP_DTLB;

                    env->error_code = 0;

                    env->spr[SPR_BOOKE_DEAR] = address;

                    env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0;

                    return -1;

                case POWERPC_MMU_REAL:

                    cpu_abort(env, "PowerPC in real mode should never raise "

                              "any MMU exceptions\n");

                    return -1;

                default:

                    cpu_abort(env, "Unknown or invalid MMU model\n");

                    return -1;

                }

                break;

            case -2:

                

                env->exception_index = POWERPC_EXCP_DSI;

                env->error_code = 0;

                if (env->mmu_model == POWERPC_MMU_SOFT_4xx

                    || env->mmu_model == POWERPC_MMU_SOFT_4xx_Z) {

                    env->spr[SPR_40x_DEAR] = address;

                    if (rw) {

                        env->spr[SPR_40x_ESR] |= 0x00800000;

                    }

                } else if ((env->mmu_model == POWERPC_MMU_BOOKE) ||

                           (env->mmu_model == POWERPC_MMU_BOOKE206)) {

                    env->spr[SPR_BOOKE_DEAR] = address;

                    env->spr[SPR_BOOKE_ESR] = rw ? ESR_ST : 0;

                } else {

                    env->spr[SPR_DAR] = address;

                    if (rw == 1) {

                        env->spr[SPR_DSISR] = 0x0A000000;

                    } else {

                        env->spr[SPR_DSISR] = 0x08000000;

                    }

                }

                break;

            case -4:

                

                switch (access_type) {

                case ACCESS_FLOAT:

                    

                    env->exception_index = POWERPC_EXCP_ALIGN;

                    env->error_code = POWERPC_EXCP_ALIGN_FP;

                    env->spr[SPR_DAR] = address;

                    break;

                case ACCESS_RES:

                    

                    env->exception_index = POWERPC_EXCP_DSI;

                    env->error_code = 0;

                    env->spr[SPR_DAR] = address;

                    if (rw == 1) {

                        env->spr[SPR_DSISR] = 0x06000000;

                    } else {

                        env->spr[SPR_DSISR] = 0x04000000;

                    }

                    break;

                case ACCESS_EXT:

                    

                    env->exception_index = POWERPC_EXCP_DSI;

                    env->error_code = 0;

                    env->spr[SPR_DAR] = address;

                    if (rw == 1) {

                        env->spr[SPR_DSISR] = 0x06100000;

                    } else {

                        env->spr[SPR_DSISR] = 0x04100000;

                    }

                    break;

                default:

                    printf("DSI: invalid exception (%d)\n", ret);

                    env->exception_index = POWERPC_EXCP_PROGRAM;

                    env->error_code =

                        POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;

                    env->spr[SPR_DAR] = address;

                    break;

                }

                break;

#if defined(TARGET_PPC64)

            case -5:

                

                if (env->mmu_model == POWERPC_MMU_620) {

                    env->exception_index = POWERPC_EXCP_DSI;

                    env->error_code = 0;

                    env->spr[SPR_DAR] = address;

                    

                    if (rw == 1) {

                        env->spr[SPR_DSISR] = 0x42000000;

                    } else {

                        env->spr[SPR_DSISR] = 0x40000000;

                    }

                } else {

                    env->exception_index = POWERPC_EXCP_DSEG;

                    env->error_code = 0;

                    env->spr[SPR_DAR] = address;

                }

                break;

#endif

            }

        }

#if 0

        printf("%s: set exception to %d %02x\n", __func__,

               env->exception, env->error_code);

#endif

        ret = 1;

    }



    return ret;

}
int FUNC_0(CPUPPCState *VAR_0, target_ulong VAR_1, int VAR_2,

                             int VAR_3)

{

    mmu_ctx_t ctx;

    int VAR_4;

    int VAR_5 = 0;



    if (VAR_2 == 2) {

        

        VAR_2 = 0;

        VAR_4 = ACCESS_CODE;

    } else {

        

        VAR_4 = VAR_0->VAR_4;

    }

    VAR_5 = get_physical_address(VAR_0, &ctx, VAR_1, VAR_2, VAR_4);

    if (VAR_5 == 0) {

        tlb_set_page(VAR_0, VAR_1 & TARGET_PAGE_MASK,

                     ctx.raddr & TARGET_PAGE_MASK, ctx.prot,

                     VAR_3, TARGET_PAGE_SIZE);

        VAR_5 = 0;

    } else if (VAR_5 < 0) {

        LOG_MMU_STATE(VAR_0);

        if (VAR_4 == ACCESS_CODE) {

            switch (VAR_5) {

            case -1:

                

                switch (VAR_0->mmu_model) {

                case POWERPC_MMU_SOFT_6xx:

                    VAR_0->exception_index = POWERPC_EXCP_IFTLB;

                    VAR_0->error_code = 1 << 18;

                    VAR_0->spr[SPR_IMISS] = VAR_1;

                    VAR_0->spr[SPR_ICMP] = 0x80000000 | ctx.ptem;

                    goto tlb_miss;

                case POWERPC_MMU_SOFT_74xx:

                    VAR_0->exception_index = POWERPC_EXCP_IFTLB;

                    goto tlb_miss_74xx;

                case POWERPC_MMU_SOFT_4xx:

                case POWERPC_MMU_SOFT_4xx_Z:

                    VAR_0->exception_index = POWERPC_EXCP_ITLB;

                    VAR_0->error_code = 0;

                    VAR_0->spr[SPR_40x_DEAR] = VAR_1;

                    VAR_0->spr[SPR_40x_ESR] = 0x00000000;

                    break;

                case POWERPC_MMU_32B:

                case POWERPC_MMU_601:

#if defined(TARGET_PPC64)

                case POWERPC_MMU_620:

                case POWERPC_MMU_64B:

                case POWERPC_MMU_2_06:


#endif

                    VAR_0->exception_index = POWERPC_EXCP_ISI;

                    VAR_0->error_code = 0x40000000;

                    break;

                case POWERPC_MMU_BOOKE206:

                    booke206_update_mas_tlb_miss(VAR_0, VAR_1, VAR_2);

                    

                case POWERPC_MMU_BOOKE:

                    VAR_0->exception_index = POWERPC_EXCP_ITLB;

                    VAR_0->error_code = 0;

                    VAR_0->spr[SPR_BOOKE_DEAR] = VAR_1;

                    return -1;

                case POWERPC_MMU_MPC8xx:

                    

                    cpu_abort(VAR_0, "MPC8xx MMU model is not implemented\n");

                    break;

                case POWERPC_MMU_REAL:

                    cpu_abort(VAR_0, "PowerPC in real mode should never raise "

                              "any MMU exceptions\n");

                    return -1;

                default:

                    cpu_abort(VAR_0, "Unknown or invalid MMU model\n");

                    return -1;

                }

                break;

            case -2:

                

                VAR_0->exception_index = POWERPC_EXCP_ISI;

                VAR_0->error_code = 0x08000000;

                break;

            case -3:

                

                if ((VAR_0->mmu_model == POWERPC_MMU_BOOKE) ||

                    (VAR_0->mmu_model == POWERPC_MMU_BOOKE206)) {

                    VAR_0->spr[SPR_BOOKE_ESR] = 0x00000000;

                }

                VAR_0->exception_index = POWERPC_EXCP_ISI;

                VAR_0->error_code = 0x10000000;

                break;

            case -4:

                

                

                VAR_0->exception_index = POWERPC_EXCP_ISI;

                VAR_0->error_code = 0x10000000;

                break;

#if defined(TARGET_PPC64)

            case -5:

                

                if (VAR_0->mmu_model == POWERPC_MMU_620) {

                    VAR_0->exception_index = POWERPC_EXCP_ISI;

                    

                    VAR_0->error_code = 0x40000000;

                } else {

                    VAR_0->exception_index = POWERPC_EXCP_ISEG;

                    VAR_0->error_code = 0;

                }

                break;

#endif

            }

        } else {

            switch (VAR_5) {

            case -1:

                

                switch (VAR_0->mmu_model) {

                case POWERPC_MMU_SOFT_6xx:

                    if (VAR_2 == 1) {

                        VAR_0->exception_index = POWERPC_EXCP_DSTLB;

                        VAR_0->error_code = 1 << 16;

                    } else {

                        VAR_0->exception_index = POWERPC_EXCP_DLTLB;

                        VAR_0->error_code = 0;

                    }

                    VAR_0->spr[SPR_DMISS] = VAR_1;

                    VAR_0->spr[SPR_DCMP] = 0x80000000 | ctx.ptem;

                tlb_miss:

                    VAR_0->error_code |= ctx.key << 19;

                    VAR_0->spr[SPR_HASH1] = VAR_0->htab_base +

                        get_pteg_offset(VAR_0, ctx.hash[0], HASH_PTE_SIZE_32);

                    VAR_0->spr[SPR_HASH2] = VAR_0->htab_base +

                        get_pteg_offset(VAR_0, ctx.hash[1], HASH_PTE_SIZE_32);

                    break;

                case POWERPC_MMU_SOFT_74xx:

                    if (VAR_2 == 1) {

                        VAR_0->exception_index = POWERPC_EXCP_DSTLB;

                    } else {

                        VAR_0->exception_index = POWERPC_EXCP_DLTLB;

                    }

                tlb_miss_74xx:

                    

                    VAR_0->error_code = ctx.key << 19;

                    VAR_0->spr[SPR_TLBMISS] = (VAR_1 & ~((target_ulong)0x3)) |

                        ((VAR_0->last_way + 1) & (VAR_0->nb_ways - 1));

                    VAR_0->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem;

                    break;

                case POWERPC_MMU_SOFT_4xx:

                case POWERPC_MMU_SOFT_4xx_Z:

                    VAR_0->exception_index = POWERPC_EXCP_DTLB;

                    VAR_0->error_code = 0;

                    VAR_0->spr[SPR_40x_DEAR] = VAR_1;

                    if (VAR_2) {

                        VAR_0->spr[SPR_40x_ESR] = 0x00800000;

                    } else {

                        VAR_0->spr[SPR_40x_ESR] = 0x00000000;

                    }

                    break;

                case POWERPC_MMU_32B:

                case POWERPC_MMU_601:

#if defined(TARGET_PPC64)

                case POWERPC_MMU_620:

                case POWERPC_MMU_64B:

                case POWERPC_MMU_2_06:


#endif

                    VAR_0->exception_index = POWERPC_EXCP_DSI;

                    VAR_0->error_code = 0;

                    VAR_0->spr[SPR_DAR] = VAR_1;

                    if (VAR_2 == 1) {

                        VAR_0->spr[SPR_DSISR] = 0x42000000;

                    } else {

                        VAR_0->spr[SPR_DSISR] = 0x40000000;

                    }

                    break;

                case POWERPC_MMU_MPC8xx:

                    

                    cpu_abort(VAR_0, "MPC8xx MMU model is not implemented\n");

                    break;

                case POWERPC_MMU_BOOKE206:

                    booke206_update_mas_tlb_miss(VAR_0, VAR_1, VAR_2);

                    

                case POWERPC_MMU_BOOKE:

                    VAR_0->exception_index = POWERPC_EXCP_DTLB;

                    VAR_0->error_code = 0;

                    VAR_0->spr[SPR_BOOKE_DEAR] = VAR_1;

                    VAR_0->spr[SPR_BOOKE_ESR] = VAR_2 ? ESR_ST : 0;

                    return -1;

                case POWERPC_MMU_REAL:

                    cpu_abort(VAR_0, "PowerPC in real mode should never raise "

                              "any MMU exceptions\n");

                    return -1;

                default:

                    cpu_abort(VAR_0, "Unknown or invalid MMU model\n");

                    return -1;

                }

                break;

            case -2:

                

                VAR_0->exception_index = POWERPC_EXCP_DSI;

                VAR_0->error_code = 0;

                if (VAR_0->mmu_model == POWERPC_MMU_SOFT_4xx

                    || VAR_0->mmu_model == POWERPC_MMU_SOFT_4xx_Z) {

                    VAR_0->spr[SPR_40x_DEAR] = VAR_1;

                    if (VAR_2) {

                        VAR_0->spr[SPR_40x_ESR] |= 0x00800000;

                    }

                } else if ((VAR_0->mmu_model == POWERPC_MMU_BOOKE) ||

                           (VAR_0->mmu_model == POWERPC_MMU_BOOKE206)) {

                    VAR_0->spr[SPR_BOOKE_DEAR] = VAR_1;

                    VAR_0->spr[SPR_BOOKE_ESR] = VAR_2 ? ESR_ST : 0;

                } else {

                    VAR_0->spr[SPR_DAR] = VAR_1;

                    if (VAR_2 == 1) {

                        VAR_0->spr[SPR_DSISR] = 0x0A000000;

                    } else {

                        VAR_0->spr[SPR_DSISR] = 0x08000000;

                    }

                }

                break;

            case -4:

                

                switch (VAR_4) {

                case ACCESS_FLOAT:

                    

                    VAR_0->exception_index = POWERPC_EXCP_ALIGN;

                    VAR_0->error_code = POWERPC_EXCP_ALIGN_FP;

                    VAR_0->spr[SPR_DAR] = VAR_1;

                    break;

                case ACCESS_RES:

                    

                    VAR_0->exception_index = POWERPC_EXCP_DSI;

                    VAR_0->error_code = 0;

                    VAR_0->spr[SPR_DAR] = VAR_1;

                    if (VAR_2 == 1) {

                        VAR_0->spr[SPR_DSISR] = 0x06000000;

                    } else {

                        VAR_0->spr[SPR_DSISR] = 0x04000000;

                    }

                    break;

                case ACCESS_EXT:

                    

                    VAR_0->exception_index = POWERPC_EXCP_DSI;

                    VAR_0->error_code = 0;

                    VAR_0->spr[SPR_DAR] = VAR_1;

                    if (VAR_2 == 1) {

                        VAR_0->spr[SPR_DSISR] = 0x06100000;

                    } else {

                        VAR_0->spr[SPR_DSISR] = 0x04100000;

                    }

                    break;

                default:

                    printf("DSI: invalid exception (%d)\n", VAR_5);

                    VAR_0->exception_index = POWERPC_EXCP_PROGRAM;

                    VAR_0->error_code =

                        POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL;

                    VAR_0->spr[SPR_DAR] = VAR_1;

                    break;

                }

                break;

#if defined(TARGET_PPC64)

            case -5:

                

                if (VAR_0->mmu_model == POWERPC_MMU_620) {

                    VAR_0->exception_index = POWERPC_EXCP_DSI;

                    VAR_0->error_code = 0;

                    VAR_0->spr[SPR_DAR] = VAR_1;

                    

                    if (VAR_2 == 1) {

                        VAR_0->spr[SPR_DSISR] = 0x42000000;

                    } else {

                        VAR_0->spr[SPR_DSISR] = 0x40000000;

                    }

                } else {

                    VAR_0->exception_index = POWERPC_EXCP_DSEG;

                    VAR_0->error_code = 0;

                    VAR_0->spr[SPR_DAR] = VAR_1;

                }

                break;

#endif

            }

        }

#if 0

        printf("%s: set exception to %d %02x\n", __func__,

               VAR_0->exception, VAR_0->error_code);

#endif

        VAR_5 = 1;

    }



    return VAR_5;

}
int FUNC_0(CPUPPCState *VAR_0, target_ulong VAR_1, int VAR_2,
int VAR_3)
{ mmu_ctx_t ctx; int VAR_4; int VAR_5 = 0; if (VAR_2 == 2) { VAR_2 = 0; VAR_4 = ACCESS_CODE; } else { VAR_4 = VAR_0->VAR_4; } VAR_5 = get_physical_address(VAR_0, &ctx, VAR_1, VAR_2, VAR_4); if (VAR_5 == 0) { tlb_set_page(VAR_0, VAR_1 & TARGET_PAGE_MASK,
ctx.raddr & TARGET_PAGE_MASK, ctx.prot,
VAR_3, TARGET_PAGE_SIZE); VAR_5 = 0; } else if (VAR_5 < 0) { LOG_MMU_STATE(VAR_0); if (VAR_4 == ACCESS_CODE) { switch (VAR_5) { case -1:
switch (VAR_0->mmu_model) { case POWERPC_MMU_SOFT_6xx:
VAR_0->exception_index = POWERPC_EXCP_IFTLB; VAR_0->error_code = 1 << 18; VAR_0->spr[SPR_IMISS] = VAR_1; VAR_0->spr[SPR_ICMP] = 0x80000000 | ctx.ptem; goto tlb_miss; case POWERPC_MMU_SOFT_74xx:
VAR_0->exception_index = POWERPC_EXCP_IFTLB; goto tlb_miss_74xx; case POWERPC_MMU_SOFT_4xx:
case POWERPC_MMU_SOFT_4xx_Z:
VAR_0->exception_index = POWERPC_EXCP_ITLB; VAR_0->error_code = 0; VAR_0->spr[SPR_40x_DEAR] = VAR_1; VAR_0->spr[SPR_40x_ESR] = 0x00000000; break; case POWERPC_MMU_32B:
case POWERPC_MMU_601:
#if defined(TARGET_PPC64)
case POWERPC_MMU_620:
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
#endif
VAR_0->exception_index = POWERPC_EXCP_ISI; VAR_0->error_code = 0x40000000; break; case POWERPC_MMU_BOOKE206:
booke206_update_mas_tlb_miss(VAR_0, VAR_1, VAR_2); case POWERPC_MMU_BOOKE:
VAR_0->exception_index = POWERPC_EXCP_ITLB; VAR_0->error_code = 0; VAR_0->spr[SPR_BOOKE_DEAR] = VAR_1; return -1; case POWERPC_MMU_MPC8xx:
cpu_abort(VAR_0, "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_REAL:
cpu_abort(VAR_0, "PowerPC in real mode should never raise "
"any MMU exceptions\n"); return -1; default:
cpu_abort(VAR_0, "Unknown or invalid MMU model\n"); return -1; } break; case -2:
VAR_0->exception_index = POWERPC_EXCP_ISI; VAR_0->error_code = 0x08000000; break; case -3:
if ((VAR_0->mmu_model == POWERPC_MMU_BOOKE) ||
(VAR_0->mmu_model == POWERPC_MMU_BOOKE206)) { VAR_0->spr[SPR_BOOKE_ESR] = 0x00000000; } VAR_0->exception_index = POWERPC_EXCP_ISI; VAR_0->error_code = 0x10000000; break; case -4:
VAR_0->exception_index = POWERPC_EXCP_ISI; VAR_0->error_code = 0x10000000; break; #if defined(TARGET_PPC64)
case -5:
if (VAR_0->mmu_model == POWERPC_MMU_620) { VAR_0->exception_index = POWERPC_EXCP_ISI; VAR_0->error_code = 0x40000000; } else { VAR_0->exception_index = POWERPC_EXCP_ISEG; VAR_0->error_code = 0; } break; #endif
} } else { switch (VAR_5) { case -1:
switch (VAR_0->mmu_model) { case POWERPC_MMU_SOFT_6xx:
if (VAR_2 == 1) { VAR_0->exception_index = POWERPC_EXCP_DSTLB; VAR_0->error_code = 1 << 16; } else { VAR_0->exception_index = POWERPC_EXCP_DLTLB; VAR_0->error_code = 0; } VAR_0->spr[SPR_DMISS] = VAR_1; VAR_0->spr[SPR_DCMP] = 0x80000000 | ctx.ptem; tlb_miss:
VAR_0->error_code |= ctx.key << 19; VAR_0->spr[SPR_HASH1] = VAR_0->htab_base +
get_pteg_offset(VAR_0, ctx.hash[0], HASH_PTE_SIZE_32); VAR_0->spr[SPR_HASH2] = VAR_0->htab_base +
get_pteg_offset(VAR_0, ctx.hash[1], HASH_PTE_SIZE_32); break; case POWERPC_MMU_SOFT_74xx:
if (VAR_2 == 1) { VAR_0->exception_index = POWERPC_EXCP_DSTLB; } else { VAR_0->exception_index = POWERPC_EXCP_DLTLB; } tlb_miss_74xx:
VAR_0->error_code = ctx.key << 19; VAR_0->spr[SPR_TLBMISS] = (VAR_1 & ~((target_ulong)0x3)) |
((VAR_0->last_way + 1) & (VAR_0->nb_ways - 1)); VAR_0->spr[SPR_PTEHI] = 0x80000000 | ctx.ptem; break; case POWERPC_MMU_SOFT_4xx:
case POWERPC_MMU_SOFT_4xx_Z:
VAR_0->exception_index = POWERPC_EXCP_DTLB; VAR_0->error_code = 0; VAR_0->spr[SPR_40x_DEAR] = VAR_1; if (VAR_2) { VAR_0->spr[SPR_40x_ESR] = 0x00800000; } else { VAR_0->spr[SPR_40x_ESR] = 0x00000000; } break; case POWERPC_MMU_32B:
case POWERPC_MMU_601:
#if defined(TARGET_PPC64)
case POWERPC_MMU_620:
case POWERPC_MMU_64B:
case POWERPC_MMU_2_06:
#endif
VAR_0->exception_index = POWERPC_EXCP_DSI; VAR_0->error_code = 0; VAR_0->spr[SPR_DAR] = VAR_1; if (VAR_2 == 1) { VAR_0->spr[SPR_DSISR] = 0x42000000; } else { VAR_0->spr[SPR_DSISR] = 0x40000000; } break; case POWERPC_MMU_MPC8xx:
cpu_abort(VAR_0, "MPC8xx MMU model is not implemented\n"); break; case POWERPC_MMU_BOOKE206:
booke206_update_mas_tlb_miss(VAR_0, VAR_1, VAR_2); case POWERPC_MMU_BOOKE:
VAR_0->exception_index = POWERPC_EXCP_DTLB; VAR_0->error_code = 0; VAR_0->spr[SPR_BOOKE_DEAR] = VAR_1; VAR_0->spr[SPR_BOOKE_ESR] = VAR_2 ? ESR_ST : 0; return -1; case POWERPC_MMU_REAL:
cpu_abort(VAR_0, "PowerPC in real mode should never raise "
"any MMU exceptions\n"); return -1; default:
cpu_abort(VAR_0, "Unknown or invalid MMU model\n"); return -1; } break; case -2:
VAR_0->exception_index = POWERPC_EXCP_DSI; VAR_0->error_code = 0; if (VAR_0->mmu_model == POWERPC_MMU_SOFT_4xx
|| VAR_0->mmu_model == POWERPC_MMU_SOFT_4xx_Z) { VAR_0->spr[SPR_40x_DEAR] = VAR_1; if (VAR_2) { VAR_0->spr[SPR_40x_ESR] |= 0x00800000; } } else if ((VAR_0->mmu_model == POWERPC_MMU_BOOKE) || (VAR_0->mmu_model == POWERPC_MMU_BOOKE206)) { VAR_0->spr[SPR_BOOKE_DEAR] = VAR_1; VAR_0->spr[SPR_BOOKE_ESR] = VAR_2 ? ESR_ST : 0; } else { VAR_0->spr[SPR_DAR] = VAR_1; if (VAR_2 == 1) { VAR_0->spr[SPR_DSISR] = 0x0A000000; } else { VAR_0->spr[SPR_DSISR] = 0x08000000; } } break; case -4:
switch (VAR_4) { case ACCESS_FLOAT:
VAR_0->exception_index = POWERPC_EXCP_ALIGN; VAR_0->error_code = POWERPC_EXCP_ALIGN_FP; VAR_0->spr[SPR_DAR] = VAR_1; break; case ACCESS_RES:
VAR_0->exception_index = POWERPC_EXCP_DSI; VAR_0->error_code = 0; VAR_0->spr[SPR_DAR] = VAR_1; if (VAR_2 == 1) { VAR_0->spr[SPR_DSISR] = 0x06000000; } else { VAR_0->spr[SPR_DSISR] = 0x04000000; } break; case ACCESS_EXT:
VAR_0->exception_index = POWERPC_EXCP_DSI; VAR_0->error_code = 0; VAR_0->spr[SPR_DAR] = VAR_1; if (VAR_2 == 1) { VAR_0->spr[SPR_DSISR] = 0x06100000; } else { VAR_0->spr[SPR_DSISR] = 0x04100000; } break; default:
printf("DSI: invalid exception (%d)\n", VAR_5); VAR_0->exception_index = POWERPC_EXCP_PROGRAM; VAR_0->error_code =
POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL; VAR_0->spr[SPR_DAR] = VAR_1; break; } break; #if defined(TARGET_PPC64)
case -5:
if (VAR_0->mmu_model == POWERPC_MMU_620) { VAR_0->exception_index = POWERPC_EXCP_DSI; VAR_0->error_code = 0; VAR_0->spr[SPR_DAR] = VAR_1; if (VAR_2 == 1) { VAR_0->spr[SPR_DSISR] = 0x42000000; } else { VAR_0->spr[SPR_DSISR] = 0x40000000; } } else { VAR_0->exception_index = POWERPC_EXCP_DSEG; VAR_0->error_code = 0; VAR_0->spr[SPR_DAR] = VAR_1; } break; #endif
} } #if 0
printf("%s: set exception to %d %02x\n", __func__,
VAR_0->exception, VAR_0->error_code); #endif
VAR_5 = 1; } return VAR_5; }