]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/bootstrap/server/src/ARCH-arm/crt0.S
update
[l4.git] / l4 / pkg / bootstrap / server / src / ARCH-arm / crt0.S
1 /*
2  * (c) 2008-2009 Adam Lackorzynski <adam@os.inf.tu-dresden.de>,
3  *               Frank Mehnert <fm3@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  *
6  * This file is part of TUD:OS and distributed under the terms of the
7  * GNU General Public License 2.
8  * Please see the COPYING-GPL-2 file for details.
9  */
10 /* -*- c -*- */
11
12 #define MIMIC_A_VMLINUZ
13
14 .section .text.init,#alloc,#execinstr
15 .type _start,#function
16 .globl _start
17 _start:
18 /* Some bootloaders like it this way, for others it won't harm */
19 #ifdef MIMIC_A_VMLINUZ
20         nop
21         nop
22         nop
23         nop
24         nop
25         nop
26         nop
27         nop
28         b 10f
29         .word 0x016f2818
30         .word _start
31         .word _edata
32 10:
33 #endif
34         /*
35          * It might be the case that we're not run at the position where we
36          * have been linked to. If this is the case we copy ourselves to the
37          * position we're linked to.
38          */
39         adr     r4, run         /* Running version */
40         ldr     r5, .LCrun      /* supposed to be version */
41         cmp     r4, r5          /* If equal ... */
42         beq     run             /* ... go to run */
43
44         /* Figure how to move */
45         ldr     r7, .LCend_bin
46         subs    r8, r5, r4      /* r8 is the distance between the blocks */
47         bpl     move_behind
48
49         /* Copy before, copy forwards */
50         /* First, copy our copy loop to the very beginning to avoid code
51          * overwrites */
52         mov     r2, r5                  /* r2: run address */
53         ldr     r0, .LCstart_bin
54         ldr     r1, 3f
55         str     r1, [r0], #4
56         ldr     r1, 32f
57         str     r1, [r0], #4
58         ldr     r1, 33f
59         str     r1, [r0], #4
60         ldr     r1, 34f
61         str     r1, [r0], #4
62         ldr     r1, 35f
63         str     r1, [r0], #4
64         ldr     pc, .LCstart_bin
65
66 3:      ldr     r6, [r4], #4
67 32:     str     r6, [r5], #4
68 33:     cmp     r5, r7
69 34:     blt     3b
70 35:     mov     pc, r2
71
72         /* Copy behind, copy backwards */
73 move_behind:
74         sub     r8, r7, r8      /* r8 points to the end of source image */
75 3:      ldr     r6, [r8, #-4]!  /* Take bytes */
76         str     r6, [r7, #-4]!  /* Put bytes */
77         cmp     r5, r7
78         blt     3b
79         ldr     pc, .LCrun
80
81
82 .LCrun:       .word run
83 .LCstart_bin: .word _start
84 .LCend_bin:   .word _module_data_end
85
86 run:
87         mov     r1, #0x1000
88         sub     r1, r1, #1                 /* r1 == 0xfff */
89         mrc     p15, 0, r0, c0, c0, 0      /* Main ID */
90         lsr     r0, #4
91         and     r0, r0, r1
92
93         /* Check for processors that understand CPU ID */
94         mov     r2, #0xb00
95         orr     r2, #0x002
96         cmp     r0, r2
97         beq     do_cpuid
98
99         mov     r2, #0xc00
100         orr     r2, #0x009
101         cmp     r0, r2
102         bne     do_bootstrap               /* None matched, normal startup */
103
104 do_cpuid:
105         mrc     p15, 0, r0, c0, c0, 5      /* CPU ID */
106         and     r0, r0, #0xf               /* CPU id */
107         cmp     r0, #0                     /* CPU0 continues with bootstrap */
108         beq     do_bootstrap    
109
110 /* CPU1+ wait for bootup */
111
112         // I-cache on
113         mrc p15, 0, r0, c1, c0, 0
114         orr r0, r0, #(1 << 12)
115         mcr p15, 0, r0, c1, c0, 0
116
117         // IRQs off, SVC
118         mrs r0, cpsr
119         orr r0, #0xd3
120         msr cpsr_c, r0
121
122 #ifdef PLATFORM_TYPE_rv
123         // enable GIC CPU interface + prio mask for IRQs
124
125         // get board ID and retrieve MPCore-base from table
126         mov     r5, #0x10000000
127         ldr     r5, [r5]
128         bic     r5, #0xff
129         adr     r6, .Lmpcore_base_table
130 2:
131         ldr     r4, [r6]
132         cmp     r4, #0
133         cmpne   r4, r5
134         ldreq   r4, [r6, #4]
135         beq     3f
136         add     r6, #8
137         b       2b
138
139 3:
140         add     r4, r4, #0x100
141         mov     r0, #0x1
142         str     r0, [r4, #0]
143         mov     r0, #0xf0
144         str     r0, [r4, #4]
145
146 1:
147         mov     r5, #0x10000000
148         ldr     r6, [r5, #0x30]
149         cmp     r6, #0
150         movne   pc, r6
151         .word 0xe320f003 /* wfi */
152         ldr     r0, [r4, #12]
153         str     r0, [r4, #16]
154         b       1b
155
156 .Lmpcore_base_table:
157         /* VExpress */
158         .word   0x1190f500 /* Board ID */
159         .word   0x1e000000 /* MPCore base */
160
161         /* Default value (with #0) must come last! */
162         /* Realview */
163         .word   0
164         .word   0x1f000000
165
166 #else
167 1:      .word 0xe320f003 /* wfi */
168         b       1b
169 #endif
170
171 do_bootstrap:
172         ldr     r3, .LCcrt0_tramppage      /* Load address of tramppage var */
173         str     sp, [r3]                   /* Store SP in variable          */
174         ldr     sp, .LCstack
175
176         bl      __main
177 1:      b       1b
178
179 .LCcrt0_tramppage:      .word crt0_tramppage
180 .LCstack: .word crt0_stack_high
181
182 .section ".bss"
183
184         .global crt0_tramppage
185 crt0_tramppage:
186         .space 4
187
188         .global crt0_stack_low
189         .align 3
190 crt0_stack_low:
191         .space  8192
192         .global crt0_stack_high
193 crt0_stack_high: