1/* $NetBSD: trap_subr.S,v 1.10 2005/12/11 12:18:42 christos 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(3); \ 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(30); \ 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),_C_LABEL(sctrapexit) 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_C_LABEL(sctrapexit): 362/* Disable interrupts: */ 363 wrteei 0 364/* Test AST pending: */ 365 lwz 5,FRAME_SRR1+8(1) 366 mtcr 5 367 bc 4,17,1f /* branch if PSL_PR is false */ 368 GET_CPUINFO(3) 369 lwz 4,CI_ASTPENDING(3) 370 andi. 4,4,1 371 beq 1f 372 li 6,EXC_AST 373 stw 6,FRAME_EXC+8(1) 374 b trapagain 3751: 376 FRAME_LEAVE(exitsave) 377 rfi 378 ba . /* Protect against prefetch */ 379 380 381/* 382 * External interrupt second level handler 383 */ 384 385#define INTRENTER \ 386/* Save non-volatile registers: */ \ 387 stwu 1,-IFRAMELEN(1); /* temporarily */ \ 388 stw 0,IFRAME_R0(1); \ 389 mfsprg 0,1; /* get original SP */ \ 390 stw 0,IFRAME_R1(1); /* and store it */ \ 391 stw 3,IFRAME_R3(1); \ 392 stw 4,IFRAME_R4(1); \ 393 stw 5,IFRAME_R5(1); \ 394 stw 6,IFRAME_R6(1); \ 395 stw 7,IFRAME_R7(1); \ 396 stw 8,IFRAME_R8(1); \ 397 stw 9,IFRAME_R9(1); \ 398 stw 10,IFRAME_R10(1); \ 399 stw 11,IFRAME_R11(1); \ 400 stw 12,IFRAME_R12(1); \ 401 stw 28,IFRAME_LR(1); /* saved LR */ \ 402 stw 29,IFRAME_CR(1); /* saved CR */ \ 403 stw 30,IFRAME_XER(1); /* saved XER */ \ 404 lmw 28,tempsave(0); /* restore r28-r31 */ \ 405 mfctr 6; \ 406 GET_CPUINFO(5); \ 407 lwz 5,CI_INTRDEPTH(5); \ 408 mfsrr0 4; \ 409 mfsrr1 3; \ 410 stw 6,IFRAME_CTR(1); \ 411 stw 5,IFRAME_INTR_DEPTH(1); \ 412 stw 4,IFRAME_SRR0(1); \ 413 stw 3,IFRAME_SRR1(1); \ 414 mfpid 0; /* get currect PID register */ \ 415 stw 0,IFRAME_PID(1); \ 416 li 0,KERNEL_PID; \ 417 mtpid 0; \ 418/* interrupts are recoverable here, and enable translation */ \ 419 mfmsr 5; \ 420 ori 5,5,(PSL_IR|PSL_DR); \ 421 mtmsr 5; \ 422 isync 423 424 .globl _C_LABEL(extint_call) 425extintr: 426 INTRENTER 427_C_LABEL(extint_call): 428 bl _C_LABEL(extint_call) /* to be filled in later */ 429 430intr_exit: 431/* Disable interrupts (should already be disabled) and MMU here: */ 432 wrteei 0 433 isync 434 lwz 3,IFRAME_PID(1) 435 lwz 4,IFRAME_SRR1(1) /* Load srr1 */ 436 bl _C_LABEL(ctx_setup) /* Get proper ctx */ 437 mfmsr 5 438 lis 4,(PSL_EE|PSL_DR|PSL_IR)@h 439 ori 4,4,(PSL_EE|PSL_DR|PSL_IR)@l 440 andc 5,5,4 441 mtmsr 5 442 isync 443 mtpid 3 /* Load CTX */ 444 445/* restore possibly overwritten registers: */ 446 lwz 12,IFRAME_R12(1) 447 lwz 11,IFRAME_R11(1) 448 lwz 10,IFRAME_R10(1) 449 lwz 9,IFRAME_R9(1) 450 lwz 8,IFRAME_R8(1) 451 lwz 7,IFRAME_R7(1) 452 lwz 6,IFRAME_SRR1(1) 453 lwz 5,IFRAME_SRR0(1) 454 lwz 4,IFRAME_CTR(1) 455 lwz 3,IFRAME_XER(1) 456 mtsrr1 6 457 mtsrr0 5 458 mtctr 4 459 mtxer 3 460/* Returning to user mode? */ 461 GET_CPUINFO(5) 462 lwz 4,CI_INTRDEPTH(5) 463 addi 4,4,-1 /* adjust reentrancy count */ 464 stw 4,CI_INTRDEPTH(5) 465 mtcr 6 /* saved SRR1 */ 466 bc 4,17,1f /* branch if PSL_PR is false */ 467 468 lwz 4,CI_ASTPENDING(5) /* Test AST pending */ 469 andi. 4,4,1 470 beq 1f 471/* Setup for entry to realtrap: */ 472 lwz 3,0(1) /* get saved SP */ 473 mtsprg 1,3 474 li 6,EXC_AST 475 stmw 28,tempsave(0) /* establish tempsave again */ 476 mtlr 6 477 lwz 28,IFRAME_LR(1) /* saved LR */ 478 lwz 29,IFRAME_CR(1) /* saved CR */ 479 lwz 6,IFRAME_R6(1) 480 lwz 5,IFRAME_R5(1) 481 lwz 4,IFRAME_R4(1) 482 lwz 3,IFRAME_R3(1) 483 lwz 0,IFRAME_R0(1) 484 b realtrap 4851: 486/* Here is the normal exit of extintr: */ 487 lwz 5,IFRAME_CR(1) 488 lwz 6,IFRAME_LR(1) 489 mtcr 5 490 mtlr 6 491 lwz 6,IFRAME_R6(1) 492 lwz 5,IFRAME_R5(1) 493 lwz 4,IFRAME_R4(1) 494 lwz 3,IFRAME_R3(1) 495 lwz 0,IFRAME_R0(1) 496 lwz 1,IFRAME_R1(1) 497 rfi 498 ba . /* Protect against prefetch */ 499 500/* 501 * PIT interrupt handler. 502 */ 503 .align 5 504_C_LABEL(pitint): 505 mtsprg 1,1 /* save SP */ 506 stmw 28,tempsave(0) /* free r28-r31 */ 507 mflr 28 /* save LR */ 508 mfcr 29 /* save CR */ 509 mfxer 30 /* save XER */ 510 GET_CPUINFO(1) 511 lwz 31,CI_INTRDEPTH(1) /* were we already running on intstk? */ 512 addic. 31,31,1 513 stw 31,CI_INTRDEPTH(1) 514 lwz 1,CI_INTSTK(1) /* get intstk */ 515 beq 1f 516 mfsprg 1,1 /* yes, get old SP */ 5171: 518 INTRENTER 519 addi 3,1,8 /* intr frame */ 520 bl _C_LABEL(decr_intr) 521 b intr_exit 522 523/* 524 * FIT interrupt handler. 525 */ 526 .align 5 527fitint: 528 mtsprg 1,1 /* save SP */ 529 stmw 28,tempsave(0) /* free r28-r31 */ 530 mflr 28 /* save LR */ 531 mfcr 29 /* save CR */ 532 mfxer 30 /* save XER */ 533 GET_CPUINFO(1) 534 lwz 31,CI_INTRDEPTH(1) /* were we already running on intstk? */ 535 addic. 31,31,1 536 stw 31,CI_INTRDEPTH(1) 537 lwz 1,CI_INTSTK(1) /* get intstk */ 538 beq 1f 539 mfsprg 1,1 /* yes, get old SP */ 5401: 541 INTRENTER 542 addi 3,1,8 /* intr frame */ 543 bl _C_LABEL(stat_intr) 544 b intr_exit 545 546#ifdef DDB 547/* 548 * Deliberate entry to ddbtrap 549 */ 550 .globl _C_LABEL(ddb_trap) 551_C_LABEL(ddb_trap): 552 mtsprg 1,1 553 mfmsr 3 554 mtsrr1 3 555 wrteei 0 /* disable interrupts */ 556 isync 557 stmw 28,ddbsave(0) 558 mflr 28 559 li 29,EXC_BPT 560 mtlr 29 561 mfcr 29 562 mtsrr0 28 563 564/* 565 * Now the ddb trap catching code. 566 */ 567ddbtrap: 568 FRAME_SETUP(ddbsave) 569/* Call C trap code: */ 570 addi 3,1,8 571 bl _C_LABEL(ddb_trap_glue) 572 or. 3,3,3 573 bne ddbleave 574/* This wasn't for DDB, so switch to real trap: */ 575 lwz 3,FRAME_EXC+8(1) /* save exception */ 576 stw 3,ddbsave+12(0) 577 FRAME_LEAVE(ddbsave) 578 mtsprg 1,1 /* prepare for entrance to realtrap */ 579 stmw 28,tempsave(0) 580 mflr 28 581 mfcr 29 582 lwz 31,ddbsave+12(0) 583 mtlr 31 584 b realtrap 585ddbleave: 586 FRAME_LEAVE(ddbsave) 587 rfi 588 ba . /* Protect against prefetch */ 589#endif /* DDB */ 590 591#ifdef IPKDB 592/* 593 * Deliberate entry to ipkdbtrap 594 */ 595 .globl _C_LABEL(ipkdb_trap) 596_C_LABEL(ipkdb_trap): 597 mtsprg 1,1 598 mfmsr 3 599 mtsrr1 3 600 wrteei 0 /* disable interrupts */ 601 isync 602 stmw 28,ipkdbsave(0) 603 mflr 28 604 li 29,EXC_BPT 605 mtlr 29 606 mfcr 29 607 mtsrr0 28 608 609/* 610 * Now the ipkdb trap catching code. 611 */ 612ipkdbtrap: 613 FRAME_SETUP(ipkdbsave) 614/* Call C trap code: */ 615 addi 3,1,8 616 bl _C_LABEL(ipkdb_trap_glue) 617 or. 3,3,3 618 bne ipkdbleave 619/* This wasn't for IPKDB, so switch to real trap: */ 620 lwz 3,FRAME_EXC+8(1) /* save exception */ 621 stw 3,ipkdbsave+8(0) 622 FRAME_LEAVE(ipkdbsave) 623 mtsprg 1,1 /* prepare for entrance to realtrap */ 624 stmw 28,tempsave(0) 625 mflr 28 626 mfcr 29 627 lwz 31,ipkdbsave+8(0) 628 mtlr 31 629 b realtrap 630ipkdbleave: 631 FRAME_LEAVE(ipkdbsave) 632 rfi 633 ba . /* Protect against prefetch */ 634 635ipkdbfault: 636 ba _ipkdbfault 637_ipkdbfault: 638 mfsrr0 3 639 addi 3,3,4 640 mtsrr0 3 641 li 3,-1 642 rfi 643 ba . /* Protect against prefetch */ 644 645/* 646 * int ipkdbfbyte(unsigned char *p) 647 */ 648 .globl _C_LABEL(ipkdbfbyte) 649_C_LABEL(ipkdbfbyte): 650 li 9,EXC_DSI /* establish new fault routine */ 651 lwz 5,0(9) 652 lis 6,ipkdbfault@ha 653 lwz 6,ipkdbfault@l(6) 654 stw 6,0(9) 655#ifdef IPKDBUSERHACK 656#ifndef PPC_IBM4XX 657 lis 8,_C_LABEL(ipkdbsr)@ha 658 lwz 8,_C_LABEL(ipkdbsr)@l(8) 659 mtsr USER_SR,8 660 isync 661#endif 662#endif 663 dcbst 0,9 /* flush data... */ 664 sync 665 icbi 0,9 /* and instruction caches */ 666 lbz 3,0(3) /* fetch data */ 667 stw 5,0(9) /* restore previous fault handler */ 668 dcbst 0,9 /* and flush data... */ 669 sync 670 icbi 0,9 /* and instruction caches */ 671 blr 672 673/* 674 * int ipkdbsbyte(unsigned char *p, int c) 675 */ 676 .globl _C_LABEL(ipkdbsbyte) 677_C_LABEL(ipkdbsbyte): 678 li 9,EXC_DSI /* establish new fault routine */ 679 lwz 5,0(9) 680 lis 6,ipkdbfault@ha 681 lwz 6,ipkdbfault@l(6) 682 stw 6,0(9) 683#ifdef IPKDBUSERHACK 684#ifndef PPC_IBM4XX 685 lis 8,_C_LABEL(ipkdbsr)@ha 686 lwz 8,_C_LABEL(ipkdbsr)@l(8) 687 mtsr USER_SR,8 688 isync 689#endif 690#endif 691 dcbst 0,9 /* flush data... */ 692 sync 693 icbi 0,9 /* and instruction caches */ 694 mr 6,3 695 xor 3,3,3 696 stb 4,0(6) 697 dcbst 0,6 /* Now do appropriate flushes 698 to data... */ 699 sync 700 icbi 0,6 /* and instruction caches */ 701 stw 5,0(9) /* restore previous fault handler */ 702 dcbst 0,9 /* and flush data... */ 703 sync 704 icbi 0,9 /* and instruction caches */ 705 blr 706#endif /* IPKDB */ 707