summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/mpc55xxevb/startup/start.S
blob: f05e2c7f1cfa748489b35373805c534506ab00ab (plain) (blame)
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
/**
 * @file
 *
 * @ingroup mpc55xx_asm
 *
 * @brief Boot and system start code.
 */

/*
 * Copyright (c) 2008-2011 embedded brains GmbH.  All rights reserved.
 *
 *  embedded brains GmbH
 *  Obere Lagerstr. 30
 *  82178 Puchheim
 *  Germany
 *  <rtems@embedded-brains.de>
 *
 * The license and distribution terms for this file may be
 * found in the file LICENSE in this distribution or at
 * http://www.rtems.com/license/LICENSE.
 */

#include <bspopts.h>

#include <libcpu/powerpc-utility.h>

#if MPC55XX_CHIP_TYPE / 10 != 551
  #define HAS_SPE
#endif

#if MPC55XX_CHIP_TYPE / 10 == 564
  #define INIT_REGISTERS_FOR_LSM
#endif

#ifdef HAS_SPE
  #define ZERO_GPR(reg) evxor	reg, reg, reg
#else
  #define ZERO_GPR(reg) xor	reg, reg, reg
#endif

	.extern	__eabi
	.extern	boot_card
	.extern	bsp_ram_start
	.extern	bsp_section_data_begin
	.extern	bsp_section_data_load_begin
	.extern	bsp_section_data_size
	.extern	bsp_section_fast_data_begin
	.extern	bsp_section_fast_data_load_begin
	.extern	bsp_section_fast_data_size
	.extern	bsp_section_fast_text_begin
	.extern	bsp_section_fast_text_load_begin
	.extern	bsp_section_fast_text_size
	.extern	mpc55xx_start_config_mmu_early
	.extern	mpc55xx_start_config_mmu_early_count
	.extern	mpc55xx_start_early

	.globl	_start
	.globl	mpc55xx_start_mmu_apply_config

#ifdef MPC55XX_BOOTFLAGS
	.globl	mpc55xx_bootflag_0
	.globl	mpc55xx_bootflag_1
#endif

	.section	".bsp_start_text", "ax"

	/* BAM: RCHW */
	.int	0x005a0000

	/* BAM: Address of start instruction */
	.int	_start

#ifdef MPC55XX_BOOTFLAGS
	/*
	 * We skip over the next two boot flag words to the next 64-bit
	 * aligned start address. It is 64-bit aligned to play well with
	 * FLASH programming.  These boot flags can be set by debuggers
	 * and emulators to customize boot.  Currently bit0 of
	 * bootflag_0 means to "skip setting up the MMU", allowing
	 * external MMU setup in a debugger before branching to 0x10.
	 * This can be used e.g., to map FLASH into RAM.
	 */
mpc55xx_bootflag_0:
	.int	0xffffffff
mpc55xx_bootflag_1:
	.int	0xffffffff
#endif

_start:

	/* Enable SPE */
#ifdef HAS_SPE
	mfmsr	r3
	oris	r3, r3, MSR_SPE >> 16
	mtmsr	r3
	isync
#endif

	/*
	 * Initialization of core registers according to "e200z4 Power
	 * Architecture Core Reference Manual" section 2.6 "Reset Settings"
	 * table 2-16 "Reset Settings of e200 Resources".  This is necessary
	 * for lock step mode (LSM).
	 */
	ZERO_GPR(r0)
#ifdef INIT_REGISTERS_FOR_LSM
	ZERO_GPR(r1)
	ZERO_GPR(r2)
	ZERO_GPR(r4)
	ZERO_GPR(r5)
	ZERO_GPR(r6)
	ZERO_GPR(r7)
	ZERO_GPR(r8)
	ZERO_GPR(r9)
	ZERO_GPR(r10)
	ZERO_GPR(r11)
	ZERO_GPR(r12)
	ZERO_GPR(r13)
	ZERO_GPR(r14)
	ZERO_GPR(r15)
	ZERO_GPR(r16)
	ZERO_GPR(r17)
	ZERO_GPR(r18)
	ZERO_GPR(r19)
	ZERO_GPR(r20)
	ZERO_GPR(r21)
	ZERO_GPR(r22)
	ZERO_GPR(r23)
	ZERO_GPR(r24)
	ZERO_GPR(r25)
	ZERO_GPR(r26)
	ZERO_GPR(r27)
	ZERO_GPR(r28)
	ZERO_GPR(r29)
	ZERO_GPR(r30)
	ZERO_GPR(r31)
	mtcrf	0xff, r0
	mtcsrr0	r0
	mtcsrr1	r0
	mtctr	r0
	mtspr	FSL_EIS_DBCNT, r0
	mtspr	DEAR_BOOKE, r0
	mtdec	r0
	mtspr	BOOKE_DECAR, r0
	mtspr	FSL_EIS_DSRR0, r0
	mtspr	FSL_EIS_DSRR1, r0
	mtspr	BOOKE_DVC1, r0
	mtspr	BOOKE_DVC2, r0
	mtspr	BOOKE_IVPR, r0
	mtlr	r0
	mtspr	FSL_EIS_MCAR, r0
	mtmcsrr0	r0
	mtmcsrr1	r0
	mtspr	SPRG0, r0
	mtspr	SPRG1, r0
	mtspr	SPRG2, r0
	mtspr	SPRG3, r0
	mtspr	SPRG4, r0
	mtspr	SPRG5, r0
	mtspr	SPRG6, r0
	mtspr	SPRG7, r0
	mtspr	FSL_EIS_SPRG8, r0
	mtspr	FSL_EIS_SPRG9, r0
	mtsrr0	r0
	mtsrr1	r0
	mtspr	USPRG0, r0
#ifdef HAS_SPE
	evmra	r0, r0
#endif
#endif /* INIT_REGISTERS_FOR_LSM */
	mtspr	TBWL, r0
	mtspr	TBWU, r0

	/* Enable time base */
	mfspr	r3, HID0
	ori	r3, r3, 0x4000
	mtspr	HID0, r3

	/* Enable branch prediction */
	LWI	r3, FSL_EIS_BUCSR_BBFI | FSL_EIS_BUCSR_BPEN
	mtspr	FSL_EIS_BUCSR, r3

	/* MMU early initialization */
	LA	r3, mpc55xx_start_config_mmu_early
	LW	r4, mpc55xx_start_config_mmu_early_count
	bl	mpc55xx_start_mmu_apply_config

	/* Initialize intermediate stack (ECC) */

	LA	r3, bsp_ram_start
	addi	r4, r3, MPC55XX_EARLY_STACK_SIZE

zero_intermediate_stack_loop:

#ifdef HAS_SPE
	evstdd	r0, 0(r3)
	evstdd	r0, 8(r3)
	evstdd	r0, 16(r3)
	evstdd	r0, 24(r3)
#else
	stw	r0, 0(r3)
	stw	r0, 4(r3)
	stw	r0, 8(r3)
	stw	r0, 12(r3)
	stw	r0, 16(r3)
	stw	r0, 20(r3)
	stw	r0, 24(r3)
	stw	r0, 28(r3)
#endif
	addi	r3, r3, 32
	cmpw	cr7, r3, r4
	bne	cr7, zero_intermediate_stack_loop
	subi	r1, r3, 16

	/* Next steps in C */
	bl	mpc55xx_start_early

	/* Initialize start stack */
	LA	r1, start_stack_end
	subi	r1, r1, 16
	li	r0, 0
	stw	r0, 0(r1)

	/* Load sections */
	LA	r3, bsp_section_fast_text_begin
	LA	r4, bsp_section_fast_text_load_begin
	LA	r5, bsp_section_fast_text_size
	bl	load_section
	LA	r3, bsp_section_fast_data_begin
	LA	r4, bsp_section_fast_data_load_begin
	LA	r5, bsp_section_fast_data_size
	bl	load_section
	LA	r3, bsp_section_data_begin
	LA	r4, bsp_section_data_load_begin
	LA	r5, bsp_section_data_size
	bl	load_section

	/* Set up EABI and SYSV environment */
	bl	__eabi

	/* Clear command line */
	li	r3, 0

	/* Start RTEMS */
	bl	boot_card

	/* Spin around */
twiddle:

	b	twiddle

mpc55xx_start_mmu_apply_config:

	cmpwi	cr7, r4, r0
	beqlr	cr7
	mtctr	r4

mmu_init_loop:

	lwz	r4, 0(r3)
	lwz	r5, 4(r3)
	lwz	r6, 8(r3)
	lwz	r7, 12(r3)
	mtspr	FSL_EIS_MAS0, r4
	mtspr	FSL_EIS_MAS1, r5
	mtspr	FSL_EIS_MAS2, r6
	mtspr	FSL_EIS_MAS3, r7
	tlbwe
	addi	r3, r3, 16
	bdnz	mmu_init_loop
	blr

load_section:
	cmpw	cr7, r3, r4
	beqlr	cr7
	b	memcpy

	/* Start stack area */

	.section	".bsp_rwextra", "aw", @nobits
	.align	4
	.space	4096

start_stack_end: