static int get_physical_addr_mmu(CPUXtensaState *env, bool update_tlb,

        uint32_t vaddr, int is_write, int mmu_idx,

        uint32_t *paddr, uint32_t *page_size, unsigned *access,

        bool may_lookup_pt)

{

    bool dtlb = is_write != 2;

    uint32_t wi;

    uint32_t ei;

    uint8_t ring;

    uint32_t vpn;

    uint32_t pte;

    const xtensa_tlb_entry *entry = NULL;

    xtensa_tlb_entry tmp_entry;

    int ret = xtensa_tlb_lookup(env, vaddr, dtlb, &wi, &ei, &ring);



    if ((ret == INST_TLB_MISS_CAUSE || ret == LOAD_STORE_TLB_MISS_CAUSE) &&

            may_lookup_pt && get_pte(env, vaddr, &pte) == 0) {

        ring = (pte >> 4) & 0x3;

        wi = 0;

        split_tlb_entry_spec_way(env, vaddr, dtlb, &vpn, wi, &ei);



        if (update_tlb) {

            wi = ++env->autorefill_idx & 0x3;

            xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, pte);

            env->sregs[EXCVADDR] = vaddr;

            qemu_log("%s: autorefill(%08x): %08x -> %08x\n",

                    __func__, vaddr, vpn, pte);

        } else {

            xtensa_tlb_set_entry_mmu(env, &tmp_entry, dtlb, wi, ei, vpn, pte);

            entry = &tmp_entry;

        }

        ret = 0;

    }

    if (ret != 0) {

        return ret;

    }



    if (entry == NULL) {

        entry = xtensa_tlb_get_entry(env, dtlb, wi, ei);

    }



    if (ring < mmu_idx) {

        return dtlb ?

            LOAD_STORE_PRIVILEGE_CAUSE :

            INST_FETCH_PRIVILEGE_CAUSE;

    }



    *access = mmu_attr_to_access(entry->attr);

    if (!is_access_granted(*access, is_write)) {

        return dtlb ?

            (is_write ?

             STORE_PROHIBITED_CAUSE :

             LOAD_PROHIBITED_CAUSE) :

            INST_FETCH_PROHIBITED_CAUSE;

    }



    *paddr = entry->paddr | (vaddr & ~xtensa_tlb_get_addr_mask(env, dtlb, wi));

    *page_size = ~xtensa_tlb_get_addr_mask(env, dtlb, wi) + 1;



    return 0;

}

static int get_physical_addr_mmu(CPUXtensaState *env, bool update_tlb,

        uint32_t vaddr, int is_write, int mmu_idx,

        uint32_t *paddr, uint32_t *page_size, unsigned *access,

        bool may_lookup_pt)

{

    bool dtlb = is_write != 2;

    uint32_t wi;

    uint32_t ei;

    uint8_t ring;

    uint32_t vpn;

    uint32_t pte;

    const xtensa_tlb_entry *entry = NULL;

    xtensa_tlb_entry tmp_entry;

    int ret = xtensa_tlb_lookup(env, vaddr, dtlb, &wi, &ei, &ring);



    if ((ret == INST_TLB_MISS_CAUSE || ret == LOAD_STORE_TLB_MISS_CAUSE) &&

            may_lookup_pt && get_pte(env, vaddr, &pte) == 0) {

        ring = (pte >> 4) & 0x3;

        wi = 0;

        split_tlb_entry_spec_way(env, vaddr, dtlb, &vpn, wi, &ei);



        if (update_tlb) {

            wi = ++env->autorefill_idx & 0x3;

            xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, pte);

            env->sregs[EXCVADDR] = vaddr;

            qemu_log("%s: autorefill(%08x): %08x -> %08x\n",

                    __func__, vaddr, vpn, pte);

        } else {

            xtensa_tlb_set_entry_mmu(env, &tmp_entry, dtlb, wi, ei, vpn, pte);

            entry = &tmp_entry;

        }

        ret = 0;

    }

    if (ret != 0) {

        return ret;

    }



    if (entry == NULL) {

        entry = xtensa_tlb_get_entry(env, dtlb, wi, ei);

    }



    if (ring < mmu_idx) {

        return dtlb ?

            LOAD_STORE_PRIVILEGE_CAUSE :

            INST_FETCH_PRIVILEGE_CAUSE;

    }



    *access = mmu_attr_to_access(entry->attr);

    if (!is_access_granted(*access, is_write)) {

        return dtlb ?

            (is_write ?

             STORE_PROHIBITED_CAUSE :

             LOAD_PROHIBITED_CAUSE) :

            INST_FETCH_PROHIBITED_CAUSE;

    }



    *paddr = entry->paddr | (vaddr & ~xtensa_tlb_get_addr_mask(env, dtlb, wi));

    *page_size = ~xtensa_tlb_get_addr_mask(env, dtlb, wi) + 1;



    return 0;

}

static int FUNC_0(CPUXtensaState *VAR_0, bool VAR_1,

        uint32_t VAR_2, int VAR_3, int VAR_4,

        uint32_t *VAR_5, uint32_t *VAR_6, unsigned *VAR_7,

        bool VAR_8)

{

    bool dtlb = VAR_3 != 2;

    uint32_t wi;

    uint32_t ei;

    uint8_t ring;

    uint32_t vpn;

    uint32_t pte;

    const xtensa_tlb_entry *VAR_9 = NULL;

    xtensa_tlb_entry tmp_entry;

    int VAR_10 = xtensa_tlb_lookup(VAR_0, VAR_2, dtlb, &wi, &ei, &ring);



    if ((VAR_10 == INST_TLB_MISS_CAUSE || VAR_10 == LOAD_STORE_TLB_MISS_CAUSE) &&

            VAR_8 && get_pte(VAR_0, VAR_2, &pte) == 0) {

        ring = (pte >> 4) & 0x3;

        wi = 0;

        split_tlb_entry_spec_way(VAR_0, VAR_2, dtlb, &vpn, wi, &ei);



        if (VAR_1) {

            wi = ++VAR_0->autorefill_idx & 0x3;

            xtensa_tlb_set_entry(VAR_0, dtlb, wi, ei, vpn, pte);

            VAR_0->sregs[EXCVADDR] = VAR_2;

            qemu_log("%s: autorefill(%08x): %08x -> %08x\n",

                    __func__, VAR_2, vpn, pte);

        } else {

            xtensa_tlb_set_entry_mmu(VAR_0, &tmp_entry, dtlb, wi, ei, vpn, pte);

            VAR_9 = &tmp_entry;

        }

        VAR_10 = 0;

    }

    if (VAR_10 != 0) {

        return VAR_10;

    }



    if (VAR_9 == NULL) {

        VAR_9 = xtensa_tlb_get_entry(VAR_0, dtlb, wi, ei);

    }



    if (ring < VAR_4) {

        return dtlb ?

            LOAD_STORE_PRIVILEGE_CAUSE :

            INST_FETCH_PRIVILEGE_CAUSE;

    }



    *VAR_7 = mmu_attr_to_access(VAR_9->attr);

    if (!is_access_granted(*VAR_7, VAR_3)) {

        return dtlb ?

            (VAR_3 ?

             STORE_PROHIBITED_CAUSE :

             LOAD_PROHIBITED_CAUSE) :

            INST_FETCH_PROHIBITED_CAUSE;

    }



    *VAR_5 = VAR_9->VAR_5 | (VAR_2 & ~xtensa_tlb_get_addr_mask(VAR_0, dtlb, wi));

    *VAR_6 = ~xtensa_tlb_get_addr_mask(VAR_0, dtlb, wi) + 1;



    return 0;

}

static int FUNC_0(CPUXtensaState *VAR_0, bool VAR_1,
uint32_t VAR_2, int VAR_3, int VAR_4,
uint32_t *VAR_5, uint32_t *VAR_6, unsigned *VAR_7,
bool VAR_8)
{ bool dtlb = VAR_3 != 2; uint32_t wi; uint32_t ei; uint8_t ring; uint32_t vpn; uint32_t pte; const xtensa_tlb_entry *VAR_9 = NULL; xtensa_tlb_entry tmp_entry; int VAR_10 = xtensa_tlb_lookup(VAR_0, VAR_2, dtlb, &wi, &ei, &ring); if ((VAR_10 == INST_TLB_MISS_CAUSE || VAR_10 == LOAD_STORE_TLB_MISS_CAUSE) &&
VAR_8 && get_pte(VAR_0, VAR_2, &pte) == 0) { ring = (pte >> 4) & 0x3; wi = 0; split_tlb_entry_spec_way(VAR_0, VAR_2, dtlb, &vpn, wi, &ei); if (VAR_1) { wi = ++VAR_0->autorefill_idx & 0x3; xtensa_tlb_set_entry(VAR_0, dtlb, wi, ei, vpn, pte); VAR_0->sregs[EXCVADDR] = VAR_2; qemu_log("%s: autorefill(%08x): %08x -> %08x\n",
__func__, VAR_2, vpn, pte); } else { xtensa_tlb_set_entry_mmu(VAR_0, &tmp_entry, dtlb, wi, ei, vpn, pte); VAR_9 = &tmp_entry; } VAR_10 = 0; } if (VAR_10 != 0) { return VAR_10; } if (VAR_9 == NULL) { VAR_9 = xtensa_tlb_get_entry(VAR_0, dtlb, wi, ei); } if (ring < VAR_4) { return dtlb ?
LOAD_STORE_PRIVILEGE_CAUSE :
INST_FETCH_PRIVILEGE_CAUSE; } *VAR_7 = mmu_attr_to_access(VAR_9->attr); if (!is_access_granted(*VAR_7, VAR_3)) { return dtlb ?
(VAR_3 ?
STORE_PROHIBITED_CAUSE :
LOAD_PROHIBITED_CAUSE) :
INST_FETCH_PROHIBITED_CAUSE; } *VAR_5 = VAR_9->VAR_5 | (VAR_2 & ~xtensa_tlb_get_addr_mask(VAR_0, dtlb, wi)); *VAR_6 = ~xtensa_tlb_get_addr_mask(VAR_0, dtlb, wi) + 1; return 0; }