1 /* ============================================================================
3 @ MMU function for armV7
5 @ Spreadtrum Communications Inc.
7 @ ============================================================================
10 @AREA mmu_functions, CODE, READONLY
16 .globl g_mmu_page_table
18 .globl MMU_InvalideDCACHEALL
19 .globl MMU_InvalideICACHEALL
20 .globl Dcache_InvalRegion
21 .globl Dcache_CleanRegion
24 @============================================================================
28 @ void Dcache_InvalRegion(void *addr, unsigned int length)
32 @ Invalid a memory region in the cache.
33 @============================================================================
35 stmfd sp!, {r0-r3, lr}
38 mrc p15, 1, r3, c0, c0, 0
46 mcrne p15, 0, r0, c7, c14, 1
50 mcrne p15, 0, r1, c7, c14, 1
53 mcr p15, 0, r0, c7, c6, 1
59 ldmfd sp!, {r0-r3, lr}
61 @============================================================================
65 @ void Dcache_CleanRegion(void *addr, unsigned int length)
69 @ clean a memory region in the cache.
70 @============================================================================
72 stmfd sp!, {r0-r3, lr}
75 mrc p15, 1, r3, c0, c0, 0
84 mcr p15, 0, r0, c7, c10, 1
94 MMU_InvalideICACHEALL:
95 stmfd sp!, {r0, lr} @ save lr_USR and non-callee
98 MCR p15, 0, r0, c7, c5, 0 @Invalidate(flush)the ICache
99 MCR p15, 0, r0, c8, c5, 0 @flush ITLB only
110 @ save lr_USR and non-callee
111 stmfd sp!, {r0-r3, lr}
113 @ Set the MMU page table address
114 LDR r2, =g_mmu_page_table
116 MCR p15, 0, r2, c2, c0, 0
118 @ Domain Access Control: set all domains to manager
120 MCR p15, 0, r0, c3, c0, 0
122 @ Enable the ICache, DCache, write buffer, MMU
123 MRC p15, 0, r0, c1, c0, 0
126 MCR p15, 0, r0, c1, c0, 0
128 @ Delay for the operations to finish
134 ldmfd sp!, {r0-r3, PC}
137 stmfd sp!, {r0-r3,lr}
143 mrc p15, 1, r3, c0, c0, 0
145 and r3, r1, r3, lsr #13
154 mcr p15, 0, r2, c7 ,c14, 2
165 ldmfd sp!, {r0-r3,pc}
168 v7_flush_dcache_all1:
170 mrc p15, 1, r0, c0, c0, 1 @ read clidr
171 ands r3, r0, #0x7000000 @ extract loc from clidr
172 mov r3, r3, lsr #23 @ left align loc bit field
173 beq finished @ if loc is 0, then no need to clean
174 mov r10, #0 @ start clean at cache level 0
176 add r2, r10, r10, lsr #1 @ work out 3x current cache level
177 mov r1, r0, lsr r2 @ extract cache type bits from clidr
178 and r1, r1, #7 @ mask of the bits for current cache only
179 cmp r1, #2 @ see what cache we have at this level
180 blt skip @ skip if no cache, or just i-cache
181 mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
183 mrc p15, 1, r1, c0, c0, 0 @ read the new csidr
184 and r2, r1, #7 @ extract the length of the cache lines
185 add r2, r2, #4 @ add 4 (line length offset)
187 ands r4, r4, r1, lsr #3 @ find maximum number on the way size
188 clz r5, r4 @ find bit position of way size increment
190 ands r7, r7, r1, lsr #13 @ extract max number of the index size
192 mov r9, r4 @ create working copy of max way size
194 orr r11, r10, r9, lsl r5 @ factor way and cache number into r11
195 orr r11, r11, r7, lsl r2 @ factor index number into r11
196 mcr p15, 0, r11, c7, c14, 2 @ clean & invalidate by set/way
197 subs r9, r9, #1 @ decrement the way
199 subs r7, r7, #1 @ decrement the index
202 add r10, r10, #2 @ increment cache number
206 mov r10, #0 @ swith back to cache level 0
207 mcr p15, 2, r10, c0, c0, 0 @ select current cache level in cssr
213 .globl MMU_DisableIDCM
215 stmfd sp!, {r0-r12, lr}
217 @ Disable the ICache, DCache, write buffer, MMU
218 MRC p15, 0, r0, c1, c0, 0
221 ORR r0, r0, #0x8 @Bit_7 must be one when write c1@
222 MCR p15, 0, r0, c1, c0, 0
224 bl v7_flush_dcache_all1
227 mcr p15, 0, r0, c7, c5, 0
228 mcr p15, 0, r0, c8, c7, 0
234 ldmfd sp!, {r0-r12, PC} @ restore registers