blob: 1d21b2324a7658a209a0bc3d63a25004c8e74b60 [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)
74 blt t0, t1, 1b
75 PTR_ADDIU t0, PTRSIZE
76
Andy Yanf5868a52017-07-24 17:45:27 +080077#if CONFIG_VAL(SYS_MALLOC_F_LEN)
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +020078 PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset
79#endif
80 .endm
81
Daniel Schwierzeck11349292015-12-19 20:20:45 +010082ENTRY(_start)
Bin Menga1875592016-02-05 19:30:11 -080083 /* U-Boot entry point */
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +010084 b reset
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +010085 mtc0 zero, CP0_COUNT # clear cp0 count for most accurate boot timing
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +010086
Daniel Schwierzeckd1c3d8b2018-09-07 19:18:44 +020087#if defined(CONFIG_MIPS_INSERT_BOOT_CONFIG)
Daniel Schwierzeck7185adb2011-07-27 13:22:37 +020088 /*
Daniel Schwierzeckd1c3d8b2018-09-07 19:18:44 +020089 * Store some board-specific boot configuration. This is used by some
90 * MIPS systems like Malta.
Daniel Schwierzeck7185adb2011-07-27 13:22:37 +020091 */
Daniel Schwierzeckaf3971f2016-02-14 18:52:57 +010092 .org 0x10
Daniel Schwierzeckd1c3d8b2018-09-07 19:18:44 +020093 .word CONFIG_MIPS_BOOT_CONFIG_WORD0
94 .word CONFIG_MIPS_BOOT_CONFIG_WORD1
wdenkc0218802003-03-27 12:09:35 +000095#endif
wdenk8bde7f72003-06-27 21:31:46 +000096
Daniel Schwierzeckaf3971f2016-02-14 18:52:57 +010097#if defined(CONFIG_ROM_EXCEPTION_VECTORS)
Daniel Schwierzeck345490f2016-02-07 19:39:58 +010098 /*
99 * Exception vector entry points. When running from ROM, an exception
100 * cannot be handled. Halt execution and transfer control to debugger,
101 * if one is attached.
102 */
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100103 .org 0x200
104 /* TLB refill, 32 bit task */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100105 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100106
107 .org 0x280
108 /* XTLB refill, 64 bit task */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100109 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100110
111 .org 0x300
112 /* Cache error exception */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100113 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100114
115 .org 0x380
116 /* General exception */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100117 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100118
119 .org 0x400
120 /* Catch interrupt exceptions */
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100121 uhi_mips_exception
Daniel Schwierzeck8b1c7342013-02-12 22:22:12 +0100122
123 .org 0x480
124 /* EJTAG debug exception */
1251: b 1b
126 nop
127
Daniel Schwierzeckaf3971f2016-02-14 18:52:57 +0100128 .org 0x500
129#endif
130
wdenkc0218802003-03-27 12:09:35 +0000131reset:
Paul Burton31d36f72016-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 Rojasee422142017-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 Burton31d36f72016-09-21 14:59:54 +01001461: mfc0 t0, CP0_EBASE
147 and t0, t0, EBASE_CPUNUM
Álvaro Fernández Rojasee422142017-04-25 00:39:20 +0200148#endif
Paul Burton31d36f72016-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
wdenkc0218802003-03-27 12:09:35 +0000156
Daniel Schwierzeck65d297a2016-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 Schwierzecke26e8dc2016-01-09 22:24:47 +0100195 mtc0 zero, CP0_WATCHHI
wdenkc0218802003-03-27 12:09:35 +0000196
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +0100197wr_done:
198 /* Clear WP, IV and SW interrupts */
Shinya Kuribayashid43d43e2008-03-25 21:30:07 +0900199 mtc0 zero, CP0_CAUSE
200
Daniel Schwierzeck65d297a2016-02-08 00:37:59 +0100201 /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
wdenkc0218802003-03-27 12:09:35 +0000202 mtc0 zero, CP0_COMPARE
203
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900204#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Paul Burton4f9226b2016-09-21 11:18:50 +0100205 mfc0 t0, CP0_CONFIG
206 and t0, t0, MIPS_CONF_IMPL
207 or t0, t0, CONF_CM_UNCACHED
wdenkc0218802003-03-27 12:09:35 +0000208 mtc0 t0, CP0_CONFIG
Paul Burtonc5b84122016-09-21 11:18:57 +0100209 ehb
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900210#endif
wdenkc0218802003-03-27 12:09:35 +0000211
Paul Burtonb2b135d2016-09-21 11:18:53 +0100212#ifdef CONFIG_MIPS_CM
213 PTR_LA t9, mips_cm_map
214 jalr t9
215 nop
216#endif
217
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200218#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
219 /* Set up initial stack and global data */
220 setup_stack_gd
Daniel Schwierzeck0d159d62017-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 Schwierzeck924ad862016-06-04 16:13:21 +0200228#endif
229
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900230#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Paul Burtonf8981272016-09-21 11:18:51 +0100231# ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900232 /* Initialize any external memory */
Paul Burtona39b1cb2015-01-29 10:04:08 +0000233 PTR_LA t9, lowlevel_init
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +0900234 jalr t9
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900235 nop
Paul Burtonf8981272016-09-21 11:18:51 +0100236# endif
wdenkc0218802003-03-27 12:09:35 +0000237
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900238 /* Initialize caches... */
Paul Burtona39b1cb2015-01-29 10:04:08 +0000239 PTR_LA t9, mips_cache_reset
Shinya Kuribayashi03c031d2007-10-27 15:27:06 +0900240 jalr t9
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900241 nop
Paul Burtonf8981272016-09-21 11:18:51 +0100242
243# ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
244 /* Initialize any external memory */
245 PTR_LA t9, lowlevel_init
246 jalr t9
247 nop
248# endif
Shinya Kuribayashi7aa1f192011-05-07 00:18:13 +0900249#endif
wdenkc0218802003-03-27 12:09:35 +0000250
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200251#ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM
Daniel Schwierzeckc3e72ab2016-09-25 18:36:38 +0200252 /* Set up initial stack and global data */
253 setup_stack_gd
Daniel Schwierzeck0d159d62017-04-24 19:03:34 +0200254
255# ifdef CONFIG_DEBUG_UART
256 /* Earliest point to set up debug uart */
257 PTR_LA t9, debug_uart_init
258 jalr t9
259 nop
260# endif
Daniel Schwierzeck924ad862016-06-04 16:13:21 +0200261#endif
Daniel Schwierzecke26e8dc2016-01-09 22:24:47 +0100262
Purna Chandra Mandala6279092016-01-21 20:02:51 +0530263 move a0, zero # a0 <-- boot_flags = 0
Paul Burtona39b1cb2015-01-29 10:04:08 +0000264 PTR_LA t9, board_init_f
Daniel Schwierzeck345490f2016-02-07 19:39:58 +0100265
Shinya Kuribayashi43c50922008-04-17 23:35:13 +0900266 jr t9
Daniel Schwierzeck6d08e222014-11-20 23:55:32 +0100267 move ra, zero
wdenkc0218802003-03-27 12:09:35 +0000268
Daniel Schwierzeck11349292015-12-19 20:20:45 +0100269 END(_start)