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
|
/***********************************************************************************
* Copyright 2005 Anglia Design
* This demo code and associated components are provided as is and has no warranty,
* implied or otherwise. You are free to use/modify any of the provided
* code at your own risk in your applications with the expressed limitation
* of liability (see below)
*
* LIMITATION OF LIABILITY: ANGLIA OR ANGLIA DESIGNS SHALL NOT BE LIABLE FOR ANY
* LOSS OF PROFITS, LOSS OF USE, LOSS OF DATA, INTERRUPTION OF BUSINESS, NOR FOR
* INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND WHETHER UNDER
* THIS AGREEMENT OR OTHERWISE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*
* Author : Spencer Oliver
* Web : www.anglia-designs.com
*
***********************************************************************************/
.equ VectorAddress, 0xFFFFF030 /* VIC Vector address register address. */
.equ VectorAddressDaisy, 0xFC000030 /* Daisy VIC Vector address register */
.equ Mode_USR, 0x10
.equ Mode_FIQ, 0x11
.equ Mode_IRQ, 0x12
.equ Mode_SVC, 0x13
.equ Mode_ABT, 0x17
.equ Mode_UND, 0x1B
.equ Mode_SYS, 0x1F /* available on ARM Arch 4 and later */
.equ I_Bit, 0x80 /* when I bit is set, IRQ is disabled */
.equ F_Bit, 0x40 /* when F bit is set, FIQ is disabled */
.text
.arm
.section .vectors, "ax"
.global Reset_Vec
/* Note: LDR PC instructions are used here, though branch (B) instructions */
/* could also be used, unless the ROM is at an address >32MB. */
/*******************************************************************************
Exception vectors
*******************************************************************************/
Reset_Vec: LDR pc, Reset_Addr /* Reset Handler */
Undef_Vec: LDR pc, Undefined_Addr
SWI_Vec: LDR pc, SWI_Addr
PAbt_Vec: LDR pc, Prefetch_Addr
DAbt_Vec: LDR pc, Abort_Addr
NOP /* Reserved vector */
IRQ_Vec: LDR pc, IRQ_Addr
FIQ_Vec: LDR pc, FIQ_Addr
/*******************************************************************************
Exception handlers address table
*******************************************************************************/
Reset_Addr: .word _start
Undefined_Addr: .word UndefinedHandler
SWI_Addr: .word SWIHandler
Prefetch_Addr: .word PrefetchHandler
Abort_Addr: .word AbortHandler
.word 0 /* reserved */
IRQ_Addr: .word IRQHandler
FIQ_Addr: .word FIQHandler
/*******************************************************************************
Exception Handlers
*******************************************************************************/
/*******************************************************************************
* Macro Name : SaveContext
* Description : This macro used to save the context before entering
an exception handler.
* Input : The range of registers to store.
* Output : none
*******************************************************************************/
.macro SaveContext reg1 reg2
STMFD sp!,{\reg1-\reg2,lr} /* Save The workspace plus the current return */
/* address lr_ mode into the stack */
MRS r1, spsr /* Save the spsr_mode into r1 */
STMFD sp!, {r1} /* Save spsr */
.endm
/*******************************************************************************
* Macro Name : RestoreContext
* Description : This macro used to restore the context to return from
an exception handler and continue the program execution.
* Input : The range of registers to restore.
* Output : none
*******************************************************************************/
.macro RestoreContext reg1 reg2
LDMFD sp!, {r1} /* Restore the saved spsr_mode into r1 */
MSR spsr_cxsf, r1 /* Restore spsr_mode */
LDMFD sp!, {\reg1-\reg2,pc}^ /* Return to the instruction following */
/* the exception interrupt */
.endm
/*******************************************************************************
* Function Name : IRQHandler
* Description : This function called when IRQ exception is entered.
* Input : none
* Output : none
*******************************************************************************/
IRQHandler:
SUB lr, lr, #4 /* Update the link register */
SaveContext r0, r12 /* Save the workspace plus the current */
/* return address lr_irq and spsr_irq */
LDR r0, =VectorAddress
LDR r0, [r0] /* Read the routine address */
LDR r1, =VectorAddressDaisy
LDR r1, [r1]
/* Padding between the acknowledge and re-enable of interrupts */
/* For more details, please refer to the following URL */
/* http://www.arm.com/support/faqip/3682.html */
NOP
NOP
MSR cpsr_c, #Mode_SYS /* Switch to SYS mode and enable IRQ */
STMFD sp!, {lr} /* Save the link register. */
LDR lr, =ReturnAddress /* Read the return address. */
MOV pc, r0 /* Branch to the IRQ handler. */
ReturnAddress:
LDMFD sp!, {lr} /* Restore the link register. */
MSR cpsr_c, #Mode_IRQ|I_Bit|F_Bit /* Switch to IRQ mode and disable IRQ */
LDR r0, =VectorAddress /* Write to the VectorAddress to clear the */
STR r0, [r0] /* respective interrupt in the internal interrupt */
LDR r1, =VectorAddressDaisy /* Write to the VectorAddressDaisy to clear the */
STR r1, [r1] /* respective interrupt in the internal interrupt */
RestoreContext r0, r12 /* Restore the context and return to the program execution. */
/*******************************************************************************
* Function Name : SWIHandler
* Description : This function called when SWI instruction executed.
* Input : none
* Output : none
*******************************************************************************/
SWIHandler:
SaveContext r0, r12 /* r0 holds swi number */
MOV r1, sp /* load regs */
BL SWI_Handler
RestoreContext r0, r12
/*******************************************************************************
* Function Name : UndefinedHandler
* Description : This function called when undefined instruction
exception is entered.
* Input : none
* Output : none
*******************************************************************************/
UndefinedHandler:
SaveContext r0, r12
BL Undefined_Handler
RestoreContext r0, r12
/*******************************************************************************
* Function Name : PrefetchAbortHandler
* Description : This function called when Prefetch Abort
exception is entered.
* Input : none
* Output : none
*******************************************************************************/
PrefetchHandler:
SUB lr, lr, #4 /* Update the link register. */
SaveContext r0, r12
BL Prefetch_Handler
RestoreContext r0, r12
/*******************************************************************************
* Function Name : DataAbortHandler
* Description : This function is called when Data Abort
exception is entered.
* Input : none
* Output : none
*******************************************************************************/
AbortHandler:
SUB lr, lr, #8 /* Update the link register. */
SaveContext r0, r12
BL Abort_Handler
RestoreContext r0, r12
/*******************************************************************************
* Function Name : FIQHandler
* Description : This function is called when FIQ
exception is entered.
* Input : none
* Output : none
*******************************************************************************/
FIQHandler:
SUB lr, lr, #4 /* Update the link register. */
SaveContext r0, r7
BL FIQ_Handler
RestoreContext r0, r7
.end
|