gemini_start.S revision 1.6 1 /* $NetBSD: gemini_start.S,v 1.6 2009/10/21 14:15:51 rmind Exp $ */
2
3 /*
4 * Machine dependant startup code for GEMINI boards.
5 * Based on omap_start.S
6 *
7 * Copyright (c) 2002, 2003 Genetec Corporation. All rights reserved.
8 * Written by Hiroyuki Bessho for Genetec Corporation.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. The name of Genetec Corporation may not be used to endorse or
19 * promote products derived from this software without specific prior
20 * written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 * Copyright (c) 2003
35 * Ichiro FUKUHARA <ichiro (at) ichiro.org>.
36 * All rights reserved.
37 *
38 * Redistribution and use in source and binary forms, with or without
39 * modification, are permitted provided that the following conditions
40 * are met:
41 * 1. Redistributions of source code must retain the above copyright
42 * notice, this list of conditions and the following disclaimer.
43 * 2. Redistributions in binary form must reproduce the above copyright
44 * notice, this list of conditions and the following disclaimer in the
45 * documentation and/or other materials provided with the distribution.
46 *
47 * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR
48 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
49 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
50 * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
51 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 * SUCH DAMAGE.
58 *
59 * Copyright (c) 2007 Microsoft
60 * All rights reserved.
61 *
62 * Redistribution and use in source and binary forms, with or without
63 * modification, are permitted provided that the following conditions
64 * are met:
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 * 2. Redistributions in binary form must reproduce the above copyright
68 * notice, this list of conditions and the following disclaimer in the
69 * documentation and/or other materials provided with the distribution.
70 * 3. All advertising materials mentioning features or use of this software
71 * must display the following acknowledgement:
72 * This product includes software developed by Microsoft
73 *
74 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
75 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
76 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
77 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT,
78 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
79 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
80 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
81 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
82 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
83 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
84 * SUCH DAMAGE.
85 */
86
87 #include "opt_gemini.h"
88 #include "opt_com.h"
89 #include "assym.h"
90
91 #include <machine/asm.h>
92 #include <arm/armreg.h>
93 #undef DOMAIN_CLIENT /* assym.h defines as 1, but pte.h defines as 0x01 */
94 #include <arm/arm32/pmap.h>
95 #include <arm/gemini/gemini_reg.h>
96 #include <evbarm/gemini/gemini.h>
97
98 RCSID("$NetBSD: gemini_start.S,v 1.6 2009/10/21 14:15:51 rmind Exp $")
99
100
101 #if defined(VERBOSE_INIT_ARM)
102 # define _PUTCHAR(addr, areg, breg, c) \
103 ldr areg, addr; \
104 1: \
105 ldr breg, [ areg, #0x14 ]; /* LSR */ \
106 tst breg, #0x20; /* TXRDY? */ \
107 beq 1b; \
108 mov breg, #(c); /* c */ \
109 str breg, [ areg ]; /* TXDATA */ \
110 2: \
111 ldr breg, [ areg, #0x14 ]; /* LSR */ \
112 tst breg, #0x40; /* TSRE? */ \
113 beq 2b;
114 #else
115 # define _PUTCHAR(addr, areg, breg, c)
116 #endif
117
118
119 /*
120 * Kernel start routine for GEMINI Eval board.
121 * At this point, this code has been loaded into SDRAM
122 * and the MMU is off
123 */
124 .section .start,"ax",%progbits
125
126 .global _C_LABEL(gemini_start)
127 _C_LABEL(gemini_start):
128 /* Move into supervisor mode and disable IRQs/FIQs. */
129 mrs r0, cpsr
130 bic r0, r0, #PSR_MODE
131 orr r0, r0, #(I32_bit | F32_bit | PSR_SVC32_MODE)
132 msr cpsr, r0
133
134 _PUTCHAR(Lconsole_pbase, r4, r3, 'a')
135
136 /*
137 * Set up a preliminary mapping in the MMU to allow us to run
138 * at KERNEL_BASE with caches on.
139 */
140 /* Build page table from scratch */
141 ldr r0, Ltemp_l1_table
142 mov r1, r0 /* Save the page table address. */
143 /* Zero the entire table so all virtual addresses are invalid. */
144 mov r2, #L1_TABLE_SIZE /* in bytes */
145 mov r3, #0
146 mov r4, r3
147 mov r5, r3
148 mov r6, r3
149 mov r7, r3
150 mov r8, r3
151 mov r10, r3
152 mov r11, r3
153 1: stmia r1!, {r3-r8,r10-r11}
154 stmia r1!, {r3-r8,r10-r11}
155 stmia r1!, {r3-r8,r10-r11}
156 stmia r1!, {r3-r8,r10-r11}
157 subs r2, r2, #(4 * 4 * 8) /* bytes per loop */
158 bne 1b
159
160 _PUTCHAR(Lconsole_pbase, r4, r3, 'b')
161
162 /* Now create our entries per the mmu_init_table. */
163 l1table .req r0
164 va .req r1
165 pa .req r2
166 n_sec .req r3
167 attr .req r4
168 itable .req r5
169 l1sfrm .req r6
170 ldr l1table, Ltemp_l1_table
171 adr itable, mmu_init_table
172 ldr l1sfrm, Ll1_s_frame
173 b 3f
174 2: str pa, [l1table, va]
175 add va, va, #4
176 add pa, pa, #(L1_S_SIZE)
177 adds n_sec, n_sec, #-1
178 bhi 2b
179 3: ldmia itable!, {va,pa,n_sec,attr}
180 /* Convert va to l1 offset: va = 4 * (va >> L1_S_SHIFT) */
181 mov va, va, LSR #L1_S_SHIFT
182 mov va, va, LSL #2
183 /* Convert pa to l1 entry: pa = (pa & L1_S_FRAME) | attr */
184 and pa, pa, l1sfrm
185 orr pa, pa, attr
186 cmp n_sec, #0
187 bne 2b
188 mov r5, r0 /* l1table */
189 .unreq va
190 .unreq pa
191 .unreq n_sec
192 .unreq attr
193 .unreq itable
194 .unreq l1table
195 .unreq l1sfrm
196
197 _PUTCHAR(Lconsole_pbase, r4, r3, 'c')
198
199 /*
200 * using FA526 -specific cache ops here...
201 */
202 mov r0, #0
203 mcr p15, 0, r0, c7, c5, 0 /* Invalidate Entire I cache */
204 mcr p15, 0, r0, c7, c14, 0 /* Clean & Invalidate Entire D cache */
205
206 ldr r2, Lctl_ID_dis /* Disable I+D caches */
207 mrc p15, 0, r1, c1, c0, 0 /* " " " */
208 and r1, r1, r2 /* " " " */
209 mcr p15, 0, r1, c1, c0, 0 /* " " " */
210
211 _PUTCHAR(Lconsole_pbase, r4, r3, 'd')
212
213 mcr p15, 0, r0, c7, c5, 6 /* invalidate BTB all */
214 mcr p15, 0, r0, c7, c10, 4 /* Drain the write buffers. */
215 mcr p15, 0, r5, c2, c0, 0 /* Set Translation Table Base */
216 mcr p15, 0, r0, c8, c7, 0 /* Invalidate TLBs */
217
218 /* Set the Domain Access register */
219 mov r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
220 mcr p15, 0, r0, c3, c0, 0
221
222 /*
223 * set Extension Control Enable in ECR, so we can use BTB
224 */
225 ldr r0, Lecr_set
226 mcr p15, 0, r0, c1, c1, 0
227
228 /*
229 * Enable the MMU, etc.
230 */
231 mrc p15, 0, r0, c1, c0, 0
232 ldr r1, Lcontrol_wax
233 and r0, r0, r1
234 ldr r1, Lcontrol_clr
235 mvn r1, r1
236 and r0, r0, r1
237 ldr r1, Lcontrol_set
238 orr r0, r0, r1
239 mcr p15, 0, r0, c1, c0, 0
240
241 /*
242 * Ensure that the coprocessor has finished turning on the MMU.
243 */
244 mrc p15, 0, r0, c2, c0, 0 /* Read an arbitrary value. */
245 mov r0, r0 /* Stall until read completes. */
246
247 _PUTCHAR(Luart_vbase, r4, r3, 'e')
248
249 /*
250 * Zero .bss
251 */
252 ldr r0, L_edata
253 ldr r1, L_end
254 mov r2, #0
255 1:
256 str r2, [r0], #0x04 /* *r0++ = r2 */
257 cmp r0, r1
258 bne 1b
259
260 #if 0
261 /*
262 * Jump to start in locore.S, which in turn will call initarm and main.
263 */
264 adr r0, Ltestjmp
265 ldr pc, [r0]
266 nop
267 nop
268 nop
269 nop
270 testjmp:
271 #endif
272
273 _PUTCHAR(Luart_vbase, r4, r3, 'f')
274
275 adr r0, Lstart
276 ldr pc, [r0]
277 nop
278 nop
279 nop
280 nop
281
282 /* NOTREACHED */
283
284 L_edata:
285 .word _C_LABEL(_edata)
286 L_end:
287 .word _C_LABEL(_end)
288
289 #if 0
290 Ltestjmp:
291 .word testjmp
292 #endif
293
294 Lstart:
295 .word start
296 Ll1_s_frame:
297 .word L1_S_FRAME
298 Ltemp_l1_table:
299 /* Put the temporary L1 translation table at the end of SDRAM. */
300 .word MEMSIZE * 0x100000 - L1_TABLE_SIZE
301
302 /*
303 * Coprocessor register initialization values
304 */
305 #if !defined(CPU_ECR_ECE)
306 # define CPU_ECR_ECE 1
307 #endif
308 /* bits to set in the Extension Control Register */
309 Lecr_set:
310 .word CPU_ECR_ECE
311
312 #if !defined(CPU_CONTROL_BTB_ENABLE)
313 # define CPU_CONTROL_BTB_ENABLE (1 << 11)
314 #endif
315 /* bits to set in the Control Register */
316 /* bits 6..4 SB1 */
317 Lcontrol_set:
318 .word CPU_CONTROL_MMU_ENABLE | \
319 CPU_CONTROL_AFLT_ENABLE | \
320 CPU_CONTROL_DC_ENABLE | \
321 CPU_CONTROL_WBUF_ENABLE | \
322 CPU_CONTROL_32BP_ENABLE | \
323 CPU_CONTROL_32BD_ENABLE | \
324 CPU_CONTROL_LABT_ENABLE | \
325 CPU_CONTROL_SYST_ENABLE | \
326 CPU_CONTROL_IC_ENABLE | \
327 CPU_CONTROL_DC_ENABLE | \
328 CPU_CONTROL_BTB_ENABLE
329
330 /* bits to clear in the Control Register */
331 /* bits 31..14, 10, SBZ */
332 Lcontrol_clr:
333 .word ((~0) << 14) | \
334 (1 << 10)
335
336 /* bits to "write as existing" in the Control Register */
337 Lcontrol_wax:
338 .word CPU_CONTROL_BEND_ENABLE
339
340 /* bits to disable the caches */
341 Lctl_ID_dis:
342 .word ~(CPU_CONTROL_IC_ENABLE|CPU_CONTROL_DC_ENABLE)
343
344 /* console addressing */
345 Lconsole_pbase:
346 #if 0
347 .word CONSADDR
348 #else
349 .word GEMINI_UART_BASE
350 #endif
351 Luart_vbase:
352 .word GEMINI_UART_VBASE
353
354
355 /* We'll modify va and pa at run time so we can use relocatable addresses. */
356 #define MMU_INIT(va,pa,n_sec,attr) \
357 .word va ; \
358 .word pa ; \
359 .word n_sec ; \
360 .word attr ;
361
362 mmu_init_table:
363 /* Maintain current 1:1 addressability */
364 MMU_INIT(KERNEL_BASE_phys, KERNEL_BASE_phys,
365 (MEMSIZE * L1_S_SIZE + L1_S_SIZE - 1) / L1_S_SIZE,
366 L1_S_PROTO | L1_S_AP(AP_KRW) | L1_S_B | L1_S_C)
367
368 /* Map Kernel base VA:PA, write-back cacheable */
369 MMU_INIT(KERNEL_BASE_virt, KERNEL_BASE_phys,
370 (MEMSIZE * L1_S_SIZE + L1_S_SIZE - 1) / L1_S_SIZE,
371 L1_S_PROTO | L1_S_AP(AP_KRW) | L1_S_B | L1_S_C)
372
373 /* Map Gemini GLOBAL regs */
374 MMU_INIT(GEMINI_GLOBAL_VBASE, GEMINI_GLOBAL_BASE,
375 1,
376 L1_S_PROTO | L1_S_AP(AP_KRW))
377
378 /* Map Gemini UART */
379 MMU_INIT(GEMINI_UART_VBASE, GEMINI_UART_BASE,
380 1,
381 L1_S_PROTO | L1_S_AP(AP_KRW))
382
383 /* Map Gemini LPC Host Controlr Space */
384 MMU_INIT(GEMINI_LPCHC_VBASE, GEMINI_LPCHC_BASE,
385 1,
386 L1_S_PROTO | L1_S_AP(AP_KRW))
387
388 /* Map Gemini LPC IO Space */
389 MMU_INIT(GEMINI_LPCIO_VBASE, GEMINI_LPCIO_BASE,
390 1,
391 L1_S_PROTO | L1_S_AP(AP_KRW))
392
393 /* Map Gemini DRAM Controller Space */
394 MMU_INIT(GEMINI_DRAMC_VBASE, GEMINI_DRAMC_BASE,
395 1,
396 L1_S_PROTO | L1_S_AP(AP_KRW))
397
398 /* end of table */
399 MMU_INIT(0, 0, 0, 0)
400
401