xref: /netbsd-src/sys/arch/arm/arm32/locore.S (revision 10ad5ffa714ce1a679dcc9dd8159648df2d67b5a)
1/*	$NetBSD: locore.S,v 1.24 2008/08/07 04:18:21 matt Exp $	*/
2
3/*
4 * Copyright (C) 1994-1997 Mark Brinicombe
5 * Copyright (C) 1994 Brini
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 *    must display the following acknowledgement:
18 *	This product includes software developed by Brini.
19 * 4. The name of Brini may not be used to endorse or promote products
20 *    derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY BRINI ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL BRINI BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33
34#include "assym.h"
35#include <sys/syscall.h>
36#include <sys/errno.h>
37#include <machine/asm.h>
38#include <machine/cpu.h>
39#include <machine/frame.h>
40#include <machine/param.h>
41
42/* What size should this really be ? It is only used by init_arm() */
43#define INIT_ARM_STACK_SIZE	2048
44
45	RCSID("$NetBSD: locore.S,v 1.24 2008/08/07 04:18:21 matt Exp $")
46
47/*
48 * This is for kvm_mkdb, and should be the address of the beginning
49 * of the kernel text segment (not necessarily the same as kernbase).
50 */
51
52	.text
53	.align	0
54
55ENTRY_NP(kernel_text)
56
57ASENTRY_NP(start)
58	adr	r1, .Lstart
59	ldmia	r1, {r1, r2, sp}	/* Set initial stack and */
60	sub	r2, r2, r1		/* get zero init data */
61	mov	r3, #0
62
63.L1:
64	str	r3, [r1], #0x0004	/* Zero the bss */
65	subs	r2, r2, #4
66	bgt	.L1
67
68	mov	fp, #0x00000000		/* trace back starts here */
69	bl	_C_LABEL(initarm)	/* Off we go */
70
71	/* init arm will return the new stack pointer. */
72	mov	sp, r0
73
74	mov	fp, #0x00000000		/* trace back starts here */
75	mov	ip, sp
76	stmfd	sp!, {fp, ip, lr, pc}
77	sub	fp, ip, #4
78
79	bl	_C_LABEL(main)		/* call main()! */
80
81	adr	r0, .Lmainreturned
82	b	_C_LABEL(panic)
83	/* NOTREACHED */
84
85.Lstart:
86	.word	_edata
87	.word	_end
88	.word	svcstk + INIT_ARM_STACK_SIZE
89
90.Lmainreturned:
91	.asciz	"main() returned"
92	.align	0
93
94	.bss
95svcstk:
96	.space	INIT_ARM_STACK_SIZE
97
98	.text
99	.align	0
100
101#ifndef OFW
102	/* OFW based systems will used OF_boot() */
103
104.Lcpufuncs:
105	.word	_C_LABEL(cpufuncs)
106
107ENTRY_NP(cpu_reset)
108	mrs     r2, cpsr
109	bic	r2, r2, #(PSR_MODE)
110	orr     r2, r2, #(PSR_SVC32_MODE)
111	orr	r2, r2, #(IF32_bits)
112	msr     cpsr_c, r2
113
114	ldr	r4, .Lcpu_reset_address
115	ldr	r4, [r4]
116
117	ldr	r0, .Lcpufuncs
118	mov	lr, pc
119	ldr	pc, [r0, #CF_IDCACHE_WBINV_ALL]
120
121	/*
122	 * Load the cpu_reset_needs_v4_MMU_disable flag to determine if it's
123	 * necessary.
124	 */
125
126	ldr	r1, .Lcpu_reset_needs_v4_MMU_disable
127	ldr	r1, [r1]
128	cmp	r1, #0
129	mov	r2, #0
130
131	/*
132 	 * MMU & IDC off, 32 bit program & data space
133	 * Hurl ourselves into the ROM
134	 */
135	mov	r0, #(CPU_CONTROL_32BP_ENABLE | CPU_CONTROL_32BD_ENABLE)
136	mcr     15, 0, r0, c1, c0, 0
137	mcrne   15, 0, r2, c8, c7, 0 	/* nail I+D TLB on ARMv4 and greater */
138	mov     pc, r4
139
140	/*
141	 * _cpu_reset_address contains the address to branch to, to complete
142	 * the CPU reset after turning the MMU off
143	 * This variable is provided by the hardware specific code
144	 */
145.Lcpu_reset_address:
146	.word	_C_LABEL(cpu_reset_address)
147
148	/*
149	 * cpu_reset_needs_v4_MMU_disable contains a flag that signals if the
150	 * v4 MMU disable instruction needs executing... it is an illegal instruction
151	 * on f.e. ARM6/7 that locks up the computer in an endless illegal
152	 * instruction / data-abort / reset loop.
153	 */
154.Lcpu_reset_needs_v4_MMU_disable:
155	.word	_C_LABEL(cpu_reset_needs_v4_MMU_disable)
156
157#endif	/* OFW */
158
159/*
160 * setjump + longjmp
161 */
162ENTRY(setjmp)
163	stmia	r0, {r4-r14}
164	mov	r0, #0x00000000
165	mov	pc, lr
166
167ENTRY(longjmp)
168	ldmia	r0, {r4-r14}
169	mov	r0, #0x00000001
170	mov	pc, lr
171
172	.data
173	.global _C_LABEL(esym)
174_C_LABEL(esym):	.word	_C_LABEL(end)
175
176ENTRY_NP(abort)
177	b	_C_LABEL(abort)
178
179/*
180 * Part of doing a system dump, we need to save a switchframe onto the
181 * stack, then save the rest of the registers into the dumppcb.
182 */
183ENTRY(dumpsys)
184	/* push registers onto stack */
185	mov	ip, sp
186	stmfd	sp!, {r4-r7, ip, lr}
187
188	/* fill in dumppcb */
189	ldr	r0, .Ldumppcb
190
191#ifndef __XSCALE__
192        add     r2, r0, #(PCB_R8)
193        stmia   r2, {r8-r13}
194#else
195        strd    r8, [r0, #(PCB_R8)]
196        strd    r10, [r0, #(PCB_R10)]
197        strd    r12, [r0, #(PCB_R12)]
198#endif
199
200	bl	_C_LABEL(dodumpsys)
201
202	/* unwind the stack */
203	ldmfd	sp, {r4-r7, sp, pc}
204
205.Ldumppcb:
206	.word	_C_LABEL(dumppcb)
207
208/* End of locore.S */
209