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) | |