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
348
349
350
351
352
353
354
355
356
357
358
359
360
361
|
#*************************************************************************
# *** STR912 Startup Code For GNU Tools (executed after Reset) ***
#
# (C) Hitex (UK) Ltd. 2006
#
# Disclaimer: Whilst every effort has been made to ensure the correctness
# of this code, Hitex (UK) Ltd. cannot be held responsible for the consequences
# of its use. Users should therefore verify its operation before including it
# in any program.
#*************************************************************************
#
#
# ---------------------------------------------
# Include startup macros
# ---------------------------------------------
.include "./startup_generic.S"
# reference to external interrupt handlers
#
# .extern SWI_Handler
# .extern PAbt_Handler
# .extern DAbt_Handler
# .extern Undefined_Handler
# .extern FIQ_Handler
#
# Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs
#
.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
#
.equ I_BIT, 0x80 /* when I bit is set, IRQ is disabled */
.equ F_BIT, 0x40 /* when F bit is set, FIQ is disabled */
#
#
# System Memory definitions
#
# Internal RAM definitions
.equ RAM_Size, 0x00018000 /* 96K */
.equ RAM_Base, 0x04000000
#*************************************************************************
# Control Startup Code Operation
#*************************************************************************
.equ SRAM_SETUP , 0 /* Enable setup of SRAM */
.equ FMI_SETUP , 0 /* Enable FMI Setup */
.equ CLOCK_SETUP , 1 /* Enable clock setup */
.equ ETM_SETUP , 0 /* Enable ETM setup */
#*************************************************************************
# Hardware Definitions
#*************************************************************************
# Flash Memory Interface (FMI) definitions (Flash banks sizes and addresses)
.equ FMI_BASE , 0x54000000 /* FMI Base Address (non-buffered) */
.equ FMI_BBSR_OFS , 0x00 /* Boot Bank Size Register */
.equ FMI_NBBSR_OFS , 0x04 /* Non-boot Bank Size Register */
.equ FMI_BBADR_OFS , 0x0C /* Boot Bank Base Address Register #!!! Documentation page 30,*/
.equ FMI_NBBADR_OFS , 0x10 /* Non-boot Bank Base Address Register #!!! adresseses do not correspond*/
.equ FMI_CR_OFS , 0x18 /* Control Register */
.equ FMI_SR_OFS , 0x1C /* Status Register */
.equ FMI_CR_Val , 0x00000018
.equ FMI_BBSR_Val , 0x00000004
.equ FMI_BBADR_Val , 0x00000000
.equ FMI_NBBSR_Val , 0x00000002
.equ FMI_NBBADR_Val , 0x00080000
.equ FLASH_CFG_Val , 0x00001010
.equ FMI_SR_Val , 0x00000003 /* Clear status errors (register not in STR912 manual! */
# System Control Unit (SCU) definitions
.equ SCU_BASE , 0x5C002000 /* SCU Base Address (non-buffered) */
.equ SCU_CLKCNTR_OFS , 0x00 /* Clock Control register Offset */
.equ SCU_PLLCONF_OFS , 0x04 /* PLL Configuration register Offset */
.equ SCU_SYSTAT_OFS , 0x08 /* SCU status register offset */
.equ SCU_PCGR0_OFS , 0x14 /* Peripheral Clock Gating Register 0 Offset */
.equ SCU_PCGR1_OFS , 0x18 /* Peripheral Clock Gating Register 1 Offset */
.equ SCU_SCR0_OFS , 0x34 /* System Configuration Register 0 Offset */
.equ SCU_CLKCNTR_Val , 0x00030000 /* Use PLL, external memory ratio/2 */
.equ SCU_PLLCONF_Val , 0x000AC019
.equ SCU_PCGR0_Val , 0x000000DB /* Setup ext mem clock, EMI, SRAM, Prefetch Queue/Branch cache, FMI */
.equ SCU_PCGR1_Val , 0x00C40000 /* Setup GPIO8, 9 & 4 */
.equ SCU_SCR0_Val , 0x00000196 /* Disable Prefetch Queue and Branch cache, SRAM = 96kb */
.equ SCU_SYSSTAT_LOCK , 0x01 /* Check for PLL locked */
# APB Bridge 1 & 2 definitions (Peripherals)
.equ APB0_BUF_BASE , 0x48001802 /* APB Bridge 0 Buffered Base Address */
.equ APB0_NBUF_BASE , 0x58000000 /* APB Bridge 0 Non-buffered Base Address */
.equ APB1_BUF_BASE , 0x4C000000 /* APB Bridge 1 Buffered Base Address */
.equ APB1_NBUF_BASE , 0x5C000000 /* APB Bridge 1 Non-buffered Base Address */
# ETM Definitions
.equ IOPORT2_ETM_ENABLE_BASE , 0x5C00204C
.equ IOPORT6_ETM_ENABLE_BASE , 0x5C00205C
.equ IOPORT2_ETM_ENABLE_VAL , 0x0000FFFF
.equ IOPORT6_ETM_ENABLE_VAL , 0x0000FFFF
#*************************************************************************
# Stack definitions
#*************************************************************************
.equ UND_Stack_Size, 8
.equ SVC_Stack_Size, 256
.equ ABT_Stack_Size, 8
.equ FIQ_Stack_Size, 32
.equ IRQ_Stack_Size, 512
.equ USR_Stack_Size, 512
.equ Top_Stack, RAM_Base + RAM_Size
# NOTE: Startup Code must be linked first at Address at which it expects to run.
#*************************************************************************
# STARTUP EXECUTABLE CODE
#*************************************************************************
.text
.arm
.extern main
.global _startup
_startup:
#*************************************************************************
# Exception Vectors
#*************************************************************************
Vectors:
LDR PC, Reset_Addr /* 0x0000 */
LDR PC, Undef_Addr /* 0x0004 */
LDR PC, SWI_Addr /* 0x0008 */
LDR PC, PAbt_Addr /* 0x000C */
LDR PC, DAbt_Addr /* 0x0010 */
NOP /* 0x0014 Reserved Vector */
LDR PC, [PC, #-0xFF0] /* 0x0018 wraps around address space to 0xFFFFFF030. Vector from VicVECAddr */
LDR PC, FIQ_Addr /* 0x001C FIQ has no VIC vector slot! */
#*************************************************************************
# Interrupt Vectors
#*************************************************************************
Reset_Addr: .word Hard_Reset /* CPU reset vector and entry point */
Undef_Addr: .word Undefined_Handler
SWI_Addr: .word SWI_Handler
PAbt_Addr: .word PAbt_Handler
DAbt_Addr: .word DAbt_Handler
.word 0 /* Reserved Address */
IRQ_Addr: .word IRQ_Handler /* Does not get used due to "LDR PC, [PC, #-0xFF0]" above */
FIQ_Addr: .word FIQ_Handler
# Dummy Interrupt Vector Table (real service routines in INTERRUPT.C)
Undefined_Handler: B Undefined_Handler
SWI_Handler: B SWI_Handler
PAbt_Handler: B PAbt_Handler
DAbt_Handler: B DAbt_Handler
IRQ_Handler: B IRQ_Handler /* should never get here as IRQ is via VIC slot... */
FIQ_Handler: B FIQ_Handler
#*************************************************************************
# Reset Handler Entry Point
#*************************************************************************
Hard_Reset:
StartupDelay 500000
#*************************************************************************
# Setup SRAM Size
.IF SRAM_SETUP == 1
LDR R0, =SCU_BASE
LDR R1, =SCU_SCR0_Val
STR R1, [R0, #SCU_SCR0_OFS]
.ENDIF
#*************************************************************************
# Setup Flash Memory Interface (FMI)
.IF FMI_SETUP == 1
LDR R0, =FMI_BASE
LDR R1, =FMI_BBSR_Val
STR R1, [R0, #FMI_BBSR_OFS]
LDR R1, =FMI_NBBSR_Val
STR R1, [R0, #FMI_NBBSR_OFS]
LDR R1, =(FMI_BBADR_Val >> 2)
STR R1, [R0, #FMI_BBADR_OFS]
LDR R1, =(FMI_NBBADR_Val >> 2)
STR R1, [R0, #FMI_NBBADR_OFS]
LDR R2, =FMI_CR_Val
STR R2, [R0, #FMI_CR_OFS]
LDR R2, =FMI_SR_Val
STR R2, [R0, #FMI_SR_OFS]
# Write "Write flash configuration" command (60h)
MOV R0, R1, LSL #2
MOV R1, #0x60
STRH R1, [R0, #0]
# Write "Write flash configuration confirm" command (03h)
LDR R2, =(FLASH_CFG_Val >> 2)
ADD R0, R0, R2
MOV R1, #0x03
STRH R1, [R0, #0]
.ENDIF
#*************************************************************************
# Setup Clock PLL
.IF CLOCK_SETUP == 1
LDR R0, =SCU_BASE
LDR R1, =0x00020002
STR R1, [R0, #SCU_CLKCNTR_OFS] /* Select OSC as clock src */
NOP /* Wait for oscillator stabilisation */
NOP /* Must be more than 10 oscillator periods */
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
LDR R1, =0x0003C019 /* Disable PLL */
STR R1, [R0, #SCU_PLLCONF_OFS]
LDR R1, =SCU_PLLCONF_Val
STR R1, [R0, #SCU_PLLCONF_OFS] /* Set new PLL values */
.IF (SCU_PLLCONF_Val & 0x8000) /* See if PLL is being used */
LDR R1, =SCU_SYSSTAT_LOCK
PLL_LOCK_LOOP:
LDR R2,[R0, #SCU_SYSTAT_OFS] /* Wait for PLL lock */
ANDS R2, R2, R1
BEQ PLL_LOCK_LOOP
.ENDIF
LDR R1, =SCU_PLLCONF_Val
STR R1, [R0, #SCU_PLLCONF_OFS]
LDR R1, =SCU_CLKCNTR_Val
STR R1, [R0, #SCU_CLKCNTR_OFS]
LDR R1, =SCU_PCGR0_Val /* Enable clock gating */
STR R1, [R0, #SCU_PCGR0_OFS]
LDR R1, =SCU_PCGR1_Val
STR R1, [R0, #SCU_PCGR1_OFS]
.ENDIF
#*************************************************************************
# Embedded Trace Module Setup
#*************************************************************************
.IF ETM_SETUP == 1
# Configure IOPORT2 for ETM operation
LDR R0, =IOPORT2_ETM_ENABLE_BASE
LDR R1, =IOPORT2_ETM_ENABLE_VAL
STR R1, [R0, #0]
# Configure IOPORT6 for ETM operation
LDR R0, =IOPORT6_ETM_ENABLE_BASE
LDR R1, =IOPORT6_ETM_ENABLE_VAL
STR R1, [R0, #0]
.ENDIF
#*************************************************************************
# Compiler Runtime Environment Setup
#*************************************************************************
# Note: R13 = SP
# Setup Stack for each mode
LDR R0, =Top_Stack
# Set up Fast Interrupt Mode and set FIQ Mode Stack
MSR CPSR_c, #Mode_FIQ|I_BIT|F_BIT
mov r13, r0
sub r0, r0, #FIQ_Stack_Size
# Set up Interrupt Mode and set IRQ Mode Stack
msr CPSR_c, #Mode_IRQ|I_BIT|F_BIT
mov r13, r0
sub r0, r0, #IRQ_Stack_Size
# Set up Abort Mode and set Abort Mode Stack
msr CPSR_c, #Mode_ABT|I_BIT|F_BIT
mov r13, r0
sub r0, r0, #ABT_Stack_Size
# Set up Undefined Instruction Mode and set Undef Mode Stack
msr CPSR_c, #Mode_UND|I_BIT|F_BIT
mov r13, r0
sub r0, r0, #UND_Stack_Size
# Set up Supervisor Mode and set Supervisor Mode Stack
msr CPSR_c, #Mode_SVC|I_BIT|F_BIT
mov r13, r0
sub r0, r0, #SVC_Stack_Size
# Set up User Mode and set User Mode Stack
msr CPSR_c, #Mode_USR /* Leave interrupts enabled in user mode */
mov r13, r0 /* Note: interrupts will not happen until VIC is enabled */
# Setup a default Stack Limit (when compiled with "-mapcs-stack-check")
SUB SL, SP, #1<<10 /* 1kB */
# Initialise current CPU status to prevent unwanted interrupts
# msr CPSR_c,#0xD3
#*************************************************************************
# Initialise RAM For Compiler Variables
#*************************************************************************
copy_section2 data, _etext, __data_start__, _edata
#*************************************************************************
# Clear .bss section
#*************************************************************************
clear_section bss, __bss_start__, __bss_end__
clear_section bss2, __bss2_start__, __bss2_end__
#*************************************************************************
# Enter the C code
#*************************************************************************
# Jump to main()
B main
.size _startup, . - _startup
#*************************************************************************
# END
#*************************************************************************
.end
|