summaryrefslogtreecommitdiffstats
path: root/target/linux/at91/image/dfboot/src/cstartup_ram.S
blob: 223900098d9e9d9e2ec37ebc7b7d7a5cb96d8e71 (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
#include "AT91RM9200_inc.h"
		
/*---------------------------
ARM Core Mode and Status Bits
---------------------------*/
.section start
	.text
			
#define ARM_MODE_USER   0x10
#define ARM_MODE_FIQ    0x11
#define ARM_MODE_IRQ    0x12
#define ARM_MODE_SVC    0x13
#define ARM_MODE_ABORT  0x17
#define ARM_MODE_UNDEF  0x1B
#define ARM_MODE_SYS    0x1F

#define I_BIT           0x80
#define F_BIT           0x40
#define T_BIT           0x20

/*----------------------------------------------------------------------------
 Area Definition
----------------
 Must be defined as function to put first in the code as it must be mapped
 at offset 0 of the flash EBI_CSR0, ie. at address 0 before remap.
_---------------------------------------------------------------------------*/

  .align  4
	.globl _start
_start:

/*----------------------------------------------------------------------------
 Exception vectors ( before Remap )
------------------------------------
 These vectors are read at address 0.
 They absolutely requires to be in relative addresssing mode in order to
 guarantee a valid jump. For the moment, all are just looping (what may be
 dangerous in a final system). If an exception occurs before remap, this
 would result in an infinite loop.
----------------------------------------------------------------------------*/
                b           reset			       	/* reset */
                b           undefvec        	/* Undefined Instruction */
                b           swivec          	/* Software Interrupt */
                b           pabtvec         	/* Prefetch Abort */
                b           dabtvec         	/* Data Abort */
                b           rsvdvec         	/* reserved */
                b           aicvec				    /* IRQ : read the AIC */
                b           fiqvec          	/* FIQ */

undefvec:
swivec:
pabtvec:
dabtvec:
rsvdvec:
aicvec:
fiqvec:
	b	undefvec

reset:

#define MEMEND 0x00004000

/* ----------------------------
 Setup the stack for each mode
---------------------------- */

#define IRQ_STACK_SIZE  0x10
#define FIQ_STACK_SIZE  0x04
#define ABT_STACK_SIZE  0x04
#define UND_STACK_SIZE  0x04
#define SVC_STACK_SIZE  0x10
#define USER_STACK_SIZE 0x400
	
                ldr     r0,= MEMEND

/*- Set up Supervisor Mode and set Supervisor Mode Stack*/
                msr     CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT
                mov     r13, r0                     /* Init stack Undef*/
                sub     r0, r0, #SVC_STACK_SIZE

/*- 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

/*- Set up Fast Interrupt Mode and set FIQ Mode Stack*/
                msr     CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT
                mov     r13, r0                     /* Init stack FIQ*/
                sub     r0, r0, #FIQ_STACK_SIZE

/*- Set up Abort Mode and set Abort Mode Stack*/
                msr     CPSR_c, #ARM_MODE_ABORT | I_BIT | F_BIT
                mov     r13, r0                     /* Init stack Abort*/
                sub     r0, r0, #ABT_STACK_SIZE

/*- Set up Undefined Instruction Mode and set Undef Mode Stack*/
                msr     CPSR_c, #ARM_MODE_UNDEF | I_BIT | F_BIT
                mov     r13, r0                     /* Init stack Undef*/
                sub     r0, r0, #UND_STACK_SIZE

/*- Set up user Mode and set System Mode Stack*/
                msr     CPSR_c, #ARM_MODE_SYS | I_BIT | F_BIT
                bic     r0, r0, #3                  /* Insure word alignement */
               	mov     sp, r0                      /* Init stack System */


		ldr       r0, = AT91F_LowLevelInit
		mov       lr, pc
		bx        r0

/*----------------------------------------
 Read/modify/write CP15 control register
----------------------------------------*/
		mrc     p15, 0, r0, c1, c0,0  /* read cp15 control registre (cp15 r1) in r0 */
		ldr     r3,= 0xC0000080      /* Reset bit :Little Endian end fast bus mode */
		ldr     r4,= 0xC0001000      /* Set bit :Asynchronous clock mode, Not Fast Bus, I-Cache enable */
		bic     r0, r0, r3
		orr     r0, r0, r4
		mcr     p15, 0, r0, c1, c0,0 /* write r0 in cp15 control registre (cp15 r1) */

/* Enable interrupts */
		msr     CPSR_c, #ARM_MODE_SYS | F_BIT

/*------------------------------------------------------------------------------
- Branch on C code Main function (with interworking)
----------------------------------------------------
- Branch must be performed by an interworking call as either an ARM or Thumb
- _start function must be supported. This makes the code not position-
- independent. A Branch with link would generate errors
----------------------------------------------------------------------------*/
	
/*- Branch to _start by interworking*/
		ldr     r4, = main
	        mov     lr, pc
	        bx      r4
	
/*-----------------------------------------------------------------------------
- Loop for ever
---------------
- End of application. Normally, never occur.
- Could jump on Software Reset ( B 0x0 ).
------------------------------------------------------------------------------*/
End:
	        b       End