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