aboutsummaryrefslogtreecommitdiff
path: root/AT91SAM7S256/SAM7S256/Include/Cstartup.s79
blob: 550ae1eaca87b95c41b8c9e6d6832e255ee76254 (plain)
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
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
;------------------------------------------------------------------------------
;-         ATMEL Microcontroller Software Support  -  ROUSSET  -
;------------------------------------------------------------------------------
; The software is delivered "AS IS" without warranty or condition of any
; kind, either express, implied or statutory. This includes without
; limitation any warranty or condition with respect to merchantability or
; fitness for any particular purpose, or against the infringements of
; intellectual property rights of others.
;-----------------------------------------------------------------------------
;- File source          : Cstartup.s79
;- Object               : Generic CStartup for IAR No Use REMAP
;- Compilation flag     : None
;-
;- 1.0 15/Jun/04 JPP    : Creation
;- 1.2 04/Feb/05 JPP    : Add Copy Flash vector to RAM and remap
;- 1.3 08/Feb/05 JPP    : Remap
;- 1.4 01/Apr/05 JPP    : save SPSR
;------------------------------------------------------------------------------

#include "AT91SAM7S256_inc.h"

#define ARM_MODE_FIQ    ( 0x11) // Core Mode
#define ARM_MODE_IRQ    ( 0x12) // Core Mode
#define ARM_MODE_SVC    ( 0x13) // Core Mode
#define I_BIT           ( 0x80) // Core Mode
#define F_BIT           ( 0x40) // Core Mode

;------------------------------------------------------------------------------
;- Area Definition
;------------------------------------------------------------------------------

;---------------------------------------------------------------
; ?RESET
; Reset Vector.
; Normally, segment INTVEC is linked at address 0.
; For debugging purposes, INTVEC may be placed at other
; addresses.
;-------------------------------------------------------------

		PROGRAM	?RESET

		RSEG	ICODE:CODE:ROOT(2)
		CODE32	; Always ARM mode after reset	
		ORG	0	
	        PUBLIC	reset
            	EXTERN   InitReset

reset		
;------------------------------------------------------------------------------
;- Program RESET
;--------------------
;- These vectors can be read at address 0 or at RAM address
;- They ABSOLUTELY requires to be in relative addresssing mode in order to
;- guarantee a valid jump. For the moment, all are just looping.
;- If an exception occurs before remap, this would result in an infinite loop.
;- To ensure if a exeption occurs before start application to infinite loop.
;------------------------------------------------------------------------------

                B           InitReset           ; 0x00 Reset handler
undefvec:
                B           undefvec            ; 0x04 Undefined Instruction
swivec:
                B           swivec              ; 0x08 Software Interrupt
pabtvec:
                B           pabtvec             ; 0x0C Prefetch Abort
dabtvec:
                B           dabtvec             ; 0x10 Data Abort
rsvdvec:
                B           rsvdvec             ; 0x14 reserved
irqvec:
                B           IRQ_Handler_Entry   ; 0x18 IRQ
fiqvec:               				; 0x1c FIQ
;------------------------------------------------------------------------------
;- Function             : FIQ_Handler_Entry
;- Treatments           : FIQ Controller Interrupt Handler.
;- Called Functions     : AIC_FVR[interrupt]
;------------------------------------------------------------------------------
FIQ_Handler_Entry:

;- Switch in SVC/User Mode to allow User Stack access for C code
; because the FIQ is not yet acknowledged

;- Save and r0 in FIQ_Register
            mov         r9,r0
	    ldr         r0 , [r8, #AIC_FVR]
            msr         CPSR_c,#I_BIT | F_BIT | ARM_MODE_SVC

;- Save scratch/used registers and LR in User Stack
            stmfd       sp!, { r1-r3, r12, lr}

;- Branch to the routine pointed by the AIC_FVR
            mov         r14, pc
            bx          r0

;- Restore scratch/used registers and LR from User Stack
            ldmia       sp!, { r1-r3, r12, lr}

;- Leave Interrupts disabled and switch back in FIQ mode
            msr         CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ

;- Restore the R0 ARM_MODE_SVC register
            mov         r0,r9

;- Restore the Program Counter using the LR_fiq directly in the PC
            subs        pc,lr,#4

;------------------------------------------------------------------------------
;- Manage exception
;---------------
;- This module The exception must be ensure in ARM mode
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;- Function             : IRQ_Handler_Entry
;- Treatments           : IRQ Controller Interrupt Handler.
;- Called Functions     : AIC_IVR[interrupt]
;------------------------------------------------------------------------------
IRQ_Handler_Entry:

;- Manage Exception Entry
;- Adjust and save LR_irq in IRQ stack
            sub         lr, lr, #4
            stmfd       sp!, {lr}

;- Save SPSR need to be saved for nested interrupt
            mrs         r14, SPSR
            stmfd       sp!, {r14}

;- Save and r0 in IRQ stack
            stmfd       sp!, {r0}

;- Write in the IVR to support Protect Mode
;- No effect in Normal Mode
;- De-assert the NIRQ and clear the source in Protect Mode
            ldr         r14, =AT91C_BASE_AIC
	    ldr         r0 , [r14, #AIC_IVR]
	    str         r14, [r14, #AIC_IVR]

;- Enable Interrupt and Switch in Supervisor Mode
           msr         CPSR_c, #ARM_MODE_SVC

;- Save scratch/used registers and LR in User Stack
            stmfd       sp!, { r1-r3, r12, r14}

;- Branch to the routine pointed by the AIC_IVR
            mov         r14, pc
            bx          r0

;- Restore scratch/used registers and LR from User Stack
            ldmia       sp!, { r1-r3, r12, r14}

;- Disable Interrupt and switch back in IRQ mode
            msr         CPSR_c, #I_BIT | ARM_MODE_IRQ

;- Mark the End of Interrupt on the AIC
            ldr         r14, =AT91C_BASE_AIC
            str         r14, [r14, #AIC_EOICR]

;- Restore R0
            ldmia       sp!, {r0}

;- Restore SPSR_irq and r0 from IRQ stack
            ldmia       sp!, {r14}
            msr         SPSR_cxsf, r14

;- Restore adjusted  LR_irq from IRQ stack directly in the PC
            ldmia       sp!, {pc}^

;---------------------------------------------------------------
; ?EXEPTION_VECTOR
; This module is only linked if needed for closing files.
;---------------------------------------------------------------
		PUBLIC	AT91F_Default_FIQ_handler
		PUBLIC	AT91F_Default_IRQ_handler
		PUBLIC	AT91F_Spurious_handler

AT91F_Default_FIQ_handler
            b     AT91F_Default_FIQ_handler

AT91F_Default_IRQ_handler
            b     AT91F_Default_IRQ_handler

AT91F_Spurious_handler
            b     AT91F_Spurious_handler

		ENDMOD
		
;------------------------------------------------------------------------------
;- Program RESET_init
;--------------------
;- This Program continous the initialization.
;------------------------------------------------------------------------------
		PROGRAM	?RESET_init
		RSEG	INTRAMEND_REMAP
		RSEG	INTRAMSTART
		RSEG    INTRAMEND_BEFORE_REMAP		

		RSEG	ICODE:CODE:ROOT(2)
		CODE32	; Always ARM mode after reset	
	        PUBLIC	InitReset
           	EXTERN   AT91F_LowLevelInit

InitReset:
;------------------------------------------------------------------------------
;- Low level Init (PMC, AIC, ? ....) by C function AT91F_LowLevelInit
;------------------------------------------------------------------------------

#define  __iStack_end 	SFB(INTRAMEND_BEFORE_REMAP)

;- minumum C initialization
;- call  AT91F_LowLevelInit( void)
; note this fonction can be write in Assembeler

            ldr     r13,=__iStack_end         ; temporary stack in internal RAM
;--Call Low level init function in ABSOLUTE through the Interworking

	    ldr	    r0,=AT91F_LowLevelInit
            ldr     r1,=0x0000FFFF
            and     r0,r0,r1
            mov     lr, pc
	    bx	    r0
;---------------------------------------------------------------
; ?CSTARTUP
;---------------------------------------------------------------
; copy the flash code to RAM code this product use a very littel RAM
; and no need to get the code size
#define  __intram       SFB(INTRAMSTART)

                ldr     r12, = __intram

; get the relative address offset
           	EXTERN   reset

add_pc:         sub     r11,pc,#((add_pc+8)-InitReset)
#ifndef RAM_DEBUG
add_pc_1:	sub     r10,pc,#((add_pc_1+4)-reset)
; copy the UndefVec at Software vec to protect a software reset	
		ldr     r1,[r10],#4
		str     r1,[r12],#4
#else
add_pc_1:	sub     r10,pc,#((add_pc_1+8)-reset)
; copy the UndefVec at Software vec to protect a software reset	
		ldr     r1,[r10],#4
    	        str     r1,[r12],#4
		ldr     r1,[r10],#4
#endif
		str     r1,[r12],#4

; copy next address
copy:		
		ldr     r1,[r10],#4
		str     r1,[r12],#4
		cmp	r10,r11
		BNE     copy

;------------------------------------------------------------------------------
;- Stack Sizes Definition
;------------------------
;- Interrupt Stack requires 2 words x 8 priority level x 4 bytes when using
;- the vectoring. This assume that the IRQ management.
;- The Interrupt Stack must be adjusted depending on the interrupt handlers.
;- Fast Interrupt not requires stack If in your application it required you must
;- be definehere.
;- The System stack size is not defined and is limited by the free internal
;- SRAM.
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
;- Top of Stack Definition
;-------------------------
;- Interrupt and Supervisor Stack are located at the top of internal memory in
;- order to speed the exception handling context saving and restoring.
;- ARM_MODE_SVC (Application, C) Stack is located at the top of the external memory.
;------------------------------------------------------------------------------

IRQ_STACK_SIZE          EQU     (3*8*4)     ; 3 words per interrupt priority level


;------------------------------------------------------------------------------
;- Setup the stack for each mode
;-------------------------------
#define  __iramend 	SFB(INTRAMEND_REMAP)

                ldr     r0, =__iramend

;- Set up Fast Interrupt Mode and set FIQ Mode Stack
                msr     CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT
;- Init the FIQ register
            	ldr     r8, =AT91C_BASE_AIC

;- Set up Interrupt Mode and set IRQ Mode Stack
                msr     CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
                mov     r13, r0                     ; Init stack IRQ
                sub     r0, r0, #IRQ_STACK_SIZE

;- Enable interrupt & Set up Supervisor Mode and set Supervisor Mode Stack
                msr     CPSR_c, #ARM_MODE_SVC
                mov     r13, r0

;--------------------------------------------
;- Remap Command and jump on ABSOLUT address
;--------------------------------------------
                ldr     r12, PtInitRemap        ; Get the real jump address ( after remap )
                ldr     r0,=AT91C_MC_RCR        ; Get remap address
		mov     r1,#1                   ; Get the REMAP value

#ifndef RAM_DEBUG
                str     r1,[r0]
#endif	
;- Jump to LINK address at its absolut address
                mov     pc, r12                 ; Jump and break the pipeline
PtInitRemap:
                DCD     InitRemap               ; Address where to jump after REMAP
InitRemap:
;---------------------------------------------------------------
; ?CSTARTUP
;---------------------------------------------------------------
		EXTERN	__segment_init
		EXTERN	main
; Initialize segments.
; __segment_init is assumed to use
; instruction set and to be reachable by BL from the ICODE segment
; (it is safest to link them in segment ICODE).
		ldr	r0,=__segment_init
                mov     lr, pc
		bx	r0

		PUBLIC	__main
?jump_to_main:
		ldr	lr,=?call_exit
		ldr	r0,=main
__main:
		bx	r0

;------------------------------------------------------------------------------
;- Loop for ever
;---------------
;- End of application. Normally, never occur.
;- Could jump on Software Reset ( B 0x0 ).
;------------------------------------------------------------------------------
?call_exit:
End
            b       End

	ENDMOD

	END