static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,

                            target_ulong opcode, target_ulong *args)

{

    CPUPPCState *env = &cpu->env;

    target_ulong flags = args[0];

    target_ulong pte_index = args[1];

    target_ulong pteh = args[2];

    target_ulong ptel = args[3];

    unsigned apshift, spshift;

    target_ulong raddr;

    target_ulong index;

    uint64_t token;



    apshift = ppc_hash64_hpte_page_shift_noslb(cpu, pteh, ptel, &spshift);

    if (!apshift) {

        /* Bad page size encoding */

        return H_PARAMETER;

    }



    raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << apshift) - 1);



    if (is_ram_address(spapr, raddr)) {

        /* Regular RAM - should have WIMG=0010 */

        if ((ptel & HPTE64_R_WIMG) != HPTE64_R_M) {

            return H_PARAMETER;

        }

    } else {

        /* Looks like an IO address */

        /* FIXME: What WIMG combinations could be sensible for IO?

         * For now we allow WIMG=010x, but are there others? */

        /* FIXME: Should we check against registered IO addresses? */

        if ((ptel & (HPTE64_R_W | HPTE64_R_I | HPTE64_R_M)) != HPTE64_R_I) {

            return H_PARAMETER;

        }

    }



    pteh &= ~0x60ULL;



    if (!valid_pte_index(env, pte_index)) {

        return H_PARAMETER;

    }



    index = 0;

    if (likely((flags & H_EXACT) == 0)) {

        pte_index &= ~7ULL;

        token = ppc_hash64_start_access(cpu, pte_index);

        for (; index < 8; index++) {

            if (!(ppc_hash64_load_hpte0(cpu, token, index) & HPTE64_V_VALID)) {

                break;

            }

        }

        ppc_hash64_stop_access(token);

        if (index == 8) {

            return H_PTEG_FULL;

        }

    } else {

        token = ppc_hash64_start_access(cpu, pte_index);

        if (ppc_hash64_load_hpte0(cpu, token, 0) & HPTE64_V_VALID) {

            ppc_hash64_stop_access(token);

            return H_PTEG_FULL;

        }

        ppc_hash64_stop_access(token);

    }



    ppc_hash64_store_hpte(cpu, pte_index + index,

                          pteh | HPTE64_V_HPTE_DIRTY, ptel);



    args[0] = pte_index + index;

    return H_SUCCESS;

}

static target_ulong h_enter(PowerPCCPU *cpu, sPAPRMachineState *spapr,

                            target_ulong opcode, target_ulong *args)

{

    CPUPPCState *env = &cpu->env;

    target_ulong flags = args[0];

    target_ulong pte_index = args[1];

    target_ulong pteh = args[2];

    target_ulong ptel = args[3];

    unsigned apshift, spshift;

    target_ulong raddr;

    target_ulong index;

    uint64_t token;



    apshift = ppc_hash64_hpte_page_shift_noslb(cpu, pteh, ptel, &spshift);

    if (!apshift) {

        

        return H_PARAMETER;

    }



    raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << apshift) - 1);



    if (is_ram_address(spapr, raddr)) {

        

        if ((ptel & HPTE64_R_WIMG) != HPTE64_R_M) {

            return H_PARAMETER;

        }

    } else {

        

        



        

        if ((ptel & (HPTE64_R_W | HPTE64_R_I | HPTE64_R_M)) != HPTE64_R_I) {

            return H_PARAMETER;

        }

    }



    pteh &= ~0x60ULL;



    if (!valid_pte_index(env, pte_index)) {

        return H_PARAMETER;

    }



    index = 0;

    if (likely((flags & H_EXACT) == 0)) {

        pte_index &= ~7ULL;

        token = ppc_hash64_start_access(cpu, pte_index);

        for (; index < 8; index++) {

            if (!(ppc_hash64_load_hpte0(cpu, token, index) & HPTE64_V_VALID)) {

                break;

            }

        }

        ppc_hash64_stop_access(token);

        if (index == 8) {

            return H_PTEG_FULL;

        }

    } else {

        token = ppc_hash64_start_access(cpu, pte_index);

        if (ppc_hash64_load_hpte0(cpu, token, 0) & HPTE64_V_VALID) {

            ppc_hash64_stop_access(token);

            return H_PTEG_FULL;

        }

        ppc_hash64_stop_access(token);

    }



    ppc_hash64_store_hpte(cpu, pte_index + index,

                          pteh | HPTE64_V_HPTE_DIRTY, ptel);



    args[0] = pte_index + index;

    return H_SUCCESS;

}

static target_ulong FUNC_0(PowerPCCPU *cpu, sPAPRMachineState *spapr,

                            target_ulong opcode, target_ulong *args)

{

    CPUPPCState *env = &cpu->env;

    target_ulong flags = args[0];

    target_ulong pte_index = args[1];

    target_ulong pteh = args[2];

    target_ulong ptel = args[3];

    unsigned VAR_0, VAR_1;

    target_ulong raddr;

    target_ulong index;

    uint64_t token;



    VAR_0 = ppc_hash64_hpte_page_shift_noslb(cpu, pteh, ptel, &VAR_1);

    if (!VAR_0) {

        

        return H_PARAMETER;

    }



    raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << VAR_0) - 1);



    if (is_ram_address(spapr, raddr)) {

        

        if ((ptel & HPTE64_R_WIMG) != HPTE64_R_M) {

            return H_PARAMETER;

        }

    } else {

        

        



        

        if ((ptel & (HPTE64_R_W | HPTE64_R_I | HPTE64_R_M)) != HPTE64_R_I) {

            return H_PARAMETER;

        }

    }



    pteh &= ~0x60ULL;



    if (!valid_pte_index(env, pte_index)) {

        return H_PARAMETER;

    }



    index = 0;

    if (likely((flags & H_EXACT) == 0)) {

        pte_index &= ~7ULL;

        token = ppc_hash64_start_access(cpu, pte_index);

        for (; index < 8; index++) {

            if (!(ppc_hash64_load_hpte0(cpu, token, index) & HPTE64_V_VALID)) {

                break;

            }

        }

        ppc_hash64_stop_access(token);

        if (index == 8) {

            return H_PTEG_FULL;

        }

    } else {

        token = ppc_hash64_start_access(cpu, pte_index);

        if (ppc_hash64_load_hpte0(cpu, token, 0) & HPTE64_V_VALID) {

            ppc_hash64_stop_access(token);

            return H_PTEG_FULL;

        }

        ppc_hash64_stop_access(token);

    }



    ppc_hash64_store_hpte(cpu, pte_index + index,

                          pteh | HPTE64_V_HPTE_DIRTY, ptel);



    args[0] = pte_index + index;

    return H_SUCCESS;

}

static target_ulong FUNC_0(PowerPCCPU *cpu, sPAPRMachineState *spapr,
target_ulong opcode, target_ulong *args)
{ CPUPPCState *env = &cpu->env; target_ulong flags = args[0]; target_ulong pte_index = args[1]; target_ulong pteh = args[2]; target_ulong ptel = args[3]; unsigned VAR_0, VAR_1; target_ulong raddr; target_ulong index; uint64_t token; VAR_0 = ppc_hash64_hpte_page_shift_noslb(cpu, pteh, ptel, &VAR_1); if (!VAR_0) { return H_PARAMETER; } raddr = (ptel & HPTE64_R_RPN) & ~((1ULL << VAR_0) - 1); if (is_ram_address(spapr, raddr)) { if ((ptel & HPTE64_R_WIMG) != HPTE64_R_M) { return H_PARAMETER; } } else { if ((ptel & (HPTE64_R_W | HPTE64_R_I | HPTE64_R_M)) != HPTE64_R_I) { return H_PARAMETER; } } pteh &= ~0x60ULL; if (!valid_pte_index(env, pte_index)) { return H_PARAMETER; } index = 0; if (likely((flags & H_EXACT) == 0)) { pte_index &= ~7ULL; token = ppc_hash64_start_access(cpu, pte_index); for (; index < 8; index++) { if (!(ppc_hash64_load_hpte0(cpu, token, index) & HPTE64_V_VALID)) { break; } } ppc_hash64_stop_access(token); if (index == 8) { return H_PTEG_FULL; } } else { token = ppc_hash64_start_access(cpu, pte_index); if (ppc_hash64_load_hpte0(cpu, token, 0) & HPTE64_V_VALID) { ppc_hash64_stop_access(token); return H_PTEG_FULL; } ppc_hash64_stop_access(token); } ppc_hash64_store_hpte(cpu, pte_index + index,
pteh | HPTE64_V_HPTE_DIRTY, ptel); args[0] = pte_index + index; return H_SUCCESS; }