1/*	$NetBSD: rpi_start.S,v 1.7 2012/09/23 15:56:32 skrll Exp $	*/
2
3/*
4 * Copyright (c) 2002, 2003  Genetec Corporation.  All rights reserved.
5 * Written by Hiroyuki Bessho for Genetec Corporation.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. The name of Genetec Corporation may not be used to endorse or
16 *    promote products derived from this software without specific prior
17 *    written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 *
31 * Copyright (c) 2003
32 *	Ichiro FUKUHARA <ichiro@ichiro.org>.
33 * All rights reserved.
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
38 * 1. Redistributions of source code must retain the above copyright
39 *    notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 *    notice, this list of conditions and the following disclaimer in the
42 *    documentation and/or other materials provided with the distribution.
43 *
44 * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR
45 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
46 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
47 * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR
48 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
54 * SUCH DAMAGE.
55 *
56 * Copyright (c) 2007 Microsoft
57 * All rights reserved.
58 *
59 * Redistribution and use in source and binary forms, with or without
60 * modification, are permitted provided that the following conditions
61 * are met:
62 * 1. Redistributions of source code must retain the above copyright
63 *    notice, this list of conditions and the following disclaimer.
64 * 2. Redistributions in binary form must reproduce the above copyright
65 *    notice, this list of conditions and the following disclaimer in the
66 *    documentation and/or other materials provided with the distribution.
67 * 3. All advertising materials mentioning features or use of this software
68 *    must display the following acknowledgement:
69 *	This product includes software developed by Microsoft
70 *
71 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
72 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
73 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
74 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTERS BE LIABLE FOR ANY DIRECT,
75 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
76 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
77 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
78 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
79 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
80 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
81 * SUCH DAMAGE.
82 */
83
84#include "opt_cputypes.h"
85
86#include <machine/asm.h>
87#include <arm/armreg.h>
88#include "assym.h"
89
90RCSID("$NetBSD: rpi_start.S,v 1.2.2.3 2012/11/19 19:13:01 riz Exp $")
91
92/*
93 * Workaround Erratum 411920
94 *
95 *	- value of arg 'reg' Should Be Zero
96 */
97#define Invalidate_I_cache(reg) \
98	.p2align 5;								\
99	mcr	p15, 0, reg, c7, c5, 0;	/* Invalidate Entire I cache */		\
100	mcr	p15, 0, reg, c7, c5, 0;	/* Invalidate Entire I cache */		\
101	mcr	p15, 0, reg, c7, c5, 0;	/* Invalidate Entire I cache */		\
102	mcr	p15, 0, reg, c7, c5, 0;	/* Invalidate Entire I cache */		\
103	nop;									\
104	nop;									\
105	nop;									\
106	nop;									\
107	nop;									\
108	nop;									\
109	nop;									\
110	nop;									\
111	nop;									\
112	nop;									\
113	nop;
114
115/*
116 * Kernel start routine for RPI boards.
117 * At this point, this code has been loaded into SDRAM
118 * and the MMU is off
119 */
120	.text
121
122	.global	_C_LABEL(rpi_start)
123_C_LABEL(rpi_start):
124	adr	r8, rpi_boot_regs
125	stmia	r8!, {r0-r3}
126
127	mrs	r0, cpsr
128	bic	r0, r0, #PSR_MODE
129	orr	r0, r0, #(I32_bit | F32_bit | PSR_SVC32_MODE)
130	msr	cpsr, r0
131
132	/*
133	 * Set up a preliminary mapping in the MMU to allow us to run
134	 * at KERNEL_BASE with caches on.
135	 */
136	/* Build page table from scratch */
137	ldr	r0, Ltemp_l1_table	/* The page table address - entered into TTB later */
138	mov	r1, r0			/* Start address to clear memory. */
139	/* Zero the entire table so all virtual addresses are invalid. */
140	mov	r2, #L1_TABLE_SIZE	/* in bytes */
141	mov	r3, #0
142	mov	r4, r3
143	mov	r5, r3
144	mov	r6, r3
145	mov	r7, r3
146	mov	r8, r3
147	mov	r10, r3
148	mov	r11, r3
1491:	stmia	r1!, {r3-r8,r10-r11}
150	stmia	r1!, {r3-r8,r10-r11}
151	stmia	r1!, {r3-r8,r10-r11}
152	stmia	r1!, {r3-r8,r10-r11}
153	subs	r2, r2, #(4 * 4 * 8)	/* bytes per loop */
154	bne	1b
155
156	/* Now create our entries per the mmu_init_table. */
157	l1table	.req r0
158	va	.req r1
159	pa	.req r2
160	n_sec	.req r3
161	attr	.req r4
162	itable	.req r5
163	l1sfrm	.req r6
164
165	adr	itable, mmu_init_table
166	ldr	l1sfrm, Ll1_s_frame
167	b	3f
168
1692:	str	pa, [l1table, va]
170	add	va, va, #4
171	add	pa, pa, #(L1_S_SIZE)
172	adds	n_sec, n_sec, #-1
173	bhi	2b
174
1753:	ldmia	itable!, {va,pa,n_sec,attr}
176	mov	n_sec, n_sec, lsr #L1_S_SHIFT
177	/* Convert va to l1 offset:	va = 4 * (va >> L1_S_SHIFT)	*/
178	mov	va, va, LSR #L1_S_SHIFT
179	mov	va, va, LSL #2
180	/* Convert pa to l1 entry:	pa = (pa & L1_S_FRAME) | attr	*/
181	and	pa, pa, l1sfrm
182	orr	pa, pa, attr
183	cmp	n_sec, #0
184	bne	2b
185
186	.unreq	va
187	.unreq	pa
188	.unreq	n_sec
189	.unreq	attr
190	.unreq	itable
191	.unreq	l1table
192	.unreq	l1sfrm
193
194	/*
195	 * In theory, because the MMU is off, we shouldn't need all of this,
196	 * but let's not take any chances and do a typical sequence to set
197	 * the Translation Table Base.
198	 */
199	mov	r0, #0			/* SBZ */
200	Invalidate_I_cache(r0)
201
202	mcr	p15, 0, r0, c7, c14, 0	/* Clean and Invalidate Entire Data Cache */
203
204        ldr     r2, Lctl_ID_dis		/* Disable I+D caches */
205	mrc	p15, 0, r1, c1, c0, 0	/*  "       "   "     */
206	and	r1, r1, r2		/*  "       "   "     */
207	mcr	p15, 0, r1, c1, c0, 0	/*  "       "   "     */
208
209	mcr	p15, 0, r0, c7, c10, 4	/* Drain the write buffers. */
210
211	ldr	r0, Ltemp_l1_table	/* The page table address */
212	mcr	p15, 0, r0, c2, c0, 0	/* Set Translation Table Base */
213
214	mov	r0, #0
215	mcr	p15, 0, r0, c8, c7, 0	/* Invalidate TLBs */
216
217	/* Set the Domain Access register.  Very important! */
218	mov     r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
219	mcr	p15, 0, r0, c3, c0, 0
220
221	/*
222	 * Enable the MMU, etc.
223	 */
224	mrc     p15, 0, r0, c1, c0, 0
225
226	ldr     r1, Lcontrol_wax
227	and	r0, r0, r1
228	ldr     r1, Lcontrol_clr
229	bic	r0, r0, r1
230	ldr     r1, Lcontrol_set
231	orr	r0, r0, r1
232	ldr	lr, Lstart
233
234	.align 5
235	@ turn mmu on!
236	mov	r0, r0
237	mcr	p15, 0, r0, c1, c0, 0
238
239	/*
240	 * Ensure that the coprocessor has finished turning on the MMU.
241	 */
242	mrc	p15, 0, r0, c0, c0, 0	/* Read an arbitrary value. */
243	mov	r0, r0			/* Stall until read completes. */
244
245	/*
246	 * Jump to start in locore.S, which in turn will call initarm and main.
247	 */
248	mov	pc, lr
249	nop
250	nop
251	nop
252	nop
253
254	/* NOTREACHED */
255Ll1_s_frame:
256	.word	L1_S_FRAME
257
258Ltemp_l1_table:
259	/* Put the temporary L1 translation table just below the kernel. */
260	.word	0x4000
261
262Lstart:
263	.word	start
264/*
265 * Coprocessor register initialization values
266 */
267
268	/* bits to set in the Control Register */
269Lcontrol_set:
270	.word CPU_CONTROL_MMU_ENABLE  | \
271	      CPU_CONTROL_AFLT_ENABLE | \
272	      CPU_CONTROL_DC_ENABLE   | \
273	      CPU_CONTROL_WBUF_ENABLE |    /* not defined in 1176 */   \
274	      CPU_CONTROL_32BP_ENABLE | \
275	      CPU_CONTROL_32BD_ENABLE | \
276	      CPU_CONTROL_LABT_ENABLE | \
277	      CPU_CONTROL_SYST_ENABLE | \
278		(1 << 16) | 	/* SBO - Global enable for data tcm */ \
279		(1 << 18) |	/* SBO - Global enable for insn tcm */ \
280	      CPU_CONTROL_IC_ENABLE
281
282
283	/* bits to clear in the Control Register */
284Lcontrol_clr:
285	.word	0
286
287	/* bits to "write as existing" in the Control Register */
288Lcontrol_wax:
289	.word	(3 << 30) | \
290		(1 << 29) | \
291		(1 << 28) | \
292		(3 << 26) | \
293		(3 << 19) | \
294		(1 << 17) | \
295	        (1 << 10)
296
297	/* bits to disable the caches */
298Lctl_ID_dis:
299	.word	~(CPU_CONTROL_IC_ENABLE|CPU_CONTROL_DC_ENABLE)
300
301/* We'll modify va and pa at run time so we can use relocatable addresses. */
302#define MMU_INIT(va,pa,n_sec,attr) \
303	.word	va					    ; \
304	.word	pa					    ; \
305	.word	n_sec					    ; \
306	.word	attr					    ;
307
308mmu_init_table:
309	/* Add 1MB of VA==PA at 0x00000000 so we can keep the kernel going */
310	MMU_INIT(0x0, 0x0,
311	    (_end - KERNEL_BASE + 2 * L1_S_SIZE - 1),
312	    L1_S_PROTO | L1_S_AP_KRW)
313
314	MMU_INIT(KERNEL_BASE, 0x0,
315	    (_end - KERNEL_BASE + 2 * L1_S_SIZE - 1),
316	    L1_S_PROTO | L1_S_AP_KRW  | L1_S_B | L1_S_C)
317
318	/* Map the 16MB of peripherals */
319	MMU_INIT(RPI_KERNEL_IO_VBASE, RPI_KERNEL_IO_PBASE,
320	    (RPI_KERNEL_IO_VSIZE + L1_S_SIZE - 1),
321	    L1_S_PROTO | L1_S_AP_KRW)
322
323	/* end of table */
324	MMU_INIT(0, 0, 0, 0)
325
326	.globl	_C_LABEL(rpi_boot_regs)
327rpi_boot_regs:
328	.space 4 * 4
329