aboutsummaryrefslogtreecommitdiffstats
path: root/arch/avr32
diff options
context:
space:
mode:
authorHaavard Skinnemoen <hskinnemoen@atmel.com>2007-03-14 08:59:13 -0400
committerHaavard Skinnemoen <hskinnemoen@atmel.com>2007-04-27 07:44:15 -0400
commitc0c3e81608fc300027f2131e351e67ab118cf24c (patch)
treed1e7ebe582e7a554a6735cb17ed0a60c6be03c09 /arch/avr32
parent9ca20a8366462c553c27216161c735937f9de108 (diff)
[AVR32] Optimize the TLB miss handler
Reorder some instructions and change the register usage to reduce the number of pipeline stalls. Also use the bfextu and bfins instructions for bitfield manipulations instead of shifting and masking. This makes gzipping a 80MB file approximately 2% faster. Signed-off-by: Haavard Skinnemoen <hskinnemoen@atmel.com>
Diffstat (limited to 'arch/avr32')
-rw-r--r--arch/avr32/kernel/entry-avr32b.S54
1 files changed, 24 insertions, 30 deletions
diff --git a/arch/avr32/kernel/entry-avr32b.S b/arch/avr32/kernel/entry-avr32b.S
index 484e08310f15..42657f1703b2 100644
--- a/arch/avr32/kernel/entry-avr32b.S
+++ b/arch/avr32/kernel/entry-avr32b.S
@@ -100,55 +100,49 @@ dtlb_miss_write:
100 100
101 .global tlb_miss_common 101 .global tlb_miss_common
102tlb_miss_common: 102tlb_miss_common:
103 mfsr r0, SYSREG_PTBR 103 mfsr r0, SYSREG_TLBEAR
104 mfsr r1, SYSREG_TLBEAR 104 mfsr r1, SYSREG_PTBR
105 105
106 /* Is it the vmalloc space? */ 106 /* Is it the vmalloc space? */
107 bld r1, 31 107 bld r0, 31
108 brcs handle_vmalloc_miss 108 brcs handle_vmalloc_miss
109 109
110 /* First level lookup */ 110 /* First level lookup */
111pgtbl_lookup: 111pgtbl_lookup:
112 lsr r2, r1, PGDIR_SHIFT 112 lsr r2, r0, PGDIR_SHIFT
113 ld.w r0, r0[r2 << 2] 113 ld.w r3, r1[r2 << 2]
114 bld r0, _PAGE_BIT_PRESENT 114 bfextu r1, r0, PAGE_SHIFT, PGDIR_SHIFT - PAGE_SHIFT
115 bld r3, _PAGE_BIT_PRESENT
115 brcc page_table_not_present 116 brcc page_table_not_present
116 117
117 /* TODO: Check access rights on page table if necessary */
118
119 /* Translate to virtual address in P1. */ 118 /* Translate to virtual address in P1. */
120 andl r0, 0xf000 119 andl r3, 0xf000
121 sbr r0, 31 120 sbr r3, 31
122 121
123 /* Second level lookup */ 122 /* Second level lookup */
124 lsl r1, (32 - PGDIR_SHIFT) 123 ld.w r2, r3[r1 << 2]
125 lsr r1, (32 - PGDIR_SHIFT) + PAGE_SHIFT 124 mfsr r0, SYSREG_TLBARLO
126 add r2, r0, r1 << 2 125 bld r2, _PAGE_BIT_PRESENT
127 ld.w r1, r2[0]
128 bld r1, _PAGE_BIT_PRESENT
129 brcc page_not_present 126 brcc page_not_present
130 127
131 /* Mark the page as accessed */ 128 /* Mark the page as accessed */
132 sbr r1, _PAGE_BIT_ACCESSED 129 sbr r2, _PAGE_BIT_ACCESSED
133 st.w r2[0], r1 130 st.w r3[r1 << 2], r2
134 131
135 /* Drop software flags */ 132 /* Drop software flags */
136 andl r1, _PAGE_FLAGS_HARDWARE_MASK & 0xffff 133 andl r2, _PAGE_FLAGS_HARDWARE_MASK & 0xffff
137 mtsr SYSREG_TLBELO, r1 134 mtsr SYSREG_TLBELO, r2
138 135
139 /* Figure out which entry we want to replace */ 136 /* Figure out which entry we want to replace */
140 mfsr r0, SYSREG_TLBARLO 137 mfsr r1, SYSREG_MMUCR
141 clz r2, r0 138 clz r2, r0
142 brcc 1f 139 brcc 1f
143 mov r1, -1 /* All entries have been accessed, */ 140 mov r3, -1 /* All entries have been accessed, */
144 mtsr SYSREG_TLBARLO, r1 /* so reset TLBAR */ 141 mov r2, 0 /* so start at 0 */
145 mov r2, 0 /* and start at 0 */ 142 mtsr SYSREG_TLBARLO, r3 /* and reset TLBAR */
1461: mfsr r1, SYSREG_MMUCR
147 lsl r2, 14
148 andl r1, 0x3fff, COH
149 or r1, r2
150 mtsr SYSREG_MMUCR, r1
151 143
1441: bfins r1, r2, SYSREG_DRP_OFFSET, SYSREG_DRP_SIZE
145 mtsr SYSREG_MMUCR, r1
152 tlbw 146 tlbw
153 147
154 tlbmiss_restore 148 tlbmiss_restore
@@ -156,8 +150,8 @@ pgtbl_lookup:
156 150
157handle_vmalloc_miss: 151handle_vmalloc_miss:
158 /* Simply do the lookup in init's page table */ 152 /* Simply do the lookup in init's page table */
159 mov r0, lo(swapper_pg_dir) 153 mov r1, lo(swapper_pg_dir)
160 orh r0, hi(swapper_pg_dir) 154 orh r1, hi(swapper_pg_dir)
161 rjmp pgtbl_lookup 155 rjmp pgtbl_lookup
162 156
163 157