int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,

                              int is_user, int is_softmmu)

{

    int exception = 0;

    int access_type, access_perms = 0, access_index = 0;

    uint8_t *pde_ptr;

    uint32_t pde, virt_addr;

    int error_code = 0, is_dirty, prot, ret = 0;

    unsigned long paddr, vaddr, page_offset;



    access_type = env->access_type;

    if (env->user_mode_only) {

        /* user mode only emulation */

        ret = -2;

        goto do_fault;

    }



    virt_addr = address & TARGET_PAGE_MASK;

    if ((env->mmuregs[0] & MMU_E) == 0) { /* MMU disabled */

	paddr = address;

	page_offset = address & (TARGET_PAGE_SIZE - 1);

        prot = PAGE_READ | PAGE_WRITE;

        goto do_mapping;

    }



    /* SPARC reference MMU table walk: Context table->L1->L2->PTE */

    /* Context base + context number */

    pde_ptr = phys_ram_base + (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4);

    env->access_type = ACCESS_MMU;

    pde = ldl_raw(pde_ptr);



    /* Ctx pde */

    switch (pde & PTE_ENTRYTYPE_MASK) {

    case 0: /* Invalid */

        error_code = 1;

        goto do_fault;

    case 2: /* PTE, maybe should not happen? */

    case 3: /* Reserved */

        error_code = 4;

        goto do_fault;

    case 1: /* L1 PDE */

	pde_ptr = phys_ram_base + ((address >> 22) & ~3) + ((pde & ~3) << 4);

	pde = ldl_raw(pde_ptr);



	switch (pde & PTE_ENTRYTYPE_MASK) {

	case 0: /* Invalid */

	    error_code = 1;

	    goto do_fault;

	case 3: /* Reserved */

	    error_code = 4;

	    goto do_fault;

	case 1: /* L2 PDE */

	    pde_ptr = phys_ram_base + ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);

	    pde = ldl_raw(pde_ptr);



	    switch (pde & PTE_ENTRYTYPE_MASK) {

	    case 0: /* Invalid */

		error_code = 1;

		goto do_fault;

	    case 3: /* Reserved */

		error_code = 4;

		goto do_fault;

	    case 1: /* L3 PDE */

		pde_ptr = phys_ram_base + ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);

		pde = ldl_raw(pde_ptr);



		switch (pde & PTE_ENTRYTYPE_MASK) {

		case 0: /* Invalid */

		    error_code = 1;

		    goto do_fault;

		case 1: /* PDE, should not happen */

		case 3: /* Reserved */

		    error_code = 4;

		    goto do_fault;

		case 2: /* L3 PTE */

		    virt_addr = address & TARGET_PAGE_MASK;

		    page_offset = (address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1);

		}

		break;

	    case 2: /* L2 PTE */

		virt_addr = address & ~0x3ffff;

		page_offset = address & 0x3ffff;

	    }

	    break;

	case 2: /* L1 PTE */

	    virt_addr = address & ~0xffffff;

	    page_offset = address & 0xffffff;

	}

    }



    /* update page modified and dirty bits */

    is_dirty = rw && !(pde & PG_MODIFIED_MASK);

    if (!(pde & PG_ACCESSED_MASK) || is_dirty) {

	pde |= PG_ACCESSED_MASK;

	if (is_dirty)

	    pde |= PG_MODIFIED_MASK;

	stl_raw(pde_ptr, pde);

    }



    /* check access */

    access_index = (rw << 2) | ((access_type == ACCESS_CODE)? 2 : 0) | (is_user? 0 : 1);

    access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;

    error_code = access_table[access_index][access_perms];

    if (error_code)

	goto do_fault;



    /* the page can be put in the TLB */

    prot = PAGE_READ;

    if (pde & PG_MODIFIED_MASK) {

        /* only set write access if already dirty... otherwise wait

           for dirty access */

	if (rw_table[is_user][access_perms])

	        prot |= PAGE_WRITE;

    }



    /* Even if large ptes, we map only one 4KB page in the cache to

       avoid filling it too fast */

    virt_addr = address & TARGET_PAGE_MASK;

    paddr = ((pde & PTE_ADDR_MASK) << 4) + page_offset;



 do_mapping:

    env->access_type = access_type;

    vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));



    ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);

    return ret;



 do_fault:

    env->access_type = access_type;

    if (env->mmuregs[3]) /* Fault status register */

	env->mmuregs[3] = 1; /* overflow (not read before another fault) */

    env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2;

    env->mmuregs[4] = address; /* Fault address register */



    if (env->mmuregs[0] & MMU_NF) // No fault

	return 0;



    env->exception_index = exception;

    env->error_code = error_code;

    return error_code;

}

int cpu_sparc_handle_mmu_fault (CPUState *env, uint32_t address, int rw,

                              int is_user, int is_softmmu)

{

    int exception = 0;

    int access_type, access_perms = 0, access_index = 0;

    uint8_t *pde_ptr;

    uint32_t pde, virt_addr;

    int error_code = 0, is_dirty, prot, ret = 0;

    unsigned long paddr, vaddr, page_offset;



    access_type = env->access_type;

    if (env->user_mode_only) {

        

        ret = -2;

        goto do_fault;

    }



    virt_addr = address & TARGET_PAGE_MASK;

    if ((env->mmuregs[0] & MMU_E) == 0) { 

	paddr = address;

	page_offset = address & (TARGET_PAGE_SIZE - 1);

        prot = PAGE_READ | PAGE_WRITE;

        goto do_mapping;

    }



    

    

    pde_ptr = phys_ram_base + (env->mmuregs[1] << 4) + (env->mmuregs[2] << 4);

    env->access_type = ACCESS_MMU;

    pde = ldl_raw(pde_ptr);



    

    switch (pde & PTE_ENTRYTYPE_MASK) {

    case 0: 

        error_code = 1;

        goto do_fault;

    case 2: 

    case 3: 

        error_code = 4;

        goto do_fault;

    case 1: 

	pde_ptr = phys_ram_base + ((address >> 22) & ~3) + ((pde & ~3) << 4);

	pde = ldl_raw(pde_ptr);



	switch (pde & PTE_ENTRYTYPE_MASK) {

	case 0: 

	    error_code = 1;

	    goto do_fault;

	case 3: 

	    error_code = 4;

	    goto do_fault;

	case 1: 

	    pde_ptr = phys_ram_base + ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4);

	    pde = ldl_raw(pde_ptr);



	    switch (pde & PTE_ENTRYTYPE_MASK) {

	    case 0: 

		error_code = 1;

		goto do_fault;

	    case 3: 

		error_code = 4;

		goto do_fault;

	    case 1: 

		pde_ptr = phys_ram_base + ((address & 0x3f000) >> 10) + ((pde & ~3) << 4);

		pde = ldl_raw(pde_ptr);



		switch (pde & PTE_ENTRYTYPE_MASK) {

		case 0: 

		    error_code = 1;

		    goto do_fault;

		case 1: 

		case 3: 

		    error_code = 4;

		    goto do_fault;

		case 2: 

		    virt_addr = address & TARGET_PAGE_MASK;

		    page_offset = (address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1);

		}

		break;

	    case 2: 

		virt_addr = address & ~0x3ffff;

		page_offset = address & 0x3ffff;

	    }

	    break;

	case 2: 

	    virt_addr = address & ~0xffffff;

	    page_offset = address & 0xffffff;

	}

    }



    

    is_dirty = rw && !(pde & PG_MODIFIED_MASK);

    if (!(pde & PG_ACCESSED_MASK) || is_dirty) {

	pde |= PG_ACCESSED_MASK;

	if (is_dirty)

	    pde |= PG_MODIFIED_MASK;

	stl_raw(pde_ptr, pde);

    }



    

    access_index = (rw << 2) | ((access_type == ACCESS_CODE)? 2 : 0) | (is_user? 0 : 1);

    access_perms = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;

    error_code = access_table[access_index][access_perms];

    if (error_code)

	goto do_fault;



    

    prot = PAGE_READ;

    if (pde & PG_MODIFIED_MASK) {

        



	if (rw_table[is_user][access_perms])

	        prot |= PAGE_WRITE;

    }



    



    virt_addr = address & TARGET_PAGE_MASK;

    paddr = ((pde & PTE_ADDR_MASK) << 4) + page_offset;



 do_mapping:

    env->access_type = access_type;

    vaddr = virt_addr + ((address & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));



    ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu);

    return ret;



 do_fault:

    env->access_type = access_type;

    if (env->mmuregs[3]) 

	env->mmuregs[3] = 1; 

    env->mmuregs[3] |= (access_index << 5) | (error_code << 2) | 2;

    env->mmuregs[4] = address; 



    if (env->mmuregs[0] & MMU_NF) 

	return 0;



    env->exception_index = exception;

    env->error_code = error_code;

    return error_code;

}

int FUNC_0 (CPUState *VAR_0, uint32_t VAR_1, int VAR_2,

                              int VAR_3, int VAR_4)

{

    int VAR_5 = 0;

    int VAR_6, VAR_7 = 0, VAR_8 = 0;

    uint8_t *pde_ptr;

    uint32_t pde, virt_addr;

    int VAR_9 = 0, VAR_10, VAR_11, VAR_12 = 0;

    unsigned long VAR_13, VAR_14, VAR_15;



    VAR_6 = VAR_0->VAR_6;

    if (VAR_0->user_mode_only) {

        

        VAR_12 = -2;

        goto do_fault;

    }



    virt_addr = VAR_1 & TARGET_PAGE_MASK;

    if ((VAR_0->mmuregs[0] & MMU_E) == 0) { 

	VAR_13 = VAR_1;

	VAR_15 = VAR_1 & (TARGET_PAGE_SIZE - 1);

        VAR_11 = PAGE_READ | PAGE_WRITE;

        goto do_mapping;

    }



    

    

    pde_ptr = phys_ram_base + (VAR_0->mmuregs[1] << 4) + (VAR_0->mmuregs[2] << 4);

    VAR_0->VAR_6 = ACCESS_MMU;

    pde = ldl_raw(pde_ptr);



    

    switch (pde & PTE_ENTRYTYPE_MASK) {

    case 0: 

        VAR_9 = 1;

        goto do_fault;

    case 2: 

    case 3: 

        VAR_9 = 4;

        goto do_fault;

    case 1: 

	pde_ptr = phys_ram_base + ((VAR_1 >> 22) & ~3) + ((pde & ~3) << 4);

	pde = ldl_raw(pde_ptr);



	switch (pde & PTE_ENTRYTYPE_MASK) {

	case 0: 

	    VAR_9 = 1;

	    goto do_fault;

	case 3: 

	    VAR_9 = 4;

	    goto do_fault;

	case 1: 

	    pde_ptr = phys_ram_base + ((VAR_1 & 0xfc0000) >> 16) + ((pde & ~3) << 4);

	    pde = ldl_raw(pde_ptr);



	    switch (pde & PTE_ENTRYTYPE_MASK) {

	    case 0: 

		VAR_9 = 1;

		goto do_fault;

	    case 3: 

		VAR_9 = 4;

		goto do_fault;

	    case 1: 

		pde_ptr = phys_ram_base + ((VAR_1 & 0x3f000) >> 10) + ((pde & ~3) << 4);

		pde = ldl_raw(pde_ptr);



		switch (pde & PTE_ENTRYTYPE_MASK) {

		case 0: 

		    VAR_9 = 1;

		    goto do_fault;

		case 1: 

		case 3: 

		    VAR_9 = 4;

		    goto do_fault;

		case 2: 

		    virt_addr = VAR_1 & TARGET_PAGE_MASK;

		    VAR_15 = (VAR_1 & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1);

		}

		break;

	    case 2: 

		virt_addr = VAR_1 & ~0x3ffff;

		VAR_15 = VAR_1 & 0x3ffff;

	    }

	    break;

	case 2: 

	    virt_addr = VAR_1 & ~0xffffff;

	    VAR_15 = VAR_1 & 0xffffff;

	}

    }



    

    VAR_10 = VAR_2 && !(pde & PG_MODIFIED_MASK);

    if (!(pde & PG_ACCESSED_MASK) || VAR_10) {

	pde |= PG_ACCESSED_MASK;

	if (VAR_10)

	    pde |= PG_MODIFIED_MASK;

	stl_raw(pde_ptr, pde);

    }



    

    VAR_8 = (VAR_2 << 2) | ((VAR_6 == ACCESS_CODE)? 2 : 0) | (VAR_3? 0 : 1);

    VAR_7 = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT;

    VAR_9 = access_table[VAR_8][VAR_7];

    if (VAR_9)

	goto do_fault;



    

    VAR_11 = PAGE_READ;

    if (pde & PG_MODIFIED_MASK) {

        



	if (rw_table[VAR_3][VAR_7])

	        VAR_11 |= PAGE_WRITE;

    }



    



    virt_addr = VAR_1 & TARGET_PAGE_MASK;

    VAR_13 = ((pde & PTE_ADDR_MASK) << 4) + VAR_15;



 do_mapping:

    VAR_0->VAR_6 = VAR_6;

    VAR_14 = virt_addr + ((VAR_1 & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1));



    VAR_12 = tlb_set_page(VAR_0, VAR_14, VAR_13, VAR_11, VAR_3, VAR_4);

    return VAR_12;



 do_fault:

    VAR_0->VAR_6 = VAR_6;

    if (VAR_0->mmuregs[3]) 

	VAR_0->mmuregs[3] = 1; 

    VAR_0->mmuregs[3] |= (VAR_8 << 5) | (VAR_9 << 2) | 2;

    VAR_0->mmuregs[4] = VAR_1; 



    if (VAR_0->mmuregs[0] & MMU_NF) 

	return 0;



    VAR_0->exception_index = VAR_5;

    VAR_0->VAR_9 = VAR_9;

    return VAR_9;

}

int FUNC_0 (CPUState *VAR_0, uint32_t VAR_1, int VAR_2,
int VAR_3, int VAR_4)
{ int VAR_5 = 0; int VAR_6, VAR_7 = 0, VAR_8 = 0; uint8_t *pde_ptr; uint32_t pde, virt_addr; int VAR_9 = 0, VAR_10, VAR_11, VAR_12 = 0; unsigned long VAR_13, VAR_14, VAR_15; VAR_6 = VAR_0->VAR_6; if (VAR_0->user_mode_only) { VAR_12 = -2; goto do_fault; } virt_addr = VAR_1 & TARGET_PAGE_MASK; if ((VAR_0->mmuregs[0] & MMU_E) == 0) { VAR_13 = VAR_1; VAR_15 = VAR_1 & (TARGET_PAGE_SIZE - 1); VAR_11 = PAGE_READ | PAGE_WRITE; goto do_mapping; } pde_ptr = phys_ram_base + (VAR_0->mmuregs[1] << 4) + (VAR_0->mmuregs[2] << 4); VAR_0->VAR_6 = ACCESS_MMU; pde = ldl_raw(pde_ptr); switch (pde & PTE_ENTRYTYPE_MASK) { case 0:
VAR_9 = 1; goto do_fault; case 2:
case 3:
VAR_9 = 4; goto do_fault; case 1:
pde_ptr = phys_ram_base + ((VAR_1 >> 22) & ~3) + ((pde & ~3) << 4); pde = ldl_raw(pde_ptr); switch (pde & PTE_ENTRYTYPE_MASK) { case 0:
VAR_9 = 1; goto do_fault; case 3:
VAR_9 = 4; goto do_fault; case 1:
pde_ptr = phys_ram_base + ((VAR_1 & 0xfc0000) >> 16) + ((pde & ~3) << 4); pde = ldl_raw(pde_ptr); switch (pde & PTE_ENTRYTYPE_MASK) { case 0:
VAR_9 = 1; goto do_fault; case 3:
VAR_9 = 4; goto do_fault; case 1:
pde_ptr = phys_ram_base + ((VAR_1 & 0x3f000) >> 10) + ((pde & ~3) << 4); pde = ldl_raw(pde_ptr); switch (pde & PTE_ENTRYTYPE_MASK) { case 0:
VAR_9 = 1; goto do_fault; case 1:
case 3:
VAR_9 = 4; goto do_fault; case 2:
virt_addr = VAR_1 & TARGET_PAGE_MASK; VAR_15 = (VAR_1 & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1); } break; case 2:
virt_addr = VAR_1 & ~0x3ffff; VAR_15 = VAR_1 & 0x3ffff; } break; case 2:
virt_addr = VAR_1 & ~0xffffff; VAR_15 = VAR_1 & 0xffffff; } } VAR_10 = VAR_2 && !(pde & PG_MODIFIED_MASK); if (!(pde & PG_ACCESSED_MASK) || VAR_10) { pde |= PG_ACCESSED_MASK; if (VAR_10)
pde |= PG_MODIFIED_MASK; stl_raw(pde_ptr, pde); } VAR_8 = (VAR_2 << 2) | ((VAR_6 == ACCESS_CODE)? 2 : 0) | (VAR_3? 0 : 1); VAR_7 = (pde & PTE_ACCESS_MASK) >> PTE_ACCESS_SHIFT; VAR_9 = access_table[VAR_8][VAR_7]; if (VAR_9)
goto do_fault; VAR_11 = PAGE_READ; if (pde & PG_MODIFIED_MASK) { if (rw_table[VAR_3][VAR_7])
VAR_11 |= PAGE_WRITE; } virt_addr = VAR_1 & TARGET_PAGE_MASK; VAR_13 = ((pde & PTE_ADDR_MASK) << 4) + VAR_15; do_mapping:
VAR_0->VAR_6 = VAR_6; VAR_14 = virt_addr + ((VAR_1 & TARGET_PAGE_MASK) & (TARGET_PAGE_SIZE - 1)); VAR_12 = tlb_set_page(VAR_0, VAR_14, VAR_13, VAR_11, VAR_3, VAR_4); return VAR_12; do_fault:
VAR_0->VAR_6 = VAR_6; if (VAR_0->mmuregs[3])
VAR_0->mmuregs[3] = 1; VAR_0->mmuregs[3] |= (VAR_8 << 5) | (VAR_9 << 2) | 2; VAR_0->mmuregs[4] = VAR_1; if (VAR_0->mmuregs[0] & MMU_NF)
return 0; VAR_0->exception_index = VAR_5; VAR_0->VAR_9 = VAR_9; return VAR_9; }