blob: 6de9a2f36243e6e5a815a3de0a2724e039dfcf0b [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
Weijie Gaoc95c3ec2020-04-21 09:28:33 +020062#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
63 !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
Andy Yanf5868a52017-07-24 17:45:27 +080064 li t2, CONFIG_VAL(SYS_MALLOC_F_LEN)
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +020065 PTR_SUBU \
66 sp, sp, t2 # reserve space for early malloc
67 and sp, sp, t0 # force 16 byte alignment
68#endif
69 move fp, sp
70
71 /* Clear gd */
72 move t0, k0
731:
74 PTR_S zero, 0(t0)
Weijie Gao6e9281b2020-04-21 09:28:28 +020075 PTR_ADDIU t0, PTRSIZE
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +020076 blt t0, t1, 1b
Weijie Gao6e9281b2020-04-21 09:28:28 +020077 nop
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +020078
Weijie Gaoc95c3ec2020-04-21 09:28:33 +020079#if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
80 !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +020081 PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset
82#endif
83 .endm
84
Daniel Schwierzeck11349292015-12-19 20:20:45 +010085ENTRY(_start)
Bin Menga1875592016-02-05 19:30:11 -080086 /* U-Boot entry point */
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +010087 b reset
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +010088 mtc0 zero, CP0_COUNT # clear cp0 count for most accurate boot timing
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +010089
Daniel Schwierzeckd1c3d8b2018-09-07 19:18:44 +020090#if defined(CONFIG_MIPS_INSERT_BOOT_CONFIG)
Daniel Schwierzeck7185adb2011-07-27 13:22:37 +020091 /*
Daniel Schwierzeckd1c3d8b2018-09-07 19:18:44 +020092 * Store some board-specific boot configuration. This is used by some
93 * MIPS systems like Malta.
Daniel Schwierzeck7185adb2011-07-27 13:22:37 +020094 */
Daniel Schwierzeckaf3971f2016-02-14 18:52:57 +010095 .org 0x10
Daniel Schwierzeckd1c3d8b2018-09-07 19:18:44 +020096 .word CONFIG_MIPS_BOOT_CONFIG_WORD0
97 .word CONFIG_MIPS_BOOT_CONFIG_WORD1
wdenkc0218802003-03-27 12:09:35 +000098#endif
wdenk8bde7f72003-06-27 21:31:46 +000099
Daniel Schwierzeckaf3971f2016-02-14 18:52:57 +0100100#if defined(CONFIG_ROM_EXCEPTION_VECTORS)
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100101 /*
102 * Exception vector entry points. When running from ROM, an exception
103 * cannot be handled. Halt execution and transfer control to debugger,
104 * if one is attached.
105 */
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100106 .org 0x200
107 /* TLB refill, 32 bit task */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100108 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100109
110 .org 0x280
111 /* XTLB refill, 64 bit task */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100112 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100113
114 .org 0x300
115 /* Cache error exception */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100116 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100117
118 .org 0x380
119 /* General exception */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100120 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100121
122 .org 0x400
123 /* Catch interrupt exceptions */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100124 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100125
126 .org 0x480
127 /* EJTAG debug exception */
1281: b 1b
129 nop
130
Daniel Schwierzeckaf3971f2016-02-14 18:52:57 +0100131 .org 0x500
132#endif
133
wdenkc0218802003-03-27 12:09:35 +0000134reset:
Paul Burton31d36f72016-09-21 14:59:54 +0100135#if __mips_isa_rev >= 6
136 mfc0 t0, CP0_CONFIG, 5
137 and t0, t0, MIPS_CONF5_VP
138 beqz t0, 1f
139 nop
140
141 b 2f
142 mfc0 t0, CP0_GLOBALNUMBER
143#endif
144
Álvaro Fernández Rojasee422142017-04-25 00:39:20 +0200145#ifdef CONFIG_ARCH_BMIPS
1461: mfc0 t0, CP0_DIAGNOSTIC, 3
147 and t0, t0, (1 << 31)
148#else
Paul Burton31d36f72016-09-21 14:59:54 +01001491: mfc0 t0, CP0_EBASE
150 and t0, t0, EBASE_CPUNUM
Álvaro Fernández Rojasee422142017-04-25 00:39:20 +0200151#endif
Paul Burton31d36f72016-09-21 14:59:54 +0100152
153 /* Hang if this isn't the first CPU in the system */
1542: beqz t0, 4f
155 nop
1563: wait
157 b 3b
158 nop
wdenkc0218802003-03-27 12:09:35 +0000159
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +0100160 /* Init CP0 Status */
1614: mfc0 t0, CP0_STATUS
162 and t0, ST0_IMPL
163 or t0, ST0_BEV | ST0_ERL | STATUS_SET
164 mtc0 t0, CP0_STATUS
165
166 /*
167 * Check whether CP0 Config1 is implemented. If not continue
168 * with legacy Watch register initialization.
169 */
170 mfc0 t0, CP0_CONFIG
171 bgez t0, wr_legacy
172 nop
173
174 /*
175 * Check WR bit in CP0 Config1 to determine if Watch registers
176 * are implemented.
177 */
178 mfc0 t0, CP0_CONFIG, 1
179 andi t0, (1 << 3)
180 beqz t0, wr_done
181 nop
182
183 /* Clear Watch Status bits and disable watch exceptions */
184 li t1, 0x7 # Clear I, R and W conditions
185 init_wr 0
186 init_wr 1
187 init_wr 2
188 init_wr 3
189 init_wr 4
190 init_wr 5
191 init_wr 6
192 init_wr 7
193 b wr_done
194 nop
195
196wr_legacy:
197 MTC0 zero, CP0_WATCHLO
Daniel Schwierzecke26e8dc2016-01-09 22:24:47 +0100198 mtc0 zero, CP0_WATCHHI
wdenkc0218802003-03-27 12:09:35 +0000199
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +0100200wr_done:
201 /* Clear WP, IV and SW interrupts */
Shinya Kuribayashid43d43e2008-03-25 21:30:07 +0900202 mtc0 zero, CP0_CAUSE
203
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +0100204 /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
wdenkc0218802003-03-27 12:09:35 +0000205 mtc0 zero, CP0_COMPARE
206
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900207#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Paul Burton4f9226b2016-09-21 11:18:50 +0100208 mfc0 t0, CP0_CONFIG
209 and t0, t0, MIPS_CONF_IMPL
210 or t0, t0, CONF_CM_UNCACHED
wdenkc0218802003-03-27 12:09:35 +0000211 mtc0 t0, CP0_CONFIG
Paul Burtonc5b84122016-09-21 11:18:57 +0100212 ehb
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900213#endif
wdenkc0218802003-03-27 12:09:35 +0000214
Paul Burtonb2b135d2016-09-21 11:18:53 +0100215#ifdef CONFIG_MIPS_CM
216 PTR_LA t9, mips_cm_map
217 jalr t9
218 nop
219#endif
220
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200221#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
Weijie Gao2434f582020-04-21 09:28:27 +0200222#ifdef CONFIG_MIPS_SRAM_INIT
223 /* Initialize the SRAM first */
224 PTR_LA t9, mips_sram_init
225 jalr t9
226 nop
227#endif
228
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200229 /* Set up initial stack and global data */
230 setup_stack_gd
Daniel Schwierzeck0d159d62017-04-24 19:03:34 +0200231
232# ifdef CONFIG_DEBUG_UART
233 /* Earliest point to set up debug uart */
234 PTR_LA t9, debug_uart_init
235 jalr t9
236 nop
237# endif
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200238#endif
239
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900240#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Paul Burtonf8981272016-09-21 11:18:51 +0100241# ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900242 /* Initialize any external memory */
Paul Burtona39b1cb2015-01-29 10:04:08 +0000243 PTR_LA t9, lowlevel_init
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +0900244 jalr t9
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900245 nop
Paul Burtonf8981272016-09-21 11:18:51 +0100246# endif
wdenkc0218802003-03-27 12:09:35 +0000247
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900248 /* Initialize caches... */
Paul Burtona39b1cb2015-01-29 10:04:08 +0000249 PTR_LA t9, mips_cache_reset
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +0900250 jalr t9
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900251 nop
Paul Burtonf8981272016-09-21 11:18:51 +0100252
253# ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
254 /* Initialize any external memory */
255 PTR_LA t9, lowlevel_init
256 jalr t9
257 nop
258# endif
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900259#endif
wdenkc0218802003-03-27 12:09:35 +0000260
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200261#ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +0200262 /* Set up initial stack and global data */
263 setup_stack_gd
Daniel Schwierzeck0d159d62017-04-24 19:03:34 +0200264
265# ifdef CONFIG_DEBUG_UART
266 /* Earliest point to set up debug uart */
267 PTR_LA t9, debug_uart_init
268 jalr t9
269 nop
270# endif
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200271#endif
Daniel Schwierzecke26e8dc2016-01-09 22:24:47 +0100272
Purna Chandra Mandala6279092016-01-21 20:02:51 +0530273 move a0, zero # a0 <-- boot_flags = 0
Paul Burtona39b1cb2015-01-29 10:04:08 +0000274 PTR_LA t9, board_init_f
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100275
Shinya Kuribayashi43c50922008-04-17 23:35:13 +0900276 jr t9
Daniel Schwierzeck6d08e222014-11-20 23:55:32 +0100277 move ra, zero
wdenkc0218802003-03-27 12:09:35 +0000278
Daniel Schwierzeck11349292015-12-19 20:20:45 +0100279 END(_start)