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 641: 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 76ENTRY(_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 */ 1241: b 1b 125 nop 126 127 .org 0x500 128#endif 129 130reset: 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 1431: mfc0 t0, CP0_DIAGNOSTIC, 3 144 and t0, t0, (1 << 31) 145#else 1461: 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 */ 1512: beqz t0, 4f 152 nop 1533: wait 154 b 3b 155 nop 156 157 /* 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 195 mtc0 zero, CP0_WATCHHI 196 197wr_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#ifndef CONFIG_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#ifndef CONFIG_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) 285