Commit bc814401c2061f0d362f0fb709397a890df47e7c
1 parent
8e71621f
Bring TLB / PageSize handling in line with real hardware behaviour.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2341 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
2 changed files
with
5 additions
and
25 deletions
target-mips/helper.c
| @@ -50,7 +50,7 @@ static int map_address (CPUState *env, target_ulong *physical, int *prot, | @@ -50,7 +50,7 @@ static int map_address (CPUState *env, target_ulong *physical, int *prot, | ||
| 50 | tlb = &env->tlb[i]; | 50 | tlb = &env->tlb[i]; |
| 51 | /* Check ASID, virtual page number & size */ | 51 | /* Check ASID, virtual page number & size */ |
| 52 | if ((tlb->G == 1 || tlb->ASID == ASID) && | 52 | if ((tlb->G == 1 || tlb->ASID == ASID) && |
| 53 | - tlb->VPN == tag && address < tlb->end2) { | 53 | + tlb->VPN == tag) { |
| 54 | /* TLB match */ | 54 | /* TLB match */ |
| 55 | n = (address >> TARGET_PAGE_BITS) & 1; | 55 | n = (address >> TARGET_PAGE_BITS) & 1; |
| 56 | /* Check access rights */ | 56 | /* Check access rights */ |
| @@ -420,7 +420,6 @@ void do_interrupt (CPUState *env) | @@ -420,7 +420,6 @@ void do_interrupt (CPUState *env) | ||
| 420 | void invalidate_tlb (CPUState *env, int idx, int use_extra) | 420 | void invalidate_tlb (CPUState *env, int idx, int use_extra) |
| 421 | { | 421 | { |
| 422 | tlb_t *tlb; | 422 | tlb_t *tlb; |
| 423 | - target_ulong addr; | ||
| 424 | uint8_t ASID; | 423 | uint8_t ASID; |
| 425 | 424 | ||
| 426 | ASID = env->CP0_EntryHi & 0xFF; | 425 | ASID = env->CP0_EntryHi & 0xFF; |
| @@ -441,19 +440,8 @@ void invalidate_tlb (CPUState *env, int idx, int use_extra) | @@ -441,19 +440,8 @@ void invalidate_tlb (CPUState *env, int idx, int use_extra) | ||
| 441 | return; | 440 | return; |
| 442 | } | 441 | } |
| 443 | 442 | ||
| 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 | - } | 443 | + if (tlb->V0) |
| 444 | + tlb_flush_page (env, tlb->VPN); | ||
| 445 | + if (tlb->V1) | ||
| 446 | + tlb_flush_page (env, tlb->VPN + TARGET_PAGE_SIZE); | ||
| 458 | } | 447 | } |
| 459 | - |
target-mips/op_helper.c
| @@ -387,16 +387,11 @@ static void mips_tlb_flush_extra (CPUState *env, int first) | @@ -387,16 +387,11 @@ static void mips_tlb_flush_extra (CPUState *env, int first) | ||
| 387 | static void fill_tlb (int idx) | 387 | static void fill_tlb (int idx) |
| 388 | { | 388 | { |
| 389 | tlb_t *tlb; | 389 | tlb_t *tlb; |
| 390 | - int size; | ||
| 391 | 390 | ||
| 392 | /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */ | 391 | /* XXX: detect conflicting TLBs and raise a MCHECK exception when needed */ |
| 393 | tlb = &env->tlb[idx]; | 392 | tlb = &env->tlb[idx]; |
| 394 | tlb->VPN = env->CP0_EntryHi & (int32_t)0xFFFFE000; | 393 | tlb->VPN = env->CP0_EntryHi & (int32_t)0xFFFFE000; |
| 395 | tlb->ASID = env->CP0_EntryHi & 0xFF; | 394 | tlb->ASID = env->CP0_EntryHi & 0xFF; |
| 396 | - size = env->CP0_PageMask >> 13; | ||
| 397 | - size = 4 * (size + 1); | ||
| 398 | - tlb->end = tlb->VPN + (1 << (8 + size)); | ||
| 399 | - tlb->end2 = tlb->end + (1 << (8 + size)); | ||
| 400 | tlb->G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1; | 395 | tlb->G = env->CP0_EntryLo0 & env->CP0_EntryLo1 & 1; |
| 401 | tlb->V0 = (env->CP0_EntryLo0 & 2) != 0; | 396 | tlb->V0 = (env->CP0_EntryLo0 & 2) != 0; |
| 402 | tlb->D0 = (env->CP0_EntryLo0 & 4) != 0; | 397 | tlb->D0 = (env->CP0_EntryLo0 & 4) != 0; |
| @@ -467,7 +462,6 @@ void do_tlbr (void) | @@ -467,7 +462,6 @@ void do_tlbr (void) | ||
| 467 | { | 462 | { |
| 468 | tlb_t *tlb; | 463 | tlb_t *tlb; |
| 469 | uint8_t ASID; | 464 | uint8_t ASID; |
| 470 | - int size; | ||
| 471 | 465 | ||
| 472 | ASID = env->CP0_EntryHi & 0xFF; | 466 | ASID = env->CP0_EntryHi & 0xFF; |
| 473 | tlb = &env->tlb[env->CP0_index & (MIPS_TLB_NB - 1)]; | 467 | tlb = &env->tlb[env->CP0_index & (MIPS_TLB_NB - 1)]; |
| @@ -479,8 +473,6 @@ void do_tlbr (void) | @@ -479,8 +473,6 @@ void do_tlbr (void) | ||
| 479 | mips_tlb_flush_extra(env, MIPS_TLB_NB); | 473 | mips_tlb_flush_extra(env, MIPS_TLB_NB); |
| 480 | 474 | ||
| 481 | env->CP0_EntryHi = tlb->VPN | tlb->ASID; | 475 | env->CP0_EntryHi = tlb->VPN | tlb->ASID; |
| 482 | - size = (tlb->end - tlb->VPN) >> 12; | ||
| 483 | - env->CP0_PageMask = (size - 1) << 13; | ||
| 484 | env->CP0_EntryLo0 = tlb->G | (tlb->V0 << 1) | (tlb->D0 << 2) | | 476 | env->CP0_EntryLo0 = tlb->G | (tlb->V0 << 1) | (tlb->D0 << 2) | |
| 485 | (tlb->C0 << 3) | (tlb->PFN[0] >> 6); | 477 | (tlb->C0 << 3) | (tlb->PFN[0] >> 6); |
| 486 | env->CP0_EntryLo1 = tlb->G | (tlb->V1 << 1) | (tlb->D1 << 2) | | 478 | env->CP0_EntryLo1 = tlb->G | (tlb->V1 << 1) | (tlb->D1 << 2) | |