-
Notifications
You must be signed in to change notification settings - Fork 1
/
crt.S
executable file
·174 lines (154 loc) · 4.88 KB
/
crt.S
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
/******************************************************
crt.S
Este modulo em assembly tem os vetores de interrupcao
e os procedimentos de inicializacao
***************************************************** */
.extern main
.extern exit
.text
.code 32
.align 0
/* Nomes dos segmentos definidos no script do linker *.ld */
.extern __bss_beg__
.extern __bss_end__
.extern __stack_end__
.extern __data_beg__
.extern __data_end__
.extern __data+beg_src__
.global start
.global endless_loop
/* Tamanho das pilhas */
.set UND_STACK_SIZE, 0x00000800
.set ABT_STACK_SIZE, 0x00000800
.set FIQ_STACK_SIZE, 0x00000800
.set IRQ_STACK_SIZE, 0X00000800
.set SVC_STACK_SIZE, 0x00000800
/* Bits de definicao dos modos de operacao no CPSR */
.set MODE_USR, 0x10 /* User Mode */
.set MODE_FIQ, 0x11 /* FIQ Mode */
.set MODE_IRQ, 0x12 /* IRQ Mode */
.set MODE_SVC, 0x13 /* Supervisor Mode */
.set MODE_ABT, 0x17 /* Abort Mode */
.set MODE_UND, 0x1B /* Undefined Mode */
.set MODE_SYS, 0x1F /* System Mode */
.equ I_BIT, 0x80 /* when I bit is set, IRQ is disabled */
.equ F_BIT, 0x40 /* when F bit is set, FIQ is disabled */
start:
_start:
_mainCRTStartup:
/* Configura a pilha para cada modo de operacao: system/user, SWI e IRQ */
ldr r0, .LC6
msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */
mov sp, r0
sub r0, r0, #UND_STACK_SIZE
msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */
mov sp, r0
sub r0, r0, #ABT_STACK_SIZE
msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */
mov sp, r0
sub r0, r0, #FIQ_STACK_SIZE
msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
mov sp, r0
sub r0, r0, #IRQ_STACK_SIZE
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */
mov sp, r0
sub r0, r0, #SVC_STACK_SIZE
msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* System Mode */
mov sp, r0
/* Inicia em modo supervisor. */
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT
/* Limpa BSS. */
mov a2, #0 /* Fill value */
mov fp, a2 /* Null frame pointer */
mov r7, a2 /* Null frame pointer for Thumb */
ldr r1, .LC1 /* Start of memory block */
ldr r3, .LC2 /* End of memory block */
subs r3, r3, r1 /* Length of block */
beq .end_clear_loop
mov r2, #0
.clear_loop:
strb r2, [r1], #1
subs r3, r3, #1
bgt .clear_loop
.end_clear_loop:
/* Initialise data. */
ldr r1, .LC3 /* Start of memory block */
ldr r2, .LC4 /* End of memory block */
ldr r3, .LC5
subs r3, r3, r1 /* Length of block */
beq .end_set_loop
.set_loop:
ldrb r4, [r2], #1
strb r4, [r1], #1
subs r3, r3, #1
bgt .set_loop
.end_set_loop:
/******** Configura clock (Acrescentado por Marcos Stemmer)*/
ldr r3, = 0xE01FC100
mov r2, #0x21 /* Liga clock 12M */
str r2, [r3, #0xa0] /* SCS = 0x21 GPIO em modo Fast */
Lp2:
ldr r2, [r3, #0xa0] /* Espera estabilizar */
tst r2, #0x40 /* while(SCS & 0x40); */
beq Lp2
mov r2, #1 /* Usa clock 12M para a CPU */
str r2, [r3, #0x0c] /* CLKSRCSEL = 1; */
mov r2, #0 /* Divisor por 1 na CPU */
str r2, [r3, #0x04] /* CCLKCFG=0; */
/* Divisor por 4 nos perifericos */
ldr r2, = 0x55555555
str r2, [r3, #0xA8] /* PCLKSEL0 = 0x55555555; */
str r2, [r3, #0xAC] /* PCLKSEL1 = 0x55555555; */
mov r2, #0 /*Deve fazer PINSEL10=0 para que */
/* Coloca 0 em todos os PINSELs (Todos os pinos como GPIO)*/
ldr r3, = 0xE002C000
str r2, [r3, #0x00]
str r2, [r3, #0x04]
str r2, [r3, #0x08]
str r2, [r3, #0x0c]
str r2, [r3, #0x10]
str r2, [r3, #0x14]
str r2, [r3, #0x18]
str r2, [r3, #0x1c]
str r2, [r3, #0x20]
str r2, [r3, #0x24]
str r2, [r3, #0x28]
/* Configura o MAM */
ldr r3, = 0xE01FC000
str r2, [r3, #0] /* MAMCR=0 */
mov r2, #3
str r2, [r3, #4] /* MAMTIM=3 */
mov r2, #2
str r2, [r3, #0] /* MAMCR=2 */
/****** Fim da configuracao do clock *******/
/* Entra na funcao main() do programa em C */
mov r0, #0 /* argc = 0 */
mov r1, #0 /* argv = NULL */
ldr r14, =start /* Se retornar vai para start */
ldr pc, = main
.align 0
.LC1: .word __bss_beg__
.LC2: .word __bss_end__
.LC3: .word __data_beg__
.LC4: .word __data_beg_src__
.LC5: .word __data_end__
.LC6: .word __stack_end__
.section .startup,"ax"
.code 32
.align 0
/* Vetores de interrupcao */
_vectors: ldr PC, Reset_Addr
ldr PC, Undef_Addr
ldr PC, SWI_Addr
ldr PC, PAbt_Addr
ldr PC, DAbt_Addr
nop /* Reservado para a soma (checksum) dos vetores */
ldr PC, [PC,#-0x0120]
ldr PC, FIQ_Addr
Reset_Addr: .word start /* definido neste modulo */
Undef_Addr: .word UNDEF_Routine /* definido no main.c */
SWI_Addr: .word SWI_Routine /* definido no main.c */
PAbt_Addr: .word UNDEF_Routine /* definido no main.c */
DAbt_Addr: .word UNDEF_Routine /* definido no main.c */
FIQ_Addr: .word FIQ_Routine /* definido no main.c */
.word 0 /* Arredonda para um total de 16 vetores */