Commit fe11dc3f authored by Joakim Tjernlund's avatar Joakim Tjernlund Committed by Benjamin Herrenschmidt

powerpc/8xx: Update TLB asm so it behaves as linux mm expects.

Update the TLB asm to make proper use of _PAGE_DIRY and _PAGE_ACCESSED.
Get rid of _PAGE_HWWRITE too.
Pros:
 - I/D TLB Miss never needs to write to the linux pte.
 - _PAGE_ACCESSED is only set on TLB Error fixing accounting
 - _PAGE_DIRTY is mapped to 0x100, the changed bit, and is set directly
    when a page has been made dirty.
 - Proper RO/RW mapping of user space.
 - Free up 2 SW TLB bits in the linux pte(add back _PAGE_WRITETHRU ?)
 - kernel RO/user NA support.
Cons:
 - A few more instructions in the TLB Miss routines.
Signed-off-by: default avatarJoakim Tjernlund <Joakim.Tjernlund@transmode.se>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 5efab4a0
...@@ -33,21 +33,20 @@ ...@@ -33,21 +33,20 @@
#define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */ #define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */
#define _PAGE_SHARED 0x0004 /* No ASID (context) compare */ #define _PAGE_SHARED 0x0004 /* No ASID (context) compare */
#define _PAGE_SPECIAL 0x0008 /* SW entry, forced to 0 by the TLB miss */ #define _PAGE_SPECIAL 0x0008 /* SW entry, forced to 0 by the TLB miss */
#define _PAGE_DIRTY 0x0100 /* C: page changed */
/* These five software bits must be masked out when the entry is loaded /* These 3 software bits must be masked out when the entry is loaded
* into the TLB. * into the TLB, 2 SW bits left.
*/ */
#define _PAGE_GUARDED 0x0010 /* software: guarded access */ #define _PAGE_GUARDED 0x0010 /* software: guarded access */
#define _PAGE_DIRTY 0x0020 /* software: page changed */ #define _PAGE_ACCESSED 0x0020 /* software: page referenced */
#define _PAGE_RW 0x0040 /* software: user write access allowed */
#define _PAGE_ACCESSED 0x0080 /* software: page referenced */
/* Setting any bits in the nibble with the follow two controls will /* Setting any bits in the nibble with the follow two controls will
* require a TLB exception handler change. It is assumed unused bits * require a TLB exception handler change. It is assumed unused bits
* are always zero. * are always zero.
*/ */
#define _PAGE_HWWRITE 0x0100 /* h/w write enable: never set in Linux PTE */ #define _PAGE_RW 0x0400 /* lsb PP bits, inverted in HW */
#define _PAGE_USER 0x0800 /* One of the PP bits, the other is USER&~RW */ #define _PAGE_USER 0x0800 /* msb PP bits */
#define _PMD_PRESENT 0x0001 #define _PMD_PRESENT 0x0001
#define _PMD_BAD 0x0ff0 #define _PMD_BAD 0x0ff0
......
...@@ -333,26 +333,20 @@ InstructionTLBMiss: ...@@ -333,26 +333,20 @@ InstructionTLBMiss:
mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ mfspr r11, SPRN_MD_TWC /* ....and get the pte address */
lwz r10, 0(r11) /* Get the pte */ lwz r10, 0(r11) /* Get the pte */
#ifdef CONFIG_SWAP andi. r11, r10, _PAGE_ACCESSED | _PAGE_PRESENT
/* do not set the _PAGE_ACCESSED bit of a non-present page */ cmpwi cr0, r11, _PAGE_ACCESSED | _PAGE_PRESENT
andi. r11, r10, _PAGE_PRESENT bne- cr0, 2f
beq 4f
ori r10, r10, _PAGE_ACCESSED /* Clear PP lsb, 0x400 */
mfspr r11, SPRN_MD_TWC /* get the pte address again */ rlwinm r10, r10, 0, 22, 20
stw r10, 0(r11)
4:
#else
ori r10, r10, _PAGE_ACCESSED
stw r10, 0(r11)
#endif
/* The Linux PTE won't go exactly into the MMU TLB. /* The Linux PTE won't go exactly into the MMU TLB.
* Software indicator bits 21, 22 and 28 must be clear. * Software indicator bits 22 and 28 must be clear.
* Software indicator bits 24, 25, 26, and 27 must be * Software indicator bits 24, 25, 26, and 27 must be
* set. All other Linux PTE bits control the behavior * set. All other Linux PTE bits control the behavior
* of the MMU. * of the MMU.
*/ */
2: li r11, 0x00f0 li r11, 0x00f0
rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */ rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
DO_8xx_CPU6(0x2d80, r3) DO_8xx_CPU6(0x2d80, r3)
mtspr SPRN_MI_RPN, r10 /* Update TLB entry */ mtspr SPRN_MI_RPN, r10 /* Update TLB entry */
...@@ -365,6 +359,22 @@ InstructionTLBMiss: ...@@ -365,6 +359,22 @@ InstructionTLBMiss:
lwz r3, 8(r0) lwz r3, 8(r0)
#endif #endif
rfi rfi
2:
mfspr r11, SPRN_SRR1
/* clear all error bits as TLB Miss
* sets a few unconditionally
*/
rlwinm r11, r11, 0, 0xffff
mtspr SPRN_SRR1, r11
mfspr r10, SPRN_M_TW /* Restore registers */
lwz r11, 0(r0)
mtcr r11
lwz r11, 4(r0)
#ifdef CONFIG_8xx_CPU6
lwz r3, 8(r0)
#endif
b InstructionAccess
. = 0x1200 . = 0x1200
DataStoreTLBMiss: DataStoreTLBMiss:
...@@ -409,21 +419,27 @@ DataStoreTLBMiss: ...@@ -409,21 +419,27 @@ DataStoreTLBMiss:
DO_8xx_CPU6(0x3b80, r3) DO_8xx_CPU6(0x3b80, r3)
mtspr SPRN_MD_TWC, r11 mtspr SPRN_MD_TWC, r11
#ifdef CONFIG_SWAP /* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set.
/* do not set the _PAGE_ACCESSED bit of a non-present page */ * We also need to know if the insn is a load/store, so:
andi. r11, r10, _PAGE_PRESENT * Clear _PAGE_PRESENT and load that which will
beq 4f * trap into DTLB Error with store bit set accordinly.
ori r10, r10, _PAGE_ACCESSED */
4: /* PRESENT=0x1, ACCESSED=0x20
/* and update pte in table */ * r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5));
#else * r10 = (r10 & ~PRESENT) | r11;
ori r10, r10, _PAGE_ACCESSED */
#endif rlwinm r11, r10, 32-5, 31, 31
mfspr r11, SPRN_MD_TWC /* get the pte address again */ and r11, r11, r10
stw r10, 0(r11) rlwimi r10, r11, 0, 31, 31
/* Honour kernel RO, User NA */
andi. r11, r10, _PAGE_USER | _PAGE_RW
bne- cr0, 5f
ori r10,r10, 0x200 /* Extended encoding, bit 22 */
5: xori r10, r10, _PAGE_RW /* invert RW bit */
/* The Linux PTE won't go exactly into the MMU TLB. /* The Linux PTE won't go exactly into the MMU TLB.
* Software indicator bits 21, 22 and 28 must be clear. * Software indicator bits 22 and 28 must be clear.
* Software indicator bits 24, 25, 26, and 27 must be * Software indicator bits 24, 25, 26, and 27 must be
* set. All other Linux PTE bits control the behavior * set. All other Linux PTE bits control the behavior
* of the MMU. * of the MMU.
...@@ -469,11 +485,12 @@ DataTLBError: ...@@ -469,11 +485,12 @@ DataTLBError:
stw r10, 0(r0) stw r10, 0(r0)
stw r11, 4(r0) stw r11, 4(r0)
/* First, make sure this was a store operation. mfspr r11, SPRN_DSISR
andis. r11, r11, 0x4800 /* !translation or protection */
bne 2f /* branch if either is set */
/* Only Change bit left now, do it here as it is faster
* than trapping to the C fault handler.
*/ */
mfspr r10, SPRN_DSISR
andis. r11, r10, 0x0200 /* If set, indicates store op */
beq 2f
/* The EA of a data TLB miss is automatically stored in the MD_EPN /* The EA of a data TLB miss is automatically stored in the MD_EPN
* register. The EA of a data TLB error is automatically stored in * register. The EA of a data TLB error is automatically stored in
...@@ -522,26 +539,12 @@ DataTLBError: ...@@ -522,26 +539,12 @@ DataTLBError:
mfspr r11, SPRN_MD_TWC /* ....and get the pte address */ mfspr r11, SPRN_MD_TWC /* ....and get the pte address */
lwz r10, 0(r11) /* Get the pte */ lwz r10, 0(r11) /* Get the pte */
andi. r11, r10, _PAGE_RW /* Is it writeable? */ ori r10, r10, _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HWWRITE
beq 2f /* Bail out if not */
/* Update 'changed', among others.
*/
#ifdef CONFIG_SWAP
ori r10, r10, _PAGE_DIRTY|_PAGE_HWWRITE
/* do not set the _PAGE_ACCESSED bit of a non-present page */
andi. r11, r10, _PAGE_PRESENT
beq 4f
ori r10, r10, _PAGE_ACCESSED
4:
#else
ori r10, r10, _PAGE_DIRTY|_PAGE_ACCESSED|_PAGE_HWWRITE
#endif
mfspr r11, SPRN_MD_TWC /* Get pte address again */
stw r10, 0(r11) /* and update pte in table */ stw r10, 0(r11) /* and update pte in table */
xori r10, r10, _PAGE_RW /* RW bit is inverted */
/* The Linux PTE won't go exactly into the MMU TLB. /* The Linux PTE won't go exactly into the MMU TLB.
* Software indicator bits 21, 22 and 28 must be clear. * Software indicator bits 22 and 28 must be clear.
* Software indicator bits 24, 25, 26, and 27 must be * Software indicator bits 24, 25, 26, and 27 must be
* set. All other Linux PTE bits control the behavior * set. All other Linux PTE bits control the behavior
* of the MMU. * of the MMU.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment