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 /* Invalidate DCache for this range */
90 /* Will do write back */
91 void invalidate_dcache_range(const void *base
, unsigned int size
) {
92 unsigned int addr
= (((int) base
) & ~31); /* Align start to cache line*/
93 unsigned int end
= ((addr
+size
) & ~31)+64; /* Align end to cache line, pad */
96 "mcr p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
99 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
100 "addne %0, %0, #32 \n"
102 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
103 "addne %0, %0, #32 \n"
105 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
106 "addne %0, %0, #32 \n"
108 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
109 "addne %0, %0, #32 \n"
111 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
112 "addne %0, %0, #32 \n"
114 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
115 "addne %0, %0, #32 \n"
117 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line */
118 "addne %0, %0, #32 \n"
122 "mcr p15,0,%0,c7,c10,4\n" /* Drain write buffer */
123 : : "r" (addr
), "r" (end
));
126 /* clean DCache for this range */
127 /* forces DCache writeback for the specified range */
128 void clean_dcache_range(const void *base
, unsigned int size
) {
129 unsigned int addr
= (int) base
;
130 unsigned int end
= addr
+size
+32;
134 "mcr p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
137 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
138 "addlo %0, %0, #32 \n"
140 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
141 "addlo %0, %0, #32 \n"
143 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
144 "addlo %0, %0, #32 \n"
146 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
147 "addlo %0, %0, #32 \n"
149 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
150 "addlo %0, %0, #32 \n"
152 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
153 "addlo %0, %0, #32 \n"
155 "mcrlo p15, 0, %0, c7, c10, 1 \n" /* Clean this line */
156 "addlo %0, %0, #32 \n"
160 "mcr p15,0,%0,c7,c10,4 \n" /* Drain write buffer */
161 : : "r" (addr
), "r" (end
));
164 /* Dump DCache for this range */
165 /* Will *NOT* do write back */
166 void dump_dcache_range(const void *base
, unsigned int size
) {
167 unsigned int addr
= (int) base
;
168 unsigned int end
= addr
+size
;
170 "tst %0, #31 \n" /* Check to see if low five bits are set */
171 "bic %0, %0, #31 \n" /* Clear them */
172 "mcrne p15, 0, %0, c7, c14, 1 \n" /* Clean and invalidate this line, if those bits were set */
173 "add %0, %0, #32 \n" /* Move to the next cache line */
174 "tst %1, #31 \n" /* Check last line for bits set */
175 "bic %1, %1, #31 \n" /* Clear those bits */
176 "mcrne p15, 0, %1, c7, c14, 1 \n" /* Clean and invalidate this line, if not cache aligned */
178 "mcr p15, 0, %0, c7, c6, 1 \n" /* Invalidate this line */
179 "add %0, %0, #32 \n" /* Next cache line */
183 "mcr p15,0,%0,c7,c10,4 \n" /* Drain write buffer */
184 : : "r" (addr
), "r" (end
));
186 /* Cleans entire DCache */
187 void clean_dcache(void)
189 unsigned int index
, addr
;
191 for(index
= 0; index
<= 63; index
++) {
192 addr
= (0 << 5) | (index
<< 26);
194 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
196 addr
= (1 << 5) | (index
<< 26);
198 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
200 addr
= (2 << 5) | (index
<< 26);
202 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
204 addr
= (3 << 5) | (index
<< 26);
206 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
208 addr
= (4 << 5) | (index
<< 26);
210 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
212 addr
= (5 << 5) | (index
<< 26);
214 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
216 addr
= (6 << 5) | (index
<< 26);
218 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */
220 addr
= (7 << 5) | (index
<< 26);
222 "mcr p15, 0, %0, c7, c10, 2 \n" /* Clean this entry by index */