static target_ulong h_protect(CPUPPCState *env, sPAPREnvironment *spapr,

                              target_ulong opcode, target_ulong *args)

{

    target_ulong flags = args[0];

    target_ulong pte_index = args[1];

    target_ulong avpn = args[2];

    uint8_t *hpte;

    target_ulong v, r, rb;



    if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {

        return H_PARAMETER;

    }



    hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);

    while (!lock_hpte(hpte, HPTE_V_HVLOCK)) {

        /* We have no real concurrency in qemu soft-emulation, so we

         * will never actually have a contested lock */

        assert(0);

    }



    v = ldq_p(hpte);

    r = ldq_p(hpte + (HASH_PTE_SIZE_64/2));



    if ((v & HPTE_V_VALID) == 0 ||

        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {

        stq_p(hpte, v & ~HPTE_V_HVLOCK);

        assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));

        return H_NOT_FOUND;

    }



    r &= ~(HPTE_R_PP0 | HPTE_R_PP | HPTE_R_N |

           HPTE_R_KEY_HI | HPTE_R_KEY_LO);

    r |= (flags << 55) & HPTE_R_PP0;

    r |= (flags << 48) & HPTE_R_KEY_HI;

    r |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO);

    rb = compute_tlbie_rb(v, r, pte_index);

    stq_p(hpte, v & ~HPTE_V_VALID);

    ppc_tlb_invalidate_one(env, rb);

    stq_p(hpte + (HASH_PTE_SIZE_64/2), r);

    /* Don't need a memory barrier, due to qemu's global lock */

    stq_p(hpte, v & ~HPTE_V_HVLOCK);

    assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));

    return H_SUCCESS;

}

static target_ulong h_protect(CPUPPCState *env, sPAPREnvironment *spapr,

                              target_ulong opcode, target_ulong *args)

{

    target_ulong flags = args[0];

    target_ulong pte_index = args[1];

    target_ulong avpn = args[2];

    uint8_t *hpte;

    target_ulong v, r, rb;



    if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {

        return H_PARAMETER;

    }



    hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);

    while (!lock_hpte(hpte, HPTE_V_HVLOCK)) {

        



        assert(0);

    }



    v = ldq_p(hpte);

    r = ldq_p(hpte + (HASH_PTE_SIZE_64/2));



    if ((v & HPTE_V_VALID) == 0 ||

        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {

        stq_p(hpte, v & ~HPTE_V_HVLOCK);

        assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));

        return H_NOT_FOUND;

    }



    r &= ~(HPTE_R_PP0 | HPTE_R_PP | HPTE_R_N |

           HPTE_R_KEY_HI | HPTE_R_KEY_LO);

    r |= (flags << 55) & HPTE_R_PP0;

    r |= (flags << 48) & HPTE_R_KEY_HI;

    r |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO);

    rb = compute_tlbie_rb(v, r, pte_index);

    stq_p(hpte, v & ~HPTE_V_VALID);

    ppc_tlb_invalidate_one(env, rb);

    stq_p(hpte + (HASH_PTE_SIZE_64/2), r);

    

    stq_p(hpte, v & ~HPTE_V_HVLOCK);

    assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));

    return H_SUCCESS;

}

    assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));     while (!lock_hpte(hpte, HPTE_V_HVLOCK)) {         assert(0);         stq_p(hpte, v & ~HPTE_V_HVLOCK);         assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));     assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));     while (!lock_hpte(hpte, HPTE_V_HVLOCK)) {         assert(0);         stq_p(hpte, v & ~HPTE_V_HVLOCK);         assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));     stq_p(hpte, v & ~HPTE_V_HVLOCK);     assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));
static target_ulong FUNC_0(CPUPPCState *env, sPAPREnvironment *spapr,

                              target_ulong opcode, target_ulong *args)

{

    target_ulong flags = args[0];

    target_ulong pte_index = args[1];

    target_ulong avpn = args[2];

    uint8_t *hpte;

    target_ulong v, r, rb;



    if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {

        return H_PARAMETER;

    }



    hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);

    while (!lock_hpte(hpte, HPTE_V_HVLOCK)) {

        



        assert(0);

    }



    v = ldq_p(hpte);

    r = ldq_p(hpte + (HASH_PTE_SIZE_64/2));



    if ((v & HPTE_V_VALID) == 0 ||

        ((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) {

        stq_p(hpte, v & ~HPTE_V_HVLOCK);

        assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));

        return H_NOT_FOUND;

    }



    r &= ~(HPTE_R_PP0 | HPTE_R_PP | HPTE_R_N |

           HPTE_R_KEY_HI | HPTE_R_KEY_LO);

    r |= (flags << 55) & HPTE_R_PP0;

    r |= (flags << 48) & HPTE_R_KEY_HI;

    r |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO);

    rb = compute_tlbie_rb(v, r, pte_index);

    stq_p(hpte, v & ~HPTE_V_VALID);

    ppc_tlb_invalidate_one(env, rb);

    stq_p(hpte + (HASH_PTE_SIZE_64/2), r);

    

    stq_p(hpte, v & ~HPTE_V_HVLOCK);

    assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));

    return H_SUCCESS;

}

static target_ulong FUNC_0(CPUPPCState *env, sPAPREnvironment *spapr,
target_ulong opcode, target_ulong *args)
{ target_ulong flags = args[0]; target_ulong pte_index = args[1]; target_ulong avpn = args[2]; uint8_t *hpte; target_ulong v, r, rb; if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) { return H_PARAMETER; } hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64); while (!lock_hpte(hpte, HPTE_V_HVLOCK)) { assert(0); } v = ldq_p(hpte); r = ldq_p(hpte + (HASH_PTE_SIZE_64/2)); if ((v & HPTE_V_VALID) == 0 ||
((flags & H_AVPN) && (v & ~0x7fULL) != avpn)) { stq_p(hpte, v & ~HPTE_V_HVLOCK); assert(!(ldq_p(hpte) & HPTE_V_HVLOCK)); return H_NOT_FOUND; } r &= ~(HPTE_R_PP0 | HPTE_R_PP | HPTE_R_N |
HPTE_R_KEY_HI | HPTE_R_KEY_LO); r |= (flags << 55) & HPTE_R_PP0; r |= (flags << 48) & HPTE_R_KEY_HI; r |= flags & (HPTE_R_PP | HPTE_R_N | HPTE_R_KEY_LO); rb = compute_tlbie_rb(v, r, pte_index); stq_p(hpte, v & ~HPTE_V_VALID); ppc_tlb_invalidate_one(env, rb); stq_p(hpte + (HASH_PTE_SIZE_64/2), r); stq_p(hpte, v & ~HPTE_V_HVLOCK); assert(!(ldq_p(hpte) & HPTE_V_HVLOCK)); return H_SUCCESS; }