int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,

                                 target_ulong address, int rw, int access_type)

{

    ppcemb_tlb_t *tlb;

    target_phys_addr_t raddr;

    int i, ret, zsel, zpr;



    ret = -1;

    raddr = -1;

    for (i = 0; i < env->nb_tlb; i++) {

        tlb = &env->tlb[i].tlbe;

        if (ppcemb_tlb_check(env, tlb, &raddr, address,

                             env->spr[SPR_40x_PID], 0, i) < 0)

            continue;

        zsel = (tlb->attr >> 4) & 0xF;

        zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3;

#if defined (DEBUG_SOFTWARE_TLB)

        if (loglevel != 0) {

            fprintf(logfile, "%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",

                    __func__, i, zsel, zpr, rw, tlb->attr);

        }

#endif

        if (access_type == ACCESS_CODE) {

            /* Check execute enable bit */

            switch (zpr) {

            case 0x2:

                if (msr_pr)

                    goto check_exec_perm;

                goto exec_granted;

            case 0x0:

                if (msr_pr) {

                    ctx->prot = 0;

                    ret = -3;

                    break;

                }

                /* No break here */

            case 0x1:

            check_exec_perm:

                /* Check from TLB entry */

                if (!(tlb->prot & PAGE_EXEC)) {

                    ret = -3;

                } else {

                    if (tlb->prot & PAGE_WRITE) {

                        ctx->prot = PAGE_READ | PAGE_WRITE;

                    } else {

                        ctx->prot = PAGE_READ;

                    }

                    ret = 0;

                }

                break;

            case 0x3:

            exec_granted:

                /* All accesses granted */

                ctx->prot = PAGE_READ | PAGE_WRITE;

                ret = 0;

                break;

            }

        } else {

            switch (zpr) {

            case 0x2:

                if (msr_pr)

                    goto check_rw_perm;

                goto rw_granted;

            case 0x0:

                if (msr_pr) {

                    ctx->prot = 0;

                    ret = -2;

                    break;

                }

                /* No break here */

            case 0x1:

            check_rw_perm:

                /* Check from TLB entry */

                /* Check write protection bit */

                if (tlb->prot & PAGE_WRITE) {

                    ctx->prot = PAGE_READ | PAGE_WRITE;

                    ret = 0;

                } else {

                    ctx->prot = PAGE_READ;

                    if (rw)

                        ret = -2;

                    else

                        ret = 0;

                }

                break;

            case 0x3:

            rw_granted:

                /* All accesses granted */

                ctx->prot = PAGE_READ | PAGE_WRITE;

                ret = 0;

                break;

            }

        }

        if (ret >= 0) {

            ctx->raddr = raddr;

#if defined (DEBUG_SOFTWARE_TLB)

            if (loglevel != 0) {

                fprintf(logfile, "%s: access granted " ADDRX " => " REGX

                        " %d %d\n", __func__, address, ctx->raddr, ctx->prot,

                        ret);

            }

#endif

            return 0;

        }

    }

#if defined (DEBUG_SOFTWARE_TLB)

    if (loglevel != 0) {

        fprintf(logfile, "%s: access refused " ADDRX " => " REGX

                " %d %d\n", __func__, address, raddr, ctx->prot,

                ret);

    }

#endif



    return ret;

}

int mmu40x_get_physical_address (CPUState *env, mmu_ctx_t *ctx,

                                 target_ulong address, int rw, int access_type)

{

    ppcemb_tlb_t *tlb;

    target_phys_addr_t raddr;

    int i, ret, zsel, zpr;



    ret = -1;

    raddr = -1;

    for (i = 0; i < env->nb_tlb; i++) {

        tlb = &env->tlb[i].tlbe;

        if (ppcemb_tlb_check(env, tlb, &raddr, address,

                             env->spr[SPR_40x_PID], 0, i) < 0)

            continue;

        zsel = (tlb->attr >> 4) & 0xF;

        zpr = (env->spr[SPR_40x_ZPR] >> (28 - (2 * zsel))) & 0x3;

#if defined (DEBUG_SOFTWARE_TLB)

        if (loglevel != 0) {

            fprintf(logfile, "%s: TLB %d zsel %d zpr %d rw %d attr %08x\n",

                    __func__, i, zsel, zpr, rw, tlb->attr);

        }

#endif

        if (access_type == ACCESS_CODE) {

            

            switch (zpr) {

            case 0x2:

                if (msr_pr)

                    goto check_exec_perm;

                goto exec_granted;

            case 0x0:

                if (msr_pr) {

                    ctx->prot = 0;

                    ret = -3;

                    break;

                }

                

            case 0x1:

            check_exec_perm:

                

                if (!(tlb->prot & PAGE_EXEC)) {

                    ret = -3;

                } else {

                    if (tlb->prot & PAGE_WRITE) {

                        ctx->prot = PAGE_READ | PAGE_WRITE;

                    } else {

                        ctx->prot = PAGE_READ;

                    }

                    ret = 0;

                }

                break;

            case 0x3:

            exec_granted:

                

                ctx->prot = PAGE_READ | PAGE_WRITE;

                ret = 0;

                break;

            }

        } else {

            switch (zpr) {

            case 0x2:

                if (msr_pr)

                    goto check_rw_perm;

                goto rw_granted;

            case 0x0:

                if (msr_pr) {

                    ctx->prot = 0;

                    ret = -2;

                    break;

                }

                

            case 0x1:

            check_rw_perm:

                

                

                if (tlb->prot & PAGE_WRITE) {

                    ctx->prot = PAGE_READ | PAGE_WRITE;

                    ret = 0;

                } else {

                    ctx->prot = PAGE_READ;

                    if (rw)

                        ret = -2;

                    else

                        ret = 0;

                }

                break;

            case 0x3:

            rw_granted:

                

                ctx->prot = PAGE_READ | PAGE_WRITE;

                ret = 0;

                break;

            }

        }

        if (ret >= 0) {

            ctx->raddr = raddr;

#if defined (DEBUG_SOFTWARE_TLB)

            if (loglevel != 0) {

                fprintf(logfile, "%s: access granted " ADDRX " => " REGX

                        " %d %d\n", __func__, address, ctx->raddr, ctx->prot,

                        ret);

            }

#endif

            return 0;

        }

    }

#if defined (DEBUG_SOFTWARE_TLB)

    if (loglevel != 0) {

        fprintf(logfile, "%s: access refused " ADDRX " => " REGX

                " %d %d\n", __func__, address, raddr, ctx->prot,

                ret);

    }

#endif



    return ret;

}

int FUNC_0 (CPUState *VAR_0, mmu_ctx_t *VAR_1,

                                 target_ulong VAR_2, int VAR_3, int VAR_4)

{

    ppcemb_tlb_t *tlb;

    target_phys_addr_t raddr;

    int VAR_5, VAR_6, VAR_7, VAR_8;



    VAR_6 = -1;

    raddr = -1;

    for (VAR_5 = 0; VAR_5 < VAR_0->nb_tlb; VAR_5++) {

        tlb = &VAR_0->tlb[VAR_5].tlbe;

        if (ppcemb_tlb_check(VAR_0, tlb, &raddr, VAR_2,

                             VAR_0->spr[SPR_40x_PID], 0, VAR_5) < 0)

            continue;

        VAR_7 = (tlb->attr >> 4) & 0xF;

        VAR_8 = (VAR_0->spr[SPR_40x_ZPR] >> (28 - (2 * VAR_7))) & 0x3;

#if defined (DEBUG_SOFTWARE_TLB)

        if (loglevel != 0) {

            fprintf(logfile, "%s: TLB %d VAR_7 %d VAR_8 %d VAR_3 %d attr %08x\n",

                    __func__, VAR_5, VAR_7, VAR_8, VAR_3, tlb->attr);

        }

#endif

        if (VAR_4 == ACCESS_CODE) {

            

            switch (VAR_8) {

            case 0x2:

                if (msr_pr)

                    goto check_exec_perm;

                goto exec_granted;

            case 0x0:

                if (msr_pr) {

                    VAR_1->prot = 0;

                    VAR_6 = -3;

                    break;

                }

                

            case 0x1:

            check_exec_perm:

                

                if (!(tlb->prot & PAGE_EXEC)) {

                    VAR_6 = -3;

                } else {

                    if (tlb->prot & PAGE_WRITE) {

                        VAR_1->prot = PAGE_READ | PAGE_WRITE;

                    } else {

                        VAR_1->prot = PAGE_READ;

                    }

                    VAR_6 = 0;

                }

                break;

            case 0x3:

            exec_granted:

                

                VAR_1->prot = PAGE_READ | PAGE_WRITE;

                VAR_6 = 0;

                break;

            }

        } else {

            switch (VAR_8) {

            case 0x2:

                if (msr_pr)

                    goto check_rw_perm;

                goto rw_granted;

            case 0x0:

                if (msr_pr) {

                    VAR_1->prot = 0;

                    VAR_6 = -2;

                    break;

                }

                

            case 0x1:

            check_rw_perm:

                

                

                if (tlb->prot & PAGE_WRITE) {

                    VAR_1->prot = PAGE_READ | PAGE_WRITE;

                    VAR_6 = 0;

                } else {

                    VAR_1->prot = PAGE_READ;

                    if (VAR_3)

                        VAR_6 = -2;

                    else

                        VAR_6 = 0;

                }

                break;

            case 0x3:

            rw_granted:

                

                VAR_1->prot = PAGE_READ | PAGE_WRITE;

                VAR_6 = 0;

                break;

            }

        }

        if (VAR_6 >= 0) {

            VAR_1->raddr = raddr;

#if defined (DEBUG_SOFTWARE_TLB)

            if (loglevel != 0) {

                fprintf(logfile, "%s: access granted " ADDRX " => " REGX

                        " %d %d\n", __func__, VAR_2, VAR_1->raddr, VAR_1->prot,

                        VAR_6);

            }

#endif

            return 0;

        }

    }

#if defined (DEBUG_SOFTWARE_TLB)

    if (loglevel != 0) {

        fprintf(logfile, "%s: access refused " ADDRX " => " REGX

                " %d %d\n", __func__, VAR_2, raddr, VAR_1->prot,

                VAR_6);

    }

#endif



    return VAR_6;

}

int FUNC_0 (CPUState *VAR_0, mmu_ctx_t *VAR_1,
target_ulong VAR_2, int VAR_3, int VAR_4)
{ ppcemb_tlb_t *tlb; target_phys_addr_t raddr; int VAR_5, VAR_6, VAR_7, VAR_8; VAR_6 = -1; raddr = -1; for (VAR_5 = 0; VAR_5 < VAR_0->nb_tlb; VAR_5++) { tlb = &VAR_0->tlb[VAR_5].tlbe; if (ppcemb_tlb_check(VAR_0, tlb, &raddr, VAR_2,
VAR_0->spr[SPR_40x_PID], 0, VAR_5) < 0)
continue; VAR_7 = (tlb->attr >> 4) & 0xF; VAR_8 = (VAR_0->spr[SPR_40x_ZPR] >> (28 - (2 * VAR_7))) & 0x3; #if defined (DEBUG_SOFTWARE_TLB)
if (loglevel != 0) { fprintf(logfile, "%s: TLB %d VAR_7 %d VAR_8 %d VAR_3 %d attr %08x\n",
__func__, VAR_5, VAR_7, VAR_8, VAR_3, tlb->attr); } #endif
if (VAR_4 == ACCESS_CODE) { switch (VAR_8) { case 0x2:
if (msr_pr)
goto check_exec_perm; goto exec_granted; case 0x0:
if (msr_pr) { VAR_1->prot = 0; VAR_6 = -3; break; } case 0x1:
check_exec_perm:
if (!(tlb->prot & PAGE_EXEC)) { VAR_6 = -3; } else { if (tlb->prot & PAGE_WRITE) { VAR_1->prot = PAGE_READ | PAGE_WRITE; } else { VAR_1->prot = PAGE_READ; } VAR_6 = 0; } break; case 0x3:
exec_granted:
VAR_1->prot = PAGE_READ | PAGE_WRITE; VAR_6 = 0; break; } } else { switch (VAR_8) { case 0x2:
if (msr_pr)
goto check_rw_perm; goto rw_granted; case 0x0:
if (msr_pr) { VAR_1->prot = 0; VAR_6 = -2; break; } case 0x1:
check_rw_perm:
if (tlb->prot & PAGE_WRITE) { VAR_1->prot = PAGE_READ | PAGE_WRITE; VAR_6 = 0; } else { VAR_1->prot = PAGE_READ; if (VAR_3)
VAR_6 = -2; else
VAR_6 = 0; } break; case 0x3:
rw_granted:
VAR_1->prot = PAGE_READ | PAGE_WRITE; VAR_6 = 0; break; } } if (VAR_6 >= 0) { VAR_1->raddr = raddr; #if defined (DEBUG_SOFTWARE_TLB)
if (loglevel != 0) { fprintf(logfile, "%s: access granted " ADDRX " => " REGX
" %d %d\n", __func__, VAR_2, VAR_1->raddr, VAR_1->prot,
VAR_6); } #endif
return 0; } } #if defined (DEBUG_SOFTWARE_TLB)
if (loglevel != 0) { fprintf(logfile, "%s: access refused " ADDRX " => " REGX
" %d %d\n", __func__, VAR_2, raddr, VAR_1->prot,
VAR_6); } #endif
return VAR_6; }