1/* $NetBSD: trap_subr.S,v 1.13 2011/01/18 01:02:54 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 * XXX Interrupt and spill stacks need to be per-CPU. 78 */ 79 80#define GET_PCB(rX) \ 81 GET_CPUINFO(rX); \ 82 lwz rX,CI_CURPCB(rX) 83 84#define STANDARD_PROLOG(savearea) \ 85 mtsprg1 %r1; /* save SP */ \ 86 GET_CPUINFO(%r1); \ 87 stmw %r28,(savearea+CPUSAVE_R28)(%r1); /* free r28-r31 */ \ 88 mflr %r28; /* save LR */ \ 89 mfcr %r29; /* save CR */ \ 90 mfsrr0 %r30; \ 91 mfsrr1 %r31; /* Test whether we already had PR set */ \ 92 stmw %r30,(savearea+CPUSAVE_SRR0)(%r1); /* save srr0/srr1 */ \ 93 mtcr %r31; \ 94 bc %cr4,MSR_PR,1f; /* branch if MSR[PR] is clear */ \ 95 lwz %r1,CI_CURPCB(%r1); \ 96 addi %r1,%r1,USPACE-CALLFRAMELEN; /* stack is top of user struct */ \ 971: 98 99#define ACCESS_PROLOG(savearea) \ 100 mtsprg1 %r1; /* save SP */ \ 101 GET_CPUINFO(%r1); \ 102 stmw %r28,(savearea+CPUSAVE_R28)(%r1); /* free r28-r31 */ \ 103 mflr %r28; /* save LR */ \ 104 mfcr %r29; /* save CR */ \ 105 mfdear %r30; \ 106 mfesr %r31; \ 107 stmw %r30,(savearea+CPUSAVE_DEAR)(%r1); \ 108 mfsrr0 %r30; \ 109 mfsrr1 %r31; /* Test whether we already had PR set */ \ 110 stmw %r30,(savearea+CPUSAVE_SRR0)(%r1); /* save srr0/srr1 */ \ 111 mtcr %r31; \ 112 bc %cr4,MSR_PR,1f; /* branch if MSR[PR] is clear */ \ 113 lwz %r1,CI_CURPCB(%r1); \ 114 addi %r1,%r1,USPACE-CALLFRAMELEN; /* stack is top of user struct */ \ 1151: 116 117#define CRITICAL_PROLOG(savearea) \ 118 mtsprg1 %r1; /* save SP */ \ 119 GET_CPUINFO(%r2); \ 120 stmw %r28,(savearea+CPUSAVE_R28)(%r1); /* free r28-r31 */ \ 121 mflr %r28; /* save LR */ \ 122 mfcr %r29; /* save CR */ \ 123 mfsrr2 %r30; /* Fake a standard trap */ \ 124 mfsrr3 %r31; /* Test whether we already had PR set */ \ 125 stmw %r30,(savearea+CPUSAVE_SRR0)(%r1); /* save srr0/srr1 */ \ 126 mtcr %r31; \ 127 bc %cr4,MSR_PR,1f; /* branch if MSR[PR] is clear */ \ 128 lwz %r1,CI_CURPCB(%r1); \ 129 addi %r1,%r1,USPACE-CALLFRAMELEN; /* 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(CI_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 ACCESS_PROLOG(CI_TEMPSAVE); \ 146 bla s_trap ; \ 147_C_LABEL(name ## size) = .-_C_LABEL(name ## trap) 148 149/* Maybe this should call ddb.... */ 150#define CRITICAL_EXC_HANDLER(name)\ 151 .globl _C_LABEL(name ## trap),_C_LABEL(name ## size) ; \ 152_C_LABEL(name ## trap): \ 153 CRITICAL_PROLOG(CI_TEMPSAVE); \ 154 bla s_trap ; \ 155_C_LABEL(name ## size) = .-_C_LABEL(name ## trap) 156 157#define INTR_PROLOG(tempsave) \ 158 mtsprg1 %r1; /* save SP */ \ 159 GET_CPUINFO(%r1); \ 160 stmw %r28,(tempsave+CPUSAVE_R28)(%r1); /* free r28-r31 */ \ 161 mflr %r28; /* save LR */ \ 162 mfcr %r29; /* save CR */ \ 163 mfxer %r30; /* save XER */ \ 164 lwz %r31,CI_IDEPTH(%r1); /* already running on intstk? */ \ 165 addic. %r31,%r31,1; \ 166 stw %r31,CI_IDEPTH(%r1); \ 167 lwz %r1,CI_INTSTK(%r1); /* get intstk */ \ 168 beq 1f; \ 169 mfsprg1 %r1; /* yes, get old SP */ \ 1701: 171 172/* 173 * This code gets copied to all the trap vectors 174 * (except ISI/DSI, ALI, the interrupts, and possibly the debugging 175 * traps when using IPKDB). 176 */ 177 .text 178 STANDARD_EXC_HANDLER(default) 179 ACCESS_EXC_HANDLER(ali) 180 ACCESS_EXC_HANDLER(dsi) 181 ACCESS_EXC_HANDLER(isi) 182 STANDARD_EXC_HANDLER(debug) 183 CRITICAL_EXC_HANDLER(mchk) 184 185/* 186 * This one for the external interrupt handler. 187 */ 188 .globl _C_LABEL(extint),_C_LABEL(extsize) 189_C_LABEL(extint): 190 INTR_PROLOG(CI_TEMPSAVE) 191 ba extintr 192_C_LABEL(extsize) = .-_C_LABEL(extint) 193 194 195#if defined(DDB) || defined(KGDB) 196/* 197 * In case of DDB we want a separate trap catcher for it 198 */ 199 .lcomm ddbstk,INTSTK,16 /* ddb stack */ 200 201 .globl _C_LABEL(ddblow),_C_LABEL(ddbsize) 202_C_LABEL(ddblow): 203 mtsprg1 %r1 /* save SP */ 204 GET_CPUINFO(%r1) 205 stmw %r28,CI_DDBSAVE(%r1) /* free r28-r31 */ 206 mflr %r28 /* save LR */ 207 mfcr %r29 /* save CR */ 208 lis %r1,ddbstk+INTSTK-CALLFRAMELEN@ha /* get new SP */ 209 addi %r1,%r1,ddbstk+INTSTK-CALLFRAMELEN@l 210 bla ddbtrap 211_C_LABEL(ddbsize) = .-_C_LABEL(ddblow) 212#endif /* DDB || KGDB */ 213 214#ifdef IPKDB 215/* 216 * In case of IPKDB we want a separate trap catcher for it 217 */ 218 219 .lcomm ipkdbstk,INTSTK,16 /* ipkdb stack */ 220 221 .globl _C_LABEL(ipkdblow),_C_LABEL(ipkdbsize) 222_C_LABEL(ipkdblow): 223 mtsprg1 %r1 /* save SP */ 224 GET_CPUINFO(%r1) 225 stmw %r28,CI_IPKDBSAVE(%r1) /* free r28-r31 */ 226 mflr %r28 /* save LR */ 227 mfcr %r29 /* save CR */ 228 lis %r1,ipkdbstk+INTSTK-CALLFRAMELEN@ha /* get new SP */ 229 addi %r1,%r1,ipkdbstk+INTSTK-CALLFRAMELEN@l 230 bla ipkdbtrap 231_C_LABEL(ipkdbsize) = .-_C_LABEL(ipkdblow) 232#endif /* IPKDB */ 233 234#ifdef DEBUG 235#define TRAP_IF_ZERO(r) tweqi r,0 236#else 237#define TRAP_IF_ZERO(r) 238#endif 239 240#define ENABLE_TRANSLATION(pidreg,tmpreg) \ 241 mfpid pidreg; \ 242 li tmpreg, KERNEL_PID; \ 243 mtpid tmpreg; \ 244 mfmsr tmpreg; \ 245 ori tmpreg,tmpreg,(PSL_DR|PSL_IR)@l; \ 246 mtmsr tmpreg; \ 247 isync 248 249/* 250 * FRAME_SETUP assumes: 251 * SPRG1 SP (r1) 252 * savearea r28-r31,DEAR,ESR,SRR0,SRR1 (DEAR & ESR only for DSI traps) 253 * %r28 LR 254 * %r29 CR 255 * %r1 kernel stack 256 * LR trap type 257 */ 258#define FRAME_SETUP(savearea) \ 259/* Have to enable translation to allow access of kernel stack: */ \ 260 ENABLE_TRANSLATION(%r30,%r31); \ 261 mfsprg1 %r31; \ 262 stwu %r31,-FRAMELEN(%r1); \ 263 stw %r30,FRAME_PID(%r1); \ 264 stw %r0,FRAME_R0(%r1); \ 265 stw %r31,FRAME_R1(%r1); \ 266 stw %r2,FRAME_R2(%r1); \ 267 GET_CPUINFO(%r2); \ 268 stw %r28,FRAME_LR(%r1); \ 269 stw %r29,FRAME_CR(%r1); \ 270 lmw %r28,(savearea+CPUSAVE_R28)(%r2); \ 271 stmw %r3,FRAME_R3(%r1); \ 272 lmw %r28,(savearea+CPUSAVE_DEAR)(%r2); \ 273 mfxer %r3; \ 274 mfctr %r4; \ 275 mflr %r5; \ 276 andi. %r5,%r5,0xff00; \ 277 stw %r3,FRAME_XER(%r1); \ 278 stw %r4,FRAME_CTR(%r1); \ 279 stw %r5,FRAME_EXC(%r1); \ 280 stw %r28,FRAME_DEAR(%r1); \ 281 stw %r29,FRAME_ESR(%r1); \ 282 stw %r30,FRAME_SRR0(%r1); \ 283 stw %r31,FRAME_SRR1(%r1) 284 285#define FRAME_SAVE_CALLEE \ 286 stmw %r13, FRAME_R13(%r1) 287 288#define FRAME_RESTORE \ 289 lwz %r6,FRAME_LR(%r1); \ 290 lwz %r7,FRAME_CR(%r1); \ 291 lwz %r8,FRAME_XER(%r1); \ 292 lwz %r9,FRAME_CTR(%r1); \ 293 lwz %r10,FRAME_SRR0(%r1); \ 294 lwz %r11,FRAME_SRR1(%r1); \ 295 mtlr %r6; \ 296 mtcr %r7; \ 297 mtxer %r8; \ 298 mtctr %r9; \ 299 mtsrr0 %r10; \ 300 mtsrr1 %r11; \ 301 lwz %r12,FRAME_R12(%r1); \ 302 lwz %r11,FRAME_R11(%r1); \ 303 lwz %r10,FRAME_R10(%r1); \ 304 lwz %r9,FRAME_R9(%r1); \ 305 lwz %r8,FRAME_R8(%r1); \ 306 lwz %r7,FRAME_R7(%r1); \ 307 lwz %r6,FRAME_R6(%r1); \ 308 lwz %r5,FRAME_R5(%r1); \ 309 lwz %r4,FRAME_R4(%r1); \ 310 lwz %r3,FRAME_R3(%r1); \ 311 lwz %r2,FRAME_R2(%r1); \ 312 lwz %r0,FRAME_R1(%r1); \ 313 mtsprg1 %r0; \ 314 lwz %r0,FRAME_R0(%r1) 315 316/* 317 * Now the common trap catching code. 318 */ 319s_trap: 320 FRAME_SETUP(CI_TEMPSAVE) 321 /* R31 = SRR1 */ 322/* Now we can recover interrupts again: */ 323trapagain: 324 wrtee %r31 /* reenable interrupts */ 325/* Call C trap code: */ 326 addi %r3,%r1,FRAME_TF 327 bl _C_LABEL(trap) 328 .globl _C_LABEL(trapexit) 329_C_LABEL(trapexit): 330 /* Disable interrupts: */ 331 wrteei 0 332 333 /* Test AST pending: */ 334 mtcr %r31 335 bc %cr4,MSR_PR,trapleave_to_kernel /* branch if MSR[PR] is false */ 336 337 GET_CPUINFO(%r3) 338 lwz %r4,CI_ASTPENDING(%r3) 339 andi. %r4,%r4,1 340 beq trapleave_to_user 341 342 li %r6,EXC_AST 343 stw %r6,FRAME_EXC(%r1) 344 b trapagain 345 346trapleave_to_kernel: 347 lmw %r13, FRAME_R13(%r1) /* restore callee registers */ 348 349intrleave_to_kernel: 350 FRAME_RESTORE /* old SP is now in sprg1 */ 351 /* 352 * Now that we are done with the trapframe, we can load the original SP 353 */ 354 mfsprg1 %r1 355 rfi 356 ba . /* Protect against prefetch */ 357 358trapleave_to_user: 359 lmw %r13, FRAME_R13(%r1) /* restore callee registers */ 360 361intrleave_to_user: 362/* Now restore regs: */ 363 lwz %r3,FRAME_PID(%r1) 364 lwz %r4,FRAME_SRR1(%r1) 365 bl _C_LABEL(ctx_setup) 366 TRAP_IF_ZERO(%r3) 367 stw %r3,FRAME_PID(%r1) 368 369 FRAME_RESTORE /* old SP is now in sprg1 */ 370 371 /* 372 * We are returning to userspace so we need to switch PIDs. 373 * Since the kernel executes out of what would be userspace, 374 * we need to turn off translation before we set the PID. 375 * 376 * Alterantively, we could map a kernel page at 0xfffff000 377 * that had the mtpid code in it and branch to it and avoid 378 * all this. (ba foo; foo: mtpid %r31; mfsprg3 %r31; rfi;) 379 */ 380 mfmsr %r30 381 li %r31,(PSL_DR|PSL_IR)@l 382 andc %r30,%r30,%r31 383 lwz %r31,FRAME_PID(%r1) 384 TRAP_IF_ZERO(%r31) 385 /* 386 * Now that we are done with the trapframe, we can load the original SP 387 */ 388 mfsprg1 %r1 389 mtmsr %r30 /* disable translation */ 390 isync 391 mtpid %r31 392 mfsprg3 %r31 393 mfsprg2 %r30 394 rfi 395 ba . /* Protect against prefetch */ 396 397 398 .globl _C_LABEL(sctrap),_C_LABEL(scsize),_C_LABEL(sctrapexit) 399_C_LABEL(sctrap): 400 STANDARD_PROLOG(CI_TEMPSAVE) 401 bla s_sctrap 402_C_LABEL(scsize) = .-_C_LABEL(sctrap) 403 404s_sctrap: 405 FRAME_SETUP(CI_TEMPSAVE) 406/* Now we can recover interrupts again: */ 407 wrteei 1 /* Enable interrupts */ 408/* Call the appropriate syscall handler: */ 409 addi %r3,%r1,FRAME_TF 410 GET_CPUINFO(%r4) 411 lwz %r4,CI_CURLWP(%r4) 412 lwz %r4,L_PROC(%r4) 413 lwz %r4,P_MD_SYSCALL(%r4) 414 mtctr %r4 415 bctrl 416_C_LABEL(sctrapexit): 417 b trapexit 418 419/* 420 * External interrupt second level handler 421 */ 422 423#define INTR_SAVE(tempsave) \ 424/* Save non-volatile registers: */ \ 425 stwu %r1,-FRAMELEN(%r1); /* temporarily */ \ 426 stw %r0,FRAME_R0(%r1); \ 427 mfsprg1 %r0; /* get original SP */ \ 428 stw %r0,FRAME_R1(%r1); /* and store it */ \ 429 stw %r2,FRAME_R2(%r1); \ 430 stw %r3,FRAME_R3(%r1); \ 431 stw %r4,FRAME_R4(%r1); \ 432 stw %r5,FRAME_R5(%r1); \ 433 stw %r6,FRAME_R6(%r1); \ 434 stw %r7,FRAME_R7(%r1); \ 435 stw %r8,FRAME_R8(%r1); \ 436 stw %r9,FRAME_R9(%r1); \ 437 stw %r10,FRAME_R10(%r1); \ 438 stw %r11,FRAME_R11(%r1); \ 439 stw %r12,FRAME_R12(%r1); \ 440 mfctr %r31; \ 441 stmw %r28,FRAME_LR(%r1); /* save LR, CR, XER, CTR */ \ 442 GET_CPUINFO(%r5); \ 443 lmw %r28,(tempsave+CPUSAVE_R28)(%r5); /* restore r28-r31 */ \ 444 lwz %r5,CI_IDEPTH(%r5); \ 445 mfsrr0 %r4; \ 446 mfsrr1 %r3; \ 447 stw %r5,FRAME_IDEPTH(%r1); \ 448 stw %r4,FRAME_SRR0(%r1); \ 449 stw %r3,FRAME_SRR1(%r1); \ 450/* interrupts are recoverable here, and enable translation */ \ 451 ENABLE_TRANSLATION(%r0,%r5); \ 452 stw %r0,FRAME_PID(%r1); \ 453 454 .globl _C_LABEL(extint_call) 455extintr: 456 INTR_SAVE(CI_TEMPSAVE) 457_C_LABEL(extint_call): 458 bl _C_LABEL(extint_call) /* to be filled in later */ 459 460intr_exit: 461/* Disable interrupts */ 462 wrteei 0 463 isync 464 GET_CPUINFO(%r5) 465 lwz %r4,CI_IDEPTH(%r5) 466 addi %r4,%r4,-1 /* adjust reentrancy count */ 467 stw %r4,CI_IDEPTH(%r5) 468 469 lwz %r5,FRAME_SRR1(%r1) 470/* Returning to user mode? */ 471 mtcr %r5 /* saved SRR1 */ 472 bc %cr4,MSR_PR,intrleave_to_kernel /* branch if MSR[PR] is false */ 473 474 lwz %r4,CI_ASTPENDING(%r5) /* Test AST pending */ 475 andi. %r4,%r4,1 476 beq intrleave_to_user 477 478 FRAME_SAVE_CALLEE /* save rest of callee registers */ 479 li %r6,EXC_AST 480 stw %r6,FRAME_EXC(%r1) 481 mr %r31,%r5 /* move SRR1 to R31 */ 482 b trapagain 483 484/* 485 * PIT interrupt handler. 486 */ 487 .align 5 488_C_LABEL(pitint): 489 INTR_PROLOG(CI_TEMPSAVE) 490 INTR_SAVE(CI_TEMPSAVE) 491 addi %r3,%r1,FRAME_CF /* intr frame */ 492 bl _C_LABEL(decr_intr) 493 b intr_exit 494 495/* 496 * FIT interrupt handler. 497 */ 498 .align 5 499_C_LABEL(fitint): 500 INTR_PROLOG(CI_TEMPSAVE) 501 INTR_SAVE(CI_TEMPSAVE) 502 addi %r3,%r1,FRAME_TF /* intr frame */ 503 bl _C_LABEL(stat_intr) 504 b intr_exit 505 506#if defined(DDB) || defined(KGDB) 507/* 508 * Deliberate entry to ddbtrap 509 */ 510 .globl _C_LABEL(ddb_trap) 511_C_LABEL(ddb_trap): 512 mtsprg1 %r1 513 GET_CPUINFO(%r4) 514 mfmsr %r3 515 stw %r3,CI_DDBSAVE+CPUSAVE_SRR1(%r4) 516 wrteei 0 /* disable interrupts */ 517 isync 518 stmw %r28,CI_DDBSAVE(%r1) 519 mflr %r28 520 stw %r28,CI_DDBSAVE+CPUSAVE_SRR0(%r4) 521 li %r29,EXC_BPT 522 mtlr %r29 523 mfcr %r29 524 525/* 526 * Now the ddb/kgdb trap catching code. 527 */ 528ddbtrap: 529 FRAME_SETUP(CI_DDBSAVE) 530/* Call C trap code: */ 531 addi %r3,%r1,FRAME_TF 532 bl _C_LABEL(ddb_trap_glue) 533 or. %r3,%r3,%r3 534 addi %r3,%r1,FRAME_TF 535 beq trapagain 536 b trapexit 537#endif /* DDB || KGDB */ 538 539#ifdef IPKDB 540/* 541 * Deliberate entry to ipkdbtrap 542 */ 543 .globl _C_LABEL(ipkdb_trap) 544_C_LABEL(ipkdb_trap): 545 mtsprg1 %r1 546 GET_CPUINFO(%r4) 547 mfmsr %r3 548 stw %r3,(CI_IPKDBSAVE+CPUSAVE_SRR1)(%r4) 549 wrteei 0 /* disable interrupts */ 550 isync 551 stmw %r28,CI_IPKDBSAVE(%r4) 552 mflr %r28 553 stw %r28,(CI_IPKDBSAVE+CPUSAVE_SRR0)(%r4) 554 li %r29,EXC_BPT 555 mtlr %r29 556 mfcr %r29 557 558/* 559 * Now the ipkdb trap catching code. 560 */ 561ipkdbtrap: 562 FRAME_SETUP(CI_IPKDBSAVE) 563/* Call C trap code: */ 564 addi %r3,%r1,FRAME_TF 565 bl _C_LABEL(ipkdb_trap_glue) 566 or. %r3,%r3,%r3 567 beq trapagain 568 b trapexit 569 570ipkdbfault: 571 ba _ipkdbfault 572_ipkdbfault: 573 mfsrr0 %r3 574 addi %r3,%r3,4 575 mtsrr0 %r3 576 li %r3,-1 577 rfi 578 ba . /* Protect against prefetch */ 579 580/* 581 * int ipkdbfbyte(unsigned char *p) 582 */ 583 .globl _C_LABEL(ipkdbfbyte) 584_C_LABEL(ipkdbfbyte): 585 li %r9,EXC_DSI /* establish new fault routine */ 586 lwz %r5,0(%r9) 587 lis %r6,ipkdbfault@ha 588 lwz %r6,ipkdbfault@l(%r6) 589 stw %r6,0(%r9) 590#ifdef IPKDBUSERHACK 591#ifndef PPC_IBM4XX 592 lis %r8,_C_LABEL(ipkdbsr)@ha 593 lwz %r8,_C_LABEL(ipkdbsr)@l(%r8) 594 mtsr USER_SR,%r8 595 isync 596#endif 597#endif 598 dcbst %r0,%r9 /* flush data... */ 599 sync 600 icbi %r0,%r9 /* and instruction caches */ 601 lbz %r3,0(%r3) /* fetch data */ 602 stw %r5,0(%r9) /* restore previous fault handler */ 603 dcbst %r0,%r9 /* and flush data... */ 604 sync 605 icbi %r0,%r9 /* and instruction caches */ 606 blr 607 608/* 609 * int ipkdbsbyte(unsigned char *p, int c) 610 */ 611 .globl _C_LABEL(ipkdbsbyte) 612_C_LABEL(ipkdbsbyte): 613 li %r9,EXC_DSI /* establish new fault routine */ 614 lwz %r5,0(%r9) 615 lis %r6,ipkdbfault@ha 616 lwz %r6,ipkdbfault@l(%r6) 617 stw %r6,0(%r9) 618#ifdef IPKDBUSERHACK 619#ifndef PPC_IBM4XX 620 lis %r8,_C_LABEL(ipkdbsr)@ha 621 lwz %r8,_C_LABEL(ipkdbsr)@l(%r8) 622 mtsr USER_SR,%r8 623 isync 624#endif 625#endif 626 dcbst %r0,%r9 /* flush data... */ 627 sync 628 icbi %r0,%r9 /* and instruction caches */ 629 mr %r6,%r3 630 xor %r3,%r3,%r3 631 stb %r4,0(%r6) 632 dcbst %r0,%r6 /* Now do appropriate flushes 633 to data... */ 634 sync 635 icbi %r0,%r6 /* and instruction caches */ 636 stw %r5,0(%r9) /* restore previous fault handler */ 637 dcbst %r0,%r9 /* and flush data... */ 638 sync 639 icbi %r0,%r9 /* and instruction caches */ 640 blr 641#endif /* IPKDB */ 642