summaryrefslogtreecommitdiffstats
path: root/Bachelor/Mikroprozessorsysteme2/ARM202U/EXAMPLES/ROM/INIT.S
blob: 3786ac779829a9fdeac6532f734839a102ffeef9 (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
;
; The AREA must have the attribute READONLY, otherwise the linker will not
; place it in ROM.
;
; The AREA must have the attribute CODE, otherwise the assembler will not
; let us put any code in this AREA
;
; Note the '|' character is used to surround any symbols which contain
; non standard characters like '!'.

		AREA	Init, CODE, READONLY

; Now some standard definitions...

Mode_IRQ	EQU	0x12
Mode_SVC	EQU	0x13

I_Bit		EQU	0x80
F_Bit		EQU	0x40

SWI_Exit	EQU	0x11

; Locations of various things in our memory system

RAM_Base	EQU	0x10000000	; 64k RAM at this base
RAM_Limit	EQU	0x10010000

IRQ_Stack	EQU	RAM_Limit	; 1K IRQ stack at top of memory
SVC_Stack	EQU	RAM_Limit-1024	; followed by SVC stack

; --- Define __main & set entry point
	ENTRY

; --- Setup interrupt / exception vectors
    IF :DEF: ROM_AT_ADDRESS_ZERO
; If the ROM is at address 0 this is just a sequence of branches
	B	Reset_Handler
	B	Undefined_Handler
	B	SWI_Handler
	B	Prefetch_Handler
	B	Abort_Handler
	NOP		; Reserved vector
	B	IRQ_Handler
	B	FIQ_Handler
    ELSE
; Otherwise we copy a sequence of LDR PC instructions over the vectors
; (Note: We copy LDR PC instructions because branch instructions
; could not simply be copied, the offset in the branch instruction
; would have to be modified so that it branched into ROM. Also, a
; branch instructions might not reach if the ROM is at an address
; > 32M).
	MOV	R8, #0
	ADR	R9, Vector_Init_Block
	LDMIA	R9!, {R0-R7}
	STMIA	R8!, {R0-R7}
	LDMIA	R9!, {R0-R7}
	STMIA	R8!, {R0-R7}

; Now fall into the LDR PC, Reset_Addr instruction which will continue
; execution at 'Reset_Handler'

Vector_Init_Block
	LDR	PC, Reset_Addr
	LDR	PC, Undefined_Addr
	LDR	PC, SWI_Addr
	LDR	PC, Prefetch_Addr
	LDR	PC, Abort_Addr
	NOP
	LDR	PC, IRQ_Addr
	LDR	PC, FIQ_Addr

Reset_Addr	DCD	Reset_Handler
Undefined_Addr	DCD	Undefined_Handler
SWI_Addr	DCD	SWI_Handler
Prefetch_Addr	DCD	Prefetch_Handler
Abort_Addr	DCD	Abort_Handler
		DCD	0	; Reserved vector
IRQ_Addr	DCD	IRQ_Handler
FIQ_Addr	DCD	FIQ_Handler
    ENDIF

; The following handlers do not do anything useful in this example.
;
Undefined_Handler
	B	Undefined_Handler
SWI_Handler
	B	SWI_Handler
Prefetch_Handler
	B	Prefetch_Handler
Abort_Handler
	B	Abort_Handler
IRQ_Handler
	B	IRQ_Handler
FIQ_Handler
	B	FIQ_Handler

; The RESET entry point
Reset_Handler

; --- Initialise stack pointer registers
; Enter IRQ mode and set up the IRQ stack pointer
	MOV	R0, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; No interrupts
	MSR	CPSR, R0
	LDR	R13, =IRQ_Stack

; Set up other stack pointers if necessary
	; ...

; Set up the SVC stack pointer last and return to SVC mode
	MOV	R0, #Mode_SVC:OR:I_Bit:OR:F_Bit ; No interrupts
	MSR	CPSR, R0
	LDR	R13, =SVC_Stack

; --- Initialise memory system
	; ...

; --- Initialise critical IO devices
	; ...

; --- Initialise interrupt system variables here
	; ...

; --- Enable interrupts
; Now safe to enable interrupts, so do this and remain in SVC mode
	MOV	R0, #Mode_SVC:OR:F_Bit	; Only IRQ enabled
	MSR	CPSR, R0

; --- Initialise memory required by C code

	IMPORT	|Image$$RO$$Limit|	; End of ROM code (=start of ROM data)
	IMPORT	|Image$$RW$$Base|	; Base of RAM to initialise
	IMPORT	|Image$$ZI$$Base|	; Base and limit of area
	IMPORT	|Image$$ZI$$Limit|	; to zero initialise

	LDR     r0, =|Image$$RO$$Limit| ; Get pointer to ROM data
	LDR     r1, =|Image$$RW$$Base|  ; and RAM copy
	LDR     r3, =|Image$$ZI$$Base|  ; Zero init base => top of initialised data
	CMP     r0, r1                  ; Check that they are different
	BEQ     %1
0	CMP     r1, r3                  ; Copy init data
	LDRCC   r2, [r0], #4
	STRCC   r2, [r1], #4
	BCC     %0
1	LDR     r1, =|Image$$ZI$$Limit| ; Top of zero init segment
	MOV     r2, #0
2	CMP     r3, r1                  ; Zero init
	STRCC   r2, [r3], #4
	BCC     %2

; --- Now we enter the C code

	IMPORT	C_Entry
    [ :DEF:THUMB
	ORR	lr, pc, #1
	BX	lr
	CODE16				; Next instruction will be Thumb
    ]
	BL	C_Entry
; In a real application we wouldn't normally expect to return, however
; this example does so the debug monitor swi SWI_Exit is used to halt the
; application.
	SWI	SWI_Exit

	END