No empty .Rs/.Re
[netbsd-mini2440.git] / sys / arch / arm / arm32 / locore.S
blobbcc96dc420b1f9c9d59eb524da8793f0cd7bdcf8
1 /*      $NetBSD: locore.S,v 1.23 2008/04/27 18:58:44 matt Exp $ */
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  */
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>
42 /* What size should this really be ? It is only used by init_arm() */
43 #define INIT_ARM_STACK_SIZE     2048
45         RCSID("$NetBSD: locore.S,v 1.23 2008/04/27 18:58:44 matt Exp $")
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  */
52         .text
53         .align  0
55 ENTRY_NP(kernel_text)
57 ASENTRY_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
63 .L1:
64         str     r3, [r1], #0x0004       /* Zero the bss */
65         subs    r2, r2, #4
66         bgt     .L1
68         mov     fp, #0x00000000         /* trace back starts here */
69         bl      _C_LABEL(initarm)       /* Off we go */
71         /* init arm will return the new stack pointer. */
72         mov     sp, r0
74         mov     fp, #0x00000000         /* trace back starts here */
75         mov     ip, sp
76         stmfd   sp!, {fp, ip, lr, pc}
77         sub     fp, ip, #4
79         bl      _C_LABEL(main)          /* call main()! */
81         adr     r0, .Lmainreturned
82         b       _C_LABEL(panic)
83         /* NOTREACHED */
85 .Lstart:
86         .word   _edata
87         .word   _end
88         .word   svcstk + INIT_ARM_STACK_SIZE
90 .Lmainreturned:
91         .asciz  "main() returned"
92         .align  0
94         .bss
95 svcstk:
96         .space  INIT_ARM_STACK_SIZE
98         .text
99         .align  0
101 #ifndef OFW
102         /* OFW based systems will used OF_boot() */
103         
104 .Lcpufuncs:     
105         .word   _C_LABEL(cpufuncs)
107 ENTRY_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
114         ldr     r4, .Lcpu_reset_address
115         ldr     r4, [r4]
117         ldr     r0, .Lcpufuncs
118         mov     lr, pc
119         ldr     pc, [r0, #CF_IDCACHE_WBINV_ALL]
121         /*
122          * Load the cpu_reset_needs_v4_MMU_disable flag to determine if it's
123          * necessary.
124          */
126         ldr     r1, .Lcpu_reset_needs_v4_MMU_disable
127         ldr     r1, [r1]
128         cmp     r1, #0
129         mov     r2, #0
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
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)
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)
157 #endif  /* OFW */
160  * setjump + longjmp
161  */
162 ENTRY(setjmp)
163         stmia   r0, {r4-r14}
164         mov     r0, #0x00000000
165         mov     pc, lr
167 ENTRY(longjmp)
168         ldmia   r0, {r4-r14}
169         mov     r0, #0x00000001
170         mov     pc, lr
172         .data
173         .global _C_LABEL(esym)
174 _C_LABEL(esym): .word   _C_LABEL(end)
176 ENTRY_NP(abort)
177         b       _C_LABEL(abort)
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  */
183 ENTRY(dumpsys)
184         /* push registers onto stack */
185         mov     ip, sp
186         stmfd   sp!, {r4-r7, ip, lr}
188         /* fill in dumppcb */
189         ldr     r0, .Ldumppcb
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
200         bl      _C_LABEL(dodumpsys)
202         /* unwind the stack */
203         ldmfd   sp, {r4-r7, sp, pc}
205 .Ldumppcb:
206         .word   _C_LABEL(dumppcb)
208 /* End of locore.S */