summaryrefslogtreecommitdiff
path: root/Demo/lwIP_Demo_Rowley_ARM7/crt0.s
blob: a16c220125dc85fb7b55c77c2837ce10856be4c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
/*****************************************************************************
 * Copyright (c) 2001, 2002 Rowley Associates Limited.                       *
 *                                                                           *
 * This file may be distributed under the terms of the License Agreement     *
 * provided with this software.                                              *
 *                                                                           *
 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING THE   *
 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. *
 *****************************************************************************/
  .section .init, "ax"
  .code 32
  .align 0
                
  .weak _start
  .global __start
  .global __gccmain
  .extern main
  .extern exit

/*****************************************************************************
 * Function    : _start                                                      *
 * Description : Main entry point and startup code for C system.             *
 *****************************************************************************/
_start:
__start:                        
  mrs r0, cpsr
  bic r0, r0, #0x1F

  /* Setup stacks */ 
  orr r1, r0, #0x1B /* Undefined mode */
  msr cpsr_cxsf, r1
  ldr sp, =__stack_und_end__
  
  orr r1, r0, #0x17 /* Abort mode */
  msr cpsr_cxsf, r1
  ldr sp, =__stack_abt_end__

  orr r1, r0, #0x12 /* IRQ mode */
  msr cpsr_cxsf, r1
  ldr sp, =__stack_irq_end__

  orr r1, r0, #0x11 /* FIQ mode */
  msr cpsr_cxsf, r1
  ldr sp, =__stack_fiq_end__

  orr r1, r0, #0x13 /* Supervisor mode */
  msr cpsr_cxsf, r1
  ldr sp, =__stack_svc_end__
#ifdef SUPERVISOR_START
  /* Start application in supervisor mode */
  ldr r1, =__stack_end__ /* Setup user/system mode stack */ 
  mov r2, sp
  stmfd r2!, {r1}
  ldmfd r2, {sp}^
#else
  /* Start application in system mode */
  orr r1, r0, #0x1F /* System mode */
  msr cpsr_cxsf, r1
  ldr sp, =__stack_end__
#endif
  
  /* Copy from initialised data section to data section (if necessary). */
  ldr r0, =__data_load_start__
  ldr r1, =__data_start__
  cmp r0, r1
  beq copy_data_end
  
  ldr r2, =__data_end__
  subs r2, r2, r1
  beq copy_data_end
  
copy_data_loop:
  ldrb r3, [r0], #+1
  strb r3, [r1], #+1
  subs r2, r2, #1
  bne copy_data_loop
copy_data_end:  

  /* Copy from initialised text section to text section (if necessary). */
  ldr r0, =__text_load_start__
  ldr r1, =__text_start__
  cmp r0, r1
  beq copy_text_end
  
  ldr r2, =__text_end__
  subs r2, r2, r1
  beq copy_text_end
  
copy_text_loop:
  ldrb r3, [r0], #+1
  strb r3, [r1], #+1
  subs r2, r2, #1
  bne copy_text_loop
copy_text_end:  

  /* Copy from initialised fast_text section to fast_text section (if necessary). */
  ldr r0, =__fast_load_start__
  ldr r1, =__fast_start__
  cmp r0, r1
  beq copy_fast_end
  
  ldr r2, =__fast_end__
  subs r2, r2, r1
  beq copy_fast_end
  
copy_fast_loop:
  ldrb r3, [r0], #+1
  strb r3, [r1], #+1
  subs r2, r2, #1
  bne copy_fast_loop
copy_fast_end:  

  /* Zero the bss. */
  ldr r0, =__bss_start__
  ldr r1, =__bss_end__
  mov r2, #0
zero_bss_loop:
  cmp r0, r1
  beq zero_bss_end
  strb r2, [r0], #+1
  b zero_bss_loop
zero_bss_end:    

#ifdef CHECK  
  /* Check data */
  ldr r0, =__data_load_start__
  ldr r1, =__data_start__
  cmp r0, r1
  beq check_data_end
  ldr r2, =__data_end__
  subs r2, r2, r1
  beq check_data_end
  
check_data_loop:
  ldrb r3, [r0], #+1
  ldrb r4, [r1], #+1
  cmp r3, r4
  bne data_error_loop
  subs r2, r2, #1
  bne check_data_loop
check_data_end:  

  /* Check text */
  ldr r0, =__text_load_start__
  ldr r1, =__text_start__
  cmp r0, r1
  beq check_text_end
  ldr r2, =__text_end__
  subs r2, r2, r1
  beq check_text_end
  
check_text_loop:
  ldrb r3, [r0], #+1
  ldrb r4, [r1], #+1
  cmp r3, r4
  bne text_error_loop
  subs r2, r2, #1
  bne check_text_loop
check_text_end:  

  /* Check fast */
  ldr r0, =__fast_load_start__
  ldr r1, =__fast_start__
  cmp r0, r1
  beq check_fast_end
  ldr r2, =__fast_end__
  subs r2, r2, r1
  beq check_fast_end
  
check_fast_loop:
  ldrb r3, [r0], #+1
  ldrb r4, [r1], #+1
  cmp r3, r4
  bne fast_error_loop
  subs r2, r2, #1
  bne check_fast_loop
check_fast_end:  

  /* Check bss */
  ldr r0, =__bss_start__
  ldr r1, =__bss_end__
  mov r2, #0
check_bss_loop:
  cmp r0, r1
  beq check_bss_end
  ldrb r2, [r0], #+1
  cmp r2, #0
  bne bss_error_loop  
  b check_bss_loop
check_bss_end:    
#endif

  /* Initialise the heap */
  ldr r0, = __heap_start__
  ldr r1, = __heap_end__
  sub r1, r1, r0     /* r1 = r1-r0 */ 
  mov r2, #0
  str r2, [r0], #+4 /* *r0++ = 0 */
  str r1, [r0]      /* *r0 = __heap_end__ - __heap_start__ */

  /* Call constructors */
  ldr r0, =__ctors_start__
  ldr r1, =__ctors_end__
ctor_loop:
  cmp r0, r1
  beq ctor_end
  ldr r2, [r0], #+4
  stmfd sp!, {r0-r1}
  mov lr, pc
  mov pc, r2
  ldmfd sp!, {r0-r1}
  b ctor_loop
ctor_end:

  /* Setup initial call frame */
  mov lr, #4
  mov r12, sp
  stmfd sp!, {r11-r12, lr-pc}
  sub r11, r12, #0x00000004

start:
  /* Jump to main entry point */
  mov r0, #0
  mov r1, #0
  ldr r2, =main
  mov lr, pc
#ifdef __ARM_ARCH_3__
  mov pc, r2
#else    
  bx r2
#endif

  /* Call destructors */
  ldr r0, =__dtors_start__
  ldr r1, =__dtors_end__
dtor_loop:
  cmp r0, r1
  beq dtor_end
  ldr r2, [r0], #+4
  stmfd sp!, {r0-r1}
  mov lr, pc
  mov pc, r2
  ldmfd sp!, {r0-r1}
  b dtor_loop
dtor_end:

  /* Return from main, loop forever. */
exit_loop:
  b exit_loop

#ifdef CHECK
data_error_loop:
  b data_error_loop

text_error_loop:
  b text_error_loop
  
fast_error_loop:
  b fast_error_loop
  
bss_error_loop:
  b bss_error_loop  
#endif