Commit 2ee4aed86ff2ba38a0e1846de18a9aec38d73015

Authored by bellard
1 parent df628ff1

moved invalidate_tlb() to helper.c as a work around for gcc 3.2.2 bug - suppress…

…ed invalid tb_invalidate_page_range() calls


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2287 c046a42c-6fe2-441c-8c8c-71466251a162
target-mips/exec.h
@@ -149,6 +149,7 @@ void dump_sc (void); @@ -149,6 +149,7 @@ void dump_sc (void);
149 int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, 149 int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
150 int is_user, int is_softmmu); 150 int is_user, int is_softmmu);
151 void do_interrupt (CPUState *env); 151 void do_interrupt (CPUState *env);
  152 +void invalidate_tlb (CPUState *env, int idx, int use_extra);
152 153
153 void cpu_loop_exit(void); 154 void cpu_loop_exit(void);
154 void do_raise_exception_err (uint32_t exception, int error_code); 155 void do_raise_exception_err (uint32_t exception, int error_code);
target-mips/helper.c
@@ -416,3 +416,44 @@ void do_interrupt (CPUState *env) @@ -416,3 +416,44 @@ void do_interrupt (CPUState *env)
416 env->exception_index = EXCP_NONE; 416 env->exception_index = EXCP_NONE;
417 } 417 }
418 #endif /* !defined(CONFIG_USER_ONLY) */ 418 #endif /* !defined(CONFIG_USER_ONLY) */
  419 +
  420 +void invalidate_tlb (CPUState *env, int idx, int use_extra)
  421 +{
  422 + tlb_t *tlb;
  423 + target_ulong addr;
  424 + uint8_t ASID;
  425 +
  426 + ASID = env->CP0_EntryHi & 0xFF;
  427 +
  428 + tlb = &env->tlb[idx];
  429 + /* The qemu TLB is flushed then the ASID changes, so no need to
  430 + flush these entries again. */
  431 + if (tlb->G == 0 && tlb->ASID != ASID) {
  432 + return;
  433 + }
  434 +
  435 + if (use_extra && env->tlb_in_use < MIPS_TLB_MAX) {
  436 + /* For tlbwr, we can shadow the discarded entry into
  437 + a new (fake) TLB entry, as long as the guest can not
  438 + tell that it's there. */
  439 + env->tlb[env->tlb_in_use] = *tlb;
  440 + env->tlb_in_use++;
  441 + return;
  442 + }
  443 +
  444 + if (tlb->V0) {
  445 + addr = tlb->VPN;
  446 + while (addr < tlb->end) {
  447 + tlb_flush_page (env, addr);
  448 + addr += TARGET_PAGE_SIZE;
  449 + }
  450 + }
  451 + if (tlb->V1) {
  452 + addr = tlb->end;
  453 + while (addr < tlb->end2) {
  454 + tlb_flush_page (env, addr);
  455 + addr += TARGET_PAGE_SIZE;
  456 + }
  457 + }
  458 +}
  459 +
target-mips/op_helper.c
@@ -376,53 +376,11 @@ void cpu_mips_tlb_flush (CPUState *env, int flush_global) @@ -376,53 +376,11 @@ void cpu_mips_tlb_flush (CPUState *env, int flush_global)
376 env->tlb_in_use = MIPS_TLB_NB; 376 env->tlb_in_use = MIPS_TLB_NB;
377 } 377 }
378 378
379 -static void invalidate_tlb (int idx, int use_extra)  
380 -{  
381 - tlb_t *tlb;  
382 - target_ulong addr;  
383 - uint8_t ASID;  
384 -  
385 - ASID = env->CP0_EntryHi & 0xFF;  
386 -  
387 - tlb = &env->tlb[idx];  
388 - /* The qemu TLB is flushed then the ASID changes, so no need to  
389 - flush these entries again. */  
390 - if (tlb->G == 0 && tlb->ASID != ASID) {  
391 - return;  
392 - }  
393 -  
394 - if (use_extra && env->tlb_in_use < MIPS_TLB_MAX) {  
395 - /* For tlbwr, we can shadow the discarded entry into  
396 - a new (fake) TLB entry, as long as the guest can not  
397 - tell that it's there. */  
398 - env->tlb[env->tlb_in_use] = *tlb;  
399 - env->tlb_in_use++;  
400 - return;  
401 - }  
402 -  
403 - if (tlb->V0) {  
404 - tb_invalidate_page_range(tlb->PFN[0], tlb->end - tlb->VPN);  
405 - addr = tlb->VPN;  
406 - while (addr < tlb->end) {  
407 - tlb_flush_page (env, addr);  
408 - addr += TARGET_PAGE_SIZE;  
409 - }  
410 - }  
411 - if (tlb->V1) {  
412 - tb_invalidate_page_range(tlb->PFN[1], tlb->end2 - tlb->end);  
413 - addr = tlb->end;  
414 - while (addr < tlb->end2) {  
415 - tlb_flush_page (env, addr);  
416 - addr += TARGET_PAGE_SIZE;  
417 - }  
418 - }  
419 -}  
420 -  
421 static void mips_tlb_flush_extra (CPUState *env, int first) 379 static void mips_tlb_flush_extra (CPUState *env, int first)
422 { 380 {
423 /* Discard entries from env->tlb[first] onwards. */ 381 /* Discard entries from env->tlb[first] onwards. */
424 while (env->tlb_in_use > first) { 382 while (env->tlb_in_use > first) {
425 - invalidate_tlb(--env->tlb_in_use, 0); 383 + invalidate_tlb(env, --env->tlb_in_use, 0);
426 } 384 }
427 } 385 }
428 386
@@ -459,7 +417,7 @@ void do_tlbwi (void) @@ -459,7 +417,7 @@ void do_tlbwi (void)
459 417
460 /* Wildly undefined effects for CP0_index containing a too high value and 418 /* Wildly undefined effects for CP0_index containing a too high value and
461 MIPS_TLB_NB not being a power of two. But so does real silicon. */ 419 MIPS_TLB_NB not being a power of two. But so does real silicon. */
462 - invalidate_tlb(env->CP0_index & (MIPS_TLB_NB - 1), 0); 420 + invalidate_tlb(env, env->CP0_index & (MIPS_TLB_NB - 1), 0);
463 fill_tlb(env->CP0_index & (MIPS_TLB_NB - 1)); 421 fill_tlb(env->CP0_index & (MIPS_TLB_NB - 1));
464 } 422 }
465 423
@@ -467,7 +425,7 @@ void do_tlbwr (void) @@ -467,7 +425,7 @@ void do_tlbwr (void)
467 { 425 {
468 int r = cpu_mips_get_random(env); 426 int r = cpu_mips_get_random(env);
469 427
470 - invalidate_tlb(r, 1); 428 + invalidate_tlb(env, r, 1);
471 fill_tlb(r); 429 fill_tlb(r);
472 } 430 }
473 431