blob: 335aafa6a8d7dc7ee2921954a159d250c756d7eb [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001/* SPDX-License-Identifier: GPL-2.0+ */
wdenkc0218802003-03-27 12:09:35 +00002/*
3 * Startup Code for MIPS32 CPU-core
4 *
5 * Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
wdenkc0218802003-03-27 12:09:35 +00006 */
7
Wolfgang Denk25ddd1f2010-10-26 14:34:52 +02008#include <asm-offsets.h>
wdenkc0218802003-03-27 12:09:35 +00009#include <config.h>
Paul Burtona39b1cb2015-01-29 10:04:08 +000010#include <asm/asm.h>
wdenkc0218802003-03-27 12:09:35 +000011#include <asm/regdef.h>
12#include <asm/mipsregs.h>
13
Daniel Schwierzeckdd821282015-01-18 22:18:38 +010014#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
Paul Burtonab0d0022015-01-29 10:04:09 +000019#ifdef CONFIG_32BIT
Paul Burtonf1c64a02015-01-29 10:04:10 +000020# define STATUS_SET 0
Paul Burtonab0d0022015-01-29 10:04:09 +000021#endif
22
23#ifdef CONFIG_64BIT
Paul Burtonf1c64a02015-01-29 10:04:10 +000024# define STATUS_SET ST0_KX
Paul Burtonab0d0022015-01-29 10:04:09 +000025#endif
26
wdenkc0218802003-03-27 12:09:35 +000027 .set noreorder
28
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +010029 .macro init_wr sel
30 MTC0 zero, CP0_WATCHLO,\sel
31 mtc0 t1, CP0_WATCHHI,\sel
32 mfc0 t0, CP0_WATCHHI,\sel
33 bgez t0, wr_done
34 nop
35 .endm
36
Daniel Schwierzeck345490f2016-02-07 19:39:58 +010037 .macro uhi_mips_exception
38 move k0, t9 # preserve t9 in k0
39 move k1, a0 # preserve a0 in k1
40 li t9, 15 # UHI exception operation
41 li a0, 0 # Use hard register context
42 sdbbp 1 # Invoke UHI operation
43 .endm
44
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +020045 .macro setup_stack_gd
46 li t0, -16
47 PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR
48 and sp, t1, t0 # force 16 byte alignment
49 PTR_SUBU \
50 sp, sp, GD_SIZE # reserve space for gd
51 and sp, sp, t0 # force 16 byte alignment
52 move k0, sp # save gd pointer
Weijie Gaoc95c3ec2020-04-21 09:28:33 +020053#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
54 !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
Andy Yanf5868a52017-07-24 17:45:27 +080055 li t2, CONFIG_VAL(SYS_MALLOC_F_LEN)
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +020056 PTR_SUBU \
57 sp, sp, t2 # reserve space for early malloc
58 and sp, sp, t0 # force 16 byte alignment
59#endif
60 move fp, sp
61
62 /* Clear gd */
63 move t0, k0
641:
65 PTR_S zero, 0(t0)
Weijie Gao6e9281b2020-04-21 09:28:28 +020066 PTR_ADDIU t0, PTRSIZE
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +020067 blt t0, t1, 1b
Weijie Gao6e9281b2020-04-21 09:28:28 +020068 nop
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +020069
Weijie Gaoc95c3ec2020-04-21 09:28:33 +020070#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
71 !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +020072 PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset
73#endif
74 .endm
75
Daniel Schwierzeck11349292015-12-19 20:20:45 +010076ENTRY(_start)
Stefan Roesede24bc72020-10-28 15:09:59 +010077 /*
78 * U-Boot entry point.
79 * Do not add instructions to the branch delay slot! Some SoC's
80 * like Octeon might patch the final U-Boot binary at this location
81 * with additional boot headers.
82 */
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +010083 b reset
Stefan Roesede24bc72020-10-28 15:09:59 +010084 nop
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +010085
Daniel Schwierzeckd1c3d8b2018-09-07 19:18:44 +020086#if defined(CONFIG_MIPS_INSERT_BOOT_CONFIG)
Daniel Schwierzeck7185adb2011-07-27 13:22:37 +020087 /*
Daniel Schwierzeckd1c3d8b2018-09-07 19:18:44 +020088 * Store some board-specific boot configuration. This is used by some
89 * MIPS systems like Malta.
Daniel Schwierzeck7185adb2011-07-27 13:22:37 +020090 */
Daniel Schwierzeckaf3971f2016-02-14 18:52:57 +010091 .org 0x10
Daniel Schwierzeckd1c3d8b2018-09-07 19:18:44 +020092 .word CONFIG_MIPS_BOOT_CONFIG_WORD0
93 .word CONFIG_MIPS_BOOT_CONFIG_WORD1
wdenkc0218802003-03-27 12:09:35 +000094#endif
wdenk8bde7f72003-06-27 21:31:46 +000095
Daniel Schwierzeckaf3971f2016-02-14 18:52:57 +010096#if defined(CONFIG_ROM_EXCEPTION_VECTORS)
Daniel Schwierzeck345490f2016-02-07 19:39:58 +010097 /*
98 * Exception vector entry points. When running from ROM, an exception
99 * cannot be handled. Halt execution and transfer control to debugger,
100 * if one is attached.
101 */
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100102 .org 0x200
103 /* TLB refill, 32 bit task */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100104 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100105
106 .org 0x280
107 /* XTLB refill, 64 bit task */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100108 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100109
110 .org 0x300
111 /* Cache error exception */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100112 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100113
114 .org 0x380
115 /* General exception */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100116 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100117
118 .org 0x400
119 /* Catch interrupt exceptions */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100120 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100121
122 .org 0x480
123 /* EJTAG debug exception */
1241: b 1b
125 nop
126
Daniel Schwierzeckaf3971f2016-02-14 18:52:57 +0100127 .org 0x500
128#endif
129
wdenkc0218802003-03-27 12:09:35 +0000130reset:
Stefan Roesede24bc72020-10-28 15:09:59 +0100131 mtc0 zero, CP0_COUNT # clear cp0 count for most accurate boot timing
Paul Burton31d36f72016-09-21 14:59:54 +0100132#if __mips_isa_rev >= 6
133 mfc0 t0, CP0_CONFIG, 5
134 and t0, t0, MIPS_CONF5_VP
135 beqz t0, 1f
136 nop
137
138 b 2f
139 mfc0 t0, CP0_GLOBALNUMBER
140#endif
141
Álvaro Fernández Rojasee422142017-04-25 00:39:20 +0200142#ifdef CONFIG_ARCH_BMIPS
1431: mfc0 t0, CP0_DIAGNOSTIC, 3
144 and t0, t0, (1 << 31)
145#else
Paul Burton31d36f72016-09-21 14:59:54 +01001461: mfc0 t0, CP0_EBASE
Daniel Schwierzeck81d4b142020-07-12 01:46:18 +0200147 and t0, t0, MIPS_EBASE_CPUNUM
Álvaro Fernández Rojasee422142017-04-25 00:39:20 +0200148#endif
Paul Burton31d36f72016-09-21 14:59:54 +0100149
150 /* Hang if this isn't the first CPU in the system */
1512: beqz t0, 4f
152 nop
1533: wait
154 b 3b
155 nop
wdenkc0218802003-03-27 12:09:35 +0000156
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +0100157 /* Init CP0 Status */
1584: mfc0 t0, CP0_STATUS
159 and t0, ST0_IMPL
160 or t0, ST0_BEV | ST0_ERL | STATUS_SET
161 mtc0 t0, CP0_STATUS
162
163 /*
164 * Check whether CP0 Config1 is implemented. If not continue
165 * with legacy Watch register initialization.
166 */
167 mfc0 t0, CP0_CONFIG
168 bgez t0, wr_legacy
169 nop
170
171 /*
172 * Check WR bit in CP0 Config1 to determine if Watch registers
173 * are implemented.
174 */
175 mfc0 t0, CP0_CONFIG, 1
176 andi t0, (1 << 3)
177 beqz t0, wr_done
178 nop
179
180 /* Clear Watch Status bits and disable watch exceptions */
181 li t1, 0x7 # Clear I, R and W conditions
182 init_wr 0
183 init_wr 1
184 init_wr 2
185 init_wr 3
186 init_wr 4
187 init_wr 5
188 init_wr 6
189 init_wr 7
190 b wr_done
191 nop
192
193wr_legacy:
194 MTC0 zero, CP0_WATCHLO
Daniel Schwierzecke26e8dc2016-01-09 22:24:47 +0100195 mtc0 zero, CP0_WATCHHI
wdenkc0218802003-03-27 12:09:35 +0000196
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +0100197wr_done:
198 /* Clear WP, IV and SW interrupts */
Shinya Kuribayashid43d43e2008-03-25 21:30:07 +0900199 mtc0 zero, CP0_CAUSE
200
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +0100201 /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
wdenkc0218802003-03-27 12:09:35 +0000202 mtc0 zero, CP0_COMPARE
203
Daniel Schwierzeck57bfb1a2020-07-12 00:45:57 +0200204#ifdef CONFIG_MIPS_CACHE_DISABLE
Daniel Schwierzeck60772432020-07-12 00:45:56 +0200205 /* Disable caches */
206 PTR_LA t9, mips_cache_disable
207 jalr t9
208 nop
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900209#endif
wdenkc0218802003-03-27 12:09:35 +0000210
Paul Burtonb2b135d2016-09-21 11:18:53 +0100211#ifdef CONFIG_MIPS_CM
212 PTR_LA t9, mips_cm_map
213 jalr t9
214 nop
215#endif
216
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200217#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
Weijie Gao2434f582020-04-21 09:28:27 +0200218#ifdef CONFIG_MIPS_SRAM_INIT
219 /* Initialize the SRAM first */
220 PTR_LA t9, mips_sram_init
221 jalr t9
222 nop
223#endif
224
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200225 /* Set up initial stack and global data */
226 setup_stack_gd
Daniel Schwierzeck0d159d62017-04-24 19:03:34 +0200227
228# ifdef CONFIG_DEBUG_UART
229 /* Earliest point to set up debug uart */
230 PTR_LA t9, debug_uart_init
231 jalr t9
232 nop
233# endif
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200234#endif
235
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900236#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Paul Burtonf8981272016-09-21 11:18:51 +0100237# ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900238 /* Initialize any external memory */
Paul Burtona39b1cb2015-01-29 10:04:08 +0000239 PTR_LA t9, lowlevel_init
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +0900240 jalr t9
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900241 nop
Paul Burtonf8981272016-09-21 11:18:51 +0100242# endif
Daniel Schwierzeck57bfb1a2020-07-12 00:45:57 +0200243#endif
wdenkc0218802003-03-27 12:09:35 +0000244
Stefan Roesede34a612020-06-30 12:33:16 +0200245#ifdef CONFIG_MIPS_MACH_EARLY_INIT
246 bal mips_mach_early_init
247 nop
248#endif
249
Daniel Schwierzeck57bfb1a2020-07-12 00:45:57 +0200250#ifdef CONFIG_MIPS_CACHE_SETUP
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900251 /* Initialize caches... */
Paul Burtona39b1cb2015-01-29 10:04:08 +0000252 PTR_LA t9, mips_cache_reset
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +0900253 jalr t9
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900254 nop
Daniel Schwierzeck57bfb1a2020-07-12 00:45:57 +0200255#endif
Paul Burtonf8981272016-09-21 11:18:51 +0100256
Daniel Schwierzeck57bfb1a2020-07-12 00:45:57 +0200257#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Paul Burtonf8981272016-09-21 11:18:51 +0100258# ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
259 /* Initialize any external memory */
260 PTR_LA t9, lowlevel_init
261 jalr t9
262 nop
263# endif
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900264#endif
wdenkc0218802003-03-27 12:09:35 +0000265
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200266#ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +0200267 /* Set up initial stack and global data */
268 setup_stack_gd
Daniel Schwierzeck0d159d62017-04-24 19:03:34 +0200269
270# ifdef CONFIG_DEBUG_UART
271 /* Earliest point to set up debug uart */
272 PTR_LA t9, debug_uart_init
273 jalr t9
274 nop
275# endif
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200276#endif
Daniel Schwierzecke26e8dc2016-01-09 22:24:47 +0100277
Purna Chandra Mandala6279092016-01-21 20:02:51 +0530278 move a0, zero # a0 <-- boot_flags = 0
Paul Burtona39b1cb2015-01-29 10:04:08 +0000279 PTR_LA t9, board_init_f
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100280
Shinya Kuribayashi43c50922008-04-17 23:35:13 +0900281 jr t9
Daniel Schwierzeck6d08e222014-11-20 23:55:32 +0100282 move ra, zero
wdenkc0218802003-03-27 12:09:35 +0000283
Daniel Schwierzeck11349292015-12-19 20:20:45 +0100284 END(_start)