]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/bootstrap/server/src/ARCH-arm/crt0.S
1bbc33ce4fe85cf2c74bb64ebc32504fc95d50c3
[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         // enable GIC CPU interface + prio mask for IRQs
105         mov     r4, #0x1f000000
106         add     r4, r4, #0x100
107         mov     r0, #0x1
108         str     r0, [r4, #0]
109         mov     r0, #0xf0
110         str     r0, [r4, #4]
111
112 1:
113         mov     r5,#0x10000000
114         ldr     r6, [r5, #0x30]
115         cmp     r6, #0
116         movne   pc, r6
117         .word 0xe320f003 /* wfi */
118         ldr     r0, [r4, #12]
119         str     r0, [r4, #16]
120         b       1b
121
122 do_bootstrap:
123         ldr     r3, .LCcrt0_tramppage      /* Load address of tramppage var */
124         str     sp, [r3]                   /* Store SP in variable          */
125         ldr     sp, .LCstack
126
127         bl      __main
128 1:      b       1b
129
130 .LCcrt0_tramppage:      .word crt0_tramppage
131 .LCstack: .word crt0_stack_high
132
133 .section ".bss"
134
135         .global crt0_tramppage
136 crt0_tramppage:
137         .space 4
138
139         .global crt0_stack_low
140         .align 3
141 crt0_stack_low:
142         .space  8192
143         .global crt0_stack_high
144 crt0_stack_high: