blob: 784b8be81469964298ceb1ccb20347c0697c59dc [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
20# define MIPS_RELOC 3
Paul Burtonf1c64a02015-01-29 10:04:10 +000021# define STATUS_SET 0
Paul Burtonab0d0022015-01-29 10:04:09 +000022#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)
Paul Burtonf1c64a02015-01-29 10:04:10 +000033# define STATUS_SET ST0_KX
Paul Burtonab0d0022015-01-29 10:04:09 +000034#endif
35
wdenkc0218802003-03-27 12:09:35 +000036 .set noreorder
37
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +010038 .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
Daniel Schwierzeck345490f2016-02-07 19:39:58 +010046 .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
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +020054 .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
Andy Yanf5868a52017-07-24 17:45:27 +080062#if CONFIG_VAL(SYS_MALLOC_F_LEN)
63 li t2, CONFIG_VAL(SYS_MALLOC_F_LEN)
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +020064 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)
Weijie Gao6e9281b2020-04-21 09:28:28 +020074 PTR_ADDIU t0, PTRSIZE
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +020075 blt t0, t1, 1b
Weijie Gao6e9281b2020-04-21 09:28:28 +020076 nop
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +020077
Andy Yanf5868a52017-07-24 17:45:27 +080078#if CONFIG_VAL(SYS_MALLOC_F_LEN)
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +020079 PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset
80#endif
81 .endm
82
Daniel Schwierzeck11349292015-12-19 20:20:45 +010083ENTRY(_start)
Bin Menga1875592016-02-05 19:30:11 -080084 /* U-Boot entry point */
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +010085 b reset
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +010086 mtc0 zero, CP0_COUNT # clear cp0 count for most accurate boot timing
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +010087
Daniel Schwierzeckd1c3d8b2018-09-07 19:18:44 +020088#if defined(CONFIG_MIPS_INSERT_BOOT_CONFIG)
Daniel Schwierzeck7185adb2011-07-27 13:22:37 +020089 /*
Daniel Schwierzeckd1c3d8b2018-09-07 19:18:44 +020090 * Store some board-specific boot configuration. This is used by some
91 * MIPS systems like Malta.
Daniel Schwierzeck7185adb2011-07-27 13:22:37 +020092 */
Daniel Schwierzeckaf3971f2016-02-14 18:52:57 +010093 .org 0x10
Daniel Schwierzeckd1c3d8b2018-09-07 19:18:44 +020094 .word CONFIG_MIPS_BOOT_CONFIG_WORD0
95 .word CONFIG_MIPS_BOOT_CONFIG_WORD1
wdenkc0218802003-03-27 12:09:35 +000096#endif
wdenk8bde7f72003-06-27 21:31:46 +000097
Daniel Schwierzeckaf3971f2016-02-14 18:52:57 +010098#if defined(CONFIG_ROM_EXCEPTION_VECTORS)
Daniel Schwierzeck345490f2016-02-07 19:39:58 +010099 /*
100 * Exception vector entry points. When running from ROM, an exception
101 * cannot be handled. Halt execution and transfer control to debugger,
102 * if one is attached.
103 */
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100104 .org 0x200
105 /* TLB refill, 32 bit task */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100106 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100107
108 .org 0x280
109 /* XTLB refill, 64 bit task */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100110 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100111
112 .org 0x300
113 /* Cache error exception */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100114 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100115
116 .org 0x380
117 /* General exception */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100118 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100119
120 .org 0x400
121 /* Catch interrupt exceptions */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100122 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100123
124 .org 0x480
125 /* EJTAG debug exception */
1261: b 1b
127 nop
128
Daniel Schwierzeckaf3971f2016-02-14 18:52:57 +0100129 .org 0x500
130#endif
131
wdenkc0218802003-03-27 12:09:35 +0000132reset:
Paul Burton31d36f72016-09-21 14:59:54 +0100133#if __mips_isa_rev >= 6
134 mfc0 t0, CP0_CONFIG, 5
135 and t0, t0, MIPS_CONF5_VP
136 beqz t0, 1f
137 nop
138
139 b 2f
140 mfc0 t0, CP0_GLOBALNUMBER
141#endif
142
Álvaro Fernández Rojasee422142017-04-25 00:39:20 +0200143#ifdef CONFIG_ARCH_BMIPS
1441: mfc0 t0, CP0_DIAGNOSTIC, 3
145 and t0, t0, (1 << 31)
146#else
Paul Burton31d36f72016-09-21 14:59:54 +01001471: mfc0 t0, CP0_EBASE
148 and t0, t0, EBASE_CPUNUM
Álvaro Fernández Rojasee422142017-04-25 00:39:20 +0200149#endif
Paul Burton31d36f72016-09-21 14:59:54 +0100150
151 /* Hang if this isn't the first CPU in the system */
1522: beqz t0, 4f
153 nop
1543: wait
155 b 3b
156 nop
wdenkc0218802003-03-27 12:09:35 +0000157
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +0100158 /* Init CP0 Status */
1594: mfc0 t0, CP0_STATUS
160 and t0, ST0_IMPL
161 or t0, ST0_BEV | ST0_ERL | STATUS_SET
162 mtc0 t0, CP0_STATUS
163
164 /*
165 * Check whether CP0 Config1 is implemented. If not continue
166 * with legacy Watch register initialization.
167 */
168 mfc0 t0, CP0_CONFIG
169 bgez t0, wr_legacy
170 nop
171
172 /*
173 * Check WR bit in CP0 Config1 to determine if Watch registers
174 * are implemented.
175 */
176 mfc0 t0, CP0_CONFIG, 1
177 andi t0, (1 << 3)
178 beqz t0, wr_done
179 nop
180
181 /* Clear Watch Status bits and disable watch exceptions */
182 li t1, 0x7 # Clear I, R and W conditions
183 init_wr 0
184 init_wr 1
185 init_wr 2
186 init_wr 3
187 init_wr 4
188 init_wr 5
189 init_wr 6
190 init_wr 7
191 b wr_done
192 nop
193
194wr_legacy:
195 MTC0 zero, CP0_WATCHLO
Daniel Schwierzecke26e8dc2016-01-09 22:24:47 +0100196 mtc0 zero, CP0_WATCHHI
wdenkc0218802003-03-27 12:09:35 +0000197
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +0100198wr_done:
199 /* Clear WP, IV and SW interrupts */
Shinya Kuribayashid43d43e2008-03-25 21:30:07 +0900200 mtc0 zero, CP0_CAUSE
201
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +0100202 /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
wdenkc0218802003-03-27 12:09:35 +0000203 mtc0 zero, CP0_COMPARE
204
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900205#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Paul Burton4f9226b2016-09-21 11:18:50 +0100206 mfc0 t0, CP0_CONFIG
207 and t0, t0, MIPS_CONF_IMPL
208 or t0, t0, CONF_CM_UNCACHED
wdenkc0218802003-03-27 12:09:35 +0000209 mtc0 t0, CP0_CONFIG
Paul Burtonc5b84122016-09-21 11:18:57 +0100210 ehb
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900211#endif
wdenkc0218802003-03-27 12:09:35 +0000212
Paul Burtonb2b135d2016-09-21 11:18:53 +0100213#ifdef CONFIG_MIPS_CM
214 PTR_LA t9, mips_cm_map
215 jalr t9
216 nop
217#endif
218
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200219#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
220 /* Set up initial stack and global data */
221 setup_stack_gd
Daniel Schwierzeck0d159d62017-04-24 19:03:34 +0200222
223# ifdef CONFIG_DEBUG_UART
224 /* Earliest point to set up debug uart */
225 PTR_LA t9, debug_uart_init
226 jalr t9
227 nop
228# endif
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200229#endif
230
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900231#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Paul Burtonf8981272016-09-21 11:18:51 +0100232# ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900233 /* Initialize any external memory */
Paul Burtona39b1cb2015-01-29 10:04:08 +0000234 PTR_LA t9, lowlevel_init
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +0900235 jalr t9
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900236 nop
Paul Burtonf8981272016-09-21 11:18:51 +0100237# endif
wdenkc0218802003-03-27 12:09:35 +0000238
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900239 /* Initialize caches... */
Paul Burtona39b1cb2015-01-29 10:04:08 +0000240 PTR_LA t9, mips_cache_reset
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +0900241 jalr t9
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900242 nop
Paul Burtonf8981272016-09-21 11:18:51 +0100243
244# ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
245 /* Initialize any external memory */
246 PTR_LA t9, lowlevel_init
247 jalr t9
248 nop
249# endif
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900250#endif
wdenkc0218802003-03-27 12:09:35 +0000251
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200252#ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +0200253 /* Set up initial stack and global data */
254 setup_stack_gd
Daniel Schwierzeck0d159d62017-04-24 19:03:34 +0200255
256# ifdef CONFIG_DEBUG_UART
257 /* Earliest point to set up debug uart */
258 PTR_LA t9, debug_uart_init
259 jalr t9
260 nop
261# endif
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200262#endif
Daniel Schwierzecke26e8dc2016-01-09 22:24:47 +0100263
Purna Chandra Mandala6279092016-01-21 20:02:51 +0530264 move a0, zero # a0 <-- boot_flags = 0
Paul Burtona39b1cb2015-01-29 10:04:08 +0000265 PTR_LA t9, board_init_f
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100266
Shinya Kuribayashi43c50922008-04-17 23:35:13 +0900267 jr t9
Daniel Schwierzeck6d08e222014-11-20 23:55:32 +0100268 move ra, zero
wdenkc0218802003-03-27 12:09:35 +0000269
Daniel Schwierzeck11349292015-12-19 20:20:45 +0100270 END(_start)