Skip to content

Commit 4f94b2c

Browse files
chleroympe
authored andcommitted
powerpc/8xx: Use L1 entry APG to handle _PAGE_ACCESSED for CONFIG_SWAP
When CONFIG_SWAP is set, the TLB miss handlers have to also take into account _PAGE_ACCESSED flag. At the moment it is done by anding _PAGE_ACCESSED into _PAGE_PRESENT using 3 instructions. This patch uses APG for handling _PAGE_ACCESSED, allowing to just copy _PAGE_ACCESSED bit into APG field, hence reducing the action to a single instruction. Signed-off-by: Christophe Leroy <[email protected]> Signed-off-by: Michael Ellerman <[email protected]>
1 parent de0f938 commit 4f94b2c

File tree

3 files changed

+47
-34
lines changed

3 files changed

+47
-34
lines changed

arch/powerpc/include/asm/mmu-8xx.h

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,20 @@
3434
* respectively NA for All or X for Supervisor and no access for User.
3535
* Then we use the APG to say whether accesses are according to Page rules or
3636
* "all Supervisor" rules (Access to all)
37-
* Therefore, we define 2 APG groups. lsb is _PMD_USER
38-
* 0 => No user => 01 (all accesses performed according to page definition)
39-
* 1 => User => 00 (all accesses performed as supervisor iaw page definition)
37+
* We also use the 2nd APG bit for _PAGE_ACCESSED when having SWAP:
38+
* When that bit is not set access is done iaw "all user"
39+
* which means no access iaw page rules.
40+
* Therefore, we define 4 APG groups. lsb is _PMD_USER, 2nd is _PAGE_ACCESSED
41+
* 0x => No access => 11 (all accesses performed as user iaw page definition)
42+
* 10 => No user => 01 (all accesses performed according to page definition)
43+
* 11 => User => 00 (all accesses performed as supervisor iaw page definition)
4044
* We define all 16 groups so that all other bits of APG can take any value
4145
*/
46+
#ifdef CONFIG_SWAP
47+
#define MI_APG_INIT 0xf4f4f4f4
48+
#else
4249
#define MI_APG_INIT 0x44444444
50+
#endif
4351

4452
/* The effective page number register. When read, contains the information
4553
* about the last instruction TLB miss. When MI_RPN is written, bits in
@@ -107,12 +115,20 @@
107115
* Supervisor and no access for user and NA for ALL.
108116
* Then we use the APG to say whether accesses are according to Page rules or
109117
* "all Supervisor" rules (Access to all)
110-
* Therefore, we define 2 APG groups. lsb is _PMD_USER
111-
* 0 => No user => 01 (all accesses performed according to page definition)
112-
* 1 => User => 00 (all accesses performed as supervisor iaw page definition)
118+
* We also use the 2nd APG bit for _PAGE_ACCESSED when having SWAP:
119+
* When that bit is not set access is done iaw "all user"
120+
* which means no access iaw page rules.
121+
* Therefore, we define 4 APG groups. lsb is _PMD_USER, 2nd is _PAGE_ACCESSED
122+
* 0x => No access => 11 (all accesses performed as user iaw page definition)
123+
* 10 => No user => 01 (all accesses performed according to page definition)
124+
* 11 => User => 00 (all accesses performed as supervisor iaw page definition)
113125
* We define all 16 groups so that all other bits of APG can take any value
114126
*/
127+
#ifdef CONFIG_SWAP
128+
#define MD_APG_INIT 0xf4f4f4f4
129+
#else
115130
#define MD_APG_INIT 0x44444444
131+
#endif
116132

117133
/* The effective page number register. When read, contains the information
118134
* about the last instruction TLB miss. When MD_RPN is written, bits in
@@ -164,6 +180,12 @@
164180
*/
165181
#define SPRN_M_TW 799
166182

183+
/* APGs */
184+
#define M_APG0 0x00000000
185+
#define M_APG1 0x00000020
186+
#define M_APG2 0x00000040
187+
#define M_APG3 0x00000060
188+
167189
#ifndef __ASSEMBLY__
168190
typedef struct {
169191
unsigned int id;

arch/powerpc/kernel/head_8xx.S

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -354,14 +354,13 @@ _ENTRY(ITLBMiss_cmp)
354354
#if defined(ITLB_MISS_KERNEL) || defined(CONFIG_HUGETLB_PAGE)
355355
mtcr r12
356356
#endif
357-
/* Load the MI_TWC with the attributes for this "segment." */
358-
mtspr SPRN_MI_TWC, r11 /* Set segment attributes */
359357

360358
#ifdef CONFIG_SWAP
361-
rlwinm r11, r10, 32-5, _PAGE_PRESENT
362-
and r11, r11, r10
363-
rlwimi r10, r11, 0, _PAGE_PRESENT
359+
rlwinm r11, r10, 31, _PAGE_ACCESSED >> 1
364360
#endif
361+
/* Load the MI_TWC with the attributes for this "segment." */
362+
mtspr SPRN_MI_TWC, r11 /* Set segment attributes */
363+
365364
li r11, RPN_PATTERN | 0x200
366365
/* The Linux PTE won't go exactly into the MMU TLB.
367366
* Software indicator bits 20 and 23 must be clear.
@@ -472,22 +471,14 @@ _ENTRY(DTLBMiss_jmp)
472471
* above.
473472
*/
474473
rlwimi r11, r10, 0, _PAGE_GUARDED
475-
mtspr SPRN_MD_TWC, r11
476-
477-
/* Both _PAGE_ACCESSED and _PAGE_PRESENT has to be set.
478-
* We also need to know if the insn is a load/store, so:
479-
* Clear _PAGE_PRESENT and load that which will
480-
* trap into DTLB Error with store bit set accordinly.
481-
*/
482-
/* PRESENT=0x1, ACCESSED=0x20
483-
* r11 = ((r10 & PRESENT) & ((r10 & ACCESSED) >> 5));
484-
* r10 = (r10 & ~PRESENT) | r11;
485-
*/
486474
#ifdef CONFIG_SWAP
487-
rlwinm r11, r10, 32-5, _PAGE_PRESENT
488-
and r11, r11, r10
489-
rlwimi r10, r11, 0, _PAGE_PRESENT
475+
/* _PAGE_ACCESSED has to be set. We use second APG bit for that, 0
476+
* on that bit will represent a Non Access group
477+
*/
478+
rlwinm r11, r10, 31, _PAGE_ACCESSED >> 1
490479
#endif
480+
mtspr SPRN_MD_TWC, r11
481+
491482
/* The Linux PTE won't go exactly into the MMU TLB.
492483
* Software indicator bits 24, 25, 26, and 27 must be
493484
* set. All other Linux PTE bits control the behavior
@@ -647,8 +638,8 @@ InstructionBreakpoint:
647638
*/
648639
DTLBMissIMMR:
649640
mtcr r12
650-
/* Set 512k byte guarded page and mark it valid */
651-
li r10, MD_PS512K | MD_GUARDED | MD_SVALID
641+
/* Set 512k byte guarded page and mark it valid and accessed */
642+
li r10, MD_PS512K | MD_GUARDED | MD_SVALID | M_APG2
652643
mtspr SPRN_MD_TWC, r10
653644
mfspr r10, SPRN_IMMR /* Get current IMMR */
654645
rlwinm r10, r10, 0, 0xfff80000 /* Get 512 kbytes boundary */
@@ -666,8 +657,8 @@ _ENTRY(dtlb_miss_exit_2)
666657

667658
DTLBMissLinear:
668659
mtcr r12
669-
/* Set 8M byte page and mark it valid */
670-
li r11, MD_PS8MEG | MD_SVALID
660+
/* Set 8M byte page and mark it valid and accessed */
661+
li r11, MD_PS8MEG | MD_SVALID | M_APG2
671662
mtspr SPRN_MD_TWC, r11
672663
rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */
673664
ori r10, r10, 0xf0 | MD_SPS16K | _PAGE_PRIVILEGED | _PAGE_DIRTY | \
@@ -685,8 +676,8 @@ _ENTRY(dtlb_miss_exit_3)
685676
#ifndef CONFIG_PIN_TLB_TEXT
686677
ITLBMissLinear:
687678
mtcr r12
688-
/* Set 8M byte page and mark it valid */
689-
li r11, MI_PS8MEG | MI_SVALID
679+
/* Set 8M byte page and mark it valid,accessed */
680+
li r11, MI_PS8MEG | MI_SVALID | M_APG2
690681
mtspr SPRN_MI_TWC, r11
691682
rlwinm r10, r10, 0, 0x0f800000 /* 8xx supports max 256Mb RAM */
692683
ori r10, r10, 0xf0 | MI_SPS16K | _PAGE_PRIVILEGED | _PAGE_DIRTY | \
@@ -969,7 +960,7 @@ initial_mmu:
969960
ori r8, r8, MI_EVALID /* Mark it valid */
970961
mtspr SPRN_MI_EPN, r8
971962
li r8, MI_PS8MEG /* Set 8M byte page */
972-
ori r8, r8, MI_SVALID /* Make it valid */
963+
ori r8, r8, MI_SVALID | M_APG2 /* Make it valid, APG 2 */
973964
mtspr SPRN_MI_TWC, r8
974965
li r8, MI_BOOTINIT /* Create RPN for address 0 */
975966
mtspr SPRN_MI_RPN, r8 /* Store TLB entry */
@@ -996,7 +987,7 @@ initial_mmu:
996987
ori r8, r8, MD_EVALID /* Mark it valid */
997988
mtspr SPRN_MD_EPN, r8
998989
li r8, MD_PS512K | MD_GUARDED /* Set 512k byte page */
999-
ori r8, r8, MD_SVALID /* Make it valid */
990+
ori r8, r8, MD_SVALID | M_APG2 /* Make it valid and accessed */
1000991
mtspr SPRN_MD_TWC, r8
1001992
mr r8, r9 /* Create paddr for TLB */
1002993
ori r8, r8, MI_BOOTINIT|0x2 /* Inhibit cache -- Cort */

arch/powerpc/mm/8xx_mmu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ void __init MMU_init_hw(void)
7979
for (; i < 32 && mem >= LARGE_PAGE_SIZE_8M; i++) {
8080
mtspr(SPRN_MD_CTR, ctr | (i << 8));
8181
mtspr(SPRN_MD_EPN, (unsigned long)__va(addr) | MD_EVALID);
82-
mtspr(SPRN_MD_TWC, MD_PS8MEG | MD_SVALID);
82+
mtspr(SPRN_MD_TWC, MD_PS8MEG | MD_SVALID | M_APG2);
8383
mtspr(SPRN_MD_RPN, addr | flags | _PAGE_PRESENT);
8484
addr += LARGE_PAGE_SIZE_8M;
8585
mem -= LARGE_PAGE_SIZE_8M;

0 commit comments

Comments
 (0)