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 | 149 | int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw, |
150 | 150 | int is_user, int is_softmmu); |
151 | 151 | void do_interrupt (CPUState *env); |
152 | +void invalidate_tlb (CPUState *env, int idx, int use_extra); | |
152 | 153 | |
153 | 154 | void cpu_loop_exit(void); |
154 | 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 | 416 | env->exception_index = EXCP_NONE; |
417 | 417 | } |
418 | 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 | 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 | 379 | static void mips_tlb_flush_extra (CPUState *env, int first) |
422 | 380 | { |
423 | 381 | /* Discard entries from env->tlb[first] onwards. */ |
424 | 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 | 417 | |
460 | 418 | /* Wildly undefined effects for CP0_index containing a too high value and |
461 | 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 | 421 | fill_tlb(env->CP0_index & (MIPS_TLB_NB - 1)); |
464 | 422 | } |
465 | 423 | |
... | ... | @@ -467,7 +425,7 @@ void do_tlbwr (void) |
467 | 425 | { |
468 | 426 | int r = cpu_mips_get_random(env); |
469 | 427 | |
470 | - invalidate_tlb(r, 1); | |
428 | + invalidate_tlb(env, r, 1); | |
471 | 429 | fill_tlb(r); |
472 | 430 | } |
473 | 431 | ... | ... |