-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstart.s
185 lines (143 loc) · 3.09 KB
/
start.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
175
176
177
178
179
180
181
182
183
184
185
.text
.global bare_start
@; The next 16 words will be copied to address 0. The ldr instruction will use relative addressing
@; to indicate the adress being loaded from, so we preserve the offset between the instructions and
@; the corresponding vectors by copying both. The vector variables themselves then contain absolute
@; addresses of the handler routines.
interrupt_vectors:
ldr pc, bare_start_addr
ldr pc, undef_vector
ldr pc, swi_vector
ldr pc, prefetch_abort_vector
ldr pc, data_abort_vector
ldr pc, nothing
ldr pc, irq_vector
ldr pc, fiq_vector
bare_start_addr:
.word bare_start
undef_vector:
.word undef_instr_handler
swi_vector:
.word loop
prefetch_abort_vector:
.word loop
data_abort_vector:
.word loop
nothing:
.word 0
irq_vector:
.word irq_handler_blink
fiq_vector:
.word loop
bare_start:
@; enable single & double precision vfp using coprocessor access control register
mrc p15, 0, r0, c1, c0, 2
orr r0, #0xf00000
mcr p15, 0, r0, c1, c0, 2
@; enable vfp
mov r0, #0x40000000
fmxr fpexc, r0
@; enable flush-to-zero (24)
@; disable traps for underflow (11), inexact (12), and input denormal (15)
fmrx r0, fpscr
orr r0, #0x01000000
bic r0, #0x9800
fmxr fpscr, r0
@; change to irq mode and set up stack
cps #18
ldr sp, =irq_stack
@; change to undefined mode and set up stack
cps #27
ldr sp, =und_stack
@; enable irq, change to user mode
cpsie i, #16
ldr sp, =user_stack
@; install interrupt handlers
mov r0, #0x8000
mov r1, #0
ldm r0!, {r2, r3, r4, r5, r6, r7, r8, r9}
stm r1!, {r2, r3, r4, r5, r6, r7, r8, r9}
ldm r0!, {r2, r3, r4, r5, r6, r7, r8, r9}
stm r1!, {r2, r3, r4, r5, r6, r7, r8, r9}
bl notmain
loop:
b loop
irq_handler_blink:
push {r0, r1, r2, lr}
bl blink_fast
mov r0, #0xffffffff
ldr r1, =0x20200040 @; GPEDS0
str r0, [r1]
pop {r0, r1, r2, lr}
subs pc, lr, #4
blink_fast:
mov r2, #3
@; Set GPIO16 for output using GPFSEL1
ldr r1, =0x20200004
ldr r0, [r1]
bic r0, r0, #0x1c0000
orr r0, r0, #0x040000
str r0, [r1]
blink2:
@; Set GPIO16 using GPSET0
ldr r1, =0x2020001C
mov r0, #0x10000
str r0, [r1]
mov r0, #0x100000
blink3:
subs r0, r0, #1
bne blink3
@; Clear GPIO16 using GPCLR0
ldr r1, =0x20200028
mov r0, #0x10000
str r0, [r1]
mov r0, #0x100000
blink4:
subs r0, r0, #1
bne blink4
subs r2, r2, #1
bne blink2
bx lr
@; when a floating-point exception occurs, clear exception flags and resume
undef_instr_handler:
push {r0}
mov r0, #0x40000000
fmxr fpexc, r0
pop {r0}
subs pc, lr, #4
.global raise
@; Needed by libgcc functions, like ldiv0
raise:
b raise
.global dummy
dummy:
bx lr
.global malloc
malloc:
@; save num bytes to allocate in r1
mov r1, r0
ldr r2, =heap_pointer
@; current heap pointer will be returned in r0
ldr r0, [r2]
@; adjust heap pointer and save it
add r1, r1, r0
str r1, [r2]
bx lr
.data
.global dma_control_blocks
.align 8
dma_control_blocks:
.space 0x80
heap_pointer:
.word heap_base
.space 0x1000,0xbb
user_stack:
.word 0xbb
.space 0x1000,0xbb
irq_stack:
.word 0xbb
.space 0x1000,0xbb
und_stack:
.word 0xbb
heap_base:
.word 0xbb