xref: /openbmc/u-boot/arch/mips/cpu/start.S (revision 78a88f79)
1/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 *  Startup Code for MIPS32 CPU-core
4 *
5 *  Copyright (c) 2003	Wolfgang Denk <wd@denx.de>
6 */
7
8#include <asm-offsets.h>
9#include <config.h>
10#include <asm/asm.h>
11#include <asm/regdef.h>
12#include <asm/mipsregs.h>
13
14#ifndef CONFIG_SYS_INIT_SP_ADDR
15#define CONFIG_SYS_INIT_SP_ADDR	(CONFIG_SYS_SDRAM_BASE + \
16				CONFIG_SYS_INIT_SP_OFFSET)
17#endif
18
19#ifdef CONFIG_32BIT
20# define MIPS_RELOC	3
21# define STATUS_SET	0
22#endif
23
24#ifdef CONFIG_64BIT
25# ifdef CONFIG_SYS_LITTLE_ENDIAN
26#  define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
27	(((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym))
28# else
29#  define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \
30	((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24)
31# endif
32# define MIPS_RELOC	MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03)
33# define STATUS_SET	ST0_KX
34#endif
35
36	.set noreorder
37
38	.macro init_wr sel
39	MTC0	zero, CP0_WATCHLO,\sel
40	mtc0	t1, CP0_WATCHHI,\sel
41	mfc0	t0, CP0_WATCHHI,\sel
42	bgez	t0, wr_done
43	 nop
44	.endm
45
46	.macro uhi_mips_exception
47	move	k0, t9		# preserve t9 in k0
48	move	k1, a0		# preserve a0 in k1
49	li	t9, 15		# UHI exception operation
50	li	a0, 0		# Use hard register context
51	sdbbp	1		# Invoke UHI operation
52	.endm
53
54	.macro setup_stack_gd
55	li	t0, -16
56	PTR_LI	t1, CONFIG_SYS_INIT_SP_ADDR
57	and	sp, t1, t0		# force 16 byte alignment
58	PTR_SUBU \
59		sp, sp, GD_SIZE		# reserve space for gd
60	and	sp, sp, t0		# force 16 byte alignment
61	move	k0, sp			# save gd pointer
62#if CONFIG_VAL(SYS_MALLOC_F_LEN)
63	li	t2, CONFIG_VAL(SYS_MALLOC_F_LEN)
64	PTR_SUBU \
65		sp, sp, t2		# reserve space for early malloc
66	and	sp, sp, t0		# force 16 byte alignment
67#endif
68	move	fp, sp
69
70	/* Clear gd */
71	move	t0, k0
721:
73	PTR_S	zero, 0(t0)
74	blt	t0, t1, 1b
75	 PTR_ADDIU t0, PTRSIZE
76
77#if CONFIG_VAL(SYS_MALLOC_F_LEN)
78	PTR_S	sp, GD_MALLOC_BASE(k0)	# gd->malloc_base offset
79#endif
80	.endm
81
82ENTRY(_start)
83	/* U-Boot entry point */
84	b	reset
85	 mtc0	zero, CP0_COUNT	# clear cp0 count for most accurate boot timing
86
87#if defined(CONFIG_SYS_XWAY_EBU_BOOTCFG)
88	/*
89	 * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to
90	 * access external NOR flashes. If the board boots from NOR flash the
91	 * internal BootROM does a blind read at address 0xB0000010 to read the
92	 * initial configuration for that EBU in order to access the flash
93	 * device with correct parameters. This config option is board-specific.
94	 */
95	.org 0x10
96	.word CONFIG_SYS_XWAY_EBU_BOOTCFG
97	.word 0x0
98#endif
99#if defined(CONFIG_MALTA)
100	/*
101	 * Linux expects the Board ID here.
102	 */
103	.org 0x10
104	.word 0x00000420	# 0x420 (Malta Board with CoreLV)
105	.word 0x00000000
106#endif
107
108#if defined(CONFIG_ROM_EXCEPTION_VECTORS)
109	/*
110	 * Exception vector entry points. When running from ROM, an exception
111	 * cannot be handled. Halt execution and transfer control to debugger,
112	 * if one is attached.
113	 */
114	.org 0x200
115	/* TLB refill, 32 bit task */
116	uhi_mips_exception
117
118	.org 0x280
119	/* XTLB refill, 64 bit task */
120	uhi_mips_exception
121
122	.org 0x300
123	/* Cache error exception */
124	uhi_mips_exception
125
126	.org 0x380
127	/* General exception */
128	uhi_mips_exception
129
130	.org 0x400
131	/* Catch interrupt exceptions */
132	uhi_mips_exception
133
134	.org 0x480
135	/* EJTAG debug exception */
1361:	b	1b
137	 nop
138
139	.org 0x500
140#endif
141
142reset:
143#if __mips_isa_rev >= 6
144	mfc0	t0, CP0_CONFIG, 5
145	and	t0, t0, MIPS_CONF5_VP
146	beqz	t0, 1f
147	 nop
148
149	b	2f
150	 mfc0	t0, CP0_GLOBALNUMBER
151#endif
152
153#ifdef CONFIG_ARCH_BMIPS
1541:	mfc0	t0, CP0_DIAGNOSTIC, 3
155	and	t0, t0, (1 << 31)
156#else
1571:	mfc0	t0, CP0_EBASE
158	and	t0, t0, EBASE_CPUNUM
159#endif
160
161	/* Hang if this isn't the first CPU in the system */
1622:	beqz	t0, 4f
163	 nop
1643:	wait
165	b	3b
166	 nop
167
168	/* Init CP0 Status */
1694:	mfc0	t0, CP0_STATUS
170	and	t0, ST0_IMPL
171	or	t0, ST0_BEV | ST0_ERL | STATUS_SET
172	mtc0	t0, CP0_STATUS
173
174	/*
175	 * Check whether CP0 Config1 is implemented. If not continue
176	 * with legacy Watch register initialization.
177	 */
178	mfc0	t0, CP0_CONFIG
179	bgez	t0, wr_legacy
180	 nop
181
182	/*
183	 * Check WR bit in CP0 Config1 to determine if Watch registers
184	 * are implemented.
185	 */
186	mfc0	t0, CP0_CONFIG, 1
187	andi	t0, (1 << 3)
188	beqz	t0, wr_done
189	 nop
190
191	/* Clear Watch Status bits and disable watch exceptions */
192	li	t1, 0x7		# Clear I, R and W conditions
193	init_wr	0
194	init_wr	1
195	init_wr	2
196	init_wr	3
197	init_wr	4
198	init_wr	5
199	init_wr	6
200	init_wr	7
201	b	wr_done
202	 nop
203
204wr_legacy:
205	MTC0	zero, CP0_WATCHLO
206	mtc0	zero, CP0_WATCHHI
207
208wr_done:
209	/* Clear WP, IV and SW interrupts */
210	mtc0	zero, CP0_CAUSE
211
212	/* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
213	mtc0	zero, CP0_COMPARE
214
215#ifndef CONFIG_SKIP_LOWLEVEL_INIT
216	mfc0	t0, CP0_CONFIG
217	and	t0, t0, MIPS_CONF_IMPL
218	or	t0, t0, CONF_CM_UNCACHED
219	mtc0	t0, CP0_CONFIG
220	ehb
221#endif
222
223#ifdef CONFIG_MIPS_CM
224	PTR_LA	t9, mips_cm_map
225	jalr	t9
226	 nop
227#endif
228
229#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
230	/* Set up initial stack and global data */
231	setup_stack_gd
232
233# ifdef CONFIG_DEBUG_UART
234	/* Earliest point to set up debug uart */
235	PTR_LA	t9, debug_uart_init
236	jalr	t9
237	 nop
238# endif
239#endif
240
241#ifndef CONFIG_SKIP_LOWLEVEL_INIT
242# ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
243	/* Initialize any external memory */
244	PTR_LA	t9, lowlevel_init
245	jalr	t9
246	 nop
247# endif
248
249	/* Initialize caches... */
250	PTR_LA	t9, mips_cache_reset
251	jalr	t9
252	 nop
253
254# ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
255	/* Initialize any external memory */
256	PTR_LA	t9, lowlevel_init
257	jalr	t9
258	 nop
259# endif
260#endif
261
262#ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM
263	/* Set up initial stack and global data */
264	setup_stack_gd
265
266# ifdef CONFIG_DEBUG_UART
267	/* Earliest point to set up debug uart */
268	PTR_LA	t9, debug_uart_init
269	jalr	t9
270	 nop
271# endif
272#endif
273
274	move	a0, zero		# a0 <-- boot_flags = 0
275	PTR_LA	t9, board_init_f
276
277	jr	t9
278	 move	ra, zero
279
280	END(_start)
281