blob: dd93df9e4a1ffe6d089ac2f8199cda9b1d1d0388 [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
20# define MIPS_RELOC 3
Paul Burtondebf0e02015-01-29 10:04:10 +000021# define STATUS_SET 0
Paul Burtoncb2ab2f2015-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 Burtondebf0e02015-01-29 10:04:10 +000033# define STATUS_SET ST0_KX
Paul Burtoncb2ab2f2015-01-29 10:04:09 +000034#endif
35
wdenkbb1b8262003-03-27 12:09:35 +000036 .set noreorder
37
Daniel Schwierzeckecf0d792016-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 Schwierzeck8b2fd072016-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 Schwierzeck993a1222016-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 Yan984c10d2017-07-24 17:45:27 +080062#if CONFIG_VAL(SYS_MALLOC_F_LEN)
63 li t2, CONFIG_VAL(SYS_MALLOC_F_LEN)
Daniel Schwierzeck993a1222016-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)
developerde8b4cf2020-04-21 09:28:28 +020074 PTR_ADDIU t0, PTRSIZE
Daniel Schwierzeck993a1222016-09-25 18:36:38 +020075 blt t0, t1, 1b
developerde8b4cf2020-04-21 09:28:28 +020076 nop
Daniel Schwierzeck993a1222016-09-25 18:36:38 +020077
Andy Yan984c10d2017-07-24 17:45:27 +080078#if CONFIG_VAL(SYS_MALLOC_F_LEN)
Daniel Schwierzeck993a1222016-09-25 18:36:38 +020079 PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset
80#endif
81 .endm
82
Daniel Schwierzeck7509b572015-12-19 20:20:45 +010083ENTRY(_start)
Bin Meng75574052016-02-05 19:30:11 -080084 /* U-Boot entry point */
Daniel Schwierzeckec443162013-02-12 22:22:12 +010085 b reset
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +010086 mtc0 zero, CP0_COUNT # clear cp0 count for most accurate boot timing
Daniel Schwierzeckec443162013-02-12 22:22:12 +010087
Daniel Schwierzeck2cc9a772018-09-07 19:18:44 +020088#if defined(CONFIG_MIPS_INSERT_BOOT_CONFIG)
Daniel Schwierzeck6ff8ae02011-07-27 13:22:37 +020089 /*
Daniel Schwierzeck2cc9a772018-09-07 19:18:44 +020090 * Store some board-specific boot configuration. This is used by some
91 * MIPS systems like Malta.
Daniel Schwierzeck6ff8ae02011-07-27 13:22:37 +020092 */
Daniel Schwierzeck754cd052016-02-14 18:52:57 +010093 .org 0x10
Daniel Schwierzeck2cc9a772018-09-07 19:18:44 +020094 .word CONFIG_MIPS_BOOT_CONFIG_WORD0
95 .word CONFIG_MIPS_BOOT_CONFIG_WORD1
wdenkbb1b8262003-03-27 12:09:35 +000096#endif
wdenk57b2d802003-06-27 21:31:46 +000097
Daniel Schwierzeck754cd052016-02-14 18:52:57 +010098#if defined(CONFIG_ROM_EXCEPTION_VECTORS)
Daniel Schwierzeck8b2fd072016-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 Schwierzeckec443162013-02-12 22:22:12 +0100104 .org 0x200
105 /* TLB refill, 32 bit task */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100106 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100107
108 .org 0x280
109 /* XTLB refill, 64 bit task */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100110 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100111
112 .org 0x300
113 /* Cache error exception */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100114 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100115
116 .org 0x380
117 /* General exception */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100118 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100119
120 .org 0x400
121 /* Catch interrupt exceptions */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100122 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100123
124 .org 0x480
125 /* EJTAG debug exception */
1261: b 1b
127 nop
128
Daniel Schwierzeck754cd052016-02-14 18:52:57 +0100129 .org 0x500
130#endif
131
wdenkbb1b8262003-03-27 12:09:35 +0000132reset:
Paul Burtonfcdc1fb2016-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 Rojas98a97a82017-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 Burtonfcdc1fb2016-09-21 14:59:54 +01001471: mfc0 t0, CP0_EBASE
148 and t0, t0, EBASE_CPUNUM
Álvaro Fernández Rojas98a97a82017-04-25 00:39:20 +0200149#endif
Paul Burtonfcdc1fb2016-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
wdenkbb1b8262003-03-27 12:09:35 +0000157
Daniel Schwierzeckecf0d792016-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 Schwierzeck7aa71642016-01-09 22:24:47 +0100196 mtc0 zero, CP0_WATCHHI
wdenkbb1b8262003-03-27 12:09:35 +0000197
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +0100198wr_done:
199 /* Clear WP, IV and SW interrupts */
Shinya Kuribayashi79727f82008-03-25 21:30:07 +0900200 mtc0 zero, CP0_CAUSE
201
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +0100202 /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
wdenkbb1b8262003-03-27 12:09:35 +0000203 mtc0 zero, CP0_COMPARE
204
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900205#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Paul Burton4f5561c2016-09-21 11:18:50 +0100206 mfc0 t0, CP0_CONFIG
207 and t0, t0, MIPS_CONF_IMPL
208 or t0, t0, CONF_CM_UNCACHED
wdenkbb1b8262003-03-27 12:09:35 +0000209 mtc0 t0, CP0_CONFIG
Paul Burton82c9d892016-09-21 11:18:57 +0100210 ehb
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900211#endif
wdenkbb1b8262003-03-27 12:09:35 +0000212
Paul Burton79ac1742016-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 Schwierzeck41dc35e2016-06-04 16:13:21 +0200219#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
developereb7d3a22020-04-21 09:28:27 +0200220#ifdef CONFIG_MIPS_SRAM_INIT
221 /* Initialize the SRAM first */
222 PTR_LA t9, mips_sram_init
223 jalr t9
224 nop
225#endif
226
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200227 /* Set up initial stack and global data */
228 setup_stack_gd
Daniel Schwierzeckfd32b132017-04-24 19:03:34 +0200229
230# ifdef CONFIG_DEBUG_UART
231 /* Earliest point to set up debug uart */
232 PTR_LA t9, debug_uart_init
233 jalr t9
234 nop
235# endif
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200236#endif
237
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900238#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Paul Burton68b4c752016-09-21 11:18:51 +0100239# ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900240 /* Initialize any external memory */
Paul Burtonce14da22015-01-29 10:04:08 +0000241 PTR_LA t9, lowlevel_init
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900242 jalr t9
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900243 nop
Paul Burton68b4c752016-09-21 11:18:51 +0100244# endif
wdenkbb1b8262003-03-27 12:09:35 +0000245
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900246 /* Initialize caches... */
Paul Burtonce14da22015-01-29 10:04:08 +0000247 PTR_LA t9, mips_cache_reset
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900248 jalr t9
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900249 nop
Paul Burton68b4c752016-09-21 11:18:51 +0100250
251# ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
252 /* Initialize any external memory */
253 PTR_LA t9, lowlevel_init
254 jalr t9
255 nop
256# endif
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900257#endif
wdenkbb1b8262003-03-27 12:09:35 +0000258
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200259#ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM
Daniel Schwierzeck993a1222016-09-25 18:36:38 +0200260 /* Set up initial stack and global data */
261 setup_stack_gd
Daniel Schwierzeckfd32b132017-04-24 19:03:34 +0200262
263# ifdef CONFIG_DEBUG_UART
264 /* Earliest point to set up debug uart */
265 PTR_LA t9, debug_uart_init
266 jalr t9
267 nop
268# endif
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200269#endif
Daniel Schwierzeck7aa71642016-01-09 22:24:47 +0100270
Purna Chandra Mandal5c8cdf42016-01-21 20:02:51 +0530271 move a0, zero # a0 <-- boot_flags = 0
Paul Burtonce14da22015-01-29 10:04:08 +0000272 PTR_LA t9, board_init_f
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100273
Shinya Kuribayashi9dabea12008-04-17 23:35:13 +0900274 jr t9
Daniel Schwierzeckf224c1a2014-11-20 23:55:32 +0100275 move ra, zero
wdenkbb1b8262003-03-27 12:09:35 +0000276
Daniel Schwierzeck7509b572015-12-19 20:20:45 +0100277 END(_start)