diff options
author | Gleb O. Raiko <raiko@niisi.msk.ru> | 1999-09-27 11:13:47 +0000 |
---|---|---|
committer | Gleb O. Raiko <raiko@niisi.msk.ru> | 1999-09-27 11:13:47 +0000 |
commit | 273767781288c35c9d679e908672b9996cda4c34 (patch) | |
tree | 2455900d5a8f1c52086e8ea6359b6619844b9024 | |
parent | f7a41bfc36a271d396debf6db6b3a3a0551514e0 (diff) |
Fix bug in tlbl/tlbs handlers that assumed the faulted entry already in tlb
because tlb refill must occur before and store the tlb entry. On r3k it's
not always true: miss on kseg2 doesn't generate tlb refill.
Now modules work. As a side effect, the kernel runs faster because
a vmalloced area is distrubuted across entire tlb.
-rw-r--r-- | arch/mips/kernel/r2300_misc.S | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/arch/mips/kernel/r2300_misc.S b/arch/mips/kernel/r2300_misc.S index e5bef295f..2d53e9503 100644 --- a/arch/mips/kernel/r2300_misc.S +++ b/arch/mips/kernel/r2300_misc.S @@ -1,4 +1,4 @@ -/* $Id: r2300_misc.S,v 1.4 1999/08/09 19:43:14 harald Exp $ +/* $Id: r2300_misc.S,v 1.5 1999/08/18 23:37:44 ralf Exp $ * misc.S: Misc. exception handling code for R3000/R2000. * * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse @@ -8,7 +8,7 @@ * * Further modifications to make this work: * Copyright (c) 1998 Harald Koerfgen - * Copyright (c) 1998 Gleb Raiko & Vladimir Roganov + * Copyright (c) 1998, 1999 Gleb Raiko & Vladimir Roganov */ #include <linux/config.h> @@ -116,6 +116,27 @@ _PAGE_VALID | _PAGE_DIRTY); \ sw pte, (ptr); +/* + * The index register may have the probe fail bit set, + * because we would trap on access kseg2, i.e. without refill. + */ +#define TLB_WRITE(reg) \ + mfc0 reg, CP0_INDEX; \ + nop; \ + bltz reg, 1f; \ + nop; \ + tlbwi; \ + j 2f; \ + nop; \ +1: tlbwr; \ +2: + +#define RET(reg) \ + mfc0 reg, CP0_EPC; \ + nop; \ + jr reg; \ + rfe + .set noreorder .align 5 @@ -126,16 +147,11 @@ NESTED(handle_tlbl, PT_SIZE, sp) /* Test present bit in entry. */ LOAD_PTE(k0, k1) tlbp - nop PTE_PRESENT(k0, k1, nopage_tlbl) PTE_MAKEVALID(k0, k1) PTE_RELOAD(k1) - tlbwi - nop - mfc0 k0, CP0_EPC - nop - jr k0 - rfe + TLB_WRITE(k0) + RET(k0) nopage_tlbl: #endif @@ -148,16 +164,11 @@ NESTED(handle_tlbs, PT_SIZE, sp) #ifndef NOTLB_OPTIMIZE LOAD_PTE(k0, k1) tlbp # find faulting entry - nop PTE_WRITABLE(k0, k1, nopage_tlbs) PTE_MAKEWRITE(k0, k1) PTE_RELOAD(k1) - tlbwi - nop - mfc0 k0, CP0_EPC - nop - jr k0 - rfe + TLB_WRITE(k0) + RET(k0) nopage_tlbs: #endif @@ -182,13 +193,8 @@ NESTED(handle_mod, PT_SIZE, sp) /* Now reload the entry into the tlb. */ PTE_RELOAD(k1) - nop tlbwi - nop - mfc0 k0, CP0_EPC - nop - jr k0 - rfe + RET(k0) #endif nowrite_mod: |