xref: /netbsd-src/sys/arch/evbarm/gemini/gemini_start.S (revision 6c8cc9bf94eb2185293a7025df500392136487ed)
1/*	$NetBSD: gemini_start.S,v 1.10 2024/11/19 05:00:09 andvar Exp $	*/
2
3/*
4 * Machine dependent 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@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
90#include <machine/asm.h>
91#include <arm/armreg.h>
92#include "assym.h"
93
94RCSID("$NetBSD: gemini_start.S,v 1.10 2024/11/19 05:00:09 andvar Exp $")
95
96
97#if defined(VERBOSE_INIT_ARM)
98# define _PUTCHAR(addr, areg, breg, c) 			\
99	ldr	areg, addr;				\
1001:							\
101	ldr	breg, [areg, #0x14];	/* LSR    */	\
102	tst	breg, #0x20;		/* TXRDY? */	\
103	beq	1b;					\
104	mov	breg, #(c);		/*   c    */	\
105	str	breg, [areg];		/* TXDATA */	\
1062:							\
107	ldr	breg, [areg, #0x14];	/* LSR    */	\
108	tst	breg, #0x40;		/* TSRE?  */	\
109	beq	2b;
110#else
111# define _PUTCHAR(addr, areg, breg, c)
112#endif
113
114
115/*
116 * Kernel start routine for GEMINI Eval board.
117 * At this point, this code has been loaded into SDRAM
118 * and the MMU is off
119 */
120	.section .start,"ax",%progbits
121
122	.global	_C_LABEL(gemini_start)
123_C_LABEL(gemini_start):
124	/* Move into supervisor mode and disable IRQs/FIQs. */
125	mrs	r0, cpsr
126	bic	r0, r0, #PSR_MODE
127	orr	r0, r0, #(I32_bit | F32_bit | PSR_SVC32_MODE)
128	msr	cpsr, r0
129
130	_PUTCHAR(Lconsole_pbase, r4, r3, 'a')
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
138	mov	r1, r0			/* Save the page table address. */
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	_PUTCHAR(Lconsole_pbase, r4, r3, 'b')
157
158	/* Now create our entries per the mmu_init_table. */
159	l1table	.req r0
160	va	.req r1
161	pa	.req r2
162	n_sec	.req r3
163	attr	.req r4
164	itable	.req r5
165	l1sfrm	.req r6
166	ldr	l1table, Ltemp_l1_table
167	adr	itable, mmu_init_table
168	ldr	l1sfrm, Ll1_s_frame
169	b	3f
1702:	str	pa, [l1table, va]
171	add	va, va, #4
172	add	pa, pa, #(L1_S_SIZE)
173	adds	n_sec, n_sec, #-1
174	bhi	2b
1753:	ldmia	itable!, {va,pa,n_sec,attr}
176	/* Convert va to l1 offset:	va = 4 * (va >> L1_S_SHIFT)	*/
177	mov	va, va, LSR #L1_S_SHIFT
178	mov	va, va, LSL #2
179	/* Convert pa to l1 entry:	pa = (pa & L1_S_FRAME) | attr	*/
180	and	pa, pa, l1sfrm
181	orr	pa, pa, attr
182	cmp	n_sec, #0
183	bne	2b
184	mov	r5, r0			/* l1table */
185	.unreq	va
186	.unreq	pa
187	.unreq	n_sec
188	.unreq	attr
189	.unreq	itable
190	.unreq	l1table
191	.unreq	l1sfrm
192
193	_PUTCHAR(Lconsole_pbase, r4, r3, 'c')
194
195	/*
196	 * using FA526 -specific cache ops here...
197	 */
198	mov	r0, #0
199	mcr	p15, 0, r0, c7, c5,  0	/* Invalidate Entire I cache */
200	mcr	p15, 0, r0, c7, c14, 0	/* Clean & Invalidate Entire D cache */
201
202        ldr     r2, Lctl_ID_dis		/* Disable I+D caches */
203	mrc	p15, 0, r1, c1, c0, 0	/*  "       "   "     */
204	and	r1, r1, r2		/*  "       "   "     */
205	mcr	p15, 0, r1, c1, c0, 0	/*  "       "   "     */
206
207	_PUTCHAR(Lconsole_pbase, r4, r3, 'd')
208
209	mcr	p15, 0, r0, c7, c5, 6	/* invalidate BTB all */
210	mcr	p15, 0, r0, c7, c10, 4	/* Drain the write buffers. */
211	mcr	p15, 0, r5, c2, c0, 0	/* Set Translation Table Base */
212	mcr	p15, 0, r0, c8, c7, 0	/* Invalidate TLBs */
213
214	/* Set the Domain Access register */
215        mov     r0, #((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT)
216	mcr	p15, 0, r0, c3, c0, 0
217
218	/*
219	 * set Extension Control Enable in ECR, so we can use BTB
220	 */
221	ldr     r0, Lecr_set
222	mcr     p15, 0, r0, c1, c1, 0
223
224	/*
225	 * Enable the MMU, etc.
226	 */
227	mrc     p15, 0, r0, c1, c0, 0
228	ldr     r1, Lcontrol_wax
229	and	r0, r0, r1
230	ldr     r1, Lcontrol_clr
231	mvn	r1, r1
232	and	r0, r0, r1
233	ldr     r1, Lcontrol_set
234	orr	r0, r0, r1
235	mcr     p15, 0, r0, c1, c0, 0
236
237	/*
238	 * Ensure that the coprocessor has finished turning on the MMU.
239	 */
240	mrc	p15, 0, r0, c2, c0, 0	/* Read an arbitrary value. */
241	mov	r0, r0			/* Stall until read completes. */
242
243	_PUTCHAR(Luart_vbase, r4, r3, 'e')
244
245	/*
246	 * Zero .bss
247	 */
248	ldr	r0, L_edata
249	ldr	r1, L_end
250	mov	r2, #0
2511:
252	str	r2, [r0], #0x04		/* *r0++ = r2 */
253	cmp	r0, r1
254	bne	1b
255
256#if 0
257	/*
258	 * Jump to start in locore.S, which in turn will call initarm and main.
259	 */
260	adr	r0, Ltestjmp
261	ldr	pc, [r0]
262	nop
263	nop
264	nop
265	nop
266testjmp:
267#endif
268
269	_PUTCHAR(Luart_vbase, r4, r3, 'f')
270
271	adr	r0, Lstart
272	ldr	pc, [r0]
273	nop
274	nop
275	nop
276	nop
277
278	/* NOTREACHED */
279
280L_edata:
281	.word   _C_LABEL(_edata)
282L_end:
283	.word   _C_LABEL(_end)
284
285#if 0
286Ltestjmp:
287	.word	testjmp
288#endif
289
290Lstart:
291	.word	start
292Ll1_s_frame:
293	.word	L1_S_FRAME
294Ltemp_l1_table:
295	/* Put the temporary L1 translation table at the end of SDRAM. */
296	.word	MEMSIZE * 0x100000 - L1_TABLE_SIZE
297
298/*
299 * Coprocessor register initialization values
300 */
301#if !defined(CPU_ECR_ECE)
302# define	CPU_ECR_ECE		1
303#endif
304	/* bits to set in the Extension Control Register */
305Lecr_set:
306	.word	CPU_ECR_ECE
307
308#if !defined(CPU_CONTROL_BTB_ENABLE)
309# define	CPU_CONTROL_BTB_ENABLE	(1 << 11)
310#endif
311	/* bits to set in the Control Register */
312	/* bits 6..4 SB1 */
313Lcontrol_set:
314	.word CPU_CONTROL_MMU_ENABLE  | \
315	      CPU_CONTROL_AFLT_ENABLE | \
316	      CPU_CONTROL_DC_ENABLE   | \
317	      CPU_CONTROL_WBUF_ENABLE | \
318	      CPU_CONTROL_32BP_ENABLE | \
319	      CPU_CONTROL_32BD_ENABLE | \
320	      CPU_CONTROL_LABT_ENABLE | \
321	      CPU_CONTROL_SYST_ENABLE | \
322	      CPU_CONTROL_IC_ENABLE   | \
323	      CPU_CONTROL_DC_ENABLE   | \
324	      CPU_CONTROL_BTB_ENABLE
325
326	/* bits to clear in the Control Register */
327	/* bits 31..14, 10,  SBZ */
328Lcontrol_clr:
329	.word	((~0) << 14) | \
330		(1 << 10)
331
332	/* bits to "write as existing" in the Control Register */
333Lcontrol_wax:
334	.word	CPU_CONTROL_BEND_ENABLE
335
336	/* bits to disable the caches */
337Lctl_ID_dis:
338	.word	~(CPU_CONTROL_IC_ENABLE|CPU_CONTROL_DC_ENABLE)
339
340	/* console addressing */
341Lconsole_pbase:
342#if 0
343	.word	CONSADDR
344#else
345	.word	GEMINI_UART_BASE
346#endif
347Luart_vbase:
348	.word	GEMINI_UART_VBASE
349
350
351/* We'll modify va and pa at run time so we can use relocatable addresses. */
352#define MMU_INIT(va,pa,n_sec,attr) \
353	.word	va					    ; \
354	.word	pa					    ; \
355	.word	n_sec					    ; \
356	.word	attr					    ;
357
358mmu_init_table:
359	/* Maintain current 1:1 addressability */
360	MMU_INIT(KERNEL_BASE_phys, KERNEL_BASE_phys,
361		(MEMSIZE * L1_S_SIZE + L1_S_SIZE - 1) / L1_S_SIZE,
362		L1_S_PROTO | L1_S_AP_KRW | L1_S_B | L1_S_C)
363
364	/* Map Kernel base VA:PA, write-back cacheable */
365	MMU_INIT(KERNEL_BASE_virt, KERNEL_BASE_phys,
366		(MEMSIZE * L1_S_SIZE + L1_S_SIZE - 1) / L1_S_SIZE,
367		L1_S_PROTO | L1_S_AP_KRW | L1_S_B | L1_S_C)
368
369	/* Map Gemini GLOBAL regs */
370	MMU_INIT(GEMINI_GLOBAL_VBASE, GEMINI_GLOBAL_BASE,
371		1,
372		L1_S_PROTO | L1_S_AP_KRW)
373
374	/* Map Gemini UART */
375	MMU_INIT(GEMINI_UART_VBASE, GEMINI_UART_BASE,
376		1,
377		L1_S_PROTO | L1_S_AP_KRW)
378
379	/* Map Gemini LPC Host Controller Space */
380	MMU_INIT(GEMINI_LPCHC_VBASE, GEMINI_LPCHC_BASE,
381		1,
382		L1_S_PROTO | L1_S_AP_KRW)
383
384	/* Map Gemini LPC IO Space */
385	MMU_INIT(GEMINI_LPCIO_VBASE, GEMINI_LPCIO_BASE,
386		1,
387		L1_S_PROTO | L1_S_AP_KRW)
388
389	/* Map Gemini DRAM Controller Space */
390	MMU_INIT(GEMINI_DRAMC_VBASE, GEMINI_DRAMC_BASE,
391		1,
392		L1_S_PROTO | L1_S_AP_KRW)
393
394	/* end of table */
395	MMU_INIT(0, 0, 0, 0)
396
397