1/* $OpenBSD: locore.S,v 1.64 2023/12/12 07:37:21 deraadt Exp $ */ 2/* $NetBSD: locore.S,v 1.2 1996/10/16 19:33:09 ws Exp $ */ 3 4/* 5 * Copyright (C) 1995, 1996 Wolfgang Solfrank. 6 * Copyright (C) 1995, 1996 TooLs GmbH. 7 * All rights reserved. 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 by TooLs GmbH. 20 * 4. The name of TooLs GmbH may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 29 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 31 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35#include "assym.h" 36 37#include <sys/syscall.h> 38 39#include <machine/asm.h> 40#include <machine/param.h> 41#include <machine/pmap.h> 42#include <machine/psl.h> 43#include <machine/trap.h> 44 45#define GET_CPUINFO(r) mfsprg r,0 46 47#define INTSTK (8*1024) /* 8K interrupt stack */ 48#define SPILLSTK (1*1024) 49#define DDBSTK (7*1024) 50 51 .text 52 53#ifdef MULTIPROCESSOR 54_ENTRY(cpu_spinup_trampoline) 55 lis %r3,cpu_hatch_stack@ha 56 lwz %r1,cpu_hatch_stack@l(%r3) 57 58 b cpu_hatch 59 /* NOTREACHED */ 60#endif 61 62/* 63 * void cpu_switchto(struct proc *old, struct proc *new) 64 * Switch from "old" proc to "new". 65 */ 66_ENTRY(cpu_switchto_asm) 67 mflr %r0 /* save lr */ 68 stw %r0,4(%r1) 69 stwu %r1,(-SFRAMELEN - 16)(%r1) 70 stw %r31,(SFRAMELEN + 12)(%r1) 71 stw %r30,(SFRAMELEN + 8)(%r1) 72 73/* 74 * r3 - old proc 75 * r4 - new proc 76 * r5 - cpuinfo 77 */ 78 GET_CPUINFO(%r5) 79 80 li %r31,SONPROC 81 stb %r31,P_STAT(%r4) 82 83 or. %r3,%r3,%r3 /* old process was exiting? */ 84 beq switch_exited 85 86 mfsr %r10,PPC_USER_SR /* save PPC_USER_SR for copyin/copyout*/ 87 mfcr %r11 /* save cr */ 88 mr %r12,%r2 /* save r2 */ 89 stmw %r10,8(%r1) 90 lwz %r31,P_ADDR(%r3) 91 stw %r1,PCB_SP(%r31) /* save SP */ 92 93switch_exited: 94 /* disable interrupts while actually switching */ 95 mfmsr %r30 96 andi. %r30,%r30,~PSL_EE@l 97 mtmsr %r30 98 isync 99 100 stw %r4,CI_CURPROC(%r5) /* record new process */ 101 102#ifdef MULTIPROCESSOR 103 stw %r5,P_CPU(%r4) 104#endif 105 106 lwz %r31,P_ADDR(%r4) 107 stw %r31,CI_CURPCB(%r5) /* indicate new pcb */ 108 109 lwz %r6,PCB_PMR(%r31) 110 111 /* save real pmap pointer for spill fill */ 112 stwu %r6,CI_CURPM(%r5) 113 stwcx. %r6,%r0,%r5 /* clear possible reservation */ 114 115 addic. %r6,%r6,64 116 li %r5,0 117 118 lwz %r1,PCB_SP(%r31) /* get new procs SP */ 119 lwz %r0,(SFRAMELEN + 16 + 4)(%r1) 120 RETGUARD_SETUP_LATE(cpu_switchto_asm, %r9, %r0) 121 122 ori %r30,%r30,PSL_EE /* interrupts are okay again */ 123 mtmsr %r30 124 125 lmw %r10,8(%r1) /* get other regs */ 126 mr %r2,%r12 /* get saved r2 */ 127 mtcr %r11 /* get saved cr */ 128 isync 129 mtsr PPC_USER_SR,%r10 /* get saved PPC_USER_SR */ 130 isync 131 132 lwz %r31,(SFRAMELEN + 12)(%r1) 133 lwz %r30,(SFRAMELEN + 8)(%r1) 134 addi %r1,%r1,SFRAMELEN + 16 135 mtlr %r0 136 RETGUARD_CHECK(cpu_switchto_asm, %r9, %r0) 137 blr 138 139_ENTRY(cpu_idle_enter) 140 RETGUARD_SETUP(cpu_idle_enter, %r11, %r12) 141 lis %r4, ppc_cpuidle@ha 142 lwz %r4, ppc_cpuidle@l(%r4) 143 cmpwi %r4, 0 144 beq 1f 145 /* must disable external interrupts during idle queue checking */ 146 mfmsr %r3 147 andi. %r3,%r3,~PSL_EE@l 148 mtmsr %r3 149 isync 1501: 151 RETGUARD_CHECK(cpu_idle_enter, %r11, %r12) 152 blr 153 154_ENTRY(cpu_idle_cycle) 155 RETGUARD_SETUP(cpu_idle_cycle, %r11, %r12) 156 lis %r4, ppc_cpuidle@ha 157 lwz %r4, ppc_cpuidle@l(%r4) 158 cmpwi %r4, 0 159 beq idledone 160 161 /* 162 * Interrupts were disabled in cpu_idle_enter, but must be 163 * enabled for sleeping, but before that indicate that we 164 * are entering sleep mode. 165 */ 166 GET_CPUINFO(%r4) 167 lwz %r6,CI_FLAGS(%r4) 168 ori %r6,%r6,CI_FLAGS_SLEEPING@l 169 stw %r6,CI_FLAGS(%r4) 170 171 /* enable interrupts, required before setting POW */ 172 mfmsr %r3 173 ori %r5,%r3,PSL_EE@l 174 mtmsr %r5 175 oris %r5, %r5, PSL_POW@h 176 sync 177 /* low power mode */ 178 mtmsr %r5 179 sync 180 isync 181 182 /* 183 * restore interrupts to disabled, so CI_FLAGS is only modified 184 * with interrupts disabled. 185 */ 186 mtmsr %r3 187 isync 188 189 /* clear CI_FLAGS_SLEEPING since sleeping is over */ 190 andi. %r6,%r6,~CI_FLAGS_SLEEPING@l 191 stw %r6,CI_FLAGS(%r4) 192idledone: 193 RETGUARD_CHECK(cpu_idle_cycle, %r11, %r12) 194 blr 195 196_ENTRY(cpu_idle_leave) 197 RETGUARD_SETUP(cpu_idle_leave, %r11, %r12) 198 lis %r4, ppc_cpuidle@ha 199 lwz %r4, ppc_cpuidle@l(%r4) 200 cmpwi %r4, 0 201 beq 1f 202 /* enable interrupts disabled in cpu_idle_enter. */ 203 mfmsr %r3 204 ori %r3,%r3,PSL_EE@l 205 mtmsr %r3 2061: 207 RETGUARD_CHECK(cpu_idle_leave, %r11, %r12) 208 blr 209 210/* 211 * This code gets copied to all the trap vectors 212 * except ISI/DSI, ALI, and the interrupts 213 */ 214 .text 215 .globl trapcode,trapsize 216 .type trapcode,@function 217 .type trapsize,@object 218trapcode: 219 mtsprg 1,%r1 /* save SP */ 220nop32_1s: 221 mfmsr %r1 222 clrldi %r1,%r1,1 223 mtmsrd %r1 224nop32_1e: 225 GET_CPUINFO(%r1) 226 stmw %r28,CI_TEMPSAVE(%r1) /* free r28-r31 */ 227 mflr %r28 /* save LR */ 228 mfcr %r29 /* save CR */ 229 mfsprg %r1,1 /* restore SP */ 230 231 /* Test whether we already had PR set */ 232 mfsrr1 %r31 233 mtcr %r31 234 bc 4,17,1f /* branch if PSL_PR is clear */ 235 GET_CPUINFO(%r1) 236 lwz %r1,CI_CURPCB(%r1) 237 addi %r1,%r1,USPACE /* stack is top of user struct */ 2381: 239 bla s_trap 240trapsize = .-trapcode 241 242/* 243 * For ALI: has to save DSISR and DAR 244 */ 245 .globl alitrap,alisize 246alitrap: 247 mtsprg 1,%r1 /* save SP */ 248nop32_2s: 249 mfmsr %r1 250 clrldi %r1,%r1,1 251 mtmsrd %r1 252nop32_2e: 253 GET_CPUINFO(%r1) 254 stmw %r28,CI_TEMPSAVE(%r1) /* free r28-r31 */ 255 mfdar %r30 256 mfdsisr %r31 257 stmw %r30,CI_TEMPSAVE+16(%r1) 258 mflr %r28 /* save LR */ 259 mfcr %r29 /* save CR */ 260 mfsprg %r1,1 /* restore SP */ 261 262 /* Test whether we already had PR set */ 263 mfsrr1 %r31 264 mtcr %r31 265 bc 4,17,1f /* branch if PSL_PR is clear */ 266 GET_CPUINFO(%r1) 267 lwz %r1,CI_CURPCB(%r1) 268 addi %r1,%r1,USPACE /* stack is top of user struct */ 2691: 270 bla s_trap 271alisize = .-alitrap 272 273/* 274 * Similar to the above for DSI 275 * Has to handle BAT spills 276 * and standard pagetable spills 277 */ 278 .globl dsitrap,dsisize 279 .type dsitrap,@function 280 .type dsisize,@object 281dsitrap: 282 mtsprg 1,%r1 283 GET_CPUINFO(%r1) 284 stmw %r28,CI_DISISAVE(%r1) /* free r28-r31 */ 285nop32_3s: 286 mfmsr %r28 287 clrldi %r28,%r28,1 288 mtmsrd %r28 289nop32_3e: 290 mfsprg %r1,1 291 mfcr %r29 /* save CR */ 292 mfxer %r30 /* save XER */ 293 mtsprg 2,%r30 /* in SPRG2 */ 294 mfsrr1 %r31 /* test kernel mode */ 295nopbat_1s: 296 mtcr %r31 297 bc 12,17,1f /* branch if PSL_PR is set */ 298 mfdar %r31 /* get fault address */ 299 rlwinm %r31,%r31,7,25,28 /* get segment * 8 */ 300 addis %r31,%r31,battable@ha 301 lwz %r30,battable@l(%r31) /* get batu */ 302 mtcr %r30 303 bc 4,30,1f /* branch if supervisor valid is false */ 304 lwz %r31,battable+4@l(%r31) /* get batl */ 305/* We randomly use the highest two bat registers here */ 306 mftb %r28 307 andi. %r28,%r28,1 308 bne 2f 309 mtdbatu 2,%r30 310 mtdbatl 2,%r31 311 b 3f 3122: 313 mtdbatu 3,%r30 314 mtdbatl 3,%r31 3153: 316 mfsprg %r30,2 /* restore XER */ 317 mtxer %r30 318 mtcr %r29 /* restore CR */ 319 mtsprg 1,%r1 320 GET_CPUINFO(%r1) 321 lmw %r28,CI_DISISAVE(%r1) /* restore r28-r31 */ 322 mfsprg 1,%r1 323 rfi /* return to trapped code */ 3241: 325nopbat_1e: 326 mflr %r28 /* save LR */ 327 bla s_dsitrap 328dsisize = .-dsitrap 329 330/* 331 * Similar to the above for ISI 332 */ 333 .globl isitrap,isisize 334 .type isitrap,@function 335 .type isisize,@object 336isitrap: 337 mtsprg 1,%r1 /* save SP */ 338nop32_4s: 339 mfmsr %r1 340 clrldi %r1,%r1,1 341 mtmsrd %r1 342nop32_4e: 343 GET_CPUINFO(%r1) 344 stmw %r28,CI_DISISAVE(%r1) /* free r28-r31 */ 345 mflr %r28 /* save LR */ 346 mfcr %r29 /* save CR */ 347 mfsrr1 %r31 /* test kernel mode */ 348 mfsprg %r1,1 /* restore SP */ 349 bla s_isitrap 350isisize = .-isitrap 351 352/* 353 * This one for the external interrupt handler. 354 */ 355 .globl extint,extsize 356 .type extint,@function 357 .type extsize,@object 358extint: 359 mtsprg 1,%r1 /* save SP */ 360nop32_5s: 361 mfmsr %r1 362 clrldi %r1,%r1,1 363 mtmsrd %r1 364nop32_5e: 365 GET_CPUINFO(%r1) 366 stmw %r28,CI_TEMPSAVE(%r1) /* free r28-r31 */ 367 mflr %r28 /* save LR */ 368 mfcr %r29 /* save CR */ 369 mfxer %r30 /* save XER */ 370 lwz %r31,CI_INTRDEPTH(%r1) /* were we already running on intstk? */ 371 addic. %r31,%r31,1 372 stw %r31,CI_INTRDEPTH(%r1) 373 lwz %r1,CI_INTSTK(%r1) /* get interrupt stack */ 374 beq 1f 375 mfsprg %r1,1 /* yes, get old SP */ 3761: 377 ba extintr 378extsize = .-extint 379 380/* 381 * And this one for the decrementer interrupt handler. 382 */ 383 .globl decrint,decrsize 384 .type decrint,@function 385 .type decrsize,@object 386decrint: 387 mtsprg 1,%r1 /* save SP */ 388nop32_6s: 389 mfmsr %r1 390 clrldi %r1,%r1,1 391 mtmsrd %r1 392nop32_6e: 393 GET_CPUINFO(%r1) 394 stmw %r28,CI_TEMPSAVE(%r1) /* free r28-r31 */ 395 mflr %r28 /* save LR */ 396 mfcr %r29 /* save CR */ 397 mfxer %r30 /* save XER */ 398 lwz %r31,CI_INTRDEPTH(%r1) /* were we already running on intstk? */ 399 addic. %r31,%r31,1 400 stw %r31,CI_INTRDEPTH(%r1) 401 lwz %r1,CI_INTSTK(%r1) /* get interrupt stack */ 402 beq 1f 403 mfsprg %r1,1 /* yes, get old SP */ 4041: 405 ba decrintr 406decrsize = .-decrint 407 408/* 409 * Now the tlb software load for 603 processors: 410 * (Code essentially from the 603e User Manual, Chapter 5) 411 */ 412#define DMISS 976 413#define DCMP 977 414#define HASH1 978 415#define HASH2 979 416#define IMISS 980 417#define ICMP 981 418#define RPA 982 419 420#define bdneq bdnzf 2, 421#define tlbli .long 0x7c0007e4+0x800* 422#define tlbld .long 0x7c0007a4+0x800* 423 424 .globl tlbimiss,tlbimsize 425 .type tlbimiss,@function 426 .type tlbimsize,@object 427tlbimiss: 428 mfspr %r2,HASH1 /* get first pointer */ 429 li %r1,8 430 mfctr %r0 /* save counter */ 431 mfspr %r3,ICMP /* get first compare value */ 432 addi %r2,%r2,-8 /* predec pointer */ 4331: 434 mtctr %r1 /* load counter */ 4352: 436 lwzu %r1,8(%r2) /* get next pte */ 437 cmplw 0,%r1,%r3 /* see if found pte */ 438 bdneq 2b /* loop if not eq */ 439 bne 3f /* not found */ 440 lwz %r1,4(%r2) /* load tlb entry lower word */ 441 andi. %r3,%r1,8 /* check G-bit */ 442 bne 4f /* if guarded, take ISI */ 443 mtctr %r0 /* restore counter */ 444 mfspr %r0,IMISS /* get the miss address for the tlbli */ 445 mfsrr1 %r3 /* get the saved cr0 bits */ 446 mtcrf 0x80,%r3 /* and restore */ 447 ori %r1,%r1,0x100 /* set the reference bit */ 448 mtspr RPA,%r1 /* set the pte */ 449 srwi %r1,%r1,8 /* get byte 7 of pte */ 450 tlbli 0 /* load the itlb */ 451 stb %r1,6(%r2) /* update page table */ 452 rfi 453 4543: /* not found in pteg */ 455 andi. %r1,%r3,0x40 /* have we already done second hash? */ 456 bne 5f 457 mfspr %r2,HASH2 /* get the second pointer */ 458 ori %r3,%r3,0x40 /* change the compare value */ 459 li %r1,8 460 addi %r2,%r2,-8 /* predec pointer */ 461 b 1b 4624: /* guarded */ 463 mfsrr1 %r3 464 andi. %r2,%r3,0xffff /* clean upper srr1 */ 465 addis %r2,%r2,0x800 /* set srr<4> to flag prot violation */ 466 b 6f 4675: /* not found anywhere */ 468 mfsrr1 %r3 469 andi. %r2,%r3,0xffff /* clean upper srr1 */ 470 addis %r2,%r2,0x4000 /* set srr1<1> to flag pte not found */ 4716: 472 mtctr %r0 /* restore counter */ 473 mtsrr1 %r2 474 mfmsr %r0 475 xoris %r0,%r0,2 /* flip the msr<tgpr> bit */ 476 mtcrf 0x80,%r3 /* restore cr0 */ 477 mtmsr %r0 /* now with native gprs */ 478 isync 479 ba EXC_ISI 480tlbimsize = .-tlbimiss 481 482 .globl tlbdlmiss,tlbdlmsize 483 .type tlbdlmiss,@function 484 .type tlbdlmsize,@object 485tlbdlmiss: 486 mfspr %r2,HASH1 /* get first pointer */ 487 li %r1,8 488 mfctr %r0 /* save counter */ 489 mfspr %r3,DCMP /* get first compare value */ 490 addi %r2,%r2,-8 /* predec pointer */ 4911: 492 mtctr %r1 /* load counter */ 4932: 494 lwzu %r1,8(%r2) /* get next pte */ 495 cmplw 0,%r1,%r3 /* see if found pte */ 496 bdneq 2b /* loop if not eq */ 497 bne 3f /* not found */ 498 lwz %r1,4(%r2) /* load tlb entry lower word */ 499 mtctr %r0 /* restore counter */ 500 mfspr %r0,DMISS /* get the miss address for the tlbld */ 501 mfsrr1 %r3 /* get the saved cr0 bits */ 502 mtcrf 0x80,%r3 /* and restore */ 503 ori %r1,%r1,0x100 /* set the reference bit */ 504 mtspr RPA,%r1 /* set the pte */ 505 srwi %r1,%r1,8 /* get byte 7 of pte */ 506 tlbld 0 /* load the dtlb */ 507 stb %r1,6(%r2) /* update page table */ 508 rfi 509 5103: /* not found in pteg */ 511 andi. %r1,%r3,0x40 /* have we already done second hash? */ 512 bne 5f 513 mfspr %r2,HASH2 /* get the second pointer */ 514 ori %r3,%r3,0x40 /* change the compare value */ 515 li %r1,8 516 addi %r2,%r2,-8 /* predec pointer */ 517 b 1b 5185: /* not found anywhere */ 519 mfsrr1 %r3 520 lis %r1,0x4000 /* set dsisr<1> to flag pte not found */ 521 mtctr %r0 /* restore counter */ 522 andi. %r2,%r3,0xffff /* clean upper srr1 */ 523 mtsrr1 %r2 524 mtdsisr %r1 /* load the dsisr */ 525 mfspr %r1,DMISS /* get the miss address */ 526 mtdar %r1 /* put in dar */ 527 mfmsr %r0 528 xoris %r0,%r0,2 /* flip the msr<tgpr> bit */ 529 mtcrf 0x80,%r3 /* restore cr0 */ 530 mtmsr %r0 /* now with native gprs */ 531 isync 532 ba EXC_DSI 533tlbdlmsize = .-tlbdlmiss 534 535 .globl tlbdsmiss,tlbdsmsize 536 .type tlbdsmiss,@function 537 .type tlbdsmsize,@object 538tlbdsmiss: 539 mfspr %r2,HASH1 /* get first pointer */ 540 li %r1,8 541 mfctr %r0 /* save counter */ 542 mfspr %r3,DCMP /* get first compare value */ 543 addi %r2,%r2,-8 /* predec pointer */ 5441: 545 mtctr %r1 /* load counter */ 5462: 547 lwzu %r1,8(%r2) /* get next pte */ 548 cmplw 0,%r1,%r3 /* see if found pte */ 549 bdneq 2b /* loop if not eq */ 550 bne 3f /* not found */ 551 lwz %r1,4(%r2) /* load tlb entry lower word */ 552 andi. %r3,%r1,0x80 /* check the C-bit */ 553 beq 4f 5545: 555 mtctr %r0 /* restore counter */ 556 mfspr %r0,DMISS /* get the miss address for the tlbld */ 557 mfsrr1 %r3 /* get the saved cr0 bits */ 558 mtcrf 0x80,%r3 /* and restore */ 559 mtspr RPA,%r1 /* set the pte */ 560 tlbld 0 /* load the dtlb */ 561 rfi 562 5633: /* not found in pteg */ 564 andi. %r1,%r3,0x40 /* have we already done second hash? */ 565 bne 5f 566 mfspr %r2,HASH2 /* get the second pointer */ 567 ori %r3,%r3,0x40 /* change the compare value */ 568 li %r1,8 569 addi %r2,%r2,-8 /* predec pointer */ 570 b 1b 5714: /* found, but C-bit = 0 */ 572 rlwinm. %r3,%r1,30,0,1 /* test PP */ 573 bge- 7f 574 andi. %r3,%r1,1 575 beq+ 8f 5769: /* found, but protection violation (PP==00)*/ 577 mfsrr1 %r3 578 lis %r1,0xa00 /* indicate protection violation on store */ 579 b 1f 5807: /* found, PP=1x */ 581 mfspr %r3,DMISS /* get the miss address */ 582 mfsrin %r1,%r3 /* get the segment register */ 583 mfsrr1 %r3 584 rlwinm %r3,%r3,18,31,31 /* get PR-bit */ 585 rlwnm. %r1,%r1,%r3,1,1 /* get the key */ 586 bne- 9b /* protection violation */ 5878: /* found, set reference/change bits */ 588 lwz %r1,4(%r2) /* reload tlb entry */ 589 ori %r1,%r1,0x180 590 sth %r1,6(%r2) 591 b 5b 5925: /* not found anywhere */ 593 mfsrr1 %r3 594 lis %r1,0x4200 /* set dsisr<1> to flag pte not found */ 595 /* dsisr<6> to flag store */ 5961: 597 mtctr %r0 /* restore counter */ 598 andi. %r2,%r3,0xffff /* clean upper srr1 */ 599 mtsrr1 %r2 600 mtdsisr %r1 /* load the dsisr */ 601 mfspr %r1,DMISS /* get the miss address */ 602 mtdar %r1 /* put in dar */ 603 mfmsr %r0 604 xoris %r0,%r0,2 /* flip the msr<tgpr> bit */ 605 mtcrf 0x80,%r3 /* restore cr0 */ 606 mtmsr %r0 /* now with native gprs */ 607 isync 608 ba EXC_DSI 609tlbdsmsize = .-tlbdsmiss 610 611#ifdef DDB 612/* 613 * In case of DDB we want a separate trap catcher for it 614 */ 615 .globl ddblow,ddbsize 616ddblow: 617 mtsprg 1,%r1 /* save SP */ 618nop32_7s: 619 mfmsr %r1 620 clrldi %r1,%r1,1 621 mtmsrd %r1 622nop32_7e: 623 GET_CPUINFO(%r1) 624 stmw %r28,CI_DDBSAVE(%r1) /* free r28-r31 */ 625 mflr %r28 /* save LR */ 626 mfcr %r29 /* save CR */ 627 GET_CPUINFO(%r30) 628 lwz %r30,CI_INTSTK(%r30) /* get interrupt stack */ 629 addi %r1,%r30,(SPILLSTK+DDBSTK) 630 bla ddbtrap 631ddbsize = .-ddblow 632#endif /* DDB */ 633 634/* 635 * If this interrupt occurred between the runqueue check and the setting 636 * of the POW bit, do no enter to sleep. We do that in order to process 637 * the result of this interrupt directly and not when coming back from 638 * sleep, when the next clock tick or interrupt will fire. 639 */ 640#define CPU_IDLE_CHECK(sr1,sr2,sr3,rSRR0,flag) \ 641 GET_CPUINFO(sr1); \ 642 lwz sr2,CI_FLAGS(sr1); \ 643 andi. sr3,sr2,flag@l; \ 644 beq 1f; \ 645 andi. sr2,sr2,~flag@l; \ 646 stw sr2,CI_FLAGS(sr1); \ 647 lis rSRR0,idledone@ha; \ 648 addi rSRR0,rSRR0,idledone@l; \ 6491: 650 651/* 652 * FRAME_SETUP assumes: 653 * SPRG1 SP (1) 654 * savearea r28-r31,DAR,DSISR (DAR & DSISR only for DSI traps) 655 * 28 LR 656 * 29 CR 657 * 1 kernel stack 658 * LR trap type 659 * SRR0/1 as at start of trap 660 */ 661#define FRAME_SETUP(savearea) FRAME_SETUP_FLAG(savearea, CI_FLAGS_SLEEPING) 662 663#define FRAME_SETUP_FLAG(savearea, flag) \ 664/* Have to enable translation to allow access of kernel stack: */ \ 665 GET_CPUINFO(%r31); \ 666 mfsrr0 %r30; \ 667 stw %r30,savearea+24(%r31); \ 668 mfsrr1 %r30; \ 669 stw %r30,savearea+28(%r31); \ 670 /* load all kernel segment registers. */ \ 671 lis %r31,kernel_pmap_@ha; \ 672 addi %r31,%r31,kernel_pmap_@l; \ 673 lwz %r30,0(%r31); mtsr 0,%r30; \ 674 lwz %r30,4(%r31); mtsr 1,%r30; \ 675 lwz %r30,8(%r31); mtsr 2,%r30; \ 676 lwz %r30,12(%r31); mtsr 3,%r30; \ 677 lwz %r30,16(%r31); mtsr 4,%r30; \ 678 lwz %r30,20(%r31); mtsr 5,%r30; \ 679 lwz %r30,24(%r31); mtsr 6,%r30; \ 680 lwz %r30,28(%r31); mtsr 7,%r30; \ 681 lwz %r30,32(%r31); mtsr 8,%r30; \ 682 lwz %r30,36(%r31); mtsr 9,%r30; \ 683 lwz %r30,40(%r31); mtsr 10,%r30; \ 684 lwz %r30,44(%r31); mtsr 11,%r30; \ 685 lwz %r30,48(%r31); mtsr 12,%r30; \ 686/* lwz %r30,52(%r31); mtsr 13,%r30; - dont load user SR - XXX? */ \ 687 lwz %r30,56(%r31); mtsr 14,%r30; \ 688 lwz %r30,60(%r31); mtsr 15,%r30; \ 689 mfmsr %r30; \ 690 ori %r30,%r30,(PSL_DR|PSL_IR); \ 691 mtmsr %r30; \ 692 isync; \ 693 mfsprg %r31,1; \ 694 stwu %r31,-FRAMELEN(%r1); \ 695 stw %r0,FRAME_0+8(%r1); \ 696 stw %r31,FRAME_1+8(%r1); \ 697 stw %r2,FRAME_2+8(%r1); \ 698 stw %r28,FRAME_LR+8(%r1); \ 699 stw %r29,FRAME_CR+8(%r1); \ 700 GET_CPUINFO(%r2); \ 701 lmw %r28,savearea(%r2); \ 702 stmw %r3,FRAME_3+8(%r1); \ 703 lmw %r28,savearea+16(%r2); \ 704 mfxer %r3; \ 705 mfctr %r4; \ 706 mflr %r5; \ 707 andi. %r5,%r5,0xff00; \ 708 stw %r3,FRAME_XER+8(%r1); \ 709 stw %r4,FRAME_CTR+8(%r1); \ 710 stw %r5,FRAME_EXC+8(%r1); \ 711 stw %r28,FRAME_DAR+8(%r1); \ 712 stw %r29,FRAME_DSISR+8(%r1); \ 713 CPU_IDLE_CHECK(%r5,%r6,%r0,%r30,flag) \ 714 stw %r30,FRAME_SRR0+8(%r1); \ 715 stw %r31,FRAME_SRR1+8(%r1) 716 717#define FRAME_LEAVE(savearea) \ 718/* Now restore regs: */ \ 719 lwz %r2,FRAME_SRR0+8(%r1); \ 720 lwz %r3,FRAME_SRR1+8(%r1); \ 721 lwz %r4,FRAME_CTR+8(%r1); \ 722 lwz %r5,FRAME_XER+8(%r1); \ 723 lwz %r6,FRAME_LR+8(%r1); \ 724 GET_CPUINFO(%r7); \ 725 stw %r2,savearea(%r7); \ 726 stw %r3,savearea+4(%r7); \ 727 lwz %r7,FRAME_CR+8(%r1); \ 728 mtctr %r4; \ 729 mtxer %r5; \ 730 mtlr %r6; \ 731 mtsprg 1,%r7; /* save cr */ \ 732 lmw %r2,FRAME_2+8(%r1); \ 733 lwz %r0,FRAME_0+8(%r1); \ 734 lwz %r1,FRAME_1+8(%r1); \ 735 mtsprg 2,%r2; /* save r2 & r3 */ \ 736 mtsprg 3,%r3; \ 737/* Disable translation, machine check and recoverability: */ \ 738 mfmsr %r2; \ 739 lis %r3,(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@ha; \ 740 addi %r3,%r3,(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \ 741 andc %r2,%r2,%r3; \ 742 mtmsr %r2; \ 743 isync; \ 744/* Decide whether we return to user mode: */ \ 745 GET_CPUINFO(%r2); \ 746 lwz %r3,savearea+4(%r2); \ 747 mtcr %r3; \ 748 bc 4,17,1f; /* branch if PSL_PR is false */ \ 749/* Restore user & kernel access SR: */ \ 750 lwz %r2,CI_CURPM(%r2); /* get real address of pmap */ \ 751 lwz %r3,0(%r2); mtsr 0,%r3; \ 752 lwz %r3,4(%r2); mtsr 1,%r3; \ 753 lwz %r3,8(%r2); mtsr 2,%r3; \ 754 lwz %r3,12(%r2); mtsr 3,%r3; \ 755 lwz %r3,16(%r2); mtsr 4,%r3; \ 756 lwz %r3,20(%r2); mtsr 5,%r3; \ 757 lwz %r3,24(%r2); mtsr 6,%r3; \ 758 lwz %r3,28(%r2); mtsr 7,%r3; \ 759 lwz %r3,32(%r2); mtsr 8,%r3; \ 760 lwz %r3,36(%r2); mtsr 9,%r3; \ 761 lwz %r3,40(%r2); mtsr 10,%r3; \ 762 lwz %r3,44(%r2); mtsr 11,%r3; \ 763 lwz %r3,48(%r2); mtsr 12,%r3; \ 764 lwz %r3,52(%r2); mtsr 13,%r3; \ 765 lwz %r3,56(%r2); mtsr 14,%r3; \ 766 lwz %r3,60(%r2); mtsr 15,%r3; \ 7671: mfsprg %r2,1; /* restore cr */ \ 768 mtcr %r2; \ 769 GET_CPUINFO(%r2); \ 770 lwz %r3,savearea(%r2); \ 771 mtsrr0 %r3; \ 772 lwz %r3,savearea+4(%r2); \ 773 mtsrr1 %r3; \ 774 mfsprg %r2,2; /* restore r2 & r3 */ \ 775 mfsprg %r3,3 776 777/* 778 * Preamble code for DSI/ISI traps 779 */ 780disitrap: 781 GET_CPUINFO(%r1) 782 lmw %r30,CI_DISISAVE(%r1) 783 stmw %r30,CI_TEMPSAVE(%r1) 784 lmw %r30,CI_DISISAVE+8(%r1) 785 stmw %r30,CI_TEMPSAVE+8(%r1) 786 mfdar %r30 787 mfdsisr %r31 788 stmw %r30,CI_TEMPSAVE+16(%r1) 789realtrap: 790 /* Test whether we already had PR set */ 791 mfsrr1 %r1 792 mtcr %r1 793 /* restore SP (might have been overwritten) */ 794 mfsprg %r1,1 795 bc 4,17,s_trap /* branch if PSL_PR is false */ 796 GET_CPUINFO(%r1) 797 lwz %r1,CI_CURPCB(%r1) 798 addi %r1,%r1,USPACE /* stack is top of user struct */ 799/* 800 * Now the common trap catching code. 801 */ 802 .globl s_trap 803s_trap: 804 FRAME_SETUP(CI_TEMPSAVE) 805/* Now we can recover interrupts again: */ 806 mfmsr %r7 807 mfsrr1 %r31 808 andi. %r31,%r31,PSL_EE /* restore EE from previous context */ 809 or %r7,%r7,%r31 810 ori %r7,%r7,(PSL_ME|PSL_RI) 811 mtmsr %r7 812 isync 813/* Call C trap code: */ 814trapagain: 815 addi %r3,%r1,8 816 bl trap 817 818 .globl trapexit 819trapexit: 820/* Disable interrupts: */ 821 mfmsr %r3 822 andi. %r3,%r3,~PSL_EE@l 823 mtmsr %r3 824 isync 825/* Test AST pending: */ 826 lwz %r5,FRAME_SRR1+8(%r1) 827 mtcr %r5 828 bc 4,17,1f /* branch if PSL_PR is false */ 829 GET_CPUINFO(%r3) 830 lwz %r4,CI_CURPROC(%r3) 831 lwz %r4,P_MD_ASTPENDING(%r4) 832 andi. %r4,%r4,1 833 beq 1f 834 li %r6,EXC_AST 835 stw %r6,FRAME_EXC+8(%r1) 836 b trapagain 8371: 838 FRAME_LEAVE(CI_TEMPSAVE) 839rfi1: rfi 840 841/* 842 * Child comes here at the end of a fork. 843 * Mostly similar to the above. 844 */ 845 .globl proc_trampoline 846 .type proc_trampoline,@function 847proc_trampoline: 848 bl proc_trampoline_mi 849 mtlr %r31 850 mr %r3,%r30 851 blrl /* jump indirect to r31 */ 852 b trapexit 853 854/* 855 * DSI second stage fault handler 856 */ 857s_dsitrap: 858 mfdsisr %r31 /* test if this is spill fault */ 859 mtcr %r31 860 mtsprg 1,%r1 /* save SP */ 861 bc 4,1,disitrap /* branch if table miss is false */ 862 GET_CPUINFO(%r30) 863 lwz %r30,CI_INTSTK(%r30) /* get interrupt stack */ 864 addi %r1,%r30,SPILLSTK 865 stwu %r1,-52(%r1) 866 stw %r0,48(%r1) /* save non-volatile registers */ 867 stw %r3,44(%r1) 868 stw %r4,40(%r1) 869 stw %r5,36(%r1) 870 stw %r6,32(%r1) 871 stw %r7,28(%r1) 872 stw %r8,24(%r1) 873 stw %r9,20(%r1) 874 stw %r10,16(%r1) 875 stw %r11,12(%r1) 876 stw %r12,8(%r1) 877 mfxer %r30 /* save XER */ 878 mtsprg 2,%r30 879 mflr %r30 /* save trap type */ 880 mfctr %r31 /* & CTR */ 881 mfdar %r7 882 mfsrr1 %r4 883 mfdsisr %r5 884 li %r6, 0 885s_pte_spill: 886 andi. %r0,%r4,PSL_PR 887 li %r3,0 888 bne 1f 889 mr %r3,%r7 890 bl pte_spill_r /* try a spill */ 8911: 892 cmpwi 0,%r3,0 893 mtctr %r31 /* restore CTR */ 894 mtlr %r30 /* and trap type */ 895 mfsprg %r31,2 /* get saved XER */ 896 mtxer %r31 /* restore XER */ 897 lwz %r12,8(%r1) /* restore non-volatile registers */ 898 lwz %r11,12(%r1) 899 lwz %r10,16(%r1) 900 lwz %r9,20(%r1) 901 lwz %r8,24(%r1) 902 lwz %r7,28(%r1) 903 lwz %r6,32(%r1) 904 lwz %r5,36(%r1) 905 lwz %r4,40(%r1) 906 lwz %r3,44(%r1) 907 lwz %r0,48(%r1) 908 beq disitrap 909 mtcr %r29 /* restore CR */ 910 mtlr %r28 /* restore LR */ 911 GET_CPUINFO(%r1) 912 lmw %r28,CI_DISISAVE(%r1) /* restore r28-r31 */ 913 mfsprg %r1,1 /* restore SP */ 914rfi2: rfi /* return to trapped code */ 915 916/* 917 * ISI second stage fault handler 918 */ 919s_isitrap: 920 mfsrr1 %r31 /* test if this may be a spill fault */ 921 mtcr %r31 922 mtsprg 1,%r1 /* save SP */ 923 bc 4,1,disitrap /* branch if table miss is false */ 924 GET_CPUINFO(%r30) 925 lwz %r30,CI_INTSTK(%r30) /* get interrupt stack */ 926 addi %r1,%r30,SPILLSTK 927 stwu %r1,-52(%r1) 928 stw %r0,48(%r1) /* save non-volatile registers */ 929 stw %r3,44(%r1) 930 stw %r4,40(%r1) 931 stw %r5,36(%r1) 932 stw %r6,32(%r1) 933 stw %r7,28(%r1) 934 stw %r8,24(%r1) 935 stw %r9,20(%r1) 936 stw %r10,16(%r1) 937 stw %r11,12(%r1) 938 stw %r12,8(%r1) 939 mfxer %r30 /* save XER */ 940 mtsprg 2,%r30 941 mflr %r30 /* save trap type */ 942 mfctr %r31 /* & ctr */ 943 mfsrr0 %r7 944 mfsrr1 %r4 945 li %r5, 0 946 li %r6, 1 947 b s_pte_spill /* above */ 948 949/* 950 * External interrupt second level handler 951 */ 952#define INTRENTER \ 953/* Save non-volatile registers: */ \ 954 stwu %r1,-88(%r1); /* temporarily */ \ 955 stw %r0,84(%r1); \ 956 mfsprg %r0,1; /* get original SP */ \ 957 stw %r0,0(%r1); /* and store it */ \ 958 stw %r3,80(%r1); \ 959 stw %r4,76(%r1); \ 960 stw %r5,72(%r1); \ 961 stw %r6,68(%r1); \ 962 stw %r7,64(%r1); \ 963 stw %r8,60(%r1); \ 964 stw %r9,56(%r1); \ 965 stw %r10,52(%r1); \ 966 stw %r11,48(%r1); \ 967 stw %r12,44(%r1); \ 968 stw %r28,40(%r1); /* saved LR */ \ 969 stw %r29,36(%r1); /* saved CR */ \ 970 stw %r30,32(%r1); /* saved XER */ \ 971 GET_CPUINFO(%r4); \ 972 lmw %r28,CI_TEMPSAVE(%r4); /* restore r28-r31 */ \ 973 mfctr %r6; \ 974 lwz %r5,CI_INTRDEPTH(%r4); \ 975 mfsrr0 %r4; \ 976 mfsrr1 %r3; \ 977 stw %r6,28(%r1); \ 978 stw %r5,20(%r1); \ 979 stw %r4,12(%r1); \ 980 stw %r3,8(%r1); \ 981/* load all kernel segment registers. */ \ 982 lis 3,kernel_pmap_@ha; \ 983 addi 3,3,kernel_pmap_@l; \ 984 lwz %r5,0(%r3); mtsr 0,%r5; \ 985 lwz %r5,4(%r3); mtsr 1,%r5; \ 986 lwz %r5,8(%r3); mtsr 2,%r5; \ 987 lwz %r5,12(%r3); mtsr 3,%r5; \ 988 lwz %r5,16(%r3); mtsr 4,%r5; \ 989 lwz %r5,20(%r3); mtsr 5,%r5; \ 990 lwz %r5,24(%r3); mtsr 6,%r5; \ 991 lwz %r5,28(%r3); mtsr 7,%r5; \ 992 lwz %r5,32(%r3); mtsr 8,%r5; \ 993 lwz %r5,36(%r3); mtsr 9,%r5; \ 994 lwz %r5,40(%r3); mtsr 10,%r5; \ 995 lwz %r5,44(%r3); mtsr 11,%r5; \ 996 lwz %r5,48(%r3); mtsr 12,%r5; \ 997/* lwz %r5,52(%r3); mtsr 13,%r5; - dont load user SR - XXX? */ \ 998 lwz %r5,56(%r3); mtsr 14,%r5; \ 999 lwz %r5,60(%r3); mtsr 15,%r5; \ 1000/* interrupts are recoverable here, and enable translation */ \ 1001 mfmsr %r5; \ 1002 ori %r5,%r5,(PSL_IR|PSL_DR|PSL_RI); \ 1003 mtmsr %r5; \ 1004 isync 1005 1006 .globl extint_call 1007 .type extint_call,@function 1008extintr: 1009 INTRENTER 1010extint_call: 1011 bl extint_call /* to be filled in later */ 1012intr_exit: 1013/* Disable interrupts (should already be disabled) and MMU here: */ 1014 mfmsr %r3 1015 andi. %r3,%r3,~(PSL_EE|PSL_ME|PSL_RI|PSL_DR|PSL_IR)@l 1016 mtmsr %r3 1017 isync 1018/* restore possibly overwritten registers: */ 1019 lwz %r12,44(%r1) 1020 lwz %r11,48(%r1) 1021 lwz %r10,52(%r1) 1022 lwz %r9,56(%r1) 1023 lwz %r8,60(%r1) 1024 lwz %r7,64(%r1) 1025 lwz %r6,8(%r1) 1026 lwz %r5,12(%r1) 1027 lwz %r4,28(%r1) 1028 lwz %r3,32(%r1) 1029 mtsrr1 %r6 1030 mtsrr0 %r5 1031 mtctr %r4 1032 mtxer %r3 1033 1034 GET_CPUINFO(%r5) 1035 lwz %r4,CI_INTRDEPTH(%r5) 1036 addi %r4,%r4,-1 /* adjust reentrancy count */ 1037 stw %r4,CI_INTRDEPTH(%r5) 1038 1039/* Returning to user mode? */ 1040 mtcr %r6 /* saved SRR1 */ 1041 bc 4,17,1f /* branch if PSL_PR is false */ 1042 lwz %r3,CI_CURPM(%r5) /* get current pmap real address */ 1043 /* reload all segment registers. */ 1044 lwz %r4,0(3); mtsr 0,%r4; 1045 lwz %r4,4(3); mtsr 1,%r4; 1046 lwz %r4,8(3); mtsr 2,%r4; 1047 lwz %r4,12(3); mtsr 3,%r4; 1048 lwz %r4,16(3); mtsr 4,%r4; 1049 lwz %r4,20(3); mtsr 5,%r4; 1050 lwz %r4,24(3); mtsr 6,%r4; 1051 lwz %r4,28(3); mtsr 7,%r4; 1052 lwz %r4,32(3); mtsr 8,%r4; 1053 lwz %r4,36(3); mtsr 9,%r4; 1054 lwz %r4,40(3); mtsr 10,%r4; 1055 lwz %r4,44(3); mtsr 11,%r4; 1056 lwz %r4,48(3); mtsr 12,%r4; 1057 lwz %r4,52(3); mtsr 13,%r4; 1058 lwz %r4,56(3); mtsr 14,%r4; 1059 lwz %r4,60(3); mtsr 15,%r4; 1060 lwz %r4,CI_CURPROC(%r5) 1061 lwz %r4,P_MD_ASTPENDING(%r4) /* Test AST pending */ 1062 andi. %r4,%r4,1 1063 beq 1f 1064/* Setup for entry to realtrap: */ 1065 lwz %r3,0(%r1) /* get saved SP */ 1066 mtsprg 1,%r3 1067 li %r6,EXC_AST 1068 stmw %r28,CI_TEMPSAVE(%r5) /* establish tempsave again */ 1069 mtlr %r6 1070 lwz %r28,40(%r1) /* saved LR */ 1071 lwz %r29,36(%r1) /* saved CR */ 1072 lwz %r6,68(%r1) 1073 lwz %r5,72(%r1) 1074 lwz %r4,76(%r1) 1075 lwz %r3,80(%r1) 1076 lwz %r0,84(%r1) 1077 b realtrap 10781: 1079/* Here is the normal exit of extintr: */ 1080 lwz %r5,36(%r1) 1081 lwz %r6,40(%r1) 1082 mtcr %r5 1083 mtlr %r6 1084 lwz %r6,68(%r1) 1085 lwz %r5,72(%r1) 1086 lwz %r4,76(%r1) 1087 lwz %r3,80(%r1) 1088 lwz %r0,84(%r1) 1089 lwz %r1,0(%r1) 1090rfi3: rfi 1091 1092/* 1093 * Decrementer interrupt second level handler 1094 */ 1095 .globl decrintr 1096decrintr: 1097 INTRENTER 1098 addi %r3,%r1,8 /* intr frame */ 1099 bl decr_intr 1100 b intr_exit 1101 1102 1103/* 1104 * int setfault() 1105 * 1106 * Similar to setjmp to setup for handling faults on accesses to user memory. 1107 * Any routine using this may only call bcopy, either the form below, 1108 * or the (currently used) C code optimized, so it doesn't use any non-volatile 1109 * registers. 1110 */ 1111 .globl setfault 1112 .type setfault,@function 1113setfault: 1114 mflr %r0 1115 RETGUARD_SETUP_LATE(setfault, %r11, %r0) 1116 mfcr %r12 1117 GET_CPUINFO(%r4) 1118 lwz %r4,CI_CURPCB(%r4) 1119 stw %r3,PCB_FAULT(%r4) 1120 stw %r0,0(%r3) 1121 stw %r1,4(%r3) 1122 stmw %r12,8(%r3) 1123 li %r3,0 1124 RETGUARD_CHECK(setfault, %r11, %r0) 1125 blr 1126 1127/* 1128 * The following code gets copied to the top of the user stack on process 1129 * execution. It does signal trampolining on signal delivery. 1130 * 1131 * On entry r1 points to a struct sigframe at bottom of current stack. 1132 * All other registers are unchanged. 1133 */ 1134 .section .rodata 1135 .globl sigcode,esigcode 1136 .type sigcode,@function 1137 .type esigcode,@function 1138sigcode: 1139 addi %r1,%r1,-((16+FPSIG_SIZEOF+15)& ~0xf) /* reserved space for callee */ 1140 addi %r6,%r1,8 1141 stfd %f0,0(%r6) 1142 stfd %f1,8(%r6) 1143 stfd %f2,16(%r6) 1144 stfd %f3,24(%r6) 1145 stfd %f4,32(%r6) 1146 stfd %f5,40(%r6) 1147 stfd %f6,48(%r6) 1148 stfd %f7,56(%r6) 1149 stfd %f8,64(%r6) 1150 stfd %f9,72(%r6) 1151 stfd %f10,80(%r6) 1152 stfd %f11,88(%r6) 1153 stfd %f12,96(%r6) 1154 stfd %f13,104(%r6) 1155 mffs %f0 1156 stfd %f0,112(%r6) 1157 lfd %f0,0(%r6) /* restore the clobbered register */ 1158 blrl 1159 addi %r6,%r1,8 1160 lfd %f0,112(%r6) 1161 mtfsf 0xff,%f0 1162 lfd %f0,0(%r6) 1163 lfd %f1,8(%r6) 1164 lfd %f2,16(%r6) 1165 lfd %f3,24(%r6) 1166 lfd %f4,32(%r6) 1167 lfd %f5,40(%r6) 1168 lfd %f6,48(%r6) 1169 lfd %f7,56(%r6) 1170 lfd %f8,64(%r6) 1171 lfd %f9,72(%r6) 1172 lfd %f10,80(%r6) 1173 lfd %f11,88(%r6) 1174 lfd %f12,96(%r6) 1175 lfd %f13,104(%r6) 1176 addi %r3,%r1,((16+FPSIG_SIZEOF+15)&~0xf)+SF_SC /* compute &sf_sc */ 1177 li %r0,SYS_sigreturn 1178 .globl sigcodecall 1179sigcodecall: 1180 sc /* sigreturn(scp) */ 1181 .globl sigcoderet 1182sigcoderet: 1183esigcode: 1184 /* FALLTHROUGH */ 1185 .globl sigfill 1186sigfill: 1187 .long 0 # illegal 1188esigfill: 1189 .align 4 1190 .globl sigfillsiz 1191sigfillsiz: 1192 .long esigfill - sigfill 1193 1194 .text 1195 1196#ifdef DDB 1197/* 1198 * Deliberate entry to ddbtrap 1199 */ 1200 .globl ddb_trap 1201ddb_trap: 1202 mtsprg 1,%r1 1203 mfmsr %r3 1204 mtsrr1 %r3 1205 andi. %r3,%r3,~(PSL_EE|PSL_ME)@l 1206 mtmsr %r3 /* disable interrupts */ 1207 isync 1208 GET_CPUINFO(%r3) 1209 stmw %r28,CI_DDBSAVE(%r3) 1210 1211 mflr %r28 1212 li %r29,EXC_BPT 1213 mtlr %r29 1214 mfcr %r29 1215 mtsrr0 %r28 1216 1217/* 1218 * Now the ddb trap catching code. 1219 */ 1220ddbtrap: 1221 /* 1222 * Do not let FRAME_SETUP() change the return address of, and 1223 * corrupt, this frame. 1224 */ 1225 FRAME_SETUP_FLAG(CI_DDBSAVE, 0) 1226/* Call C trap code: */ 1227 addi %r3,%r1,8 1228 bl db_trap_glue 1229 or. %r3,%r3,%r3 1230 bne ddbleave 1231/* This wasn't for DDB, so switch to real trap: */ 1232 lwz %r3,FRAME_EXC+8(%r1) /* save exception */ 1233 GET_CPUINFO(%r4) 1234 stw %r3,CI_DDBSAVE+8(%r4) 1235 FRAME_LEAVE(CI_DDBSAVE) 1236 mtsprg 1,%r1 /* prepare for entrance to realtrap */ 1237 GET_CPUINFO(%r1) 1238 stmw %r28,CI_TEMPSAVE(%r1) 1239 mflr %r28 1240 mfcr %r29 1241 lwz %r31,CI_DDBSAVE+8(%r1) 1242 mtlr %r31 1243 b realtrap 1244ddbleave: 1245 FRAME_LEAVE(CI_DDBSAVE) 1246rfi4: rfi 1247#endif /* DDB */ 1248 1249 .globl rfi_inst 1250rfi_inst: 1251 rfi 1252 .globl rfid_inst 1253rfid_inst: 1254 rfid 1255 .globl nop_inst 1256 nop_inst: 1257 nop 1258 1259 .globl rfi_start 1260rfi_start: 1261 .long rfi1, rfi1 + 4 1262 .long rfi2, rfi2 + 4 1263 .long rfi3, rfi3 + 4 1264#ifdef DDB 1265 .long rfi4, rfi4 + 4 1266#endif 1267 .long 0, 0 1268 1269 1270 .globl nopbat_start 1271nopbat_start: 1272 .long nopbat_1s, nopbat_1e 1273 .long 0, 0 1274 1275 .globl nop32_start 1276nop32_start: 1277 .long nop32_1s, nop32_1e 1278 .long nop32_2s, nop32_2e 1279 .long nop32_3s, nop32_3e 1280 .long nop32_4s, nop32_4e 1281 .long nop32_5s, nop32_5e 1282 .long nop32_6s, nop32_6e 1283#ifdef DDB 1284 .long nop32_7s, nop32_7e 1285#endif 1286 .long 0, 0 1287