1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006,2007 by Greg White
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
23 void __attribute__((naked
)) ttb_init(void) {
26 "mcr p15, 0, %[ttbB], c2, c0, 0 \n" /* Set the TTB base address */
27 "mcr p15, 0, %[ffff], c3, c0, 0 \n" /* Set all domains to manager status */
30 : [ttbB
] "r" (TTB_BASE
),
31 [ffff
] "r" (0xFFFFFFFF)
35 void __attribute__((naked
)) map_section(unsigned int pa
, unsigned int va
, int mb
, int flags
) {
38 /* pa &= (-1 << 20); // align to 1MB */
39 "mov r0, r0, lsr #20 \n"
40 "mov r0, r0, lsl #20 \n"
42 /* pa |= (flags | 0x412);
44 * 10: superuser - r/w, user - no access
46 * 3,2: Cache flags (flags (r3))
47 * 1: Section signature
51 "orr r0, r0, #0x410 \n"
57 register int *ttb_base
asm ("r3") = TTB_BASE
; /* force in r3 */
61 /* unsigned int* ttbPtr = TTB_BASE + (va >> 20);
62 * sections are 1MB size
65 "mov r1, r1, lsr #20 \n"
66 "add r1, %[ttbB], r1, lsl #0x2 \n"
68 /* Add MB to pa, flags are already present in pa, but addition
69 * should not effect them
71 * #define MB (1 << 20)
72 * for( ; mb>0; mb--, pa += MB)
84 "add r0, r0, #0x100000 \n"
90 : [ttbB
] "r" (ttb_base
) /* This /HAS/ to be in r3 */
98 void __attribute__((naked
)) enable_mmu(void) {
101 "mcr p15, 0, r0, c8, c7, 0 \n" /* invalidate TLB */
102 "mcr p15, 0, r0, c7, c7,0 \n" /* invalidate both icache and dcache */
103 "mrc p15, 0, r0, c1, c0, 0 \n"
104 "orr r0, r0, #1 \n" /* enable mmu bit, icache and dcache */
105 "orr r0, r0, #1<<2 \n" /* enable dcache */
106 "orr r0, r0, #1<<12 \n" /* enable icache */
107 "mcr p15, 0, r0, c1, c0, 0 \n"
119 #if CONFIG_CPU == IMX31L
120 void __attribute__((naked
)) invalidate_dcache_range(const void *base
, unsigned int size
)
125 "mcrr p15, 0, r1, r0, c14 \n" /* Clean and invalidate dcache range */
126 "mcr p15, 0, r2, c7, c10, 4 \n" /* Data synchronization barrier */
129 (void)base
; (void)size
;
132 /* Invalidate DCache for this range */
133 /* Will do write back */
134 void invalidate_dcache_range(const void *base
, unsigned int size
) {
135 unsigned int addr
= (((int) base
) & ~31); /* Align start to cache line*/
136 unsigned int end
= ((addr
+size
) & ~31)+64; /* Align end to cache line, pad */
139 "mcr p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
142 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
143 "addne %0, %0, #32 \n"
145 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
146 "addne %0, %0, #32 \n"
148 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
149 "addne %0, %0, #32 \n"
151 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
152 "addne %0, %0, #32 \n"
154 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
155 "addne %0, %0, #32 \n"
157 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
158 "addne %0, %0, #32 \n"
160 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
161 "addne %0, %0, #32 \n"
165 "mcr p15,0,%0,c7,c10,4\n" /* Drain write buffer */
166 : : "r" (addr
), "r" (end
)
172 #if CONFIG_CPU == IMX31L
173 void __attribute__((naked
)) clean_dcache_range(const void *base
, unsigned int size
)
178 "mcrr p15, 0, r1, r0, c12 \n" /* Clean dcache range */
179 "mcr p15, 0, r2, c7, c10, 4 \n" /* Data synchronization barrier */
182 (void)base
; (void)size
;
185 /* clean DCache for this range */
186 /* forces DCache writeback for the specified range */
187 void clean_dcache_range(const void *base
, unsigned int size
) {
188 unsigned int addr
= (int) base
;
189 unsigned int end
= addr
+size
+32;
193 "mcr p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
196 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
197 "addlo %0, %0, #32 \n"
199 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
200 "addlo %0, %0, #32 \n"
202 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
203 "addlo %0, %0, #32 \n"
205 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
206 "addlo %0, %0, #32 \n"
208 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
209 "addlo %0, %0, #32 \n"
211 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
212 "addlo %0, %0, #32 \n"
214 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
215 "addlo %0, %0, #32 \n"
219 "mcr p15,0,%0,c7,c10,4 \n" /* Drain write buffer */
220 : : "r" (addr
), "r" (end
));
224 #if CONFIG_CPU == IMX31L
225 void __attribute__((naked
)) dump_dcache_range(const void *base
, unsigned int size
)
229 "mcrr p15, 0, r1, r0, c6 \n"
232 (void)base
; (void)size
;
235 /* Dump DCache for this range */
236 /* Will *NOT* do write back */
237 void dump_dcache_range(const void *base
, unsigned int size
) {
238 unsigned int addr
= (int) base
;
239 unsigned int end
= addr
+size
;
241 "tst %0, #31 \n" /* Check to see if low five bits are set */
242 "bic %0, %0, #31 \n" /* Clear them */
243 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line, if those bits were set */
244 "add %0, %0, #32 \n" /* Move to the next cache line */
245 "tst %1, #31 \n" /* Check last line for bits set */
246 "bic %1, %1, #31 \n" /* Clear those bits */
247 "mcrne p15, 0, %1, c7, c14, 1 \n" /* Clean and invalidate this line, if not cache aligned */
249 "mcr p15, 0, %0, c7, c6, 1 \n" /* Invalidate this line */
250 "add %0, %0, #32 \n" /* Next cache line */
254 "mcr p15,0,%0,c7,c10,4 \n" /* Drain write buffer */
255 : : "r" (addr
), "r" (end
));
259 #if CONFIG_CPU == IMX31L
260 void __attribute__((naked
)) clean_dcache(void)
263 /* Clean entire data cache */
265 "mcr p15, 0, r0, c7, c10, 0 \n"
270 /* Cleans entire DCache */
271 void clean_dcache(void)
273 unsigned int index
, addr
, low
;
275 for(index
= 0; index
<= 63; index
++)
277 for(low
= 0;low
<= 7; low
++)
279 addr
= (index
<< 26) | (low
<< 5);
282 "mcr p15, 0, %[addr], c7, c10, 2 \n" /* Clean this entry by index */