1/* ********************************************************************* 2 * SB1250 Board Support Package 3 * 4 * CPU initialization File: sb1250_cpu.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 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 "cpu_config.h" 53#include "mipsmacros.h" 54#include "exception.h" 55 56#include "sb1250_regs.h" 57#include "sb1250_scd.h" 58 59 60 .text 61 .set mips64 62 63 .extern _exc_entry 64 65 66/* ********************************************************************* 67 * Macros 68 ********************************************************************* */ 69 70/* 71 * Duplicates from cfe_iocb.h -- warning! 72 */ 73 74#define CFE_CACHE_FLUSH_D 1 75#define CFE_CACHE_INVAL_I 2 76#define CFE_CACHE_INVAL_D 4 77#define CFE_CACHE_INVAL_L2 8 78#define CFE_CACHE_FLUSH_L2 16 79#define CFE_CACHE_INVAL_RANGE 32 80#define CFE_CACHE_FLUSH_RANGE 64 81 82#define L1CACHE_NUMWAYS 4 83#define L1CACHE_NUMIDX 256 84#define L1CACHE_LINESIZE 32 85#define L1CACHE_IDXHIGH (L1CACHE_LINESIZE*L1CACHE_NUMWAYS*L1CACHE_NUMIDX) 86 87#define L1CACHEOP(cachename,op) ((cachename) | ((op) << 2)) 88 89#define L1C_OP_IDXINVAL 0 90#define L1C_OP_IDXLOADTAG 1 91#define L1C_OP_IDXSTORETAG 2 92#define L1C_OP_IMPLRSVD 3 93#define L1C_OP_HITINVAL 4 94#define L1C_OP_FILL 5 95#define L1C_OP_HITWRITEBACK 6 96#define L1C_OP_FETCHLOCK 7 97 98#define L1C_I 0 99#define L1C_D 1 100 101 102/* ********************************************************************* 103 * LED macros 104 ********************************************************************* */ 105 106#define SETLEDS1(a,b,c,d) \ 107 li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \ 108 JAL_KSEG1(board_setleds) 109#define SETLEDS(a,b,c,d) \ 110 li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \ 111 JAL_KSEG1(board_setleds) 112 113 114 115/* ********************************************************************* 116 * SB1250_CPUINIT 117 * 118 * Initialize the CPU core. 119 * 120 * Input parameters: 121 * nothing 122 * 123 * Return value: 124 * nothing 125 ********************************************************************* */ 126 127LEAF(sb1250_cpuinit) 128 129 move k0,ra /* will be trashing RA */ 130 131 132 /* 133 * Clear the SOFTRES bit in the SYSTEM_CONFIG register. 134 */ 135 136 li t0,PHYS_TO_K1(A_SCD_SYSTEM_CFG) 137 ld t1,0(t0) 138 dli t2,~M_SYS_SB_SOFTRES 139 and t1,t1,t2 140 sd t1,0(t0) 141 142 143 /* 144 * Note that the initialization order here is important. 145 * In particular, the cache needs to be running before 146 * DRAM is turned on, since the DRAM init code is 147 * in cacheable space. This code assumes that we are 148 * linked at KSEG0's address but are executed starting 149 * in KSEG1. Therefore, we need to be somewhat careful 150 * until the cache is alive to call routines 151 * making sure we are calling in KSEG1. 152 */ 153 154 JAL_KSEG1(sb1_cpu_init) 155 156 157#ifdef _SB1250_PASS1_WORKAROUNDS_ 158 /* 159 * Note: We initially set the coherency attribute 160 * to just "cacheable" since we want to avoid problems 161 * with coherency when Generic Bus (KSEG1) addresses are involved. 162 * This is a pass-1 workaround, as in pass-1 the bridge can 163 * respond again (after the CPU has already responded) 164 * to a cacheable read, causing the cache to get wrong data. 165 * 166 * Once you are not using the generic bus for data anymore, 167 * it is safe to switch to coherent. 168 */ 169 170 SETCCAMODE(v0,K_CFG_K0COH_CACHEABLE) /* cacheable NONCOHERENT */ 171#endif 172 173#------------------------------------------------------------------------------ 174 175 /* 176 * Init the L1 cache. 177 */ 178 179#if CFG_INIT_L1 180 SETLEDS1('L','1','C','I') 181 JAL_KSEG1(sb1250_l1cache_init) 182#endif 183 184 /* 185 * Init the L2 cache. We don't init L2 on 186 * secondary CPU(s), since they are shared by all CPUs. We'll 187 * do it here on CPU0. 188 */ 189 190#if CFG_INIT_L2 191 SETLEDS1('L','2','C','I') 192 JAL_KSEG1(sb1250_l2cache_init) 193#endif 194 195 move ra,k0 /* saved return address */ 196 j ra 197 198 199END(sb1250_cpuinit) 200 201/* ********************************************************************* 202 * SB1250_CPURESTART 203 * 204 * 'Restart' the CPU (reset things back to some sane state after 205 * a program returns to the firmware) 206 * 207 * Input parameters: 208 * nothing 209 * 210 * Return value: 211 * nothing 212 ********************************************************************* */ 213 214#ifndef _ZIPSTART_ 215LEAF(sb1250_cpurestart) 216 217 move k0,ra 218 219 JAL(sb1_cp0_init) 220 221 LR v0,cfe_pagetable # reestablish 222 dsll v0,v0,13 # see mips_arena.c for this 223 dmtc0 v0,C0_CTEXT # boot area TLBs 224 225 move ra,k0 226 j ra 227 228END(sb1250_cpurestart) 229#endif 230 231 232/* ********************************************************************* 233 * SB1250_CACHEOPS 234 * 235 * This routine handles the various cache-related functions 236 * needed by CFE. 237 * 238 * Input parameters: 239 * a0 - cache functions (bit mask) 240 * 241 * Return value: 242 * nothing 243 * 244 * Registers used: 245 * trashes t0..t7, a0, v0 (especially for L2) 246 ********************************************************************* */ 247 248LEAF(sb1250_cacheops) 249 250 move s0,ra 251 252 move v1,a0 253 254 /* 255 * With no flags, we flush L1D and invalid L1I 256 */ 257 258 bne v1,zero,1f 259 li v1,CFE_CACHE_FLUSH_D | CFE_CACHE_INVAL_I 2601: 261 262 /* 263 * Flush the D-Cache, since the program we loaded is "data". 264 */ 265 266 and a0,v1,CFE_CACHE_FLUSH_D 267 beq a0,zero,1f 268 JAL(sb1250_l1cache_flush_d) 2691: 270 271 /* 272 * Invalidate the I-Cache, so that addresses in the program 273 * region will miss and need to be filled from the data we 274 * just flushed above. 275 */ 276 277 and a0,v1,CFE_CACHE_INVAL_I 278 beq a0,zero,1f 279 JAL(sb1250_l1cache_inval_i) 2801: 281 282 /* 283 * Invalidate the L2, if requested. Use this cautiously, 284 * since it invalidates both I and D! 285 */ 286 287 and a0,v1,CFE_CACHE_INVAL_L2 288 beq a0,zero,1f 289 JAL(sb1250_l2cache_init) 2901: 291 292 293 /* 294 * Invalidate cache range 295 */ 296 297 and a0,v1,CFE_CACHE_INVAL_RANGE 298 beq a0,zero,2f 299 300 move t0,a1 3011: cache L1CACHEOP(L1C_D,L1C_OP_HITINVAL),0(t0) 302 add t0,L1CACHE_LINESIZE 303 blt t0,a2,1b 304 305 /* 306 * Flush cache range 307 */ 308 309 3102: 311 and a0,v1,CFE_CACHE_FLUSH_RANGE 312 beq a0,zero,2f 313 314 move t0,a1 3151: cache L1CACHEOP(L1C_D,L1C_OP_HITWRITEBACK),0(t0) 316 add t0,L1CACHE_LINESIZE 317 blt t0,a2,1b 318 3192: 320 321 /* 322 * Invalidate the L2, if requested. Use this cautiously, 323 * since it invalidates both I and D! 324 */ 325 326 and a0,v1,CFE_CACHE_FLUSH_L2 327 beq a0,zero,1f 328 JAL(sb1250_l2cache_flush) /* Trashes T0..T7, V0, A0 */ 3291: 330 331 move ra,s0 332 j ra 333 334END(sb1250_cacheops) 335 336 337/* ********************************************************************* 338 * SB1250_TLBHANDLER 339 * 340 * This is the TLB exception handler for the SB1250. 341 * 342 * Note: only K0 and K1 are available to us at this time. 343 * 344 * Input parameters: 345 * nothing 346 * 347 * Return value: 348 * nothing 349 ********************************************************************* */ 350 351 352LEAF(sb1250_tlbhandler) 353 .set noreorder 354 .set noat 355 356/* 357 * This requires a bit of explanation: We only support 256KB 358 * of mapped space for the boot program. This space will be 359 * mapped from 0x2000_0000 to 0x2004_0000 to some physical 360 * memory allocated by the firmware. This is 64 pages 361 * of 4KB each. 362 * 363 * We know our BadVPN2 will be in the range 364 * 0x100000 to 0x1001F0, since the memory is mapped from 365 * 0x2000_0000 to 0x2004_0000. BadVPN2 plus the four bits 366 * of zeroes at the end are bits 31..9 367 * 368 * We also want to place the PTEbase on something other than 369 * a 16MB boundary. Each entry is 16 bytes, and there 370 * are 64 entries, so we need only 10 bits to address 371 * the entire table (it can therefore be aligned on a 372 * 1KB boundary). 373 * 374 * To make this work, we'll shift PTEbase to the right, leaving 375 * the bottom ten bits for the page number, as: 376 * 377 * Bits 31..10: PTEbase 378 * Bits 9..4: BadVPN 379 * Bits 3..0: 16 bytes for table entry 380 * 381 * Therefore: 382 * PTEbase gets shifted right 13 bits. 383 * BadVPN gets masked at 6 bits (mask is 0x3F0) 384 * The bottom 4 bits are zero. 385 * 386 * To range check the address, we can shift the Bad VPN 387 * right by 9 bits, and check for values of 0x1000 and 388 * 0x1001. 389 */ 390 391 392 /* 393 * This part range checks the VPN2 field in the 394 * context register. We only handle 395 * VPN2s in the range 0x100000 to 0x1001F0 396 */ 397 dmfc0 k0,C0_TLBHI 398 399 dmfc0 k0,C0_CTEXT # Get context 400 dsra k0,8 # keep hi part 401 and k0,0x1FFF # of VPN2 402 li k1,0x1000 # 0x1000 is ok 403 beq k0,k1,1f # 404 nop # BDSLOT 405 li k1,0x1001 # 0x1001 is ok 406 beq k0,k1,1f # 407 nop # BDSLOT 408 409 li k0,XTYPE_TLBFILL # all other bits are not 410 JMP(_exc_entry) 411 nop # BDSLOT 412 4131: dmfc0 k0,C0_CTEXT # Get context 414 dsra k0,13 # Shift PTEbase 415 li k1,0x3FF # Generate mask to kill 416 not k1 # BadVPN2 bits 417 and k0,k1 # keep only PTEBase part. 418 419 dmfc0 k1,C0_CTEXT # Get Context 420 and k1,0x3F0 # Keep only BadVPN2 bits 421 or k1,k0 # Replace PTEBase 422 423 ld k0,0(k1) # Load entrylo0 424 ld k1,8(k1) # Load entrylo1 425 mtc0 k0,C0_TLBLO0 # and write to CP0 426 mtc0 k1,C0_TLBLO1 427 tlbwr # put it in the TLB 428 eret 429 nop 430 431 .set reorder 432 .set at 433 434END(sb1250_tlbhandler) 435 436/* ********************************************************************* 437 * sb1250_cerrhandler 438 * 439 * Cache error handler. We get called here on a cache error 440 * exception. Registers k0, k1, gp, and sp have been saved 441 * for us. We are running uncached, with ERL set, so kuseg 442 * is mapped into uncached memory. 443 * 444 * Input parameters: 445 * nothing 446 * 447 * Return value: 448 * nothing 449 ********************************************************************* */ 450 451LEAF(sb1250_cerrhandler) 452 453 mfc0 k0, $26 454 bgez k0, real_cerr 455 456 mtc0 zero, $26 457 mtc0 zero, $27 458 mtc0 zero, $27, 1 459 mtc0 zero, $27, 3 460 eret 461 462real_cerr: SETLEDS1('C','e','r','r') 463 4641: b 1b /* death */ 465 466END(sb1250_cerrhandler) 467 468 469/* ********************************************************************* 470 * End 471 ********************************************************************* */ 472 473 474