]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/bootstrap/server/src/ARCH-arm/crt0.S
6f1ce94246c0c95ad6f4c2dac3bbb77e92c08a11
[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         /* Disable caches as we're moving code around */
45         mcr p15, 0, r3, c7, c5, 0 /* ICIALLU */
46         mrc p15, 0, r0, c1, c0
47         bic r0, #0x0004
48         bic r0, #0x1000
49         mcr p15, 0, r0, c1, c0
50
51         /* Figure how to move */
52         ldr     r7, .LCend_bin
53         subs    r8, r5, r4      /* r8 is the distance between the blocks */
54         bpl     move_behind
55
56         /* Copy before, copy forwards */
57         /* First, copy our copy loop to the very beginning to avoid code
58          * overwrites */
59         mov     r9, r5                  /* r9: run address */
60         ldr     r0, .LCstart_bin
61         ldr     r3, 3f
62         str     r3, [r0], #4
63         ldr     r3, 32f
64         str     r3, [r0], #4
65         ldr     r3, 33f
66         str     r3, [r0], #4
67         ldr     r3, 34f
68         str     r3, [r0], #4
69         ldr     r3, 35f
70         str     r3, [r0], #4
71         ldr     pc, .LCstart_bin
72
73 3:      ldr     r6, [r4], #4
74 32:     str     r6, [r5], #4
75 33:     cmp     r5, r7
76 34:     blt     3b
77 35:     mov     pc, r9
78
79         /* Copy behind, copy backwards */
80 move_behind:
81         sub     r8, r7, r8      /* r8 points to the end of source image */
82 3:      ldr     r6, [r8, #-4]!  /* Take bytes */
83         str     r6, [r7, #-4]!  /* Put bytes */
84         cmp     r5, r7
85         blt     3b
86         ldr     pc, .LCrun
87
88
89 .LCrun:       .word run
90 .LCstart_bin: .word _start
91 .LCend_bin:   .word _module_data_end
92
93 run:
94         mov     r3, #0x1000
95         sub     r3, r3, #1                 /* r3 == 0xfff */
96         mrc     p15, 0, r0, c0, c0, 0      /* Main ID */
97         lsr     r0, #4
98         and     r0, r0, r3
99
100         /* Check for processors that understand CPU ID */
101         mov     r9, #0xb00
102         orr     r9, #0x002
103         cmp     r0, r9
104         beq     do_cpuid
105
106         mov     r9, #0xc00
107         orr     r9, #0x009
108         cmp     r0, r9
109         bne     do_bootstrap               /* None matched, normal startup */
110
111 do_cpuid:
112         mrc     p15, 0, r0, c0, c0, 5      /* CPU ID */
113         and     r0, r0, #0xf               /* CPU id */
114         cmp     r0, #0                     /* CPU0 continues with bootstrap */
115         beq     do_bootstrap    
116
117 /* CPU1+ wait for bootup */
118
119         // I-cache on
120         mrc p15, 0, r0, c1, c0, 0
121         orr r0, r0, #(1 << 12)
122         mcr p15, 0, r0, c1, c0, 0
123
124         // IRQs off, SVC
125         mrs r0, cpsr
126         orr r0, #0xd3
127         msr cpsr_c, r0
128
129 #if defined(PLATFORM_TYPE_rv) || defined(PLATFORM_TYPE_rv_pbx) || defined(PLATFORM_TYPE_rv_vexpress)
130         // enable GIC CPU interface + prio mask for IRQs
131
132         // get board ID and retrieve MPCore-base from table
133         mov     r5, #0x10000000
134         ldr     r5, [r5]
135         bic     r5, #0xff
136         adr     r6, .Lmpcore_base_table
137 2:
138         ldr     r4, [r6]
139         cmp     r4, #0
140         cmpne   r4, r5
141         ldreq   r4, [r6, #4]
142         beq     3f
143         add     r6, #8
144         b       2b
145
146 3:
147         add     r4, r4, #0x100
148         mov     r0, #0x1
149         str     r0, [r4, #0]
150         mov     r0, #0xf0
151         str     r0, [r4, #4]
152
153 1:
154         mov     r5, #0x10000000
155         ldr     r6, [r5, #0x30]
156         cmp     r6, #0
157         movne   pc, r6
158         .inst 0xe320f003 /* wfi */
159         ldr     r0, [r4, #12]
160         str     r0, [r4, #16]
161         b       1b
162
163 .Lmpcore_base_table:
164         /* VExpress */
165         .word   0x1190f500 /* Board ID */
166         .word   0x1e000000 /* MPCore base */
167
168         /* Default value (with #0) must come last! */
169         /* Realview */
170         .word   0
171         .word   0x1f000000
172
173 #else
174 1:      .word 0xe320f003 /* wfi */
175         b       1b
176 #endif
177
178 do_bootstrap:
179         ldr     r3, .LCcrt0_tramppage      /* Load address of tramppage var */
180         str     sp, [r3]                   /* Store SP in variable          */
181         ldr     sp, .LCstack
182
183         mov     r0, r2                     /* ATAG pointer */
184         bl      __main
185 1:      b       1b
186
187 .LCcrt0_tramppage:      .word crt0_tramppage
188 .LCstack: .word crt0_stack_high
189
190 .section ".bss"
191
192         .global crt0_tramppage
193 crt0_tramppage:
194         .space 4
195
196         .global crt0_stack_low
197         .align 3
198 crt0_stack_low:
199         .space  8192
200         .global crt0_stack_high
201 crt0_stack_high: