Commit bbc0d79cb7ab5b2214cd984638ff8e0faa366fcf

Authored by aurel32
1 parent 75973fa1

MIPS: Fix tlbwi/tlbwr

In CP0 Index register, bit 31 means 'Probe Failure', while lowest bits
contain the TLB index.

In tlbwi and tlbwr instructions, this Probe Failure bit must be ignored
when reading the TLB index.

Attached patch fixes it.

(Hervé Poussineau)

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5215 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 9 additions and 3 deletions
target-mips/op_helper.c
@@ -1572,13 +1572,17 @@ static void r4k_fill_tlb (int idx) @@ -1572,13 +1572,17 @@ static void r4k_fill_tlb (int idx)
1572 1572
1573 void r4k_do_tlbwi (void) 1573 void r4k_do_tlbwi (void)
1574 { 1574 {
  1575 + int idx;
  1576 +
  1577 + idx = (env->CP0_Index & ~0x80000000) % env->tlb->nb_tlb;
  1578 +
1575 /* Discard cached TLB entries. We could avoid doing this if the 1579 /* Discard cached TLB entries. We could avoid doing this if the
1576 tlbwi is just upgrading access permissions on the current entry; 1580 tlbwi is just upgrading access permissions on the current entry;
1577 that might be a further win. */ 1581 that might be a further win. */
1578 r4k_mips_tlb_flush_extra (env, env->tlb->nb_tlb); 1582 r4k_mips_tlb_flush_extra (env, env->tlb->nb_tlb);
1579 1583
1580 - r4k_invalidate_tlb(env, env->CP0_Index % env->tlb->nb_tlb, 0);  
1581 - r4k_fill_tlb(env->CP0_Index % env->tlb->nb_tlb); 1584 + r4k_invalidate_tlb(env, idx, 0);
  1585 + r4k_fill_tlb(idx);
1582 } 1586 }
1583 1587
1584 void r4k_do_tlbwr (void) 1588 void r4k_do_tlbwr (void)
@@ -1635,9 +1639,11 @@ void r4k_do_tlbr (void) @@ -1635,9 +1639,11 @@ void r4k_do_tlbr (void)
1635 { 1639 {
1636 r4k_tlb_t *tlb; 1640 r4k_tlb_t *tlb;
1637 uint8_t ASID; 1641 uint8_t ASID;
  1642 + int idx;
1638 1643
1639 ASID = env->CP0_EntryHi & 0xFF; 1644 ASID = env->CP0_EntryHi & 0xFF;
1640 - tlb = &env->tlb->mmu.r4k.tlb[env->CP0_Index % env->tlb->nb_tlb]; 1645 + idx = (env->CP0_Index & ~0x80000000) % env->tlb->nb_tlb;
  1646 + tlb = &env->tlb->mmu.r4k.tlb[idx];
1641 1647
1642 /* If this will change the current ASID, flush qemu's TLB. */ 1648 /* If this will change the current ASID, flush qemu's TLB. */
1643 if (ASID != tlb->ASID) 1649 if (ASID != tlb->ASID)