|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * @OSF_COPYRIGHT@ ! 24: */ ! 25: ! 26: /* ! 27: * Low-memory exception vector code for PowerPC MACH ! 28: * ! 29: * These are the only routines that are ever run with ! 30: * VM instruction translation switched off. ! 31: * ! 32: * The PowerPC is quite strange in that rather than having a set ! 33: * of exception vectors, the exception handlers are installed ! 34: * in well-known addresses in low memory. This code must be loaded ! 35: * at ZERO in physical memory. The simplest way of doing this is ! 36: * to load the kernel at zero, and specify this as the first file ! 37: * on the linker command line. ! 38: * ! 39: * When this code is loaded into place, it is loaded at virtual ! 40: * address KERNELBASE, which is mapped to zero (physical). ! 41: * ! 42: * This code handles all powerpc exceptions and is always entered ! 43: * in supervisor mode with translation off. It saves the minimum ! 44: * processor state before switching back on translation and ! 45: * jumping to the approprate routine. ! 46: * ! 47: * Vectors from 0x100 to 0x3fff occupy 0x100 bytes each (64 instructions) ! 48: * ! 49: * We use some of this space to decide which stack to use, and where to ! 50: * save the context etc, before jumping to a generic handler. ! 51: */ ! 52: ! 53: #include <assym.s> ! 54: #include <debug.h> ! 55: #include <cpus.h> ! 56: #include <db_machine_commands.h> ! 57: #include <mach_rt.h> ! 58: ! 59: #include <mach_debug.h> ! 60: #include <ppc/asm.h> ! 61: #include <ppc/proc_reg.h> ! 62: #include <ppc/exception.h> ! 63: #include <ppc/Performance.h> ! 64: #include <mach/ppc/vm_param.h> ! 65: #include <ppc/POWERMAC/mp/MPPlugIn.h> ! 66: ! 67: #define RUPTTRC 0 ! 68: #define CHECKSAVE 0 ! 69: #define PERFTIMES 0 ! 70: #define ESPDEBUG 0 ! 71: ! 72: #define VECTOR_SEGMENT .section __VECTORS, __interrupts ! 73: ! 74: VECTOR_SEGMENT ! 75: ! 76: ! 77: .globl EXT(ExceptionVectorsStart) ! 78: ! 79: EXT(ExceptionVectorsStart): /* Used if relocating the exception vectors */ ! 80: baseR: /* Used so we have more readable code */ ! 81: ! 82: /* ! 83: * System reset - call debugger ! 84: */ ! 85: . = 0xf0 ! 86: .globl EXT(ResetHandler) ! 87: EXT(ResetHandler): ! 88: .long 0x0 ! 89: .long 0x0 ! 90: .long 0x0 ! 91: ! 92: . = 0x100 ! 93: .L_handler100: ! 94: mtsprg 2,r13 /* Save R13 */ ! 95: mtsprg 3,r11 /* Save R11 */ ! 96: lwz r13,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_TYPE)(br0) ; Get reset type ! 97: mfcr r11 ! 98: cmpi cr0,r13,RESET_HANDLER_START ! 99: bne resetexc ! 100: ! 101: li r11,RESET_HANDLER_NULL ! 102: stw r11,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_TYPE)(br0) ; Clear reset type ! 103: ! 104: lwz r4,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_CALL)(br0) ! 105: lwz r3,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_ARG)(br0) ! 106: mtlr r4 ! 107: blr ! 108: ! 109: resetexc: ! 110: mtcr r11 ! 111: mfsprg r13,1 /* Get the exception save area */ ! 112: li r11,T_RESET /* Set 'rupt code */ ! 113: b .L_exception_entry /* Join common... */ ! 114: ! 115: /* ! 116: * This is the data used by the exception trace code ! 117: */ ! 118: ! 119: . = 0x180 ! 120: .L_TraceData: ! 121: ! 122: .globl traceMask ! 123: traceMask: /* Allowable trace types indexed by vector >> 8 */ ! 124: #if DEBUG ! 125: /* .long 0x02000000 */ /* Only alignment exceptions enabled */ ! 126: .long 0xFFFFFFFF /* All enabled */ ! 127: /* .long 0xFBBFFFFF */ /* EXT and DEC disabled */ ! 128: /* .long 0xFFBFFFFF */ /* DEC disabled */ ! 129: #else ! 130: .long 0x00000000 ; All disabled on non-debug systems ! 131: #endif ! 132: ! 133: .globl EXT(traceCurr) ! 134: EXT(traceCurr): .long traceTableBeg-EXT(ExceptionVectorsStart) /* The next trace entry to use */ ! 135: ! 136: .globl EXT(traceStart) ! 137: EXT(traceStart): .long traceTableBeg-EXT(ExceptionVectorsStart) /* Start of the trace table */ ! 138: ! 139: .globl EXT(traceEnd) ! 140: EXT(traceEnd): ! 141: .long traceTableEnd-EXT(ExceptionVectorsStart) /* End (wrap point) of the trace */ ! 142: ! 143: .globl traceMsnd ! 144: ! 145: traceMsnd: .long 0 /* Saved mask while in debugger */ ! 146: ! 147: /* ! 148: * Machine check (physical bus error) - call debugger ! 149: */ ! 150: ! 151: . = 0x200 ! 152: .L_handler200: ! 153: mtsprg 2,r13 /* Save R13 */ ! 154: mtsprg 3,r11 /* Save R11 */ ! 155: mfsprg r13,1 /* Get the exception save area */ ! 156: li r11,T_MACHINE_CHECK /* Set 'rupt code */ ! 157: b .L_exception_entry /* Join common... */ ! 158: ! 159: /* ! 160: * Data access - page fault, invalid memory rights for operation ! 161: */ ! 162: ! 163: . = 0x300 ! 164: .L_handler300: ! 165: mtsprg 2,r13 /* Save R13 */ ! 166: mtsprg 3,r11 /* Save R11 */ ! 167: mfsprg r13,1 /* Get the exception save area */ ! 168: li r11,T_DATA_ACCESS /* Set 'rupt code */ ! 169: b .L_exception_entry /* Join common... */ ! 170: ! 171: /* ! 172: * Instruction access - as for data access ! 173: */ ! 174: ! 175: . = 0x400 ! 176: .L_handler400: ! 177: mtsprg 2,r13 /* Save R13 */ ! 178: mtsprg 3,r11 /* Save R11 */ ! 179: mfsprg r13,1 /* Get the exception save area */ ! 180: li r11,T_INSTRUCTION_ACCESS /* Set 'rupt code */ ! 181: b .L_exception_entry /* Join common... */ ! 182: ! 183: /* ! 184: * External interrupt ! 185: */ ! 186: ! 187: . = 0x500 ! 188: .L_handler500: ! 189: mtsprg 2,r13 /* Save R13 */ ! 190: mtsprg 3,r11 /* Save R11 */ ! 191: mfsprg r13,1 /* Get the exception save area */ ! 192: li r11,T_INTERRUPT /* Set 'rupt code */ ! 193: b .L_exception_entry /* Join common... */ ! 194: ! 195: /* ! 196: * Alignment - many reasons ! 197: */ ! 198: ! 199: . = 0x600 ! 200: .L_handler600: ! 201: mtsprg 2,r13 /* Save R13 */ ! 202: mtsprg 3,r11 /* Save R11 */ ! 203: mfsprg r13,1 /* Get the exception save area */ ! 204: li r11,T_ALIGNMENT /* Set 'rupt code */ ! 205: b .L_exception_entry /* Join common... */ ! 206: ! 207: /* ! 208: * Program - floating point exception, illegal inst, priv inst, user trap ! 209: */ ! 210: ! 211: . = 0x700 ! 212: .L_handler700: ! 213: mtsprg 2,r13 /* Save R13 */ ! 214: mtsprg 3,r11 /* Save R11 */ ! 215: mfsprg r13,1 /* Get the exception save area */ ! 216: li r11,T_PROGRAM /* Set 'rupt code */ ! 217: b .L_exception_entry /* Join common... */ ! 218: ! 219: /* ! 220: * Floating point disabled ! 221: */ ! 222: ! 223: . = 0x800 ! 224: .L_handler800: ! 225: mtsprg 2,r13 /* Save R13 */ ! 226: mtsprg 3,r11 /* Save R11 */ ! 227: mfsprg r13,1 /* Get the exception save area */ ! 228: li r11,T_FP_UNAVAILABLE /* Set 'rupt code */ ! 229: b .L_exception_entry /* Join common... */ ! 230: ! 231: ! 232: /* ! 233: * Decrementer - DEC register has passed zero. ! 234: */ ! 235: ! 236: . = 0x900 ! 237: .L_handler900: ! 238: mtsprg 2,r13 /* Save R13 */ ! 239: mtsprg 3,r11 /* Save R11 */ ! 240: mfsprg r13,1 /* Get the exception save area */ ! 241: li r11,T_DECREMENTER /* Set 'rupt code */ ! 242: b .L_exception_entry /* Join common... */ ! 243: ! 244: /* ! 245: * I/O controller interface error - MACH does not use this ! 246: */ ! 247: ! 248: . = 0xA00 ! 249: .L_handlerA00: ! 250: mtsprg 2,r13 /* Save R13 */ ! 251: mtsprg 3,r11 /* Save R11 */ ! 252: mfsprg r13,1 /* Get the exception save area */ ! 253: li r11,T_IO_ERROR /* Set 'rupt code */ ! 254: b .L_exception_entry /* Join common... */ ! 255: ! 256: /* ! 257: * Reserved ! 258: */ ! 259: ! 260: . = 0xB00 ! 261: .L_handlerB00: ! 262: mtsprg 2,r13 /* Save R13 */ ! 263: mtsprg 3,r11 /* Save R11 */ ! 264: mfsprg r13,1 /* Get the exception save area */ ! 265: li r11,T_RESERVED /* Set 'rupt code */ ! 266: b .L_exception_entry /* Join common... */ ! 267: ! 268: /* ! 269: * System call - generated by the sc instruction ! 270: */ ! 271: ! 272: . = 0xC00 ! 273: .L_handlerC00: ! 274: cmplwi r0,0x7FF2 ; Ultra fast path cthread info call? ! 275: blt+ notufp ; Not ultra fast... ! 276: cmplwi r0,0x7FF3 ; Ultra fast path fp/vec facility state? ! 277: bgt+ notufp ; Not ultra fast... ! 278: mfsprg r3,0 ; Get the per_proc_area ! 279: beq- isvecfp ; This is the facility stat call ! 280: lwz r3,UAW(r3) ; Get the assist word ! 281: rfi ; All done, scream back... (no need to restore CR or R11, they are volatile) ! 282: ; ! 283: isvecfp: lwz r3,spcFlags(r3) ; Get the facility status ! 284: rfi ; Bail back... ! 285: ; ! 286: .align 5 ! 287: notufp: mtsprg 3,r11 /* Save R11 */ ! 288: mtsprg 2,r13 /* Save R13 */ ! 289: li r11,T_SYSTEM_CALL /* Set 'rupt code */ ! 290: mfsprg r13,1 /* Get the exception save area */ ! 291: b .L_exception_entry /* Join common... */ ! 292: ! 293: /* ! 294: * Trace - generated by single stepping ! 295: */ ! 296: ! 297: . = 0xD00 ! 298: .L_handlerD00: ! 299: mtsprg 2,r13 /* Save R13 */ ! 300: mtsprg 3,r11 /* Save R11 */ ! 301: mfsprg r13,1 /* Get the exception save area */ ! 302: li r11,T_TRACE /* Set 'rupt code */ ! 303: b .L_exception_entry /* Join common... */ ! 304: ! 305: /* ! 306: * Floating point assist ! 307: */ ! 308: ! 309: . = 0xe00 ! 310: .L_handlerE00: ! 311: mtsprg 2,r13 /* Save R13 */ ! 312: mtsprg 3,r11 /* Save R11 */ ! 313: mfsprg r13,1 /* Get the exception save area */ ! 314: li r11,T_FP_ASSIST /* Set 'rupt code */ ! 315: b .L_exception_entry /* Join common... */ ! 316: ! 317: ! 318: /* ! 319: * Performance monitor interruption ! 320: */ ! 321: ! 322: . = 0xF00 ! 323: PMIhandler: ! 324: mtsprg 2,r13 /* Save R13 */ ! 325: mtsprg 3,r11 /* Save R11 */ ! 326: mfsprg r13,1 /* Get the exception save area */ ! 327: li r11,T_PERF_MON /* Set 'rupt code */ ! 328: b .L_exception_entry /* Join common... */ ! 329: ! 330: ! 331: /* ! 332: * VMX exception ! 333: */ ! 334: ! 335: . = 0xF20 ! 336: VMXhandler: ! 337: mtsprg 2,r13 /* Save R13 */ ! 338: mtsprg 3,r11 /* Save R11 */ ! 339: mfsprg r13,1 /* Get the exception save area */ ! 340: li r11,T_VMX /* Set 'rupt code */ ! 341: b .L_exception_entry /* Join common... */ ! 342: ! 343: ! 344: ! 345: /* ! 346: * Instruction translation miss - we inline this code. ! 347: * Upon entry (done for us by the machine): ! 348: * srr0 : addr of instruction that missed ! 349: * srr1 : bits 0-3 = saved CR0 ! 350: * 4 = lru way bit ! 351: * 16-31 = saved msr ! 352: * msr[tgpr] = 1 (so gpr0-3 become our temporary variables) ! 353: * imiss: ea that missed ! 354: * icmp : the compare value for the va that missed ! 355: * hash1: pointer to first hash pteg ! 356: * hash2: pointer to 2nd hash pteg ! 357: * ! 358: * Register usage: ! 359: * tmp0: saved counter ! 360: * tmp1: junk ! 361: * tmp2: pointer to pteg ! 362: * tmp3: current compare value ! 363: * ! 364: * This code is taken from the 603e User's Manual with ! 365: * some bugfixes and minor improvements to save bytes and cycles ! 366: */ ! 367: ! 368: . = 0x1000 ! 369: .L_handler1000: ! 370: mfspr tmp2, hash1 ! 371: mfctr tmp0 /* use tmp0 to save ctr */ ! 372: mfspr tmp3, icmp ! 373: ! 374: .L_imiss_find_pte_in_pteg: ! 375: li tmp1, 8 /* count */ ! 376: subi tmp2, tmp2, 8 /* offset for lwzu */ ! 377: mtctr tmp1 /* count... */ ! 378: ! 379: .L_imiss_pteg_loop: ! 380: lwz tmp1, 8(tmp2) /* check pte0 for match... */ ! 381: addi tmp2, tmp2, 8 ! 382: cmpw cr0, tmp1, tmp3 ! 383: #if 0 ! 384: bdnzf+ cr0, .L_imiss_pteg_loop ! 385: #else ! 386: bc 0,2, .L_imiss_pteg_loop ! 387: #endif ! 388: beq+ cr0, .L_imiss_found_pte ! 389: ! 390: /* Not found in PTEG, we must scan 2nd then give up */ ! 391: ! 392: andi. tmp1, tmp3, MASK(PTE0_HASH_ID) ! 393: bne- .L_imiss_do_no_hash_exception /* give up */ ! 394: ! 395: mfspr tmp2, hash2 ! 396: ori tmp3, tmp3, MASK(PTE0_HASH_ID) ! 397: b .L_imiss_find_pte_in_pteg ! 398: ! 399: .L_imiss_found_pte: ! 400: ! 401: lwz tmp1, 4(tmp2) /* get pte1_t */ ! 402: andi. tmp3, tmp1, MASK(PTE1_WIMG_GUARD) /* Fault? */ ! 403: bne- .L_imiss_do_prot_exception /* Guarded - illegal */ ! 404: ! 405: /* Ok, we've found what we need to, restore and rfi! */ ! 406: ! 407: mtctr tmp0 /* restore ctr */ ! 408: mfsrr1 tmp3 ! 409: mfspr tmp0, imiss ! 410: mtcrf 0x80, tmp3 /* Restore CR0 */ ! 411: mtspr rpa, tmp1 /* set the pte */ ! 412: ori tmp1, tmp1, MASK(PTE1_REFERENCED) /* set referenced */ ! 413: tlbli tmp0 ! 414: sth tmp1, 6(tmp2) ! 415: rfi ! 416: ! 417: .L_imiss_do_prot_exception: ! 418: /* set up srr1 to indicate protection exception... */ ! 419: mfsrr1 tmp3 ! 420: andi. tmp2, tmp3, 0xffff ! 421: addis tmp2, tmp2, MASK(SRR1_TRANS_PROT) >> 16 ! 422: b .L_imiss_do_exception ! 423: ! 424: .L_imiss_do_no_hash_exception: ! 425: /* clean up registers for protection exception... */ ! 426: mfsrr1 tmp3 ! 427: andi. tmp2, tmp3, 0xffff ! 428: addis tmp2, tmp2, MASK(SRR1_TRANS_HASH) >> 16 ! 429: ! 430: /* And the entry into the usual instruction fault handler ... */ ! 431: .L_imiss_do_exception: ! 432: ! 433: mtctr tmp0 /* Restore ctr */ ! 434: mtsrr1 tmp2 /* Set up srr1 */ ! 435: mfmsr tmp0 ! 436: xoris tmp0, tmp0, MASK(MSR_TGPR)>>16 /* no TGPR */ ! 437: mtcrf 0x80, tmp3 /* Restore CR0 */ ! 438: mtmsr tmp0 /* reset MSR[TGPR] */ ! 439: b .L_handler400 /* Instr Access */ ! 440: ! 441: /* ! 442: * Data load translation miss ! 443: * ! 444: * Upon entry (done for us by the machine): ! 445: * srr0 : addr of instruction that missed ! 446: * srr1 : bits 0-3 = saved CR0 ! 447: * 4 = lru way bit ! 448: * 5 = 1 if store ! 449: * 16-31 = saved msr ! 450: * msr[tgpr] = 1 (so gpr0-3 become our temporary variables) ! 451: * dmiss: ea that missed ! 452: * dcmp : the compare value for the va that missed ! 453: * hash1: pointer to first hash pteg ! 454: * hash2: pointer to 2nd hash pteg ! 455: * ! 456: * Register usage: ! 457: * tmp0: saved counter ! 458: * tmp1: junk ! 459: * tmp2: pointer to pteg ! 460: * tmp3: current compare value ! 461: * ! 462: * This code is taken from the 603e User's Manual with ! 463: * some bugfixes and minor improvements to save bytes and cycles ! 464: */ ! 465: ! 466: . = 0x1100 ! 467: .L_handler1100: ! 468: mfspr tmp2, hash1 ! 469: mfctr tmp0 /* use tmp0 to save ctr */ ! 470: mfspr tmp3, dcmp ! 471: ! 472: .L_dlmiss_find_pte_in_pteg: ! 473: li tmp1, 8 /* count */ ! 474: subi tmp2, tmp2, 8 /* offset for lwzu */ ! 475: mtctr tmp1 /* count... */ ! 476: ! 477: .L_dlmiss_pteg_loop: ! 478: lwz tmp1, 8(tmp2) /* check pte0 for match... */ ! 479: addi tmp2, tmp2, 8 ! 480: cmpw cr0, tmp1, tmp3 ! 481: #if 0 /* How to write this correctly? */ ! 482: bdnzf+ cr0, .L_dlmiss_pteg_loop ! 483: #else ! 484: bc 0,2, .L_dlmiss_pteg_loop ! 485: #endif ! 486: beq+ cr0, .L_dmiss_found_pte ! 487: ! 488: /* Not found in PTEG, we must scan 2nd then give up */ ! 489: ! 490: andi. tmp1, tmp3, MASK(PTE0_HASH_ID) /* already at 2nd? */ ! 491: bne- .L_dmiss_do_no_hash_exception /* give up */ ! 492: ! 493: mfspr tmp2, hash2 ! 494: ori tmp3, tmp3, MASK(PTE0_HASH_ID) ! 495: b .L_dlmiss_find_pte_in_pteg ! 496: ! 497: .L_dmiss_found_pte: ! 498: ! 499: lwz tmp1, 4(tmp2) /* get pte1_t */ ! 500: ! 501: /* Ok, we've found what we need to, restore and rfi! */ ! 502: ! 503: mtctr tmp0 /* restore ctr */ ! 504: mfsrr1 tmp3 ! 505: mfspr tmp0, dmiss ! 506: mtcrf 0x80, tmp3 /* Restore CR0 */ ! 507: mtspr rpa, tmp1 /* set the pte */ ! 508: ori tmp1, tmp1, MASK(PTE1_REFERENCED) /* set referenced */ ! 509: tlbld tmp0 /* load up tlb */ ! 510: sth tmp1, 6(tmp2) /* sth is faster? */ ! 511: rfi ! 512: ! 513: /* This code is shared with data store translation miss */ ! 514: ! 515: .L_dmiss_do_no_hash_exception: ! 516: /* clean up registers for protection exception... */ ! 517: mfsrr1 tmp3 ! 518: /* prepare to set DSISR_WRITE_BIT correctly from srr1 info */ ! 519: rlwinm tmp1, tmp3, 9, 6, 6 ! 520: addis tmp1, tmp1, MASK(DSISR_HASH) >> 16 ! 521: ! 522: /* And the entry into the usual data fault handler ... */ ! 523: ! 524: mtctr tmp0 /* Restore ctr */ ! 525: andi. tmp2, tmp3, 0xffff /* Clean up srr1 */ ! 526: mtsrr1 tmp2 /* Set srr1 */ ! 527: mtdsisr tmp1 ! 528: mfspr tmp2, dmiss ! 529: mtdar tmp2 ! 530: mfmsr tmp0 ! 531: xoris tmp0, tmp0, MASK(MSR_TGPR)>>16 /* no TGPR */ ! 532: mtcrf 0x80, tmp3 /* Restore CR0 */ ! 533: sync /* Needed on some */ ! 534: mtmsr tmp0 /* reset MSR[TGPR] */ ! 535: b .L_handler300 /* Data Access */ ! 536: ! 537: /* ! 538: * Data store translation miss (similar to data load) ! 539: * ! 540: * Upon entry (done for us by the machine): ! 541: * srr0 : addr of instruction that missed ! 542: * srr1 : bits 0-3 = saved CR0 ! 543: * 4 = lru way bit ! 544: * 5 = 1 if store ! 545: * 16-31 = saved msr ! 546: * msr[tgpr] = 1 (so gpr0-3 become our temporary variables) ! 547: * dmiss: ea that missed ! 548: * dcmp : the compare value for the va that missed ! 549: * hash1: pointer to first hash pteg ! 550: * hash2: pointer to 2nd hash pteg ! 551: * ! 552: * Register usage: ! 553: * tmp0: saved counter ! 554: * tmp1: junk ! 555: * tmp2: pointer to pteg ! 556: * tmp3: current compare value ! 557: * ! 558: * This code is taken from the 603e User's Manual with ! 559: * some bugfixes and minor improvements to save bytes and cycles ! 560: */ ! 561: ! 562: . = 0x1200 ! 563: .L_handler1200: ! 564: mfspr tmp2, hash1 ! 565: mfctr tmp0 /* use tmp0 to save ctr */ ! 566: mfspr tmp3, dcmp ! 567: ! 568: .L_dsmiss_find_pte_in_pteg: ! 569: li tmp1, 8 /* count */ ! 570: subi tmp2, tmp2, 8 /* offset for lwzu */ ! 571: mtctr tmp1 /* count... */ ! 572: ! 573: .L_dsmiss_pteg_loop: ! 574: lwz tmp1, 8(tmp2) /* check pte0 for match... */ ! 575: addi tmp2, tmp2, 8 ! 576: ! 577: cmpw cr0, tmp1, tmp3 ! 578: #if 0 /* I don't know how to write this properly */ ! 579: bdnzf+ cr0, .L_dsmiss_pteg_loop ! 580: #else ! 581: bc 0,2, .L_dsmiss_pteg_loop ! 582: #endif ! 583: beq+ cr0, .L_dsmiss_found_pte ! 584: ! 585: /* Not found in PTEG, we must scan 2nd then give up */ ! 586: ! 587: andi. tmp1, tmp3, MASK(PTE0_HASH_ID) /* already at 2nd? */ ! 588: bne- .L_dmiss_do_no_hash_exception /* give up */ ! 589: ! 590: mfspr tmp2, hash2 ! 591: ori tmp3, tmp3, MASK(PTE0_HASH_ID) ! 592: b .L_dsmiss_find_pte_in_pteg ! 593: ! 594: .L_dsmiss_found_pte: ! 595: ! 596: lwz tmp1, 4(tmp2) /* get pte1_t */ ! 597: andi. tmp3, tmp1, MASK(PTE1_CHANGED) /* unchanged, check? */ ! 598: beq- .L_dsmiss_check_prot /* yes, check prot */ ! 599: ! 600: .L_dsmiss_resolved: ! 601: /* Ok, we've found what we need to, restore and rfi! */ ! 602: ! 603: mtctr tmp0 /* restore ctr */ ! 604: mfsrr1 tmp3 ! 605: mfspr tmp0, dmiss ! 606: mtcrf 0x80, tmp3 /* Restore CR0 */ ! 607: mtspr rpa, tmp1 /* set the pte */ ! 608: tlbld tmp0 /* load up tlb */ ! 609: rfi ! 610: ! 611: .L_dsmiss_check_prot: ! 612: /* PTE is unchanged, we must check that we can write */ ! 613: rlwinm. tmp3, tmp1, 30, 0, 1 /* check PP[1] */ ! 614: bge- .L_dsmiss_check_prot_user_kern ! 615: andi. tmp3, tmp1, 1 /* check PP[0] */ ! 616: beq+ .L_dsmiss_check_prot_ok ! 617: ! 618: .L_dmiss_do_prot_exception: ! 619: /* clean up registers for protection exception... */ ! 620: mfsrr1 tmp3 ! 621: /* prepare to set DSISR_WRITE_BIT correctly from srr1 info */ ! 622: rlwinm tmp1, tmp3, 9, 6, 6 ! 623: addis tmp1, tmp1, MASK(DSISR_PROT) >> 16 ! 624: ! 625: /* And the entry into the usual data fault handler ... */ ! 626: ! 627: mtctr tmp0 /* Restore ctr */ ! 628: andi. tmp2, tmp3, 0xffff /* Clean up srr1 */ ! 629: mtsrr1 tmp2 /* Set srr1 */ ! 630: mtdsisr tmp1 ! 631: mfspr tmp2, dmiss ! 632: mtdar tmp2 ! 633: mfmsr tmp0 ! 634: xoris tmp0, tmp0, MASK(MSR_TGPR)>>16 /* no TGPR */ ! 635: mtcrf 0x80, tmp3 /* Restore CR0 */ ! 636: sync /* Needed on some */ ! 637: mtmsr tmp0 /* reset MSR[TGPR] */ ! 638: b .L_handler300 /* Data Access */ ! 639: ! 640: /* NB - if we knew we were on a 603e we could test just the MSR_KEY bit */ ! 641: .L_dsmiss_check_prot_user_kern: ! 642: mfsrr1 tmp3 ! 643: andi. tmp3, tmp3, MASK(MSR_PR) ! 644: beq+ .L_dsmiss_check_prot_kern ! 645: mfspr tmp3, dmiss /* check user privs */ ! 646: mfsrin tmp3, tmp3 /* get excepting SR */ ! 647: andis. tmp3, tmp3, 0x2000 /* Test SR ku bit */ ! 648: beq+ .L_dsmiss_check_prot_ok ! 649: b .L_dmiss_do_prot_exception ! 650: ! 651: .L_dsmiss_check_prot_kern: ! 652: mfspr tmp3, dmiss /* check kern privs */ ! 653: mfsrin tmp3, tmp3 ! 654: andis. tmp3, tmp3, 0x4000 /* Test SR Ks bit */ ! 655: bne- .L_dmiss_do_prot_exception ! 656: ! 657: .L_dsmiss_check_prot_ok: ! 658: /* Ok, mark as referenced and changed before resolving the fault */ ! 659: ori tmp1, tmp1, (MASK(PTE1_REFERENCED)|MASK(PTE1_CHANGED)) ! 660: sth tmp1, 6(tmp2) ! 661: b .L_dsmiss_resolved ! 662: ! 663: /* ! 664: * Instruction address breakpoint ! 665: */ ! 666: ! 667: . = 0x1300 ! 668: .L_handler1300: ! 669: mtsprg 2,r13 /* Save R13 */ ! 670: mtsprg 3,r11 /* Save R11 */ ! 671: mfsprg r13,1 /* Get the exception save area */ ! 672: li r11,T_INSTRUCTION_BKPT /* Set 'rupt code */ ! 673: b .L_exception_entry /* Join common... */ ! 674: ! 675: /* ! 676: * System management interrupt ! 677: */ ! 678: ! 679: . = 0x1400 ! 680: .L_handler1400: ! 681: mtsprg 2,r13 /* Save R13 */ ! 682: mtsprg 3,r11 /* Save R11 */ ! 683: mfsprg r13,1 /* Get the exception save area */ ! 684: li r11,T_SYSTEM_MANAGEMENT /* Set 'rupt code */ ! 685: b .L_exception_entry /* Join common... */ ! 686: ! 687: ; ! 688: ; Altivec Java Mode Assist interrupt ! 689: ; ! 690: ! 691: . = 0x1600 ! 692: .L_handler1600: ! 693: mtsprg 2,r13 /* Save R13 */ ! 694: mtsprg 3,r11 /* Save R11 */ ! 695: mfsprg r13,1 /* Get the exception save area */ ! 696: li r11,T_ALTIVEC_ASSIST /* Set 'rupt code */ ! 697: b .L_exception_entry /* Join common... */ ! 698: ! 699: /* ! 700: * There is now a large gap of reserved traps ! 701: */ ! 702: ! 703: /* ! 704: * Run mode/ trace exception - single stepping on 601 processors ! 705: */ ! 706: ! 707: . = 0x2000 ! 708: .L_handler2000: ! 709: mtsprg 2,r13 /* Save R13 */ ! 710: mtsprg 3,r11 /* Save R11 */ ! 711: mfsprg r13,1 /* Get the exception save area */ ! 712: li r11,T_RUNMODE_TRACE /* Set 'rupt code */ ! 713: b .L_exception_entry /* Join common... */ ! 714: ! 715: /* ! 716: * .L_exception_entry(type) ! 717: * ! 718: * This is the common exception handling routine called by any ! 719: * type of system exception. ! 720: * ! 721: * ENTRY: via a system exception handler, thus interrupts off, VM off. ! 722: * r3 has been saved in sprg3 and now contains a number ! 723: * representing the exception's origins ! 724: * ! 725: */ ! 726: ! 727: .data ! 728: .align ALIGN ! 729: #ifdef __ELF__ ! 730: .type EXT(exception_entry),@object ! 731: .size EXT(exception_entry), 4 ! 732: #endif ! 733: .globl EXT(exception_entry) ! 734: EXT(exception_entry): ! 735: .long .L_exception_entry-EXT(ExceptionVectorsStart) /* phys addr of fn */ ! 736: ! 737: VECTOR_SEGMENT ! 738: .align 2 ! 739: ! 740: .L_exception_entry: ! 741: ! 742: /* ! 743: * ! 744: * Here we will save off a mess of registers, the special ones and R0-R12. We use the DCBZ ! 745: * instruction to clear and allcoate a line in the cache. This way we won't take any cache ! 746: * misses, so these stores won't take all that long. ! 747: * ! 748: * ! 749: */ ! 750: ! 751: dcbz 0,r13 /* Allocate the first line of the savearea in the cache */ ! 752: ! 753: stw r1,saver1(r13) /* Save this one */ ! 754: li r1,32 /* Point to the second line */ ! 755: stw r0,saver0(r13) /* Save this one */ ! 756: dcbz r1,r13 /* Reserve our line in cache */ ! 757: ! 758: #if PERFTIMES && DEBUG ! 759: mftb r1 ; Get the time of interruption ! 760: stw r1,0x17C(br0) ; Save the time of interruption ! 761: #endif ! 762: ! 763: stw r2,saver2(r13) /* Save this one */ ! 764: stw r3,saver3(r13) /* Save this one */ ! 765: stw r6,saver6(r13) /* Save this one */ ! 766: stw r4,saver4(r13) /* Save this one */ ! 767: ! 768: stw r8,saver8(r13) /* Save this one */ ! 769: mfsrr0 r6 /* Get the interruption SRR0 */ ! 770: stw r7,saver7(r13) /* Save this one */ ! 771: mfsrr1 r7 /* Get the interrupt SRR1 */ ! 772: stw r6,savesrr0(r13) /* Save the SRR0 */ ! 773: stw r5,saver5(r13) /* Save this one */ ! 774: mfsprg r6,2 /* Get interrupt time R13 */ ! 775: stw r7,savesrr1(r13) /* Save SRR1 */ ! 776: mfsprg r8,3 /* Get 'rupt time R11 */ ! 777: stw r6,saver13(r13) /* Save 'rupt R1 */ ! 778: la r6,saver14(r13) /* Point to the next cache line */ ! 779: stw r8,saver11(r13) /* Save 'rupt time R11 */ ! 780: ! 781: dcbz 0,r6 /* Allocate in cache */ ! 782: ! 783: stw r9,saver9(r13) /* Save this one */ ! 784: mfcr r7 /* Get the CR */ ! 785: #if 0 ! 786: cmplwi r13,0x1000 ; (TEST/DEBUG) ! 787: bgt+ notpage0yy ; (TEST/DEBUG) ! 788: li r9,1 ; (TEST/DEBUG) ! 789: lwz r9,0(br0) ; (TEST/DEBUG) ! 790: dcbst br0,r9 ; (TEST/DEBUG) ! 791: notpage0aa: b notpage0aa ; (TEST/DEBUG) ! 792: ! 793: notpage0yy: lwz r9,0(br0) ; (TEST/DEBUG) ! 794: mr. r9,r9 ; (TEST/DEBUG) ! 795: notpage0bb: bne- notpage0bb ; (TEST/DEBUG) ! 796: #endif ! 797: ! 798: la r9,saver30(r13) /* Point to the trailing end */ ! 799: stw r10,saver10(r13) /* Save this one */ ! 800: mflr r8 /* Get the LR */ ! 801: stw r12,saver12(r13) /* Save this one */ ! 802: ! 803: dcbz 0,r9 /* Allocate the last in the area */ ! 804: ! 805: stw r14,saver14(r13) /* Save this one */ ! 806: la r10,saver22(r13) /* Point to the next block to save into */ ! 807: stw r15,saver15(r13) /* Save this one */ ! 808: stw r7,savecr(r13) /* Save 'rupt CR */ ! 809: mfctr r6 /* Get the CTR */ ! 810: stw r16,saver16(r13) /* Save this one */ ! 811: stw r8,savelr(r13) /* Save 'rupt LR */ ! 812: ! 813: dcbz 0,r10 /* Allocate next save area line */ ! 814: ! 815: stw r17,saver17(r13) /* Save this one */ ! 816: stw r18,saver18(r13) /* Save this one */ ! 817: stw r6,savectr(r13) /* Save 'rupt CTR */ ! 818: mfxer r7 /* Get the XER */ ! 819: stw r19,saver19(r13) /* Save this one */ ! 820: lis r12,HIGH_ADDR(KERNEL_SEG_REG0_VALUE) /* Get the high half of the kernel SR0 value */ ! 821: mfdar r6 /* Get the 'rupt DAR */ ! 822: stw r20,saver20(r13) /* Save this one */ ! 823: #if 0 ! 824: mfsr r10,sr0 ; (TEST/DEBUG) ! 825: mfsr r20,sr1 ; (TEST/DEBUG) ! 826: stw r10,savesr0(r13) ; (TEST/DEBUG) ! 827: mfsr r10,sr2 ; (TEST/DEBUG) ! 828: mfsr r19,sr3 ; (TEST/DEBUG) ! 829: stw r20,savesr1(r13) ; (TEST/DEBUG) ! 830: mfsr r14,sr4 ; (TEST/DEBUG) ! 831: mfsr r15,sr5 ; (TEST/DEBUG) ! 832: stw r10,savesr2(r13) ; (TEST/DEBUG) ! 833: mfsr r16,sr6 ; (TEST/DEBUG) ! 834: mfsr r17,sr7 ; (TEST/DEBUG) ! 835: stw r19,savesr3(r13) ; (TEST/DEBUG) ! 836: mfsr r10,sr8 ; (TEST/DEBUG) ! 837: mfsr r20,sr9 ; (TEST/DEBUG) ! 838: stw r14,savesr4(r13) ; (TEST/DEBUG) ! 839: mfsr r14,sr10 ; (TEST/DEBUG) ! 840: mfsr r19,sr11 ; (TEST/DEBUG) ! 841: stw r15,savesr5(r13) ; (TEST/DEBUG) ! 842: mfsr r15,sr13 ; (TEST/DEBUG) ! 843: stw r16,savesr6(r13) ; (TEST/DEBUG) ! 844: mfsr r16,sr14 ; (TEST/DEBUG) ! 845: stw r17,savesr7(r13) ; (TEST/DEBUG) ! 846: mfsr r17,sr15 ; (TEST/DEBUG) ! 847: ! 848: stw r10,savesr8(r13) ; (TEST/DEBUG) ! 849: stw r20,savesr9(r13) ; (TEST/DEBUG) ! 850: stw r14,savesr10(r13) ; (TEST/DEBUG) ! 851: stw r19,savesr11(r13) ; (TEST/DEBUG) ! 852: stw r15,savesr13(r13) ; (TEST/DEBUG) ! 853: stw r16,savesr14(r13) ; (TEST/DEBUG) ! 854: stw r17,savesr15(r13) ; (TEST/DEBUG) ! 855: #endif ! 856: ! 857: mtsr sr0,r12 /* Set the kernel SR0 */ ! 858: stw r21,saver21(r13) /* Save this one */ ! 859: addis r12,r12,0x0010 ; Point to the second segment of kernel ! 860: stw r7,savexer(r13) /* Save the 'rupt XER */ ! 861: mtsr sr1,r12 /* Set the kernel SR1 */ ! 862: stw r30,saver30(r13) /* Save this one */ ! 863: addis r12,r12,0x0010 ; Point to the third segment of kernel ! 864: stw r31,saver31(r13) /* Save this one */ ! 865: mtsr sr2,r12 /* Set the kernel SR2 */ ! 866: stw r22,saver22(r13) /* Save this one */ ! 867: addis r12,r12,0x0010 ; Point to the third segment of kernel ! 868: la r10,savedar(r13) /* Point to exception info block */ ! 869: stw r23,saver23(r13) /* Save this one */ ! 870: mtsr sr3,r12 /* Set the kernel SR3 */ ! 871: stw r24,saver24(r13) /* Save this one */ ! 872: stw r25,saver25(r13) /* Save this one */ ! 873: mfdsisr r7 /* Get the 'rupt DSISR */ ! 874: stw r26,saver26(r13) /* Save this one */ ! 875: ! 876: dcbz 0,r10 /* Allocate exception info line */ ! 877: ! 878: stw r27,saver27(r13) /* Save this one */ ! 879: stw r28,saver28(r13) /* Save this one */ ! 880: stw r29,saver29(r13) /* Save this one */ ! 881: mfsr r14,sr14 ; Get the copyin/out segment register ! 882: stw r6,savedar(r13) /* Save the 'rupt DAR */ ! 883: stw r7,savedsisr(r13) /* Save the 'rupt code DSISR */ ! 884: stw r11,saveexception(r13) /* Save the exception code */ ! 885: stw r14,savesr14(r13) ; Save copyin/copyout ! 886: ! 887: lis r8,HIGH_ADDR(EXT(saveanchor)) /* Get the high part of the anchor */ ! 888: mfpvr r20 /* Get the PVR */ ! 889: ori r8,r8,LOW_ADDR(EXT(saveanchor)) /* Bottom half of the anchor */ ! 890: li r21,0x3612 /* Mask of processors with a PIR */ ! 891: rlwinm r20,r20,16,16,31 /* Isolate the CPU type */ ! 892: srw r21,r21,r20 /* Isolate the PIR valid bit */ ! 893: cmplwi cr1,r20,PROCESSOR_VERSION_Max ; Do we have Altivec? ! 894: rlwinm r21,r21,0,31,31 /* Isolate the PIR valid */ ! 895: ! 896: li r19,0 ; Assume no Altivec ! 897: blt cr1,noavec ; No possible AltiVec here... ! 898: mfspr r19,vrsave ; Get the VRSAVE register ! 899: ! 900: noavec: cmplwi cr6,r21,1 /* Check if PIR is valid */ ! 901: stw r19,savevrsave(r13) ; Save the vector register usage flags ! 902: ! 903: #if 0 ! 904: lwz r14,savesrr0(r13) /* (TEST/DEBUG) */ ! 905: cmplw cr7,r5,r5 /* (TEST/DEBUG) */ ! 906: rlwinm. r14,r14,0,0,15 /* (TEST/DEBUG) */ ! 907: cmplwi cr2,r11,T_INTERRUPT /* (TEST/DEBUG) */ ! 908: beq- noeattrace2 /* (TEST/DEBUG) */ ! 909: cmplwi r11,T_SYSTEM_CALL /* (TEST/DEBUG) */ ! 910: rlwinm r14,r0,1,0,31 /* (TEST/DEBUG) */ ! 911: beq cr2,eatatjoes /* (TEST/DEBUG) */ ! 912: bne+ noeattrace2 /* (TEST/DEBUG) */ ! 913: cmplwi r14,0x001B /* (TEST/DEBUG) */ ! 914: bne+ noeattrace2 /* (TEST/DEBUG) */ ! 915: ! 916: eatatjoes: cmplwi cr7,r13,0 /* (TEST/DEBUG) */ ! 917: ! 918: noeattrace2: ! 919: #else ! 920: cmplw cr7,r13,r13 /* (TEST/DEBUG) */ ! 921: #endif ! 922: #if RUPTTRC ! 923: lwz r9,0(br0) /* (TEST/DEBUG) */ ! 924: lis r14,0x7FFF /* (TEST/DEBUG) */ ! 925: mr. r9,r9 /* (TEST/DEBUG) */ ! 926: beq+ nono1 /* (TEST/DEBUG) */ ! 927: bne cr7,nono1 /* (TEST/DEBUG) */ ! 928: ! 929: mfdec r9 /* (TEST/DEBUG) */ ! 930: or r14,r14,r9 /* (TEST/DEBUG) */ ! 931: mtdec r14 /* (TEST/DEBUG) */ ! 932: li r14,0x20 /* (TEST/DEBUG) */ ! 933: ! 934: lwarx r15,0,r14 ; ? ! 935: ! 936: mpwait0: lwarx r15,0,r14 /* (TEST/DEBUG) */ ! 937: mr. r15,r15 /* (TEST/DEBUG) */ ! 938: bne- mpwait0 /* (TEST/DEBUG) */ ! 939: stwcx. r14,0,r14 /* (TEST/DEBUG) */ ! 940: bne- mpwait0 /* (TEST/DEBUG) */ ! 941: ! 942: stw r0,0x280(br0) /* (TEST/DEBUG) */ ! 943: stmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 944: bne cr6,nopir0 /* (TEST/DEBUG) */ ! 945: mfspr r4,pir /* (TEST/DEBUG) */ ! 946: b gotpir0 /* (TEST/DEBUG) */ ! 947: nopir0: li r4,0 /* (TEST/DEBUG) */ ! 948: gotpir0: /* (TEST/DEBUG) */ ! 949: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 950: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 951: li r3,0 /* (TEST/DEBUG) */ ! 952: rlwimi r4,r11,30,8,31 /* (TEST/DEBUG) */ ! 953: mfsrr0 r5 /* (TEST/DEBUG) */ ! 954: oris r4,r4,0x3030 /* (TEST/DEBUG) */ ! 955: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 956: ori r4,r4,0x3030 /* (TEST/DEBUG) */ ! 957: mtlr r31 /* (TEST/DEBUG) */ ! 958: blrl /* (TEST/DEBUG) */ ! 959: ! 960: bne cr6,nopir1 /* (TEST/DEBUG) */ ! 961: mfspr r4,pir /* (TEST/DEBUG) */ ! 962: b gotpir1 /* (TEST/DEBUG) */ ! 963: nopir1: li r4,0 /* (TEST/DEBUG) */ ! 964: gotpir1: /* (TEST/DEBUG) */ ! 965: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 966: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 967: lwz r5,savelr(r13) /* (TEST/DEBUG) */ ! 968: li r3,0 /* (TEST/DEBUG) */ ! 969: oris r4,r4,0x3030 /* (TEST/DEBUG) */ ! 970: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 971: ori r4,r4,0x3130 /* (TEST/DEBUG) */ ! 972: mtlr r31 /* (TEST/DEBUG) */ ! 973: blrl /* (TEST/DEBUG) */ ! 974: ! 975: bne cr6,nopir2 /* (TEST/DEBUG) */ ! 976: mfspr r4,pir /* (TEST/DEBUG) */ ! 977: b gotpir2 /* (TEST/DEBUG) */ ! 978: nopir2: li r4,0 /* (TEST/DEBUG) */ ! 979: gotpir2: /* (TEST/DEBUG) */ ! 980: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 981: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 982: li r3,0 /* (TEST/DEBUG) */ ! 983: mr r5,r13 /* (TEST/DEBUG) */ ! 984: oris r4,r4,0x3030 /* (TEST/DEBUG) */ ! 985: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 986: ori r4,r4,0x3131 /* (TEST/DEBUG) */ ! 987: mtlr r31 /* (TEST/DEBUG) */ ! 988: blrl /* (TEST/DEBUG) */ ! 989: lmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 990: lwz r0,0x280(br0) /* (TEST/DEBUG) */ ! 991: ! 992: li r15,0 /* (TEST/DEBUG) */ ! 993: stw r15,0x20(br0) /* (TEST/DEBUG) */ ! 994: mtdec r9 /* (TEST/DEBUG) */ ! 995: nono1: ! 996: #endif ! 997: ! 998: ! 999: /* ! 1000: * Everything is saved at this point, except for FPRs, and VMX registers ! 1001: * ! 1002: * Time for a new save area. Allocate the trace table entry now also ! 1003: * Note that we haven't touched R0-R5 yet. Except for R1, that's in the save ! 1004: */ ! 1005: ! 1006: #if 0 ! 1007: mfsrr1 r20 ; (TEST/DEBUG) ! 1008: mfsrr0 r7 ; (TEST/DEBUG) ! 1009: lis r9,0x8000 ; (TEST/DEBUG) ! 1010: mfmsr r25 ; (TEST/DEBUG) ! 1011: ori r15,r25,0x10 ; (TEST/DEBUG) ! 1012: mtmsr r15 ; (TEST/DEBUG) ! 1013: isync ; (TEST/DEBUG) ! 1014: ori r9,r9,lo16(0x870C) ; (TEST/DEBUG) ! 1015: stw r11,0(r9) ; (TEST/DEBUG) ! 1016: stw r7,0(r9) ; (TEST/DEBUG) ! 1017: mtmsr r25 ; (TEST/DEBUG) ! 1018: isync ; (TEST/DEBUG) ! 1019: mtsrr1 r20 ; (TEST/DEBUG) ! 1020: mtsrr0 r7 ; (TEST/DEBUG) ! 1021: #endif ! 1022: ! 1023: ! 1024: lwarx r9,0,r8 ; ? ! 1025: ! 1026: lllck: lwarx r9,0,r8 /* Grab the lock value */ ! 1027: li r7,1 /* Use part of the delay time */ ! 1028: mr. r9,r9 /* Is it locked? */ ! 1029: bne- lllcks /* Yeah, wait for it to clear... */ ! 1030: stwcx. r7,0,r8 /* Try to seize that there durn lock */ ! 1031: beq+ lllckd /* Got it... */ ! 1032: b lllck /* Collision, try again... */ ! 1033: ! 1034: lllcks: lwz r9,SVlock(r8) /* Get that lock in here */ ! 1035: mr. r9,r9 /* Is it free yet? */ ! 1036: beq+ lllck /* Yeah, try for it again... */ ! 1037: b lllcks /* Sniff away... */ ! 1038: ! 1039: lllckd: isync /* Purge any speculative executions here */ ! 1040: rlwinm r7,r11,30,0,31 /* Save 'rupt code shifted right 2 */ ! 1041: #if 1 ! 1042: lwz r14,LOW_ADDR(traceMask-EXT(ExceptionVectorsStart))(br0) /* Get the trace mask */ ! 1043: #else ! 1044: li r14,-1 /* (TEST/DEBUG) */ ! 1045: #endif ! 1046: addi r7,r7,10 /* Adjust for CR5_EQ position */ ! 1047: lwz r15,SVfree(r8) /* Get the head of the save area list */ ! 1048: lwz r25,SVinuse(r8) /* Get the in use count */ ! 1049: rlwnm r7,r14,r7,22,22 /* Set CR5_EQ bit position to 0 if tracing allowed */ ! 1050: lwz r20,LOW_ADDR(EXT(traceCurr)-EXT(ExceptionVectorsStart))(br0) /* Pick up the current trace entry */ ! 1051: mtcrf 0x04,r7 /* Set CR5 to show trace or not */ ! 1052: ! 1053: lwz r14,SACalloc(r15) /* Pick up the allocation bits */ ! 1054: addi r25,r25,1 /* Bump up the in use count for the new savearea */ ! 1055: lwz r21,LOW_ADDR(EXT(traceEnd)-EXT(ExceptionVectorsStart))(br0) /* Grab up the end of it all */ ! 1056: mr. r14,r14 /* Can we use the first one? */ ! 1057: blt use1st /* Yeah... */ ! 1058: ! 1059: andis. r14,r14,0x8000 /* Show we used the second and remember if it was the last */ ! 1060: addi r10,r15,0x0800 /* Point to the first one */ ! 1061: b gotsave /* We have the area now... */ ! 1062: ! 1063: use1st: andis. r14,r14,0x4000 /* Mark first gone and remember if empty */ ! 1064: mr r10,r15 /* Set the save area */ ! 1065: ! 1066: gotsave: stw r14,SACalloc(r15) /* Put back the allocation bits */ ! 1067: bne nodqsave /* There's still an empty slot, don't dequeue... */ ! 1068: ! 1069: lwz r16,SACnext(r15) /* Get the next in line */ ! 1070: stw r16,SVfree(r8) /* Dequeue our now empty save area block */ ! 1071: ! 1072: nodqsave: addi r22,r20,LTR_size /* Point to the next trace entry */ ! 1073: stw r25,SVinuse(r8) /* Set the in use count */ ! 1074: li r17,0 /* Clear this for the lock */ ! 1075: cmplw r22,r21 /* Do we need to wrap the trace table? */ ! 1076: stw r17,SAVprev(r10) /* Clear back pointer for the newly allocated guy */ ! 1077: mtsprg 1,r10 /* Get set for the next 'rupt */ ! 1078: bne+ gotTrcEnt /* We got a trace entry... */ ! 1079: ! 1080: lwz r22,LOW_ADDR(EXT(traceStart)-EXT(ExceptionVectorsStart))(br0) /* Wrap back to the top */ ! 1081: ! 1082: gotTrcEnt: bne- cr5,skipTrace1 /* Don't want to trace this kind... */ ! 1083: ! 1084: stw r22,LOW_ADDR(EXT(traceCurr)-EXT(ExceptionVectorsStart))(br0) /* Set the next entry for the next guy */ ! 1085: ! 1086: #if ESPDEBUG ! 1087: li r22,0x180 ; (TEST/DEBUG) ! 1088: dcbst br0,r22 ; (TEST/DEBUG) ! 1089: sync ; (TEST/DEBUG) ! 1090: #endif ! 1091: ! 1092: dcbz 0,r20 /* Allocate cache for the entry */ ! 1093: ! 1094: skipTrace1: sync /* Make sure all stores are done */ ! 1095: stw r17,SVlock(r8) /* Unlock both save and trace areas */ ! 1096: ! 1097: #if RUPTTRC ! 1098: lis r14,0x7FFF /* (TEST/DEBUG) */ ! 1099: mfdec r17 /* (TEST/DEBUG) */ ! 1100: or r14,r14,r17 /* (TEST/DEBUG) */ ! 1101: mtdec r14 /* (TEST/DEBUG) */ ! 1102: li r14,0x20 /* (TEST/DEBUG) */ ! 1103: ! 1104: lwarx r16,0,r14 ; ? ! 1105: ! 1106: mpwait1: lwarx r16,0,r14 /* (TEST/DEBUG) */ ! 1107: mr. r16,r16 /* (TEST/DEBUG) */ ! 1108: bne- mpwait1 /* (TEST/DEBUG) */ ! 1109: stwcx. r14,0,r14 /* (TEST/DEBUG) */ ! 1110: bne- mpwait1 /* (TEST/DEBUG) */ ! 1111: ! 1112: stw r0,0x280(br0) /* (TEST/DEBUG) */ ! 1113: stmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 1114: bne cr7,nono2 /* (TEST/DEBUG) */ ! 1115: lwz r0,0(br0) /* (TEST/DEBUG) */ ! 1116: mr. r0,r0 /* (TEST/DEBUG) */ ! 1117: beq+ nono2 /* (TEST/DEBUG) */ ! 1118: bne cr6,nopir3 /* (TEST/DEBUG) */ ! 1119: mfspr r4,pir /* (TEST/DEBUG) */ ! 1120: b gotpir3 /* (TEST/DEBUG) */ ! 1121: nopir3: li r4,0 /* (TEST/DEBUG) */ ! 1122: gotpir3: /* (TEST/DEBUG) */ ! 1123: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 1124: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 1125: li r3,0 /* (TEST/DEBUG) */ ! 1126: mr r5,r10 /* (TEST/DEBUG) */ ! 1127: oris r4,r4,0x3030 /* (TEST/DEBUG) */ ! 1128: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 1129: ori r4,r4,0x3230 /* (TEST/DEBUG) */ ! 1130: mtlr r31 /* (TEST/DEBUG) */ ! 1131: blrl /* (TEST/DEBUG) */ ! 1132: nono2: ! 1133: lmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 1134: lwz r0,0x280(br0) /* (TEST/DEBUG) */ ! 1135: li r16,0 /* (TEST/DEBUG) */ ! 1136: stw r16,0x20(br0) /* (TEST/DEBUG) */ ! 1137: mtdec r17 /* (TEST/DEBUG) */ ! 1138: ! 1139: #endif ! 1140: ! 1141: ! 1142: ! 1143: /* ! 1144: * At this point, we can take another exception and lose nothing. ! 1145: * ! 1146: * We still have the current savearea pointed to by R13, the next by R10 and ! 1147: * sprg1. R20 contains the pointer to a trace entry and CR5_eq says ! 1148: * to do the trace or not. ! 1149: * ! 1150: * Note that R13 was chosen as the save area pointer because the SIGP, ! 1151: * firmware, and DSI/ISI handlers aren't supposed to touch anything ! 1152: * over R12. But, actually, the DSI/ISI stuff does. ! 1153: * ! 1154: * ! 1155: * Let's cut that trace entry now. ! 1156: */ ! 1157: ! 1158: bne- cr5,skipTrace2 /* Don't want to trace this kind... */ ! 1159: ! 1160: li r14,32 /* Second line of entry */ ! 1161: ! 1162: getTB: mftbu r16 /* Get the upper timebase */ ! 1163: mftb r17 /* Get the lower timebase */ ! 1164: mftbu r18 /* Get the upper one again */ ! 1165: cmplw r16,r18 /* Did the top tick? */ ! 1166: bne- getTB /* Yeah, need to get it again... */ ! 1167: ! 1168: dcbz r14,r20 /* Zap the second half */ ! 1169: ! 1170: stw r16,LTR_timeHi(r20) /* Set the upper part of TB */ ! 1171: bne cr6,nopir4 /* Is there a processor ID number on this guy? */ ! 1172: mfspr r19,pir /* Get the processor address */ ! 1173: b gotpir4 /* Got it... */ ! 1174: nopir4: li r19,0 /* Assume processor 0 for those underprivileged folks */ ! 1175: gotpir4: ! 1176: lwz r1,saver1(r13) /* Get back interrupt time R1 */ ! 1177: stw r17,LTR_timeLo(r20) /* Set the lower part of TB */ ! 1178: rlwinm r19,r19,0,27,31 /* Cut the junk */ ! 1179: stw r0,LTR_r0(r20) /* Save off register 0 */ ! 1180: sth r19,LTR_cpu(r20) /* Stash the cpu address */ ! 1181: stw r1,LTR_r1(r20) /* Save off register 1 */ ! 1182: stw r2,LTR_r2(r20) /* Save off register 2 */ ! 1183: stw r3,LTR_r3(r20) /* Save off register 3 */ ! 1184: lwz r16,savecr(r13) /* We don't remember the CR anymore, get it */ ! 1185: stw r4,LTR_r4(r20) /* Save off register 4 */ ! 1186: mfsrr0 r17 /* Get this back, it's still good */ ! 1187: stw r5,LTR_r5(r20) /* Save off register 5 */ ! 1188: mfsrr1 r18 /* This is still good in here also */ ! 1189: ! 1190: stw r16,LTR_cr(r20) /* Save the CR (or dec) */ ! 1191: stw r17,LTR_srr0(r20) /* Save the SSR0 */ ! 1192: stw r18,LTR_srr1(r20) /* Save the SRR1 */ ! 1193: mfdar r17 /* Get this back */ ! 1194: ! 1195: mflr r16 /* Get the LR */ ! 1196: stw r17,LTR_dar(r20) /* Save the DAR */ ! 1197: mfctr r17 /* Get the CTR */ ! 1198: stw r16,LTR_lr(r20) /* Save the LR */ ! 1199: #if 0 ! 1200: lis r17,HIGH_ADDR(EXT(saveanchor)) ; (TEST/DEBUG) ! 1201: ori r17,r17,LOW_ADDR(EXT(saveanchor)) ; (TEST/DEBUG) ! 1202: lwz r16,SVcount(r17) ; (TEST/DEBUG) ! 1203: lwz r17,SVinuse(r17) ; (TEST/DEBUG) ! 1204: rlwimi r17,r16,16,0,15 ; (TEST/DEBUG) ! 1205: #endif ! 1206: stw r17,LTR_ctr(r20) /* Save off the CTR */ ! 1207: stw r13,LTR_save(r20) /* Save the savearea */ ! 1208: sth r11,LTR_excpt(r20) /* Save the exception type */ ! 1209: #if ESPDEBUG ! 1210: addi r17,r20,32 ; (TEST/DEBUG) ! 1211: dcbst br0,r20 ; (TEST/DEBUG) ! 1212: dcbst br0,r17 ; (TEST/DEBUG) ! 1213: sync ; (TEST/DEBUG) ! 1214: #endif ! 1215: ! 1216: /* ! 1217: * We're done with the trace, except for maybe modifying the exception ! 1218: * code later on. So, that means that we need to save R20 and CR5, but ! 1219: * R0 to R5 are clear now. ! 1220: * ! 1221: * So, let's finish setting up the kernel registers now. ! 1222: */ ! 1223: ! 1224: skipTrace2: ! 1225: ! 1226: #if PERFTIMES && DEBUG ! 1227: li r3,68 ; Indicate interrupt ! 1228: mr r4,r11 ; Get code to log ! 1229: mr r5,r13 ; Get savearea to log ! 1230: mr r8,r0 ; Save R0 ! 1231: bl EXT(dbgLog2) ; Cut log entry ! 1232: mr r0,r8 ; Restore R0 ! 1233: #endif ! 1234: ! 1235: mfsprg r2,0 /* Get the per processor block */ ! 1236: ! 1237: #if 0 ! 1238: lis r19,0xF300 /* (TEST/DEBUG) */ ! 1239: ori r19,r19,0x0020 /* (TEST/DEBUG) */ ! 1240: dcbi 0,r19 /* (TEST/DEBUG) */ ! 1241: sync /* (TEST/DEBUG) */ ! 1242: eieio /* (TEST/DEBUG) */ ! 1243: lwz r18,0x000C(r19) /* (TEST/DEBUG) */ ! 1244: eieio /* (TEST/DEBUG) */ ! 1245: dcbi 0,r19 /* (TEST/DEBUG) */ ! 1246: rlwinm. r4,r18,0,19,19 /* (TEST/DEBUG) */ ! 1247: rlwinm r18,r18,0,20,18 /* (TEST/DEBUG) */ ! 1248: sync /* (TEST/DEBUG) */ ! 1249: eieio /* (TEST/DEBUG) */ ! 1250: beq+ nonmi /* (TEST/DEBUG) */ ! 1251: ! 1252: stw r18,0x0008(r19) /* (TEST/DEBUG) */ ! 1253: dcbi 0,r19 /* (TEST/DEBUG) */ ! 1254: sync /* (TEST/DEBUG) */ ! 1255: eieio /* (TEST/DEBUG) */ ! 1256: BREAKPOINT_TRAP /* (TEST/DEBUG) */ ! 1257: ! 1258: nonmi: /* (TEST/DEBUG) */ ! 1259: #endif ! 1260: ! 1261: #if 0 ! 1262: lis r4,hi16(EXT(hash_table_base)) ; (TEST/DEBUG) ! 1263: ori r4,r4,lo16(EXT(hash_table_base)) ; (TEST/DEBUG) ! 1264: lwz r8,0(r4) ; (TEST/DEBUG) ! 1265: lwz r4,4(r4) ; (TEST/DEBUG) ! 1266: add r8,r4,r8 ; (TEST/DEBUG) ! 1267: ! 1268: yyyck: lwz r12,4(r8) ; (TEST/DEBUG) ! 1269: rlwimn. r12,r12,0,24,31 ; (TEST/DEBUG) ! 1270: bne+ yyyok ; (TEST/DEBUG) ! 1271: BREAKPOINT_TRAP ; (TEST/DEBUG) ! 1272: ! 1273: yyyok: addi r8,r8,0x40 ; (TEST/DEBUG) ! 1274: subic r4,r4,0x40 ; (TEST/DEBUG) ! 1275: bgt+ yyyck ; (TEST/DEBUG) ! 1276: #endif ! 1277: ! 1278: #if CHECKSAVE ! 1279: ! 1280: lis r4,0x7FFF /* (TEST/DEBUG) */ ! 1281: mfdec r12 /* (TEST/DEBUG) */ ! 1282: or r4,r4,r12 /* (TEST/DEBUG) */ ! 1283: mtdec r4 /* (TEST/DEBUG) */ ! 1284: li r4,0x20 /* (TEST/DEBUG) */ ! 1285: ! 1286: lwarx r8,0,r4 ; ? ! 1287: ! 1288: mpwait2: lwarx r8,0,r4 /* (TEST/DEBUG) */ ! 1289: mr. r8,r8 /* (TEST/DEBUG) */ ! 1290: bne- mpwait2 /* (TEST/DEBUG) */ ! 1291: stwcx. r4,0,r4 /* (TEST/DEBUG) */ ! 1292: bne- mpwait2 /* (TEST/DEBUG) */ ! 1293: ! 1294: isync /* (TEST/DEBUG) */ ! 1295: lwz r4,0xD80(br0) /* (TEST/DEBUG) */ ! 1296: mr. r4,r4 /* (TEST/DEBUG) */ ! 1297: li r4,1 /* (TEST/DEBUG) */ ! 1298: bne- doncheksv /* (TEST/DEBUG) */ ! 1299: ! 1300: lis r8,HIGH_ADDR(EXT(saveanchor)) /* (TEST/DEBUG) */ ! 1301: ori r8,r8,LOW_ADDR(EXT(saveanchor)) /* (TEST/DEBUG) */ ! 1302: ! 1303: stw r4,0xD80(br0) /* (TEST/DEBUG) */ ! 1304: ! 1305: lwarx r4,0,r8 ; ? ! 1306: ! 1307: mpwait2x: lwarx r4,0,r8 /* (TEST/DEBUG) */ ! 1308: mr. r4,r4 /* (TEST/DEBUG) */ ! 1309: bne- mpwait2x /* (TEST/DEBUG) */ ! 1310: stwcx. r8,0,r8 /* (TEST/DEBUG) */ ! 1311: bne- mpwait2x /* (TEST/DEBUG) */ ! 1312: ! 1313: isync /* (TEST/DEBUG) */ ! 1314: ! 1315: #if 0 ! 1316: rlwinm r4,r13,0,0,19 /* (TEST/DEBUG) */ ! 1317: lwz r21,SACflags(r4) /* (TEST/DEBUG) */ ! 1318: rlwinm r22,r21,24,24,31 /* (TEST/DEBUG) */ ! 1319: cmplwi r22,0x00EE /* (TEST/DEBUG) */ ! 1320: lwz r22,SACvrswap(r4) /* (TEST/DEBUG) */ ! 1321: bne- currbad /* (TEST/DEBUG) */ ! 1322: andis. r21,r21,hi16(sac_perm) /* (TEST/DEBUG) */ ! 1323: bne- currnotbad /* (TEST/DEBUG) */ ! 1324: mr. r22,r22 /* (TEST/DEBUG) */ ! 1325: bne+ currnotbad /* (TEST/DEBUG) */ ! 1326: ! 1327: currbad: lis r23,hi16(EXT(debugbackpocket)) /* (TEST/DEBUG) */ ! 1328: ori r23,r23,lo16(EXT(debugbackpocket)) /* (TEST/DEBUG) */ ! 1329: stw r23,SVfree(r8) /* (TEST/DEBUG) */ ! 1330: ! 1331: mfsprg r25,1 /* (TEST/DEBUG) */ ! 1332: mtsprg 1,r23 /* (TEST/DEBUG) */ ! 1333: lwz r26,SACalloc(r23) /* (TEST/DEBUG) */ ! 1334: rlwinm r26,r26,0,1,31 /* (TEST/DEBUG) */ ! 1335: stw r26,SACalloc(r23) /* (TEST/DEBUG) */ ! 1336: ! 1337: sync /* (TEST/DEBUG) */ ! 1338: li r28,0 /* (TEST/DEBUG) */ ! 1339: stw r28,0x20(br0) /* (TEST/DEBUG) */ ! 1340: stw r28,0(r8) /* (TEST/DEBUG) */ ! 1341: BREAKPOINT_TRAP /* (TEST/DEBUG) */ ! 1342: ! 1343: currnotbad: ! 1344: #endif ! 1345: ! 1346: lwz r28,SVcount(r8) /* (TEST/DEBUG) */ ! 1347: #if RUPTTRC ! 1348: stw r0,0x280(br0) /* (TEST/DEBUG) */ ! 1349: stmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 1350: bne cr7,nono90 /* (TEST/DEBUG) */ ! 1351: lwz r0,0(br0) /* (TEST/DEBUG) */ ! 1352: mr. r0,r0 /* (TEST/DEBUG) */ ! 1353: beq+ nono90 /* (TEST/DEBUG) */ ! 1354: bne cr6,nopir5 /* (TEST/DEBUG) */ ! 1355: mfspr r4,pir /* (TEST/DEBUG) */ ! 1356: b gotpir0 /* (TEST/DEBUG) */ ! 1357: nopir5: li r4,0 /* (TEST/DEBUG) */ ! 1358: gotpir5: /* (TEST/DEBUG) */ ! 1359: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 1360: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 1361: li r3,0 /* (TEST/DEBUG) */ ! 1362: mr r5,r28 /* (TEST/DEBUG) */ ! 1363: oris r4,r4,0x3036 /* (TEST/DEBUG) */ ! 1364: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 1365: ori r4,r4,0x3636 /* (TEST/DEBUG) */ ! 1366: mtlr r31 /* (TEST/DEBUG) */ ! 1367: blrl /* (TEST/DEBUG) */ ! 1368: nono90: ! 1369: lmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 1370: lwz r0,0x280(br0) /* (TEST/DEBUG) */ ! 1371: #endif ! 1372: lwz r21,SVinuse(r8) /* (TEST/DEBUG) */ ! 1373: lwz r23,SVmin(r8) /* (TEST/DEBUG) */ ! 1374: sub r22,r28,r21 /* (TEST/DEBUG) */ ! 1375: cmpw r22,r23 /* (TEST/DEBUG) */ ! 1376: bge+ cksave0 /* (TEST/DEBUG) */ ! 1377: ! 1378: li r4,0 /* (TEST/DEBUG) */ ! 1379: stw r4,0x20(br0) /* (TEST/DEBUG) */ ! 1380: stw r4,0(r8) /* (TEST/DEBUG) */ ! 1381: BREAKPOINT_TRAP /* (TEST/DEBUG) */ ! 1382: ! 1383: cksave0: lwz r28,SVfree(r8) /* (TEST/DEBUG) */ ! 1384: li r24,0 /* (TEST/DEBUG) */ ! 1385: li r29,1 /* (TEST/SAVE) */ ! 1386: ! 1387: cksave0a: mr. r28,r28 /* (TEST/DEBUG) */ ! 1388: beq- cksave3 /* (TEST/DEBUG) */ ! 1389: ! 1390: rlwinm. r21,r28,0,4,19 /* (TEST/DEBUG) */ ! 1391: bne+ cksave1 /* (TEST/DEBUG) */ ! 1392: ! 1393: li r4,0 /* (TEST/DEBUG) */ ! 1394: stw r4,0x20(br0) /* (TEST/DEBUG) */ ! 1395: stw r4,0(r8) /* (TEST/DEBUG) */ ! 1396: BREAKPOINT_TRAP /* (TEST/DEBUG) */ ! 1397: ! 1398: cksave1: rlwinm. r21,r28,0,21,3 /* (TEST/DEBUG) */ ! 1399: beq+ cksave2 /* (TEST/DEBUG) */ ! 1400: ! 1401: li r4,0 /* (TEST/DEBUG) */ ! 1402: stw r4,0x20(br0) /* (TEST/DEBUG) */ ! 1403: stw r4,0(r8) /* (TEST/DEBUG) */ ! 1404: BREAKPOINT_TRAP /* (TEST/DEBUG) */ ! 1405: ! 1406: cksave2: lwz r25,SACalloc(r28) /* (TEST/DEBUG) */ ! 1407: lbz r26,SACflags+2(r28) /* (TEST/DEBUG) */ ! 1408: lbz r21,SACflags+3(r28) /* (TEST/DEBUG) */ ! 1409: cmplwi r26,0x00EE /* (TEST/DEBUG) */ ! 1410: stb r29,SACflags+3(r28) /* (TEST/DEBUG) */ ! 1411: beq+ cksave2z ! 1412: ! 1413: li r4,0 /* (TEST/DEBUG) */ ! 1414: stw r4,0x20(br0) /* (TEST/DEBUG) */ ! 1415: stw r4,0(r8) /* (TEST/DEBUG) */ ! 1416: BREAKPOINT_TRAP /* (TEST/DEBUG) */ ! 1417: ! 1418: cksave2z: mr. r21,r21 /* (TEST/DEBUG) */ ! 1419: beq+ cksave2a /* (TEST/DEBUG) */ ! 1420: ! 1421: li r4,0 /* (TEST/DEBUG) */ ! 1422: stw r4,0x20(br0) /* (TEST/DEBUG) */ ! 1423: stw r4,0(r8) /* (TEST/DEBUG) */ ! 1424: BREAKPOINT_TRAP /* (TEST/DEBUG) */ ! 1425: ! 1426: cksave2a: rlwinm r26,r25,1,31,31 /* (TEST/DEBUG) */ ! 1427: rlwinm r27,r25,2,31,31 /* (TEST/DEBUG) */ ! 1428: add r24,r24,r26 /* (TEST/DEBUG) */ ! 1429: add r24,r24,r27 /* (TEST/DEBUG) */ ! 1430: lwz r28,SACnext(r28) /* (TEST/DEBUG) */ ! 1431: b cksave0a /* (TEST/DEBUG) */ ! 1432: ! 1433: cksave3: cmplw r24,r22 /* (TEST/DEBUG) */ ! 1434: beq+ cksave4 /* (TEST/DEBUG) */ ! 1435: ! 1436: li r4,0 /* (TEST/DEBUG) */ ! 1437: stw r4,0x20(br0) /* (TEST/DEBUG) */ ! 1438: stw r4,0(r8) /* (TEST/DEBUG) */ ! 1439: BREAKPOINT_TRAP /* (TEST/DEBUG) */ ! 1440: ! 1441: cksave4: lwz r28,SVfree(r8) /* (TEST/DEBUG) */ ! 1442: li r24,0 /* (TEST/DEBUG) */ ! 1443: ! 1444: cksave5: mr. r28,r28 /* (TEST/DEBUG) */ ! 1445: beq- cksave6 /* (TEST/DEBUG) */ ! 1446: stb r24,SACflags+3(r28) /* (TEST/DEBUG) */ ! 1447: lwz r28,SACnext(r28) /* (TEST/DEBUG) */ ! 1448: b cksave5 /* (TEST/DEBUG) */ ! 1449: ! 1450: cksave6: ! 1451: ! 1452: li r4,0 /* (TEST/DEBUG) */ ! 1453: stw r4,0xD80(br0) /* (TEST/DEBUG) */ ! 1454: stw r4,0(r8) /* (TEST/DEBUG) */ ! 1455: ! 1456: doncheksv: ! 1457: li r4,0 /* (TEST/DEBUG) */ ! 1458: stw r4,0x20(br0) /* (TEST/DEBUG) */ ! 1459: mtdec r12 /* (TEST/DEBUG) */ ! 1460: #endif ! 1461: ! 1462: #if 0 ! 1463: lhz r4,0x980(br0) ; (TEST/DEBUG) ! 1464: xoris r4,r4,lo16(0xFFF8) ; (TEST/DEBUG) ! 1465: mr. r4,r4 ; (TEST/DEBUG) ! 1466: beq- dontkillmedead ; (TEST/DEBUG) ! 1467: mfmsr r12 ; (TEST/DEBUG) ! 1468: ori r4,r12,0x2000 ; (TEST/DEBUG) ! 1469: mtmsr r4 ; (TEST/DEBUG) ! 1470: isync ; (TEST/DEBUG) ! 1471: stfd f13,0x980(br0) ; (TEST/DEBUG) ! 1472: mtmsr r12 ; (TEST/DEBUG) ! 1473: isync ; (TEST/DEBUG) ! 1474: lhz r4,0x980(br0) ; (TEST/DEBUG) ! 1475: xoris r4,r4,lo16(0xFFF8) ; (TEST/DEBUG) ! 1476: mr. r4,r4 ; (TEST/DEBUG) ! 1477: bne+ dontkillmedead ; (TEST/DEBUG) ! 1478: BREAKPOINT_TRAP ; (TEST/DEBUG) ! 1479: ! 1480: dontkillmedead: ; (TEST/DEBUG) ! 1481: #endif ! 1482: ! 1483: lis r4,HIGH_ADDR(EXT(MPspec)) /* Get the MP control block */ ! 1484: dcbt 0,r2 /* We'll need the per_proc in a sec */ ! 1485: cmplwi cr0,r11,T_INTERRUPT /* Do we have an external interrupt? */ ! 1486: ori r4,r4,LOW_ADDR(EXT(MPspec)) /* Get the bottom half of the MP control block */ ! 1487: bne+ notracex /* Not an external... */ ! 1488: ! 1489: /* ! 1490: * Here we check to see if there was a interprocessor signal ! 1491: */ ! 1492: ! 1493: lwz r4,MPSSIGPhandler(r4) /* Get the address of the SIGP interrupt filter */ ! 1494: lhz r3,PP_CPU_FLAGS(r2) /* Get the CPU flags */ ! 1495: cmplwi cr1,r4,0 /* Check if signal filter is initialized yet */ ! 1496: andi. r3,r3,LOW_ADDR(SIGPactive) /* See if this processor has started up */ ! 1497: mtlr r4 /* Load up filter address */ ! 1498: beq- cr1,notracex /* We don't have a filter yet... */ ! 1499: beq- notracex /* This processor hasn't started filtering yet... */ ! 1500: ! 1501: blrl /* Filter the interrupt */ ! 1502: ! 1503: mfsprg r2,0 /* Make sure we have the per processor block */ ! 1504: cmplwi cr0,r3,kMPIOInterruptPending /* See what the filter says */ ! 1505: li r11,T_INTERRUPT /* Assume we have a regular external 'rupt */ ! 1506: beq+ modRupt /* Yeah, we figured it would be... */ ! 1507: li r11,T_SIGP /* Assume we had a signal processor interrupt */ ! 1508: bgt+ modRupt /* Yeah, at this point we would assume so... */ ! 1509: li r11,T_IN_VAIN /* Nothing there actually, so eat it */ ! 1510: ! 1511: modRupt: stw r11,PP_SAVE_EXCEPTION_TYPE(r2) /* Set that it was either in vain or a SIGP */ ! 1512: stw r11,saveexception(r13) /* Save the exception code here also */ ! 1513: bne- cr5,notracex /* Jump if no tracing... */ ! 1514: sth r11,LTR_excpt(r20) /* Save the exception type */ ! 1515: ! 1516: notracex: ! 1517: ! 1518: #if 0 ! 1519: bne cr6,nopir6 /* (TEST/DEBUG) */ ! 1520: mfspr r7,pir /* (TEST/DEBUG) */ ! 1521: b gotpir6 /* (TEST/DEBUG) */ ! 1522: nopir6: li r7,0 /* (TEST/DEBUG) */ ! 1523: gotpir6: /* (TEST/DEBUG) */ ! 1524: lis r6,HIGH_ADDR(EXT(RuptCtrs)) /* (TEST/DEBUG) */ ! 1525: rlwinm r7,r7,8,23,23 /* (TEST/DEBUG) */ ! 1526: lis r12,HIGH_ADDR(EXT(GratefulDeb)) /* (TEST/DEBUG) */ ! 1527: rlwimi r7,r7,1,22,22 /* (TEST/DEBUG) */ ! 1528: ori r6,r6,LOW_ADDR(EXT(RuptCtrs)) /* (TEST/DEBUG) */ ! 1529: rlwinm r1,r11,2,0,29 /* (TEST/DEBUG) */ ! 1530: add r6,r6,r7 /* (TEST/DEBUG) */ ! 1531: ori r12,r12,LOW_ADDR(EXT(GratefulDeb)) /* (TEST/DEBUG) */ ! 1532: lwz r21,(47*16)+8(r6) /* (TEST/DEBUG) */ ! 1533: lwz r22,(47*16)+12(r6) /* (TEST/DEBUG) */ ! 1534: add r1,r1,r6 /* (TEST/DEBUG) */ ! 1535: mftb r24 /* (TEST/DEBUG) */ ! 1536: sub r22,r24,r22 /* (TEST/DEBUG) */ ! 1537: lwz r4,4(r6) /* (TEST/DEBUG) */ ! 1538: cmplw cr2,r22,r21 /* (TEST/DEBUG) */ ! 1539: lwz r7,4(r1) /* (TEST/DEBUG) */ ! 1540: lwz r21,8(r6) /* (TEST/DEBUG) */ ! 1541: blt+ cr2,nottime /* (TEST/DEBUG) */ ! 1542: stw r24,(47*16)+12(r6) /* (TEST/DEBUG) */ ! 1543: ! 1544: nottime: addi r4,r4,1 /* (TEST/DEBUG) */ ! 1545: lwz r22,8(r1) /* (TEST/DEBUG) */ ! 1546: addi r7,r7,1 /* (TEST/DEBUG) */ ! 1547: stw r4,4(r6) /* (TEST/DEBUG) */ ! 1548: lwz r3,0(r6) /* (TEST/DEBUG) */ ! 1549: mr. r21,r21 /* (TEST/DEBUG) */ ! 1550: stw r7,4(r1) /* (TEST/DEBUG) */ ! 1551: mtlr r12 /* (TEST/DEBUG) */ ! 1552: lwz r1,0(r1) /* (TEST/DEBUG) */ ! 1553: beq- nottimed1 /* (TEST/DEBUG) */ ! 1554: blt+ cr2,isnttime1 /* (TEST/DEBUG) */ ! 1555: ! 1556: nottimed1: mr. r3,r3 /* (TEST/DEBUG) */ ! 1557: bgelrl+ /* (TEST/DEBUG) */ ! 1558: ! 1559: isnttime1: mr. r22,r22 /* (TEST/DEBUG) */ ! 1560: beq- nottimed2 /* (TEST/DEBUG) */ ! 1561: blt+ cr2,isnttime2 /* (TEST/DEBUG) */ ! 1562: ! 1563: nottimed2: mr. r3,r1 /* (TEST/DEBUG) */ ! 1564: mtlr r12 /* (TEST/DEBUG) */ ! 1565: mr r4,r7 /* (TEST/DEBUG) */ ! 1566: bgelrl+ /* (TEST/DEBUG) */ ! 1567: mr r3,r11 /* (TEST/DEBUG) */ ! 1568: ! 1569: isnttime2: cmplwi r11,T_DATA_ACCESS /* (TEST/DEBUG) */ ! 1570: lis r12,HIGH_ADDR(EXT(GratefulDeb)) /* (TEST/DEBUG) */ ! 1571: bne+ nodsidisp /* (TEST/DEBUG) */ ! 1572: mr. r22,r22 /* (TEST/DEBUG) */ ! 1573: beq- nottimed3 /* (TEST/DEBUG) */ ! 1574: blt+ cr2,nodsidisp /* (TEST/DEBUG) */ ! 1575: ! 1576: nottimed3: li r3,5 /* (TEST/DEBUG) */ ! 1577: ori r12,r12,LOW_ADDR(EXT(GratefulDeb)) /* (TEST/DEBUG) */ ! 1578: lwz r4,savesrr0(r13) /* (TEST/DEBUG) */ ! 1579: mtlr r12 /* (TEST/DEBUG) */ ! 1580: blrl /* (TEST/DEBUG) */ ! 1581: ! 1582: lis r12,HIGH_ADDR(EXT(GratefulDeb)) /* (TEST/DEBUG) */ ! 1583: ori r12,r12,LOW_ADDR(EXT(GratefulDeb)) /* (TEST/DEBUG) */ ! 1584: lis r3,9 /* (TEST/DEBUG) */ ! 1585: ori r3,r3,5 /* (TEST/DEBUG) */ ! 1586: mtlr r12 /* (TEST/DEBUG) */ ! 1587: lwz r4,savedar(r13) /* (TEST/DEBUG) */ ! 1588: blrl /* (TEST/DEBUG) */ ! 1589: ! 1590: nodsidisp: cmplwi r11,T_INSTRUCTION_ACCESS /* (TEST/DEBUG) */ ! 1591: lis r12,HIGH_ADDR(EXT(GratefulDeb)) /* (TEST/DEBUG) */ ! 1592: bne+ noisidisp /* (TEST/DEBUG) */ ! 1593: mr. r22,r22 /* (TEST/DEBUG) */ ! 1594: beq- nottimed4 /* (TEST/DEBUG) */ ! 1595: blt+ cr2,noisidisp /* (TEST/DEBUG) */ ! 1596: ! 1597: nottimed4: li r3,6 /* (TEST/DEBUG) */ ! 1598: ori r12,r12,LOW_ADDR(EXT(GratefulDeb)) /* (TEST/DEBUG) */ ! 1599: lwz r4,savesrr0(r13) /* (TEST/DEBUG) */ ! 1600: mtlr r12 /* (TEST/DEBUG) */ ! 1601: blrl /* (TEST/DEBUG) */ ! 1602: ! 1603: noisidisp: mr r3,r11 /* (TEST/DEBUG) */ ! 1604: #endif ! 1605: ! 1606: #if 0 ! 1607: cmplwi r11,T_PROGRAM /* (TEST/DEBUG) */ ! 1608: lis r12,HIGH_ADDR(EXT(GratefulDeb)) /* (TEST/DEBUG) */ ! 1609: bne+ nopgmdisp /* (TEST/DEBUG) */ ! 1610: li r3,7 /* (TEST/DEBUG) */ ! 1611: ori r12,r12,LOW_ADDR(EXT(GratefulDeb)) /* (TEST/DEBUG) */ ! 1612: lwz r4,savesrr0(r13) /* (TEST/DEBUG) */ ! 1613: mtlr r12 /* (TEST/DEBUG) */ ! 1614: blrl /* (TEST/DEBUG) */ ! 1615: ! 1616: nopgmdisp: mr r3,r11 /* (TEST/DEBUG) */ ! 1617: #endif ! 1618: ! 1619: #if RUPTTRC ! 1620: ! 1621: lis r6,0x7FFF /* (TEST/DEBUG) */ ! 1622: mfdec r7 /* (TEST/DEBUG) */ ! 1623: or r6,r6,r7 /* (TEST/DEBUG) */ ! 1624: mtdec r6 /* (TEST/DEBUG) */ ! 1625: li r6,0x20 /* (TEST/DEBUG) */ ! 1626: ! 1627: lwarx r1,0,r6 ; ? ! 1628: ! 1629: mpwait3: lwarx r1,0,r6 /* (TEST/DEBUG) */ ! 1630: mr. r1,r1 /* (TEST/DEBUG) */ ! 1631: bne- mpwait3 /* (TEST/DEBUG) */ ! 1632: stwcx. r6,0,r6 /* (TEST/DEBUG) */ ! 1633: bne- mpwait3 /* (TEST/DEBUG) */ ! 1634: ! 1635: stw r0,0x280(br0) /* (TEST/DEBUG) */ ! 1636: stmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 1637: bne cr7,nono3 /* (TEST/DEBUG) */ ! 1638: lwz r0,0(br0) /* (TEST/DEBUG) */ ! 1639: mr. r0,r0 /* (TEST/DEBUG) */ ! 1640: beq+ nono3 /* (TEST/DEBUG) */ ! 1641: bne cr6,nopir7 /* (TEST/DEBUG) */ ! 1642: mfspr r4,pir /* (TEST/DEBUG) */ ! 1643: b gotpir7 /* (TEST/DEBUG) */ ! 1644: nopir7: li r4,0 /* (TEST/DEBUG) */ ! 1645: gotpir7: /* (TEST/DEBUG) */ ! 1646: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 1647: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 1648: li r3,0 /* (TEST/DEBUG) */ ! 1649: mr r5,r11 /* (TEST/DEBUG) */ ! 1650: oris r4,r4,0x3030 /* (TEST/DEBUG) */ ! 1651: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 1652: ori r4,r4,0x3330 /* (TEST/DEBUG) */ ! 1653: mtlr r31 /* (TEST/DEBUG) */ ! 1654: blrl /* (TEST/DEBUG) */ ! 1655: ! 1656: bne cr6,nopir8 /* (TEST/DEBUG) */ ! 1657: mfspr r4,pir /* (TEST/DEBUG) */ ! 1658: b gotpir8 /* (TEST/DEBUG) */ ! 1659: nopir8: li r4,0 /* (TEST/DEBUG) */ ! 1660: gotpir8: /* (TEST/DEBUG) */ ! 1661: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 1662: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 1663: li r3,0 /* (TEST/DEBUG) */ ! 1664: lwz r5,0x280(br0) /* (TEST/DEBUG) */ ! 1665: oris r4,r4,0x3030 /* (TEST/DEBUG) */ ! 1666: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 1667: ori r4,r4,0x3430 /* (TEST/DEBUG) */ ! 1668: mtlr r31 /* (TEST/DEBUG) */ ! 1669: blrl /* (TEST/DEBUG) */ ! 1670: nono3: ! 1671: lmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 1672: lwz r0,0x280(br0) /* (TEST/DEBUG) */ ! 1673: li r6,0 /* (TEST/DEBUG) */ ! 1674: stw r6,0x20(br0) /* (TEST/DEBUG) */ ! 1675: mtdec r7 /* (TEST/DEBUG) */ ! 1676: ! 1677: #endif ! 1678: ! 1679: li r21,0 ; Assume no processor register for now ! 1680: lis r12,hi16(EXT(hw_counts)) ; Get the high part of the interrupt counters ! 1681: bne- cr6,nopirhere ; Jump if this processor does not have a PIR... ! 1682: mfspr r21,pir ; Get the PIR ! 1683: ! 1684: nopirhere: ori r12,r12,lo16(EXT(hw_counts)) ; Get the low part of the interrupt counters ! 1685: rlwinm r21,r21,8,20,23 ; Get index to processor counts ! 1686: mtcrf 0x80,r0 /* Set our CR0 to the high nybble of the request code */ ! 1687: rlwinm r6,r0,1,0,31 /* Move sign bit to the end */ ! 1688: cmplwi cr1,r11,T_SYSTEM_CALL /* Did we get a system call? */ ! 1689: crandc cr0_lt,cr0_lt,cr0_gt /* See if we have R0 equal to 0b10xx...x */ ! 1690: add r12,r12,r21 ; Point to the processor count area ! 1691: cmplwi cr3,r11,T_IN_VAIN /* Was this all in vain? All for nothing? */ ! 1692: lwzx r22,r12,r11 ; Get the old value ! 1693: cmplwi cr2,r6,1 /* See if original R0 had the CutTrace request code in it */ ! 1694: addi r22,r22,1 ; Count this one ! 1695: cmplwi cr4,r11,T_SIGP /* Indicate if we had a SIGP 'rupt */ ! 1696: stwx r22,r12,r11 ; Store it back ! 1697: ! 1698: beq- cr3,EatRupt /* Interrupt was all for nothing... */ ! 1699: cmplwi cr3,r11,T_MACHINE_CHECK ; Did we get a machine check? ! 1700: bne+ cr1,noCutT /* Not a system call... */ ! 1701: bnl+ cr0,noCutT /* R0 not 0b10xxx...x, can't be any kind of magical system call... */ ! 1702: beq- cr2,isCutTrace /* This is a CutTrace system call */ ! 1703: ! 1704: /* ! 1705: * Here's where we call the firmware. If it returns T_IN_VAIN, that means ! 1706: * that it has handled the interruption. Remember: thou shalt not trash R13 ! 1707: * or R20 while you are away. Anything else is ok. ! 1708: */ ! 1709: ! 1710: ! 1711: lis r1,HIGH_ADDR(EXT(FirmwareCall)) /* Top half of firmware call handler */ ! 1712: ori r1,r1,LOW_ADDR(EXT(FirmwareCall)) /* Bottom half of it */ ! 1713: lwz r3,saver3(r13) /* Restore the first parameter, the rest are ok already */ ! 1714: mtlr r1 /* Get it in the link register */ ! 1715: blrl /* Call the handler */ ! 1716: ! 1717: #if RUPTTRC ! 1718: lis r7,0x7FFF /* (TEST/DEBUG) */ ! 1719: mfdec r6 /* (TEST/DEBUG) */ ! 1720: or r7,r7,r6 /* (TEST/DEBUG) */ ! 1721: mtdec r7 /* (TEST/DEBUG) */ ! 1722: li r7,0x20 /* (TEST/DEBUG) */ ! 1723: ! 1724: lwarx r1,0,r7 ; ? ! 1725: ! 1726: mpwait4: lwarx r1,0,r7 /* (TEST/DEBUG) */ ! 1727: mr. r1,r1 /* (TEST/DEBUG) */ ! 1728: bne- mpwait4 /* (TEST/DEBUG) */ ! 1729: stwcx. r7,0,r7 /* (TEST/DEBUG) */ ! 1730: bne- mpwait4 /* (TEST/DEBUG) */ ! 1731: ! 1732: stw r0,0x280(br0) /* (TEST/DEBUG) */ ! 1733: stmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 1734: bne cr7,nono4 /* (TEST/DEBUG) */ ! 1735: lwz r0,0(br0) /* (TEST/DEBUG) */ ! 1736: mr. r0,r0 /* (TEST/DEBUG) */ ! 1737: beq+ nono4 /* (TEST/DEBUG) */ ! 1738: ! 1739: bne cr6,nopir9 /* (TEST/DEBUG) */ ! 1740: mfspr r4,pir /* (TEST/DEBUG) */ ! 1741: b gotpir9 /* (TEST/DEBUG) */ ! 1742: nopir9: li r4,0 /* (TEST/DEBUG) */ ! 1743: gotpir9: /* (TEST/DEBUG) */ ! 1744: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 1745: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 1746: mr r5,r3 /* (TEST/DEBUG) */ ! 1747: li r3,0 /* (TEST/DEBUG) */ ! 1748: oris r4,r4,0x3030 /* (TEST/DEBUG) */ ! 1749: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 1750: ori r4,r4,0x3530 /* (TEST/DEBUG) */ ! 1751: mtlr r31 /* (TEST/DEBUG) */ ! 1752: blrl /* (TEST/DEBUG) */ ! 1753: mtdec r25 /* (TEST/DEBUG) */ ! 1754: nono4: ! 1755: lmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 1756: lwz r0,0x280(br0) /* (TEST/DEBUG) */ ! 1757: li r7,0 /* (TEST/DEBUG) */ ! 1758: stw r7,0x20(br0) /* (TEST/DEBUG) */ ! 1759: mtdec r6 /* (TEST/DEBUG) */ ! 1760: #endif ! 1761: ! 1762: cmplwi r3,T_IN_VAIN /* Was it handled? */ ! 1763: mfsprg r2,0 /* Restore the per_processor area */ ! 1764: beq+ EatRupt /* Interrupt was handled... */ ! 1765: mr r11,r3 /* Put the 'rupt code in the right register */ ! 1766: b noSIGP /* Go to the normal system call handler */ ! 1767: ! 1768: isCutTrace: ! 1769: li r7,-32768 /* Get a 0x8000 for the exception code */ ! 1770: bne- cr5,EatRupt /* Tracing is disabled... */ ! 1771: sth r7,LTR_excpt(r20) /* Modify the exception type to a CutTrace */ ! 1772: b EatRupt /* Time to go home... */ ! 1773: ! 1774: /* We are here 'cause we didn't have a CutTrace system call */ ! 1775: ! 1776: noCutT: beq- cr3,MachineCheck ; Whoa... Machine check... ! 1777: bne+ cr4,noSIGP /* Skip away if we didn't get a SIGP... */ ! 1778: ! 1779: lis r6,HIGH_ADDR(EXT(MPsignalFW)) /* Top half of SIGP handler */ ! 1780: ori r6,r6,LOW_ADDR(EXT(MPsignalFW)) /* Bottom half of it */ ! 1781: mtlr r6 /* Get it in the link register */ ! 1782: ! 1783: blrl /* Call the handler - we'll only come back if this is an AST, */ ! 1784: /* 'cause FW can't handle that */ ! 1785: mfsprg r2,0 /* Restore the per_processor area */ ! 1786: ; ! 1787: ; The following interrupts are the only ones that can be redriven ! 1788: ; by the higher level code or emulation routines. ! 1789: ; ! 1790: ! 1791: Redrive: cmplwi cr0,r3,T_IN_VAIN /* Did the signal handler eat the signal? */ ! 1792: mr r11,r3 /* Move it to the right place */ ! 1793: beq+ cr0,EatRupt /* Bail now if the signal handler processed the signal... */ ! 1794: ! 1795: ! 1796: /* ! 1797: * Here's where we check for the other fast-path exceptions: translation exceptions, ! 1798: * emulated instructions, etc. ! 1799: */ ! 1800: ! 1801: noSIGP: cmplwi cr3,r11,T_ALTIVEC_ASSIST ; Check for an Altivec denorm assist ! 1802: cmplwi cr1,r11,T_PROGRAM /* See if we got a program exception */ ! 1803: cmplwi cr2,r11,T_INSTRUCTION_ACCESS /* Check on an ISI */ ! 1804: bne+ cr3,noAltivecAssist ; It is not an assist... ! 1805: b EXT(AltivecAssist) ; It is an assist... ! 1806: ! 1807: noAltivecAssist: ! 1808: bne+ cr1,noEmulate ; No emulation here... ! 1809: b EXT(Emulate) ; Go try to emulate... ! 1810: ! 1811: noEmulate: cmplwi cr3,r11,T_CSWITCH /* Are we context switching */ ! 1812: cmplwi r11,T_DATA_ACCESS /* Check on a DSI */ ! 1813: beq- cr2,DSIorISI /* It's a PTE fault... */ ! 1814: beq- cr3,conswtch /* It's a context switch... */ ! 1815: bne+ PassUp /* It's not a PTE fault... */ ! 1816: ! 1817: /* ! 1818: * This call will either handle the fault, in which case it will not ! 1819: * return, or return to pass the fault up the line. ! 1820: */ ! 1821: ! 1822: DSIorISI: ! 1823: lis r7,HIGH_ADDR(EXT(handlePF)) /* Top half of DSI handler */ ! 1824: ori r7,r7,LOW_ADDR(EXT(handlePF)) /* Bottom half of it */ ! 1825: mtlr r7 /* Get it in the link register */ ! 1826: mr r3,r11 /* Move the 'rupt code */ ! 1827: ! 1828: blrl /* See if we can handle this fault */ ! 1829: ! 1830: #if RUPTTRC ! 1831: bne cr7,nononono2 /* (TEST/DEBUG) */ ! 1832: lwz r7,0(br0) /* (TEST/DEBUG) */ ! 1833: mr. r7,r7 /* (TEST/DEBUG) */ ! 1834: beq+ nononono2 /* (TEST/DEBUG) */ ! 1835: #if 0 ! 1836: lis r7,0x7FFF /* (TEST/DEBUG) */ ! 1837: mfdec r2 /* (TEST/DEBUG) */ ! 1838: or r7,r7,r2 /* (TEST/DEBUG) */ ! 1839: mtdec r7 /* (TEST/DEBUG) */ ! 1840: li r7,0x20 /* (TEST/DEBUG) */ ! 1841: ! 1842: lwarx r0,0,r7 ; ? ! 1843: ! 1844: yesyesyes2: lwarx r0,0,r7 /* (TEST/DEBUG) */ ! 1845: mr. r0,r0 /* (TEST/DEBUG) */ ! 1846: li r0,1 /* (TEST/DEBUG) */ ! 1847: bne- yesyesyes2 /* (TEST/DEBUG) */ ! 1848: stwcx. r0,0,r7 /* (TEST/DEBUG) */ ! 1849: bne- yesyesyes2 /* (TEST/DEBUG) */ ! 1850: #endif ! 1851: stw r0,0x280(br0) /* (TEST/DEBUG) */ ! 1852: stmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 1853: mr r20,r3 ! 1854: bne cr6,nopir10 /* (TEST/DEBUG) */ ! 1855: mfspr r4,pir /* (TEST/DEBUG) */ ! 1856: b gotpir10 /* (TEST/DEBUG) */ ! 1857: nopir10: li r4,0 /* (TEST/DEBUG) */ ! 1858: gotpir10: /* (TEST/DEBUG) */ ! 1859: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 1860: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 1861: li r3,0 /* (TEST/DEBUG) */ ! 1862: or r4,r4,r20 /* (TEST/DEBUG) */ ! 1863: lwz r5,savedar(r13) /* (TEST/DEBUG) */ ! 1864: oris r4,r4,0x3030 /* (TEST/DEBUG) */ ! 1865: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 1866: ori r4,r4,0x3630 /* (TEST/DEBUG) */ ! 1867: mtlr r31 /* (TEST/DEBUG) */ ! 1868: blrl /* (TEST/DEBUG) */ ! 1869: ! 1870: #if 0 ! 1871: lis r31,HIGH_ADDR(EXT(dbgRegs)) /* (TEST/DEBUG) */ ! 1872: ori r31,r31,LOW_ADDR(EXT(dbgRegs)) /* (TEST/DEBUG) */ ! 1873: mtlr r31 /* (TEST/DEBUG) */ ! 1874: li r3,0 /* (TEST/DEBUG) */ ! 1875: blrl /* (TEST/DEBUG) */ ! 1876: #endif ! 1877: lmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 1878: lwz r0,0x280(br0) /* (TEST/DEBUG) */ ! 1879: li r0,0 /* (TEST/DEBUG) */ ! 1880: stw r0,0x20(br0) /* (TEST/DEBUG) */ ! 1881: mtdec r2 /* (TEST/DEBUG) */ ! 1882: nononono2: /* (TEST/DEBUG) */ ! 1883: #endif ! 1884: ! 1885: lwz r0,savesrr1(r13) ; Get the MSR in use at exception time ! 1886: mfsprg r2, 0 /* Get back per_proc */ ! 1887: cmplwi cr1,r3,T_IN_VAIN ; Was it handled? ! 1888: andi. r4,r0,lo16(MASK(MSR_RI)) ; See if the recover bit is on ! 1889: mr r11,r3 /* Make sure we can find this later */ ! 1890: beq+ cr1,EatRupt ; Yeah, just blast back to the user... ! 1891: andc r0,r0,r4 ; Remove the recover bit ! 1892: beq+ PassUp ; Not on, normal case... ! 1893: lwz r4,savesrr0(r13) ; Get the failing instruction address ! 1894: lwz r5,savecr(r13) ; Get the condition register ! 1895: stw r0,savesrr1(r13) ; Save the result MSR ! 1896: addi r4,r4,4 ; Skip failing instruction ! 1897: rlwinm r5,r5,0,3,1 ; Clear CR0_EQ to let emulation code know we failed ! 1898: stw r4,savesrr0(r13) ; Save instruction address ! 1899: stw r4,savecr(r13) ; And the resume CR ! 1900: b EatRupt ; Resume emulated code ! 1901: ! 1902: /* ! 1903: * Here is where we handle the context switch firmware call. The old ! 1904: * context has been saved, and the new savearea in in saver3. We'll just ! 1905: * muck around with the savearea pointers, and then join the exit routine ! 1906: */ ! 1907: conswtch: lwz r28,SAVflags(r13) /* The the flags of the current */ ! 1908: mr r29,r13 /* Save the save */ ! 1909: rlwinm r30,r13,0,0,19 /* Get the start of the savearea block */ ! 1910: lwz r5,saver3(r13) /* Switch to the new savearea */ ! 1911: oris r28,r28,HIGH_ADDR(SAVattach) /* Turn on the attached flag */ ! 1912: lwz r30,SACvrswap(r30) /* get real to virtual translation */ ! 1913: mr r13,r5 /* Switch saveareas */ ! 1914: xor r27,r29,r30 /* Flip to virtual */ ! 1915: stw r28,SAVflags(r29) /* Stash it back */ ! 1916: stw r27,saver3(r5) /* Push the new savearea to the switch to routine */ ! 1917: b EatRupt /* Start 'er up... */ ! 1918: ! 1919: ; ! 1920: ; Handle machine check here. ! 1921: ; ! 1922: ; ? ! 1923: ; ! 1924: MachineCheck: ! 1925: lwz r27,savesrr1(r13) ; ? ! 1926: rlwinm. r11,r27,0,dcmck,dcmck ; ? ! 1927: beq+ notDCache ; ? ! 1928: ! 1929: mfspr r11,msscr0 ; ? ! 1930: dssall ; ? ! 1931: sync ! 1932: ! 1933: lwz r27,savesrr1(r13) ; ? ! 1934: ! 1935: hiccup: cmplw r27,r27 ; ? ! 1936: bne- hiccup ; ? ! 1937: isync ; ? ! 1938: ! 1939: oris r11,r11,hi16(dl1hwfm) ; ? ! 1940: mtspr msscr0,r11 ; ? ! 1941: ! 1942: rstbsy: mfspr r11,msscr0 ; ? ! 1943: ! 1944: rlwinm. r11,r11,0,dl1hwf,dl1hwf ; ? ! 1945: bne rstbsy ; ? ! 1946: ! 1947: sync ; ? ! 1948: ! 1949: li r11,T_IN_VAIN ; ? ! 1950: b EatRupt ; ? ! 1951: ! 1952: ! 1953: notDCache: ! 1954: ; ! 1955: ; Check if the failure was in ! 1956: ; ml_probe_read. If so, this is expected, so modify the PC to ! 1957: ; ml_proble_read_mck and then eat the exception. ! 1958: ; ! 1959: lwz r30,savesrr0(r13) ; Get the failing PC ! 1960: lis r28,hi16(EXT(ml_probe_read_mck)) ; High order part ! 1961: lis r27,hi16(EXT(ml_probe_read)) ; High order part ! 1962: ori r28,r28,lo16(EXT(ml_probe_read_mck)) ; Get the low part ! 1963: ori r27,r27,lo16(EXT(ml_probe_read)) ; Get the low part ! 1964: cmplw r30,r28 ; Check highest possible ! 1965: cmplw cr1,r30,r27 ; Check lowest ! 1966: bge- PassUp ; Outside of range ! 1967: blt- cr1,PassUp ; Outside of range ! 1968: ; ! 1969: ; We need to fix up the BATs here because the probe ! 1970: ; routine messed them all up... As long as we are at it, ! 1971: ; fix up to return directly to caller of probe. ! 1972: ; ! 1973: ! 1974: lwz r30,saver5(r13) ; Get proper DBAT values ! 1975: lwz r28,saver6(r13) ! 1976: lwz r27,saver7(r13) ! 1977: lwz r11,saver8(r13) ! 1978: lwz r18,saver9(r13) ! 1979: ! 1980: sync ! 1981: mtdbatu 0,r30 ; Restore DBAT 0 high ! 1982: mtdbatl 0,r28 ; Restore DBAT 0 low ! 1983: mtdbatu 1,r27 ; Restore DBAT 1 high ! 1984: mtdbatu 2,r11 ; Restore DBAT 2 high ! 1985: mtdbatu 3,r18 ; Restore DBAT 3 high ! 1986: sync ! 1987: ! 1988: lwz r28,savelr(r13) ; Get return point ! 1989: lwz r27,saver0(r13) ; Get the saved MSR ! 1990: li r30,0 ; Get a failure RC ! 1991: stw r28,savesrr0(r13) ; Set the return point ! 1992: stw r27,savesrr1(r13) ; Set the continued MSR ! 1993: stw r30,saver3(r13) ; Set return code ! 1994: li r11,T_IN_VAIN ; Set new interrupt code ! 1995: b EatRupt ; Yum, yum, eat it all up... ! 1996: ! 1997: /* ! 1998: * Here's where we come back from some instruction emulator. If we come back with ! 1999: * T_IN_VAIN, the emulation is done and we should just reload state and directly ! 2000: * go back to the interrupted code. Otherwise, we'll check to see if ! 2001: * we need to redrive with a different interrupt, i.e., DSI. ! 2002: */ ! 2003: ! 2004: .align 5 ! 2005: .globl EXT(EmulExit) ! 2006: ! 2007: LEXT(EmulExit) ! 2008: ! 2009: cmplwi r11,T_IN_VAIN /* Was it emulated? */ ! 2010: lis r1,hi16(SAVredrive) ; Get redrive request ! 2011: mfsprg r2,0 ; Restore the per_proc area ! 2012: beq+ EatRupt /* Yeah, just blast back to the user... */ ! 2013: lwz r4,SAVflags(r13) ; Pick up the flags ! 2014: ! 2015: and. r0,r4,r1 ; Check if redrive requested ! 2016: andc r4,r4,r1 ; Clear redrive ! 2017: ! 2018: beq+ PassUp ; No redrive, just keep on going... ! 2019: ! 2020: lwz r3,saveexception(r13) ; Restore exception code ! 2021: stw r4,SAVflags(r13) ; Set the flags ! 2022: b Redrive ; Redrive the exception... ! 2023: ! 2024: /* Jump into main handler code switching on VM at the same time */ ! 2025: ! 2026: /* We assume kernel data is mapped contiguously in physical ! 2027: * memory, otherwise we'd need to switch on (at least) virtual data. ! 2028: * SRs are already set up. ! 2029: */ ! 2030: PassUp: lwz r2,PP_PHYS_EXCEPTION_HANDLERS(r2) /* Pick up the exception handler base */ ! 2031: lwzx r6,r2,r11 /* Get the actual exception handler address */ ! 2032: ! 2033: PassUpDeb: lwz r8,SAVflags(r13) /* Get the flags */ ! 2034: mtsrr0 r6 /* Set up the handler address */ ! 2035: oris r8,r8,HIGH_ADDR(SAVattach) /* Since we're passing it up, attach it */ ! 2036: rlwinm r5,r13,0,0,19 /* Back off to the start of savearea block */ ! 2037: ! 2038: mfmsr r3 /* Get our MSR */ ! 2039: stw r8,SAVflags(r13) /* Pass up the flags */ ! 2040: rlwinm r3,r3,0,MSR_BE_BIT+1,MSR_SE_BIT-1 /* Clear all but the trace bits */ ! 2041: li r2,MSR_SUPERVISOR_INT_OFF /* Get our normal MSR value */ ! 2042: lwz r5,SACvrswap(r5) /* Get real to virtual conversion */ ! 2043: or r2,r2,r3 /* Keep the trace bits if they're on */ ! 2044: mr r3,r11 /* Pass the exception code in the paramter reg */ ! 2045: mtsrr1 r2 /* Set up our normal MSR value */ ! 2046: xor r4,r13,r5 /* Pass up the virtual address of context savearea */ ! 2047: ! 2048: #if RUPTTRC ! 2049: lis r20,0x7FFF /* (TEST/DEBUG) */ ! 2050: mfdec r25 /* (TEST/DEBUG) */ ! 2051: or r20,r20,r25 /* (TEST/DEBUG) */ ! 2052: mtdec r20 /* (TEST/DEBUG) */ ! 2053: li r20,0x20 /* (TEST/DEBUG) */ ! 2054: ! 2055: lwarx r21,0,r20 ; ? ! 2056: ! 2057: mpwait5: lwarx r21,0,r20 /* (TEST/DEBUG) */ ! 2058: mr. r21,r21 /* (TEST/DEBUG) */ ! 2059: bne- mpwait5 /* (TEST/DEBUG) */ ! 2060: stwcx. r20,0,r20 /* (TEST/DEBUG) */ ! 2061: bne- mpwait5 /* (TEST/DEBUG) */ ! 2062: ! 2063: stw r0,0x280(br0) /* (TEST/DEBUG) */ ! 2064: stmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 2065: bne cr7,nono9 /* (TEST/DEBUG) */ ! 2066: lwz r0,0(br0) /* (TEST/DEBUG) */ ! 2067: mr. r0,r0 /* (TEST/DEBUG) */ ! 2068: beq+ nono9 /* (TEST/DEBUG) */ ! 2069: mr r30,r4 /* (TEST/DEBUG) */ ! 2070: mr r24,r5 /* (TEST/DEBUG) */ ! 2071: ! 2072: bne cr6,nopir11 /* (TEST/DEBUG) */ ! 2073: mfspr r4,pir /* (TEST/DEBUG) */ ! 2074: b gotpir11 /* (TEST/DEBUG) */ ! 2075: nopir11: li r4,0 /* (TEST/DEBUG) */ ! 2076: gotpir11: /* (TEST/DEBUG) */ ! 2077: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2078: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 2079: li r3,0 /* (TEST/DEBUG) */ ! 2080: mr r5,r6 /* (TEST/DEBUG) */ ! 2081: oris r4,r4,0x3030 /* (TEST/DEBUG) */ ! 2082: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2083: ori r4,r4,0x3930 /* (TEST/DEBUG) */ ! 2084: mtlr r31 /* (TEST/DEBUG) */ ! 2085: blrl /* (TEST/DEBUG) */ ! 2086: ! 2087: bne cr6,nopir12 /* (TEST/DEBUG) */ ! 2088: mfspr r4,pir /* (TEST/DEBUG) */ ! 2089: b gotpir12 /* (TEST/DEBUG) */ ! 2090: nopir12: li r4,0 /* (TEST/DEBUG) */ ! 2091: gotpir12: /* (TEST/DEBUG) */ ! 2092: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2093: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 2094: li r3,0 /* (TEST/DEBUG) */ ! 2095: mr r5,r30 /* (TEST/DEBUG) */ ! 2096: oris r4,r4,0x3031 /* (TEST/DEBUG) */ ! 2097: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2098: ori r4,r4,0x3130 /* (TEST/DEBUG) */ ! 2099: mtlr r31 /* (TEST/DEBUG) */ ! 2100: blrl /* (TEST/DEBUG) */ ! 2101: ! 2102: bne cr6,nopir13 /* (TEST/DEBUG) */ ! 2103: mfspr r4,pir /* (TEST/DEBUG) */ ! 2104: b gotpir13 /* (TEST/DEBUG) */ ! 2105: nopir13: li r4,0 /* (TEST/DEBUG) */ ! 2106: gotpir13: /* (TEST/DEBUG) */ ! 2107: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2108: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 2109: li r3,0 /* (TEST/DEBUG) */ ! 2110: xor r5,r30,r24 /* (TEST/DEBUG) */ ! 2111: oris r4,r4,0x3031 /* (TEST/DEBUG) */ ! 2112: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2113: ori r4,r4,0x3131 /* (TEST/DEBUG) */ ! 2114: mtlr r31 /* (TEST/DEBUG) */ ! 2115: blrl /* (TEST/DEBUG) */ ! 2116: ! 2117: bne cr6,nopir14 /* (TEST/DEBUG) */ ! 2118: mfspr r4,pir /* (TEST/DEBUG) */ ! 2119: b gotpir14 /* (TEST/DEBUG) */ ! 2120: nopir14: li r4,0 /* (TEST/DEBUG) */ ! 2121: gotpir14: /* (TEST/DEBUG) */ ! 2122: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2123: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 2124: li r3,0 /* (TEST/DEBUG) */ ! 2125: mr r5,r25 /* (TEST/DEBUG) */ ! 2126: oris r4,r4,0x3031 /* (TEST/DEBUG) */ ! 2127: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2128: ori r4,r4,0x3132 /* (TEST/DEBUG) */ ! 2129: mtlr r31 /* (TEST/DEBUG) */ ! 2130: blrl /* (TEST/DEBUG) */ ! 2131: ! 2132: bne cr6,nopir15 /* (TEST/DEBUG) */ ! 2133: mfspr r4,pir /* (TEST/DEBUG) */ ! 2134: b gotpir15 /* (TEST/DEBUG) */ ! 2135: nopir15: li r4,0 /* (TEST/DEBUG) */ ! 2136: gotpir15: /* (TEST/DEBUG) */ ! 2137: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2138: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 2139: li r3,0 /* (TEST/DEBUG) */ ! 2140: mfsrr0 r5 /* (TEST/DEBUG) */ ! 2141: oris r4,r4,0x3031 /* (TEST/DEBUG) */ ! 2142: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2143: ori r4,r4,0x3133 /* (TEST/DEBUG) */ ! 2144: mtlr r31 /* (TEST/DEBUG) */ ! 2145: blrl /* (TEST/DEBUG) */ ! 2146: nono9: ! 2147: lmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 2148: lwz r0,0x280(br0) /* (TEST/DEBUG) */ ! 2149: li r20,0 /* (TEST/DEBUG) */ ! 2150: stw r20,0x20(br0) /* (TEST/DEBUG) */ ! 2151: mtdec r25 /* (TEST/DEBUG) */ ! 2152: #endif ! 2153: ! 2154: rfi /* Launch the exception handler */ ! 2155: ! 2156: .long 0 /* Leave these here gol durn it! */ ! 2157: .long 0 ! 2158: .long 0 ! 2159: .long 0 ! 2160: .long 0 ! 2161: .long 0 ! 2162: .long 0 ! 2163: .long 0 ! 2164: ! 2165: /* ! 2166: * This routine is the only place where we return from an interruption. ! 2167: * Anyplace else is wrong. Even if I write the code, it's still wrong ! 2168: * Feel free to come by and slap me if I do do it. Even though I may ! 2169: * have had a good reason to do it. ! 2170: * ! 2171: * All we need to remember here is that R13 must point to the savearea ! 2172: * that has the context we need to load up. Translation and interruptions ! 2173: * must be disabled. ! 2174: * ! 2175: * This code always loads the context in the savearea pointed to ! 2176: * by R13. In the process, it throws away the savearea. If there ! 2177: * is any tomfoolery with savearea stacks, it must be taken care of ! 2178: * before we get here. ! 2179: */ ! 2180: ! 2181: EatRupt: mr r31,r13 /* Move the savearea pointer to the far end of the register set */ ! 2182: ! 2183: EatRupt2: mfsprg r2,0 /* Get the per_proc block */ ! 2184: ! 2185: /* ! 2186: * First we see if we are able to free the new savearea. ! 2187: * If it is not attached to anything, put it on the free list. ! 2188: * This is real dangerous, we haven't restored context yet... ! 2189: * So, the free savearea chain lock must stay until the bitter end! ! 2190: */ ! 2191: ! 2192: #if RUPTTRC ! 2193: lis r18,0x7FFF /* (TEST/DEBUG) */ ! 2194: mfdec r25 /* (TEST/DEBUG) */ ! 2195: or r18,r18,r25 /* (TEST/DEBUG) */ ! 2196: mtdec r18 /* (TEST/DEBUG) */ ! 2197: li r18,0x20 /* (TEST/DEBUG) */ ! 2198: ! 2199: lwarx r19,0,r18 ; ? ! 2200: ! 2201: mpwait6: lwarx r19,0,r18 /* (TEST/DEBUG) */ ! 2202: mr. r19,r19 /* (TEST/DEBUG) */ ! 2203: bne- mpwait6 /* (TEST/DEBUG) */ ! 2204: stwcx. r18,0,r18 /* (TEST/DEBUG) */ ! 2205: bne- mpwait6 /* (TEST/DEBUG) */ ! 2206: ! 2207: stw r0,0x280(br0) /* (TEST/DEBUG) */ ! 2208: stmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 2209: bne cr7,nono5 /* (TEST/DEBUG) */ ! 2210: lwz r0,0(br0) /* (TEST/DEBUG) */ ! 2211: mr. r0,r0 /* (TEST/DEBUG) */ ! 2212: beq+ nono5 /* (TEST/DEBUG) */ ! 2213: ! 2214: bne cr6,nopir16 /* (TEST/DEBUG) */ ! 2215: mfspr r4,pir /* (TEST/DEBUG) */ ! 2216: b gotpir16 /* (TEST/DEBUG) */ ! 2217: nopir16: li r4,0 /* (TEST/DEBUG) */ ! 2218: gotpir16: /* (TEST/DEBUG) */ ! 2219: rlwinm r24,r31,0,0,19 /* (TEST/DEBUG) */ ! 2220: mr r5,r31 /* (TEST/DEBUG) */ ! 2221: mr r30,r31 /* (TEST/DEBUG) */ ! 2222: lwz r24,SACvrswap(r24) /* (TEST/DEBUG) */ ! 2223: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2224: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 2225: li r3,0 /* (TEST/DEBUG) */ ! 2226: oris r4,r4,0x3030 /* (TEST/DEBUG) */ ! 2227: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2228: ori r4,r4,0x3730 /* (TEST/DEBUG) */ ! 2229: mtlr r31 /* (TEST/DEBUG) */ ! 2230: blrl /* (TEST/DEBUG) */ ! 2231: ! 2232: ! 2233: bne cr6,nopir17 /* (TEST/DEBUG) */ ! 2234: mfspr r4,pir /* (TEST/DEBUG) */ ! 2235: b gotpir17 /* (TEST/DEBUG) */ ! 2236: nopir17: li r4,0 /* (TEST/DEBUG) */ ! 2237: gotpir17: /* (TEST/DEBUG) */ ! 2238: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2239: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 2240: li r3,0 /* (TEST/DEBUG) */ ! 2241: xor r5,r30,r24 /* (TEST/DEBUG) */ ! 2242: oris r4,r4,0x3030 /* (TEST/DEBUG) */ ! 2243: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2244: ori r4,r4,0x3731 /* (TEST/DEBUG) */ ! 2245: mtlr r31 /* (TEST/DEBUG) */ ! 2246: blrl /* (TEST/DEBUG) */ ! 2247: ! 2248: bne cr6,nopir18 /* (TEST/DEBUG) */ ! 2249: mfspr r4,pir /* (TEST/DEBUG) */ ! 2250: b gotpir18 /* (TEST/DEBUG) */ ! 2251: nopir18: li r4,0 /* (TEST/DEBUG) */ ! 2252: gotpir18: /* (TEST/DEBUG) */ ! 2253: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2254: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 2255: li r3,0 /* (TEST/DEBUG) */ ! 2256: mfsprg r5,1 /* (TEST/DEBUG) */ ! 2257: oris r4,r4,0x3030 /* (TEST/DEBUG) */ ! 2258: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2259: ori r4,r4,0x3830 /* (TEST/DEBUG) */ ! 2260: mtlr r31 /* (TEST/DEBUG) */ ! 2261: blrl /* (TEST/DEBUG) */ ! 2262: ! 2263: bne cr6,nopir19 /* (TEST/DEBUG) */ ! 2264: mfspr r4,pir /* (TEST/DEBUG) */ ! 2265: b gotpir19 /* (TEST/DEBUG) */ ! 2266: nopir19: li r4,0 /* (TEST/DEBUG) */ ! 2267: gotpir19: /* (TEST/DEBUG) */ ! 2268: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2269: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 2270: li r3,0 /* (TEST/DEBUG) */ ! 2271: lwz r5,savesrr0(r30) /* (TEST/DEBUG) */ ! 2272: oris r4,r4,0x3031 /* (TEST/DEBUG) */ ! 2273: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2274: ori r4,r4,0x3130 /* (TEST/DEBUG) */ ! 2275: mtlr r31 /* (TEST/DEBUG) */ ! 2276: blrl /* (TEST/DEBUG) */ ! 2277: ! 2278: bne cr6,nopir20 /* (TEST/DEBUG) */ ! 2279: mfspr r4,pir /* (TEST/DEBUG) */ ! 2280: b gotpir20 /* (TEST/DEBUG) */ ! 2281: nopir20: li r4,0 /* (TEST/DEBUG) */ ! 2282: gotpir20: /* (TEST/DEBUG) */ ! 2283: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2284: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 2285: li r3,0 /* (TEST/DEBUG) */ ! 2286: lwz r5,savesrr1(r30) /* (TEST/DEBUG) */ ! 2287: oris r4,r4,0x3031 /* (TEST/DEBUG) */ ! 2288: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2289: ori r4,r4,0x3131 /* (TEST/DEBUG) */ ! 2290: mtlr r31 /* (TEST/DEBUG) */ ! 2291: blrl /* (TEST/DEBUG) */ ! 2292: ! 2293: bne cr6,nopir21 /* (TEST/DEBUG) */ ! 2294: mfspr r4,pir /* (TEST/DEBUG) */ ! 2295: b gotpir21 /* (TEST/DEBUG) */ ! 2296: nopir21: li r4,0 /* (TEST/DEBUG) */ ! 2297: gotpir21: /* (TEST/DEBUG) */ ! 2298: lis r31,HIGH_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2299: rlwinm r4,r4,24,4,7 /* (TEST/DEBUG) */ ! 2300: li r3,0 /* (TEST/DEBUG) */ ! 2301: lwz r5,savelr(r30) /* (TEST/DEBUG) */ ! 2302: oris r4,r4,0x3031 /* (TEST/DEBUG) */ ! 2303: ori r31,r31,LOW_ADDR(EXT(dbgDispLL)) /* (TEST/DEBUG) */ ! 2304: ori r4,r4,0x3132 /* (TEST/DEBUG) */ ! 2305: mtlr r31 /* (TEST/DEBUG) */ ! 2306: blrl /* (TEST/DEBUG) */ ! 2307: nono5: ! 2308: lmw r1,0x284(br0) /* (TEST/DEBUG) */ ! 2309: lwz r0,0x280(br0) /* (TEST/DEBUG) */ ! 2310: li r19,0 /* (TEST/DEBUG) */ ! 2311: stw r19,0x20(br0) /* (TEST/DEBUG) */ ! 2312: mtdec r25 /* (TEST/DEBUG) */ ! 2313: ! 2314: #endif ! 2315: ! 2316: ! 2317: /* ! 2318: * It's dangerous here. We haven't restored anything from the current savearea yet. ! 2319: * And, we mark it the active one. So, if we get an exception in here, it is ! 2320: * unrecoverable. Unless we mess up, we can't get any kind of exception. So, ! 2321: * it is important to assay this code as only the purest of gold. ! 2322: * ! 2323: * But first, see if there is a savearea hanging off of quickfret. If so, ! 2324: * we release that one first and then come back for the other. We should rarely ! 2325: * see one, they appear when FPU or VMX context is discarded by either returning ! 2326: * to a higher exception level, or explicitly. ! 2327: * ! 2328: * A word about QUICKFRET: Multiple saveareas may be queued for release. It is ! 2329: * the responsibility of the queuer to insure that the savearea is not multiply ! 2330: * queued and that the appropriate inuse bits are reset. ! 2331: */ ! 2332: ! 2333: #define TRCSAVE 0 ! 2334: ! 2335: #if TRCSAVE ! 2336: lwz r30,saver0(r31) ; (TEST/DEBUG) Get users R0 ! 2337: lwz r20,saveexception(r31) ; (TEST/DEBUG) Returning from trace? ! 2338: xor r30,r20,r30 ; (TEST/DEBUG) Make code ! 2339: rlwinm r30,r30,1,0,31 ; (TEST/DEBUG) Make an easy test ! 2340: cmplwi cr5,r30,0x61 ; (TEST/DEBUG) See if this is a trace ! 2341: #endif ! 2342: ! 2343: mr r18,r31 /* Save the savearea pointer */ ! 2344: lwz r19,PP_QUICKFRET(r2) /* Get the quick release savearea */ ! 2345: ! 2346: la r20,savesrr0(r18) /* Point to the first thing we look at */ ! 2347: li r0,0 /* Get a zero */ ! 2348: dcbt 0,r20 /* Touch in the first thing in the real savearea */ ! 2349: la r21,savesr0(r18) /* Point to the first thing we restore */ ! 2350: lis r30,HIGH_ADDR(EXT(saveanchor)) /* Get the high part of the anchor */ ! 2351: stw r0,PP_QUICKFRET(r2) /* Clear quickfret pointer */ ! 2352: ori r30,r30,LOW_ADDR(EXT(saveanchor)) /* Bottom half of the anchor */ ! 2353: dcbt 0,r21 /* Touch in the first thing */ ! 2354: ! 2355: #if TRCSAVE ! 2356: beq- cr5,trkill0 ; (TEST/DEBUG) Do not trace this type ! 2357: lwz r14,LOW_ADDR(traceMask-EXT(ExceptionVectorsStart))(br0) ; (TEST/DEBUG) Get the trace mask ! 2358: mr. r14,r14 ; (TEST/DEBUG) Is it stopped? ! 2359: beq- trkill0 ; (TEST/DEBUG) yes... ! 2360: bl cte ; (TEST/DEBUG) Trace this ! 2361: stw r18,LTR_r1(r20) ; (TEST/DEBUG) Normal savearea ! 2362: stw r19,LTR_r2(r20) ; (TEST/DEBUG) Quickfret savearea ! 2363: trkill0: ! 2364: #endif ! 2365: ! 2366: lwarx r22,0,r30 ; ? ! 2367: ! 2368: rtlck: lwarx r22,0,r30 /* Grab the lock value */ ! 2369: li r23,1 /* Use part of the delay time */ ! 2370: mr. r22,r22 /* Is it locked? */ ! 2371: bne- rtlcks /* Yeah, wait for it to clear... */ ! 2372: stwcx. r23,0,r30 /* Try to seize that there durn lock */ ! 2373: beq+ fretagain ; Got it... ! 2374: b rtlck /* Collision, try again... */ ! 2375: ! 2376: rtlcks: lwz r22,SVlock(r30) /* Get that lock in here */ ! 2377: mr. r22,r22 /* Is it free yet? */ ! 2378: beq+ rtlck /* Yeah, try for it again... */ ! 2379: b rtlcks /* Sniff away... */ ! 2380: ! 2381: ; ! 2382: ; Lock gotten, toss the saveareas ! 2383: ; ! 2384: fretagain: ! 2385: #if TRCSAVE ! 2386: beq- cr5,trkill1 ; (TEST/DEBUG) Do not trace this type ! 2387: lwz r14,LOW_ADDR(traceMask-EXT(ExceptionVectorsStart))(br0) ; (TEST/DEBUG) Get the trace mask ! 2388: mr. r14,r14 ; (TEST/DEBUG) Is it stopped? ! 2389: beq- trkill1 ; (TEST/DEBUG) yes... ! 2390: li r0,1 ; (TEST/DEBUG) ID number ! 2391: bl cte ; (TEST/DEBUG) Trace this ! 2392: stw r18,LTR_r1(r20) ; (TEST/DEBUG) Normal savearea ! 2393: stw r19,LTR_r2(r20) ; (TEST/DEBUG) Quickfret savearea ! 2394: trkill1: ! 2395: #endif ! 2396: ! 2397: mr. r18,r18 ; Are we actually done here? ! 2398: beq- donefret ; Yeah... ! 2399: mr. r31,r19 ; Is there a quickfret to do? ! 2400: beq+ noqfrt ; Nope... ! 2401: lwz r19,SAVqfret(r19) ; Yes, get the next in line ! 2402: #if TRCSAVE ! 2403: beq- cr5,trkill2 ; (TEST/DEBUG) Do not trace this type ! 2404: lwz r14,LOW_ADDR(traceMask-EXT(ExceptionVectorsStart))(br0) ; (TEST/DEBUG) Get the trace mask ! 2405: mr. r14,r14 ; (TEST/DEBUG) Is it stopped? ! 2406: beq- trkill2 ; (TEST/DEBUG) yes... ! 2407: li r0,2 ; (TEST/DEBUG) ID number ! 2408: bl cte ; (TEST/DEBUG) Trace this ! 2409: stw r18,LTR_r1(r20) ; (TEST/DEBUG) Normal savearea ! 2410: stw r19,LTR_r2(r20) ; (TEST/DEBUG) next quickfret savearea ! 2411: stw r31,LTR_r3(r20) ; (TEST/DEBUG) Current one to toss ! 2412: trkill2: ! 2413: #endif ! 2414: b doqfrt ; Go do it... ! 2415: ! 2416: noqfrt: mr r31,r18 ; Set the area to release ! 2417: li r18,0 ; Show we have done it ! 2418: #if TRCSAVE ! 2419: beq- cr5,trkill3 ; (TEST/DEBUG) Do not trace this type ! 2420: lwz r14,LOW_ADDR(traceMask-EXT(ExceptionVectorsStart))(br0) ; (TEST/DEBUG) Get the trace mask ! 2421: mr. r14,r14 ; (TEST/DEBUG) Is it stopped? ! 2422: beq- trkill3 ; (TEST/DEBUG) yes... ! 2423: li r0,3 ; (TEST/DEBUG) ID number ! 2424: bl cte ; (TEST/DEBUG) Trace this ! 2425: stw r18,LTR_r1(r20) ; (TEST/DEBUG) Normal savearea ! 2426: stw r19,LTR_r2(r20) ; (TEST/DEBUG) next quickfret savearea ! 2427: stw r31,LTR_r3(r20) ; (TEST/DEBUG) Current one to toss ! 2428: trkill3: ! 2429: #endif ! 2430: ! 2431: doqfrt: li r0,0 ; Get a constant 0 ! 2432: lis r26,0x8000 /* Build a bit mask and assume first savearea */ ! 2433: stw r0,SAVqfret(r31) ; Make sure back chain is unlinked ! 2434: lwz r28,SAVflags(r31) ; Get the flags for the old active one ! 2435: #if TRCSAVE ! 2436: beq- cr5,trkill4 ; (TEST/DEBUG) Do not trace this type ! 2437: lwz r14,LOW_ADDR(traceMask-EXT(ExceptionVectorsStart))(br0) ; (TEST/DEBUG) Get the trace mask ! 2438: mr. r14,r14 ; (TEST/DEBUG) Is it stopped? ! 2439: beq- trkill4 ; (TEST/DEBUG) yes... ! 2440: li r0,4 ; (TEST/DEBUG) ID number ! 2441: bl cte ; (TEST/DEBUG) Trace this ! 2442: stw r18,LTR_r1(r20) ; (TEST/DEBUG) Normal savearea ! 2443: stw r19,LTR_r2(r20) ; (TEST/DEBUG) next quickfret savearea ! 2444: stw r31,LTR_r3(r20) ; (TEST/DEBUG) Current one to toss ! 2445: stw r28,LTR_r4(r20) ; (TEST/DEBUG) Save current flags ! 2446: trkill4: ! 2447: #endif ! 2448: rlwinm r25,r31,21,31,31 /* Get position of savearea in block */ ! 2449: andis. r28,r28,HIGH_ADDR(SAVinuse) /* See if we need to free it */ ! 2450: srw r26,r26,r25 /* Get bit position to deallocate */ ! 2451: rlwinm r29,r31,0,0,19 /* Round savearea pointer to even page address */ ! 2452: ! 2453: bne- fretagain /* Still in use, we can't free this one... */ ! 2454: ! 2455: lwz r23,SACalloc(r29) /* Get the allocation for this block */ ! 2456: lwz r24,SVinuse(r30) /* Get the in use count */ ! 2457: mr r28,r23 ; (TEST/DEBUG) save for trace ! 2458: or r23,r23,r26 /* Turn on our bit */ ! 2459: subi r24,r24,1 /* Show that this one is free */ ! 2460: cmplw r23,r26 /* Is our's the only one free? */ ! 2461: stw r23,SACalloc(r29) /* Save it out */ ! 2462: bne+ rstrest /* Nope, then the block is already on the free list */ ! 2463: ! 2464: lwz r22,SVfree(r30) /* Get the old head of the free list */ ! 2465: stw r29,SVfree(r30) /* Point the head at us now */ ! 2466: stw r22,SACnext(r29) ; Point us to the old last ! 2467: ! 2468: rstrest: stw r24,SVinuse(r30) /* Set the in use count */ ! 2469: #if TRCSAVE ! 2470: beq- cr5,trkill5 ; (TEST/DEBUG) Do not trace this type ! 2471: lwz r14,LOW_ADDR(traceMask-EXT(ExceptionVectorsStart))(br0) ; (TEST/DEBUG) Get the trace mask ! 2472: mr. r14,r14 ; (TEST/DEBUG) Is it stopped? ! 2473: beq- trkill5 ; (TEST/DEBUG) yes... ! 2474: li r0,5 ; (TEST/DEBUG) ID number ! 2475: bl cte ; (TEST/DEBUG) Trace this ! 2476: stw r18,LTR_r1(r20) ; (TEST/DEBUG) Normal savearea ! 2477: stw r19,LTR_r2(r20) ; (TEST/DEBUG) Next quickfret savearea ! 2478: stw r31,LTR_r3(r20) ; (TEST/DEBUG) Current one to toss ! 2479: stw r28,LTR_srr1(r20) ; (TEST/DEBUG) Save the original allocation ! 2480: stw r23,LTR_dar(r20) ; (TEST/DEBUG) Save the new allocation ! 2481: stw r24,LTR_save(r20) ; (TEST/DEBUG) Save the new in use count ! 2482: stw r22,LTR_lr(r20) ; (TEST/DEBUG) Save the old top of free list ! 2483: stw r29,LTR_ctr(r20) ; (TEST/DEBUG) Save the new top of free list ! 2484: trkill5: ! 2485: #endif ! 2486: b fretagain ; Go finish up the rest... ! 2487: ! 2488: ; ! 2489: ; Build the SR values depending upon destination. If we are going to the kernel, ! 2490: ; the SRs are almost all the way set up. SR14 (or the currently used copyin/out register) ! 2491: ; must be set to whatever it was at the last exception because it varies. All the rest ! 2492: ; have been set up already. ! 2493: ; ! 2494: ; If we are going into user space, we need to check a bit more. SR0, SR1, SR2, and ! 2495: ; SR14 (current implementation) must be restored always. The others must be set if ! 2496: ; they are different that what was loaded last time (i.e., tasks have switched). ! 2497: ; We check the last loaded address space ID and if the same, we skip the loads. ! 2498: ; This is a performance gain because SR manipulations are slow. ! 2499: ; ! 2500: ! 2501: donefret: lwz r26,savesrr1(r31) ; Get destination state flags ! 2502: lwz r15,PP_USERSPACE(r2) ; Pick up the user space ID we may launch ! 2503: rlwinm. r17,r26,0,MSR_PR_BIT,MSR_PR_BIT ; See if we are going to user or system ! 2504: lwz r16,PP_LASTSPACE(r2) ; Pick up the last loaded SR value ! 2505: oris r13,r15,hi16(SEG_REG_PROT) ; Get the protection bits correct ! 2506: ! 2507: cmplw cr3,r15,r15 ; Set that we do not need to stop streams ! 2508: addis r14,r13,0x0010 ; Generate next SR value ! 2509: beq- gotokern ; We are going into kernel state, SRs all set up... ! 2510: ! 2511: mtsr sr0,r13 ; Set SR0 ! 2512: addis r13,r14,0x0010 ; Generate next SR value ! 2513: cmplw cr3,r15,r16 ; See if most of the SRs are already loaded ! 2514: mtsr sr1,r14 ; Set SR1 ! 2515: addis r14,r13,0x0010 ; Generate next SR value ! 2516: mtsr sr2,r13 ; Set SR2 ! 2517: addis r13,r14,0x0010 ; Generate next SR value ! 2518: mtsr sr3,r14 ; Set SR3 ! 2519: ! 2520: beq+ cr3,noloadsr ; SRs have not changed, no reload... ! 2521: ! 2522: addis r14,r13,0x0010 ; Generate next SR value ! 2523: mtsr sr4,r13 ; Set SR4 ! 2524: addis r13,r14,0x0010 ; Generate next SR value ! 2525: mtsr sr5,r14 ; Set SR5 ! 2526: addis r14,r13,0x0010 ; Generate next SR value ! 2527: mtsr sr6,r13 ; Set SR6 ! 2528: addis r13,r14,0x0010 ; Generate next SR value ! 2529: mtsr sr7,r14 ; Set SR7 ! 2530: addis r14,r13,0x0010 ; Generate next SR value ! 2531: mtsr sr8,r13 ; Set SR8 ! 2532: addis r13,r14,0x0010 ; Generate next SR value ! 2533: mtsr sr9,r14 ; Set SR9 ! 2534: addis r14,r13,0x0010 ; Generate next SR value ! 2535: mtsr sr10,r13 ; Set SR10 ! 2536: addis r13,r14,0x0010 ; Generate next SR value ! 2537: mtsr sr11,r14 ; Set SR11 ! 2538: addis r14,r13,0x0010 ; Generate next SR value ! 2539: mtsr sr12,r13 ; Set SR12 ! 2540: addis r13,r14,0x0010 ; Generate next SR value ! 2541: mtsr sr13,r14 ; Set SR13 ! 2542: addis r14,r13,0x0010 ; Generate next SR value ! 2543: mtsr sr14,r13 ; Set SR14 ! 2544: mtsr sr15,r14 ; Set SR15 ! 2545: stw r15,PP_LASTSPACE(r2) ; Set the last loaded SR value ! 2546: b ngotokern ; All done with user state SRs... ! 2547: ! 2548: noloadsr: oris r14,r15,hi16(SEG_REG_PROT|0x00E00000) ; Build SR14 (copyin/out) value ! 2549: b loadsr14 ; All done with user state SRs (except for SR14)... ! 2550: ! 2551: gotokern: lwz r14,savesr14(r31) ; Get the copyin/out register at interrupt time ! 2552: ! 2553: loadsr14: mtsr sr14,r14 ; Set SR14 ! 2554: ! 2555: ngotokern: lwz r25,savesrr0(r31) /* Get the SRR0 to use */ ! 2556: la r28,saver6(r31) /* Point to the next line to use */ ! 2557: lwz r0,saver0(r31) /* Restore */ ! 2558: dcbt 0,r28 /* Touch it in */ ! 2559: lwz r1,saver1(r31) /* Restore */ ! 2560: lwz r2,saver2(r31) /* Restore */ ! 2561: la r28,saver14(r31) /* Point to the next line to get */ ! 2562: lwz r3,saver3(r31) /* Restore */ ! 2563: mtsrr0 r25 /* Restore the SRR0 now */ ! 2564: lwz r4,saver4(r31) /* Restore */ ! 2565: lwz r5,saver5(r31) /* Restore */ ! 2566: mtsrr1 r26 /* Restore the SRR1 now */ ! 2567: lwz r6,saver6(r31) /* Restore */ ! 2568: ! 2569: dcbt 0,r28 /* Touch that next line on in */ ! 2570: ! 2571: lwz r7,saver7(r31) /* Restore */ ! 2572: lwz r8,saver8(r31) /* Restore */ ! 2573: lwz r9,saver9(r31) /* Restore */ ! 2574: lwz r10,saver10(r31) /* Restore */ ! 2575: lwz r11,saver11(r31) /* Restore */ ! 2576: lwz r12,saver12(r31) /* Restore */ ! 2577: lwz r13,saver13(r31) /* Restore */ ! 2578: la r28,saver22(r31) /* Point to the next line to do */ ! 2579: lwz r14,saver14(r31) /* Restore */ ! 2580: lwz r15,saver15(r31) /* Restore */ ! 2581: ! 2582: dcbt 0,r28 /* Touch in another line of context */ ! 2583: ! 2584: lwz r16,saver16(r31) /* Restore */ ! 2585: lwz r17,saver17(r31) /* Restore */ ! 2586: lwz r18,saver18(r31) /* Restore */ ! 2587: lwz r19,saver19(r31) /* Restore */ ! 2588: lwz r20,saver20(r31) /* Restore */ ! 2589: lwz r21,saver21(r31) /* Restore */ ! 2590: la r28,saver30(r31) /* Point to the final line */ ! 2591: lwz r22,saver22(r31) /* Restore */ ! 2592: ! 2593: dcbt 0,r28 /* Suck it in */ ! 2594: ! 2595: lwz r23,saver23(r31) /* Restore */ ! 2596: mfpvr r27 ; Get the processor version ! 2597: lwz r24,saver24(r31) /* Restore */ ! 2598: rlwinm r27,r27,16,16,31 ; Get the processor type ! 2599: lwz r25,saver25(r31) /* Restore */ ! 2600: cmplwi cr1,r27,PROCESSOR_VERSION_Max ; Do we have Altivec? */ ! 2601: lwz r26,saver26(r31) /* Restore */ ! 2602: lwz r27,saver27(r31) /* Restore */ ! 2603: ! 2604: dcbt 0,r28 /* Get the final line */ ! 2605: lwz r28,savecr(r31) /* Get CR to restore */ ! 2606: blt cr1,noavec4 ; No vector on this machine ! 2607: lwz r29,savevrsave(r31) ; Get the vrsave ! 2608: beq+ cr3,noavec3 ; SRs have not changed, no need to stop the streams... ! 2609: dssall ; Kill all data streams ! 2610: ; The streams should be suspended ! 2611: ; already, and we do a bunch of ! 2612: ; dependent loads and a sync later ! 2613: ; so we should be cool. ! 2614: ! 2615: noavec3: mtspr vrsave,r29 ; Set the vrsave ! 2616: ! 2617: noavec4: lwz r29,savexer(r31) /* Get XER to restore */ ! 2618: mtcr r28 /* Restore the CR */ ! 2619: lwz r28,savelr(r31) /* Get LR to restore */ ! 2620: mtxer r29 /* Restore the XER */ ! 2621: lwz r29,savectr(r31) /* Get the CTR to restore */ ! 2622: mtlr r28 /* Restore the LR */ ! 2623: lwz r28,saver30(r31) /* Restore */ ! 2624: mtctr r29 /* Restore the CTR */ ! 2625: lwz r29,saver31(r31) /* Restore */ ! 2626: mtsprg 2,r28 /* Save R30 */ ! 2627: lwz r28,saver28(r31) /* Restore */ ! 2628: mtsprg 3,r29 /* Save R31 */ ! 2629: lwz r29,saver29(r31) /* Restore */ ! 2630: ! 2631: #if PERFTIMES && DEBUG ! 2632: stmw r1,0x280(br0) ; Save all registers ! 2633: mfcr r20 ; Save the CR ! 2634: mflr r21 ; Save the LR ! 2635: mfsrr0 r9 ; Save SRR0 ! 2636: mfsrr1 r11 ; Save SRR1 ! 2637: mr r8,r0 ; Save R0 ! 2638: li r3,69 ; Indicate interrupt ! 2639: mr r4,r11 ; Set MSR to log ! 2640: mr r5,r31 ; Get savearea to log ! 2641: bl EXT(dbgLog2) ; Cut log entry ! 2642: mr r0,r8 ; Restore R0 ! 2643: mtsrr0 r9 ; Restore SRR0 ! 2644: mtsrr1 r11 ; Restore SRR1 ! 2645: mtlr r21 ; Restore the LR ! 2646: mtcr r20 ; Restore the CR ! 2647: lmw r1,0x280(br0) ; Restore all the rest ! 2648: #endif ! 2649: ! 2650: li r31,0 /* Get set to clear lock */ ! 2651: sync /* Make sure it's all out there */ ! 2652: stw r31,SVlock(r30) /* Unlock it */ ! 2653: mfsprg r30,2 /* Restore R30 */ ! 2654: mfsprg r31,3 /* Restore R31 */ ! 2655: ! 2656: rfi /* Click heels three times and think very hard that there's no place like home */ ! 2657: ! 2658: .long 0 /* For old 601 bug */ ! 2659: .long 0 ! 2660: .long 0 ! 2661: .long 0 ! 2662: .long 0 ! 2663: .long 0 ! 2664: .long 0 ! 2665: .long 0 ! 2666: ! 2667: ! 2668: ! 2669: ! 2670: /* ! 2671: * exception_exit(savearea *) ! 2672: * ! 2673: * ! 2674: * ENTRY : IR and/or DR and/or interruptions can be on ! 2675: * R3 points to the physical address of a savearea ! 2676: */ ! 2677: ! 2678: .align 5 ! 2679: .globl EXT(exception_exit) ! 2680: ! 2681: nop ; Align ISYNC to last line in cache ! 2682: nop ! 2683: ! 2684: LEXT(exception_exit) ! 2685: ! 2686: mfmsr r30 /* Get the current MSR */ ! 2687: mr r31,r3 /* Get the savearea in the right register */ ! 2688: andi. r30,r30,0x7FCF /* Turn off externals, IR, and DR */ ! 2689: lis r1,hi16(SAVredrive) ; Get redrive request ! 2690: mtmsr r30 /* Translation and all off */ ! 2691: isync /* Toss prefetch */ ! 2692: ! 2693: mfsprg r2,0 ; Get the per_proc block ! 2694: lwz r4,SAVflags(r3) ; Pick up the flags ! 2695: mr r13,r3 ; Put savearea here also ! 2696: ! 2697: and. r0,r4,r1 ; Check if redrive requested ! 2698: andc r4,r4,r1 ; Clear redrive ! 2699: ! 2700: dcbt br0,r2 ; We will need this in just a sec ! 2701: ! 2702: beq+ EatRupt ; No redrive, just exit... ! 2703: ! 2704: lwz r3,saveexception(r13) ; Restore exception code ! 2705: stw r4,SAVflags(r13) ; Set the flags ! 2706: b Redrive ; Redrive the exception... ! 2707: ! 2708: ; ! 2709: ; Make trace entry for lowmem_vectors internal debug ! 2710: ; ! 2711: #if TRCSAVE ! 2712: cte: ! 2713: lwz r20,LOW_ADDR(EXT(traceCurr)-EXT(ExceptionVectorsStart))(br0) ; Pick up the current trace entry ! 2714: lwz r16,LOW_ADDR(EXT(traceEnd)-EXT(ExceptionVectorsStart))(br0) ; Grab up the end of it all ! 2715: addi r17,r20,LTR_size ; Point to the next trace entry ! 2716: cmplw r17,r16 ; Do we need to wrap the trace table? ! 2717: li r15,32 ; Second line of entry ! 2718: bne+ ctenwrap ; We got a trace entry... ! 2719: lwz r17,LOW_ADDR(EXT(traceStart)-EXT(ExceptionVectorsStart))(br0) ; Wrap back to the top ! 2720: ! 2721: ctenwrap: stw r17,LOW_ADDR(EXT(traceCurr)-EXT(ExceptionVectorsStart))(br0) ; Set the next entry for the next guy ! 2722: ! 2723: dcbz 0,r20 ; Allocate cache for the entry ! 2724: dcbz r15,r20 ; Zap the second half ! 2725: ! 2726: ctegetTB: mftbu r16 ; Get the upper timebase ! 2727: mftb r17 ; Get the lower timebase ! 2728: mftbu r15 ; Get the upper one again ! 2729: cmplw r16,r15 ; Did the top tick? ! 2730: bne- ctegetTB ; Yeah, need to get it again... ! 2731: ! 2732: li r15,0x111 ; Get the special trace ID code ! 2733: stw r0,LTR_r0(r20) ; Save R0 (usually used as an ID number ! 2734: stw r16,LTR_timeHi(r20) ; Set the upper part of TB ! 2735: mflr r16 ; Get the return point ! 2736: stw r17,LTR_timeLo(r20) ; Set the lower part of TB ! 2737: sth r15,LTR_excpt(r20) ; Save the exception type ! 2738: stw r16,LTR_srr0(r20) ; Save the return point ! 2739: blr ; Leave... ! 2740: #endif ! 2741: ! 2742: /* ! 2743: * Start of the trace table ! 2744: */ ! 2745: ! 2746: .align 12 /* Align to 4k boundary */ ! 2747: ! 2748: traceTableBeg: /* Start of trace table */ ! 2749: /* .fill 2048,4,0 Make an 8k trace table for now */ ! 2750: .fill 13760,4,0 /* Make an .trace table for now */ ! 2751: /* .fill 240000,4,0 Make an .trace table for now */ ! 2752: traceTableEnd: /* End of trace table */ ! 2753: ! 2754: .globl EXT(ExceptionVectorsEnd) ! 2755: EXT(ExceptionVectorsEnd): /* Used if relocating the exception vectors */ ! 2756: #ifndef HACKALERTHACKALERT ! 2757: /* ! 2758: * This .long needs to be here because the linker gets confused and tries to ! 2759: * include the final label in a section in the next section if there is nothing ! 2760: * after it ! 2761: */ ! 2762: .long 0 /* (HACK/HACK/HACK) */ ! 2763: #endif ! 2764: ! 2765: .data ! 2766: .align ALIGN ! 2767: .globl EXT(exception_end) ! 2768: EXT(exception_end): ! 2769: .long EXT(ExceptionVectorsEnd) -EXT(ExceptionVectorsStart) /* phys fn */ ! 2770: ! 2771:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.