-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcsd_asm.S
227 lines (172 loc) · 3.88 KB
/
csd_asm.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
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
#include "uart_regs.h"
#include "csd_zynq_peripherals.h"
#include "uart_init.s"
#include "uart_print.s"
#define TIMER_INITIAL 0x2500000
// 1000000
.extern csd_main
.align 8
csd_entry:
b csd_reset
b csd_undefined
b csd_software_interrupt
b csd_prefetch
b csd_data
b csd_not_used
b csd_irq
b csd_fiq
.global main
main:
uart_init // UART initialization
// Disable interrupt: Turn on I bit in CPSR
cpsID i
cps #0x12 /* IRQ mode */
ldr r13,=irq_stack_top /* stack pointer setup for IRQ mode */
cps #0x13 /* supervisor mode */
ldr r13,=svc_stack_top /* stack pointer setup for SVC mode */
cps #0x11 /* FIQ mode */
ldr r13,=fiq_stack_top /* stack pointer setup for FIQ mode */
cps #0x1F /* SYS mode */
// Set VBAR (Vector Base Address Register) to the base of my interrupt vector table
ldr r0, =csd_entry
mcr p15, 0, r0, c12, c0, 0
dsb
isb
// Enable interrupt: Turn off I bit in CPSR
cpsIE i
// ---------------------------
// Generic Interrupt Controller (GIC) setup - Begin
//
// CPU Interface ID Register
ldr r0, =GICC_IIDR
ldr r3, [r0]
// CPU Controller Type Register
ldr r0, =GICD_TYPER
ldr r3, [r0]
// CPU Binary Pointer Register
ldr r0, =GICC_BPR
ldr r3, [r0]
// Distributor Control Register
ldr r0, =GICD_CTLR
ldr r1, [r0]
mov r2, #1 // Enable
orr r1, r1, r2
str r1, [r0]
ldr r3, [r0]
// Interrupt Set-Enable Register 0
ldr r0, =GICD_ISENABLER0
ldr r1, [r0]
mov r2, #1 << 29 // Enable #29 (Private Timer)
orr r1, r1, r2
str r1, [r0]
ldr r3, [r0]
// Interrupt Priority Register #7
ldr r0, =GICD_PRIOR7
ldr r1, [r0]
mov r2, #1 << 8 // 2nd Highest: 1 for ID# 29 (Private Timer)
orr r1, r1, r2
str r1, [r0]
ldr r3, [r0]
// CPU Interface Control Register
ldr r0, =GICC_CTLR
ldr r1, [r0]
mov r2, #1 // Enable
orr r1, r1, r2
str r1, [r0]
ldr r3, [r0]
// CPU Interface Interrupt Priority Mask Register
ldr r0, =GICC_PMR
ldr r1, [r0]
mov r2, #0xFF // Lowest
orr r1, r1, r2
str r1, [r0]
ldr r3, [r0]
//
// Generic Interrupt Controller (GIC) setup - End
// ---------------------------
// ---------------------------
// Private Timer setup - Begin
//
// Private Timer Load Register
ldr r0, =PRIVATE_LOAD
ldr r1, =TIMER_INITIAL
str r1, [r0]
// Private Timer Control Register
ldr r0, =PRIVATE_CONTROL
mov r1, #10 << 8 // Prescalar
orr r1, r1, #7 // IRQ Enable, Auto-Reload, Timer Enable
str r1, [r0]
//
// Private Timer setup - End
// ----------------------------
// Check out the counter value to make sure the counter is decrementing
ldr r0, =PRIVATE_COUNTER
ldr r1, [r0]
ldr r2, [r0]
ldr r3, [r0]
ldr r4, [r0]
ldr r5, [r0]
ldr r6, [r0]
ldr r7, [r0]
ldr r8, [r0]
ldr r0, =PRIVATE_COUNTER
ldr r1, =PRIVATE_STATUS
ldr r2, =GICD_ISPENDR0
forever:
ldr r5, [r0]
ldr r6, [r1]
ldr r7, [r2]
b forever
// ----------------------------
// Interrupt Service Routines (ISRs) - Begin
//
csd_software_interrupt:
ldr r0, =csd_LED_ADDR
ldr r1, =led_initial
str r1, [r0]
bl csd_main
b csd_software_interrupt
csd_reset:
csd_undefined:
csd_prefetch:
csd_data:
csd_not_used:
csd_irq:
stmfd sp!, {r0-r12, lr}
// »óÅÂ Ãâ·Â
stmfd sp!, {r0-r12, lr}
uart_print // Print time
ldmfd sp!, {r0-r12, lr}
// Interrupt Ack
ldr r0, =GICC_IAR
ldr r3, [r0]
// Toggle LEDs
ldr r0, =csd_LED_ADDR
ldr r1, =led_initial
ldr r2, [r1]
eor r2, r2, #0xFF
str r2, [r0]
str r2, [r1]
// Clear Interrupt Status bit
ldr r0, =PRIVATE_STATUS
mov r1, #1
str r1, [r0]
// End-of-Interrupt
ldr r0, =GICC_EOIR
str r3, [r0]
ldmfd sp!, {r0-r12, lr}
subs pc, lr, #4
csd_fiq:
b .
//
// Interrupt Service Routines (ISRs) - End
// ----------------------------
.data
.align 4
irq_stack: .space 1024
irq_stack_top:
fiq_stack: .space 1024
fiq_stack_top:
svc_stack: .space 1024
svc_stack_top:
led_initial: .word 0xC3