提交 fe11dc3f 编写于 作者: J Joakim Tjernlund 提交者: 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: NJoakim Tjernlund <Joakim.Tjernlund@transmode.se>
Signed-off-by: NBenjamin Herrenschmidt <benh@kernel.crashing.org>
上级 5efab4a0
master alk-4.19.24 alk-4.19.30 alk-4.19.34 alk-4.19.36 alk-4.19.43 alk-4.19.48 alk-4.19.57 ck-4.19.67 ck-4.19.81 ck-4.19.91 github/fork/deepanshu1422/fix-typo-in-comment github/fork/haosdent/fix-typo linux-next v4.19.91 v4.19.90 v4.19.89 v4.19.88 v4.19.87 v4.19.86 v4.19.85 v4.19.84 v4.19.83 v4.19.82 v4.19.81 v4.19.80 v4.19.79 v4.19.78 v4.19.77 v4.19.76 v4.19.75 v4.19.74 v4.19.73 v4.19.72 v4.19.71 v4.19.70 v4.19.69 v4.19.68 v4.19.67 v4.19.66 v4.19.65 v4.19.64 v4.19.63 v4.19.62 v4.19.61 v4.19.60 v4.19.59 v4.19.58 v4.19.57 v4.19.56 v4.19.55 v4.19.54 v4.19.53 v4.19.52 v4.19.51 v4.19.50 v4.19.49 v4.19.48 v4.19.47 v4.19.46 v4.19.45 v4.19.44 v4.19.43 v4.19.42 v4.19.41 v4.19.40 v4.19.39 v4.19.38 v4.19.37 v4.19.36 v4.19.35 v4.19.34 v4.19.33 v4.19.32 v4.19.31 v4.19.30 v4.19.29 v4.19.28 v4.19.27 v4.19.26 v4.19.25 v4.19.24 v4.19.23 v4.19.22 v4.19.21 v4.19.20 v4.19.19 v4.19.18 v4.19.17 v4.19.16 v4.19.15 v4.19.14 v4.19.13 v4.19.12 v4.19.11 v4.19.10 v4.19.9 v4.19.8 v4.19.7 v4.19.6 v4.19.5 v4.19.4 v4.19.3 v4.19.2 v4.19.1 v4.19 v4.19-rc8 v4.19-rc7 v4.19-rc6 v4.19-rc5 v4.19-rc4 v4.19-rc3 v4.19-rc2 v4.19-rc1 ck-release-21 ck-release-20 ck-release-19.2 ck-release-19.1 ck-release-19 ck-release-18 ck-release-17.2 ck-release-17.1 ck-release-17 ck-release-16 ck-release-15.1 ck-release-15 ck-release-14 ck-release-13.2 ck-release-13 ck-release-12 ck-release-11 ck-release-10 ck-release-9 ck-release-7 alk-release-15 alk-release-14 alk-release-13.2 alk-release-13 alk-release-12 alk-release-11 alk-release-10 alk-release-9 alk-release-7
无相关合并请求
......@@ -33,21 +33,20 @@
#define _PAGE_NO_CACHE 0x0002 /* I: cache inhibit */
#define _PAGE_SHARED 0x0004 /* No ASID (context) compare */
#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
* into the TLB.
/* These 3 software bits must be masked out when the entry is loaded
* into the TLB, 2 SW bits left.
*/
#define _PAGE_GUARDED 0x0010 /* software: guarded access */
#define _PAGE_DIRTY 0x0020 /* software: page changed */
#define _PAGE_RW 0x0040 /* software: user write access allowed */
#define _PAGE_ACCESSED 0x0080 /* software: page referenced */
#define _PAGE_ACCESSED 0x0020 /* software: page referenced */
/* Setting any bits in the nibble with the follow two controls will
* require a TLB exception handler change. It is assumed unused bits
* are always zero.
*/
#define _PAGE_HWWRITE 0x0100 /* h/w write enable: never set in Linux PTE */
#define _PAGE_USER 0x0800 /* One of the PP bits, the other is USER&~RW */
#define _PAGE_RW 0x0400 /* lsb PP bits, inverted in HW */
#define _PAGE_USER 0x0800 /* msb PP bits */
#define _PMD_PRESENT 0x0001
#define _PMD_BAD 0x0ff0
......
......@@ -333,26 +333,20 @@ InstructionTLBMiss:
mfspr r11, SPRN_MD_TWC /* ....and get the pte address */
lwz r10, 0(r11) /* Get the pte */
#ifdef CONFIG_SWAP
/* do not set the _PAGE_ACCESSED bit of a non-present page */
andi. r11, r10, _PAGE_PRESENT
beq 4f
ori r10, r10, _PAGE_ACCESSED
mfspr r11, SPRN_MD_TWC /* get the pte address again */
stw r10, 0(r11)
4:
#else
ori r10, r10, _PAGE_ACCESSED
stw r10, 0(r11)
#endif
andi. r11, r10, _PAGE_ACCESSED | _PAGE_PRESENT
cmpwi cr0, r11, _PAGE_ACCESSED | _PAGE_PRESENT
bne- cr0, 2f
/* Clear PP lsb, 0x400 */
rlwinm r10, r10, 0, 22, 20
/* 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
* set. All other Linux PTE bits control the behavior
* of the MMU.
*/
2: li r11, 0x00f0
li r11, 0x00f0
rlwimi r10, r11, 0, 24, 28 /* Set 24-27, clear 28 */
DO_8xx_CPU6(0x2d80, r3)
mtspr SPRN_MI_RPN, r10 /* Update TLB entry */
......@@ -365,6 +359,22 @@ InstructionTLBMiss:
lwz r3, 8(r0)
#endif
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
DataStoreTLBMiss:
......@@ -409,21 +419,27 @@ DataStoreTLBMiss:
DO_8xx_CPU6(0x3b80, r3)
mtspr SPRN_MD_TWC, r11
#ifdef CONFIG_SWAP
/* 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:
/* and update pte in table */
#else
ori r10, r10, _PAGE_ACCESSED
#endif
mfspr r11, SPRN_MD_TWC /* get the pte address again */
stw r10, 0(r11)
/* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set.
* We also need to know if the insn is a load/store, so:
* Clear _PAGE_PRESENT and load that which will
* trap into DTLB Error with store bit set accordinly.
*/
/* PRESENT=0x1, ACCESSED=0x20
* r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5));
* r10 = (r10 & ~PRESENT) | r11;
*/
rlwinm r11, r10, 32-5, 31, 31
and r11, r11, r10
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.
* 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
* set. All other Linux PTE bits control the behavior
* of the MMU.
......@@ -469,11 +485,12 @@ DataTLBError:
stw r10, 0(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
* register. The EA of a data TLB error is automatically stored in
......@@ -522,26 +539,12 @@ DataTLBError:
mfspr r11, SPRN_MD_TWC /* ....and get the pte address */
lwz r10, 0(r11) /* Get the pte */
andi. r11, r10, _PAGE_RW /* Is it writeable? */
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 */
ori r10, r10, _PAGE_DIRTY | _PAGE_ACCESSED | _PAGE_HWWRITE
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.
* 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
* set. All other Linux PTE bits control the behavior
* of the MMU.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册
反馈
建议
客服 返回
顶部