1/* ********************************************************************* 2 * SB1250 Board Support Package 3 * 4 * Exception Handler File: exception.S 5 * 6 * Author: Mitch Lichtenberg (mpl@broadcom.com) 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 "exception.h" 48#include "mipsmacros.h" 49#include "cpu_config.h" /* for definition of HAZARD and ERET */ 50#include "bsp_config.h" 51 52/* ********************************************************************* 53 * Macros 54 ********************************************************************* */ 55 56#ifdef _MIPSREGS32_ 57#define LREG lw 58#define SREG sw 59#define SRL srl 60#define SLL sll 61#else 62#define LREG ld 63#define SREG sd 64#define SRL dsrl 65#define SLL dsll 66#endif 67 68 69/* ********************************************************************* 70 * Data 71 ********************************************************************* */ 72 73 .sdata 74 75 .globl _exc_vectab 76_exc_vectab: _LONG_ 0 # XTYPE_RESET 77 _LONG_ 0 # XTYPE_TLBFILL (not used) 78 _LONG_ 0 # XTYPE_XTLBFILL 79 _LONG_ 0 # XTYPE_CACHEERR (not used) 80 _LONG_ 0 # XTYPE_EXCEPTION 81 _LONG_ 0 # XTYPE_INTERRUPT 82 _LONG_ 0 # XTYPE_EJTAG 83 84/* ********************************************************************* 85 * Common Data 86 ********************************************************************* */ 87 88 .bss 89 90 91/* ********************************************************************* 92 * Code 93 ********************************************************************* */ 94 95 .text 96 97#define R_EXC_CERR_TEMPLATE _TBLIDX(0) 98#define R_EXC_CERR_TEMPLATE_END _TBLIDX(1) 99 100 .globl _exc_cerr_htable 101_exc_cerr_htable: 102 _LONG_ _exc_cerr_template 103 _LONG_ _exc_cerr_template_end 104 105 106/* ********************************************************************* 107 * _exc_cerr_template 108 * 109 * This is a template routine for our cache error handler. 110 * We save a couple of registers in our magic save area, then 111 * dispatch to code elsewhere in CFE. 112 * 113 * This code is copied right to the vector address, so it has 114 * to be kept tiny! 115 * 116 * Input parameters: 117 * nothing - running uncached, all registers trashed 118 * 119 * Return value: 120 * might return, might not 121 ********************************************************************* */ 122 123LEAF(_exc_cerr_template) 124 125 /* 126 * Magic! When the cache error handler is running, 127 * we are in a very special state, running uncached 128 * and with translations turned off. We can use offsets 129 * from r0(zero) to store registers we need to use 130 * during the error handler. 131 */ 132 133 .set push ; .set noreorder 134 135 SR k0,CFE_LOCORE_GLOBAL_K0TMP(zero) 136 SR k1,CFE_LOCORE_GLOBAL_K1TMP(zero) 137 SR ra,CFE_LOCORE_GLOBAL_RATMP(zero) 138 SR gp,CFE_LOCORE_GLOBAL_GPTMP(zero) 139 140 LR k0,CFE_LOCORE_GLOBAL_CERRH(zero) 141 jal k0 142 nop 143 144 LR k0,CFE_LOCORE_GLOBAL_K0TMP(zero) 145 LR k1,CFE_LOCORE_GLOBAL_K1TMP(zero) 146 LR ra,CFE_LOCORE_GLOBAL_RATMP(zero) 147 LR gp,CFE_LOCORE_GLOBAL_GPTMP(zero) 148 ERET 149 150 .set pop 151 152 /* 153 * Note: make sure this routine does not exceed 128 bytes 154 */ 155 156_exc_cerr_template_end: 157 158END(_exc_cerr_template) 159 160/* ********************************************************************* 161 * _exc_setup_locore(cerrh) 162 * 163 * Set global data into the low-memory region. We do this in 164 * assembly language so it's easier to deal with the 32-bit/64-bit 165 * issues that arise in the "C" code. 166 * 167 * Input parameters: 168 * a0 - cache error handler 169 * 170 * Return value: 171 * nothing 172 ********************************************************************* */ 173 174LEAF(_exc_setup_locore) 175 176 move t4,ra 177 178 /* 179 * Save GP for easy re-use, using uncached writes. 180 */ 181 182 li t0,PHYS_TO_K1(CFE_LOCORE_GLOBAL_GP) 183 SR gp,0(t0) 184 185 /* 186 * Initialize cache error handler pointer. Make it 187 * uncached, since cache error handlers should not 188 * touch the cache. 189 */ 190 191 li t1,(K0SIZE-1) 192 and a0,a0,t1 # keep just physical part 193 li t1,K1BASE 194 or a0,a0,t1 # make into an uncached address 195 196 li t0,PHYS_TO_K1(CFE_LOCORE_GLOBAL_CERRH) 197 SR a0,0(t0) 198 199 /* 200 * Move the cache error handler into low RAM. 201 */ 202 203 li t0,PHYS_TO_K1(MIPS_RAM_VEC_CACHEERR) 204 205 LOADREL(t1,_exc_cerr_htable) 206 LR t2,R_EXC_CERR_TEMPLATE_END(t1) 207 LR t1,R_EXC_CERR_TEMPLATE(t1) 208 2091: lw t3,0(t1) # get a word 210 sw t3,0(t0) # write a word 211 ADD t0,4 # next word... 212 ADD t1,4 213 blt t1,t2,1b # till done 214 215 /* 216 * Now do the whole thing again, but with cached writes. 217 * Writing uncached makes sure the data is actually in memory, 218 * and writing cached makes sure we write the same 219 * stuff again when the cache is evicted. 220 * This way we don't have to bother with cacheops, 221 * a bonus on the BCM1250 with its funky L2. 222 */ 223 224 li t0,PHYS_TO_K0(CFE_LOCORE_GLOBAL_GP) 225 SR gp,0(t0) 226 227 li t0,PHYS_TO_K0(CFE_LOCORE_GLOBAL_CERRH) 228 SR a0,0(t0) 229 230 li t0,PHYS_TO_K0(MIPS_RAM_VEC_CACHEERR) 231 232 LOADREL(t1,_exc_cerr_htable) 233 LR t2,R_EXC_CERR_TEMPLATE_END(t1) 234 LR t1,R_EXC_CERR_TEMPLATE(t1) 235 2361: lw t3,0(t1) # get a word 237 sw t3,0(t0) # write a word 238 ADD t0,4 # next word... 239 ADD t1,4 240 blt t1,t2,1b # till done 241 242 243 /* 244 * done! 245 */ 246 247 move ra,t4 248 j ra 249 250END(_exc_setup_locore) 251 252 253 254 255/* ********************************************************************* 256 * _exc_setvector(xtype,addr) 257 * 258 * Set an exception vector address 259 * 260 * Input parameters: 261 * xtype - exception vector type 262 * addr - routine address 263 * 264 * Return value: 265 * nothing 266 ********************************************************************* */ 267 268LEAF(_exc_setvector) 269 270 la v0,_exc_vectab 271 srl a0,3 /* convert 8-byte index to array index */ 272 sll a0,BPWSIZE /* convert back to index appropriate for word size */ 273 add v0,a0 274 SR a1,(v0) 275 j ra 276 277END(_exc_setvector) 278 279 280/* ********************************************************************* 281 * _exc_crash_sim() 282 * 283 * Crash the GDB simulator, causing it to exit. 284 * 285 * Input parameters: 286 * nothing 287 * 288 * Return value: 289 * nothing - does not return 290 ********************************************************************* */ 291 292 293LEAF(_exc_crash_sim) 294 295 li $2,1 296 li $3,0xdead 297 li $4,0 298 syscall 0xca 2991: b 1b 300 301END(_exc_crash_sim) 302 303 304/* ********************************************************************* 305 * _exc_cache_crash_sim() 306 * 307 * As _exc_crash_sim, but distinguish cache error exception. 308 * 309 * Input parameters: 310 * nothing 311 * 312 * Return value: 313 * nothing - does not return 314 ********************************************************************* */ 315 316 317LEAF(_exc_cache_crash_sim) 318 319 li $2,1 320 li $3,0xbadc 321 li $4,0 322 syscall 0xca 3231: b 1b 324 325END(_exc_cache_crash_sim) 326 327 328/* ********************************************************************* 329 * _exc_restart() 330 * 331 * Restart the firmware at the boot address 332 * 333 * Input parameters: 334 * nothing 335 * 336 * Return value: 337 * nothing 338 ********************************************************************* */ 339 340LEAF(_exc_restart) 341 342 li t0,0xBFC00000 # ROM restart vector 343 jr t0 344 345END(_exc_restart) 346 347/* ********************************************************************* 348 * _exc_entry(k0) 349 * 350 * Main exception entry point. 351 * 352 * Input parameters: 353 * k0 - exception type 354 * 355 * Return value: 356 * ... 357 ********************************************************************* */ 358 359LEAF(_exc_entry) 360 361 .set noreorder 362 .set noat 363 364 subu k1,sp,EXCEPTION_SIZE 365 SRL k1,3 366 SLL k1,3 367 368 SREG zero,XGR_ZERO(k1) 369 SREG AT,XGR_AT(k1) 370 371 SREG v0,XGR_V0(k1) 372 SREG v1,XGR_V1(k1) 373 374 SREG a0,XGR_A0(k1) 375 SREG a1,XGR_A1(k1) 376 SREG a2,XGR_A2(k1) 377 SREG a3,XGR_A3(k1) 378 379 SREG t0,XGR_T0(k1) 380 SREG t1,XGR_T1(k1) 381 SREG t2,XGR_T2(k1) 382 SREG t3,XGR_T3(k1) 383 SREG t4,XGR_T4(k1) 384 SREG t5,XGR_T5(k1) 385 SREG t6,XGR_T6(k1) 386 SREG t7,XGR_T7(k1) 387 388 SREG s0,XGR_S0(k1) 389 SREG s1,XGR_S1(k1) 390 SREG s2,XGR_S2(k1) 391 SREG s3,XGR_S3(k1) 392 SREG s4,XGR_S4(k1) 393 SREG s5,XGR_S5(k1) 394 SREG s6,XGR_S6(k1) 395 SREG s7,XGR_S7(k1) 396 397 SREG t8,XGR_T8(k1) 398 SREG t9,XGR_T9(k1) 399 400 SREG gp,XGR_GP(k1) 401 SREG sp,XGR_SP(k1) 402 SREG fp,XGR_FP(k1) 403 SREG ra,XGR_RA(k1) 404 405 mfc0 t0,C0_CAUSE 406 mfc0 t1,C0_SR 407 MFC0 t2,C0_BADVADDR 408 MFC0 t3,C0_EPC 409 mfc0 t4,C0_PRID 410 mflo t5 411 mfhi t6 412 SREG t0,XCP0_CAUSE(k1) 413 SREG t1,XCP0_SR(k1) 414 SREG t2,XCP0_VADDR(k1) 415 SREG t3,XCP0_EPC(k1) 416 SREG t4,XCP0_PRID(k1) 417 SREG t5,XGR_LO(k1) 418 SREG t6,XGR_HI(k1) 419 420#if CFG_EMBEDDED_PIC 421 la gp,PHYS_TO_K0(CFE_LOCORE_GLOBAL_GP) 422 LR gp,0(gp) # get our GP handle from low memory vector 423#else 424 la gp,_gp # Load up GP, not relocated so it's easy 425#endif 426 427 move a0,k0 # Pass exception type 428 move a1,k1 # Pass frame to exception handler 429 la t0,_exc_vectab # get base of exception vectors 430 srl k0,3 # convert 8-byte index to array index 431 sll k0,BPWSIZE # convert back to index appropriate for word size 432 addu t0,k0 # get vector address 433 LR t0,(t0) # to call handler 434 435 move sp,k1 # "C" gets fresh stack area 436 437 jalr t0 # Call exception handler 438 nop 439 440 move k1, sp 441 LREG AT,XGR_AT(k1) 442 443 LREG t0,XGR_LO(k1) 444 LREG t1,XGR_HI(k1) 445 mtlo t0 446 mthi t1 447 448 LREG a0,XGR_A0(k1) 449 LREG a1,XGR_A1(k1) 450 LREG a2,XGR_A2(k1) 451 LREG a3,XGR_A3(k1) 452 453 LREG t0,XGR_T0(k1) 454 LREG t1,XGR_T1(k1) 455 LREG t2,XGR_T2(k1) 456 LREG t3,XGR_T3(k1) 457 LREG t4,XGR_T4(k1) 458 LREG t5,XGR_T5(k1) 459 LREG t6,XGR_T6(k1) 460 LREG t7,XGR_T7(k1) 461 462 LREG s0,XGR_S0(k1) 463 LREG s1,XGR_S1(k1) 464 LREG s2,XGR_S2(k1) 465 LREG s3,XGR_S3(k1) 466 LREG s4,XGR_S4(k1) 467 LREG s5,XGR_S5(k1) 468 LREG s6,XGR_S6(k1) 469 LREG s7,XGR_S7(k1) 470 471 LREG t8,XGR_T8(k1) 472 LREG t9,XGR_T9(k1) 473 474 LREG gp,XGR_GP(k1) 475 LREG sp,XGR_SP(k1) 476 LREG fp,XGR_FP(k1) 477 LREG ra,XGR_RA(k1) 478 479/* do any CP0 cleanup here */ 480 481 LREG v0,XGR_V0(k1) 482 LREG v1,XGR_V1(k1) 483 484 ERET 485 486 .set at 487 .set reorder 488 489 490END(_exc_entry) 491 492 493/* ********************************************************************* 494 * _exc_clear_sr_exl() 495 * 496 * Clear SR(EXL) and return to caller. 497 * 498 * Input parameters: 499 * nothing 500 * 501 * Return value: 502 * nothing 503 ********************************************************************* */ 504 505LEAF(_exc_clear_sr_exl) 506 507 mfc0 t0,C0_SR 508 and t0,t0,~(0x02) # clear SR(EXL). Bit 1 509 mtc0 t0,C0_SR 510 511 HAZARD 512 513 j ra 514 515END(_exc_clear_sr_exl) 516 517/* ********************************************************************* 518 * _exc_clear_sr_erl() 519 * 520 * Clear SR(ERL) and return to caller. 521 * 522 * Input parameters: 523 * nothing 524 * 525 * Return value: 526 * nothing 527 ********************************************************************* */ 528 529LEAF(_exc_clear_sr_erl) 530 531 mfc0 t0,C0_SR 532 and t0,t0,~(0x04) # clear SR(ERL). Bit 2 533 mtc0 t0,C0_SR 534 535 HAZARD 536 537 j ra 538 539END(_exc_clear_sr_erl) 540 541 542/* ********************************************************************* 543 * End 544 ********************************************************************* */ 545