blob: d0c412236dd8a7c8d0b2630cc18c2cf4a46b05c5 [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)
Bin Meng75574052016-02-05 19:30:11 -080077 /* U-Boot entry point */
Daniel Schwierzeckec443162013-02-12 22:22:12 +010078 b reset
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +010079 mtc0 zero, CP0_COUNT # clear cp0 count for most accurate boot timing
Daniel Schwierzeckec443162013-02-12 22:22:12 +010080
Daniel Schwierzeck2cc9a772018-09-07 19:18:44 +020081#if defined(CONFIG_MIPS_INSERT_BOOT_CONFIG)
Daniel Schwierzeck6ff8ae02011-07-27 13:22:37 +020082 /*
Daniel Schwierzeck2cc9a772018-09-07 19:18:44 +020083 * Store some board-specific boot configuration. This is used by some
84 * MIPS systems like Malta.
Daniel Schwierzeck6ff8ae02011-07-27 13:22:37 +020085 */
Daniel Schwierzeck754cd052016-02-14 18:52:57 +010086 .org 0x10
Daniel Schwierzeck2cc9a772018-09-07 19:18:44 +020087 .word CONFIG_MIPS_BOOT_CONFIG_WORD0
88 .word CONFIG_MIPS_BOOT_CONFIG_WORD1
wdenkbb1b8262003-03-27 12:09:35 +000089#endif
wdenk57b2d802003-06-27 21:31:46 +000090
Daniel Schwierzeck754cd052016-02-14 18:52:57 +010091#if defined(CONFIG_ROM_EXCEPTION_VECTORS)
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +010092 /*
93 * Exception vector entry points. When running from ROM, an exception
94 * cannot be handled. Halt execution and transfer control to debugger,
95 * if one is attached.
96 */
Daniel Schwierzeckec443162013-02-12 22:22:12 +010097 .org 0x200
98 /* TLB refill, 32 bit task */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +010099 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100100
101 .org 0x280
102 /* XTLB refill, 64 bit task */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100103 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100104
105 .org 0x300
106 /* Cache error exception */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100107 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100108
109 .org 0x380
110 /* General exception */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100111 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100112
113 .org 0x400
114 /* Catch interrupt exceptions */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100115 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100116
117 .org 0x480
118 /* EJTAG debug exception */
1191: b 1b
120 nop
121
Daniel Schwierzeck754cd052016-02-14 18:52:57 +0100122 .org 0x500
123#endif
124
wdenkbb1b8262003-03-27 12:09:35 +0000125reset:
Paul Burtonfcdc1fb2016-09-21 14:59:54 +0100126#if __mips_isa_rev >= 6
127 mfc0 t0, CP0_CONFIG, 5
128 and t0, t0, MIPS_CONF5_VP
129 beqz t0, 1f
130 nop
131
132 b 2f
133 mfc0 t0, CP0_GLOBALNUMBER
134#endif
135
Álvaro Fernández Rojas98a97a82017-04-25 00:39:20 +0200136#ifdef CONFIG_ARCH_BMIPS
1371: mfc0 t0, CP0_DIAGNOSTIC, 3
138 and t0, t0, (1 << 31)
139#else
Paul Burtonfcdc1fb2016-09-21 14:59:54 +01001401: mfc0 t0, CP0_EBASE
Daniel Schwierzecke4ccb472020-07-12 01:46:18 +0200141 and t0, t0, MIPS_EBASE_CPUNUM
Álvaro Fernández Rojas98a97a82017-04-25 00:39:20 +0200142#endif
Paul Burtonfcdc1fb2016-09-21 14:59:54 +0100143
144 /* Hang if this isn't the first CPU in the system */
1452: beqz t0, 4f
146 nop
1473: wait
148 b 3b
149 nop
wdenkbb1b8262003-03-27 12:09:35 +0000150
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +0100151 /* Init CP0 Status */
1524: mfc0 t0, CP0_STATUS
153 and t0, ST0_IMPL
154 or t0, ST0_BEV | ST0_ERL | STATUS_SET
155 mtc0 t0, CP0_STATUS
156
157 /*
158 * Check whether CP0 Config1 is implemented. If not continue
159 * with legacy Watch register initialization.
160 */
161 mfc0 t0, CP0_CONFIG
162 bgez t0, wr_legacy
163 nop
164
165 /*
166 * Check WR bit in CP0 Config1 to determine if Watch registers
167 * are implemented.
168 */
169 mfc0 t0, CP0_CONFIG, 1
170 andi t0, (1 << 3)
171 beqz t0, wr_done
172 nop
173
174 /* Clear Watch Status bits and disable watch exceptions */
175 li t1, 0x7 # Clear I, R and W conditions
176 init_wr 0
177 init_wr 1
178 init_wr 2
179 init_wr 3
180 init_wr 4
181 init_wr 5
182 init_wr 6
183 init_wr 7
184 b wr_done
185 nop
186
187wr_legacy:
188 MTC0 zero, CP0_WATCHLO
Daniel Schwierzeck7aa71642016-01-09 22:24:47 +0100189 mtc0 zero, CP0_WATCHHI
wdenkbb1b8262003-03-27 12:09:35 +0000190
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +0100191wr_done:
192 /* Clear WP, IV and SW interrupts */
Shinya Kuribayashi79727f82008-03-25 21:30:07 +0900193 mtc0 zero, CP0_CAUSE
194
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +0100195 /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
wdenkbb1b8262003-03-27 12:09:35 +0000196 mtc0 zero, CP0_COMPARE
197
Daniel Schwierzeckc95e7f12020-07-12 00:45:57 +0200198#ifdef CONFIG_MIPS_CACHE_DISABLE
Daniel Schwierzeck765f4172020-07-12 00:45:56 +0200199 /* Disable caches */
200 PTR_LA t9, mips_cache_disable
201 jalr t9
202 nop
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900203#endif
wdenkbb1b8262003-03-27 12:09:35 +0000204
Paul Burton79ac1742016-09-21 11:18:53 +0100205#ifdef CONFIG_MIPS_CM
206 PTR_LA t9, mips_cm_map
207 jalr t9
208 nop
209#endif
210
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200211#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
developereb7d3a22020-04-21 09:28:27 +0200212#ifdef CONFIG_MIPS_SRAM_INIT
213 /* Initialize the SRAM first */
214 PTR_LA t9, mips_sram_init
215 jalr t9
216 nop
217#endif
218
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200219 /* Set up initial stack and global data */
220 setup_stack_gd
Daniel Schwierzeckfd32b132017-04-24 19:03:34 +0200221
222# ifdef CONFIG_DEBUG_UART
223 /* Earliest point to set up debug uart */
224 PTR_LA t9, debug_uart_init
225 jalr t9
226 nop
227# endif
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200228#endif
229
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900230#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Paul Burton68b4c752016-09-21 11:18:51 +0100231# ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900232 /* Initialize any external memory */
Paul Burtonce14da22015-01-29 10:04:08 +0000233 PTR_LA t9, lowlevel_init
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900234 jalr t9
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900235 nop
Paul Burton68b4c752016-09-21 11:18:51 +0100236# endif
Daniel Schwierzeckc95e7f12020-07-12 00:45:57 +0200237#endif
wdenkbb1b8262003-03-27 12:09:35 +0000238
Stefan Roesec6f54b42020-06-30 12:33:16 +0200239#ifdef CONFIG_MIPS_MACH_EARLY_INIT
240 bal mips_mach_early_init
241 nop
242#endif
243
Daniel Schwierzeckc95e7f12020-07-12 00:45:57 +0200244#ifdef CONFIG_MIPS_CACHE_SETUP
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900245 /* Initialize caches... */
Paul Burtonce14da22015-01-29 10:04:08 +0000246 PTR_LA t9, mips_cache_reset
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900247 jalr t9
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900248 nop
Daniel Schwierzeckc95e7f12020-07-12 00:45:57 +0200249#endif
Paul Burton68b4c752016-09-21 11:18:51 +0100250
Daniel Schwierzeckc95e7f12020-07-12 00:45:57 +0200251#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Paul Burton68b4c752016-09-21 11:18:51 +0100252# ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
253 /* Initialize any external memory */
254 PTR_LA t9, lowlevel_init
255 jalr t9
256 nop
257# endif
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900258#endif
wdenkbb1b8262003-03-27 12:09:35 +0000259
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200260#ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM
Daniel Schwierzeck993a1222016-09-25 18:36:38 +0200261 /* Set up initial stack and global data */
262 setup_stack_gd
Daniel Schwierzeckfd32b132017-04-24 19:03:34 +0200263
264# ifdef CONFIG_DEBUG_UART
265 /* Earliest point to set up debug uart */
266 PTR_LA t9, debug_uart_init
267 jalr t9
268 nop
269# endif
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200270#endif
Daniel Schwierzeck7aa71642016-01-09 22:24:47 +0100271
Purna Chandra Mandal5c8cdf42016-01-21 20:02:51 +0530272 move a0, zero # a0 <-- boot_flags = 0
Paul Burtonce14da22015-01-29 10:04:08 +0000273 PTR_LA t9, board_init_f
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100274
Shinya Kuribayashi9dabea12008-04-17 23:35:13 +0900275 jr t9
Daniel Schwierzeckf224c1a2014-11-20 23:55:32 +0100276 move ra, zero
wdenkbb1b8262003-03-27 12:09:35 +0000277
Daniel Schwierzeck7509b572015-12-19 20:20:45 +0100278 END(_start)