| @@ -74,220 +74,120 @@ | | | @@ -74,220 +74,120 @@ |
74 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 74 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
75 | * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT, | | 75 | * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT, |
76 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | | 76 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
77 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | | 77 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
78 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 78 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
79 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 79 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
80 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 80 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
81 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 81 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
82 | * SUCH DAMAGE. | | 82 | * SUCH DAMAGE. |
83 | */ | | 83 | */ |
84 | | | 84 | |
85 | #include "opt_omap.h" | | 85 | #include "opt_omap.h" |
86 | #include "opt_com.h" | | 86 | #include "opt_com.h" |
| | | 87 | #include "opt_cpuoptions.h" |
| | | 88 | #include "opt_cputypes.h" |
| | | 89 | #include "opt_multiprocessor.h" |
87 | | | 90 | |
88 | #include <machine/asm.h> | | 91 | #include <arm/asm.h> |
89 | #include <arm/armreg.h> | | 92 | #include <arm/armreg.h> |
90 | #include "assym.h" | | 93 | #include "assym.h" |
91 | | | 94 | |
92 | #include <arm/omap/omap2_obioreg.h> | | 95 | #include <arm/omap/omap2_obioreg.h> |
93 | #include <evbarm/beagle/beagle.h> | | 96 | #include <evbarm/beagle/beagle.h> |
94 | | | 97 | |
95 | #ifdef MEMSIZE | | 98 | #ifdef CPU_CORTEXA9 |
96 | #define INIT_MEMSIZE MEMSIZE | | 99 | #include <arm/cortex/a9tmr_reg.h> |
97 | #else | | | |
98 | #define INIT_MEMSIZE 128 | | | |
99 | #endif | | 100 | #endif |
100 | | | 101 | |
101 | RCSID("$NetBSD: beagle_start.S,v 1.15 2013/06/16 17:57:21 matt Exp $") | | 102 | RCSID("$NetBSD: beagle_start.S,v 1.16 2013/06/17 04:39:48 matt Exp $") |
| | | 103 | |
| | | 104 | #undef VERBOSE_INIT_ARM |
| | | 105 | #define VERBOSE_INIT_ARM |
| | | 106 | #if defined(VERBOSE_INIT_ARM) |
| | | 107 | #define XPUTC(n) mov r0, n; bl xputc |
| | | 108 | #define COM_MULT 4 |
| | | 109 | #define XPUTC_COM 1 |
| | | 110 | #else |
| | | 111 | #define XPUTC(n) |
| | | 112 | #endif |
102 | | | 113 | |
103 | #define Invalidate_I_cache(reg) \ | | 114 | #define INIT_MEMSIZE 128 |
104 | mcr p15, 0, reg, c7, c5, 0 /* Invalidate Entire I cache */ | | 115 | #define TEMP_L1_TABLE (0x80000000 + INIT_MEMSIZE * 0x100000 - L1_TABLE_SIZE) |
105 | | | 116 | |
106 | /* | | 117 | /* |
107 | * Kernel start routine for BEAGLEBOARD boards. | | 118 | * Kernel start routine for BEAGLEBOARD boards. |
108 | * At this point, this code has been loaded into SDRAM | | 119 | * At this point, this code has been loaded into SDRAM |
109 | * and the MMU is off | | 120 | * and the MMU is off |
110 | */ | | 121 | */ |
111 | .section .start,"ax",%progbits | | 122 | .section .start,"ax",%progbits |
112 | | | 123 | |
113 | .global _C_LABEL(beagle_start) | | 124 | .global _C_LABEL(beagle_start) |
114 | _C_LABEL(beagle_start): | | 125 | _C_LABEL(beagle_start): |
115 | /* Move into supervisor mode and disable IRQs/FIQs. */ | | 126 | /* Move into supervisor mode and disable IRQs/FIQs. */ |
116 | cpsid if, #PSR_SVC32_MODE | | 127 | cpsid if, #PSR_SVC32_MODE |
117 | | | 128 | |
118 | ldr r4, .Luboot_args | | | |
119 | stmia r4, {r0-r3} | | | |
120 | | | | |
121 | /* | | 129 | /* |
122 | * Set up a preliminary mapping in the MMU to allow us to run | | 130 | * Save any arguments passed to us. |
123 | * at KERNEL_BASE with caches on. | | | |
124 | */ | | 131 | */ |
125 | /* Build page table from scratch */ | | 132 | movw r4, #:lower16:uboot_args |
126 | ldr r0, Ltemp_l1_table | | 133 | movt r4, #:upper16:uboot_args |
127 | mov r1, r0 /* Save the page table address. */ | | 134 | stmia r4, {r0-r3} |
128 | /* Zero the entire table so all virtual addresses are invalid. */ | | | |
129 | mov r2, #L1_TABLE_SIZE /* in bytes */ | | | |
130 | mov r3, #0 | | | |
131 | mov r4, r3 | | | |
132 | mov r5, r3 | | | |
133 | mov r6, r3 | | | |
134 | mov r7, r3 | | | |
135 | mov r8, r3 | | | |
136 | mov r10, r3 | | | |
137 | mov r11, r3 | | | |
138 | 1: stmia r1!, {r3-r8,r10-r11} | | | |
139 | stmia r1!, {r3-r8,r10-r11} | | | |
140 | stmia r1!, {r3-r8,r10-r11} | | | |
141 | stmia r1!, {r3-r8,r10-r11} | | | |
142 | subs r2, r2, #(4 * 4 * 8) /* bytes per loop */ | | | |
143 | bne 1b | | | |
144 | | | | |
145 | /* Now create our entries per the mmu_init_table. */ | | | |
146 | l1table .req r0 | | | |
147 | va .req r1 | | | |
148 | pa .req r2 | | | |
149 | n_sec .req r3 | | | |
150 | attr .req r4 | | | |
151 | itable .req r5 | | | |
152 | l1sfrm .req r6 | | | |
153 | adr itable, mmu_init_table | | | |
154 | ldr l1sfrm, Ll1_s_frame | | | |
155 | b 3f | | | |
156 | 2: str pa, [l1table, va, lsl #2] | | | |
157 | add va, va, #1 | | | |
158 | add pa, pa, #(L1_S_SIZE) | | | |
159 | adds n_sec, n_sec, #-1 | | | |
160 | bhi 2b | | | |
161 | 3: ldmia itable!, {va,pa,n_sec,attr} | | | |
162 | /* Convert va to l1 offset: va = 4 * (va >> L1_S_SHIFT) */ | | | |
163 | lsr va, va, #L1_S_SHIFT | | | |
164 | /* Convert pa to l1 entry: pa = (pa & L1_S_FRAME) | attr */ | | | |
165 | and pa, pa, l1sfrm | | | |
166 | orr pa, pa, attr | | | |
167 | cmp n_sec, #0 | | | |
168 | bne 2b | | | |
169 | .unreq va | | | |
170 | .unreq pa | | | |
171 | .unreq n_sec | | | |
172 | .unreq attr | | | |
173 | .unreq itable | | | |
174 | .unreq l1table | | | |
175 | .unreq l1sfrm | | | |
176 | | | 135 | |
| | | 136 | #ifdef CPU_CORTEXA9 |
177 | /* | | 137 | /* |
178 | * In theory, because the MMU is off, we shouldn't need all of this, | | 138 | * Turn on the SCU if we are on a Cortex-A9 |
179 | * but let's not take any chances and do a typical sequence to set | | | |
180 | * the Translation Table Base. | | | |
181 | */ | | 139 | */ |
182 | | | 140 | bl a9_start |
183 | Invalidate_I_cache(r0) | | 141 | XPUTC(#67) |
184 | | | 142 | #endif |
185 | ldr r2, Lctl_ID_dis /* Disable I+D caches */ | | | |
186 | mrc p15, 0, r1, c1, c0, 0 /* " " " */ | | | |
187 | and r1, r1, r2 /* " " " */ | | | |
188 | mcr p15, 0, r1, c1, c0, 0 /* " " " */ | | | |
189 | | | | |
190 | mcr p15, 0, r0, c7, c10, 4 /* Drain the write buffers. */ | | | |
191 | mcr p15, 0, r0, c2, c0, 0 /* Set Translation Table Base */ | | | |
192 | mcr p15, 0, r0, c8, c7, 0 /* Invalidate TLBs */ | | | |
193 | | | | |
194 | /* Set the Domain Access register. Very important! */ | | | |
195 | mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT) | | | |
196 | mcr p15, 0, r0, c3, c0, 0 | | | |
197 | | | 143 | |
198 | /* | | 144 | /* |
199 | * Enable the MMU, etc. | | 145 | * Set up a preliminary mapping in the MMU to allow us to run |
| | | 146 | * at KERNEL_BASE with caches on. |
200 | */ | | 147 | */ |
201 | mrc p15, 0, r0, c1, c0, 0 | | 148 | movw r0, #:lower16:TEMP_L1_TABLE |
202 | ldr r1, Lcontrol_wax | | 149 | movt r0, #:upper16:TEMP_L1_TABLE |
203 | and r0, r0, r1 | | 150 | adr r1, .Lmmu_init_table |
204 | ldr r1, Lcontrol_clr | | 151 | bl arm_boot_l1pt_init |
205 | mvn r1, r1 | | 152 | |
206 | and r0, r0, r1 | | 153 | XPUTC(#68) |
207 | ldr r1, Lcontrol_set | | | |
208 | orr r0, r0, r1 | | | |
209 | mcr p15, 0, r0, c1, c0, 0 | | | |
210 | | | 154 | |
211 | /* | | 155 | /* |
212 | * Ensure that the coprocessor has finished turning on the MMU. | | 156 | * Turn on the MMU, Caches, etc. |
213 | */ | | 157 | */ |
214 | mrc p15, 0, r0, c2, c0, 0 /* Read an arbitrary value. */ | | 158 | movw r0, #:lower16:TEMP_L1_TABLE |
215 | mov r0, r0 /* Stall until read completes. */ | | 159 | movt r0, #:upper16:TEMP_L1_TABLE |
| | | 160 | bl arm_cpuinit |
| | | 161 | XPUTC(#90) |
216 | | | 162 | |
217 | /* | | 163 | /* |
218 | * Jump to start in locore.S, which in turn will call initarm and main. | | 164 | * Jump to start in locore.S, which in turn will call initarm and main. |
219 | */ | | 165 | */ |
220 | b start /* Jump to start (flushes pipeline). */ | | 166 | b start /* Jump to start (flushes pipeline). */ |
221 | nop | | 167 | nop |
222 | nop | | 168 | nop |
223 | nop | | 169 | nop |
224 | nop | | 170 | nop |
225 | | | 171 | |
226 | /* NOTREACHED */ | | 172 | /* NOTREACHED */ |
227 | | | 173 | |
228 | .Luboot_args: | | 174 | #include <arm/cortex/a9_mpsubr.S> |
229 | .word uboot_args | | | |
230 | Ll1_s_frame: | | | |
231 | .word L1_S_FRAME | | | |
232 | Ltemp_l1_table: | | | |
233 | /* Put the temporary L1 translation table at the end of SDRAM. */ | | | |
234 | .word 0x80000000 + INIT_MEMSIZE * 0x100000 - L1_TABLE_SIZE | | | |
235 | | | | |
236 | /* | | | |
237 | * Coprocessor register initialization values | | | |
238 | */ | | | |
239 | # define CPU_AUXCTL_CZ (1 << 6) /* Restrict Cache Size */ | | | |
240 | | | | |
241 | /* bits to set in the Control Register */ | | | |
242 | Lcontrol_set: | | | |
243 | .word CPU_CONTROL_MMU_ENABLE | \ | | | |
244 | CPU_CONTROL_AFLT_ENABLE | \ | | | |
245 | CPU_CONTROL_DC_ENABLE | \ | | | |
246 | CPU_CONTROL_IC_ENABLE | \ | | | |
247 | CPU_CONTROL_BPRD_ENABLE | | | |
248 | | | | |
249 | /* bits to clear in the Control Register */ | | | |
250 | Lcontrol_clr: | | | |
251 | .word 0 | | | |
252 | | | | |
253 | /* bits to "write as existing" in the Control Register */ | | | |
254 | Lcontrol_wax: | | | |
255 | .word (1 << 31) | \ | | | |
256 | (1 << 26) | \ | | | |
257 | (0x7ff << 14) | \ | | | |
258 | (0xff << 3) | | | |
259 | | | | |
260 | /* bits to disable the caches */ | | | |
261 | Lctl_ID_dis: | | | |
262 | .word ~(CPU_CONTROL_IC_ENABLE|CPU_CONTROL_DC_ENABLE) | | | |
263 | | | | |
264 | /* bit to restrict cache size */ | | | |
265 | Lauxctl_CZ_restrict: | | | |
266 | .word CPU_AUXCTL_CZ | | | |
267 | | | | |
268 | | | | |
269 | /* We'll modify va and pa at run time so we can use relocatable addresses. */ | | | |
270 | #define MMU_INIT(va,pa,n_sec,attr) \ | | | |
271 | .word va ; \ | | | |
272 | .word pa ; \ | | | |
273 | .word n_sec ; \ | | | |
274 | .word attr ; | | | |
275 | | | 175 | |
276 | mmu_init_table: | | 176 | .Lmmu_init_table: |
277 | /* Map KERNEL_BASE VA to SDRAM PA, write-back cacheable */ | | 177 | /* Map KERNEL_BASE VA to SDRAM PA, write-back cacheable, shareable */ |
278 | MMU_INIT(KERNEL_BASE, KERNEL_BASE, | | 178 | MMU_INIT(KERNEL_BASE, KERNEL_BASE, |
279 | (INIT_MEMSIZE * L1_S_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, | | 179 | (INIT_MEMSIZE * L1_S_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, |
280 | L1_S_PROTO | L1_S_APv7_KRW | L1_S_B | L1_S_C) | | 180 | L1_S_PROTO | L1_S_APv7_KRW | L1_S_B | L1_S_C | L1_S_V6_S) |
281 | | | 181 | |
282 | /* Map first 1MB of L4 CORE (so console will work) */ | | 182 | /* Map first 1MB of L4 CORE (so console will work) */ |
283 | MMU_INIT(OMAP_L4_CORE_VBASE, OMAP_L4_CORE_BASE, | | 183 | MMU_INIT(OMAP_L4_CORE_VBASE, OMAP_L4_CORE_BASE, |
284 | (OMAP_L4_CORE_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, | | 184 | (OMAP_L4_CORE_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, |
285 | L1_S_PROTO | L1_S_APv7_KRW) | | 185 | L1_S_PROTO | L1_S_APv7_KRW) |
286 | | | 186 | |
287 | #if OMAP_L4_CORE_BASE <= CONSADDR \ | | 187 | #if OMAP_L4_CORE_BASE <= CONSADDR \ |
288 | && CONSADDR < OMAP_L4_CORE_BASE + OMAP_L4_CORE_SIZE | | 188 | && CONSADDR < OMAP_L4_CORE_BASE + OMAP_L4_CORE_SIZE |
289 | /* Map first 1MB of L4 CORE 1:1 (so console will work) */ | | 189 | /* Map first 1MB of L4 CORE 1:1 (so console will work) */ |
290 | MMU_INIT(OMAP_L4_CORE_BASE, OMAP_L4_CORE_BASE, | | 190 | MMU_INIT(OMAP_L4_CORE_BASE, OMAP_L4_CORE_BASE, |
291 | (OMAP_L4_CORE_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, | | 191 | (OMAP_L4_CORE_SIZE + L1_S_SIZE - 1) / L1_S_SIZE, |
292 | L1_S_PROTO | L1_S_APv7_KRW) | | 192 | L1_S_PROTO | L1_S_APv7_KRW) |
293 | #endif | | 193 | #endif |