blob: a95c95bc783243a69fccc3d84b197dbeb37aa2fe [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>
Tom Rini4ddbade2022-05-25 12:16:03 -040013#include <system-constants.h>
Daniel Schwierzeck28144592015-01-18 22:18:38 +010014
Paul Burtoncb2ab2f2015-01-29 10:04:09 +000015#ifdef CONFIG_32BIT
Paul Burtondebf0e02015-01-29 10:04:10 +000016# define STATUS_SET 0
Paul Burtoncb2ab2f2015-01-29 10:04:09 +000017#endif
18
19#ifdef CONFIG_64BIT
Paul Burtondebf0e02015-01-29 10:04:10 +000020# define STATUS_SET ST0_KX
Paul Burtoncb2ab2f2015-01-29 10:04:09 +000021#endif
22
wdenkbb1b8262003-03-27 12:09:35 +000023 .set noreorder
24
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +010025 .macro init_wr sel
26 MTC0 zero, CP0_WATCHLO,\sel
27 mtc0 t1, CP0_WATCHHI,\sel
28 mfc0 t0, CP0_WATCHHI,\sel
29 bgez t0, wr_done
30 nop
31 .endm
32
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +010033 .macro uhi_mips_exception
34 move k0, t9 # preserve t9 in k0
35 move k1, a0 # preserve a0 in k1
36 li t9, 15 # UHI exception operation
37 li a0, 0 # Use hard register context
38 sdbbp 1 # Invoke UHI operation
39 .endm
40
Daniel Schwierzeck993a1222016-09-25 18:36:38 +020041 .macro setup_stack_gd
42 li t0, -16
Tom Rini4ddbade2022-05-25 12:16:03 -040043 PTR_LI t1, SYS_INIT_SP_ADDR
Daniel Schwierzeck993a1222016-09-25 18:36:38 +020044 and sp, t1, t0 # force 16 byte alignment
45 PTR_SUBU \
46 sp, sp, GD_SIZE # reserve space for gd
47 and sp, sp, t0 # force 16 byte alignment
48 move k0, sp # save gd pointer
Simon Glassadad2d02023-09-26 08:14:27 -060049#if CONFIG_IS_ENABLED(SYS_MALLOC_F) && \
developer01a28282020-04-21 09:28:33 +020050 !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
Andy Yan984c10d2017-07-24 17:45:27 +080051 li t2, CONFIG_VAL(SYS_MALLOC_F_LEN)
Daniel Schwierzeck993a1222016-09-25 18:36:38 +020052 PTR_SUBU \
53 sp, sp, t2 # reserve space for early malloc
54 and sp, sp, t0 # force 16 byte alignment
55#endif
56 move fp, sp
57
58 /* Clear gd */
59 move t0, k0
601:
61 PTR_S zero, 0(t0)
developerde8b4cf2020-04-21 09:28:28 +020062 PTR_ADDIU t0, PTRSIZE
Daniel Schwierzeck993a1222016-09-25 18:36:38 +020063 blt t0, t1, 1b
developerde8b4cf2020-04-21 09:28:28 +020064 nop
Daniel Schwierzeck993a1222016-09-25 18:36:38 +020065
Simon Glassadad2d02023-09-26 08:14:27 -060066#if CONFIG_IS_ENABLED(SYS_MALLOC_F) && \
developer01a28282020-04-21 09:28:33 +020067 !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
Daniel Schwierzeck993a1222016-09-25 18:36:38 +020068 PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset
69#endif
70 .endm
71
Daniel Schwierzeck7509b572015-12-19 20:20:45 +010072ENTRY(_start)
Stefan Roese04c8b5a2020-10-28 15:09:59 +010073 /*
74 * U-Boot entry point.
75 * Do not add instructions to the branch delay slot! Some SoC's
76 * like Octeon might patch the final U-Boot binary at this location
77 * with additional boot headers.
78 */
Daniel Schwierzeckec443162013-02-12 22:22:12 +010079 b reset
Stefan Roese04c8b5a2020-10-28 15:09:59 +010080 nop
Daniel Schwierzeckec443162013-02-12 22:22:12 +010081
Daniel Schwierzeck2cc9a772018-09-07 19:18:44 +020082#if defined(CONFIG_MIPS_INSERT_BOOT_CONFIG)
Daniel Schwierzeck6ff8ae02011-07-27 13:22:37 +020083 /*
Daniel Schwierzeck2cc9a772018-09-07 19:18:44 +020084 * Store some board-specific boot configuration. This is used by some
85 * MIPS systems like Malta.
Daniel Schwierzeck6ff8ae02011-07-27 13:22:37 +020086 */
Daniel Schwierzeck754cd052016-02-14 18:52:57 +010087 .org 0x10
Daniel Schwierzeck2cc9a772018-09-07 19:18:44 +020088 .word CONFIG_MIPS_BOOT_CONFIG_WORD0
89 .word CONFIG_MIPS_BOOT_CONFIG_WORD1
wdenkbb1b8262003-03-27 12:09:35 +000090#endif
wdenk57b2d802003-06-27 21:31:46 +000091
Daniel Schwierzeck754cd052016-02-14 18:52:57 +010092#if defined(CONFIG_ROM_EXCEPTION_VECTORS)
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +010093 /*
94 * Exception vector entry points. When running from ROM, an exception
95 * cannot be handled. Halt execution and transfer control to debugger,
96 * if one is attached.
97 */
Daniel Schwierzeckec443162013-02-12 22:22:12 +010098 .org 0x200
99 /* TLB refill, 32 bit task */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100100 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100101
102 .org 0x280
103 /* XTLB refill, 64 bit task */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100104 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100105
106 .org 0x300
107 /* Cache error exception */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100108 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100109
110 .org 0x380
111 /* General exception */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100112 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100113
114 .org 0x400
115 /* Catch interrupt exceptions */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100116 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100117
118 .org 0x480
119 /* EJTAG debug exception */
1201: b 1b
121 nop
122
Daniel Schwierzeck754cd052016-02-14 18:52:57 +0100123 .org 0x500
124#endif
125
wdenkbb1b8262003-03-27 12:09:35 +0000126reset:
Stefan Roese04c8b5a2020-10-28 15:09:59 +0100127 mtc0 zero, CP0_COUNT # clear cp0 count for most accurate boot timing
Paul Burtonfcdc1fb2016-09-21 14:59:54 +0100128#if __mips_isa_rev >= 6
129 mfc0 t0, CP0_CONFIG, 5
130 and t0, t0, MIPS_CONF5_VP
131 beqz t0, 1f
132 nop
133
134 b 2f
135 mfc0 t0, CP0_GLOBALNUMBER
136#endif
137
Álvaro Fernández Rojas98a97a82017-04-25 00:39:20 +0200138#ifdef CONFIG_ARCH_BMIPS
1391: mfc0 t0, CP0_DIAGNOSTIC, 3
140 and t0, t0, (1 << 31)
141#else
Paul Burtonfcdc1fb2016-09-21 14:59:54 +01001421: mfc0 t0, CP0_EBASE
Daniel Schwierzecke4ccb472020-07-12 01:46:18 +0200143 and t0, t0, MIPS_EBASE_CPUNUM
Álvaro Fernández Rojas98a97a82017-04-25 00:39:20 +0200144#endif
Paul Burtonfcdc1fb2016-09-21 14:59:54 +0100145
146 /* Hang if this isn't the first CPU in the system */
1472: beqz t0, 4f
148 nop
1493: wait
150 b 3b
151 nop
wdenkbb1b8262003-03-27 12:09:35 +0000152
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +0100153 /* Init CP0 Status */
1544: mfc0 t0, CP0_STATUS
155 and t0, ST0_IMPL
156 or t0, ST0_BEV | ST0_ERL | STATUS_SET
157 mtc0 t0, CP0_STATUS
158
159 /*
160 * Check whether CP0 Config1 is implemented. If not continue
161 * with legacy Watch register initialization.
162 */
163 mfc0 t0, CP0_CONFIG
164 bgez t0, wr_legacy
165 nop
166
167 /*
168 * Check WR bit in CP0 Config1 to determine if Watch registers
169 * are implemented.
170 */
171 mfc0 t0, CP0_CONFIG, 1
172 andi t0, (1 << 3)
173 beqz t0, wr_done
174 nop
175
176 /* Clear Watch Status bits and disable watch exceptions */
177 li t1, 0x7 # Clear I, R and W conditions
178 init_wr 0
179 init_wr 1
180 init_wr 2
181 init_wr 3
182 init_wr 4
183 init_wr 5
184 init_wr 6
185 init_wr 7
186 b wr_done
187 nop
188
189wr_legacy:
190 MTC0 zero, CP0_WATCHLO
Daniel Schwierzeck7aa71642016-01-09 22:24:47 +0100191 mtc0 zero, CP0_WATCHHI
wdenkbb1b8262003-03-27 12:09:35 +0000192
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +0100193wr_done:
194 /* Clear WP, IV and SW interrupts */
Shinya Kuribayashi79727f82008-03-25 21:30:07 +0900195 mtc0 zero, CP0_CAUSE
196
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +0100197 /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
wdenkbb1b8262003-03-27 12:09:35 +0000198 mtc0 zero, CP0_COMPARE
199
Daniel Schwierzeckc95e7f12020-07-12 00:45:57 +0200200#ifdef CONFIG_MIPS_CACHE_DISABLE
Daniel Schwierzeck765f4172020-07-12 00:45:56 +0200201 /* Disable caches */
202 PTR_LA t9, mips_cache_disable
203 jalr t9
204 nop
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900205#endif
wdenkbb1b8262003-03-27 12:09:35 +0000206
Paul Burton79ac1742016-09-21 11:18:53 +0100207#ifdef CONFIG_MIPS_CM
208 PTR_LA t9, mips_cm_map
209 jalr t9
210 nop
211#endif
212
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200213#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
developereb7d3a22020-04-21 09:28:27 +0200214#ifdef CONFIG_MIPS_SRAM_INIT
215 /* Initialize the SRAM first */
216 PTR_LA t9, mips_sram_init
217 jalr t9
218 nop
219#endif
220
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200221 /* Set up initial stack and global data */
222 setup_stack_gd
Daniel Schwierzeckfd32b132017-04-24 19:03:34 +0200223
224# ifdef CONFIG_DEBUG_UART
225 /* Earliest point to set up debug uart */
226 PTR_LA t9, debug_uart_init
227 jalr t9
228 nop
229# endif
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200230#endif
231
Tom Rinie1e85442021-08-27 21:18:30 -0400232#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
Paul Burton68b4c752016-09-21 11:18:51 +0100233# ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900234 /* Initialize any external memory */
Paul Burtonce14da22015-01-29 10:04:08 +0000235 PTR_LA t9, lowlevel_init
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900236 jalr t9
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900237 nop
Paul Burton68b4c752016-09-21 11:18:51 +0100238# endif
Daniel Schwierzeckc95e7f12020-07-12 00:45:57 +0200239#endif
wdenkbb1b8262003-03-27 12:09:35 +0000240
Stefan Roesec6f54b42020-06-30 12:33:16 +0200241#ifdef CONFIG_MIPS_MACH_EARLY_INIT
242 bal mips_mach_early_init
243 nop
244#endif
245
Daniel Schwierzeckc95e7f12020-07-12 00:45:57 +0200246#ifdef CONFIG_MIPS_CACHE_SETUP
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900247 /* Initialize caches... */
Paul Burtonce14da22015-01-29 10:04:08 +0000248 PTR_LA t9, mips_cache_reset
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900249 jalr t9
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900250 nop
Daniel Schwierzeckc95e7f12020-07-12 00:45:57 +0200251#endif
Paul Burton68b4c752016-09-21 11:18:51 +0100252
Tom Rinie1e85442021-08-27 21:18:30 -0400253#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
Paul Burton68b4c752016-09-21 11:18:51 +0100254# 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
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900260#endif
wdenkbb1b8262003-03-27 12:09:35 +0000261
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200262#ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM
Daniel Schwierzeck993a1222016-09-25 18:36:38 +0200263 /* Set up initial stack and global data */
264 setup_stack_gd
Daniel Schwierzeckfd32b132017-04-24 19:03:34 +0200265
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
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200272#endif
Daniel Schwierzeck7aa71642016-01-09 22:24:47 +0100273
Purna Chandra Mandal5c8cdf42016-01-21 20:02:51 +0530274 move a0, zero # a0 <-- boot_flags = 0
Paul Burtonce14da22015-01-29 10:04:08 +0000275 PTR_LA t9, board_init_f
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100276
Shinya Kuribayashi9dabea12008-04-17 23:35:13 +0900277 jr t9
Daniel Schwierzeckf224c1a2014-11-20 23:55:32 +0100278 move ra, zero
wdenkbb1b8262003-03-27 12:09:35 +0000279
Daniel Schwierzeck7509b572015-12-19 20:20:45 +0100280 END(_start)