Convert CONFIG_SKIP_LOWLEVEL_INIT et al to Kconfig
[platform/kernel/u-boot.git] / arch / mips / cpu / start.S
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3  *  Startup Code for MIPS32 CPU-core
4  *
5  *  Copyright (c) 2003  Wolfgang Denk <wd@denx.de>
6  */
7
8 #include <asm-offsets.h>
9 #include <config.h>
10 #include <asm/asm.h>
11 #include <asm/regdef.h>
12 #include <asm/mipsregs.h>
13
14 #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
19 #ifdef CONFIG_32BIT
20 # define STATUS_SET     0
21 #endif
22
23 #ifdef CONFIG_64BIT
24 # define STATUS_SET     ST0_KX
25 #endif
26
27         .set noreorder
28
29         .macro init_wr sel
30         MTC0    zero, CP0_WATCHLO,\sel
31         mtc0    t1, CP0_WATCHHI,\sel
32         mfc0    t0, CP0_WATCHHI,\sel
33         bgez    t0, wr_done
34          nop
35         .endm
36
37         .macro uhi_mips_exception
38         move    k0, t9          # preserve t9 in k0
39         move    k1, a0          # preserve a0 in k1
40         li      t9, 15          # UHI exception operation
41         li      a0, 0           # Use hard register context
42         sdbbp   1               # Invoke UHI operation
43         .endm
44
45         .macro setup_stack_gd
46         li      t0, -16
47         PTR_LI  t1, CONFIG_SYS_INIT_SP_ADDR
48         and     sp, t1, t0              # force 16 byte alignment
49         PTR_SUBU \
50                 sp, sp, GD_SIZE         # reserve space for gd
51         and     sp, sp, t0              # force 16 byte alignment
52         move    k0, sp                  # save gd pointer
53 #if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
54     !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
55         li      t2, CONFIG_VAL(SYS_MALLOC_F_LEN)
56         PTR_SUBU \
57                 sp, sp, t2              # reserve space for early malloc
58         and     sp, sp, t0              # force 16 byte alignment
59 #endif
60         move    fp, sp
61
62         /* Clear gd */
63         move    t0, k0
64 1:
65         PTR_S   zero, 0(t0)
66         PTR_ADDIU t0, PTRSIZE
67         blt     t0, t1, 1b
68          nop
69
70 #if CONFIG_VAL(SYS_MALLOC_F_LEN) && \
71     !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F)
72         PTR_S   sp, GD_MALLOC_BASE(k0)  # gd->malloc_base offset
73 #endif
74         .endm
75
76 ENTRY(_start)
77         /*
78          * U-Boot entry point.
79          * Do not add instructions to the branch delay slot! Some SoC's
80          * like Octeon might patch the final U-Boot binary at this location
81          * with additional boot headers.
82          */
83         b       reset
84          nop
85
86 #if defined(CONFIG_MIPS_INSERT_BOOT_CONFIG)
87         /*
88          * Store some board-specific boot configuration. This is used by some
89          * MIPS systems like Malta.
90          */
91         .org 0x10
92         .word CONFIG_MIPS_BOOT_CONFIG_WORD0
93         .word CONFIG_MIPS_BOOT_CONFIG_WORD1
94 #endif
95
96 #if defined(CONFIG_ROM_EXCEPTION_VECTORS)
97         /*
98          * Exception vector entry points. When running from ROM, an exception
99          * cannot be handled. Halt execution and transfer control to debugger,
100          * if one is attached.
101          */
102         .org 0x200
103         /* TLB refill, 32 bit task */
104         uhi_mips_exception
105
106         .org 0x280
107         /* XTLB refill, 64 bit task */
108         uhi_mips_exception
109
110         .org 0x300
111         /* Cache error exception */
112         uhi_mips_exception
113
114         .org 0x380
115         /* General exception */
116         uhi_mips_exception
117
118         .org 0x400
119         /* Catch interrupt exceptions */
120         uhi_mips_exception
121
122         .org 0x480
123         /* EJTAG debug exception */
124 1:      b       1b
125          nop
126
127         .org 0x500
128 #endif
129
130 reset:
131         mtc0    zero, CP0_COUNT # clear cp0 count for most accurate boot timing
132 #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
142 #ifdef CONFIG_ARCH_BMIPS
143 1:      mfc0    t0, CP0_DIAGNOSTIC, 3
144         and     t0, t0, (1 << 31)
145 #else
146 1:      mfc0    t0, CP0_EBASE
147         and     t0, t0, MIPS_EBASE_CPUNUM
148 #endif
149
150         /* Hang if this isn't the first CPU in the system */
151 2:      beqz    t0, 4f
152          nop
153 3:      wait
154         b       3b
155          nop
156
157         /* Init CP0 Status */
158 4:      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
193 wr_legacy:
194         MTC0    zero, CP0_WATCHLO
195         mtc0    zero, CP0_WATCHHI
196
197 wr_done:
198         /* Clear WP, IV and SW interrupts */
199         mtc0    zero, CP0_CAUSE
200
201         /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */
202         mtc0    zero, CP0_COMPARE
203
204 #ifdef CONFIG_MIPS_CACHE_DISABLE
205         /* Disable caches */
206         PTR_LA  t9, mips_cache_disable
207         jalr    t9
208          nop
209 #endif
210
211 #ifdef CONFIG_MIPS_CM
212         PTR_LA  t9, mips_cm_map
213         jalr    t9
214          nop
215 #endif
216
217 #ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM
218 #ifdef CONFIG_MIPS_SRAM_INIT
219         /* Initialize the SRAM first */
220         PTR_LA  t9, mips_sram_init
221         jalr    t9
222          nop
223 #endif
224
225         /* Set up initial stack and global data */
226         setup_stack_gd
227
228 # ifdef CONFIG_DEBUG_UART
229         /* Earliest point to set up debug uart */
230         PTR_LA  t9, debug_uart_init
231         jalr    t9
232          nop
233 # endif
234 #endif
235
236 #if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
237 # ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
238         /* Initialize any external memory */
239         PTR_LA  t9, lowlevel_init
240         jalr    t9
241          nop
242 # endif
243 #endif
244
245 #ifdef CONFIG_MIPS_MACH_EARLY_INIT
246         bal     mips_mach_early_init
247          nop
248 #endif
249
250 #ifdef CONFIG_MIPS_CACHE_SETUP
251         /* Initialize caches... */
252         PTR_LA  t9, mips_cache_reset
253         jalr    t9
254          nop
255 #endif
256
257 #if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT)
258 # ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD
259         /* Initialize any external memory */
260         PTR_LA  t9, lowlevel_init
261         jalr    t9
262          nop
263 # endif
264 #endif
265
266 #ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM
267         /* Set up initial stack and global data */
268         setup_stack_gd
269
270 # ifdef CONFIG_DEBUG_UART
271         /* Earliest point to set up debug uart */
272         PTR_LA  t9, debug_uart_init
273         jalr    t9
274          nop
275 # endif
276 #endif
277
278         move    a0, zero                # a0 <-- boot_flags = 0
279         PTR_LA  t9, board_init_f
280
281         jr      t9
282          move   ra, zero
283
284         END(_start)