avoid using physical accesses in user emulation
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1592 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									74c33bed31
								
							
						
					
					
						commit
						24741ef3de
					
				
							
								
								
									
										14
									
								
								exec.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								exec.c
									
									
									
									
									
								
							| @ -2152,20 +2152,6 @@ void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /* never used */ | ||||
| uint32_t ldl_phys(target_phys_addr_t addr) | ||||
| { | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| void stl_phys_notdirty(target_phys_addr_t addr, uint32_t val) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void stl_phys(target_phys_addr_t addr, uint32_t val) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| #else | ||||
| void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf,  | ||||
|                             int len, int is_write) | ||||
|  | ||||
| @ -36,6 +36,32 @@ | ||||
| /*****************************************************************************/ | ||||
| /* PowerPC MMU emulation */ | ||||
| 
 | ||||
| #if defined(CONFIG_USER_ONLY)  | ||||
| int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, | ||||
|                               int is_user, int is_softmmu) | ||||
| { | ||||
|     int exception, error_code; | ||||
|      | ||||
|     if (rw == 2) { | ||||
|         exception = EXCP_ISI; | ||||
|         error_code = 0; | ||||
|     } else { | ||||
|         exception = EXCP_DSI; | ||||
|         error_code = 0; | ||||
|         if (rw) | ||||
|             error_code |= 0x02000000; | ||||
|         env->spr[SPR_DAR] = address; | ||||
|         env->spr[SPR_DSISR] = error_code; | ||||
|     } | ||||
|     env->exception_index = exception; | ||||
|     env->error_code = error_code; | ||||
|     return 1; | ||||
| } | ||||
| target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) | ||||
| { | ||||
|     return addr; | ||||
| } | ||||
| #else | ||||
| /* Perform BAT hit & translation */ | ||||
| static int get_bat (CPUState *env, uint32_t *real, int *prot, | ||||
|                     uint32_t virtual, int rw, int type) | ||||
| @ -355,8 +381,8 @@ static int get_segment (CPUState *env, uint32_t *real, int *prot, | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| int get_physical_address (CPUState *env, uint32_t *physical, int *prot, | ||||
|                           uint32_t address, int rw, int access_type) | ||||
| static int get_physical_address (CPUState *env, uint32_t *physical, int *prot, | ||||
|                                  uint32_t address, int rw, int access_type) | ||||
| { | ||||
|     int ret; | ||||
| #if 0 | ||||
| @ -387,12 +413,6 @@ int get_physical_address (CPUState *env, uint32_t *physical, int *prot, | ||||
|     return ret; | ||||
| } | ||||
| 
 | ||||
| #if defined(CONFIG_USER_ONLY)  | ||||
| target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) | ||||
| { | ||||
|     return addr; | ||||
| } | ||||
| #else | ||||
| target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) | ||||
| { | ||||
|     uint32_t phys_addr; | ||||
| @ -402,7 +422,6 @@ target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) | ||||
|         return -1; | ||||
|     return phys_addr; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| /* Perform address translation */ | ||||
| int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, | ||||
| @ -523,6 +542,7 @@ int cpu_ppc_handle_mmu_fault (CPUState *env, uint32_t address, int rw, | ||||
|     } | ||||
|     return ret; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| /*****************************************************************************/ | ||||
| /* BATs management */ | ||||
|  | ||||
| @ -230,7 +230,107 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | ||||
|         return 1; | ||||
|     } | ||||
| } | ||||
| #else | ||||
| 
 | ||||
| target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev) | ||||
| { | ||||
|     target_phys_addr_t pde_ptr; | ||||
|     uint32_t pde; | ||||
| 
 | ||||
|     /* Context base + context number */ | ||||
|     pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2); | ||||
|     pde = ldl_phys(pde_ptr); | ||||
| 
 | ||||
|     switch (pde & PTE_ENTRYTYPE_MASK) { | ||||
|     default: | ||||
|     case 0: /* Invalid */ | ||||
|     case 2: /* PTE, maybe should not happen? */ | ||||
|     case 3: /* Reserved */ | ||||
| 	return 0; | ||||
|     case 1: /* L1 PDE */ | ||||
| 	if (mmulev == 3) | ||||
| 	    return pde; | ||||
| 	pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4); | ||||
|         pde = ldl_phys(pde_ptr); | ||||
| 
 | ||||
| 	switch (pde & PTE_ENTRYTYPE_MASK) { | ||||
| 	default: | ||||
| 	case 0: /* Invalid */ | ||||
| 	case 3: /* Reserved */ | ||||
| 	    return 0; | ||||
| 	case 2: /* L1 PTE */ | ||||
| 	    return pde; | ||||
| 	case 1: /* L2 PDE */ | ||||
| 	    if (mmulev == 2) | ||||
| 		return pde; | ||||
| 	    pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4); | ||||
|             pde = ldl_phys(pde_ptr); | ||||
| 
 | ||||
| 	    switch (pde & PTE_ENTRYTYPE_MASK) { | ||||
| 	    default: | ||||
| 	    case 0: /* Invalid */ | ||||
| 	    case 3: /* Reserved */ | ||||
| 		return 0; | ||||
| 	    case 2: /* L2 PTE */ | ||||
| 		return pde; | ||||
| 	    case 1: /* L3 PDE */ | ||||
| 		if (mmulev == 1) | ||||
| 		    return pde; | ||||
| 		pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4); | ||||
|                 pde = ldl_phys(pde_ptr); | ||||
| 
 | ||||
| 		switch (pde & PTE_ENTRYTYPE_MASK) { | ||||
| 		default: | ||||
| 		case 0: /* Invalid */ | ||||
| 		case 1: /* PDE, should not happen */ | ||||
| 		case 3: /* Reserved */ | ||||
| 		    return 0; | ||||
| 		case 2: /* L3 PTE */ | ||||
| 		    return pde; | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| #ifdef DEBUG_MMU | ||||
| void dump_mmu(CPUState *env) | ||||
| { | ||||
|      target_ulong va, va1, va2; | ||||
|      unsigned int n, m, o; | ||||
|      target_phys_addr_t pde_ptr, pa; | ||||
|     uint32_t pde; | ||||
| 
 | ||||
|     printf("MMU dump:\n"); | ||||
|     pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2); | ||||
|     pde = ldl_phys(pde_ptr); | ||||
|     printf("Root ptr: " TARGET_FMT_lx ", ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]); | ||||
|     for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) { | ||||
| 	pde_ptr = mmu_probe(env, va, 2); | ||||
| 	if (pde_ptr) { | ||||
| 	    pa = cpu_get_phys_page_debug(env, va); | ||||
|  	    printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va, pa, pde_ptr); | ||||
| 	    for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) { | ||||
| 		pde_ptr = mmu_probe(env, va1, 1); | ||||
| 		if (pde_ptr) { | ||||
| 		    pa = cpu_get_phys_page_debug(env, va1); | ||||
|  		    printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va1, pa, pde_ptr); | ||||
| 		    for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) { | ||||
| 			pde_ptr = mmu_probe(env, va2, 0); | ||||
| 			if (pde_ptr) { | ||||
| 			    pa = cpu_get_phys_page_debug(env, va2); | ||||
|  			    printf("  VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PTE: " TARGET_FMT_lx "\n", va2, pa, pde_ptr); | ||||
| 			} | ||||
| 		    } | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|     printf("MMU dump ends\n"); | ||||
| } | ||||
| #endif /* DEBUG_MMU */ | ||||
| 
 | ||||
| #else /* !TARGET_SPARC64 */ | ||||
| /*
 | ||||
|  * UltraSparc IIi I/DMMUs | ||||
|  */ | ||||
| @ -382,121 +482,6 @@ int cpu_sparc_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | ||||
|     return 1; | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| #endif | ||||
| 
 | ||||
| void memcpy32(target_ulong *dst, const target_ulong *src) | ||||
| { | ||||
|     dst[0] = src[0]; | ||||
|     dst[1] = src[1]; | ||||
|     dst[2] = src[2]; | ||||
|     dst[3] = src[3]; | ||||
|     dst[4] = src[4]; | ||||
|     dst[5] = src[5]; | ||||
|     dst[6] = src[6]; | ||||
|     dst[7] = src[7]; | ||||
| } | ||||
| 
 | ||||
| #if !defined(TARGET_SPARC64) | ||||
| target_ulong mmu_probe(CPUState *env, target_ulong address, int mmulev) | ||||
| { | ||||
|     target_phys_addr_t pde_ptr; | ||||
|     uint32_t pde; | ||||
| 
 | ||||
|     /* Context base + context number */ | ||||
|     pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2); | ||||
|     pde = ldl_phys(pde_ptr); | ||||
| 
 | ||||
|     switch (pde & PTE_ENTRYTYPE_MASK) { | ||||
|     default: | ||||
|     case 0: /* Invalid */ | ||||
|     case 2: /* PTE, maybe should not happen? */ | ||||
|     case 3: /* Reserved */ | ||||
| 	return 0; | ||||
|     case 1: /* L1 PDE */ | ||||
| 	if (mmulev == 3) | ||||
| 	    return pde; | ||||
| 	pde_ptr = ((address >> 22) & ~3) + ((pde & ~3) << 4); | ||||
|         pde = ldl_phys(pde_ptr); | ||||
| 
 | ||||
| 	switch (pde & PTE_ENTRYTYPE_MASK) { | ||||
| 	default: | ||||
| 	case 0: /* Invalid */ | ||||
| 	case 3: /* Reserved */ | ||||
| 	    return 0; | ||||
| 	case 2: /* L1 PTE */ | ||||
| 	    return pde; | ||||
| 	case 1: /* L2 PDE */ | ||||
| 	    if (mmulev == 2) | ||||
| 		return pde; | ||||
| 	    pde_ptr = ((address & 0xfc0000) >> 16) + ((pde & ~3) << 4); | ||||
|             pde = ldl_phys(pde_ptr); | ||||
| 
 | ||||
| 	    switch (pde & PTE_ENTRYTYPE_MASK) { | ||||
| 	    default: | ||||
| 	    case 0: /* Invalid */ | ||||
| 	    case 3: /* Reserved */ | ||||
| 		return 0; | ||||
| 	    case 2: /* L2 PTE */ | ||||
| 		return pde; | ||||
| 	    case 1: /* L3 PDE */ | ||||
| 		if (mmulev == 1) | ||||
| 		    return pde; | ||||
| 		pde_ptr = ((address & 0x3f000) >> 10) + ((pde & ~3) << 4); | ||||
|                 pde = ldl_phys(pde_ptr); | ||||
| 
 | ||||
| 		switch (pde & PTE_ENTRYTYPE_MASK) { | ||||
| 		default: | ||||
| 		case 0: /* Invalid */ | ||||
| 		case 1: /* PDE, should not happen */ | ||||
| 		case 3: /* Reserved */ | ||||
| 		    return 0; | ||||
| 		case 2: /* L3 PTE */ | ||||
| 		    return pde; | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
| #ifdef DEBUG_MMU | ||||
| void dump_mmu(CPUState *env) | ||||
| { | ||||
|      target_ulong va, va1, va2; | ||||
|      unsigned int n, m, o; | ||||
|      target_phys_addr_t pde_ptr, pa; | ||||
|     uint32_t pde; | ||||
| 
 | ||||
|     printf("MMU dump:\n"); | ||||
|     pde_ptr = (env->mmuregs[1] << 4) + (env->mmuregs[2] << 2); | ||||
|     pde = ldl_phys(pde_ptr); | ||||
|     printf("Root ptr: " TARGET_FMT_lx ", ctx: %d\n", env->mmuregs[1] << 4, env->mmuregs[2]); | ||||
|     for (n = 0, va = 0; n < 256; n++, va += 16 * 1024 * 1024) { | ||||
| 	pde_ptr = mmu_probe(env, va, 2); | ||||
| 	if (pde_ptr) { | ||||
| 	    pa = cpu_get_phys_page_debug(env, va); | ||||
|  	    printf("VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va, pa, pde_ptr); | ||||
| 	    for (m = 0, va1 = va; m < 64; m++, va1 += 256 * 1024) { | ||||
| 		pde_ptr = mmu_probe(env, va1, 1); | ||||
| 		if (pde_ptr) { | ||||
| 		    pa = cpu_get_phys_page_debug(env, va1); | ||||
|  		    printf(" VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PDE: " TARGET_FMT_lx "\n", va1, pa, pde_ptr); | ||||
| 		    for (o = 0, va2 = va1; o < 64; o++, va2 += 4 * 1024) { | ||||
| 			pde_ptr = mmu_probe(env, va2, 0); | ||||
| 			if (pde_ptr) { | ||||
| 			    pa = cpu_get_phys_page_debug(env, va2); | ||||
|  			    printf("  VA: " TARGET_FMT_lx ", PA: " TARGET_FMT_lx " PTE: " TARGET_FMT_lx "\n", va2, pa, pde_ptr); | ||||
| 			} | ||||
| 		    } | ||||
| 		} | ||||
| 	    } | ||||
| 	} | ||||
|     } | ||||
|     printf("MMU dump ends\n"); | ||||
| } | ||||
| #endif | ||||
| #else | ||||
| #ifdef DEBUG_MMU | ||||
| void dump_mmu(CPUState *env) | ||||
| { | ||||
| @ -568,5 +553,19 @@ void dump_mmu(CPUState *env) | ||||
| 	} | ||||
|     } | ||||
| } | ||||
| #endif | ||||
| #endif | ||||
| #endif /* DEBUG_MMU */ | ||||
| 
 | ||||
| #endif /* TARGET_SPARC64 */ | ||||
| #endif /* !CONFIG_USER_ONLY */ | ||||
| 
 | ||||
| void memcpy32(target_ulong *dst, const target_ulong *src) | ||||
| { | ||||
|     dst[0] = src[0]; | ||||
|     dst[1] = src[1]; | ||||
|     dst[2] = src[2]; | ||||
|     dst[3] = src[3]; | ||||
|     dst[4] = src[4]; | ||||
|     dst[5] = src[5]; | ||||
|     dst[6] = src[6]; | ||||
|     dst[7] = src[7]; | ||||
| } | ||||
|  | ||||
| @ -221,6 +221,15 @@ void do_fcmpd_fcc3 (void) | ||||
| #undef FS | ||||
| #endif | ||||
| 
 | ||||
| #if defined(CONFIG_USER_ONLY)  | ||||
| void helper_ld_asi(int asi, int size, int sign) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| void helper_st_asi(int asi, int size, int sign) | ||||
| { | ||||
| } | ||||
| #else | ||||
| #ifndef TARGET_SPARC64 | ||||
| void helper_ld_asi(int asi, int size, int sign) | ||||
| { | ||||
| @ -727,8 +736,8 @@ void helper_st_asi(int asi, int size, int sign) | ||||
| 	return; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| #endif | ||||
| #endif /* !CONFIG_USER_ONLY */ | ||||
| 
 | ||||
| #ifndef TARGET_SPARC64 | ||||
| void helper_rett() | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 bellard
						bellard