blob: 47251a5b92a0cc5ca268181189711c6ac7b379cb [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001/* SPDX-License-Identifier: GPL-2.0+ */
wdenkbb1b8262003-03-27 12:09:35 +00002/*
3 * Startup Code for MIPS32 CPU-core
4 *
5 * Copyright (c) 2003 Wolfgang Denk <wd@denx.de>
wdenkbb1b8262003-03-27 12:09:35 +00006 */
7
Wolfgang Denk0191e472010-10-26 14:34:52 +02008#include <asm-offsets.h>
wdenkbb1b8262003-03-27 12:09:35 +00009#include <config.h>
Paul Burtonce14da22015-01-29 10:04:08 +000010#include <asm/asm.h>
wdenkbb1b8262003-03-27 12:09:35 +000011#include <asm/regdef.h>
12#include <asm/mipsregs.h>
13
Daniel Schwierzeck28144592015-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 Burtoncb2ab2f2015-01-29 10:04:09 +000019#ifdef CONFIG_32BIT
Paul Burtondebf0e02015-01-29 10:04:10 +000020# define STATUS_SET 0
Paul Burtoncb2ab2f2015-01-29 10:04:09 +000021#endif
22
23#ifdef CONFIG_64BIT
Paul Burtondebf0e02015-01-29 10:04:10 +000024# define STATUS_SET ST0_KX
Paul Burtoncb2ab2f2015-01-29 10:04:09 +000025#endif
26
wdenkbb1b8262003-03-27 12:09:35 +000027 .set noreorder
28
Daniel Schwierzeckecf0d792016-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 Schwierzeck8b2fd072016-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 Schwierzeck993a1222016-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
developer01a28282020-04-21 09:28:33 +020053#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
54 !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
Andy Yan984c10d2017-07-24 17:45:27 +080055 li t2, CONFIG_VAL(SYS_MALLOC_F_LEN)
Daniel Schwierzeck993a1222016-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)
developerde8b4cf2020-04-21 09:28:28 +020066 PTR_ADDIU t0, PTRSIZE
Daniel Schwierzeck993a1222016-09-25 18:36:38 +020067 blt t0, t1, 1b
developerde8b4cf2020-04-21 09:28:28 +020068 nop
Daniel Schwierzeck993a1222016-09-25 18:36:38 +020069
developer01a28282020-04-21 09:28:33 +020070#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
71 !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
Daniel Schwierzeck993a1222016-09-25 18:36:38 +020072 PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset
73#endif
74 .endm
75
Daniel Schwierzeck7509b572015-12-19 20:20:45 +010076ENTRY(_start)
Stefan Roese04c8b5a2020-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 Schwierzeckec443162013-02-12 22:22:12 +010083 b reset
Stefan Roese04c8b5a2020-10-28 15:09:59 +010084 nop
Daniel Schwierzeckec443162013-02-12 22:22:12 +010085
Daniel Schwierzeck2cc9a772018-09-07 19:18:44 +020086#if defined(CONFIG_MIPS_INSERT_BOOT_CONFIG)
Daniel Schwierzeck6ff8ae02011-07-27 13:22:37 +020087 /*
Daniel Schwierzeck2cc9a772018-09-07 19:18:44 +020088 * Store some board-specific boot configuration. This is used by some
89 * MIPS systems like Malta.
Daniel Schwierzeck6ff8ae02011-07-27 13:22:37 +020090 */
Daniel Schwierzeck754cd052016-02-14 18:52:57 +010091 .org 0x10
Daniel Schwierzeck2cc9a772018-09-07 19:18:44 +020092 .word CONFIG_MIPS_BOOT_CONFIG_WORD0
93 .word CONFIG_MIPS_BOOT_CONFIG_WORD1
wdenkbb1b8262003-03-27 12:09:35 +000094#endif
wdenk57b2d802003-06-27 21:31:46 +000095
Daniel Schwierzeck754cd052016-02-14 18:52:57 +010096#if defined(CONFIG_ROM_EXCEPTION_VECTORS)
Daniel Schwierzeck8b2fd072016-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 Schwierzeckec443162013-02-12 22:22:12 +0100102 .org 0x200
103 /* TLB refill, 32 bit task */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100104 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100105
106 .org 0x280
107 /* XTLB refill, 64 bit task */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100108 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100109
110 .org 0x300
111 /* Cache error exception */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100112 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100113
114 .org 0x380
115 /* General exception */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100116 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100117
118 .org 0x400
119 /* Catch interrupt exceptions */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100120 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100121
122 .org 0x480
123 /* EJTAG debug exception */
1241: b 1b
125 nop
126
Daniel Schwierzeck754cd052016-02-14 18:52:57 +0100127 .org 0x500
128#endif
129
wdenkbb1b8262003-03-27 12:09:35 +0000130reset:
Stefan Roese04c8b5a2020-10-28 15:09:59 +0100131 mtc0 zero, CP0_COUNT # clear cp0 count for most accurate boot timing
Paul Burtonfcdc1fb2016-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 Rojas98a97a82017-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 Burtonfcdc1fb2016-09-21 14:59:54 +01001461: mfc0 t0, CP0_EBASE
Daniel Schwierzecke4ccb472020-07-12 01:46:18 +0200147 and t0, t0, MIPS_EBASE_CPUNUM
Álvaro Fernández Rojas98a97a82017-04-25 00:39:20 +0200148#endif
Paul Burtonfcdc1fb2016-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
wdenkbb1b8262003-03-27 12:09:35 +0000156
Daniel Schwierzeckecf0d792016-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 Schwierzeck7aa71642016-01-09 22:24:47 +0100195 mtc0 zero, CP0_WATCHHI
wdenkbb1b8262003-03-27 12:09:35 +0000196
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +0100197wr_done:
198 /* Clear WP, IV and SW interrupts */
Shinya Kuribayashi79727f82008-03-25 21:30:07 +0900199 mtc0 zero, CP0_CAUSE
200
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +0100201 /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
wdenkbb1b8262003-03-27 12:09:35 +0000202 mtc0 zero, CP0_COMPARE
203
Daniel Schwierzeckc95e7f12020-07-12 00:45:57 +0200204#ifdef CONFIG_MIPS_CACHE_DISABLE
Daniel Schwierzeck765f4172020-07-12 00:45:56 +0200205 /* Disable caches */
206 PTR_LA t9, mips_cache_disable
207 jalr t9
208 nop
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900209#endif
wdenkbb1b8262003-03-27 12:09:35 +0000210
Paul Burton79ac1742016-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 Schwierzeck41dc35e2016-06-04 16:13:21 +0200217#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
developereb7d3a22020-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 Schwierzeck41dc35e2016-06-04 16:13:21 +0200225 /* Set up initial stack and global data */
226 setup_stack_gd
Daniel Schwierzeckfd32b132017-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 Schwierzeck41dc35e2016-06-04 16:13:21 +0200234#endif
235
Tom Rinie1e85442021-08-27 21:18:30 -0400236#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
Paul Burton68b4c752016-09-21 11:18:51 +0100237# ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900238 /* Initialize any external memory */
Paul Burtonce14da22015-01-29 10:04:08 +0000239 PTR_LA t9, lowlevel_init
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900240 jalr t9
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900241 nop
Paul Burton68b4c752016-09-21 11:18:51 +0100242# endif
Daniel Schwierzeckc95e7f12020-07-12 00:45:57 +0200243#endif
wdenkbb1b8262003-03-27 12:09:35 +0000244
Stefan Roesec6f54b42020-06-30 12:33:16 +0200245#ifdef CONFIG_MIPS_MACH_EARLY_INIT
246 bal mips_mach_early_init
247 nop
248#endif
249
Daniel Schwierzeckc95e7f12020-07-12 00:45:57 +0200250#ifdef CONFIG_MIPS_CACHE_SETUP
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900251 /* Initialize caches... */
Paul Burtonce14da22015-01-29 10:04:08 +0000252 PTR_LA t9, mips_cache_reset
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900253 jalr t9
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900254 nop
Daniel Schwierzeckc95e7f12020-07-12 00:45:57 +0200255#endif
Paul Burton68b4c752016-09-21 11:18:51 +0100256
Tom Rinie1e85442021-08-27 21:18:30 -0400257#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
Paul Burton68b4c752016-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 Kuribayashi6911d0a2011-05-07 00:18:13 +0900264#endif
wdenkbb1b8262003-03-27 12:09:35 +0000265
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200266#ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM
Daniel Schwierzeck993a1222016-09-25 18:36:38 +0200267 /* Set up initial stack and global data */
268 setup_stack_gd
Daniel Schwierzeckfd32b132017-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 Schwierzeck41dc35e2016-06-04 16:13:21 +0200276#endif
Daniel Schwierzeck7aa71642016-01-09 22:24:47 +0100277
Purna Chandra Mandal5c8cdf42016-01-21 20:02:51 +0530278 move a0, zero # a0 <-- boot_flags = 0
Paul Burtonce14da22015-01-29 10:04:08 +0000279 PTR_LA t9, board_init_f
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100280
Shinya Kuribayashi9dabea12008-04-17 23:35:13 +0900281 jr t9
Daniel Schwierzeckf224c1a2014-11-20 23:55:32 +0100282 move ra, zero
wdenkbb1b8262003-03-27 12:09:35 +0000283
Daniel Schwierzeck7509b572015-12-19 20:20:45 +0100284 END(_start)