Commit 2ee4aed86ff2ba38a0e1846de18a9aec38d73015
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
Showing
3 changed files
with
45 additions
and
45 deletions
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 |