1/* ********************************************************************* 2 * P5064 Board Support Package 3 * 4 * CPU initialization File: rm5200_cpuinit.S 5 * 6 * This module contains code to initialize the CPU. 7 * 8 * Note: all the routines in this module rely on registers only, 9 * since DRAM may not be active yet. 10 * 11 * Author: Mitch Lichtenberg (mpl@broadcom.com) 12 * 13 ********************************************************************* 14 * 15 * Copyright 2000,2001,2002,2003 16 * Broadcom Corporation. All rights reserved. 17 * 18 * This software is furnished under license and may be used and 19 * copied only in accordance with the following terms and 20 * conditions. Subject to these conditions, you may download, 21 * copy, install, use, modify and distribute modified or unmodified 22 * copies of this software in source and/or binary form. No title 23 * or ownership is transferred hereby. 24 * 25 * 1) Any source code used, modified or distributed must reproduce 26 * and retain this copyright notice and list of conditions 27 * as they appear in the source file. 28 * 29 * 2) No right is granted to use any trade name, trademark, or 30 * logo of Broadcom Corporation. The "Broadcom Corporation" 31 * name may not be used to endorse or promote products derived 32 * from this software without the prior written permission of 33 * Broadcom Corporation. 34 * 35 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 36 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 37 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 38 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 39 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 40 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 41 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 42 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 43 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 44 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 45 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 46 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 47 * THE POSSIBILITY OF SUCH DAMAGE. 48 ********************************************************************* */ 49 50#include "sbmips.h" 51#include "bsp_config.h" 52#include "mipsmacros.h" 53#include "exception.h" 54 55 56 .text 57 .set mips64 58 59 60/* ********************************************************************* 61 * Macros 62 ********************************************************************* */ 63 64#define CFG_BE 0x00008000 /* Big Endian */ 65#define CFG_EPMASK 0x0f000000 /* Transmit data pattern */ 66#define CFG_EPD 0x00000000 /* D */ 67#define NTLBENTRIES 64 68 69/* 70 * Duplicates from cfe_iocb.h -- warning! 71 */ 72 73#define CFE_CACHE_FLUSH_D 1 74#define CFE_CACHE_INVAL_I 2 75#define CFE_CACHE_INVAL_D 4 76#define CFE_CACHE_INVAL_L2 8 77#define CFE_CACHE_FLUSH_L2 16 78 79/* ********************************************************************* 80 * Linkage tables 81 ********************************************************************* */ 82 83#define R_CPU_CP0INIT _TBLIDX(0) 84#define R_CPU_L1CINIT _TBLIDX(1) 85#define R_CPU_SETLEDS _TBLIDX(2) 86 87cpuinit_table: 88 _LONG_ rm5200_cp0_init # [ 0] R_CPU_CP0INIT 89 _LONG_ rm5200_l1cache_init # [ 1] R_CPU_L1CINIT 90 _LONG_ board_setleds # [ 2] R_CPU_SETLEDS 91 92#define SETLEDS1(a,b,c,d) \ 93 li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \ 94 CALLINIT_KSEG1(cpuinit_table,R_CPU_SETLEDS) 95#define SETLEDS(a,b,c,d) \ 96 li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \ 97 CALLINIT_KSEG0(cpuinit_table,R_CPU_SETLEDS) 98 99 100 101/* ********************************************************************* 102 * RM5200_CP0_INIT 103 * 104 * Initialize CP0 registers for an RM5200 core. 105 * 106 * Input parameters: 107 * nothing 108 * 109 * Return value: 110 * nothing 111 ********************************************************************* */ 112 113LEAF(rm5200_cp0_init) 114 115 /* 116 * Set SR and CAUSE to something sensible. 117 */ 118 119 .set noreorder 120 mfc0 t0,C0_PRID 121 mfc0 v0,C0_SR 122 mtc0 zero,C0_WATCHLO 123 mtc0 zero,C0_WATCHHI 124 li t1,-1 125 mtc0 t1,C0_COMPARE 126 and v0,M_SR_SR # preserve Soft Reset 127 or v0,M_SR_BEV # set Boot Exceptions 128 mtc0 zero,C0_CAUSE # Must clear WP before 129 mtc0 v0,C0_SR # writing STATUS register. 130 .set reorder 131 132 133 mfc0 t1,C0_CONFIG 134 135 mtc0 zero,C0_WATCHLO 136 mtc0 zero,C0_WATCHHI 137 138 /* 139 * make KSEG0 cacheable 140 */ 141 142 and t1,~M_CFG_K0COH 143 or t1,V_CFG_K0COH(K_CFG_K0COH_CACHEABLE) 144 145 /* 146 * set DDDD rate for CPUs that aren't hardware configured 147 */ 148 149 and t1,~CFG_EPMASK 150 or t1,CFG_EPD 151 152#ifdef __MIPSEB 153 or t1,CFG_BE 154#else 155 and t1,~CFG_BE 156#endif 157 mtc0 t1,C0_CONFIG 158 159 160 /* 161 * initialize tlb 162 */ 163 mtc0 zero,C0_TLBLO0 /* tlblo0 = invalid */ 164 mtc0 zero,C0_TLBLO1 /* tlblo1 = invalid */ 165 mtc0 zero,C0_PGMASK 166 li t8,K1BASE /* tlbhi = impossible vpn */ 167 li t9,(NTLBENTRIES-1) /* index */ 168 169 170 .set noreorder 171 nop 1721: mtc0 t8,C0_TLBHI 173 mtc0 t9,C0_INX 174 addu t8,0x2000 /* inc vpn */ 175 tlbwi 176 bnez t9,1b 177 subu t9,1 # BDSLOT 178 .set reorder 179 180 j ra 181 182END(rm5200_cp0_init) 183 184 185/* ********************************************************************* 186 * RM5200_NULL_INIT 187 * 188 * This stub routine is used by initialization functions that 189 * we leave unimplemented. 190 * 191 * Input parameters: 192 * nothing 193 * 194 * Return value: 195 * nothing 196 ********************************************************************* */ 197 198LEAF(rm5200_null_init) 199 j ra 200END(rm5200_null_init) 201 202 203 204/* ********************************************************************* 205 * RM5200_CPUINIT 206 * 207 * Initialize the CPU core. 208 * 209 * Input parameters: 210 * nothing 211 * 212 * Return value: 213 * nothing 214 ********************************************************************* */ 215 216LEAF(rm5200_cpuinit) 217 218 move k0,ra /* will be trashing RA */ 219 220 /* 221 * Basic CPU initialization 222 */ 223 224 CALLINIT_KSEG1(cpuinit_table,R_CPU_CP0INIT) 225 226 /* 227 * CP0 registers 228 */ 229 230 231#------------------------------------------------------------------------------ 232 233 /* 234 * Init the L1 cache. 235 */ 236 237#if CFG_INIT_L1 238 SETLEDS1('L','1','C','I') 239 CALLINIT_KSEG1(cpuinit_table,R_CPU_L1CINIT) 240#endif 241 242 /* 243 * There is no L2 cache. 244 */ 245 246 move ra,k0 /* saved return address */ 247 j ra 248 249 250END(rm5200_cpuinit) 251 252/* ********************************************************************* 253 * RM5200_CPURESTART 254 * 255 * 'Restart' the CPU (reset things back to some sane state after 256 * a program returns to the firmware) 257 * 258 * Input parameters: 259 * nothing 260 * 261 * Return value: 262 * nothing 263 ********************************************************************* */ 264 265LEAF(rm5200_cpurestart) 266 267 move k0,ra 268 269 CALLINIT_KSEG0(cpuinit_table,R_CPU_CP0INIT) 270 271 LR v0,cfe_pagetable # reestablish 272 dsll v0,v0,13 # see mips_arena.c for this 273 dmtc0 v0,C0_CTEXT # boot area TLBs 274 275 move ra,k0 276 j ra 277 278END(rm5200_cpurestart) 279 280 281LEAF(rm5200_cacheops) 282 283 move s0,ra 284 285 move v1,a0 286 287 /* 288 * With no flags, we flush L1D and invalid L1I 289 */ 290 291 bne v1,zero,1f 292 li v1,CFE_CACHE_FLUSH_D | CFE_CACHE_INVAL_I 2931: 294 295 /* 296 * Flush the D-Cache, since the program we loaded is "data". 297 */ 298 299 and a0,v1,CFE_CACHE_FLUSH_D 300 beq a0,zero,1f 301 jal rm5200_l1cache_flush_d 3021: 303 304 /* 305 * Invalidate the I-Cache, so that addresses in the program 306 * region will miss and need to be filled from the data we 307 * just flushed above. 308 */ 309 310 and a0,v1,CFE_CACHE_INVAL_I 311 beq a0,zero,1f 312 jal rm5200_l1cache_inval_i 3131: 314 315 316 move ra,s0 317 j ra 318 319END(rm5200_cacheops) 320 321/* ********************************************************************* 322 * RM5200_TLBHANDLER 323 * 324 * This is the TLB exception handler for the RM5200 325 * 326 * Note: only K0 and K1 are available to us at this time. 327 * 328 * Input parameters: 329 * nothing 330 * 331 * Return value: 332 * nothing 333 ********************************************************************* */ 334 335 336LEAF(rm5200_tlbhandler) 337 .set noreorder 338 .set noat 339 340/* 341 * This requires a bit of explanation: We only support 256KB 342 * of mapped space for the boot program. This space will be 343 * mapped from 0x2000_0000 to 0x2004_0000 to some physical 344 * memory allocated by the firmware. This is 64 pages 345 * of 4KB each. 346 * 347 * We know our BadVPN2 will be in the range 348 * 0x100000 to 0x1001F0, since the memory is mapped from 349 * 0x2000_0000 to 0x2004_0000. BadVPN2 plus the four bits 350 * of zeroes at the end are bits 31..9 351 * 352 * We also want to place the PTEbase on something other than 353 * a 16MB boundary. Each entry is 16 bytes, and there 354 * are 64 entries, so we need only 10 bits to address 355 * the entire table (it can therefore be aligned on a 356 * 1KB boundary). 357 * 358 * To make this work, we'll shift PTEbase to the right, leaving 359 * the bottom ten bits for the page number, as: 360 * 361 * Bits 31..10: PTEbase 362 * Bits 9..4: BadVPN 363 * Bits 3..0: 16 bytes for table entry 364 * 365 * Therefore: 366 * PTEbase gets shifted right 13 bits. 367 * BadVPN gets masked at 6 bits (mask is 0x3F0) 368 * The bottom 4 bits are zero. 369 * 370 * To range check the address, we can shift the Bad VPN 371 * right by 9 bits, and check for values of 0x1000 and 372 * 0x1001. 373 */ 374 375 376 /* 377 * This part range checks the VPN2 field in the 378 * context register. We only handle 379 * VPN2s in the range 0x100000 to 0x1001F0 380 */ 381 dmfc0 k0,C0_TLBHI 382 383 dmfc0 k0,C0_CTEXT # Get context 384 dsra k0,8 # keep hi part 385 and k0,0x1FFF # of VPN2 386 li k1,0x1000 # 0x1000 is ok 387 beq k0,k1,1f # 388 nop # BDSLOT 389 li k1,0x1001 # 0x1001 is ok 390 beq k0,k1,1f # 391 nop # BDSLOT 392 393 li k0,XTYPE_TLBFILL # all other bits are not 394 j _exc_entry 395 nop # BDSLOT 396 3971: dmfc0 k0,C0_CTEXT # Get context 398 dsra k0,13 # Shift PTEbase 399 li k1,0x3FF # Generate mask to kill 400 not k1 # BadVPN2 bits 401 and k0,k1 # keep only PTEBase part. 402 403 dmfc0 k1,C0_CTEXT # Get Context 404 and k1,0x3F0 # Keep only BadVPN2 bits 405 or k1,k0 # Replace PTEBase 406 407 ld k0,0(k1) # Load entrylo0 408 ld k1,8(k1) # Load entrylo1 409 mtc0 k0,C0_TLBLO0 # and write to CP0 410 mtc0 k1,C0_TLBLO1 411 tlbwr # put it in the TLB 412 eret 413 nop 414 415 .set reorder 416 .set at 417 418END(rm5200_tlbhandler) 419 420/* ********************************************************************* 421 * End 422 ********************************************************************* */ 423