1/* $OpenBSD: locore.S,v 1.66 2024/10/24 17:37:06 gkoehler 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_IDEPTH(%r1) /* were we already running on intstk? */ 371 cmpwi %r31,0 372 addi %r31,%r31,1 373 stw %r31,CI_IDEPTH(%r1) 374 lwz %r1,CI_INTSTK(%r1) /* get interrupt stack */ 375 beq 1f 376 mfsprg %r1,1 /* yes, get old SP */ 3771: 378 ba extintr 379extsize = .-extint 380 381/* 382 * And this one for the decrementer interrupt handler. 383 */ 384 .globl decrint,decrsize 385 .type decrint,@function 386 .type decrsize,@object 387decrint: 388 mtsprg 1,%r1 /* save SP */ 389nop32_6s: 390 mfmsr %r1 391 clrldi %r1,%r1,1 392 mtmsrd %r1 393nop32_6e: 394 GET_CPUINFO(%r1) 395 stmw %r28,CI_TEMPSAVE(%r1) /* free r28-r31 */ 396 mflr %r28 /* save LR */ 397 mfcr %r29 /* save CR */ 398 mfxer %r30 /* save XER */ 399 lwz %r31,CI_IDEPTH(%r1) /* were we already running on intstk? */ 400 cmpwi %r31,0 401 addi %r31,%r31,1 402 stw %r31,CI_IDEPTH(%r1) 403 lwz %r1,CI_INTSTK(%r1) /* get interrupt stack */ 404 beq 1f 405 mfsprg %r1,1 /* yes, get old SP */ 4061: 407 ba decrintr 408decrsize = .-decrint 409 410/* 411 * Now the tlb software load for 603 processors: 412 * (Code essentially from the 603e User Manual, Chapter 5) 413 */ 414#define DMISS 976 415#define DCMP 977 416#define HASH1 978 417#define HASH2 979 418#define IMISS 980 419#define ICMP 981 420#define RPA 982 421 422#define bdneq bdnzf 2, 423#define tlbli .long 0x7c0007e4+0x800* 424#define tlbld .long 0x7c0007a4+0x800* 425 426 .globl tlbimiss,tlbimsize 427 .type tlbimiss,@function 428 .type tlbimsize,@object 429tlbimiss: 430 mfspr %r2,HASH1 /* get first pointer */ 431 li %r1,8 432 mfctr %r0 /* save counter */ 433 mfspr %r3,ICMP /* get first compare value */ 434 addi %r2,%r2,-8 /* predec pointer */ 4351: 436 mtctr %r1 /* load counter */ 4372: 438 lwzu %r1,8(%r2) /* get next pte */ 439 cmplw 0,%r1,%r3 /* see if found pte */ 440 bdneq 2b /* loop if not eq */ 441 bne 3f /* not found */ 442 lwz %r1,4(%r2) /* load tlb entry lower word */ 443 andi. %r3,%r1,8 /* check G-bit */ 444 bne 4f /* if guarded, take ISI */ 445 mtctr %r0 /* restore counter */ 446 mfspr %r0,IMISS /* get the miss address for the tlbli */ 447 mfsrr1 %r3 /* get the saved cr0 bits */ 448 mtcrf 0x80,%r3 /* and restore */ 449 ori %r1,%r1,0x100 /* set the reference bit */ 450 mtspr RPA,%r1 /* set the pte */ 451 srwi %r1,%r1,8 /* get byte 7 of pte */ 452 tlbli 0 /* load the itlb */ 453 stb %r1,6(%r2) /* update page table */ 454 rfi 455 4563: /* not found in pteg */ 457 andi. %r1,%r3,0x40 /* have we already done second hash? */ 458 bne 5f 459 mfspr %r2,HASH2 /* get the second pointer */ 460 ori %r3,%r3,0x40 /* change the compare value */ 461 li %r1,8 462 addi %r2,%r2,-8 /* predec pointer */ 463 b 1b 4644: /* guarded */ 465 mfsrr1 %r3 466 andi. %r2,%r3,0xffff /* clean upper srr1 */ 467 addis %r2,%r2,0x800 /* set srr<4> to flag prot violation */ 468 b 6f 4695: /* not found anywhere */ 470 mfsrr1 %r3 471 andi. %r2,%r3,0xffff /* clean upper srr1 */ 472 addis %r2,%r2,0x4000 /* set srr1<1> to flag pte not found */ 4736: 474 mtctr %r0 /* restore counter */ 475 mtsrr1 %r2 476 mfmsr %r0 477 xoris %r0,%r0,2 /* flip the msr<tgpr> bit */ 478 mtcrf 0x80,%r3 /* restore cr0 */ 479 mtmsr %r0 /* now with native gprs */ 480 isync 481 ba EXC_ISI 482tlbimsize = .-tlbimiss 483 484 .globl tlbdlmiss,tlbdlmsize 485 .type tlbdlmiss,@function 486 .type tlbdlmsize,@object 487tlbdlmiss: 488 mfspr %r2,HASH1 /* get first pointer */ 489 li %r1,8 490 mfctr %r0 /* save counter */ 491 mfspr %r3,DCMP /* get first compare value */ 492 addi %r2,%r2,-8 /* predec pointer */ 4931: 494 mtctr %r1 /* load counter */ 4952: 496 lwzu %r1,8(%r2) /* get next pte */ 497 cmplw 0,%r1,%r3 /* see if found pte */ 498 bdneq 2b /* loop if not eq */ 499 bne 3f /* not found */ 500 lwz %r1,4(%r2) /* load tlb entry lower word */ 501 mtctr %r0 /* restore counter */ 502 mfspr %r0,DMISS /* get the miss address for the tlbld */ 503 mfsrr1 %r3 /* get the saved cr0 bits */ 504 mtcrf 0x80,%r3 /* and restore */ 505 ori %r1,%r1,0x100 /* set the reference bit */ 506 mtspr RPA,%r1 /* set the pte */ 507 srwi %r1,%r1,8 /* get byte 7 of pte */ 508 tlbld 0 /* load the dtlb */ 509 stb %r1,6(%r2) /* update page table */ 510 rfi 511 5123: /* not found in pteg */ 513 andi. %r1,%r3,0x40 /* have we already done second hash? */ 514 bne 5f 515 mfspr %r2,HASH2 /* get the second pointer */ 516 ori %r3,%r3,0x40 /* change the compare value */ 517 li %r1,8 518 addi %r2,%r2,-8 /* predec pointer */ 519 b 1b 5205: /* not found anywhere */ 521 mfsrr1 %r3 522 lis %r1,0x4000 /* set dsisr<1> to flag pte not found */ 523 mtctr %r0 /* restore counter */ 524 andi. %r2,%r3,0xffff /* clean upper srr1 */ 525 mtsrr1 %r2 526 mtdsisr %r1 /* load the dsisr */ 527 mfspr %r1,DMISS /* get the miss address */ 528 mtdar %r1 /* put in dar */ 529 mfmsr %r0 530 xoris %r0,%r0,2 /* flip the msr<tgpr> bit */ 531 mtcrf 0x80,%r3 /* restore cr0 */ 532 mtmsr %r0 /* now with native gprs */ 533 isync 534 ba EXC_DSI 535tlbdlmsize = .-tlbdlmiss 536 537 .globl tlbdsmiss,tlbdsmsize 538 .type tlbdsmiss,@function 539 .type tlbdsmsize,@object 540tlbdsmiss: 541 mfspr %r2,HASH1 /* get first pointer */ 542 li %r1,8 543 mfctr %r0 /* save counter */ 544 mfspr %r3,DCMP /* get first compare value */ 545 addi %r2,%r2,-8 /* predec pointer */ 5461: 547 mtctr %r1 /* load counter */ 5482: 549 lwzu %r1,8(%r2) /* get next pte */ 550 cmplw 0,%r1,%r3 /* see if found pte */ 551 bdneq 2b /* loop if not eq */ 552 bne 3f /* not found */ 553 lwz %r1,4(%r2) /* load tlb entry lower word */ 554 andi. %r3,%r1,0x80 /* check the C-bit */ 555 beq 4f 5565: 557 mtctr %r0 /* restore counter */ 558 mfspr %r0,DMISS /* get the miss address for the tlbld */ 559 mfsrr1 %r3 /* get the saved cr0 bits */ 560 mtcrf 0x80,%r3 /* and restore */ 561 mtspr RPA,%r1 /* set the pte */ 562 tlbld 0 /* load the dtlb */ 563 rfi 564 5653: /* not found in pteg */ 566 andi. %r1,%r3,0x40 /* have we already done second hash? */ 567 bne 5f 568 mfspr %r2,HASH2 /* get the second pointer */ 569 ori %r3,%r3,0x40 /* change the compare value */ 570 li %r1,8 571 addi %r2,%r2,-8 /* predec pointer */ 572 b 1b 5734: /* found, but C-bit = 0 */ 574 rlwinm. %r3,%r1,30,0,1 /* test PP */ 575 bge- 7f 576 andi. %r3,%r1,1 577 beq+ 8f 5789: /* found, but protection violation (PP==00)*/ 579 mfsrr1 %r3 580 lis %r1,0xa00 /* indicate protection violation on store */ 581 b 1f 5827: /* found, PP=1x */ 583 mfspr %r3,DMISS /* get the miss address */ 584 mfsrin %r1,%r3 /* get the segment register */ 585 mfsrr1 %r3 586 rlwinm %r3,%r3,18,31,31 /* get PR-bit */ 587 rlwnm. %r1,%r1,%r3,1,1 /* get the key */ 588 bne- 9b /* protection violation */ 5898: /* found, set reference/change bits */ 590 lwz %r1,4(%r2) /* reload tlb entry */ 591 ori %r1,%r1,0x180 592 sth %r1,6(%r2) 593 b 5b 5945: /* not found anywhere */ 595 mfsrr1 %r3 596 lis %r1,0x4200 /* set dsisr<1> to flag pte not found */ 597 /* dsisr<6> to flag store */ 5981: 599 mtctr %r0 /* restore counter */ 600 andi. %r2,%r3,0xffff /* clean upper srr1 */ 601 mtsrr1 %r2 602 mtdsisr %r1 /* load the dsisr */ 603 mfspr %r1,DMISS /* get the miss address */ 604 mtdar %r1 /* put in dar */ 605 mfmsr %r0 606 xoris %r0,%r0,2 /* flip the msr<tgpr> bit */ 607 mtcrf 0x80,%r3 /* restore cr0 */ 608 mtmsr %r0 /* now with native gprs */ 609 isync 610 ba EXC_DSI 611tlbdsmsize = .-tlbdsmiss 612 613#ifdef DDB 614/* 615 * In case of DDB we want a separate trap catcher for it 616 */ 617 .globl ddblow,ddbsize 618ddblow: 619 mtsprg 1,%r1 /* save SP */ 620nop32_7s: 621 mfmsr %r1 622 clrldi %r1,%r1,1 623 mtmsrd %r1 624nop32_7e: 625 GET_CPUINFO(%r1) 626 stmw %r28,CI_DDBSAVE(%r1) /* free r28-r31 */ 627 mflr %r28 /* save LR */ 628 mfcr %r29 /* save CR */ 629 GET_CPUINFO(%r30) 630 lwz %r30,CI_INTSTK(%r30) /* get interrupt stack */ 631 addi %r1,%r30,(SPILLSTK+DDBSTK) 632 bla ddbtrap 633ddbsize = .-ddblow 634#endif /* DDB */ 635 636/* 637 * If this interrupt occurred between the runqueue check and the setting 638 * of the POW bit, do no enter to sleep. We do that in order to process 639 * the result of this interrupt directly and not when coming back from 640 * sleep, when the next clock tick or interrupt will fire. 641 */ 642#define CPU_IDLE_CHECK(sr1,sr2,sr3,rSRR0,flag) \ 643 GET_CPUINFO(sr1); \ 644 lwz sr2,CI_FLAGS(sr1); \ 645 andi. sr3,sr2,flag@l; \ 646 beq 1f; \ 647 andi. sr2,sr2,~flag@l; \ 648 stw sr2,CI_FLAGS(sr1); \ 649 lis rSRR0,idledone@ha; \ 650 addi rSRR0,rSRR0,idledone@l; \ 6511: 652 653/* 654 * FRAME_SETUP assumes: 655 * SPRG1 SP (1) 656 * savearea r28-r31,DAR,DSISR (DAR & DSISR only for DSI traps) 657 * 28 LR 658 * 29 CR 659 * 1 kernel stack 660 * LR trap type 661 * SRR0/1 as at start of trap 662 */ 663#define FRAME_SETUP(savearea) FRAME_SETUP_FLAG(savearea, CI_FLAGS_SLEEPING) 664 665#define FRAME_SETUP_FLAG(savearea, flag) \ 666/* Have to enable translation to allow access of kernel stack: */ \ 667 GET_CPUINFO(%r31); \ 668 mfsrr0 %r30; \ 669 stw %r30,savearea+24(%r31); \ 670 mfsrr1 %r30; \ 671 stw %r30,savearea+28(%r31); \ 672 /* load all kernel segment registers. */ \ 673 lis %r31,kernel_pmap_@ha; \ 674 addi %r31,%r31,kernel_pmap_@l; \ 675 lwz %r30,0(%r31); mtsr 0,%r30; \ 676 lwz %r30,4(%r31); mtsr 1,%r30; \ 677 lwz %r30,8(%r31); mtsr 2,%r30; \ 678 lwz %r30,12(%r31); mtsr 3,%r30; \ 679 lwz %r30,16(%r31); mtsr 4,%r30; \ 680 lwz %r30,20(%r31); mtsr 5,%r30; \ 681 lwz %r30,24(%r31); mtsr 6,%r30; \ 682 lwz %r30,28(%r31); mtsr 7,%r30; \ 683 lwz %r30,32(%r31); mtsr 8,%r30; \ 684 lwz %r30,36(%r31); mtsr 9,%r30; \ 685 lwz %r30,40(%r31); mtsr 10,%r30; \ 686 lwz %r30,44(%r31); mtsr 11,%r30; \ 687 lwz %r30,48(%r31); mtsr 12,%r30; \ 688/* lwz %r30,52(%r31); mtsr 13,%r30; - dont load user SR - XXX? */ \ 689 lwz %r30,56(%r31); mtsr 14,%r30; \ 690 lwz %r30,60(%r31); mtsr 15,%r30; \ 691 mfmsr %r30; \ 692 ori %r30,%r30,(PSL_DR|PSL_IR); \ 693 mtmsr %r30; \ 694 isync; \ 695 mfsprg %r31,1; \ 696 stwu %r31,-FRAMELEN(%r1); \ 697 stw %r0,FRAME_0+8(%r1); \ 698 stw %r31,FRAME_1+8(%r1); \ 699 stw %r2,FRAME_2+8(%r1); \ 700 stw %r28,FRAME_LR+8(%r1); \ 701 stw %r29,FRAME_CR+8(%r1); \ 702 GET_CPUINFO(%r2); \ 703 lmw %r28,savearea(%r2); \ 704 stmw %r3,FRAME_3+8(%r1); \ 705 lmw %r28,savearea+16(%r2); \ 706 mfxer %r3; \ 707 mfctr %r4; \ 708 mflr %r5; \ 709 andi. %r5,%r5,0xff00; \ 710 stw %r3,FRAME_XER+8(%r1); \ 711 stw %r4,FRAME_CTR+8(%r1); \ 712 stw %r5,FRAME_EXC+8(%r1); \ 713 stw %r28,FRAME_DAR+8(%r1); \ 714 stw %r29,FRAME_DSISR+8(%r1); \ 715 CPU_IDLE_CHECK(%r5,%r6,%r0,%r30,flag) \ 716 stw %r30,FRAME_SRR0+8(%r1); \ 717 stw %r31,FRAME_SRR1+8(%r1) 718 719#define FRAME_LEAVE(savearea) \ 720/* Now restore regs: */ \ 721 lwz %r2,FRAME_SRR0+8(%r1); \ 722 lwz %r3,FRAME_SRR1+8(%r1); \ 723 lwz %r4,FRAME_CTR+8(%r1); \ 724 lwz %r5,FRAME_XER+8(%r1); \ 725 lwz %r6,FRAME_LR+8(%r1); \ 726 GET_CPUINFO(%r7); \ 727 stw %r2,savearea(%r7); \ 728 stw %r3,savearea+4(%r7); \ 729 lwz %r7,FRAME_CR+8(%r1); \ 730 mtctr %r4; \ 731 mtxer %r5; \ 732 mtlr %r6; \ 733 mtsprg 1,%r7; /* save cr */ \ 734 lmw %r2,FRAME_2+8(%r1); \ 735 lwz %r0,FRAME_0+8(%r1); \ 736 lwz %r1,FRAME_1+8(%r1); \ 737 mtsprg 2,%r2; /* save r2 & r3 */ \ 738 mtsprg 3,%r3; \ 739/* Disable translation, machine check and recoverability: */ \ 740 mfmsr %r2; \ 741 lis %r3,(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@ha; \ 742 addi %r3,%r3,(PSL_DR|PSL_IR|PSL_ME|PSL_RI)@l; \ 743 andc %r2,%r2,%r3; \ 744 mtmsr %r2; \ 745 isync; \ 746/* Decide whether we return to user mode: */ \ 747 GET_CPUINFO(%r2); \ 748 lwz %r3,savearea+4(%r2); \ 749 mtcr %r3; \ 750 bc 4,17,1f; /* branch if PSL_PR is false */ \ 751/* Restore user & kernel access SR: */ \ 752 lwz %r2,CI_CURPM(%r2); /* get real address of pmap */ \ 753 lwz %r3,0(%r2); mtsr 0,%r3; \ 754 lwz %r3,4(%r2); mtsr 1,%r3; \ 755 lwz %r3,8(%r2); mtsr 2,%r3; \ 756 lwz %r3,12(%r2); mtsr 3,%r3; \ 757 lwz %r3,16(%r2); mtsr 4,%r3; \ 758 lwz %r3,20(%r2); mtsr 5,%r3; \ 759 lwz %r3,24(%r2); mtsr 6,%r3; \ 760 lwz %r3,28(%r2); mtsr 7,%r3; \ 761 lwz %r3,32(%r2); mtsr 8,%r3; \ 762 lwz %r3,36(%r2); mtsr 9,%r3; \ 763 lwz %r3,40(%r2); mtsr 10,%r3; \ 764 lwz %r3,44(%r2); mtsr 11,%r3; \ 765 lwz %r3,48(%r2); mtsr 12,%r3; \ 766 lwz %r3,52(%r2); mtsr 13,%r3; \ 767 lwz %r3,56(%r2); mtsr 14,%r3; \ 768 lwz %r3,60(%r2); mtsr 15,%r3; \ 7691: mfsprg %r2,1; /* restore cr */ \ 770 mtcr %r2; \ 771 GET_CPUINFO(%r2); \ 772 lwz %r3,savearea(%r2); \ 773 mtsrr0 %r3; \ 774 lwz %r3,savearea+4(%r2); \ 775 mtsrr1 %r3; \ 776 mfsprg %r2,2; /* restore r2 & r3 */ \ 777 mfsprg %r3,3 778 779/* 780 * Preamble code for DSI/ISI traps 781 */ 782disitrap: 783 GET_CPUINFO(%r1) 784 lmw %r30,CI_DISISAVE(%r1) 785 stmw %r30,CI_TEMPSAVE(%r1) 786 lmw %r30,CI_DISISAVE+8(%r1) 787 stmw %r30,CI_TEMPSAVE+8(%r1) 788 mfdar %r30 789 mfdsisr %r31 790 stmw %r30,CI_TEMPSAVE+16(%r1) 791realtrap: 792 /* Test whether we already had PR set */ 793 mfsrr1 %r1 794 mtcr %r1 795 /* restore SP (might have been overwritten) */ 796 mfsprg %r1,1 797 bc 4,17,s_trap /* branch if PSL_PR is false */ 798 GET_CPUINFO(%r1) 799 lwz %r1,CI_CURPCB(%r1) 800 addi %r1,%r1,USPACE /* stack is top of user struct */ 801/* 802 * Now the common trap catching code. 803 */ 804 .globl s_trap 805s_trap: 806 FRAME_SETUP(CI_TEMPSAVE) 807/* Now we can recover interrupts again: */ 808 mfmsr %r7 809 mfsrr1 %r31 810 andi. %r31,%r31,PSL_EE /* restore EE from previous context */ 811 or %r7,%r7,%r31 812 ori %r7,%r7,(PSL_ME|PSL_RI) 813 mtmsr %r7 814 isync 815/* Call C trap code: */ 816trapagain: 817 addi %r3,%r1,8 818 bl trap 819 820 .globl trapexit 821trapexit: 822/* Disable interrupts: */ 823 mfmsr %r3 824 andi. %r3,%r3,~PSL_EE@l 825 mtmsr %r3 826 isync 827/* Test AST pending: */ 828 lwz %r5,FRAME_SRR1+8(%r1) 829 mtcr %r5 830 bc 4,17,1f /* branch if PSL_PR is false */ 831 GET_CPUINFO(%r3) 832 lwz %r4,CI_CURPROC(%r3) 833 lwz %r4,P_MD_ASTPENDING(%r4) 834 andi. %r4,%r4,1 835 beq 1f 836 li %r6,EXC_AST 837 stw %r6,FRAME_EXC+8(%r1) 838 b trapagain 8391: 840 FRAME_LEAVE(CI_TEMPSAVE) 841rfi1: rfi 842 843/* 844 * Child comes here at the end of a fork. 845 * Mostly similar to the above. 846 */ 847 .globl proc_trampoline 848 .type proc_trampoline,@function 849proc_trampoline: 850 bl proc_trampoline_mi 851 mtlr %r31 852 mr %r3,%r30 853 blrl /* jump indirect to r31 */ 854 b trapexit 855 856/* 857 * DSI second stage fault handler 858 */ 859s_dsitrap: 860 mfdsisr %r31 /* test if this is spill fault */ 861 mtcr %r31 862 mtsprg 1,%r1 /* save SP */ 863 bc 4,1,disitrap /* branch if table miss is false */ 864 GET_CPUINFO(%r30) 865 lwz %r30,CI_INTSTK(%r30) /* get interrupt stack */ 866 addi %r1,%r30,SPILLSTK 867 stwu %r1,-52(%r1) 868 stw %r0,48(%r1) /* save non-volatile registers */ 869 stw %r3,44(%r1) 870 stw %r4,40(%r1) 871 stw %r5,36(%r1) 872 stw %r6,32(%r1) 873 stw %r7,28(%r1) 874 stw %r8,24(%r1) 875 stw %r9,20(%r1) 876 stw %r10,16(%r1) 877 stw %r11,12(%r1) 878 stw %r12,8(%r1) 879 mfxer %r30 /* save XER */ 880 mtsprg 2,%r30 881 mflr %r30 /* save trap type */ 882 mfctr %r31 /* & CTR */ 883 mfdar %r7 884 mfsrr1 %r4 885 mfdsisr %r5 886 li %r6, 0 887s_pte_spill: 888 andi. %r0,%r4,PSL_PR 889 li %r3,0 890 bne 1f 891 mr %r3,%r7 892 bl pte_spill_r /* try a spill */ 8931: 894 cmpwi 0,%r3,0 895 mtctr %r31 /* restore CTR */ 896 mtlr %r30 /* and trap type */ 897 mfsprg %r31,2 /* get saved XER */ 898 mtxer %r31 /* restore XER */ 899 lwz %r12,8(%r1) /* restore non-volatile registers */ 900 lwz %r11,12(%r1) 901 lwz %r10,16(%r1) 902 lwz %r9,20(%r1) 903 lwz %r8,24(%r1) 904 lwz %r7,28(%r1) 905 lwz %r6,32(%r1) 906 lwz %r5,36(%r1) 907 lwz %r4,40(%r1) 908 lwz %r3,44(%r1) 909 lwz %r0,48(%r1) 910 beq disitrap 911 mtcr %r29 /* restore CR */ 912 mtlr %r28 /* restore LR */ 913 GET_CPUINFO(%r1) 914 lmw %r28,CI_DISISAVE(%r1) /* restore r28-r31 */ 915 mfsprg %r1,1 /* restore SP */ 916rfi2: rfi /* return to trapped code */ 917 918/* 919 * ISI second stage fault handler 920 */ 921s_isitrap: 922 mfsrr1 %r31 /* test if this may be a spill fault */ 923 mtcr %r31 924 mtsprg 1,%r1 /* save SP */ 925 bc 4,1,disitrap /* branch if table miss is false */ 926 GET_CPUINFO(%r30) 927 lwz %r30,CI_INTSTK(%r30) /* get interrupt stack */ 928 addi %r1,%r30,SPILLSTK 929 stwu %r1,-52(%r1) 930 stw %r0,48(%r1) /* save non-volatile registers */ 931 stw %r3,44(%r1) 932 stw %r4,40(%r1) 933 stw %r5,36(%r1) 934 stw %r6,32(%r1) 935 stw %r7,28(%r1) 936 stw %r8,24(%r1) 937 stw %r9,20(%r1) 938 stw %r10,16(%r1) 939 stw %r11,12(%r1) 940 stw %r12,8(%r1) 941 mfxer %r30 /* save XER */ 942 mtsprg 2,%r30 943 mflr %r30 /* save trap type */ 944 mfctr %r31 /* & ctr */ 945 mfsrr0 %r7 946 mfsrr1 %r4 947 li %r5, 0 948 li %r6, 1 949 b s_pte_spill /* above */ 950 951/* 952 * External interrupt second level handler 953 */ 954#define INTRENTER \ 955/* Save non-volatile registers: */ \ 956 stwu %r1,-88(%r1); /* temporarily */ \ 957 stw %r0,84(%r1); \ 958 mfsprg %r0,1; /* get original SP */ \ 959 stw %r0,0(%r1); /* and store it */ \ 960 stw %r3,80(%r1); \ 961 stw %r4,76(%r1); \ 962 stw %r5,72(%r1); \ 963 stw %r6,68(%r1); \ 964 stw %r7,64(%r1); \ 965 stw %r8,60(%r1); \ 966 stw %r9,56(%r1); \ 967 stw %r10,52(%r1); \ 968 stw %r11,48(%r1); \ 969 stw %r12,44(%r1); \ 970 stw %r28,40(%r1); /* saved LR */ \ 971 stw %r29,36(%r1); /* saved CR */ \ 972 stw %r30,32(%r1); /* saved XER */ \ 973 GET_CPUINFO(%r4); \ 974 lmw %r28,CI_TEMPSAVE(%r4); /* restore r28-r31 */ \ 975 mfctr %r6; \ 976 lwz %r5,CI_IDEPTH(%r4); \ 977 mfsrr0 %r4; \ 978 mfsrr1 %r3; \ 979 stw %r6,28(%r1); \ 980 stw %r5,20(%r1); \ 981 stw %r4,12(%r1); \ 982 stw %r3,8(%r1); \ 983/* load all kernel segment registers. */ \ 984 lis 3,kernel_pmap_@ha; \ 985 addi 3,3,kernel_pmap_@l; \ 986 lwz %r5,0(%r3); mtsr 0,%r5; \ 987 lwz %r5,4(%r3); mtsr 1,%r5; \ 988 lwz %r5,8(%r3); mtsr 2,%r5; \ 989 lwz %r5,12(%r3); mtsr 3,%r5; \ 990 lwz %r5,16(%r3); mtsr 4,%r5; \ 991 lwz %r5,20(%r3); mtsr 5,%r5; \ 992 lwz %r5,24(%r3); mtsr 6,%r5; \ 993 lwz %r5,28(%r3); mtsr 7,%r5; \ 994 lwz %r5,32(%r3); mtsr 8,%r5; \ 995 lwz %r5,36(%r3); mtsr 9,%r5; \ 996 lwz %r5,40(%r3); mtsr 10,%r5; \ 997 lwz %r5,44(%r3); mtsr 11,%r5; \ 998 lwz %r5,48(%r3); mtsr 12,%r5; \ 999/* lwz %r5,52(%r3); mtsr 13,%r5; - dont load user SR - XXX? */ \ 1000 lwz %r5,56(%r3); mtsr 14,%r5; \ 1001 lwz %r5,60(%r3); mtsr 15,%r5; \ 1002/* interrupts are recoverable here, and enable translation */ \ 1003 mfmsr %r5; \ 1004 ori %r5,%r5,(PSL_IR|PSL_DR|PSL_RI); \ 1005 mtmsr %r5; \ 1006 isync 1007 1008 .globl extint_call 1009 .type extint_call,@function 1010extintr: 1011 INTRENTER 1012extint_call: 1013 bl extint_call /* to be filled in later */ 1014intr_exit: 1015/* Disable interrupts (should already be disabled) and MMU here: */ 1016 mfmsr %r3 1017 andi. %r3,%r3,~(PSL_EE|PSL_ME|PSL_RI|PSL_DR|PSL_IR)@l 1018 mtmsr %r3 1019 isync 1020/* restore possibly overwritten registers: */ 1021 lwz %r12,44(%r1) 1022 lwz %r11,48(%r1) 1023 lwz %r10,52(%r1) 1024 lwz %r9,56(%r1) 1025 lwz %r8,60(%r1) 1026 lwz %r7,64(%r1) 1027 lwz %r6,8(%r1) 1028 lwz %r5,12(%r1) 1029 lwz %r4,28(%r1) 1030 lwz %r3,32(%r1) 1031 mtsrr1 %r6 1032 mtsrr0 %r5 1033 mtctr %r4 1034 mtxer %r3 1035 1036 GET_CPUINFO(%r5) 1037 lwz %r4,CI_IDEPTH(%r5) 1038 addi %r4,%r4,-1 /* adjust reentrancy count */ 1039 stw %r4,CI_IDEPTH(%r5) 1040 1041/* Returning to user mode? */ 1042 mtcr %r6 /* saved SRR1 */ 1043 bc 4,17,1f /* branch if PSL_PR is false */ 1044 lwz %r3,CI_CURPM(%r5) /* get current pmap real address */ 1045 /* reload all segment registers. */ 1046 lwz %r4,0(3); mtsr 0,%r4; 1047 lwz %r4,4(3); mtsr 1,%r4; 1048 lwz %r4,8(3); mtsr 2,%r4; 1049 lwz %r4,12(3); mtsr 3,%r4; 1050 lwz %r4,16(3); mtsr 4,%r4; 1051 lwz %r4,20(3); mtsr 5,%r4; 1052 lwz %r4,24(3); mtsr 6,%r4; 1053 lwz %r4,28(3); mtsr 7,%r4; 1054 lwz %r4,32(3); mtsr 8,%r4; 1055 lwz %r4,36(3); mtsr 9,%r4; 1056 lwz %r4,40(3); mtsr 10,%r4; 1057 lwz %r4,44(3); mtsr 11,%r4; 1058 lwz %r4,48(3); mtsr 12,%r4; 1059 lwz %r4,52(3); mtsr 13,%r4; 1060 lwz %r4,56(3); mtsr 14,%r4; 1061 lwz %r4,60(3); mtsr 15,%r4; 1062 lwz %r4,CI_CURPROC(%r5) 1063 lwz %r4,P_MD_ASTPENDING(%r4) /* Test AST pending */ 1064 andi. %r4,%r4,1 1065 beq 1f 1066/* Setup for entry to realtrap: */ 1067 lwz %r3,0(%r1) /* get saved SP */ 1068 mtsprg 1,%r3 1069 li %r6,EXC_AST 1070 stmw %r28,CI_TEMPSAVE(%r5) /* establish tempsave again */ 1071 mtlr %r6 1072 lwz %r28,40(%r1) /* saved LR */ 1073 lwz %r29,36(%r1) /* saved CR */ 1074 lwz %r6,68(%r1) 1075 lwz %r5,72(%r1) 1076 lwz %r4,76(%r1) 1077 lwz %r3,80(%r1) 1078 lwz %r0,84(%r1) 1079 b realtrap 10801: 1081/* Here is the normal exit of extintr: */ 1082 lwz %r5,36(%r1) 1083 lwz %r6,40(%r1) 1084 mtcr %r5 1085 mtlr %r6 1086 lwz %r6,68(%r1) 1087 lwz %r5,72(%r1) 1088 lwz %r4,76(%r1) 1089 lwz %r3,80(%r1) 1090 lwz %r0,84(%r1) 1091 lwz %r1,0(%r1) 1092rfi3: rfi 1093 1094/* 1095 * Decrementer interrupt second level handler 1096 */ 1097 .globl decrintr 1098decrintr: 1099 INTRENTER 1100 addi %r3,%r1,8 /* intr frame */ 1101 bl decr_intr 1102 b intr_exit 1103 1104 1105/* 1106 * int setfault() 1107 * 1108 * Similar to setjmp to setup for handling faults on accesses to user memory. 1109 * Any routine using this may only call bcopy, either the form below, 1110 * or the (currently used) C code optimized, so it doesn't use any non-volatile 1111 * registers. 1112 */ 1113 .globl setfault 1114 .type setfault,@function 1115setfault: 1116 mflr %r0 1117 RETGUARD_SETUP_LATE(setfault, %r11, %r0) 1118 mfcr %r12 1119 GET_CPUINFO(%r4) 1120 lwz %r4,CI_CURPCB(%r4) 1121 stw %r3,PCB_FAULT(%r4) 1122 stw %r0,0(%r3) 1123 stw %r1,4(%r3) 1124 stmw %r12,8(%r3) 1125 li %r3,0 1126 RETGUARD_CHECK(setfault, %r11, %r0) 1127 blr 1128 1129/* 1130 * The following code gets copied to the top of the user stack on process 1131 * execution. It does signal trampolining on signal delivery. 1132 * 1133 * On entry r1 points to a struct sigframe at bottom of current stack. 1134 * All other registers are unchanged. 1135 */ 1136 .section .rodata 1137 .globl sigcode,esigcode 1138 .type sigcode,@function 1139 .type esigcode,@function 1140sigcode: 1141 addi %r1,%r1,-((16+FPSIG_SIZEOF+15)& ~0xf) /* reserved space for callee */ 1142 addi %r6,%r1,8 1143 stfd %f0,0(%r6) 1144 stfd %f1,8(%r6) 1145 stfd %f2,16(%r6) 1146 stfd %f3,24(%r6) 1147 stfd %f4,32(%r6) 1148 stfd %f5,40(%r6) 1149 stfd %f6,48(%r6) 1150 stfd %f7,56(%r6) 1151 stfd %f8,64(%r6) 1152 stfd %f9,72(%r6) 1153 stfd %f10,80(%r6) 1154 stfd %f11,88(%r6) 1155 stfd %f12,96(%r6) 1156 stfd %f13,104(%r6) 1157 mffs %f0 1158 stfd %f0,112(%r6) 1159 lfd %f0,0(%r6) /* restore the clobbered register */ 1160 blrl 1161 addi %r6,%r1,8 1162 lfd %f0,112(%r6) 1163 mtfsf 0xff,%f0 1164 lfd %f0,0(%r6) 1165 lfd %f1,8(%r6) 1166 lfd %f2,16(%r6) 1167 lfd %f3,24(%r6) 1168 lfd %f4,32(%r6) 1169 lfd %f5,40(%r6) 1170 lfd %f6,48(%r6) 1171 lfd %f7,56(%r6) 1172 lfd %f8,64(%r6) 1173 lfd %f9,72(%r6) 1174 lfd %f10,80(%r6) 1175 lfd %f11,88(%r6) 1176 lfd %f12,96(%r6) 1177 lfd %f13,104(%r6) 1178 addi %r3,%r1,((16+FPSIG_SIZEOF+15)&~0xf)+SF_SC /* compute &sf_sc */ 1179 li %r0,SYS_sigreturn 1180 .globl sigcodecall 1181sigcodecall: 1182 sc /* sigreturn(scp) */ 1183 .globl sigcoderet 1184sigcoderet: 1185esigcode: 1186 /* FALLTHROUGH */ 1187 .globl sigfill 1188sigfill: 1189 .long 0 # illegal 1190esigfill: 1191 .align 4 1192 .globl sigfillsiz 1193sigfillsiz: 1194 .long esigfill - sigfill 1195 1196 .text 1197 1198#ifdef DDB 1199/* 1200 * Deliberate entry to ddbtrap 1201 */ 1202 .globl ddb_trap 1203ddb_trap: 1204 mtsprg 1,%r1 1205 mfmsr %r3 1206 mtsrr1 %r3 1207 andi. %r3,%r3,~(PSL_EE|PSL_ME)@l 1208 mtmsr %r3 /* disable interrupts */ 1209 isync 1210 GET_CPUINFO(%r3) 1211 stmw %r28,CI_DDBSAVE(%r3) 1212 1213 mflr %r28 1214 li %r29,EXC_BPT 1215 mtlr %r29 1216 mfcr %r29 1217 mtsrr0 %r28 1218 1219/* 1220 * Now the ddb trap catching code. 1221 */ 1222ddbtrap: 1223 /* 1224 * Do not let FRAME_SETUP() change the return address of, and 1225 * corrupt, this frame. 1226 */ 1227 FRAME_SETUP_FLAG(CI_DDBSAVE, 0) 1228/* Call C trap code: */ 1229 addi %r3,%r1,8 1230 bl db_trap_glue 1231 or. %r3,%r3,%r3 1232 bne ddbleave 1233/* This wasn't for DDB, so switch to real trap: */ 1234 lwz %r3,FRAME_EXC+8(%r1) /* save exception */ 1235 GET_CPUINFO(%r4) 1236 stw %r3,CI_DDBSAVE+8(%r4) 1237 FRAME_LEAVE(CI_DDBSAVE) 1238 mtsprg 1,%r1 /* prepare for entrance to realtrap */ 1239 GET_CPUINFO(%r1) 1240 stmw %r28,CI_TEMPSAVE(%r1) 1241 mflr %r28 1242 mfcr %r29 1243 lwz %r31,CI_DDBSAVE+8(%r1) 1244 mtlr %r31 1245 b realtrap 1246ddbleave: 1247 FRAME_LEAVE(CI_DDBSAVE) 1248rfi4: rfi 1249#endif /* DDB */ 1250 1251 .globl rfi_inst 1252rfi_inst: 1253 rfi 1254 .globl rfid_inst 1255rfid_inst: 1256 rfid 1257 .globl nop_inst 1258 nop_inst: 1259 nop 1260 1261 .globl rfi_start 1262rfi_start: 1263 .long rfi1, rfi1 + 4 1264 .long rfi2, rfi2 + 4 1265 .long rfi3, rfi3 + 4 1266#ifdef DDB 1267 .long rfi4, rfi4 + 4 1268#endif 1269 .long 0, 0 1270 1271 1272 .globl nopbat_start 1273nopbat_start: 1274 .long nopbat_1s, nopbat_1e 1275 .long 0, 0 1276 1277 .globl nop32_start 1278nop32_start: 1279 .long nop32_1s, nop32_1e 1280 .long nop32_2s, nop32_2e 1281 .long nop32_3s, nop32_3e 1282 .long nop32_4s, nop32_4e 1283 .long nop32_5s, nop32_5e 1284 .long nop32_6s, nop32_6e 1285#ifdef DDB 1286 .long nop32_7s, nop32_7e 1287#endif 1288 .long 0, 0 1289