1/* ********************************************************************* 2 * SB1250 Board Support Package 3 * 4 * Exception Handler File: exception.S 5 * 6 * Author: Mitch Lichtenberg 7 * 8 ********************************************************************* 9 * 10 * Copyright 2000,2001,2002,2003 11 * Broadcom Corporation. All rights reserved. 12 * 13 * This software is furnished under license and may be used and 14 * copied only in accordance with the following terms and 15 * conditions. Subject to these conditions, you may download, 16 * copy, install, use, modify and distribute modified or unmodified 17 * copies of this software in source and/or binary form. No title 18 * or ownership is transferred hereby. 19 * 20 * 1) Any source code used, modified or distributed must reproduce 21 * and retain this copyright notice and list of conditions 22 * as they appear in the source file. 23 * 24 * 2) No right is granted to use any trade name, trademark, or 25 * logo of Broadcom Corporation. The "Broadcom Corporation" 26 * name may not be used to endorse or promote products derived 27 * from this software without the prior written permission of 28 * Broadcom Corporation. 29 * 30 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 31 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 32 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 33 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 34 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 35 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 36 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 38 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 39 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 40 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 41 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 42 * THE POSSIBILITY OF SUCH DAMAGE. 43 ********************************************************************* */ 44 45 46#include "sbmips.h" 47#include "cpu_config.h" /* for definition of HAZARD and ERET */ 48#include "exception.h" 49#include "bsp_config.h" 50#include "mipsmacros.h" 51 52/* ********************************************************************* 53 * Check some stuff 54 ********************************************************************* */ 55 56#if ((CPUCFG_REGS32+CPUCFG_REGS64) != 1) 57#error "You must define exactly ONE of CPUCFG_REGS32,CPUCFG_REGS64 in cpu_config.h" 58#endif 59 60 61/* ********************************************************************* 62 * Data 63 ********************************************************************* */ 64 65 .sdata 66 67 .globl _exc_vectab 68_exc_vectab: _LONG_ 0 # XTYPE_RESET 69 _LONG_ 0 # XTYPE_TLBFILL (not used) 70 _LONG_ 0 # XTYPE_XTLBFILL 71 _LONG_ 0 # XTYPE_CACHEERR (not used) 72 _LONG_ 0 # XTYPE_EXCEPTION 73 _LONG_ 0 # XTYPE_INTERRUPT 74 _LONG_ 0 # XTYPE_EJTAG 75 76/* ********************************************************************* 77 * Common Data 78 ********************************************************************* */ 79 80 .bss 81 82 83/* ********************************************************************* 84 * Code 85 ********************************************************************* */ 86 87 .text 88 89#define R_EXC_CERR_TEMPLATE _TBLIDX(0) 90#define R_EXC_CERR_TEMPLATE_END _TBLIDX(1) 91 92 .globl _exc_cerr_htable 93_exc_cerr_htable: 94 _LONG_ _exc_cerr_template 95 _LONG_ _exc_cerr_template_end 96 97 98/* ********************************************************************* 99 * _exc_cerr_template 100 * 101 * This is a template routine for our cache error handler. 102 * We save a couple of registers in our magic save area, then 103 * dispatch to code elsewhere in CFE. 104 * 105 * This code is copied right to the vector address, so it has 106 * to be kept tiny! 107 * 108 * Input parameters: 109 * nothing - running uncached, all registers trashed 110 * 111 * Return value: 112 * might return, might not 113 ********************************************************************* */ 114 115LEAF(_exc_cerr_template) 116 117 /* 118 * Magic! When the cache error handler is running, 119 * we are in a very special state, running uncached 120 * and with translations turned off. We can use offsets 121 * from r0(zero) to store registers we need to use 122 * during the error handler. 123 */ 124 125 .set push ; .set noreorder 126 127 SR k0,CFE_LOCORE_GLOBAL_K0TMP(zero) 128 SR k1,CFE_LOCORE_GLOBAL_K1TMP(zero) 129 SR ra,CFE_LOCORE_GLOBAL_RATMP(zero) 130 SR gp,CFE_LOCORE_GLOBAL_GPTMP(zero) 131 132 LR k0,CFE_LOCORE_GLOBAL_CERRH(zero) 133 jalr k0 134 nop 135 136 LR k0,CFE_LOCORE_GLOBAL_K0TMP(zero) 137 LR k1,CFE_LOCORE_GLOBAL_K1TMP(zero) 138 LR ra,CFE_LOCORE_GLOBAL_RATMP(zero) 139 LR gp,CFE_LOCORE_GLOBAL_GPTMP(zero) 140 ERET 141 142 .set pop 143 144 /* 145 * Note: make sure this routine does not exceed 128 bytes 146 */ 147 148_exc_cerr_template_end: 149 150END(_exc_cerr_template) 151 152/* ********************************************************************* 153 * _exc_setup_locore(cerrh) 154 * 155 * Set global data into the low-memory region. We do this in 156 * assembly language so it's easier to deal with the 32-bit/64-bit 157 * issues that arise in the "C" code. 158 * 159 * Input parameters: 160 * a0 - cache error handler 161 * 162 * Return value: 163 * nothing 164 ********************************************************************* */ 165 166LEAF(_exc_setup_locore) 167 168 move t4,ra 169 170 /* 171 * Save GP for easy re-use, using uncached writes. 172 */ 173 174 li t0,PHYS_TO_K1(CFE_LOCORE_GLOBAL_GP) 175 SR gp,0(t0) 176 177 /* 178 * Initialize cache error handler pointer. Make it 179 * uncached, since cache error handlers should not 180 * touch the cache. 181 */ 182 183 li t1,(K0SIZE-1) 184 and a0,a0,t1 # keep just physical part 185 li t1,K1BASE 186 or a0,a0,t1 # make into an uncached address 187 188 li t0,PHYS_TO_K1(CFE_LOCORE_GLOBAL_CERRH) 189 SR a0,0(t0) 190 191 /* 192 * Move the cache error handler into low RAM. 193 */ 194 195 li t0,PHYS_TO_K1(MIPS_RAM_VEC_CACHEERR) 196 197 la t1,_exc_cerr_htable 198 LR t2,R_EXC_CERR_TEMPLATE_END(t1) 199 LR t1,R_EXC_CERR_TEMPLATE(t1) 200 2011: lw t3,0(t1) # get a word 202 sw t3,0(t0) # write a word 203 ADD t0,4 # next word... 204 ADD t1,4 205 blt t1,t2,1b # till done 206 207 /* 208 * Now do the whole thing again, but with cached writes. 209 * Writing uncached makes sure the data is actually in memory, 210 * and writing cached makes sure we write the same 211 * stuff again when the cache is evicted. 212 * This way we don't have to bother with cacheops, 213 * a bonus on the BCM1250 with its funky L2. 214 */ 215 216 li t0,PHYS_TO_K0(CFE_LOCORE_GLOBAL_GP) 217 SR gp,0(t0) 218 219 li t0,PHYS_TO_K0(CFE_LOCORE_GLOBAL_CERRH) 220 SR a0,0(t0) 221 222 li t0,PHYS_TO_K0(MIPS_RAM_VEC_CACHEERR) 223 224 la t1,_exc_cerr_htable 225 LR t2,R_EXC_CERR_TEMPLATE_END(t1) 226 LR t1,R_EXC_CERR_TEMPLATE(t1) 227 2281: lw t3,0(t1) # get a word 229 sw t3,0(t0) # write a word 230 ADD t0,4 # next word... 231 ADD t1,4 232 blt t1,t2,1b # till done 233 234 235 /* 236 * done! 237 */ 238 239 move ra,t4 240 j ra 241 242END(_exc_setup_locore) 243 244 245 246 247/* ********************************************************************* 248 * _exc_setvector(xtype,addr) 249 * 250 * Set an exception vector address 251 * 252 * Input parameters: 253 * xtype - exception vector type 254 * addr - routine address 255 * 256 * Return value: 257 * nothing 258 ********************************************************************* */ 259 260LEAF(_exc_setvector) 261 262 la v0,_exc_vectab 263 srl a0,3 /* convert 8-byte index to array index */ 264 sll a0,BPWSIZE /* convert back to index appropriate for word size */ 265 add v0,a0 266 SR a1,(v0) 267 j ra 268 269END(_exc_setvector) 270 271 272/* ********************************************************************* 273 * _exc_crash_sim() 274 * 275 * Crash the GDB simulator, causing it to exit. 276 * 277 * Input parameters: 278 * nothing 279 * 280 * Return value: 281 * nothing - does not return 282 ********************************************************************* */ 283 284 285LEAF(_exc_crash_sim) 286 287 li $2,1 288 li $3,0xdead 289 li $4,0 290 syscall 0xca 2911: b 1b 292 293END(_exc_crash_sim) 294 295 296/* ********************************************************************* 297 * _exc_cache_crash_sim() 298 * 299 * As _exc_crash_sim, but distinguish cache error exception. 300 * 301 * Input parameters: 302 * nothing 303 * 304 * Return value: 305 * nothing - does not return 306 ********************************************************************* */ 307 308 309LEAF(_exc_cache_crash_sim) 310 311 li $2,1 312 li $3,0xbadc 313 li $4,0 314 syscall 0xca 3151: b 1b 316 317END(_exc_cache_crash_sim) 318 319 320/* ********************************************************************* 321 * _exc_restart() 322 * 323 * Restart the firmware at the boot address 324 * 325 * Input parameters: 326 * nothing 327 * 328 * Return value: 329 * nothing 330 ********************************************************************* */ 331 332LEAF(_exc_restart) 333 334 li t0,0xBFC00000 # ROM restart vector 335 jr t0 336 337END(_exc_restart) 338 339/* ********************************************************************* 340 * _exc_entry(k0) 341 * 342 * Main exception entry point. 343 * 344 * Input parameters: 345 * k0 - exception type 346 * 347 * Return value: 348 * ... 349 ********************************************************************* */ 350 351LEAF(_exc_entry) 352 353 .set noreorder 354 .set noat 355 356 subu k1,sp,EXCEPTION_SIZE 357 SRL k1,3 358 SLL k1,3 359 360 SREG zero,XGR_ZERO(k1) 361 SREG AT,XGR_AT(k1) 362 363 SREG v0,XGR_V0(k1) 364 SREG v1,XGR_V1(k1) 365 366 SREG a0,XGR_A0(k1) 367 SREG a1,XGR_A1(k1) 368 SREG a2,XGR_A2(k1) 369 SREG a3,XGR_A3(k1) 370 371 SREG t0,XGR_T0(k1) 372 SREG t1,XGR_T1(k1) 373 SREG t2,XGR_T2(k1) 374 SREG t3,XGR_T3(k1) 375 SREG t4,XGR_T4(k1) 376 SREG t5,XGR_T5(k1) 377 SREG t6,XGR_T6(k1) 378 SREG t7,XGR_T7(k1) 379 380 SREG s0,XGR_S0(k1) 381 SREG s1,XGR_S1(k1) 382 SREG s2,XGR_S2(k1) 383 SREG s3,XGR_S3(k1) 384 SREG s4,XGR_S4(k1) 385 SREG s5,XGR_S5(k1) 386 SREG s6,XGR_S6(k1) 387 SREG s7,XGR_S7(k1) 388 389 SREG t8,XGR_T8(k1) 390 SREG t9,XGR_T9(k1) 391 392 SREG gp,XGR_GP(k1) 393 SREG sp,XGR_SP(k1) 394 SREG fp,XGR_FP(k1) 395 SREG ra,XGR_RA(k1) 396 397 mfc0 t0,C0_CAUSE 398 mfc0 t1,C0_SR 399 MFC0 t2,C0_BADVADDR 400 MFC0 t3,C0_EPC 401 mfc0 t4,C0_PRID 402 mflo t5 403 mfhi t6 404 SREG t0,XCP0_CAUSE(k1) 405 SREG t1,XCP0_SR(k1) 406 SREG t2,XCP0_VADDR(k1) 407 SREG t3,XCP0_EPC(k1) 408 SREG t4,XCP0_PRID(k1) 409 SREG t5,XGR_LO(k1) 410 SREG t6,XGR_HI(k1) 411 412#if (CFG_RELOC) 413 la gp,PHYS_TO_K0(CFE_LOCORE_GLOBAL_GP) 414 LR gp,0(gp) # get our GP handle from low memory vector 415#else 416 la gp,_gp # Load up GP, not relocated so it's easy 417#endif 418 419 move a0,k0 # Pass exception type 420 move a1,k1 # Pass frame to exception handler 421 la t0,_exc_vectab # get base of exception vectors 422 srl k0,3 # convert 8-byte index to array index 423 sll k0,BPWSIZE # convert back to index appropriate for word size 424 addu t0,k0 # get vector address 425 LR t9,(t0) # to call handler 426 427 move sp,k1 # "C" gets fresh stack area 428 429 jalr t9 # Call exception handler 430 nop # use reg 't9' for SVR4 compat 431 432 move k1, sp 433 LREG AT,XGR_AT(k1) 434 435 LREG t0,XGR_LO(k1) 436 LREG t1,XGR_HI(k1) 437 mtlo t0 438 mthi t1 439 440 LREG a0,XGR_A0(k1) 441 LREG a1,XGR_A1(k1) 442 LREG a2,XGR_A2(k1) 443 LREG a3,XGR_A3(k1) 444 445 LREG t0,XGR_T0(k1) 446 LREG t1,XGR_T1(k1) 447 LREG t2,XGR_T2(k1) 448 LREG t3,XGR_T3(k1) 449 LREG t4,XGR_T4(k1) 450 LREG t5,XGR_T5(k1) 451 LREG t6,XGR_T6(k1) 452 LREG t7,XGR_T7(k1) 453 454 LREG s0,XGR_S0(k1) 455 LREG s1,XGR_S1(k1) 456 LREG s2,XGR_S2(k1) 457 LREG s3,XGR_S3(k1) 458 LREG s4,XGR_S4(k1) 459 LREG s5,XGR_S5(k1) 460 LREG s6,XGR_S6(k1) 461 LREG s7,XGR_S7(k1) 462 463 LREG t8,XGR_T8(k1) 464 LREG t9,XGR_T9(k1) 465 466 LREG gp,XGR_GP(k1) 467 LREG sp,XGR_SP(k1) 468 LREG fp,XGR_FP(k1) 469 LREG ra,XGR_RA(k1) 470 471/* do any CP0 cleanup here */ 472 473 LREG v0,XGR_V0(k1) 474 LREG v1,XGR_V1(k1) 475 476 ERET 477 478 .set at 479 .set reorder 480 481 482END(_exc_entry) 483 484 485/* ********************************************************************* 486 * _exc_clear_sr_exl() 487 * 488 * Clear SR(EXL) and return to caller. 489 * 490 * Input parameters: 491 * nothing 492 * 493 * Return value: 494 * nothing 495 ********************************************************************* */ 496 497LEAF(_exc_clear_sr_exl) 498 499 mfc0 t0,C0_SR 500 and t0,t0,~(0x02) # clear SR(EXL). Bit 1 501 mtc0 t0,C0_SR 502 503 HAZARD 504 505 j ra 506 507END(_exc_clear_sr_exl) 508 509/* ********************************************************************* 510 * _exc_clear_sr_erl() 511 * 512 * Clear SR(ERL) and return to caller. 513 * 514 * Input parameters: 515 * nothing 516 * 517 * Return value: 518 * nothing 519 ********************************************************************* */ 520 521LEAF(_exc_clear_sr_erl) 522 523 mfc0 t0,C0_SR 524 and t0,t0,~(0x04) # clear SR(ERL). Bit 2 525 mtc0 t0,C0_SR 526 527 HAZARD 528 529 j ra 530 531END(_exc_clear_sr_erl) 532 533 534/* ********************************************************************* 535 * End 536 ********************************************************************* */ 537 538 539