diff options
author | Haavard Skinnemoen <hskinnemoen@atmel.com> | 2007-03-14 08:59:13 -0400 |
---|---|---|
committer | Haavard Skinnemoen <hskinnemoen@atmel.com> | 2007-04-27 07:44:15 -0400 |
commit | c0c3e81608fc300027f2131e351e67ab118cf24c (patch) | |
tree | d1e7ebe582e7a554a6735cb17ed0a60c6be03c09 /arch/avr32 | |
parent | 9ca20a8366462c553c27216161c735937f9de108 (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.S | 54 |
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 |
102 | tlb_miss_common: | 102 | tlb_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 */ |
111 | pgtbl_lookup: | 111 | pgtbl_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 */ |
146 | 1: mfsr r1, SYSREG_MMUCR | ||
147 | lsl r2, 14 | ||
148 | andl r1, 0x3fff, COH | ||
149 | or r1, r2 | ||
150 | mtsr SYSREG_MMUCR, r1 | ||
151 | 143 | ||
144 | 1: 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 | ||
157 | handle_vmalloc_miss: | 151 | handle_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 | ||