summaryrefslogtreecommitdiffstats
path: root/crt.s
blob: 27636b6dfee947729bd537cbf186c56fb47447f0 (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
/*
    crt.s - startup code
    Copyright (C) 2007  Ch. Klippel <ck@mamalala.net>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
.global main

.global _etext
.global _data
.global _edata
.global __bss_start
.global __bss_end__
.global _stack

/* Stack Sizes */
.set  UND_STACK_SIZE,	0x00000004	/* stack for "undefined instruction" interrupts is 4 bytes  	*/
.set  ABT_STACK_SIZE,	0x00000004	/* stack for "abort" interrupts is 4 bytes                  	*/
.set  FIQ_STACK_SIZE,	0x00000104	/* stack for "FIQ" interrupts  is 4 bytes         		*/
.set  IRQ_STACK_SIZE,	0X000003F0	/* stack for "IRQ" normal interrupts is 4 bytes    		*/
.set  SVC_STACK_SIZE,	0x00000004	/* stack for "SVC" supervisor mode is 4 bytes  			*/

/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs */
.set  MODE_USR,		0x10		/* Normal User Mode 						*/
.set  MODE_FIQ,		0x11		/* FIQ Processing Fast Interrupts Mode 				*/
.set  MODE_IRQ,		0x12		/* IRQ Processing Standard Interrupts Mode 			*/
.set  MODE_SVC,		0x13		/* Supervisor Processing Software Interrupts Mode 		*/
.set  MODE_ABT,		0x17		/* Abort Processing memory Faults Mode 				*/
.set  MODE_UND,		0x1B		/* Undefined Processing Undefined Instructions Mode 		*/
.set  MODE_SYS,		0x1F		/* System Running Priviledged Operating System Tasks  Mode	*/
.set  I_BIT,		0x80		/* when I bit is set, IRQ is disabled (program status registers) */
.set  F_BIT,		0x40		/* when F bit is set, FIQ is disabled (program status registers) */


.text
.arm

.global	Reset_Handler
.global _startup

.section .text.fastcode

.global ramvectors
.func   ramvectors
ramvectors:
	ldr	PC, Ram_Reset_Addr
	ldr	PC, Ram_Undef_Addr
	ldr	PC, Ram_SWI_Addr
	ldr	PC, Ram_PAbt_Addr
	ldr	PC, Ram_DAbt_Addr
	nop				/* Reserved Vector (holds Philips ISP checksum) */
	ldr	PC, do_vic_addr		/* Route IRQ to VIC */
	ldr	PC, Ram_FIQ_Addr

Ram_Reset_Addr:	.word   Reset_Handler	/* defined in this module below  */
Ram_Undef_Addr:	.word   UNDEF_Routine	/* defined in main.c  */
Ram_SWI_Addr:	.word   SWI_Routine	/* defined in main.c  */
Ram_PAbt_Addr:	.word   UNDEF_Routine	/* defined in main.c  */
Ram_DAbt_Addr:	.word   UNDEF_Routine	/* defined in main.c  */
do_vic_addr:	.word   do_vic	
Ram_FIQ_Addr:	.word   do_fiq	/* defined in main.c  */
		.word   0		/* rounds vectors to 64 bytes total  */
.endfunc

.global do_vic
.func do_vic
do_vic:

	stmfd	sp!, { r0-r5, r12, lr }	/* save work regs & spsr on stack */
	ldr	r4, =VICVectAddr	/* get the ISR address from VIC */
	ldr	r5, [r4]
	mov	lr, pc			/* set return to common exit of ISR */
	bx	r5			/* go handle the interrupt */
/*	mov	pc, r5			/* go handle the interrupt */
	str	lr, [r4]		/* update VICVectAddr */
	ldmfd	sp!, { r0-r5, r12, lr }	/* restore work regs and spsr_irq */
	subs	pc, lr, #0x4		/* return, restoring CPSR from SPSR */
/*
stmfd sp!, { lr }
mrs lr, spsr
stmfd sp!, { r4-r5, lr }

ldr r4, =VICVectAddr
ldr r5, [r4]

msr cpsr_c, #0x13

stmfd sp!, { r0-r3, r12, lr }
mov lr, pc
bx r5
ldmfd sp!, { r0-r3, r12, lr }

msr cpsr_c, #0x92

str lr, [r4]

ldmfd sp!, { r4-r5, lr }
msr spsr_cxsf, lr
ldmfd sp!, { lr }

subs pc, lr, #0x4
*/

.endfunc

.global do_fiq
.func do_fiq
do_fiq:

	stmfd	sp!, { r0-r7, lr }
	ldr	r8, =FIQ_Routine
	mov	lr, pc
	bx	r8
	ldmfd	sp!, { r0-r7, lr }
	subs	pc, lr, #0x4
.endfunc	


.section .text

.func   _startup
_startup:

# Exception Vectors

_vectors:
		ldr	PC, Reset_Addr

Reset_Addr:     .word   Reset_Handler

# Reset Handler

Reset_Handler:  

/* Setup a stack for each mode - note that this only sets up a usable stack
   for User mode.   Also each mode is setup with interrupts initially disabled. */
	
	ldr	r0, =_stack_end
	msr	CPSR_c, #MODE_UND|I_BIT|F_BIT 	/* Undefined Instruction Mode  */
	mov	sp, r0

	sub	r0, r0, #UND_STACK_SIZE
	msr	CPSR_c, #MODE_ABT|I_BIT|F_BIT 	/* Abort Mode */
	mov	sp, r0

	sub	r0, r0, #ABT_STACK_SIZE
	msr	CPSR_c, #MODE_FIQ|I_BIT|F_BIT 	/* FIQ Mode */
	mov	sp, r0	

	sub	r0, r0, #FIQ_STACK_SIZE
	msr	CPSR_c, #MODE_IRQ|I_BIT|F_BIT 	/* IRQ Mode */
	mov	sp, r0

	sub	r0, r0, #IRQ_STACK_SIZE
	msr	CPSR_c, #MODE_SVC|I_BIT|F_BIT 	/* Supervisor Mode */
	mov	sp, r0

	sub	r0, r0, #SVC_STACK_SIZE
	msr	CPSR_c, #MODE_SYS|I_BIT|F_BIT 	/* User Mode */
	mov	sp, r0

/* Setup Pins and Memory */
	ldr	r0,=BCFG0
				/*            W B                R              */
				/*            P S                B              */
				/*        B W E E                L              */
				/*  AT|MW|M|P|R|R|reserved|WST2 |E|WST1 |r|IDCY */
				/*  --+--+-+-+-+-+--------+-----+-------+-+---- */
				/*  3 | 2| | | |2|   2   1|   1 | | 0   |0| 0   */
				/*  1 | 8| | | |4|   0   6|   2 | | 8   |4| 0   */
				/*  --+--+-+-+-+-+--------+-----+-------+-+---- */
/*	ldr	r1, =0x10000400 /*  00|01|0|0|0|0|00000000|00000|1|00000|0|0000 16bit, rble, 3wst - 10 mhz*/
/*	ldr	r1, =0x10000420 /*  00|01|0|0|0|0|00000000|00000|1|00001|0|0000 16bit, rble, 4wst - 30 mhz*/
	ldr	r1, =0x100004A0 /*  00|01|0|0|0|0|00000000|00000|1|00101|0|0000 16bit, rble, 6wst - 60 mhz*/

	str	r1,[r0]		/* set bcfg0 (flash) */
	str	r1,[r0,#0x08]	/* set bcfg2 (flash) */

	ldr	r0, =BCFG1
/*	ldr	r1, =0x00000422 /*  00|00|0|0|0|0|00000000|00000|1|00001|0|0010  8 bit, 3 sram wst, rble, 5 wst 3 idcy*/
	ldr	r1, =0x00000C42 /*  00|00|0|0|0|0|00000000|00001|1|00010|0|0010  8 bit, 3 sram wst, rble, 5 wst 3 idcy*/
	str	r1, [r0]	/* set bcfg1 (lcd) */

	ldr	r0, =PINSEL0
	ldr	r1, =0x00008005
	str	r1, [r0]

	ldr	r0, =PINSEL1
	ldr	r1, =0x00000000  /* gpio 0.30 */
	str	r1, [r0]

	ldr	r0, =PINSEL2
	ldr	r1, =0x0de049d4
	str	r1, [r0]

	ldr	r0, = IO2SET
	ldr	r1, =0x1FC0000
	str	r1, [r0]
	str	r1, [r0,#0x04]

	ldr	r0, = IO0DIR
	ldr	r1, =0x002018D0
	str	r1, [r0]

/* Setup PLL */
	ldr	r0, =0xe01fc000
	ldr	r2, =0xaa
	ldr	r3, =0x55
	ldr	r1, =0x03
	str	r1, [r0,#0x80]		/* set pllcon to 0x03 = pll enable (0x01) + pll connect (0x02) */
	ldr	r1, =0x0
	str	r1, [r0,#0x100]		/* set vbpdiv to 0x00 = 1/4th; 0x01 = 1/1, 0x02 = 1/2*/
/*	ldr	r1, =0x42 */
	ldr	r1, =0x45
	str	r1,[r0,#0x84]		/* set pllcfg to 0x42 = psel = 10 (4) = msel= 00010 (3) = 240 mhz Fcco*/
	str	r2, [r0,#0x8c]
	str	r3, [r0,#0x8c]

/* Copy .fastcode & .data section (Copy from ROM to RAM) */
	ldr	R0, =__fastcode_load	/*_etext*/
	ldr	r3, entry_mask		/* this and the next instruction are an workaround  */
	and	r0, r0, r3		/* for some ugly bug in winarm to force msb to 0x80 */
	ldr	R1, =__fastcode_start	/*_data*/
	ldr	R2, =_edata
1:
	cmp	r1,r2
	ldmltia	r0!,{r3}
	stmltia	r1!,{r3}
	blt	1b

/* Clear .bss section (Zero init)  */
	mov	R0, #0
	ldr	R1, =_bss_start
	ldr	R2, =_bss_end
2:
	cmp	R1, R2
	strlo	R0, [R1], #4
	blo	2b

	ldr	r0, =MEMMAP
	ldr	r1, =0x02		/* irq vectors in ram */
	str	r1, [r0]

	mov	r0,#0
	mov	r1,r0
	mov	r2,r0
	mov	fp,r0
	mov	r7,r0
	ldr	r10,=main
	mov	lr,pc
	bx	r10

.endfunc

entry_mask:     .word   0x8FFFFFFF	/* defined in this module below  */

.end