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 #define SECTION_ADDRESS_MASK (-1 << 20)
29 /* must be 16Kb (0x4000) aligned - clear out the TTB */
30 for (ttbPtr
=TTB_BASE
; ttbPtr
<(TTB_SIZE
+TTB_BASE
); ttbPtr
++)
35 /* Set the TTB base address */
36 asm volatile("mcr p15, 0, %0, c2, c0, 0" : : "r" (TTB_BASE
));
38 /* Set all domains to manager status */
39 asm volatile("mcr p15, 0, %0, c3, c0, 0" : : "r" (0xFFFFFFFF));
42 void map_section(unsigned int pa
, unsigned int va
, int mb
, int cache_flags
) {
47 section_no
= va
>> 20; /* sections are 1Mb size */
48 ttbPtr
= TTB_BASE
+ section_no
;
49 pa
&= SECTION_ADDRESS_MASK
; /* align to 1Mb */
50 for(i
=0; i
<mb
; i
++, pa
+= MB
) {
53 1 << 10 | /* superuser - r/w, user - no access */
54 0 << 5 | /* domain 0th */
55 1 << 4 | /* should be "1" */
57 1 << 1; /* Section signature */
61 void enable_mmu(void) {
65 "MRC p15, 0, %r0, c1, c0, 0\n" /* Read reg1, control register */
73 if ( !(regread
& 0x04) || !(regread
& 0x00001000) ) /* Was the ICache or DCache Enabled? */
74 clean_dcache(); /* If so we need to clean the DCache before invalidating below */
76 asm volatile("mov r0, #0\n"
77 "mcr p15, 0, r0, c8, c7, 0\n" /* invalidate TLB */
79 "mcr p15, 0, r0, c7, c7,0\n" /* invalidate both icache and dcache */
81 "mrc p15, 0, r0, c1, c0, 0\n"
82 "orr r0, r0, #1<<0\n" /* enable mmu bit, icache and dcache */
83 "orr r0, r0, #1<<2\n" /* enable dcache */
84 "orr r0, r0, #1<<12\n" /* enable icache */
85 "mcr p15, 0, r0, c1, c0, 0" : : : "r0");
86 asm volatile("nop \n nop \n nop \n nop");
89 #if CONFIG_CPU == IMX31L
90 void __attribute__((naked
)) invalidate_dcache_range(const void *base
, unsigned int size
)
94 "mcrr p15, 0, r1, r0, c14 \n"
97 (void)base
; (void)size
;
100 /* Invalidate DCache for this range */
101 /* Will do write back */
102 void invalidate_dcache_range(const void *base
, unsigned int size
) {
103 unsigned int addr
= (((int) base
) & ~31); /* Align start to cache line*/
104 unsigned int end
= ((addr
+size
) & ~31)+64; /* Align end to cache line, pad */
107 "mcr p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
110 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
111 "addne %0, %0, #32 \n"
113 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
114 "addne %0, %0, #32 \n"
116 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
117 "addne %0, %0, #32 \n"
119 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
120 "addne %0, %0, #32 \n"
122 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
123 "addne %0, %0, #32 \n"
125 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
126 "addne %0, %0, #32 \n"
128 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
129 "addne %0, %0, #32 \n"
133 "mcr p15,0,%0,c7,c10,4\n" /* Drain write buffer */
134 : : "r" (addr
), "r" (end
));
139 #if CONFIG_CPU == IMX31L
140 void __attribute__((naked
)) clean_dcache_range(const void *base
, unsigned int size
)
144 "mcrr p15, 0, r1, r0, c12 \n"
147 (void)base
; (void)size
;
150 /* clean DCache for this range */
151 /* forces DCache writeback for the specified range */
152 void clean_dcache_range(const void *base
, unsigned int size
) {
153 unsigned int addr
= (int) base
;
154 unsigned int end
= addr
+size
+32;
158 "mcr p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
161 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
162 "addlo %0, %0, #32 \n"
164 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
165 "addlo %0, %0, #32 \n"
167 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
168 "addlo %0, %0, #32 \n"
170 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
171 "addlo %0, %0, #32 \n"
173 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
174 "addlo %0, %0, #32 \n"
176 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
177 "addlo %0, %0, #32 \n"
179 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
180 "addlo %0, %0, #32 \n"
184 "mcr p15,0,%0,c7,c10,4 \n" /* Drain write buffer */
185 : : "r" (addr
), "r" (end
));
189 #if CONFIG_CPU == IMX31L
190 void __attribute__((naked
)) dump_dcache_range(const void *base
, unsigned int size
)
194 "mcrr p15, 0, r1, r0, c6 \n"
197 (void)base
; (void)size
;
200 /* Dump DCache for this range */
201 /* Will *NOT* do write back */
202 void dump_dcache_range(const void *base
, unsigned int size
) {
203 unsigned int addr
= (int) base
;
204 unsigned int end
= addr
+size
;
206 "tst %0, #31 \n" /* Check to see if low five bits are set */
207 "bic %0, %0, #31 \n" /* Clear them */
208 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line, if those bits were set */
209 "add %0, %0, #32 \n" /* Move to the next cache line */
210 "tst %1, #31 \n" /* Check last line for bits set */
211 "bic %1, %1, #31 \n" /* Clear those bits */
212 "mcrne p15, 0, %1, c7, c14, 1 \n" /* Clean and invalidate this line, if not cache aligned */
214 "mcr p15, 0, %0, c7, c6, 1 \n" /* Invalidate this line */
215 "add %0, %0, #32 \n" /* Next cache line */
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
)) clean_dcache(void)
228 /* Clean entire data cache */
230 "mcr p15, 0, r0, c7, c10, 0 \n"
235 /* Cleans entire DCache */
236 void clean_dcache(void)
238 unsigned int index
, addr
;
240 for(index
= 0; index
<= 63; index
++) {
241 addr
= (0 << 5) | (index
<< 26);
243 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
245 addr
= (1 << 5) | (index
<< 26);
247 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
249 addr
= (2 << 5) | (index
<< 26);
251 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
253 addr
= (3 << 5) | (index
<< 26);
255 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
257 addr
= (4 << 5) | (index
<< 26);
259 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
261 addr
= (5 << 5) | (index
<< 26);
263 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
265 addr
= (6 << 5) | (index
<< 26);
267 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
269 addr
= (7 << 5) | (index
<< 26);
271 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */