blob: 6ca0916c0670ff7e8db8fa112418bcdf34504d5e [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)
74 blt t0, t1, 1b
75 PTR_ADDIU t0, PTRSIZE
76
Andy Yan984c10d2017-07-24 17:45:27 +080077#if CONFIG_VAL(SYS_MALLOC_F_LEN)
Daniel Schwierzeck993a1222016-09-25 18:36:38 +020078 PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset
79#endif
80 .endm
81
Daniel Schwierzeck7509b572015-12-19 20:20:45 +010082ENTRY(_start)
Bin Meng75574052016-02-05 19:30:11 -080083 /* U-Boot entry point */
Daniel Schwierzeckec443162013-02-12 22:22:12 +010084 b reset
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +010085 mtc0 zero, CP0_COUNT # clear cp0 count for most accurate boot timing
Daniel Schwierzeckec443162013-02-12 22:22:12 +010086
Gabor Juhosb6be59a2013-05-22 03:57:46 +000087#if defined(CONFIG_SYS_XWAY_EBU_BOOTCFG)
Daniel Schwierzeck6ff8ae02011-07-27 13:22:37 +020088 /*
89 * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to
90 * access external NOR flashes. If the board boots from NOR flash the
91 * internal BootROM does a blind read at address 0xB0000010 to read the
92 * initial configuration for that EBU in order to access the flash
93 * device with correct parameters. This config option is board-specific.
94 */
Daniel Schwierzeck754cd052016-02-14 18:52:57 +010095 .org 0x10
Daniel Schwierzeck6ff8ae02011-07-27 13:22:37 +020096 .word CONFIG_SYS_XWAY_EBU_BOOTCFG
Daniel Schwierzeckec443162013-02-12 22:22:12 +010097 .word 0x0
Daniel Schwierzeck754cd052016-02-14 18:52:57 +010098#endif
99#if defined(CONFIG_MALTA)
Gabor Juhosb6be59a2013-05-22 03:57:46 +0000100 /*
101 * Linux expects the Board ID here.
102 */
Daniel Schwierzeck754cd052016-02-14 18:52:57 +0100103 .org 0x10
Gabor Juhosb6be59a2013-05-22 03:57:46 +0000104 .word 0x00000420 # 0x420 (Malta Board with CoreLV)
105 .word 0x00000000
wdenkbb1b8262003-03-27 12:09:35 +0000106#endif
wdenk57b2d802003-06-27 21:31:46 +0000107
Daniel Schwierzeck754cd052016-02-14 18:52:57 +0100108#if defined(CONFIG_ROM_EXCEPTION_VECTORS)
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100109 /*
110 * Exception vector entry points. When running from ROM, an exception
111 * cannot be handled. Halt execution and transfer control to debugger,
112 * if one is attached.
113 */
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100114 .org 0x200
115 /* TLB refill, 32 bit task */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100116 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100117
118 .org 0x280
119 /* XTLB refill, 64 bit task */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100120 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100121
122 .org 0x300
123 /* Cache error exception */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100124 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100125
126 .org 0x380
127 /* General exception */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100128 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100129
130 .org 0x400
131 /* Catch interrupt exceptions */
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100132 uhi_mips_exception
Daniel Schwierzeckec443162013-02-12 22:22:12 +0100133
134 .org 0x480
135 /* EJTAG debug exception */
1361: b 1b
137 nop
138
Daniel Schwierzeck754cd052016-02-14 18:52:57 +0100139 .org 0x500
140#endif
141
wdenkbb1b8262003-03-27 12:09:35 +0000142reset:
Paul Burtonfcdc1fb2016-09-21 14:59:54 +0100143#if __mips_isa_rev >= 6
144 mfc0 t0, CP0_CONFIG, 5
145 and t0, t0, MIPS_CONF5_VP
146 beqz t0, 1f
147 nop
148
149 b 2f
150 mfc0 t0, CP0_GLOBALNUMBER
151#endif
152
Álvaro Fernández Rojas98a97a82017-04-25 00:39:20 +0200153#ifdef CONFIG_ARCH_BMIPS
1541: mfc0 t0, CP0_DIAGNOSTIC, 3
155 and t0, t0, (1 << 31)
156#else
Paul Burtonfcdc1fb2016-09-21 14:59:54 +01001571: mfc0 t0, CP0_EBASE
158 and t0, t0, EBASE_CPUNUM
Álvaro Fernández Rojas98a97a82017-04-25 00:39:20 +0200159#endif
Paul Burtonfcdc1fb2016-09-21 14:59:54 +0100160
161 /* Hang if this isn't the first CPU in the system */
1622: beqz t0, 4f
163 nop
1643: wait
165 b 3b
166 nop
wdenkbb1b8262003-03-27 12:09:35 +0000167
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +0100168 /* Init CP0 Status */
1694: mfc0 t0, CP0_STATUS
170 and t0, ST0_IMPL
171 or t0, ST0_BEV | ST0_ERL | STATUS_SET
172 mtc0 t0, CP0_STATUS
173
174 /*
175 * Check whether CP0 Config1 is implemented. If not continue
176 * with legacy Watch register initialization.
177 */
178 mfc0 t0, CP0_CONFIG
179 bgez t0, wr_legacy
180 nop
181
182 /*
183 * Check WR bit in CP0 Config1 to determine if Watch registers
184 * are implemented.
185 */
186 mfc0 t0, CP0_CONFIG, 1
187 andi t0, (1 << 3)
188 beqz t0, wr_done
189 nop
190
191 /* Clear Watch Status bits and disable watch exceptions */
192 li t1, 0x7 # Clear I, R and W conditions
193 init_wr 0
194 init_wr 1
195 init_wr 2
196 init_wr 3
197 init_wr 4
198 init_wr 5
199 init_wr 6
200 init_wr 7
201 b wr_done
202 nop
203
204wr_legacy:
205 MTC0 zero, CP0_WATCHLO
Daniel Schwierzeck7aa71642016-01-09 22:24:47 +0100206 mtc0 zero, CP0_WATCHHI
wdenkbb1b8262003-03-27 12:09:35 +0000207
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +0100208wr_done:
209 /* Clear WP, IV and SW interrupts */
Shinya Kuribayashi79727f82008-03-25 21:30:07 +0900210 mtc0 zero, CP0_CAUSE
211
Daniel Schwierzeckecf0d792016-02-08 00:37:59 +0100212 /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
wdenkbb1b8262003-03-27 12:09:35 +0000213 mtc0 zero, CP0_COMPARE
214
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900215#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Paul Burton4f5561c2016-09-21 11:18:50 +0100216 mfc0 t0, CP0_CONFIG
217 and t0, t0, MIPS_CONF_IMPL
218 or t0, t0, CONF_CM_UNCACHED
wdenkbb1b8262003-03-27 12:09:35 +0000219 mtc0 t0, CP0_CONFIG
Paul Burton82c9d892016-09-21 11:18:57 +0100220 ehb
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900221#endif
wdenkbb1b8262003-03-27 12:09:35 +0000222
Paul Burton79ac1742016-09-21 11:18:53 +0100223#ifdef CONFIG_MIPS_CM
224 PTR_LA t9, mips_cm_map
225 jalr t9
226 nop
227#endif
228
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200229#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
230 /* Set up initial stack and global data */
231 setup_stack_gd
Daniel Schwierzeckfd32b132017-04-24 19:03:34 +0200232
233# ifdef CONFIG_DEBUG_UART
234 /* Earliest point to set up debug uart */
235 PTR_LA t9, debug_uart_init
236 jalr t9
237 nop
238# endif
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200239#endif
240
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900241#ifndef CONFIG_SKIP_LOWLEVEL_INIT
Paul Burton68b4c752016-09-21 11:18:51 +0100242# ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900243 /* Initialize any external memory */
Paul Burtonce14da22015-01-29 10:04:08 +0000244 PTR_LA t9, lowlevel_init
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900245 jalr t9
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900246 nop
Paul Burton68b4c752016-09-21 11:18:51 +0100247# endif
wdenkbb1b8262003-03-27 12:09:35 +0000248
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900249 /* Initialize caches... */
Paul Burtonce14da22015-01-29 10:04:08 +0000250 PTR_LA t9, mips_cache_reset
Shinya Kuribayashic7faac52007-10-27 15:27:06 +0900251 jalr t9
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900252 nop
Paul Burton68b4c752016-09-21 11:18:51 +0100253
254# ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
255 /* Initialize any external memory */
256 PTR_LA t9, lowlevel_init
257 jalr t9
258 nop
259# endif
Shinya Kuribayashi6911d0a2011-05-07 00:18:13 +0900260#endif
wdenkbb1b8262003-03-27 12:09:35 +0000261
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200262#ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM
Daniel Schwierzeck993a1222016-09-25 18:36:38 +0200263 /* Set up initial stack and global data */
264 setup_stack_gd
Daniel Schwierzeckfd32b132017-04-24 19:03:34 +0200265
266# ifdef CONFIG_DEBUG_UART
267 /* Earliest point to set up debug uart */
268 PTR_LA t9, debug_uart_init
269 jalr t9
270 nop
271# endif
Daniel Schwierzeck41dc35e2016-06-04 16:13:21 +0200272#endif
Daniel Schwierzeck7aa71642016-01-09 22:24:47 +0100273
Purna Chandra Mandal5c8cdf42016-01-21 20:02:51 +0530274 move a0, zero # a0 <-- boot_flags = 0
Paul Burtonce14da22015-01-29 10:04:08 +0000275 PTR_LA t9, board_init_f
Daniel Schwierzeck8b2fd072016-02-07 19:39:58 +0100276
Shinya Kuribayashi9dabea12008-04-17 23:35:13 +0900277 jr t9
Daniel Schwierzeckf224c1a2014-11-20 23:55:32 +0100278 move ra, zero
wdenkbb1b8262003-03-27 12:09:35 +0000279
Daniel Schwierzeck7509b572015-12-19 20:20:45 +0100280 END(_start)