xref: /netbsd-src/sys/arch/acorn32/stand/boot32/start.S (revision f81322cf185a4db50f71fcf7701f20198272620e)
1/*	$NetBSD: start.S,v 1.1 2002/12/28 23:57:37 reinoud Exp $	*/
2
3/*
4 * Copyright (c) 2002 Reinoud Zandijk
5 * All rights reserved.
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 the author may not be used to endorse or promote products
16 *    derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#include <machine/asm.h>
31#include <arm/armreg.h>
32#include <riscoscalls.h>
33
34
35/* ----------------------------------------------------------------------- */
36ENTRY(relocate_code)
37	/*
38		- r0 pointer to configuration structure
39		- r1 pointer to physical restart point
40		- r2 pointer to relocation table (P)
41		- r3 pointer to physical new L1 page address (P)
42		- r4 kernel entry point
43	*/
44
45	/* save registers / move args up in register bank later */
46	/* r8-r12 becomes r0-r4 */
47	stmfd	sp!, {r0-r4}
48	ldmfd	sp!, {r8-r12}
49
50	/*
51	 * determine processor architecture version. This is nessisary for the
52	 * correct coprocessor instruction.
53	 */
54	mrc	15, 0, r0, c0, c0, 0					/* read CPU id in r0			*/
55	mov	r3, r0							/* store in r3				*/
56
57	/* assume its ARMv4 instruction set									*/
58	mov	r14, #1
59
60	/* check ARM6. It needs a special mask									*/
61	mov	r0, #0x0000ff00
62	mov	r1, #0x00000600						/* check for 0xxxxx06xx => ARM6		*/
63	and	r2, r3, r0
64	cmp	r2, r1
65	moveq	r14, #0							/* mark v3				*/
66
67	/* newer ARM's need a different mask									*/
68	mov	r0, #0x0000f000
69
70	/* check for ARM7 and derivatives like the ARM 7500 and ARM 7500FE					*/
71	mov	r1, #0x00007000						/* check for 0xxxxx7xxx => ARM 7	*/
72	and	r2, r3, r0
73	cmp	r2, r1
74	moveq	r14, #0							/* mark v3				*/
75
76	/* switch off MMU, IDcache and WB and branch to physical code space					*/
77	cmp	r14, #0
78	mrcne	15, 0, r0, c1, c0, 0					/* read processor control register if v4*/
79	bic	r0, r0, #0x3f						/* clear only known bits		*/
80	moveq	r0, #0							/* for v3 just set to zero		*/
81	orr	r0, r0, #CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_32BP_ENABLE
82	mov	r13, r0							/* save this control value in r13	*/
83	cmp	r14, #0
84	mcr	15, 0, r0, c1, c0, 0					/* write control register!		*/
85/*1*/	mcrne	15, 0, r1, c7, c5, 0					/* write zero in ARMv4 MMU disable	*/
86/*2*/	mov	pc, r9							/* branch to physical address		*/
87
88relocate_code_physical_restart:
89	/* we are running in physical flat 1:1 space now */
90	mov	r5, r10							/* r5 = is start of relocation table	*/
91	ldr	r6, [r5], #4						/* r4 = number of relocated pages	*/
92loop_relocate_pages:
93	ldr	r2, [r5], #4						/* r2 = from address			*/
94	ldr	r3, [r5], #4						/* r3 = to address			*/
95	ldr	r7, [r5], #4						/* r7 = number of bytes to travel	*/
96	mov	r1, #0							/* r1 = offset in page			*/
97	/* its slow ... we dont know anything about alignment here 						*/
98loop_one_page:
99	ldrb	r0, [r2, r1]
100	strb	r0, [r3, r1]
101	add	r1, r1, #1
102	cmp	r1, r7							/* all bytes copied?			*/
103	bne	loop_one_page
104	subs	r6, r6, #1
105	bne	loop_relocate_pages
106
107	/* OK! all is relocated... now switch over to the new L1 pages						*/
108	/* disable SA110 clock switching (WHY?)									*/
109	mov	r0, #0
110	cmp	r14, #0
111	mcrne	15, 0, r0, c15, c2, 2
112
113	/* flush ID cache											*/
114	mov	r0, #0
115	cmp	r14, #0
116	mcreq	15, 0, r0, c7, c0, 0					/* flush v3 ID cache			*/
117	mcrne	15, 0, r0, c7, c7, 0					/* flush v4 ID cache			*/
118
119	/* drain write buffer (v4)										*/
120	mov	r0, #0
121	cmp	r14, #0
122	mcrne	15, 0, r0, c7, c10, 4					/* drain WB (v4)			*/
123
124	/* flush TLB												*/
125	mcr	15, 0, r0, c5, c0, 0					/* flush TLB for v3 and v4		*/
126
127	/* set new TLB address											*/
128	mov	r0, r11
129	mcr	15, 0, r0, c2, c0, 0					/* write TLB address			*/
130
131	/* Switch on MMU, IDCache and WB and keep on running on flat translated memory				*/
132	orr	r0, r13, #CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_32BP_ENABLE
133	orr	r0, r0,  #CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_DC_ENABLE   | CPU_CONTROL_MMU_ENABLE
134	mcr	15, 0, r0, c1, c0, 0					/* write register !!!			*/
135	mov	r0, r0							/* flat					*/
136	mov	r0, r0							/* flat					*/
137	/* not flat anymore but we just continue								*/
138
139	/* call the kernel!											*/
140	mov	r0, r8							/* saved configuration structure	*/
141	mov	pc, r12							/* entry point ..... bye bye!		*/
142
143relocate_code_end:
144	b	relocate_code_end
145
146/* ----------------------------------------------------------------------- */
147
148
149/* we are not expected to ever return from here */
150ENTRY(start_kernel)
151	/*
152	entry conditions :
153		- on RISC OS page tables in usr26 mode on virtual space
154		- r0 relocation code page (V)
155		- r1 relocation pv offset
156		- r2 configuration structure
157		- r3 relocation table (P)
158		- r4 L1 page descriptor (P)
159		- r5 kernel entry point
160	*/
161	mov	ip, sp
162	stmfd	sp!, {r4-r9, fp, ip, lr, pc}
163	sub	fp, ip, #4
164
165	/* get stuff out of the calling frame */
166	ldr	r4, [ip, #0]
167	ldr	r5, [ip, #4]
168
169	/* relocate the relocation routine to the given page */
170	adr	r6, relocate_code
171	ldr	r7, Lnbpp
172	mov	r8, r0
173relocate_code_loop:
174	ldr	r9, [r6], #4
175	str	r9, [r8], #4
176	subs	r7, r7, #4
177	bne	relocate_code_loop
178
179	/* we messed up the data cache : lets read a 64 or 128 kb <-- GROSS */
180	mov	r7, #128*1024
181	mov	r6, #0x8000						/* start of RISCOS application area	*/
182flush_ID_cache_try:
183	ldr	r9, [r6], #4
184	subs	r7, r7, #4
185	bne	flush_ID_cache_try
186
187	/* enter sub26 mode */
188	swi	OS_EnterOS
189
190	/* go to sup32 mode with ICQ and FIQ disabled */
191	mrs	r6, cpsr
192	bic	r6, r6, #PSR_MODE					/* clear processor mode			*/
193	orr	r6, r6, #(I32_bit | F32_bit)				/* disable ICQ + FIQ			*/
194	orr	r6, r6, #PSR_SVC32_MODE					/* go to 32 bit supervisor mode		*/
195	msr	cpsr, r6
196	mov	r0, r0							/* nops ... just in case		*/
197	mov	r0, r0
198
199	/* set up info */
200	mov	r9, r0							/* save relocated page address		*/
201	mov	r7, #relocate_code_physical_restart - relocate_code	/* get offset				*/
202	add	r1, r0, r1						/* get physical address			*/
203	add	r1, r1, r7						/* add offset				*/
204	mov	r0, r2							/* put configuration structure in r0	*/
205	mov	r2, r3							/* relocation table			*/
206	mov	r3, r4							/* L1 page discriptor			*/
207	mov	r4, r5							/* kernel entry point			*/
208
209	mov	pc, r9							/* jump to page addr == relocate_code	*/
210
211emergency_exit:
212	ldmdb	fp, {r4-r9, fp, sp, pc}
213
214Lnbpp:
215	.word	nbpp
216Lvideomem_start_ro:
217	.word	videomem_start_ro
218
219