1/* $NetBSD: trap_subr.S,v 1.5 2002/08/02 03:46:42 chs Exp $ */ 2 3/* 4 * Copyright 2001 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Eduardo Horvath and Simon Burge for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38/* 39 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 40 * Copyright (C) 1995, 1996 TooLs GmbH. 41 * All rights reserved. 42 * 43 * Redistribution and use in source and binary forms, with or without 44 * modification, are permitted provided that the following conditions 45 * are met: 46 * 1. Redistributions of source code must retain the above copyright 47 * notice, this list of conditions and the following disclaimer. 48 * 2. Redistributions in binary form must reproduce the above copyright 49 * notice, this list of conditions and the following disclaimer in the 50 * documentation and/or other materials provided with the distribution. 51 * 3. All advertising materials mentioning features or use of this software 52 * must display the following acknowledgement: 53 * This product includes software developed by TooLs GmbH. 54 * 4. The name of TooLs GmbH may not be used to endorse or promote products 55 * derived from this software without specific prior written permission. 56 * 57 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 58 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 59 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 60 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 61 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 62 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 63 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 64 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 65 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 66 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 67 */ 68 69/* 70 * NOTICE: This is not a standalone file. to use it, #include it in 71 * your port's locore.S, like so: 72 * 73 * #include <powerpc/ibm4xx/trap_subr.S> 74 */ 75 76/* 77 * Data used during primary/secondary traps/interrupts 78 */ 79#define tempsave 0x2e0 /* primary save area for trap handling */ 80#define disisave 0x3e0 /* primary save area for dsi/isi traps */ 81#define exitsave 0x4e0 /* use this so trap return does not conflict */ 82/* 83 * XXX Interrupt and spill stacks need to be per-CPU. 84 */ 85 .data 86 .align 4 87intstk: 88 .space INTSTK /* interrupt stack */ 89 90GLOBAL(intr_depth) 91 .long -1 /* in-use marker */ 92 93 .comm spillstk,SPILLSTK,8 94 95#if defined(MULTIPROCESSOR) 96#define GET_PCB(rX) \ 97 GET_CPUINFO(rX); \ 98 lwz rX,CI_CURPCB(rX) 99#else 100#define GET_PCB(x) \ 101 lis 1,_C_LABEL(curpcb)@ha; \ 102 lwz 1,_C_LABEL(curpcb)@l(1) 103#endif 104 105#define STANDARD_PROLOG(savearea) \ 106 mtsprg 1,1; /* save SP */ \ 107 stmw 28,savearea(0); /* free r28-r31 */ \ 108 mflr 28; /* save LR */ \ 109 mfcr 29; /* save CR */ \ 110 mfsrr1 31; /* Test whether we already had PR set */ \ 111 mtcr 31; \ 112 bc 4,17,1f; /* branch if PSL_PR is clear */ \ 113 GET_PCB(1); \ 114 addi 1,1,USPACE; /* stack is top of user struct */ \ 1151: 116 117#define CRITICAL_PROLOG(savearea) \ 118 mtsprg 1,1; /* save SP */ \ 119 stmw 28,savearea(0); /* free r28-r31 */ \ 120 mflr 28; /* save LR */ \ 121 mfcr 29; /* save CR */ \ 122 mfsrr2 30; /* Fake a standard trap */ \ 123 mtsrr0 30; \ 124 mfsrr3 31; /* Test whether we already had PR set */ \ 125 mtsrr1 31; \ 126 mtcr 31; \ 127 bc 4,17,1f; /* branch if PSL_PR is clear */ \ 128 GET_PCB(1); \ 129 addi 1,1,USPACE; /* stack is top of user struct */ \ 1301: 131 132 133/* Standard handler saves r1,r28-31,LR,CR, sets up the stack and calls s_trap */ 134#define STANDARD_EXC_HANDLER(name)\ 135 .globl _C_LABEL(name ## trap),_C_LABEL(name ## size) ; \ 136_C_LABEL(name ## trap): \ 137 STANDARD_PROLOG(tempsave); \ 138 bla s_trap ; \ 139_C_LABEL(name ## size) = .-_C_LABEL(name ## trap) 140 141/* Access exceptions also need DEAR and ESR saved */ 142#define ACCESS_EXC_HANDLER(name)\ 143 .globl _C_LABEL(name ## trap),_C_LABEL(name ## size) ; \ 144_C_LABEL(name ## trap): \ 145 STANDARD_PROLOG(tempsave); \ 146 mfdear 30; \ 147 mfesr 31; \ 148 stmw 30,16+tempsave(0); \ 149 bla s_trap ; \ 150_C_LABEL(name ## size) = .-_C_LABEL(name ## trap) 151 152/* Maybe this should call ddb.... */ 153#define CRITICAL_EXC_HANDLER(name)\ 154 .globl _C_LABEL(name ## trap),_C_LABEL(name ## size) ; \ 155_C_LABEL(name ## trap): \ 156 CRITICAL_PROLOG(tempsave); \ 157 bla s_trap ; \ 158_C_LABEL(name ## size) = .-_C_LABEL(name ## trap) 159 160/* 161 * This code gets copied to all the trap vectors 162 * (except ISI/DSI, ALI, the interrupts, and possibly the debugging 163 * traps when using IPKDB). 164 */ 165 .text 166 STANDARD_EXC_HANDLER(default) 167 ACCESS_EXC_HANDLER(ali) 168 ACCESS_EXC_HANDLER(dsi) 169 ACCESS_EXC_HANDLER(isi) 170 STANDARD_EXC_HANDLER(debug) 171 CRITICAL_EXC_HANDLER(mchk) 172 173/* 174 * This one for the external interrupt handler. 175 */ 176 .globl _C_LABEL(extint),_C_LABEL(extsize) 177_C_LABEL(extint): 178 mtsprg 1,1 /* save SP */ 179 stmw 28,tempsave(0) /* free r28-r31 */ 180 mflr 28 /* save LR */ 181 mfcr 29 /* save CR */ 182 mfxer 30 /* save XER */ 183 lis 1,intstk+INTSTK@ha /* get interrupt stack */ 184 addi 1,1,intstk+INTSTK@l 185 lwz 31,0(1) /* were we already running on intstk? */ 186 addic. 31,31,1 187 stw 31,0(1) 188 beq 1f 189 mfsprg 1,1 /* yes, get old SP */ 1901: 191 ba extintr 192_C_LABEL(extsize) = .-_C_LABEL(extint) 193 194 195#ifdef DDB 196#define ddbsave 0xde0 /* primary save area for DDB */ 197/* 198 * In case of DDB we want a separate trap catcher for it 199 */ 200 .local ddbstk 201 .comm ddbstk,INTSTK,8 /* ddb stack */ 202 203 .globl _C_LABEL(ddblow),_C_LABEL(ddbsize) 204_C_LABEL(ddblow): 205 mtsprg 1,1 /* save SP */ 206 stmw 28,ddbsave(0) /* free r28-r31 */ 207 mflr 28 /* save LR */ 208 mfcr 29 /* save CR */ 209 lis 1,ddbstk+INTSTK@ha /* get new SP */ 210 addi 1,1,ddbstk+INTSTK@l 211 bla ddbtrap 212_C_LABEL(ddbsize) = .-_C_LABEL(ddblow) 213#endif /* DDB */ 214 215#ifdef IPKDB 216#define ipkdbsave 0xde0 /* primary save area for IPKDB */ 217/* 218 * In case of IPKDB we want a separate trap catcher for it 219 */ 220 221 .local ipkdbstk 222 .comm ipkdbstk,INTSTK,8 /* ipkdb stack */ 223 224 .globl _C_LABEL(ipkdblow),_C_LABEL(ipkdbsize) 225_C_LABEL(ipkdblow): 226 mtsprg 1,1 /* save SP */ 227 stmw 28,ipkdbsave(0) /* free r28-r31 */ 228 mflr 28 /* save LR */ 229 mfcr 29 /* save CR */ 230 lis 1,ipkdbstk+INTSTK@ha /* get new SP */ 231 addi 1,1,ipkdbstk+INTSTK@l 232 bla ipkdbtrap 233_C_LABEL(ipkdbsize) = .-_C_LABEL(ipkdblow) 234#endif /* IPKDB */ 235 236#ifdef DEBUG 237#define TRAP_IF_ZERO(r) tweqi r,0 238#else 239#define TRAP_IF_ZERO(r) 240#endif 241 242/* 243 * FRAME_SETUP assumes: 244 * SPRG1 SP (1) 245 * savearea r28-r31,DEAR,ESR (DEAR & ESR only for DSI traps) 246 * 28 LR 247 * 29 CR 248 * 1 kernel stack 249 * LR trap type 250 * SRR0/1 as at start of trap 251 */ 252#define FRAME_SETUP(savearea) \ 253/* Have to enable translation to allow access of kernel stack: */ \ 254 mfsrr0 30; \ 255 mfsrr1 31; \ 256 stmw 30,savearea+24(0); \ 257 mfpid 30; \ 258 li 31,KERNEL_PID; \ 259 mtpid 31; \ 260 mfmsr 31; \ 261 ori 31,31,(PSL_DR|PSL_IR)@l; \ 262 mtmsr 31; \ 263 isync; \ 264 mfsprg 31,1; \ 265 stwu 31,-FRAMELEN(1); \ 266 stw 30,FRAME_PID+8(1); \ 267 stw 0,FRAME_0+8(1); \ 268 stw 31,FRAME_1+8(1); \ 269 stw 28,FRAME_LR+8(1); \ 270 stw 29,FRAME_CR+8(1); \ 271 lmw 28,savearea(0); \ 272 stmw 2,FRAME_2+8(1); \ 273 lmw 28,savearea+16(0); \ 274 mfxer 3; \ 275 mfctr 4; \ 276 mflr 5; \ 277 andi. 5,5,0xff00; \ 278 stw 3,FRAME_XER+8(1); \ 279 stw 4,FRAME_CTR+8(1); \ 280 stw 5,FRAME_EXC+8(1); \ 281 stw 28,FRAME_DEAR+8(1); \ 282 stw 29,FRAME_ESR+8(1); \ 283 stw 30,FRAME_SRR0+8(1); \ 284 stw 31,FRAME_SRR1+8(1) 285 286#define FRAME_LEAVE(savearea) \ 287/* Now restore regs: */ \ 288 lwz 3,FRAME_PID+8(1); \ 289 lwz 4,FRAME_SRR1+8(1); \ 290 bl _C_LABEL(ctx_setup); \ 291 TRAP_IF_ZERO(r3); \ 292 stw 3,FRAME_PID+8(1); \ 293 lmw 26,FRAME_LR+8(1); \ 294 mtlr 26; \ 295 mtcr 27; \ 296 mtxer 28; \ 297 mtctr 29; \ 298 mtsrr0 30; \ 299 mtsrr1 31; \ 300 lmw 2,FRAME_2+8(1); \ 301 lwz 0,FRAME_0+8(1); \ 302 stmw 29,savearea(0); \ 303 lwz 30,FRAME_PID+8(1); \ 304 lwz 1,FRAME_1+8(1); \ 305 mfmsr 31; \ 306 li 29,(PSL_DR|PSL_IR)@l; \ 307 andc 31,31,29; \ 308 mfcr 29; \ 309 mtcr 29; \ 310 mtmsr 31; \ 311 isync; \ 312 TRAP_IF_ZERO(r30); \ 313 mtpid 30; \ 314 lmw 29,savearea(0) 315 316realtrap: /* entry point after IPKDB is done with exception */ 317 /* Test whether we already had PR set */ 318 mfsrr1 1 319 mtcr 1 320 mfsprg 1,1 /* restore SP (might have been 321 overwritten) */ 322 bc 4,17,s_trap /* branch if PSL_PR is false */ 323 lis 1,_C_LABEL(curpcb)@ha 324 lwz 1,_C_LABEL(curpcb)@l(1) 325 addi 1,1,USPACE /* stack is top of user struct */ 326/* 327 * Now the common trap catching code. 328 */ 329s_trap: 330 FRAME_SETUP(tempsave) 331/* Now we can recover interrupts again: */ 332trapagain: 333 wrteei 1 /* Enable interrupts */ 334/* Call C trap code: */ 335 addi 3,1,8 336 bl _C_LABEL(trap) 337 .globl _C_LABEL(trapexit) 338_C_LABEL(trapexit): 339 /* Disable interrupts: */ 340 wrteei 0 341 /* Test AST pending: */ 342 lwz 5,FRAME_SRR1+8(1) 343 mtcr 5 344 bc 4,17,1f /* branch if PSL_PR is false */ 345#if defined(MULTIPROCESSOR) 346 GET_CPUINFO(3) 347 lwz 4,CI_ASTPENDING(3) 348#else 349 lis 3,_C_LABEL(astpending)@ha 350 lwz 4,_C_LABEL(astpending)@l(3) 351#endif 352 andi. 4,4,1 353 beq 1f 354 li 6,EXC_AST 355 stw 6,FRAME_EXC+8(1) 356 b trapagain 3571: 358 FRAME_LEAVE(exitsave) 359 rfi 360 ba . /* Protect against prefetch */ 361 362 363 364 .globl _C_LABEL(sctrap),_C_LABEL(scsize) 365_C_LABEL(sctrap): 366 STANDARD_PROLOG(tempsave); 367 bla s_sctrap 368_C_LABEL(scsize) = .-_C_LABEL(sctrap) 369 370s_sctrap: 371 FRAME_SETUP(tempsave) 372/* Now we can recover interrupts again: */ 373 wrteei 1 /* Enable interrupts */ 374/* Call the appropriate syscall handler: */ 375 addi 3,1,8 376 lis 4,_C_LABEL(curproc)@ha 377 lwz 4,_C_LABEL(curproc)@l(4) 378 lwz 4,P_MD_SYSCALL@l(4) 379 mtctr 4 380 bctrl 381/* Disable interrupts: */ 382 wrteei 0 383/* Test AST pending: */ 384 lwz 5,FRAME_SRR1+8(1) 385 mtcr 5 386 bc 4,17,1f /* branch if PSL_PR is false */ 387#if defined(MULTIPROCESSOR) 388 GET_CPUINFO(3) 389 lwz 4,CI_ASTPENDING(3) 390#else 391 lis 3,_C_LABEL(astpending)@ha 392 lwz 4,_C_LABEL(astpending)@l(3) 393#endif 394 andi. 4,4,1 395 beq 1f 396 li 6,EXC_AST 397 stw 6,FRAME_EXC+8(1) 398 b trapagain 3991: 400 FRAME_LEAVE(exitsave) 401 rfi 402 ba . /* Protect against prefetch */ 403 404 405/* 406 * External interrupt second level handler 407 */ 408 409#define INTRENTER \ 410/* Save non-volatile registers: */ \ 411 stwu 1,-92(1); /* temporarily */ \ 412 stw 0,84(1); \ 413 mfsprg 0,1; /* get original SP */ \ 414 stw 0,0(1); /* and store it */ \ 415 stw 3,80(1); \ 416 stw 4,76(1); \ 417 stw 5,72(1); \ 418 stw 6,68(1); \ 419 stw 7,64(1); \ 420 stw 8,60(1); \ 421 stw 9,56(1); \ 422 stw 10,52(1); \ 423 stw 11,48(1); \ 424 stw 12,44(1); \ 425 stw 28,40(1); /* saved LR */ \ 426 stw 29,36(1); /* saved CR */ \ 427 stw 30,32(1); /* saved XER */ \ 428 lmw 28,tempsave(0); /* restore r28-r31 */ \ 429 mfctr 6; \ 430 lis 5,_C_LABEL(intr_depth)@ha; \ 431 lwz 5,_C_LABEL(intr_depth)@l(5); \ 432 mfsrr0 4; \ 433 mfsrr1 3; \ 434 stw 6,28(1); \ 435 stw 5,20(1); \ 436 stw 4,12(1); \ 437 stw 3,8(1); \ 438 mfpid 0; /* get currect PID register */ \ 439 stw 0,88(1) ; \ 440 li 0, KERNEL_PID; \ 441 mtpid 0; \ 442/* interrupts are recoverable here, and enable translation */ \ 443 mfmsr 5; \ 444 ori 5,5,(PSL_IR|PSL_DR); \ 445 mtmsr 5; \ 446 isync 447 448 .globl _C_LABEL(extint_call) 449extintr: 450 INTRENTER 451_C_LABEL(extint_call): 452 bl _C_LABEL(extint_call) /* to be filled in later */ 453 454intr_exit: 455/* Disable interrupts (should already be disabled) and MMU here: */ 456 wrteei 0 457 isync 458 lwz 3,88(1) 459 lwz 4,8(1) /* Load srr1 */ 460 bl _C_LABEL(ctx_setup) /* Get proper ctx */ 461 mfmsr 5 462 lis 4,(PSL_EE|PSL_DR|PSL_IR)@h 463 ori 4,4,(PSL_EE|PSL_DR|PSL_IR)@l 464 andc 5,5,4 465 mtmsr 5 466 isync 467 mtpid 3 /* Load CTX */ 468 469/* restore possibly overwritten registers: */ 470 lwz 12,44(1) 471 lwz 11,48(1) 472 lwz 10,52(1) 473 lwz 9,56(1) 474 lwz 8,60(1) 475 lwz 7,64(1) 476 lwz 6,8(1) 477 lwz 5,12(1) 478 lwz 4,28(1) 479 lwz 3,32(1) 480 mtsrr1 6 481 mtsrr0 5 482 mtctr 4 483 mtxer 3 484/* Returning to user mode? */ 485 mtcr 6 /* saved SRR1 */ 486 bc 4,17,1f /* branch if PSL_PR is false */ 487 488#if defined(MULTIPROCESSOR) 489 lwz 4,CI_ASTPENDING(4) /* Test AST pending */ 490#else 491 lis 3,_C_LABEL(astpending)@ha /* Test AST pending */ 492 lwz 4,_C_LABEL(astpending)@l(3) 493#endif 494 andi. 4,4,1 495 beq 1f 496/* Setup for entry to realtrap: */ 497 lwz 3,0(1) /* get saved SP */ 498 mtsprg 1,3 499 li 6,EXC_AST 500 stmw 28,tempsave(0) /* establish tempsave again */ 501 mtlr 6 502 lwz 28,40(1) /* saved LR */ 503 lwz 29,36(1) /* saved CR */ 504 lwz 6,68(1) 505 lwz 5,72(1) 506 lwz 4,76(1) 507 lwz 3,80(1) 508 lwz 0,84(1) 509 lis 30,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */ 510 lwz 31,_C_LABEL(intr_depth)@l(30) 511 addi 31,31,-1 512 stw 31,_C_LABEL(intr_depth)@l(30) 513 b realtrap 5141: 515/* Here is the normal exit of extintr: */ 516 lwz 5,36(1) 517 lwz 6,40(1) 518 mtcr 5 519 mtlr 6 520 lwz 6,68(1) 521 lwz 5,72(1) 522 lis 3,_C_LABEL(intr_depth)@ha /* adjust reentrancy count */ 523 lwz 4,_C_LABEL(intr_depth)@l(3) 524 addi 4,4,-1 525 stw 4,_C_LABEL(intr_depth)@l(3) 526 lwz 4,76(1) 527 lwz 3,80(1) 528 lwz 0,84(1) 529 lwz 1,0(1) 530 rfi 531 ba . /* Protect against prefetch */ 532 533/* 534 * PIT interrupt handler. 535 */ 536 .align 5 537_C_LABEL(pitint): 538 mtsprg 1,1 /* save SP */ 539 stmw 28,tempsave(0) /* free r28-r31 */ 540 mflr 28 /* save LR */ 541 mfcr 29 /* save CR */ 542 mfxer 30 /* save XER */ 543 lis 1,intstk+INTSTK@ha /* get interrupt stack */ 544 addi 1,1,intstk+INTSTK@l 545 lwz 31,0(1) /* were we already running on intstk? */ 546 addic. 31,31,1 547 stw 31,0(1) 548 beq 1f 549 mfsprg 1,1 /* yes, get old SP */ 5501: 551 INTRENTER 552 addi 3,1,8 /* intr frame */ 553 bl _C_LABEL(decr_intr) 554 b intr_exit 555 556/* 557 * FIT interrupt handler. 558 */ 559 .align 5 560fitint: 561 mtsprg 1,1 /* save SP */ 562 stmw 28,tempsave(0) /* free r28-r31 */ 563 mflr 28 /* save LR */ 564 mfcr 29 /* save CR */ 565 mfxer 30 /* save XER */ 566 lis 1,intstk+INTSTK@ha /* get interrupt stack */ 567 addi 1,1,intstk+INTSTK@l 568 lwz 31,0(1) /* were we already running on intstk? */ 569 addic. 31,31,1 570 stw 31,0(1) 571 beq 1f 572 mfsprg 1,1 /* yes, get old SP */ 5731: 574 INTRENTER 575 addi 3,1,8 /* intr frame */ 576 bl _C_LABEL(stat_intr) 577 b intr_exit 578 579#ifdef DDB 580/* 581 * Deliberate entry to ddbtrap 582 */ 583 .globl _C_LABEL(ddb_trap) 584_C_LABEL(ddb_trap): 585 mtsprg 1,1 586 mfmsr 3 587 mtsrr1 3 588 wrteei 0 /* disable interrupts */ 589 isync 590 stmw 28,ddbsave(0) 591 mflr 28 592 li 29,EXC_BPT 593 mtlr 29 594 mfcr 29 595 mtsrr0 28 596 597/* 598 * Now the ddb trap catching code. 599 */ 600ddbtrap: 601 FRAME_SETUP(ddbsave) 602/* Call C trap code: */ 603 addi 3,1,8 604 bl _C_LABEL(ddb_trap_glue) 605 or. 3,3,3 606 bne ddbleave 607/* This wasn't for DDB, so switch to real trap: */ 608 lwz 3,FRAME_EXC+8(1) /* save exception */ 609 stw 3,ddbsave+12(0) 610 FRAME_LEAVE(ddbsave) 611 mtsprg 1,1 /* prepare for entrance to realtrap */ 612 stmw 28,tempsave(0) 613 mflr 28 614 mfcr 29 615 lwz 31,ddbsave+12(0) 616 mtlr 31 617 b realtrap 618ddbleave: 619 FRAME_LEAVE(ddbsave) 620 rfi 621 ba . /* Protect against prefetch */ 622#endif /* DDB */ 623 624#ifdef IPKDB 625/* 626 * Deliberate entry to ipkdbtrap 627 */ 628 .globl _C_LABEL(ipkdb_trap) 629_C_LABEL(ipkdb_trap): 630 mtsprg 1,1 631 mfmsr 3 632 mtsrr1 3 633 wrteei 0 /* disable interrupts */ 634 isync 635 stmw 28,ipkdbsave(0) 636 mflr 28 637 li 29,EXC_BPT 638 mtlr 29 639 mfcr 29 640 mtsrr0 28 641 642/* 643 * Now the ipkdb trap catching code. 644 */ 645ipkdbtrap: 646 FRAME_SETUP(ipkdbsave) 647/* Call C trap code: */ 648 addi 3,1,8 649 bl _C_LABEL(ipkdb_trap_glue) 650 or. 3,3,3 651 bne ipkdbleave 652/* This wasn't for IPKDB, so switch to real trap: */ 653 lwz 3,FRAME_EXC+8(1) /* save exception */ 654 stw 3,ipkdbsave+8(0) 655 FRAME_LEAVE(ipkdbsave) 656 mtsprg 1,1 /* prepare for entrance to realtrap */ 657 stmw 28,tempsave(0) 658 mflr 28 659 mfcr 29 660 lwz 31,ipkdbsave+8(0) 661 mtlr 31 662 b realtrap 663ipkdbleave: 664 FRAME_LEAVE(ipkdbsave) 665 rfi 666 ba . /* Protect against prefetch */ 667 668ipkdbfault: 669 ba _ipkdbfault 670_ipkdbfault: 671 mfsrr0 3 672 addi 3,3,4 673 mtsrr0 3 674 li 3,-1 675 rfi 676 ba . /* Protect against prefetch */ 677 678/* 679 * int ipkdbfbyte(unsigned char *p) 680 */ 681 .globl _C_LABEL(ipkdbfbyte) 682_C_LABEL(ipkdbfbyte): 683 li 9,EXC_DSI /* establish new fault routine */ 684 lwz 5,0(9) 685 lis 6,ipkdbfault@ha 686 lwz 6,ipkdbfault@l(6) 687 stw 6,0(9) 688#ifdef IPKDBUSERHACK 689#ifndef PPC_IBM4XX 690 lis 8,_C_LABEL(ipkdbsr)@ha 691 lwz 8,_C_LABEL(ipkdbsr)@l(8) 692 mtsr USER_SR,8 693 isync 694#endif 695#endif 696 dcbst 0,9 /* flush data... */ 697 sync 698 icbi 0,9 /* and instruction caches */ 699 lbz 3,0(3) /* fetch data */ 700 stw 5,0(9) /* restore previous fault handler */ 701 dcbst 0,9 /* and flush data... */ 702 sync 703 icbi 0,9 /* and instruction caches */ 704 blr 705 706/* 707 * int ipkdbsbyte(unsigned char *p, int c) 708 */ 709 .globl _C_LABEL(ipkdbsbyte) 710_C_LABEL(ipkdbsbyte): 711 li 9,EXC_DSI /* establish new fault routine */ 712 lwz 5,0(9) 713 lis 6,ipkdbfault@ha 714 lwz 6,ipkdbfault@l(6) 715 stw 6,0(9) 716#ifdef IPKDBUSERHACK 717#ifndef PPC_IBM4XX 718 lis 8,_C_LABEL(ipkdbsr)@ha 719 lwz 8,_C_LABEL(ipkdbsr)@l(8) 720 mtsr USER_SR,8 721 isync 722#endif 723#endif 724 dcbst 0,9 /* flush data... */ 725 sync 726 icbi 0,9 /* and instruction caches */ 727 mr 6,3 728 xor 3,3,3 729 stb 4,0(6) 730 dcbst 0,6 /* Now do appropriate flushes 731 to data... */ 732 sync 733 icbi 0,6 /* and instruction caches */ 734 stw 5,0(9) /* restore previous fault handler */ 735 dcbst 0,9 /* and flush data... */ 736 sync 737 icbi 0,9 /* and instruction caches */ 738 blr 739#endif /* IPKDB */ 740