1/* $NetBSD: trap_subr.S,v 1.7 2003/02/02 20:43:23 matt 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 86#define GET_PCB(rX) \ 87 GET_CPUINFO(rX); \ 88 lwz rX,CI_CURPCB(rX) 89 90#define STANDARD_PROLOG(savearea) \ 91 mtsprg 1,1; /* save SP */ \ 92 stmw 28,savearea(0); /* free r28-r31 */ \ 93 mflr 28; /* save LR */ \ 94 mfcr 29; /* save CR */ \ 95 mfsrr1 31; /* Test whether we already had PR set */ \ 96 mtcr 31; \ 97 bc 4,17,1f; /* branch if PSL_PR is clear */ \ 98 GET_PCB(1); \ 99 addi 1,1,USPACE; /* stack is top of user struct */ \ 1001: 101 102#define CRITICAL_PROLOG(savearea) \ 103 mtsprg 1,1; /* save SP */ \ 104 stmw 28,savearea(0); /* free r28-r31 */ \ 105 mflr 28; /* save LR */ \ 106 mfcr 29; /* save CR */ \ 107 mfsrr2 30; /* Fake a standard trap */ \ 108 mtsrr0 30; \ 109 mfsrr3 31; /* Test whether we already had PR set */ \ 110 mtsrr1 31; \ 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 118/* Standard handler saves r1,r28-31,LR,CR, sets up the stack and calls s_trap */ 119#define STANDARD_EXC_HANDLER(name)\ 120 .globl _C_LABEL(name ## trap),_C_LABEL(name ## size) ; \ 121_C_LABEL(name ## trap): \ 122 STANDARD_PROLOG(tempsave); \ 123 bla s_trap ; \ 124_C_LABEL(name ## size) = .-_C_LABEL(name ## trap) 125 126/* Access exceptions also need DEAR and ESR saved */ 127#define ACCESS_EXC_HANDLER(name)\ 128 .globl _C_LABEL(name ## trap),_C_LABEL(name ## size) ; \ 129_C_LABEL(name ## trap): \ 130 STANDARD_PROLOG(tempsave); \ 131 mfdear 30; \ 132 mfesr 31; \ 133 stmw 30,16+tempsave(0); \ 134 bla s_trap ; \ 135_C_LABEL(name ## size) = .-_C_LABEL(name ## trap) 136 137/* Maybe this should call ddb.... */ 138#define CRITICAL_EXC_HANDLER(name)\ 139 .globl _C_LABEL(name ## trap),_C_LABEL(name ## size) ; \ 140_C_LABEL(name ## trap): \ 141 CRITICAL_PROLOG(tempsave); \ 142 bla s_trap ; \ 143_C_LABEL(name ## size) = .-_C_LABEL(name ## trap) 144 145/* 146 * This code gets copied to all the trap vectors 147 * (except ISI/DSI, ALI, the interrupts, and possibly the debugging 148 * traps when using IPKDB). 149 */ 150 .text 151 STANDARD_EXC_HANDLER(default) 152 ACCESS_EXC_HANDLER(ali) 153 ACCESS_EXC_HANDLER(dsi) 154 ACCESS_EXC_HANDLER(isi) 155 STANDARD_EXC_HANDLER(debug) 156 CRITICAL_EXC_HANDLER(mchk) 157 158/* 159 * This one for the external interrupt handler. 160 */ 161 .globl _C_LABEL(extint),_C_LABEL(extsize) 162_C_LABEL(extint): 163 mtsprg 1,1 /* save SP */ 164 stmw 28,tempsave(0) /* free r28-r31 */ 165 mflr 28 /* save LR */ 166 mfcr 29 /* save CR */ 167 mfxer 30 /* save XER */ 168 GET_CPUINFO(1) 169 lwz 31,CI_INTRDEPTH(1) /* were we already running on intstk? */ 170 addic. 31,31,1 171 stw 31,CI_INTRDEPTH(1) 172 lwz 1,CI_INTSTK(1) /* get intstk */ 173 beq 1f 174 mfsprg 1,1 /* yes, get old SP */ 1751: 176 ba extintr 177_C_LABEL(extsize) = .-_C_LABEL(extint) 178 179 180#ifdef DDB 181#define ddbsave 0xde0 /* primary save area for DDB */ 182/* 183 * In case of DDB we want a separate trap catcher for it 184 */ 185 .local ddbstk 186 .comm ddbstk,INTSTK,8 /* ddb stack */ 187 188 .globl _C_LABEL(ddblow),_C_LABEL(ddbsize) 189_C_LABEL(ddblow): 190 mtsprg 1,1 /* save SP */ 191 stmw 28,ddbsave(0) /* free r28-r31 */ 192 mflr 28 /* save LR */ 193 mfcr 29 /* save CR */ 194 lis 1,ddbstk+INTSTK@ha /* get new SP */ 195 addi 1,1,ddbstk+INTSTK@l 196 bla ddbtrap 197_C_LABEL(ddbsize) = .-_C_LABEL(ddblow) 198#endif /* DDB */ 199 200#ifdef IPKDB 201#define ipkdbsave 0xde0 /* primary save area for IPKDB */ 202/* 203 * In case of IPKDB we want a separate trap catcher for it 204 */ 205 206 .local ipkdbstk 207 .comm ipkdbstk,INTSTK,8 /* ipkdb stack */ 208 209 .globl _C_LABEL(ipkdblow),_C_LABEL(ipkdbsize) 210_C_LABEL(ipkdblow): 211 mtsprg 1,1 /* save SP */ 212 stmw 28,ipkdbsave(0) /* free r28-r31 */ 213 mflr 28 /* save LR */ 214 mfcr 29 /* save CR */ 215 lis 1,ipkdbstk+INTSTK@ha /* get new SP */ 216 addi 1,1,ipkdbstk+INTSTK@l 217 bla ipkdbtrap 218_C_LABEL(ipkdbsize) = .-_C_LABEL(ipkdblow) 219#endif /* IPKDB */ 220 221#ifdef DEBUG 222#define TRAP_IF_ZERO(r) tweqi r,0 223#else 224#define TRAP_IF_ZERO(r) 225#endif 226 227/* 228 * FRAME_SETUP assumes: 229 * SPRG1 SP (1) 230 * savearea r28-r31,DEAR,ESR (DEAR & ESR only for DSI traps) 231 * 28 LR 232 * 29 CR 233 * 1 kernel stack 234 * LR trap type 235 * SRR0/1 as at start of trap 236 */ 237#define FRAME_SETUP(savearea) \ 238/* Have to enable translation to allow access of kernel stack: */ \ 239 mfsrr0 30; \ 240 mfsrr1 31; \ 241 stmw 30,savearea+24(0); \ 242 mfpid 30; \ 243 li 31,KERNEL_PID; \ 244 mtpid 31; \ 245 mfmsr 31; \ 246 ori 31,31,(PSL_DR|PSL_IR)@l; \ 247 mtmsr 31; \ 248 isync; \ 249 mfsprg 31,1; \ 250 stwu 31,-FRAMELEN(1); \ 251 stw 30,FRAME_PID+8(1); \ 252 stw 0,FRAME_0+8(1); \ 253 stw 31,FRAME_1+8(1); \ 254 stw 28,FRAME_LR+8(1); \ 255 stw 29,FRAME_CR+8(1); \ 256 lmw 28,savearea(0); \ 257 stmw 2,FRAME_2+8(1); \ 258 lmw 28,savearea+16(0); \ 259 mfxer 3; \ 260 mfctr 4; \ 261 mflr 5; \ 262 andi. 5,5,0xff00; \ 263 stw 3,FRAME_XER+8(1); \ 264 stw 4,FRAME_CTR+8(1); \ 265 stw 5,FRAME_EXC+8(1); \ 266 stw 28,FRAME_DEAR+8(1); \ 267 stw 29,FRAME_ESR+8(1); \ 268 stw 30,FRAME_SRR0+8(1); \ 269 stw 31,FRAME_SRR1+8(1) 270 271#define FRAME_LEAVE(savearea) \ 272/* Now restore regs: */ \ 273 lwz 3,FRAME_PID+8(1); \ 274 lwz 4,FRAME_SRR1+8(1); \ 275 bl _C_LABEL(ctx_setup); \ 276 TRAP_IF_ZERO(r3); \ 277 stw 3,FRAME_PID+8(1); \ 278 lmw 26,FRAME_LR+8(1); \ 279 mtlr 26; \ 280 mtcr 27; \ 281 mtxer 28; \ 282 mtctr 29; \ 283 mtsrr0 30; \ 284 mtsrr1 31; \ 285 lmw 2,FRAME_2+8(1); \ 286 lwz 0,FRAME_0+8(1); \ 287 stmw 29,savearea(0); \ 288 lwz 30,FRAME_PID+8(1); \ 289 lwz 1,FRAME_1+8(1); \ 290 mfmsr 31; \ 291 li 29,(PSL_DR|PSL_IR)@l; \ 292 andc 31,31,29; \ 293 mfcr 29; \ 294 mtcr 29; \ 295 mtmsr 31; \ 296 isync; \ 297 TRAP_IF_ZERO(r30); \ 298 mtpid 30; \ 299 lmw 29,savearea(0) 300 301realtrap: /* entry point after IPKDB is done with exception */ 302 /* Test whether we already had PR set */ 303 mfsrr1 1 304 mtcr 1 305 mfsprg 1,1 /* restore SP (might have been 306 overwritten) */ 307 bc 4,17,s_trap /* branch if PSL_PR is false */ 308 GET_PCB(1) 309 addi 1,1,USPACE /* stack is top of user struct */ 310/* 311 * Now the common trap catching code. 312 */ 313s_trap: 314 FRAME_SETUP(tempsave) 315/* Now we can recover interrupts again: */ 316trapagain: 317 wrteei 1 /* Enable interrupts */ 318/* Call C trap code: */ 319 addi 3,1,8 320 bl _C_LABEL(trap) 321 .globl _C_LABEL(trapexit) 322_C_LABEL(trapexit): 323 /* Disable interrupts: */ 324 wrteei 0 325 /* Test AST pending: */ 326 lwz 5,FRAME_SRR1+8(1) 327 mtcr 5 328 bc 4,17,1f /* branch if PSL_PR is false */ 329 GET_CPUINFO(3) 330 lwz 4,CI_ASTPENDING(3) 331 andi. 4,4,1 332 beq 1f 333 li 6,EXC_AST 334 stw 6,FRAME_EXC+8(1) 335 b trapagain 3361: 337 FRAME_LEAVE(exitsave) 338 rfi 339 ba . /* Protect against prefetch */ 340 341 342 343 .globl _C_LABEL(sctrap),_C_LABEL(scsize) 344_C_LABEL(sctrap): 345 STANDARD_PROLOG(tempsave); 346 bla s_sctrap 347_C_LABEL(scsize) = .-_C_LABEL(sctrap) 348 349s_sctrap: 350 FRAME_SETUP(tempsave) 351/* Now we can recover interrupts again: */ 352 wrteei 1 /* Enable interrupts */ 353/* Call the appropriate syscall handler: */ 354 addi 3,1,8 355 GET_CPUINFO(4) 356 lwz 4,CI_CURLWP(4) 357 lwz 4,L_PROC(4) 358 lwz 4,P_MD_SYSCALL(4) 359 mtctr 4 360 bctrl 361/* Disable interrupts: */ 362 wrteei 0 363/* Test AST pending: */ 364 lwz 5,FRAME_SRR1+8(1) 365 mtcr 5 366 bc 4,17,1f /* branch if PSL_PR is false */ 367 GET_CPUINFO(3) 368 lwz 4,CI_ASTPENDING(3) 369 andi. 4,4,1 370 beq 1f 371 li 6,EXC_AST 372 stw 6,FRAME_EXC+8(1) 373 b trapagain 3741: 375 FRAME_LEAVE(exitsave) 376 rfi 377 ba . /* Protect against prefetch */ 378 379 380/* 381 * External interrupt second level handler 382 */ 383 384#define INTRENTER \ 385/* Save non-volatile registers: */ \ 386 stwu 1,-IFRAMELEN(1); /* temporarily */ \ 387 stw 0,IFRAME_R0(1); \ 388 mfsprg 0,1; /* get original SP */ \ 389 stw 0,IFRAME_R1(1); /* and store it */ \ 390 stw 3,IFRAME_R3(1); \ 391 stw 4,IFRAME_R4(1); \ 392 stw 5,IFRAME_R5(1); \ 393 stw 6,IFRAME_R6(1); \ 394 stw 7,IFRAME_R7(1); \ 395 stw 8,IFRAME_R8(1); \ 396 stw 9,IFRAME_R9(1); \ 397 stw 10,IFRAME_R10(1); \ 398 stw 11,IFRAME_R11(1); \ 399 stw 12,IFRAME_R12(1); \ 400 stw 28,IFRAME_LR(1); /* saved LR */ \ 401 stw 29,IFRAME_CR(1); /* saved CR */ \ 402 stw 30,IFRAME_XER(1); /* saved XER */ \ 403 lmw 28,tempsave(0); /* restore r28-r31 */ \ 404 mfctr 6; \ 405 GET_CPUINFO(5); \ 406 lwz 5,CI_INTRDEPTH(5); \ 407 mfsrr0 4; \ 408 mfsrr1 3; \ 409 stw 6,IFRAME_CTR(1); \ 410 stw 5,IFRAME_INTR_DEPTH(1); \ 411 stw 4,IFRAME_SRR0(1); \ 412 stw 3,IFRAME_SRR1(1); \ 413 mfpid 0; /* get currect PID register */ \ 414 stw 0,IFRAME_PID(1); \ 415 li 0,KERNEL_PID; \ 416 mtpid 0; \ 417/* interrupts are recoverable here, and enable translation */ \ 418 mfmsr 5; \ 419 ori 5,5,(PSL_IR|PSL_DR); \ 420 mtmsr 5; \ 421 isync 422 423 .globl _C_LABEL(extint_call) 424extintr: 425 INTRENTER 426_C_LABEL(extint_call): 427 bl _C_LABEL(extint_call) /* to be filled in later */ 428 429intr_exit: 430/* Disable interrupts (should already be disabled) and MMU here: */ 431 wrteei 0 432 isync 433 lwz 3,IFRAME_PID(1) 434 lwz 4,IFRAME_SRR1(1) /* Load srr1 */ 435 bl _C_LABEL(ctx_setup) /* Get proper ctx */ 436 mfmsr 5 437 lis 4,(PSL_EE|PSL_DR|PSL_IR)@h 438 ori 4,4,(PSL_EE|PSL_DR|PSL_IR)@l 439 andc 5,5,4 440 mtmsr 5 441 isync 442 mtpid 3 /* Load CTX */ 443 444/* restore possibly overwritten registers: */ 445 lwz 12,IFRAME_R12(1) 446 lwz 11,IFRAME_R11(1) 447 lwz 10,IFRAME_R10(1) 448 lwz 9,IFRAME_R9(1) 449 lwz 8,IFRAME_R8(1) 450 lwz 7,IFRAME_R7(1) 451 lwz 6,IFRAME_SRR1(1) 452 lwz 5,IFRAME_SRR0(1) 453 lwz 4,IFRAME_CTR(1) 454 lwz 3,IFRAME_XER(1) 455 mtsrr1 6 456 mtsrr0 5 457 mtctr 4 458 mtxer 3 459/* Returning to user mode? */ 460 GET_CPUINFO(5) 461 lwz 4,CI_INTRDEPTH(5) 462 addi 4,4,-1 /* adjust reentrancy count */ 463 stw 4,CI_INTRDEPTH(5) 464 mtcr 6 /* saved SRR1 */ 465 bc 4,17,1f /* branch if PSL_PR is false */ 466 467 lwz 4,CI_ASTPENDING(5) /* Test AST pending */ 468 andi. 4,4,1 469 beq 1f 470/* Setup for entry to realtrap: */ 471 lwz 3,0(1) /* get saved SP */ 472 mtsprg 1,3 473 li 6,EXC_AST 474 stmw 28,tempsave(0) /* establish tempsave again */ 475 mtlr 6 476 lwz 28,IFRAME_LR(1) /* saved LR */ 477 lwz 29,IFRAME_CR(1) /* saved CR */ 478 lwz 6,IFRAME_R6(1) 479 lwz 5,IFRAME_R5(1) 480 lwz 4,IFRAME_R4(1) 481 lwz 3,IFRAME_R3(1) 482 lwz 0,IFRAME_R0(1) 483 b realtrap 4841: 485/* Here is the normal exit of extintr: */ 486 lwz 5,IFRAME_CR(1) 487 lwz 6,IFRAME_LR(1) 488 mtcr 5 489 mtlr 6 490 lwz 6,IFRAME_R6(1) 491 lwz 5,IFRAME_R5(1) 492 lwz 4,IFRAME_R4(1) 493 lwz 3,IFRAME_R3(1) 494 lwz 0,IFRAME_R0(1) 495 lwz 1,IFRAME_R1(1) 496 rfi 497 ba . /* Protect against prefetch */ 498 499/* 500 * PIT interrupt handler. 501 */ 502 .align 5 503_C_LABEL(pitint): 504 mtsprg 1,1 /* save SP */ 505 stmw 28,tempsave(0) /* free r28-r31 */ 506 mflr 28 /* save LR */ 507 mfcr 29 /* save CR */ 508 mfxer 30 /* save XER */ 509 GET_CPUINFO(1) 510 lwz 31,CI_INTRDEPTH(1) /* were we already running on intstk? */ 511 addic. 31,31,1 512 stw 31,CI_INTRDEPTH(1) 513 lwz 1,CI_INTSTK(1) /* get intstk */ 514 beq 1f 515 mfsprg 1,1 /* yes, get old SP */ 5161: 517 INTRENTER 518 addi 3,1,8 /* intr frame */ 519 bl _C_LABEL(decr_intr) 520 b intr_exit 521 522/* 523 * FIT interrupt handler. 524 */ 525 .align 5 526fitint: 527 mtsprg 1,1 /* save SP */ 528 stmw 28,tempsave(0) /* free r28-r31 */ 529 mflr 28 /* save LR */ 530 mfcr 29 /* save CR */ 531 mfxer 30 /* save XER */ 532 GET_CPUINFO(1) 533 lwz 31,CI_INTRDEPTH(1) /* were we already running on intstk? */ 534 addic. 31,31,1 535 stw 31,CI_INTRDEPTH(1) 536 lwz 1,CI_INTSTK(1) /* get intstk */ 537 beq 1f 538 mfsprg 1,1 /* yes, get old SP */ 5391: 540 INTRENTER 541 addi 3,1,8 /* intr frame */ 542 bl _C_LABEL(stat_intr) 543 b intr_exit 544 545#ifdef DDB 546/* 547 * Deliberate entry to ddbtrap 548 */ 549 .globl _C_LABEL(ddb_trap) 550_C_LABEL(ddb_trap): 551 mtsprg 1,1 552 mfmsr 3 553 mtsrr1 3 554 wrteei 0 /* disable interrupts */ 555 isync 556 stmw 28,ddbsave(0) 557 mflr 28 558 li 29,EXC_BPT 559 mtlr 29 560 mfcr 29 561 mtsrr0 28 562 563/* 564 * Now the ddb trap catching code. 565 */ 566ddbtrap: 567 FRAME_SETUP(ddbsave) 568/* Call C trap code: */ 569 addi 3,1,8 570 bl _C_LABEL(ddb_trap_glue) 571 or. 3,3,3 572 bne ddbleave 573/* This wasn't for DDB, so switch to real trap: */ 574 lwz 3,FRAME_EXC+8(1) /* save exception */ 575 stw 3,ddbsave+12(0) 576 FRAME_LEAVE(ddbsave) 577 mtsprg 1,1 /* prepare for entrance to realtrap */ 578 stmw 28,tempsave(0) 579 mflr 28 580 mfcr 29 581 lwz 31,ddbsave+12(0) 582 mtlr 31 583 b realtrap 584ddbleave: 585 FRAME_LEAVE(ddbsave) 586 rfi 587 ba . /* Protect against prefetch */ 588#endif /* DDB */ 589 590#ifdef IPKDB 591/* 592 * Deliberate entry to ipkdbtrap 593 */ 594 .globl _C_LABEL(ipkdb_trap) 595_C_LABEL(ipkdb_trap): 596 mtsprg 1,1 597 mfmsr 3 598 mtsrr1 3 599 wrteei 0 /* disable interrupts */ 600 isync 601 stmw 28,ipkdbsave(0) 602 mflr 28 603 li 29,EXC_BPT 604 mtlr 29 605 mfcr 29 606 mtsrr0 28 607 608/* 609 * Now the ipkdb trap catching code. 610 */ 611ipkdbtrap: 612 FRAME_SETUP(ipkdbsave) 613/* Call C trap code: */ 614 addi 3,1,8 615 bl _C_LABEL(ipkdb_trap_glue) 616 or. 3,3,3 617 bne ipkdbleave 618/* This wasn't for IPKDB, so switch to real trap: */ 619 lwz 3,FRAME_EXC+8(1) /* save exception */ 620 stw 3,ipkdbsave+8(0) 621 FRAME_LEAVE(ipkdbsave) 622 mtsprg 1,1 /* prepare for entrance to realtrap */ 623 stmw 28,tempsave(0) 624 mflr 28 625 mfcr 29 626 lwz 31,ipkdbsave+8(0) 627 mtlr 31 628 b realtrap 629ipkdbleave: 630 FRAME_LEAVE(ipkdbsave) 631 rfi 632 ba . /* Protect against prefetch */ 633 634ipkdbfault: 635 ba _ipkdbfault 636_ipkdbfault: 637 mfsrr0 3 638 addi 3,3,4 639 mtsrr0 3 640 li 3,-1 641 rfi 642 ba . /* Protect against prefetch */ 643 644/* 645 * int ipkdbfbyte(unsigned char *p) 646 */ 647 .globl _C_LABEL(ipkdbfbyte) 648_C_LABEL(ipkdbfbyte): 649 li 9,EXC_DSI /* establish new fault routine */ 650 lwz 5,0(9) 651 lis 6,ipkdbfault@ha 652 lwz 6,ipkdbfault@l(6) 653 stw 6,0(9) 654#ifdef IPKDBUSERHACK 655#ifndef PPC_IBM4XX 656 lis 8,_C_LABEL(ipkdbsr)@ha 657 lwz 8,_C_LABEL(ipkdbsr)@l(8) 658 mtsr USER_SR,8 659 isync 660#endif 661#endif 662 dcbst 0,9 /* flush data... */ 663 sync 664 icbi 0,9 /* and instruction caches */ 665 lbz 3,0(3) /* fetch data */ 666 stw 5,0(9) /* restore previous fault handler */ 667 dcbst 0,9 /* and flush data... */ 668 sync 669 icbi 0,9 /* and instruction caches */ 670 blr 671 672/* 673 * int ipkdbsbyte(unsigned char *p, int c) 674 */ 675 .globl _C_LABEL(ipkdbsbyte) 676_C_LABEL(ipkdbsbyte): 677 li 9,EXC_DSI /* establish new fault routine */ 678 lwz 5,0(9) 679 lis 6,ipkdbfault@ha 680 lwz 6,ipkdbfault@l(6) 681 stw 6,0(9) 682#ifdef IPKDBUSERHACK 683#ifndef PPC_IBM4XX 684 lis 8,_C_LABEL(ipkdbsr)@ha 685 lwz 8,_C_LABEL(ipkdbsr)@l(8) 686 mtsr USER_SR,8 687 isync 688#endif 689#endif 690 dcbst 0,9 /* flush data... */ 691 sync 692 icbi 0,9 /* and instruction caches */ 693 mr 6,3 694 xor 3,3,3 695 stb 4,0(6) 696 dcbst 0,6 /* Now do appropriate flushes 697 to data... */ 698 sync 699 icbi 0,6 /* and instruction caches */ 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#endif /* IPKDB */ 706