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#include <system-constants.h> 14 15#ifdef CONFIG_32BIT 16# define STATUS_SET 0 17#endif 18 19#ifdef CONFIG_64BIT 20# define STATUS_SET ST0_KX 21#endif 22 23 .set noreorder 24 25 .macro init_wr sel 26 MTC0 zero, CP0_WATCHLO,\sel 27 mtc0 t1, CP0_WATCHHI,\sel 28 mfc0 t0, CP0_WATCHHI,\sel 29 bgez t0, wr_done 30 nop 31 .endm 32 33 .macro uhi_mips_exception 34 move k0, t9 # preserve t9 in k0 35 move k1, a0 # preserve a0 in k1 36 li t9, 15 # UHI exception operation 37 li a0, 0 # Use hard register context 38 sdbbp 1 # Invoke UHI operation 39 .endm 40 41 .macro setup_stack_gd 42 li t0, -16 43 PTR_LI t1, SYS_INIT_SP_ADDR 44 and sp, t1, t0 # force 16 byte alignment 45 PTR_SUBU \ 46 sp, sp, GD_SIZE # reserve space for gd 47 and sp, sp, t0 # force 16 byte alignment 48 move k0, sp # save gd pointer 49#if CONFIG_IS_ENABLED(SYS_MALLOC_F) && \ 50 !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F) 51 li t2, CONFIG_VAL(SYS_MALLOC_F_LEN) 52 PTR_SUBU \ 53 sp, sp, t2 # reserve space for early malloc 54 and sp, sp, t0 # force 16 byte alignment 55#endif 56 move fp, sp 57 58 /* Clear gd */ 59 move t0, k0 601: 61 PTR_S zero, 0(t0) 62 PTR_ADDIU t0, PTRSIZE 63 blt t0, t1, 1b 64 nop 65 66#if CONFIG_IS_ENABLED(SYS_MALLOC_F) && \ 67 !CONFIG_IS_ENABLED(INIT_STACK_WITHOUT_MALLOC_F) 68 PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset 69#endif 70 .endm 71 72ENTRY(_start) 73 /* 74 * U-Boot entry point. 75 * Do not add instructions to the branch delay slot! Some SoC's 76 * like Octeon might patch the final U-Boot binary at this location 77 * with additional boot headers. 78 */ 79 b reset 80 nop 81 82#if defined(CONFIG_MIPS_INSERT_BOOT_CONFIG) 83 /* 84 * Store some board-specific boot configuration. This is used by some 85 * MIPS systems like Malta. 86 */ 87 .org 0x10 88 .word CONFIG_MIPS_BOOT_CONFIG_WORD0 89 .word CONFIG_MIPS_BOOT_CONFIG_WORD1 90#endif 91 92#if defined(CONFIG_ROM_EXCEPTION_VECTORS) 93 /* 94 * Exception vector entry points. When running from ROM, an exception 95 * cannot be handled. Halt execution and transfer control to debugger, 96 * if one is attached. 97 */ 98 .org 0x200 99 /* TLB refill, 32 bit task */ 100 uhi_mips_exception 101 102 .org 0x280 103 /* XTLB refill, 64 bit task */ 104 uhi_mips_exception 105 106 .org 0x300 107 /* Cache error exception */ 108 uhi_mips_exception 109 110 .org 0x380 111 /* General exception */ 112 uhi_mips_exception 113 114 .org 0x400 115 /* Catch interrupt exceptions */ 116 uhi_mips_exception 117 118 .org 0x480 119 /* EJTAG debug exception */ 1201: b 1b 121 nop 122 123 .org 0x500 124#endif 125 126reset: 127 mtc0 zero, CP0_COUNT # clear cp0 count for most accurate boot timing 128#if __mips_isa_rev >= 6 129 mfc0 t0, CP0_CONFIG, 5 130 and t0, t0, MIPS_CONF5_VP 131 beqz t0, 1f 132 nop 133 134 b 2f 135 mfc0 t0, CP0_GLOBALNUMBER 136#endif 137 138#ifdef CONFIG_ARCH_BMIPS 1391: mfc0 t0, CP0_DIAGNOSTIC, 3 140 and t0, t0, (1 << 31) 141#else 1421: mfc0 t0, CP0_EBASE 143 and t0, t0, MIPS_EBASE_CPUNUM 144#endif 145 146 /* Hang if this isn't the first CPU in the system */ 1472: beqz t0, 4f 148 nop 1493: wait 150 b 3b 151 nop 152 153 /* Init CP0 Status */ 1544: mfc0 t0, CP0_STATUS 155 and t0, ST0_IMPL 156 or t0, ST0_BEV | ST0_ERL | STATUS_SET 157 mtc0 t0, CP0_STATUS 158 159 /* 160 * Check whether CP0 Config1 is implemented. If not continue 161 * with legacy Watch register initialization. 162 */ 163 mfc0 t0, CP0_CONFIG 164 bgez t0, wr_legacy 165 nop 166 167 /* 168 * Check WR bit in CP0 Config1 to determine if Watch registers 169 * are implemented. 170 */ 171 mfc0 t0, CP0_CONFIG, 1 172 andi t0, (1 << 3) 173 beqz t0, wr_done 174 nop 175 176 /* Clear Watch Status bits and disable watch exceptions */ 177 li t1, 0x7 # Clear I, R and W conditions 178 init_wr 0 179 init_wr 1 180 init_wr 2 181 init_wr 3 182 init_wr 4 183 init_wr 5 184 init_wr 6 185 init_wr 7 186 b wr_done 187 nop 188 189wr_legacy: 190 MTC0 zero, CP0_WATCHLO 191 mtc0 zero, CP0_WATCHHI 192 193wr_done: 194 /* Clear WP, IV and SW interrupts */ 195 mtc0 zero, CP0_CAUSE 196 197 /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */ 198 mtc0 zero, CP0_COMPARE 199 200#ifdef CONFIG_MIPS_CACHE_DISABLE 201 /* Disable caches */ 202 PTR_LA t9, mips_cache_disable 203 jalr t9 204 nop 205#endif 206 207#ifdef CONFIG_MIPS_CM 208 PTR_LA t9, mips_cm_map 209 jalr t9 210 nop 211#endif 212 213#ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM 214#ifdef CONFIG_MIPS_SRAM_INIT 215 /* Initialize the SRAM first */ 216 PTR_LA t9, mips_sram_init 217 jalr t9 218 nop 219#endif 220 221 /* Set up initial stack and global data */ 222 setup_stack_gd 223 224# ifdef CONFIG_DEBUG_UART 225 /* Earliest point to set up debug uart */ 226 PTR_LA t9, debug_uart_init 227 jalr t9 228 nop 229# endif 230#endif 231 232#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT) 233# ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD 234 /* Initialize any external memory */ 235 PTR_LA t9, lowlevel_init 236 jalr t9 237 nop 238# endif 239#endif 240 241#ifdef CONFIG_MIPS_MACH_EARLY_INIT 242 bal mips_mach_early_init 243 nop 244#endif 245 246#ifdef CONFIG_MIPS_CACHE_SETUP 247 /* Initialize caches... */ 248 PTR_LA t9, mips_cache_reset 249 jalr t9 250 nop 251#endif 252 253#if !CONFIG_IS_ENABLED(SKIP_LOWLEVEL_INIT) 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 260#endif 261 262#ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM 263 /* Set up initial stack and global data */ 264 setup_stack_gd 265 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 272#endif 273 274 move a0, zero # a0 <-- boot_flags = 0 275 PTR_LA t9, board_init_f 276 277 jr t9 278 move ra, zero 279 280 END(_start) 281