1 |
633c646a
|
henryk
|
/* Sample initialization file */
|
2 |
|
|
|
3 |
|
|
.extern main
|
4 |
|
|
.extern exit
|
5 |
|
|
.extern AT91F_LowLevelInit
|
6 |
aa804cf4
|
henryk
|
.extern pio_irq_isr_value
|
7 |
3ee3c4a6
|
henryk
|
.extern tc_sniffer_next_buffer_for_fiq
|
8 |
633c646a
|
henryk
|
|
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 |
616746c2
|
henryk
|
.set FIQ_STACK_SIZE, 0x00000400
|
29 |
633c646a
|
henryk
|
.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 |
616746c2
|
henryk
|
.equ AT91C_BASE_AIC, (0xFFFFF000)
|
45 |
50c363d0
|
henryk
|
.equ AT91C_BASE_MC, (0xFFFFFF00)
|
46 |
616746c2
|
henryk
|
.equ AT91C_BASE_PIOA, 0xFFFFF400
|
47 |
|
|
.equ AT91C_BASE_TC0, 0xFFFA0000
|
48 |
3ee3c4a6
|
henryk
|
.equ AT91C_BASE_TC2, 0xFFFA0080
|
49 |
062f55ca
|
henryk
|
.equ AT91C_BASE_SSC, 0xFFFD4000
|
50 |
3d2ce8df
|
henryk
|
.equ SSC_CR, 0x0
|
51 |
062f55ca
|
henryk
|
.equ SSC_RCMR, 0x10
|
52 |
3d2ce8df
|
henryk
|
.equ SSC_CR_TXEN, 0x100
|
53 |
e777e32a
|
henryk
|
.equ AT91C_TC_SWTRG, ((1 << 2)|1)
|
54 |
062f55ca
|
henryk
|
.equ AT91C_TC_CLKEN, (1 << 0)
|
55 |
3ee3c4a6
|
henryk
|
.equ PIO_DATA, (1 << 18)
|
56 |
616746c2
|
henryk
|
.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 |
d88d1207
|
henryk
|
.equ TC2_CV, (0x80+0x10)
|
63 |
616746c2
|
henryk
|
.equ AIC_EOICR, (304)
|
64 |
062f55ca
|
henryk
|
.equ PIO_LED1, (1 << 25)
|
65 |
|
|
.equ PIO_LED2, (1 << 12)
|
66 |
50c363d0
|
henryk
|
.equ MC_RCR, 0xFFFFFF00
|
67 |
aa804cf4
|
henryk
|
.equ AIC_ISCR, (0x12C)
|
68 |
|
|
.equ PIO_SECONDARY_IRQ, 31
|
69 |
|
|
.equ PIO_SECONDARY_IRQ_BIT, (1 << PIO_SECONDARY_IRQ)
|
70 |
633c646a
|
henryk
|
|
71 |
3ee3c4a6
|
henryk
|
.equ BUFSIZE, 1024
|
72 |
|
|
|
73 |
633c646a
|
henryk
|
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 |
616746c2
|
henryk
|
/* Preload registers for FIQ handler */
|
89 |
|
|
ldr r10, =AT91C_BASE_PIOA
|
90 |
|
|
ldr r12, =AT91C_BASE_TC0
|
91 |
|
|
ldr r8, =AT91C_BASE_AIC
|
92 |
062f55ca
|
henryk
|
/*ldr r9, =AT91C_BASE_SSC*/
|
93 |
633c646a
|
henryk
|
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 |
50c363d0
|
henryk
|
/* call main */
|
146 |
633c646a
|
henryk
|
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 |
73d04ff8
|
henryk
|
/* ldr pc, [pc,#-0xF20] /* FIQ - fall through to fiq_handler */
|
187 |
633c646a
|
henryk
|
|
188 |
616746c2
|
henryk
|
|
189 |
73d04ff8
|
henryk
|
/* Following is modified from openpcd/firmware/src/start/Cstartup_app.S */
|
190 |
616746c2
|
henryk
|
#define LED_TRIGGER
|
191 |
73d04ff8
|
henryk
|
|
192 |
616746c2
|
henryk
|
.global fiq_handler
|
193 |
|
|
.func fiq_handler
|
194 |
062f55ca
|
henryk
|
my_fiq_handler:
|
195 |
|
|
/* code that uses pre-initialized FIQ reg */
|
196 |
aa804cf4
|
henryk
|
/* r8 tmp
|
197 |
3ee3c4a6
|
henryk
|
r9 tmp
|
198 |
062f55ca
|
henryk
|
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 |
aa804cf4
|
henryk
|
|
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 |
062f55ca
|
henryk
|
tst r8, #PIO_DATA /* check for PIO_DATA change */
|
216 |
3ee3c4a6
|
henryk
|
beq .no_buffer
|
217 |
3d2ce8df
|
henryk
|
|
218 |
3ee3c4a6
|
henryk
|
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 |
d88d1207
|
henryk
|
|
228 |
3ee3c4a6
|
henryk
|
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 |
3d2ce8df
|
henryk
|
|
233 |
3ee3c4a6
|
henryk
|
/* Jump to .no_buffer if the pointer is 0, indicating that no buffer is set */
|
234 |
|
|
cmp r11, #0
|
235 |
|
|
beq .no_buffer
|
236 |
d88d1207
|
henryk
|
|
237 |
3ee3c4a6
|
henryk
|
/* 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 |
3d2ce8df
|
henryk
|
|
257 |
aa804cf4
|
henryk
|
/* Trigger PIO_SECONDARY_IRQ */
|
258 |
|
|
mov r11, #PIO_SECONDARY_IRQ_BIT
|
259 |
|
|
ldr r8, =AT91C_BASE_AIC
|
260 |
|
|
str r11, [r8, #AIC_ISCR]
|
261 |
062f55ca
|
henryk
|
|
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 |
73d04ff8
|
henryk
|
_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 |
616746c2
|
henryk
|
.end
|
289 |
062f55ca
|
henryk
|
|