moved invalidate_tlb() to helper.c as a work around for gcc 3.2.2 bug - suppressed invalid tb_invalidate_page_range() calls
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2287 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
		
							parent
							
								
									df628ff14e
								
							
						
					
					
						commit
						2ee4aed86f
					
				| @ -149,6 +149,7 @@ void dump_sc (void); | ||||
| int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, | ||||
|                                int is_user, int is_softmmu); | ||||
| void do_interrupt (CPUState *env); | ||||
| void invalidate_tlb (CPUState *env, int idx, int use_extra); | ||||
| 
 | ||||
| void cpu_loop_exit(void); | ||||
| void do_raise_exception_err (uint32_t exception, int error_code); | ||||
|  | ||||
| @ -416,3 +416,44 @@ void do_interrupt (CPUState *env) | ||||
|     env->exception_index = EXCP_NONE; | ||||
| } | ||||
| #endif /* !defined(CONFIG_USER_ONLY) */ | ||||
| 
 | ||||
| void invalidate_tlb (CPUState *env, int idx, int use_extra) | ||||
| { | ||||
|     tlb_t *tlb; | ||||
|     target_ulong addr; | ||||
|     uint8_t ASID; | ||||
| 
 | ||||
|     ASID = env->CP0_EntryHi & 0xFF; | ||||
| 
 | ||||
|     tlb = &env->tlb[idx]; | ||||
|     /* The qemu TLB is flushed then the ASID changes, so no need to
 | ||||
|        flush these entries again.  */ | ||||
|     if (tlb->G == 0 && tlb->ASID != ASID) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (use_extra && env->tlb_in_use < MIPS_TLB_MAX) { | ||||
|         /* For tlbwr, we can shadow the discarded entry into
 | ||||
| 	   a new (fake) TLB entry, as long as the guest can not | ||||
| 	   tell that it's there.  */ | ||||
|         env->tlb[env->tlb_in_use] = *tlb; | ||||
|         env->tlb_in_use++; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (tlb->V0) { | ||||
|         addr = tlb->VPN; | ||||
|         while (addr < tlb->end) { | ||||
|             tlb_flush_page (env, addr); | ||||
|             addr += TARGET_PAGE_SIZE; | ||||
|         } | ||||
|     } | ||||
|     if (tlb->V1) { | ||||
|         addr = tlb->end; | ||||
|         while (addr < tlb->end2) { | ||||
|             tlb_flush_page (env, addr); | ||||
|             addr += TARGET_PAGE_SIZE; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -376,53 +376,11 @@ void cpu_mips_tlb_flush (CPUState *env, int flush_global) | ||||
|     env->tlb_in_use = MIPS_TLB_NB; | ||||
| } | ||||
| 
 | ||||
| static void invalidate_tlb (int idx, int use_extra) | ||||
| { | ||||
|     tlb_t *tlb; | ||||
|     target_ulong addr; | ||||
|     uint8_t ASID; | ||||
| 
 | ||||
|     ASID = env->CP0_EntryHi & 0xFF; | ||||
| 
 | ||||
|     tlb = &env->tlb[idx]; | ||||
|     /* The qemu TLB is flushed then the ASID changes, so no need to
 | ||||
|        flush these entries again.  */ | ||||
|     if (tlb->G == 0 && tlb->ASID != ASID) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (use_extra && env->tlb_in_use < MIPS_TLB_MAX) { | ||||
|         /* For tlbwr, we can shadow the discarded entry into
 | ||||
| 	   a new (fake) TLB entry, as long as the guest can not | ||||
| 	   tell that it's there.  */ | ||||
|         env->tlb[env->tlb_in_use] = *tlb; | ||||
|         env->tlb_in_use++; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (tlb->V0) { | ||||
|         tb_invalidate_page_range(tlb->PFN[0], tlb->end - tlb->VPN); | ||||
|         addr = tlb->VPN; | ||||
|         while (addr < tlb->end) { | ||||
|             tlb_flush_page (env, addr); | ||||
|             addr += TARGET_PAGE_SIZE; | ||||
|         } | ||||
|     } | ||||
|     if (tlb->V1) { | ||||
|         tb_invalidate_page_range(tlb->PFN[1], tlb->end2 - tlb->end); | ||||
|         addr = tlb->end; | ||||
|         while (addr < tlb->end2) { | ||||
|             tlb_flush_page (env, addr); | ||||
|             addr += TARGET_PAGE_SIZE; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void mips_tlb_flush_extra (CPUState *env, int first) | ||||
| { | ||||
|     /* Discard entries from env->tlb[first] onwards.  */ | ||||
|     while (env->tlb_in_use > first) { | ||||
|         invalidate_tlb(--env->tlb_in_use, 0); | ||||
|         invalidate_tlb(env, --env->tlb_in_use, 0); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -459,7 +417,7 @@ void do_tlbwi (void) | ||||
| 
 | ||||
|     /* Wildly undefined effects for CP0_index containing a too high value and
 | ||||
|        MIPS_TLB_NB not being a power of two.  But so does real silicon.  */ | ||||
|     invalidate_tlb(env->CP0_index & (MIPS_TLB_NB - 1), 0); | ||||
|     invalidate_tlb(env, env->CP0_index & (MIPS_TLB_NB - 1), 0); | ||||
|     fill_tlb(env->CP0_index & (MIPS_TLB_NB - 1)); | ||||
| } | ||||
| 
 | ||||
| @ -467,7 +425,7 @@ void do_tlbwr (void) | ||||
| { | ||||
|     int r = cpu_mips_get_random(env); | ||||
| 
 | ||||
|     invalidate_tlb(r, 1); | ||||
|     invalidate_tlb(env, r, 1); | ||||
|     fill_tlb(r); | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 bellard
						bellard