1
|
/* Sample initialization file */
|
2
|
|
3
|
.extern main
|
4
|
.extern exit
|
5
|
.extern AT91F_LowLevelInit
|
6
|
.extern pio_irq_isr_value
|
7
|
.extern tc_sniffer_next_buffer_for_fiq
|
8
|
|
9
|
.text
|
10
|
.code 32
|
11
|
|
12
|
|
13
|
.align 0
|
14
|
|
15
|
.extern __stack_end__
|
16
|
.extern __bss_beg__
|
17
|
.extern __bss_end__
|
18
|
.extern __data_beg__
|
19
|
.extern __data_end__
|
20
|
.extern __data+beg_src__
|
21
|
|
22
|
.global start
|
23
|
.global endless_loop
|
24
|
|
25
|
/* Stack Sizes */
|
26
|
.set UND_STACK_SIZE, 0x00000004
|
27
|
.set ABT_STACK_SIZE, 0x00000004
|
28
|
.set FIQ_STACK_SIZE, 0x00000400
|
29
|
.set IRQ_STACK_SIZE, 0X00000400
|
30
|
.set SVC_STACK_SIZE, 0x00000400
|
31
|
|
32
|
/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */
|
33
|
.set MODE_USR, 0x10 /* User Mode */
|
34
|
.set MODE_FIQ, 0x11 /* FIQ Mode */
|
35
|
.set MODE_IRQ, 0x12 /* IRQ Mode */
|
36
|
.set MODE_SVC, 0x13 /* Supervisor Mode */
|
37
|
.set MODE_ABT, 0x17 /* Abort Mode */
|
38
|
.set MODE_UND, 0x1B /* Undefined Mode */
|
39
|
.set MODE_SYS, 0x1F /* System Mode */
|
40
|
|
41
|
.equ I_BIT, 0x80 /* when I bit is set, IRQ is disabled */
|
42
|
.equ F_BIT, 0x40 /* when F bit is set, FIQ is disabled */
|
43
|
|
44
|
.equ AT91C_BASE_AIC, (0xFFFFF000)
|
45
|
.equ AT91C_BASE_MC, (0xFFFFFF00)
|
46
|
.equ AT91C_BASE_PIOA, 0xFFFFF400
|
47
|
.equ AT91C_BASE_TC0, 0xFFFA0000
|
48
|
.equ AT91C_BASE_TC2, 0xFFFA0080
|
49
|
.equ AT91C_BASE_SSC, 0xFFFD4000
|
50
|
.equ SSC_CR, 0x0
|
51
|
.equ SSC_RCMR, 0x10
|
52
|
.equ SSC_CR_TXEN, 0x100
|
53
|
.equ AT91C_TC_SWTRG, ((1 << 2)|1)
|
54
|
.equ AT91C_TC_CLKEN, (1 << 0)
|
55
|
.equ PIO_DATA, (1 << 18)
|
56
|
.equ PIOA_SODR, 0x30
|
57
|
.equ PIOA_CODR, 0x34
|
58
|
.equ PIOA_PDSR, 0x3c
|
59
|
.equ PIOA_IDR, 0x44
|
60
|
.equ PIOA_ISR, 0x4c
|
61
|
.equ TC_CCR, 0x00
|
62
|
.equ TC2_CV, (0x80+0x10)
|
63
|
.equ AIC_EOICR, (304)
|
64
|
.equ PIO_LED1, (1 << 25)
|
65
|
.equ PIO_LED2, (1 << 12)
|
66
|
.equ MC_RCR, 0xFFFFFF00
|
67
|
.equ AIC_ISCR, (0x12C)
|
68
|
.equ PIO_SECONDARY_IRQ, 31
|
69
|
.equ PIO_SECONDARY_IRQ_BIT, (1 << PIO_SECONDARY_IRQ)
|
70
|
|
71
|
.equ BUFSIZE, 1024
|
72
|
|
73
|
start:
|
74
|
_start:
|
75
|
_mainCRTStartup:
|
76
|
|
77
|
/* Setup a stack for each mode - note that this only sets up a usable stack
|
78
|
for system/user, SWI and IRQ modes. Also each mode is setup with
|
79
|
interrupts initially disabled. */
|
80
|
ldr r0, .LC6
|
81
|
msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */
|
82
|
mov sp, r0
|
83
|
sub r0, r0, #UND_STACK_SIZE
|
84
|
msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */
|
85
|
mov sp, r0
|
86
|
sub r0, r0, #ABT_STACK_SIZE
|
87
|
msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */
|
88
|
/* Preload registers for FIQ handler */
|
89
|
ldr r10, =AT91C_BASE_PIOA
|
90
|
ldr r12, =AT91C_BASE_TC0
|
91
|
ldr r8, =AT91C_BASE_AIC
|
92
|
/*ldr r9, =AT91C_BASE_SSC*/
|
93
|
mov sp, r0
|
94
|
sub r0, r0, #FIQ_STACK_SIZE
|
95
|
msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */
|
96
|
mov sp, r0
|
97
|
sub r0, r0, #IRQ_STACK_SIZE
|
98
|
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */
|
99
|
mov sp, r0
|
100
|
sub r0, r0, #SVC_STACK_SIZE
|
101
|
msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* System Mode */
|
102
|
mov sp, r0
|
103
|
|
104
|
/* We want to start in supervisor mode. Operation will switch to system
|
105
|
mode when the first task starts. */
|
106
|
msr CPSR_c, #MODE_SVC|I_BIT|F_BIT
|
107
|
|
108
|
bl AT91F_LowLevelInit
|
109
|
|
110
|
/* Clear BSS. */
|
111
|
|
112
|
mov a2, #0 /* Fill value */
|
113
|
mov fp, a2 /* Null frame pointer */
|
114
|
mov r7, a2 /* Null frame pointer for Thumb */
|
115
|
|
116
|
ldr r1, .LC1 /* Start of memory block */
|
117
|
ldr r3, .LC2 /* End of memory block */
|
118
|
subs r3, r3, r1 /* Length of block */
|
119
|
beq .end_clear_loop
|
120
|
mov r2, #0
|
121
|
|
122
|
.clear_loop:
|
123
|
strb r2, [r1], #1
|
124
|
subs r3, r3, #1
|
125
|
bgt .clear_loop
|
126
|
|
127
|
.end_clear_loop:
|
128
|
|
129
|
/* Initialise data. */
|
130
|
|
131
|
ldr r1, .LC3 /* Start of memory block */
|
132
|
ldr r2, .LC4 /* End of memory block */
|
133
|
ldr r3, .LC5
|
134
|
subs r3, r3, r1 /* Length of block */
|
135
|
beq .end_set_loop
|
136
|
|
137
|
.set_loop:
|
138
|
ldrb r4, [r2], #1
|
139
|
strb r4, [r1], #1
|
140
|
subs r3, r3, #1
|
141
|
bgt .set_loop
|
142
|
|
143
|
.end_set_loop:
|
144
|
|
145
|
/* call main */
|
146
|
mov r0, #0 /* no arguments */
|
147
|
mov r1, #0 /* no argv either */
|
148
|
|
149
|
ldr lr, =main
|
150
|
bx lr
|
151
|
|
152
|
endless_loop:
|
153
|
b endless_loop
|
154
|
|
155
|
|
156
|
.align 0
|
157
|
|
158
|
.LC1:
|
159
|
.word __bss_beg__
|
160
|
.LC2:
|
161
|
.word __bss_end__
|
162
|
.LC3:
|
163
|
.word __data_beg__
|
164
|
.LC4:
|
165
|
.word __data_beg_src__
|
166
|
.LC5:
|
167
|
.word __data_end__
|
168
|
.LC6:
|
169
|
.word __stack_end__
|
170
|
|
171
|
|
172
|
/* Setup vector table. Note that undf, pabt, dabt, fiq just execute
|
173
|
a null loop. */
|
174
|
|
175
|
.section .startup,"ax"
|
176
|
.code 32
|
177
|
.align 0
|
178
|
|
179
|
b _start /* reset - _start */
|
180
|
ldr pc, _undf /* undefined - _undf */
|
181
|
ldr pc, _swi /* SWI - _swi */
|
182
|
ldr pc, _pabt /* program abort - _pabt */
|
183
|
ldr pc, _dabt /* data abort - _dabt */
|
184
|
nop /* reserved */
|
185
|
ldr pc, [pc,#-0xF20] /* IRQ - read the AIC */
|
186
|
/* ldr pc, [pc,#-0xF20] /* FIQ - fall through to fiq_handler */
|
187
|
|
188
|
|
189
|
/* Following is modified from openpcd/firmware/src/start/Cstartup_app.S */
|
190
|
#define LED_TRIGGER
|
191
|
|
192
|
.global fiq_handler
|
193
|
.func fiq_handler
|
194
|
my_fiq_handler:
|
195
|
/* code that uses pre-initialized FIQ reg */
|
196
|
/* r8 tmp
|
197
|
r9 tmp
|
198
|
r10 AT91C_BASE_PIOA
|
199
|
r11 tmp
|
200
|
r12 AT91C_BASE_TC0
|
201
|
r13 stack
|
202
|
r14 lr
|
203
|
*/
|
204
|
|
205
|
#ifdef LED_TRIGGER
|
206
|
mov r11, #PIO_LED1
|
207
|
str r11, [r10, #PIOA_CODR] /* enable LED */
|
208
|
#endif
|
209
|
ldr r8, [r10, #PIOA_ISR]
|
210
|
|
211
|
/* Store the retrieved PIO ISR value into pio_irq_isr_value */
|
212
|
ldr r11, =pio_irq_isr_value
|
213
|
str r8, [r11]
|
214
|
|
215
|
tst r8, #PIO_DATA /* check for PIO_DATA change */
|
216
|
beq .no_buffer
|
217
|
|
218
|
ldr r11, [r10, #PIOA_PDSR]
|
219
|
tst r11, #PIO_DATA /* check for PIO_DATA == 1 */
|
220
|
beq .no_buffer
|
221
|
|
222
|
/* mov r11, #PIO_LED2
|
223
|
str r11, [r10, #PIOA_CODR] /* enable LED */
|
224
|
|
225
|
/* Load the TC2.CV into r9 */
|
226
|
ldr r9, [r12, #TC2_CV]
|
227
|
|
228
|
ldr r11, =tc_sniffer_next_buffer_for_fiq
|
229
|
ldr r11, [r11]
|
230
|
/* r11 now contains the value of tc_sniffer_next_buffer_for_fiq, e.q. the address
|
231
|
* of the next buffer */
|
232
|
|
233
|
/* Jump to .no_buffer if the pointer is 0, indicating that no buffer is set */
|
234
|
cmp r11, #0
|
235
|
beq .no_buffer
|
236
|
|
237
|
/* Increment the value at the location the pointer points to */
|
238
|
ldr r8, [r11]
|
239
|
add r8, r8, #1
|
240
|
str r8, [r11]
|
241
|
|
242
|
/* At this point:
|
243
|
r8 = count
|
244
|
r9 = TC2.CV
|
245
|
r11 = pointer to buffer
|
246
|
*/
|
247
|
|
248
|
cmp r8, #BUFSIZE
|
249
|
bge .no_buffer
|
250
|
|
251
|
str r9, [r11, r8, LSL #2]
|
252
|
|
253
|
.no_buffer:
|
254
|
/* mov r11, #PIO_LED2
|
255
|
str r11, [r10, #PIOA_SODR] /* disable LED */
|
256
|
|
257
|
/* Trigger PIO_SECONDARY_IRQ */
|
258
|
mov r11, #PIO_SECONDARY_IRQ_BIT
|
259
|
ldr r8, =AT91C_BASE_AIC
|
260
|
str r11, [r8, #AIC_ISCR]
|
261
|
|
262
|
#ifdef LED_TRIGGER
|
263
|
mov r11, #PIO_LED1
|
264
|
str r11, [r10, #PIOA_SODR] /* disable LED */
|
265
|
#endif
|
266
|
|
267
|
/*- Mark the End of Interrupt on the AIC */
|
268
|
ldr r11, =AT91C_BASE_AIC
|
269
|
str r11, [r11, #AIC_EOICR]
|
270
|
|
271
|
/*- Restore the Program Counter using the LR_fiq directly in the PC */
|
272
|
subs pc, lr, #4
|
273
|
|
274
|
.size my_fiq_handler, . - my_fiq_handler
|
275
|
.endfunc
|
276
|
|
277
|
_undf: .word __undf /* undefined */
|
278
|
_swi: .word swi_handler /* SWI */
|
279
|
_pabt: .word __pabt /* program abort */
|
280
|
_dabt: .word __dabt /* data abort */
|
281
|
_fiq: .word __fiq /* FIQ */
|
282
|
|
283
|
__undf: b . /* undefined */
|
284
|
__pabt: b . /* program abort */
|
285
|
__dabt: b . /* data abort */
|
286
|
__fiq: b . /* FIQ */
|
287
|
|
288
|
.end
|
289
|
|