2 * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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.
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
20 * @APPLE_LICENSE_HEADER_END@
28 #include <db_machine_commands.h>
30 #include <mach_debug.h>
32 #include <ppc/proc_reg.h>
33 #include <ppc/exception.h>
34 #include <ppc/Performance.h>
35 #include <ppc/savearea.h>
36 #include <mach/ppc/vm_param.h>
41 #define featAltivec 29
44 #define VECTOR_SEGMENT .section __VECTORS, __interrupts
51 .globl EXT(ExceptionVectorsStart)
53 EXT(ExceptionVectorsStart): /* Used if relocating the exception vectors */
54 baseR: /* Used so we have more readable code */
57 ; Handle system reset.
58 ; We do not ever expect a hard reset so we do not actually check.
59 ; When we come here, we check for a RESET_HANDLER_START (which means we are
60 ; waking up from sleep), a RESET_HANDLER_BUPOR (which is using for bring up
61 ; when starting directly from a POR), and RESET_HANDLER_IGNORE (which means
62 ; ignore the interrupt).
64 ; Some machines (so far, 32-bit guys) will always ignore a non-START interrupt.
65 ; The ones who do take it, check if the interrupt is too be ignored. This is
66 ; always the case until the previous reset is handled (i.e., we have exited
70 .globl EXT(ResetHandler)
78 mtsprg 2,r13 /* Save R13 */
79 mtsprg 3,r11 /* Save R11 */
80 lwz r13,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_TYPE)(br0) ; Get reset type
82 cmpi cr0,r13,RESET_HANDLER_START
85 li r11,RESET_HANDLER_NULL
86 stw r11,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_TYPE)(br0) ; Clear reset type
88 lwz r4,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_CALL)(br0)
89 lwz r3,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_ARG)(br0)
93 resetexc: cmplwi r13,RESET_HANDLER_BUPOR ; Special bring up POR sequence?
95 lis r4,hi16(EXT(resetPOR)) ; Get POR code
96 ori r4,r4,lo16(EXT(resetPOR)) ; The rest
100 resetexc2: cmplwi cr1,r13,RESET_HANDLER_IGNORE ; Are we ignoring these? (Software debounce)
102 mfsprg r13,0 ; Get per_proc
103 lwz r13,pfAvailable(r13) ; Get the features
104 rlwinm. r13,r13,0,pf64Bitb,pf64Bitb ; Is this a 64-bit machine?
105 cror cr1_eq,cr0_eq,cr1_eq ; See if we want to take this
106 bne-- cr1,rxCont ; Yes, continue...
107 bne-- rxIg64 ; 64-bit path...
109 mtcr r11 ; Restore the CR
110 mfsprg r13,2 ; Restore R13
111 mfsprg r11,0 ; Get per_proc
112 lwz r11,pfAvailable(r11) ; Get the features
113 mtsprg 2,r11 ; Restore sprg2
114 mfsprg r11,3 ; Restore R11
115 rfi ; Return and ignore the reset
117 rxIg64: mtcr r11 ; Restore the CR
118 mfsprg r11,0 ; Get per_proc
119 mtspr hsprg0,r14 ; Save a register
120 ld r14,UAW(r11) ; Get the User Assist DoubleWord
121 mfsprg r13,2 ; Restore R13
122 lwz r11,pfAvailable(r11) ; Get the features
123 mtsprg 2,r11 ; Restore sprg2
124 mfsprg r11,3 ; Restore R11
125 mtsprg 3,r14 ; Set the UAW in sprg3
126 mfspr r14,hsprg0 ; Restore R14
127 rfid ; Return and ignore the reset
130 li r11,RESET_HANDLER_IGNORE ; Get set to ignore
131 stw r11,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_TYPE)(br0) ; Start ignoring these
132 mfsprg r13,1 /* Get the exception save area */
133 li r11,T_RESET /* Set 'rupt code */
134 b .L_exception_entry /* Join common... */
142 mtsprg 2,r13 ; Save R13
143 mtsprg 3,r11 ; Save R11
145 .globl EXT(extPatchMCK)
146 LEXT(extPatchMCK) ; This is patched to a nop for 64-bit
147 b h200aaa ; Skip 64-bit code...
150 ; Fall through here for 970 MCKs.
154 sldi r11,r11,32+3 ; ?
161 sldi r11,r11,32+8 ; ?
163 lis r11,0xE000 ; Get the unlikeliest ESID possible
173 li r11,T_MACHINE_CHECK ; Set rupt code
174 b .L_exception_entry ; Join common...
177 ; Preliminary checking of other MCKs
180 h200aaa: mfsrr1 r11 ; Get the SRR1
181 mfcr r13 ; Save the CR
183 rlwinm. r11,r11,0,dcmck,dcmck ; ?
192 oris r11,r11,hi16(dl1hwfm) ; ?
195 rstbsy: mfspr r11,msscr0 ; ?
197 rlwinm. r11,r11,0,dl1hwf,dl1hwf ; ?
202 mfsprg r11,0 ; Get the per_proc
203 mtcrf 255,r13 ; Restore CRs
204 lwz r13,hwMachineChecks(r11) ; Get old count
205 addi r13,r13,1 ; Count this one
206 stw r13,hwMachineChecks(r11) ; Set new count
207 lwz r11,pfAvailable(r11) ; Get the feature flags
208 mfsprg r13,2 ; Restore R13
209 mtsprg 2,r11 ; Set the feature flags
210 mfsprg r11,3 ; Restore R11
213 notDCache: mtcrf 255,r13 ; Restore CRs
214 li r11,T_MACHINE_CHECK ; Set rupt code
215 b .L_exception_entry ; Join common...
219 * Data access - page fault, invalid memory rights for operation
224 mtsprg 2,r13 /* Save R13 */
225 mtsprg 3,r11 /* Save R11 */
226 li r11,T_DATA_ACCESS /* Set 'rupt code */
227 b .L_exception_entry /* Join common... */
236 mtsprg 2,r13 ; Save R13
237 mtsprg 3,r11 ; Save R11
238 li r11,T_DATA_SEGMENT ; Set rupt code
239 b .L_exception_entry ; Join common...
242 * Instruction access - as for data access
247 mtsprg 2,r13 ; Save R13
248 mtsprg 3,r11 ; Save R11
249 li r11,T_INSTRUCTION_ACCESS ; Set rupt code
250 b .L_exception_entry ; Join common...
253 * Instruction segment
258 mtsprg 2,r13 ; Save R13
259 mtsprg 3,r11 ; Save R11
260 li r11,T_INSTRUCTION_SEGMENT ; Set rupt code
261 b .L_exception_entry ; Join common...
269 mtsprg 2,r13 ; Save R13
270 mtsprg 3,r11 ; Save R11
271 li r11,T_INTERRUPT ; Set rupt code
272 b .L_exception_entry ; Join common...
275 * Alignment - many reasons
280 mtsprg 2,r13 /* Save R13 */
281 mtsprg 3,r11 /* Save R11 */
282 li r11,T_ALIGNMENT|T_FAM /* Set 'rupt code */
283 b .L_exception_entry /* Join common... */
286 * Program - floating point exception, illegal inst, priv inst, user trap
291 mtsprg 2,r13 /* Save R13 */
292 mtsprg 3,r11 /* Save R11 */
295 mfsrr1 r13 ; (BRINGUP)
297 rlwinm. r13,r13,0,12,12 ; (BRINGUP)
298 crmove cr1_eq,cr0_eq ; (BRINGUP)
299 mfsrr1 r13 ; (BRINGUP)
300 rlwinm. r13,r13,0,MSR_PR_BIT,MSR_PR_BIT ; (BRINGUP)
301 crorc cr0_eq,cr1_eq,cr0_eq ; (BRINGUP)
302 bf-- cr0_eq,. ; (BRINGUP)
303 mtcrf 255,r11 ; (BRINGUP)
306 li r11,T_PROGRAM|T_FAM /* Set 'rupt code */
307 b .L_exception_entry /* Join common... */
310 * Floating point disabled
315 mtsprg 2,r13 /* Save R13 */
316 mtsprg 3,r11 /* Save R11 */
317 li r11,T_FP_UNAVAILABLE /* Set 'rupt code */
318 b .L_exception_entry /* Join common... */
322 * Decrementer - DEC register has passed zero.
327 mtsprg 2,r13 /* Save R13 */
328 mtsprg 3,r11 /* Save R11 */
329 li r11,T_DECREMENTER /* Set 'rupt code */
330 b .L_exception_entry /* Join common... */
333 * I/O controller interface error - MACH does not use this
338 mtsprg 2,r13 /* Save R13 */
339 mtsprg 3,r11 /* Save R11 */
340 li r11,T_IO_ERROR /* Set 'rupt code */
341 b .L_exception_entry /* Join common... */
349 mtsprg 2,r13 /* Save R13 */
350 mtsprg 3,r11 /* Save R11 */
351 li r11,T_RESERVED /* Set 'rupt code */
352 b .L_exception_entry /* Join common... */
355 ; System Calls (sc instruction)
357 ; The syscall number is in r0. All we do here is munge the number into a
358 ; 7-bit index into the "scTable", and dispatch on it to handle the Ultra
359 ; Fast Traps (UFTs.) The index is:
361 ; 0x40 - set if syscall number is 0x00006004
362 ; 0x20 - set if upper 29 bits of syscall number are 0xFFFFFFF8
363 ; 0x10 - set if upper 29 bits of syscall number are 0x00007FF0
364 ; 0x0E - low three bits of syscall number
365 ; 0x01 - zero, as scTable is an array of shorts
369 mtsprg 3,r11 ; Save R11
370 mtsprg 2,r13 ; Save R13
371 rlwinm r11,r0,0,0xFFFFFFF8 ; mask off low 3 bits of syscall number
372 xori r13,r11,0x7FF0 ; start to check for the 0x7FFx traps
373 addi r11,r11,8 ; make a 0 iff this is a 0xFFFFFFF8 trap
374 cntlzw r13,r13 ; set bit 0x20 iff a 0x7FFx trap
375 cntlzw r11,r11 ; set bit 0x20 iff a 0xFFFFFFF8 trap
376 rlwimi r11,r13,31,0x10 ; move 0x7FFx bit into position
377 xori r13,r0,0x6004 ; start to check for 0x6004
378 rlwimi r11,r0,1,0xE ; move in low 3 bits of syscall number
379 cntlzw r13,r13 ; set bit 0x20 iff 0x6004
380 rlwinm r11,r11,0,0,30 ; clear out bit 31
381 rlwimi r11,r13,1,0x40 ; move 0x6004 bit into position
382 lhz r11,lo16(scTable)(r11) ; get branch address from sc table
383 mfctr r13 ; save caller's ctr in r13
384 mtctr r11 ; set up branch to syscall handler
385 mfsprg r11,0 ; get per_proc, which most UFTs use
386 bctr ; dispatch (r11 in sprg3, r13 in sprg2, ctr in r13, per_proc in r11)
389 * Trace - generated by single stepping
390 * performance monitor BE branch enable tracing/logging
391 * is also done here now. while this is permanently in the
392 * system the impact is completely unnoticable as this code is
393 * only executed when (a) a single step or branch exception is
394 * hit, (b) in the single step debugger case there is so much
395 * overhead already the few extra instructions for testing for BE
396 * are not even noticable, (c) the BE logging code is *only* run
397 * when it is enabled by the tool which will not happen during
398 * normal system usage
400 * Note that this trace is available only to user state so we do not
401 * need to set sprg2 before returning.
406 mtsprg 3,r11 ; Save R11
407 mfsprg r11,2 ; Get the feature flags
408 mtsprg 2,r13 ; Save R13
409 rlwinm r11,r11,pf64Bitb-4,4,4 ; Get the 64-bit flag
410 mfcr r13 ; Get the CR
411 mtcrf 0x40,r11 ; Set the CR
412 mfsrr1 r11 ; Get the old MSR
413 rlwinm. r11,r11,0,MSR_PR_BIT,MSR_PR_BIT ; Are we in supervisor state?
415 mfsprg r11,0 ; Get the per_proc
416 lhz r11,PP_CPU_FLAGS(r11) ; Get the flags
417 crmove cr1_eq,cr0_eq ; Remember if we are in supervisor state
418 rlwinm. r11,r11,0,traceBEb+16,traceBEb+16 ; Special trace enabled?
419 cror cr0_eq,cr0_eq,cr1_eq ; Is trace off or supervisor state?
420 bf-- cr0_eq,specbrtr ; No, we need to trace...
422 notspectr: mtcr r13 ; Restore CR
423 li r11,T_TRACE|T_FAM ; Set interrupt code
424 b .L_exception_entry ; Join common...
429 ; We are doing the special branch trace
432 specbrtr: mfsprg r11,0 ; Get the per_proc area
433 bt++ 4,sbxx64a ; Jump if 64-bit...
435 stw r1,tempr0+4(r11) ; Save in a scratch area
436 stw r2,tempr1+4(r11) ; Save in a scratch area
437 stw r3,tempr2+4(r11) ; Save in a scratch area
440 sbxx64a: std r1,tempr0(r11) ; Save in a scratch area
441 std r2,tempr1(r11) ; Save in a scratch area
442 std r3,tempr2(r11) ; Save in a scratch area
444 sbxx64b: lis r2,hi16(EXT(pc_trace_buf)) ; Get the top of the buffer
445 lwz r3,spcTRp(r11) ; Pick up buffer position
446 ori r2,r2,lo16(EXT(pc_trace_buf)) ; Get the bottom of the buffer
447 cmplwi cr2,r3,4092 ; Set cr1_eq if we should take exception
448 mfsrr0 r1 ; Get the pc
449 stwx r1,r2,r3 ; Save it in the buffer
450 addi r3,r3,4 ; Point to the next slot
451 rlwinm r3,r3,0,20,31 ; Wrap the slot at one page
452 stw r3,spcTRp(r11) ; Save the new slot
454 bt++ 4,sbxx64c ; Jump if 64-bit...
456 lwz r1,tempr0+4(r11) ; Restore work register
457 lwz r2,tempr1+4(r11) ; Restore work register
458 lwz r3,tempr2+4(r11) ; Restore work register
459 beq cr2,notspectr ; Buffer filled, make a rupt...
460 mtcr r13 ; Restore CR
461 b uftRFI ; Go restore and leave...
463 sbxx64c: ld r1,tempr0(r11) ; Restore work register
464 ld r2,tempr1(r11) ; Restore work register
465 ld r3,tempr2(r11) ; Restore work register
466 beq cr2,notspectr ; Buffer filled, make a rupt...
467 mtcr r13 ; Restore CR
468 b uftRFI ; Go restore and leave...
471 * Floating point assist
476 mtsprg 2,r13 /* Save R13 */
477 mtsprg 3,r11 /* Save R11 */
478 li r11,T_FP_ASSIST /* Set 'rupt code */
479 b .L_exception_entry /* Join common... */
483 * Performance monitor interruption
488 mtsprg 2,r13 /* Save R13 */
489 mtsprg 3,r11 /* Save R11 */
490 li r11,T_PERF_MON /* Set 'rupt code */
491 b .L_exception_entry /* Join common... */
500 mtsprg 2,r13 /* Save R13 */
501 mtsprg 3,r11 /* Save R11 */
502 li r11,T_VMX /* Set 'rupt code */
503 b .L_exception_entry /* Join common... */
508 ; Instruction translation miss exception - not supported
513 mtsprg 2,r13 ; Save R13
514 mtsprg 3,r11 ; Save R11
515 li r11,T_INVALID_EXCP0 ; Set rupt code
516 b .L_exception_entry ; Join common...
521 ; Data load translation miss exception - not supported
526 mtsprg 2,r13 ; Save R13
527 mtsprg 3,r11 ; Save R11
528 li r11,T_INVALID_EXCP1 ; Set rupt code
529 b .L_exception_entry ; Join common...
534 ; Data store translation miss exception - not supported
539 mtsprg 2,r13 ; Save R13
540 mtsprg 3,r11 ; Save R11
541 li r11,T_INVALID_EXCP2 ; Set rupt code
542 b .L_exception_entry ; Join common...
546 * Instruction address breakpoint
551 mtsprg 2,r13 /* Save R13 */
552 mtsprg 3,r11 /* Save R11 */
553 li r11,T_INSTRUCTION_BKPT /* Set 'rupt code */
554 b .L_exception_entry /* Join common... */
557 * System management interrupt
562 mtsprg 2,r13 /* Save R13 */
563 mtsprg 3,r11 /* Save R11 */
564 li r11,T_SYSTEM_MANAGEMENT /* Set 'rupt code */
565 b .L_exception_entry /* Join common... */
574 mtsprg 2,r13 /* Save R13 */
575 mtsprg 3,r11 /* Save R11 */
576 li r11,T_SOFT_PATCH /* Set 'rupt code */
577 b .L_exception_entry /* Join common... */
580 ; Altivec Java Mode Assist interrupt or Maintenace interrupt
585 mtsprg 2,r13 /* Save R13 */
586 mtsprg 3,r11 /* Save R11 */
587 li r11,T_ALTIVEC_ASSIST /* Set 'rupt code */
588 b .L_exception_entry /* Join common... */
591 ; Altivec Java Mode Assist interrupt or Thermal interruption
596 mtsprg 2,r13 /* Save R13 */
597 mtsprg 3,r11 /* Save R11 */
598 li r11,T_THERMAL /* Set 'rupt code */
599 b .L_exception_entry /* Join common... */
602 ; Thermal interruption - 64-bit
607 mtsprg 2,r13 /* Save R13 */
608 mtsprg 3,r11 /* Save R11 */
609 li r11,T_ARCHDEP0 /* Set 'rupt code */
610 b .L_exception_entry /* Join common... */
613 * There is now a large gap of reserved traps
617 * Instrumentation interruption
622 mtsprg 2,r13 /* Save R13 */
623 mtsprg 3,r11 /* Save R11 */
624 li r11,T_INSTRUMENTATION /* Set 'rupt code */
625 b .L_exception_entry /* Join common... */
631 .globl EXT(exception_entry)
632 EXT(exception_entry):
633 .long .L_exception_entry-EXT(ExceptionVectorsStart) /* phys addr of fn */
637 /*<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
639 * First-level syscall dispatch. The syscall vector maps r0 (the syscall number) into an
640 * index into the "scTable" (below), and then branches to one of these routines. The PPC
641 * syscalls come in several varieties, as follows:
643 * 1. If (syscall & 0xFFFFF000) == 0x00007000, then it is a PPC Fast Trap or UFT.
644 * The UFTs are dispatched here, the Fast Traps are dispatched in hw_exceptions.s.
646 * 2. If (syscall & 0xFFFFF000) == 0x00006000, then it is a PPC-only trap.
647 * One of these (0x6004) is a UFT, but most are dispatched in hw_exceptions.s. These
648 * are mostly Blue Box or VMM (Virtual Machine) calls.
650 * 3. If (syscall & 0xFFFFFFF0) == 0xFFFFFFF0, then it is also a UFT and is dispatched here.
652 * 4. If (syscall & 0xFFFFF000) == 0x80000000, then it is a "firmware" call and is dispatched in
653 * Firmware.s, though the special "Cut Trace" trap (0x80000000) is handled here in xcpSyscall.
655 * 5. If (syscall & 0xFFFFF000) == 0xFFFFF000, and it is not one of the above, then it is a Mach
656 * syscall, which are dispatched in hw_exceptions.s via "mach_trap_table".
658 * 6. If (syscall & 0xFFFFF000) == 0x00000000, then it is a BSD syscall, which are dispatched
659 * by "unix_syscall" using the "sysent" table.
661 * What distinguishes the UFTs, aside from being ultra fast, is that they cannot rely on translation
662 * being on, and so cannot look at the activation or task control block, etc. We handle them right
663 * here, and return to the caller without turning interrupts or translation on. The UFTs are:
665 * 0xFFFFFFFF - BlueBox only - MKIsPreemptiveTask
666 * 0xFFFFFFFE - BlueBox only - MKIsPreemptiveTaskEnv
667 * 0x00007FF2 - User state only - thread info (32-bit mode)
668 * 0x00007FF3 - User state only - floating point / vector facility status
669 * 0x00007FF4 - Kernel only - loadMSR - not used on 64-bit machines
670 * 0x00006004 - vmm_dispatch (only some of which are UFTs)
672 * "scTable" is an array of 2-byte addresses, accessed using a 7-bit index derived from the syscall
675 * 0x40 (A) - set if syscall number is 0x00006004
676 * 0x20 (B) - set if upper 29 bits of syscall number are 0xFFFFFFF8
677 * 0x10 (C) - set if upper 29 bits of syscall number are 0x00007FF0
678 * 0x0E (D) - low three bits of syscall number
680 * If you define another UFT, try to use a number in one of the currently decoded ranges, ie one marked
681 * "unassigned" below. The dispatch table and the UFT handlers must reside in the first 32KB of
685 .align 7 ; start this table on a cache line
687 .short uftNormalSyscall-baseR ; 000 0 these syscalls are not in a reserved range
688 .short uftNormalSyscall-baseR ; 000 1 these syscalls are not in a reserved range
689 .short uftNormalSyscall-baseR ; 000 2 these syscalls are not in a reserved range
690 .short uftNormalSyscall-baseR ; 000 3 these syscalls are not in a reserved range
691 .short uftNormalSyscall-baseR ; 000 4 these syscalls are not in a reserved range
692 .short uftNormalSyscall-baseR ; 000 5 these syscalls are not in a reserved range
693 .short uftNormalSyscall-baseR ; 000 6 these syscalls are not in a reserved range
694 .short uftNormalSyscall-baseR ; 000 7 these syscalls are not in a reserved range
696 .short uftNormalSyscall-baseR ; 001 0 0x7FF0 is unassigned
697 .short uftNormalSyscall-baseR ; 001 1 0x7FF1 is Set Thread Info Fast Trap (pass up)
698 .short uftThreadInfo-baseR ; 001 2 0x7FF2 is Thread Info
699 .short uftFacilityStatus-baseR ; 001 3 0x7FF3 is Facility Status
700 .short uftLoadMSR-baseR ; 001 4 0x7FF4 is Load MSR
701 .short uftNormalSyscall-baseR ; 001 5 0x7FF5 is the Null FastPath Trap (pass up)
702 .short uftNormalSyscall-baseR ; 001 6 0x7FF6 is unassigned
703 .short uftNormalSyscall-baseR ; 001 7 0x7FF7 is unassigned
705 .short uftNormalSyscall-baseR ; 010 0 0xFFFFFFF0 is unassigned
706 .short uftNormalSyscall-baseR ; 010 1 0xFFFFFFF1 is unassigned
707 .short uftNormalSyscall-baseR ; 010 2 0xFFFFFFF2 is unassigned
708 .short uftNormalSyscall-baseR ; 010 3 0xFFFFFFF3 is unassigned
709 .short uftNormalSyscall-baseR ; 010 4 0xFFFFFFF4 is unassigned
710 .short uftNormalSyscall-baseR ; 010 5 0xFFFFFFF5 is unassigned
711 .short uftIsPreemptiveTaskEnv-baseR ; 010 6 0xFFFFFFFE is Blue Box uftIsPreemptiveTaskEnv
712 .short uftIsPreemptiveTask-baseR ; 010 7 0xFFFFFFFF is Blue Box IsPreemptiveTask
714 .short WhoaBaby-baseR ; 011 0 impossible combination
715 .short WhoaBaby-baseR ; 011 1 impossible combination
716 .short WhoaBaby-baseR ; 011 2 impossible combination
717 .short WhoaBaby-baseR ; 011 3 impossible combination
718 .short WhoaBaby-baseR ; 011 4 impossible combination
719 .short WhoaBaby-baseR ; 011 5 impossible combination
720 .short WhoaBaby-baseR ; 011 6 impossible combination
721 .short WhoaBaby-baseR ; 011 7 impossible combination
723 .short WhoaBaby-baseR ; 100 0 0x6000 is an impossible index (diagCall)
724 .short WhoaBaby-baseR ; 100 1 0x6001 is an impossible index (vmm_get_version)
725 .short WhoaBaby-baseR ; 100 2 0x6002 is an impossible index (vmm_get_features)
726 .short WhoaBaby-baseR ; 100 3 0x6003 is an impossible index (vmm_init_context)
727 .short uftVMM-baseR ; 100 4 0x6004 is vmm_dispatch (only some of which are UFTs)
728 .short WhoaBaby-baseR ; 100 5 0x6005 is an impossible index (bb_enable_bluebox)
729 .short WhoaBaby-baseR ; 100 6 0x6006 is an impossible index (bb_disable_bluebox)
730 .short WhoaBaby-baseR ; 100 7 0x6007 is an impossible index (bb_settaskenv)
732 .align 2 ; prepare for code
735 /* Ultra Fast Trap (UFT) Handlers:
737 * We get here directly from the hw syscall vector via the "scTable" vector (above),
738 * with interrupts and VM off, in 64-bit mode if supported, and with all registers live
739 * except the following:
741 * r11 = per_proc ptr (ie, sprg0)
742 * r13 = holds caller's ctr register
743 * sprg2 = holds caller's r13
744 * sprg3 = holds caller's r11
747 ; Handle "vmm_dispatch" (0x6004), of which only some selectors are UFTs.
750 mtctr r13 ; restore caller's ctr
751 lwz r11,spcFlags(r11) ; get the special flags word from per_proc
752 mfcr r13 ; save caller's entire cr (we use all fields below)
753 rlwinm r11,r11,16,16,31 ; Extract spcFlags upper bits
754 andi. r11,r11,hi16(runningVM|FamVMena|FamVMmode)
755 cmpwi cr0,r11,hi16(runningVM|FamVMena|FamVMmode) ; Test in VM FAM
756 bne-- uftNormal80 ; not eligible for FAM UFTs
757 cmpwi cr5,r3,kvmmResumeGuest ; Compare r3 with kvmmResumeGuest
758 cmpwi cr2,r3,kvmmSetGuestRegister ; Compare r3 with kvmmSetGuestRegister
759 cror cr1_eq,cr5_lt,cr2_gt ; Set true if out of VMM Fast syscall range
760 bt-- cr1_eq,uftNormalFF ; Exit if out of range (the others are not UFTs)
761 b EXT(vmm_ufp) ; handle UFT range of vmm_dispatch syscall
764 ; Handle blue box UFTs (syscalls -1 and -2).
767 uftIsPreemptiveTaskEnv:
768 mtctr r13 ; restore caller's ctr
769 lwz r11,spcFlags(r11) ; get the special flags word from per_proc
770 mfcr r13,0x80 ; save caller's cr0 so we can use it
771 andi. r11,r11,bbNoMachSC|bbPreemptive ; Clear what we do not need
772 cmplwi r11,bbNoMachSC ; See if we are trapping syscalls
773 blt-- uftNormal80 ; No...
774 cmpwi r0,-2 ; is this call IsPreemptiveTaskEnv?
775 rlwimi r13,r11,bbPreemptivebit-cr0_eq,cr0_eq,cr0_eq ; Copy preemptive task flag into user cr0_eq
776 mfsprg r11,0 ; Get the per proc once more
777 bne++ uftRestoreThenRFI ; do not load r0 if IsPreemptiveTask
778 lwz r0,ppbbTaskEnv(r11) ; Get the shadowed taskEnv (only difference)
779 b uftRestoreThenRFI ; restore modified cr0 and return
782 ; Handle "Thread Info" UFT (0x7FF2)
784 .globl EXT(uft_uaw_nop_if_32bit)
786 lwz r3,UAW+4(r11) ; get user assist word, assuming a 32-bit processor
787 LEXT(uft_uaw_nop_if_32bit)
788 ld r3,UAW(r11) ; get the whole doubleword if 64-bit (patched to nop if 32-bit)
789 mtctr r13 ; restore caller's ctr
793 ; Handle "Facility Status" UFT (0x7FF3)
796 lwz r3,spcFlags(r11) ; get "special flags" word from per_proc
797 mtctr r13 ; restore caller's ctr
801 ; Handle "Load MSR" UFT (0x7FF4). This is not used on 64-bit processors, though it would work.
804 mfsrr1 r11 ; get caller's MSR
805 mtctr r13 ; restore caller's ctr
806 mfcr r13,0x80 ; save caller's cr0 so we can test PR
807 rlwinm. r11,r11,0,MSR_PR_BIT,MSR_PR_BIT ; really in the kernel?
808 bne- uftNormal80 ; do not permit from user mode
809 mfsprg r11,0 ; restore per_proc
810 mtsrr1 r3 ; Set new MSR
813 ; Return to caller after UFT. When called:
815 ; r13 = callers cr0 in upper nibble (if uftRestoreThenRFI called)
816 ; sprg2 = callers r13
817 ; sprg3 = callers r11
819 uftRestoreThenRFI: ; WARNING: can drop down to here
820 mtcrf 0x80,r13 ; restore caller's cr0
822 .globl EXT(uft_nop_if_32bit)
823 LEXT(uft_nop_if_32bit)
824 b uftX64 ; patched to NOP if 32-bit processor
826 lwz r11,pfAvailable(r11) ; Get the feature flags
827 mfsprg r13,2 ; Restore R13
828 mtsprg 2,r11 ; Set the feature flags
829 mfsprg r11,3 ; Restore R11
830 rfi ; Back to our guy...
832 uftX64: mtspr hsprg0,r14 ; Save a register in a Hypervisor SPRG
833 ld r14,UAW(r11) ; Get the User Assist DoubleWord
834 lwz r11,pfAvailable(r11) ; Get the feature flags
835 mfsprg r13,2 ; Restore R13
836 mtsprg 2,r11 ; Set the feature flags
837 mfsprg r11,3 ; Restore R11
838 mtsprg 3,r14 ; Set the UAW in sprg3
839 mfspr r14,hsprg0 ; Restore R14
840 rfid ; Back to our guy...
843 ; Handle a system call that is not a UFT and which thus goes upstairs.
845 uftNormalFF: ; here with entire cr in r13
846 mtcr r13 ; restore all 8 fields
847 b uftNormalSyscall1 ; Join common...
849 uftNormal80: ; here with callers cr0 in r13
850 mtcrf 0x80,r13 ; restore cr0
851 b uftNormalSyscall1 ; Join common...
853 uftNormalSyscall: ; r13 = callers ctr
854 mtctr r13 ; restore ctr
856 li r11,T_SYSTEM_CALL|T_FAM ; this is a system call (and fall through)
859 /*<><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>*/
861 * .L_exception_entry(type)
863 * Come here via branch directly from the vector, or falling down from above, with the following
866 * ENTRY: interrupts off, VM off, in 64-bit mode if supported
867 * Caller's r13 saved in sprg2.
868 * Caller's r11 saved in sprg3.
869 * Exception code (ie, T_SYSTEM_CALL etc) in r11.
870 * All other registers are live.
874 .L_exception_entry: ; WARNING: can fall through from UFT handler
878 * Here we will save off a mess of registers, the special ones and R0-R12. We use the DCBZ
879 * instruction to clear and allcoate a line in the cache. This way we won't take any cache
880 * misses, so these stores won't take all that long. Except the first line that is because
881 * we can't do a DCBZ if the L1 D-cache is off. The rest we will skip if they are
884 * Note that if we are attempting to sleep (as opposed to nap or doze) all interruptions
889 .globl EXT(extPatch32)
893 b extEntry64 ; Go do 64-bit (patched to a nop if 32-bit)
894 mfsprg r13,0 ; Load per_proc
895 lwz r13,next_savearea+4(r13) ; Get the exception save area
896 stw r0,saver0+4(r13) ; Save register 0
897 stw r1,saver1+4(r13) ; Save register 1
899 mfspr r1,hid0 ; Get HID0
900 mfcr r0 ; Save the whole CR
902 mtcrf 0x20,r1 ; Get set to test for sleep
903 cror doze,doze,nap ; Remember if we are napping
904 bf sleep,notsleep ; Skip if we are not trying to sleep
906 mtcrf 0x20,r0 ; Restore the CR
907 lwz r0,saver0+4(r13) ; Restore R0
908 lwz r1,saver1+4(r13) ; Restore R1
909 mfsprg r13,0 ; Get the per_proc
910 lwz r11,pfAvailable(r13) ; Get back the feature flags
911 mfsprg r13,2 ; Restore R13
912 mtsprg 2,r11 ; Set sprg2 to the features
913 mfsprg r11,3 ; Restore R11
914 rfi ; Jump back into sleep code...
915 .long 0 ; Leave these here please...
926 ; This is the 32-bit context saving stuff
931 notsleep: stw r2,saver2+4(r13) ; Save this one
932 bf doze,notspdo ; Skip the next if we are not napping/dozing...
933 rlwinm r2,r1,0,nap+1,doze-1 ; Clear any possible nap and doze bits
934 mtspr hid0,r2 ; Clear the nap/doze bits
938 mfspr r2,pmc1 ; INSTRUMENT - saveinstr[0] - Take earliest possible stamp
939 stw r2,0x6100+(0x00*16)+0x0(0) ; INSTRUMENT - Save it
940 mfspr r2,pmc2 ; INSTRUMENT - Get stamp
941 stw r2,0x6100+(0x00*16)+0x4(0) ; INSTRUMENT - Save it
942 mfspr r2,pmc3 ; INSTRUMENT - Get stamp
943 stw r2,0x6100+(0x00*16)+0x8(0) ; INSTRUMENT - Save it
944 mfspr r2,pmc4 ; INSTRUMENT - Get stamp
945 stw r2,0x6100+(0x00*16)+0xC(0) ; INSTRUMENT - Save it
948 la r1,saver4(r13) ; Point to the next line in case we need it
949 crmove wasNapping,doze ; Remember if we were napping
950 mfsprg r2,0 ; Get the per_proc area
951 dcbz 0,r1 ; allocate r4-r7 32-byte line in cache
954 ; Remember, we are setting up CR6 with feature flags
956 andi. r1,r11,T_FAM ; Check FAM bit
958 stw r3,saver3+4(r13) ; Save this one
959 stw r4,saver4+4(r13) ; Save this one
960 andc r11,r11,r1 ; Clear FAM bit
961 beq+ noFAM ; Is it FAM intercept
962 mfsrr1 r3 ; Load srr1
963 rlwinm. r3,r3,0,MSR_PR_BIT,MSR_PR_BIT ; Are we trapping from supervisor state?
964 beq+ noFAM ; From supervisor state
965 lwz r1,spcFlags(r2) ; Load spcFlags
966 rlwinm r1,r1,1+FamVMmodebit,30,31 ; Extract FamVMenabit and FamVMmodebit
967 cmpwi cr0,r1,2 ; Check FamVMena set without FamVMmode
968 bne+ noFAM ; Can this context be FAM intercept
969 lwz r4,FAMintercept(r2) ; Load exceptions mask to intercept
970 srwi r1,r11,2 ; divide r11 by 4
971 lis r3,0x8000 ; Set r3 to 0x80000000
972 srw r1,r3,r1 ; Set bit for current exception
973 and. r1,r1,r4 ; And current exception with the intercept mask
974 beq+ noFAM ; Is it FAM intercept
977 lwz r1,pfAvailable(r2) ; Get the CPU features flags
978 la r3,saver8(r13) ; Point to line with r8-r11
979 mtcrf 0xE2,r1 ; Put the features flags (that we care about) in the CR
980 dcbz 0,r3 ; allocate r8-r11 32-byte line in cache
981 la r3,saver12(r13) ; point to r12-r15 line
982 lis r4,hi16(MASK(MSR_VEC)|MASK(MSR_FP)|MASK(MSR_ME)) ; Set up the MSR we will use throughout. Note that ME come on here if MCK
983 stw r6,saver6+4(r13) ; Save this one
984 ori r4,r4,lo16(MASK(MSR_VEC)|MASK(MSR_FP)|MASK(MSR_ME)) ; Rest of MSR
985 stw r8,saver8+4(r13) ; Save this one
986 crmove featAltivec,pfAltivecb ; Set the Altivec flag
989 mfsrr0 r6 ; Get the interruption SRR0
990 la r8,savesrr0(r13) ; point to line with SRR0, SRR1, CR, XER, and LR
991 dcbz 0,r3 ; allocate r12-r15 32-byte line in cache
992 la r3,saver16(r13) ; point to next line
993 dcbz 0,r8 ; allocate 32-byte line with SRR0, SRR1, CR, XER, and LR
994 stw r7,saver7+4(r13) ; Save this one
995 lhz r8,PP_CPU_FLAGS(r2) ; Get the flags
996 mfsrr1 r7 ; Get the interrupt SRR1
997 rlwinm r8,r8,(((31-MSR_BE_BIT)+(traceBEb+16+1))&31),MSR_BE_BIT,MSR_BE_BIT ; Set BE bit if special trace is on
998 stw r6,savesrr0+4(r13) ; Save the SRR0
999 rlwinm r6,r7,(((31-MSR_BE_BIT)+(MSR_PR_BIT+1))&31),MSR_BE_BIT,MSR_BE_BIT ; Move PR bit to BE bit
1000 stw r5,saver5+4(r13) ; Save this one
1001 and r8,r6,r8 ; Remove BE bit only if problem state and special tracing on
1002 mfsprg r6,2 ; Get interrupt time R13
1003 mtsprg 2,r1 ; Set the feature flags
1004 andc r7,r7,r8 ; Clear BE bit if special trace is on and PR is set
1005 mfsprg r8,3 ; Get rupt time R11
1006 stw r7,savesrr1+4(r13) ; Save SRR1
1007 stw r8,saver11+4(r13) ; Save rupt time R11
1008 stw r6,saver13+4(r13) ; Save rupt R13
1009 dcbz 0,r3 ; allocate 32-byte line with r16-r19
1010 la r3,saver20(r13) ; point to next line
1012 getTB: mftbu r6 ; Get the upper timebase
1013 mftb r7 ; Get the lower timebase
1014 mftbu r8 ; Get the upper one again
1015 cmplw r6,r8 ; Did the top tick?
1016 bne- getTB ; Yeah, need to get it again...
1019 mfspr r6,pmc1 ; INSTRUMENT - saveinstr[1] - Save halfway context save stamp
1020 stw r6,0x6100+(0x01*16)+0x0(0) ; INSTRUMENT - Save it
1021 mfspr r6,pmc2 ; INSTRUMENT - Get stamp
1022 stw r6,0x6100+(0x01*16)+0x4(0) ; INSTRUMENT - Save it
1023 mfspr r6,pmc3 ; INSTRUMENT - Get stamp
1024 stw r6,0x6100+(0x01*16)+0x8(0) ; INSTRUMENT - Save it
1025 mfspr r6,pmc4 ; INSTRUMENT - Get stamp
1026 stw r6,0x6100+(0x01*16)+0xC(0) ; INSTRUMENT - Save it
1029 stw r8,ruptStamp(r2) ; Save the top of time stamp
1030 stw r8,SAVtime(r13) ; Save the top of time stamp
1031 stw r7,ruptStamp+4(r2) ; Save the bottom of time stamp
1032 stw r7,SAVtime+4(r13) ; Save the bottom of time stamp
1034 dcbz 0,r3 ; allocate 32-byte line with r20-r23
1035 stw r9,saver9+4(r13) ; Save this one
1037 stw r10,saver10+4(r13) ; Save this one
1038 mflr r4 ; Get the LR
1039 mfxer r10 ; Get the XER
1041 bf+ wasNapping,notNapping ; Skip if not waking up from nap...
1043 lwz r6,napStamp+4(r2) ; Pick up low order nap stamp
1044 lis r3,hi16(EXT(machine_idle_ret)) ; Get high part of nap/doze return
1045 lwz r5,napStamp(r2) ; and high order
1046 subfc r7,r6,r7 ; Subtract low stamp from now
1047 lwz r6,napTotal+4(r2) ; Pick up low total
1048 subfe r5,r5,r8 ; Subtract high stamp and borrow from now
1049 lwz r8,napTotal(r2) ; Pick up the high total
1050 addc r6,r6,r7 ; Add low to total
1051 ori r3,r3,lo16(EXT(machine_idle_ret)) ; Get low part of nap/doze return
1052 adde r8,r8,r5 ; Add high and carry to total
1053 stw r6,napTotal+4(r2) ; Save the low total
1054 stw r8,napTotal(r2) ; Save the high total
1055 stw r3,savesrr0+4(r13) ; Modify to return to nap/doze exit
1057 rlwinm. r3,r1,0,pfSlowNapb,pfSlowNapb ; Should HID1 be restored?
1060 lwz r3,pfHID1(r2) ; Get saved HID1 value
1061 mtspr hid1,r3 ; Restore HID1
1064 rlwinm. r3,r1,0,pfNoL2PFNapb,pfNoL2PFNapb ; Should MSSCR0 be restored?
1067 lwz r3,pfMSSCR0(r2) ; Get saved MSSCR0 value
1068 mtspr msscr0,r3 ; Restore MSSCR0
1072 notNapping: stw r12,saver12+4(r13) ; Save this one
1074 stw r14,saver14+4(r13) ; Save this one
1075 stw r15,saver15+4(r13) ; Save this one
1076 la r14,saver24(r13) ; Point to the next block to save into
1077 mfctr r6 ; Get the CTR
1078 stw r16,saver16+4(r13) ; Save this one
1079 la r15,savectr(r13) ; point to line with CTR, DAR, DSISR, Exception code, and VRSAVE
1080 stw r4,savelr+4(r13) ; Save rupt LR
1082 dcbz 0,r14 ; allocate 32-byte line with r24-r27
1083 la r16,saver28(r13) ; point to line with r28-r31
1084 dcbz 0,r15 ; allocate line with CTR, DAR, DSISR, Exception code, and VRSAVE
1085 stw r17,saver17+4(r13) ; Save this one
1086 stw r18,saver18+4(r13) ; Save this one
1087 stw r6,savectr+4(r13) ; Save rupt CTR
1088 stw r0,savecr(r13) ; Save rupt CR
1089 stw r19,saver19+4(r13) ; Save this one
1090 mfdar r6 ; Get the rupt DAR
1091 stw r20,saver20+4(r13) ; Save this one
1092 dcbz 0,r16 ; allocate 32-byte line with r28-r31
1094 stw r21,saver21+4(r13) ; Save this one
1095 lwz r21,spcFlags(r2) ; Get the special flags from per_proc
1096 stw r10,savexer+4(r13) ; Save the rupt XER
1097 stw r30,saver30+4(r13) ; Save this one
1098 lhz r30,pfrptdProc(r2) ; Get the reported processor type
1099 stw r31,saver31+4(r13) ; Save this one
1100 stw r22,saver22+4(r13) ; Save this one
1101 stw r23,saver23+4(r13) ; Save this one
1102 stw r24,saver24+4(r13) ; Save this one
1103 stw r25,saver25+4(r13) ; Save this one
1104 mfdsisr r7 ; Get the rupt DSISR
1105 stw r26,saver26+4(r13) ; Save this one
1106 stw r27,saver27+4(r13) ; Save this one
1107 andis. r21,r21,hi16(perfMonitor) ; Is the performance monitor enabled?
1108 stw r28,saver28+4(r13) ; Save this one
1109 cmpwi cr1, r30,CPU_SUBTYPE_POWERPC_750 ; G3?
1110 la r27,savevscr(r13) ; point to 32-byte line with VSCR and FPSCR
1111 cmpwi cr2,r30,CPU_SUBTYPE_POWERPC_7400 ; This guy?
1112 stw r29,saver29+4(r13) ; Save R29
1113 stw r6,savedar+4(r13) ; Save the rupt DAR
1114 li r10,savepmc ; Point to pmc savearea
1116 beq+ noPerfMonSave32 ; No perfmon on here...
1118 dcbz r10,r13 ; Clear first part of pmc area
1119 li r10,savepmc+0x20 ; Point to pmc savearea second part
1120 li r22,0 ; r22: zero
1121 dcbz r10,r13 ; Clear second part of pmc area
1123 beq cr1,perfMonSave32_750 ; This is a G3...
1125 beq cr2,perfMonSave32_7400 ; Regular olde G4...
1127 mfspr r24,pmc5 ; Here for a 7450
1129 stw r24,savepmc+16(r13) ; Save PMC5
1130 stw r25,savepmc+20(r13) ; Save PMC6
1131 mtspr pmc5,r22 ; Leave PMC5 clear
1132 mtspr pmc6,r22 ; Leave PMC6 clear
1136 stw r25,savemmcr2+4(r13) ; Save MMCR2
1137 mtspr mmcr2,r22 ; Leave MMCR2 clear
1142 stw r23,savemmcr0+4(r13) ; Save MMCR0
1143 stw r24,savemmcr1+4(r13) ; Save MMCR1
1144 mtspr mmcr0,r22 ; Leave MMCR0 clear
1145 mtspr mmcr1,r22 ; Leave MMCR1 clear
1150 stw r23,savepmc+0(r13) ; Save PMC1
1151 stw r24,savepmc+4(r13) ; Save PMC2
1152 stw r25,savepmc+8(r13) ; Save PMC3
1153 stw r26,savepmc+12(r13) ; Save PMC4
1154 mtspr pmc1,r22 ; Leave PMC1 clear
1155 mtspr pmc2,r22 ; Leave PMC2 clear
1156 mtspr pmc3,r22 ; Leave PMC3 clear
1157 mtspr pmc4,r22 ; Leave PMC4 clear
1160 dcbz 0,r27 ; allocate line with VSCR and FPSCR
1162 stw r7,savedsisr(r13) ; Save the rupt code DSISR
1163 stw r11,saveexception(r13) ; Save the exception code
1167 ; Everything is saved at this point, except for FPRs, and VMX registers.
1168 ; Time for us to get a new savearea and then trace interrupt if it is enabled.
1171 lwz r25,traceMask(0) ; Get the trace mask
1172 li r0,SAVgeneral ; Get the savearea type value
1173 lhz r19,PP_CPU_NUMBER(r2) ; Get the logical processor number
1174 rlwinm r22,r11,30,0,31 ; Divide interrupt code by 2
1175 stb r0,SAVflags+2(r13) ; Mark valid context
1176 addi r22,r22,10 ; Adjust code so we shift into CR5
1177 li r23,trcWork ; Get the trace work area address
1178 rlwnm r7,r25,r22,22,22 ; Set CR5_EQ bit position to 0 if tracing allowed
1179 li r26,0x8 ; Get start of cpu mask
1180 srw r26,r26,r19 ; Get bit position of cpu number
1181 mtcrf 0x04,r7 ; Set CR5 to show trace or not
1182 and. r26,r26,r25 ; See if we trace this cpu
1183 crandc cr5_eq,cr5_eq,cr0_eq ; Turn off tracing if cpu is disabled
1185 ; At this point, we can take another exception and lose nothing.
1189 mfspr r26,pmc1 ; INSTRUMENT - saveinstr[2] - Take stamp after save is done
1190 stw r26,0x6100+(0x02*16)+0x0(0) ; INSTRUMENT - Save it
1191 mfspr r26,pmc2 ; INSTRUMENT - Get stamp
1192 stw r26,0x6100+(0x02*16)+0x4(0) ; INSTRUMENT - Save it
1193 mfspr r26,pmc3 ; INSTRUMENT - Get stamp
1194 stw r26,0x6100+(0x02*16)+0x8(0) ; INSTRUMENT - Save it
1195 mfspr r26,pmc4 ; INSTRUMENT - Get stamp
1196 stw r26,0x6100+(0x02*16)+0xC(0) ; INSTRUMENT - Save it
1199 bne+ cr5,xcp32xit ; Skip all of this if no tracing here...
1202 ; We select a trace entry using a compare and swap on the next entry field.
1203 ; Since we do not lock the actual trace buffer, there is a potential that
1204 ; another processor could wrap an trash our entry. Who cares?
1207 lwz r25,traceStart(0) ; Get the start of trace table
1208 lwz r26,traceEnd(0) ; Get end of trace table
1210 trcsel: lwarx r20,0,r23 ; Get and reserve the next slot to allocate
1212 addi r22,r20,LTR_size ; Point to the next trace entry
1213 cmplw r22,r26 ; Do we need to wrap the trace table?
1214 bne+ gotTrcEnt ; No wrap, we got us a trace entry...
1216 mr r22,r25 ; Wrap back to start
1218 gotTrcEnt: stwcx. r22,0,r23 ; Try to update the current pointer
1219 bne- trcsel ; Collision, try again...
1222 dcbf 0,r23 ; Force to memory
1226 dcbz 0,r20 ; Clear and allocate first trace line
1229 ; Let us cut that trace entry now.
1232 lwz r16,ruptStamp(r2) ; Get top of time base
1233 lwz r17,ruptStamp+4(r2) ; Get the bottom of time stamp
1235 li r14,32 ; Offset to second line
1237 lwz r0,saver0+4(r13) ; Get back interrupt time R0
1238 lwz r1,saver1+4(r13) ; Get back interrupt time R1
1239 lwz r8,savecr(r13) ; Get the CR value
1241 dcbz r14,r20 ; Zap the second line
1243 sth r19,LTR_cpu(r20) ; Stash the cpu number
1244 li r14,64 ; Offset to third line
1245 sth r11,LTR_excpt(r20) ; Save the exception type
1246 lwz r7,saver2+4(r13) ; Get back interrupt time R2
1247 lwz r3,saver3+4(r13) ; Restore this one
1249 dcbz r14,r20 ; Zap the third half
1251 mfdsisr r9 ; Get the DSISR
1252 li r14,96 ; Offset to forth line
1253 stw r16,LTR_timeHi(r20) ; Set the upper part of TB
1254 stw r17,LTR_timeLo(r20) ; Set the lower part of TB
1255 lwz r10,savelr+4(r13) ; Get the LR
1256 mfsrr0 r17 ; Get SRR0 back, it is still good
1258 dcbz r14,r20 ; Zap the forth half
1259 lwz r4,saver4+4(r13) ; Restore this one
1260 lwz r5,saver5+4(r13) ; Restore this one
1261 mfsrr1 r18 ; SRR1 is still good in here
1263 stw r8,LTR_cr(r20) ; Save the CR
1264 lwz r6,saver6+4(r13) ; Get R6
1265 mfdar r16 ; Get this back
1266 stw r9,LTR_dsisr(r20) ; Save the DSISR
1267 stw r17,LTR_srr0+4(r20) ; Save the SSR0
1269 stw r18,LTR_srr1+4(r20) ; Save the SRR1
1270 stw r16,LTR_dar+4(r20) ; Save the DAR
1271 mfctr r17 ; Get the CTR (still good in register)
1272 stw r13,LTR_save+4(r20) ; Save the savearea
1273 stw r10,LTR_lr+4(r20) ; Save the LR
1275 stw r17,LTR_ctr+4(r20) ; Save off the CTR
1276 stw r0,LTR_r0+4(r20) ; Save off register 0
1277 stw r1,LTR_r1+4(r20) ; Save off register 1
1278 stw r7,LTR_r2+4(r20) ; Save off register 2
1281 stw r3,LTR_r3+4(r20) ; Save off register 3
1282 stw r4,LTR_r4+4(r20) ; Save off register 4
1283 stw r5,LTR_r5+4(r20) ; Save off register 5
1284 stw r6,LTR_r6+4(r20) ; Save off register 6
1287 addi r17,r20,32 ; Second line
1288 addi r16,r20,64 ; Third line
1289 dcbst br0,r20 ; Force to memory
1290 dcbst br0,r17 ; Force to memory
1291 addi r17,r17,32 ; Fourth line
1292 dcbst br0,r16 ; Force to memory
1293 dcbst br0,r17 ; Force to memory
1295 sync ; Make sure it all goes
1297 xcp32xit: mr r14,r11 ; Save the interrupt code across the call
1298 bl EXT(save_get_phys_32) ; Grab a savearea
1299 mfsprg r2,0 ; Get the per_proc info
1300 li r10,emfp0 ; Point to floating point save
1301 mr r11,r14 ; Get the exception code back
1302 dcbz r10,r2 ; Clear for speed
1303 stw r3,next_savearea+4(r2) ; Store the savearea for the next rupt
1306 mfspr r4,pmc1 ; INSTRUMENT - saveinstr[3] - Take stamp after next savearea
1307 stw r4,0x6100+(0x03*16)+0x0(0) ; INSTRUMENT - Save it
1308 mfspr r4,pmc2 ; INSTRUMENT - Get stamp
1309 stw r4,0x6100+(0x03*16)+0x4(0) ; INSTRUMENT - Save it
1310 mfspr r4,pmc3 ; INSTRUMENT - Get stamp
1311 stw r4,0x6100+(0x03*16)+0x8(0) ; INSTRUMENT - Save it
1312 mfspr r4,pmc4 ; INSTRUMENT - Get stamp
1313 stw r4,0x6100+(0x03*16)+0xC(0) ; INSTRUMENT - Save it
1315 b xcpCommon ; Go join the common interrupt processing...
1319 ; This is the 64-bit context saving stuff
1324 extEntry64: mfsprg r13,0 ; Load per_proc
1325 ld r13,next_savearea(r13) ; Get the exception save area
1326 std r0,saver0(r13) ; Save register 0
1327 lis r0,hi16(MASK(MSR_VEC)|MASK(MSR_FP)|MASK(MSR_ME)) ; Set up the MSR we will use throughout. Note that ME come on here if MCK
1328 std r1,saver1(r13) ; Save register 1
1329 ori r1,r0,lo16(MASK(MSR_VEC)|MASK(MSR_FP)|MASK(MSR_ME)) ; Rest of MSR
1330 lis r0,0x0010 ; Get rupt code transform validity mask
1334 ori r0,r0,0x0200 ; Get rupt code transform validity mask
1335 std r2,saver2(r13) ; Save this one
1336 lis r1,0x00F0 ; Top half of xform XOR
1337 rlwinm r2,r11,29,27,31 ; Get high 5 bits of rupt code
1338 std r3,saver3(r13) ; Save this one
1339 slw r0,r0,r2 ; Move transform validity bit to bit 0
1340 std r4,saver4(r13) ; Save this one
1341 std r5,saver5(r13) ; Save this one
1342 ori r1,r1,0x04EC ; Bottom half of xform XOR
1343 mfxer r5 ; Save the XER because we are about to muck with it
1344 rlwinm r4,r11,1,27,28 ; Get bottom of interrupt code * 8
1345 lis r3,hi16(dozem|napm) ; Get the nap and doze bits
1346 srawi r0,r0,31 ; Get 0xFFFFFFFF of xform valid, 0 otherwise
1347 rlwnm r4,r1,r4,24,31 ; Extract the xform XOR
1348 li r1,saver16 ; Point to the next line
1349 and r4,r4,r0 ; Only keep transform if we are to use it
1350 li r2,lgKillResv ; Point to the killing field
1351 mfcr r0 ; Save the CR
1352 stwcx. r2,0,r2 ; Kill any pending reservation
1353 dcbz128 r1,r13 ; Blow away the line
1354 sldi r3,r3,32 ; Position it
1355 mfspr r1,hid0 ; Get HID0
1356 andc r3,r1,r3 ; Clear nap and doze
1357 xor r11,r11,r4 ; Transform 970 rupt code to standard keeping FAM bit
1358 cmpld r3,r1 ; See if nap and/or doze was on
1359 std r6,saver6(r13) ; Save this one
1360 mfsprg r2,0 ; Get the per_proc area
1361 la r6,savesrr0(r13) ; point to line with SRR0, SRR1, CR, XER, and LR
1362 beq++ eE64NoNap ; No nap here, skip all this...
1364 sync ; Make sure we are clean
1365 mtspr hid0,r3 ; Set the updated hid0
1366 mfspr r1,hid0 ; Yes, this is silly, keep it here
1367 mfspr r1,hid0 ; Yes, this is a duplicate, keep it here
1368 mfspr r1,hid0 ; Yes, this is a duplicate, keep it here
1369 mfspr r1,hid0 ; Yes, this is a duplicate, keep it here
1370 mfspr r1,hid0 ; Yes, this is a duplicate, keep it here
1371 mfspr r1,hid0 ; Yes, this is a duplicate, keep it here
1373 eE64NoNap: crnot wasNapping,cr0_eq ; Remember if we were napping
1374 andi. r1,r11,T_FAM ; Check FAM bit
1375 beq++ eEnoFAM ; Is it FAM intercept
1376 mfsrr1 r3 ; Load srr1
1377 andc r11,r11,r1 ; Clear FAM bit
1378 rlwinm. r3,r3,0,MSR_PR_BIT,MSR_PR_BIT ; Are we trapping from supervisor state?
1379 beq++ eEnoFAM ; From supervisor state
1380 lwz r1,spcFlags(r2) ; Load spcFlags
1381 rlwinm r1,r1,1+FamVMmodebit,30,31 ; Extract FamVMenabit and FamVMmodebit
1382 cmpwi cr0,r1,2 ; Check FamVMena set without FamVMmode
1383 bne++ eEnoFAM ; Can this context be FAM intercept
1384 lwz r4,FAMintercept(r2) ; Load exceptions mask to intercept
1386 srwi r1,r11,2 ; divide r11 by 4
1387 oris r3,r3,0x8000 ; Set r3 to 0x80000000
1388 srw r1,r3,r1 ; Set bit for current exception
1389 and. r1,r1,r4 ; And current exception with the intercept mask
1390 beq++ eEnoFAM ; Is it FAM intercept
1395 eEnoFAM: lwz r1,pfAvailable(r2) ; Get the CPU features flags
1396 dcbz128 0,r6 ; allocate 128-byte line with SRR0, SRR1, CR, XER, and LR
1399 ; Remember, we are setting up CR6 with feature flags
1401 std r7,saver7(r13) ; Save this one
1402 mtcrf 0x80,r1 ; Put the features flags (that we care about) in the CR
1403 std r8,saver8(r13) ; Save this one
1404 mtcrf 0x40,r1 ; Put the features flags (that we care about) in the CR
1405 mfsrr0 r6 ; Get the interruption SRR0
1406 lhz r8,PP_CPU_FLAGS(r2) ; Get the flags
1407 mtcrf 0x20,r1 ; Put the features flags (that we care about) in the CR
1408 mfsrr1 r7 ; Get the interrupt SRR1
1409 rlwinm r8,r8,(((31-MSR_BE_BIT)+(traceBEb+16+1))&31),MSR_BE_BIT,MSR_BE_BIT ; Set BE bit if special trace is on
1410 std r6,savesrr0(r13) ; Save the SRR0
1411 mtcrf 0x02,r1 ; Put the features flags (that we care about) in the CR
1412 rlwinm r6,r7,(((31-MSR_BE_BIT)+(MSR_PR_BIT+1))&31),MSR_BE_BIT,MSR_BE_BIT ; Move PR bit to BE bit
1413 and r8,r6,r8 ; Remove BE bit only if problem state and special tracing on
1414 std r9,saver9(r13) ; Save this one
1415 andc r7,r7,r8 ; Clear BE bit if special trace is on and PR is set
1416 crmove featAltivec,pfAltivecb ; Set the Altivec flag
1417 std r7,savesrr1(r13) ; Save SRR1
1418 mfsprg r9,3 ; Get rupt time R11
1419 std r10,saver10(r13) ; Save this one
1420 mfsprg r6,2 ; Get interrupt time R13
1421 std r9,saver11(r13) ; Save rupt time R11
1422 mtsprg 2,r1 ; Set the feature flags
1423 std r12,saver12(r13) ; Save this one
1424 mflr r4 ; Get the LR
1425 mftb r7 ; Get the timebase
1426 std r6,saver13(r13) ; Save rupt R13
1427 std r7,ruptStamp(r2) ; Save the time stamp
1428 std r7,SAVtime(r13) ; Save the time stamp
1430 bf++ wasNapping,notNappingSF ; Skip if not waking up from nap...
1432 ld r6,napStamp(r2) ; Pick up nap stamp
1433 lis r3,hi16(EXT(machine_idle_ret)) ; Get high part of nap/doze return
1434 sub r7,r7,r6 ; Subtract stamp from now
1435 ld r6,napTotal(r2) ; Pick up total
1436 add r6,r6,r7 ; Add low to total
1437 ori r3,r3,lo16(EXT(machine_idle_ret)) ; Get low part of nap/doze return
1438 std r6,napTotal(r2) ; Save the high total
1439 std r3,savesrr0(r13) ; Modify to return to nap/doze exit
1442 std r14,saver14(r13) ; Save this one
1443 std r15,saver15(r13) ; Save this one
1444 stw r0,savecr(r13) ; Save rupt CR
1445 mfctr r6 ; Get the CTR
1446 std r16,saver16(r13) ; Save this one
1447 std r4,savelr(r13) ; Save rupt LR
1449 std r17,saver17(r13) ; Save this one
1450 li r7,savepmc ; Point to pmc area
1451 std r18,saver18(r13) ; Save this one
1452 lwz r17,spcFlags(r2) ; Get the special flags from per_proc
1453 std r6,savectr(r13) ; Save rupt CTR
1454 std r19,saver19(r13) ; Save this one
1455 mfdar r6 ; Get the rupt DAR
1456 std r20,saver20(r13) ; Save this one
1458 dcbz128 r7,r13 ; Clear out the pmc spot
1460 std r21,saver21(r13) ; Save this one
1461 std r5,savexer(r13) ; Save the rupt XER
1462 std r22,saver22(r13) ; Save this one
1463 std r23,saver23(r13) ; Save this one
1464 std r24,saver24(r13) ; Save this one
1465 std r25,saver25(r13) ; Save this one
1466 mfdsisr r7 ; Get the rupt DSISR
1467 std r26,saver26(r13) ; Save this one
1468 andis. r17,r17,hi16(perfMonitor) ; Is the performance monitor enabled?
1469 std r27,saver27(r13) ; Save this one
1470 li r10,emfp0 ; Point to floating point save
1471 std r28,saver28(r13) ; Save this one
1472 la r27,savevscr(r13) ; point to 32-byte line with VSCR and FPSCR
1473 std r29,saver29(r13) ; Save R29
1474 std r30,saver30(r13) ; Save this one
1475 std r31,saver31(r13) ; Save this one
1476 std r6,savedar(r13) ; Save the rupt DAR
1477 stw r7,savedsisr(r13) ; Save the rupt code DSISR
1478 stw r11,saveexception(r13) ; Save the exception code
1480 beq++ noPerfMonSave64 ; Performance monitor not on...
1482 li r22,0 ; r22: zero
1487 std r23,savemmcr0(r13) ; Save MMCR0
1488 std r24,savemmcr1(r13) ; Save MMCR1
1489 std r25,savemmcr2(r13) ; Save MMCRA
1490 mtspr mmcr0_gp,r22 ; Leave MMCR0 clear
1491 mtspr mmcr1_gp,r22 ; Leave MMCR1 clear
1492 mtspr mmcra_gp,r22 ; Leave MMCRA clear
1497 stw r23,savepmc+0(r13) ; Save PMC1
1498 stw r24,savepmc+4(r13) ; Save PMC2
1499 stw r25,savepmc+8(r13) ; Save PMC3
1500 stw r26,savepmc+12(r13) ; Save PMC4
1505 stw r23,savepmc+16(r13) ; Save PMC5
1506 stw r24,savepmc+20(r13) ; Save PMC6
1507 stw r25,savepmc+24(r13) ; Save PMC7
1508 stw r26,savepmc+28(r13) ; Save PMC8
1509 mtspr pmc1_gp,r22 ; Leave PMC1 clear
1510 mtspr pmc2_gp,r22 ; Leave PMC2 clear
1511 mtspr pmc3_gp,r22 ; Leave PMC3 clear
1512 mtspr pmc4_gp,r22 ; Leave PMC4 clear
1513 mtspr pmc5_gp,r22 ; Leave PMC5 clear
1514 mtspr pmc6_gp,r22 ; Leave PMC6 clear
1515 mtspr pmc7_gp,r22 ; Leave PMC7 clear
1516 mtspr pmc8_gp,r22 ; Leave PMC8 clear
1521 ; Everything is saved at this point, except for FPRs, and VMX registers.
1522 ; Time for us to get a new savearea and then trace interrupt if it is enabled.
1525 lwz r25,traceMask(0) ; Get the trace mask
1526 li r0,SAVgeneral ; Get the savearea type value
1527 lhz r19,PP_CPU_NUMBER(r2) ; Get the logical processor number
1528 stb r0,SAVflags+2(r13) ; Mark valid context
1529 rlwinm r22,r11,30,0,31 ; Divide interrupt code by 2
1530 li r23,trcWork ; Get the trace work area address
1531 addi r22,r22,10 ; Adjust code so we shift into CR5
1532 li r26,0x8 ; Get start of cpu mask
1533 rlwnm r7,r25,r22,22,22 ; Set CR5_EQ bit position to 0 if tracing allowed
1534 srw r26,r26,r19 ; Get bit position of cpu number
1535 mtcrf 0x04,r7 ; Set CR5 to show trace or not
1536 and. r26,r26,r25 ; See if we trace this cpu
1537 crandc cr5_eq,cr5_eq,cr0_eq ; Turn off tracing if cpu is disabled
1539 bne++ cr5,xcp64xit ; Skip all of this if no tracing here...
1542 ; We select a trace entry using a compare and swap on the next entry field.
1543 ; Since we do not lock the actual trace buffer, there is a potential that
1544 ; another processor could wrap an trash our entry. Who cares?
1547 lwz r25,traceStart(0) ; Get the start of trace table
1548 lwz r26,traceEnd(0) ; Get end of trace table
1550 trcselSF: lwarx r20,0,r23 ; Get and reserve the next slot to allocate
1552 addi r22,r20,LTR_size ; Point to the next trace entry
1553 cmplw r22,r26 ; Do we need to wrap the trace table?
1554 bne+ gotTrcEntSF ; No wrap, we got us a trace entry...
1556 mr r22,r25 ; Wrap back to start
1559 stwcx. r22,0,r23 ; Try to update the current pointer
1560 bne- trcselSF ; Collision, try again...
1563 dcbf 0,r23 ; Force to memory
1568 ; Let us cut that trace entry now.
1571 dcbz128 0,r20 ; Zap the trace entry
1573 lwz r9,SAVflags(r13) ; Get savearea flags
1575 ld r16,ruptStamp(r2) ; Get top of time base
1576 ld r0,saver0(r13) ; Get back interrupt time R0 (we need this whether we trace or not)
1577 std r16,LTR_timeHi(r20) ; Set the upper part of TB
1578 ld r1,saver1(r13) ; Get back interrupt time R1
1579 rlwinm r9,r9,20,16,23 ; Isolate the special flags
1580 ld r18,saver2(r13) ; Get back interrupt time R2
1581 std r0,LTR_r0(r20) ; Save off register 0
1582 rlwimi r9,r19,0,24,31 ; Slide in the cpu number
1583 ld r3,saver3(r13) ; Restore this one
1584 sth r9,LTR_cpu(r20) ; Stash the cpu number and special flags
1585 std r1,LTR_r1(r20) ; Save off register 1
1586 ld r4,saver4(r13) ; Restore this one
1587 std r18,LTR_r2(r20) ; Save off register 2
1588 ld r5,saver5(r13) ; Restore this one
1589 ld r6,saver6(r13) ; Get R6
1590 std r3,LTR_r3(r20) ; Save off register 3
1591 lwz r16,savecr(r13) ; Get the CR value
1592 std r4,LTR_r4(r20) ; Save off register 4
1593 mfsrr0 r17 ; Get SRR0 back, it is still good
1594 std r5,LTR_r5(r20) ; Save off register 5
1595 std r6,LTR_r6(r20) ; Save off register 6
1596 mfsrr1 r18 ; SRR1 is still good in here
1597 stw r16,LTR_cr(r20) ; Save the CR
1598 std r17,LTR_srr0(r20) ; Save the SSR0
1599 std r18,LTR_srr1(r20) ; Save the SRR1
1601 mfdar r17 ; Get this back
1602 ld r16,savelr(r13) ; Get the LR
1603 std r17,LTR_dar(r20) ; Save the DAR
1604 mfctr r17 ; Get the CTR (still good in register)
1605 std r16,LTR_lr(r20) ; Save the LR
1606 std r17,LTR_ctr(r20) ; Save off the CTR
1607 mfdsisr r17 ; Get the DSISR
1608 std r13,LTR_save(r20) ; Save the savearea
1609 stw r17,LTR_dsisr(r20) ; Save the DSISR
1610 sth r11,LTR_excpt(r20) ; Save the exception type
1613 dcbf 0,r20 ; Force to memory
1614 sync ; Make sure it all goes
1616 xcp64xit: mr r14,r11 ; Save the interrupt code across the call
1617 bl EXT(save_get_phys_64) ; Grab a savearea
1618 mfsprg r2,0 ; Get the per_proc info
1619 li r10,emfp0 ; Point to floating point save
1620 mr r11,r14 ; Get the exception code back
1621 dcbz128 r10,r2 ; Clear for speed
1622 std r3,next_savearea(r2) ; Store the savearea for the next rupt
1623 b xcpCommon ; Go join the common interrupt processing...
1626 ; All of the context is saved. Now we will get a
1627 ; fresh savearea. After this we can take an interrupt.
1635 ; Here we will save some floating point and vector status
1636 ; and we also set a clean default status for a new interrupt level.
1637 ; Note that we assume that emfp0 is on an altivec boundary
1638 ; and that R10 points to it (as a displacemnt from R2).
1640 ; We need to save the FPSCR as if it is normal context.
1641 ; This is because pending exceptions will cause an exception even if
1642 ; FP is disabled. We need to clear the FPSCR when we first start running in the
1646 stfd f0,emfp0(r2) ; Save FPR0
1647 stfd f1,emfp1(r2) ; Save FPR1
1648 li r19,0 ; Assume no Altivec
1649 mffs f0 ; Get the FPSCR
1650 lfd f1,Zero(0) ; Make a 0
1651 stfd f0,savefpscrpad(r13) ; Save the FPSCR
1652 li r9,0 ; Get set to clear VRSAVE
1653 mtfsf 0xFF,f1 ; Clear it
1654 addi r14,r10,16 ; Displacement to second vector register
1655 lfd f0,emfp0(r2) ; Restore FPR0
1656 la r28,savevscr(r13) ; Point to the status area
1657 lfd f1,emfp1(r2) ; Restore FPR1
1659 bf featAltivec,noavec ; No Altivec on this CPU...
1661 stvxl v0,r10,r2 ; Save a register
1662 stvxl v1,r14,r2 ; Save a second register
1663 mfspr r19,vrsave ; Get the VRSAVE register
1664 mfvscr v0 ; Get the vector status register
1665 vspltish v1,1 ; Turn on the non-Java bit and saturate
1666 stvxl v0,0,r28 ; Save the vector status
1667 vspltisw v0,1 ; Turn on the saturate bit
1668 vxor v1,v1,v0 ; Turn off saturate
1669 mtvscr v1 ; Set the non-java, no saturate status for new level
1670 mtspr vrsave,r9 ; Clear VRSAVE for each interrupt level
1672 lvxl v0,r10,r2 ; Restore first work register
1673 lvxl v1,r14,r2 ; Restore second work register
1675 noavec: stw r19,savevrsave(r13) ; Save the vector register usage flags
1678 ; We are now done saving all of the context. Start filtering the interrupts.
1679 ; Note that a Redrive will count as an actual interrupt.
1680 ; Note also that we take a lot of system calls so we will start decode here.
1687 mfspr r20,pmc1 ; INSTRUMENT - saveinstr[4] - Take stamp before exception filter
1688 stw r20,0x6100+(0x04*16)+0x0(0) ; INSTRUMENT - Save it
1689 mfspr r20,pmc2 ; INSTRUMENT - Get stamp
1690 stw r20,0x6100+(0x04*16)+0x4(0) ; INSTRUMENT - Save it
1691 mfspr r20,pmc3 ; INSTRUMENT - Get stamp
1692 stw r20,0x6100+(0x04*16)+0x8(0) ; INSTRUMENT - Save it
1693 mfspr r20,pmc4 ; INSTRUMENT - Get stamp
1694 stw r20,0x6100+(0x04*16)+0xC(0) ; INSTRUMENT - Save it
1696 lwz r22,SAVflags(r13) ; Pick up the flags
1697 lwz r0,saver0+4(r13) ; Get back interrupt time syscall number
1698 mfsprg r2,0 ; Restore per_proc
1700 lwz r20,lo16(xcpTable)(r11) ; Get the interrupt handler (note: xcpTable must be in 1st 32k of physical memory)
1701 la r12,hwCounts(r2) ; Point to the exception count area
1702 andis. r24,r22,hi16(SAVeat) ; Should we eat this one?
1703 rlwinm r22,r22,SAVredriveb+1,31,31 ; Get a 1 if we are redriving
1704 add r12,r12,r11 ; Point to the count
1705 lwz r25,0(r12) ; Get the old value
1706 lwz r23,hwRedrives(r2) ; Get the redrive count
1707 crmove cr3_eq,cr0_eq ; Remember if we are ignoring
1708 xori r24,r22,1 ; Get the NOT of the redrive
1709 mtctr r20 ; Point to the interrupt handler
1710 mtcrf 0x80,r0 ; Set our CR0 to the high nybble of possible syscall code
1711 add r25,r25,r24 ; Count this one if not a redrive
1712 add r23,r23,r22 ; Count this one if if is a redrive
1713 crandc cr0_lt,cr0_lt,cr0_gt ; See if we have R0 equal to 0b10xx...x
1714 stw r25,0(r12) ; Store it back
1715 stw r23,hwRedrives(r2) ; Save the redrive count
1716 bne-- cr3,IgnoreRupt ; Interruption is being ignored...
1717 bctr ; Go process the exception...
1721 ; Exception vector filter table (like everything in this file, must be in 1st 32KB of physical memory)
1727 .long EatRupt ; T_IN_VAIN
1728 .long PassUpTrap ; T_RESET
1729 .long MachineCheck ; T_MACHINE_CHECK
1730 .long EXT(handlePF) ; T_DATA_ACCESS
1731 .long EXT(handlePF) ; T_INSTRUCTION_ACCESS
1732 .long PassUpRupt ; T_INTERRUPT
1733 .long EXT(AlignAssist) ; T_ALIGNMENT
1734 .long EXT(Emulate) ; T_PROGRAM
1735 .long PassUpFPU ; T_FP_UNAVAILABLE
1736 .long PassUpRupt ; T_DECREMENTER
1737 .long PassUpTrap ; T_IO_ERROR
1738 .long PassUpTrap ; T_RESERVED
1739 .long xcpSyscall ; T_SYSTEM_CALL
1740 .long PassUpTrap ; T_TRACE
1741 .long PassUpTrap ; T_FP_ASSIST
1742 .long PassUpTrap ; T_PERF_MON
1743 .long PassUpVMX ; T_VMX
1744 .long PassUpTrap ; T_INVALID_EXCP0
1745 .long PassUpTrap ; T_INVALID_EXCP1
1746 .long PassUpTrap ; T_INVALID_EXCP2
1747 .long PassUpTrap ; T_INSTRUCTION_BKPT
1748 .long PassUpRupt ; T_SYSTEM_MANAGEMENT
1749 .long EXT(AltivecAssist) ; T_ALTIVEC_ASSIST
1750 .long PassUpRupt ; T_THERMAL
1751 .long PassUpTrap ; T_INVALID_EXCP5
1752 .long PassUpTrap ; T_INVALID_EXCP6
1753 .long PassUpTrap ; T_INVALID_EXCP7
1754 .long PassUpTrap ; T_INVALID_EXCP8
1755 .long PassUpTrap ; T_INVALID_EXCP9
1756 .long PassUpTrap ; T_INVALID_EXCP10
1757 .long PassUpTrap ; T_INVALID_EXCP11
1758 .long PassUpTrap ; T_INVALID_EXCP12
1759 .long PassUpTrap ; T_INVALID_EXCP13
1761 .long PassUpTrap ; T_RUNMODE_TRACE
1763 .long PassUpRupt ; T_SIGP
1764 .long PassUpTrap ; T_PREEMPT
1765 .long conswtch ; T_CSWITCH
1766 .long PassUpRupt ; T_SHUTDOWN
1767 .long PassUpAbend ; T_CHOKE
1769 .long EXT(handleDSeg) ; T_DATA_SEGMENT
1770 .long EXT(handleISeg) ; T_INSTRUCTION_SEGMENT
1772 .long WhoaBaby ; T_SOFT_PATCH
1773 .long WhoaBaby ; T_MAINTENANCE
1774 .long WhoaBaby ; T_INSTRUMENTATION
1775 .long WhoaBaby ; T_ARCHDEP0
1776 .long EatRupt ; T_HDEC
1778 ; Just what the heck happened here????
1779 ; NB: also get here from UFT dispatch table, on bogus index
1782 WhoaBaby: b . ; Open the hood and wait for help
1787 lwz r20,hwIgnored(r2) ; Grab the ignored interruption count
1788 addi r20,r20,1 ; Count this one
1789 stw r20,hwIgnored(r2) ; Save the ignored count
1790 b EatRupt ; Ignore it...
1800 xcpSyscall: lis r20,hi16(EXT(shandler)) ; Assume this is a normal one, get handler address
1801 rlwinm r6,r0,1,0,31 ; Move sign bit to the end
1802 ori r20,r20,lo16(EXT(shandler)) ; Assume this is a normal one, get handler address
1803 bnl++ cr0,PassUp ; R0 not 0b10xxx...x, can not be any kind of magical system call, just pass it up...
1804 lwz r7,savesrr1+4(r13) ; Get the entering MSR (low half)
1805 lwz r1,dgFlags(0) ; Get the flags
1806 cmplwi cr2,r6,1 ; See if original R0 had the CutTrace request code in it
1808 rlwinm. r7,r7,0,MSR_PR_BIT,MSR_PR_BIT ; Did we come from user state?
1809 beq++ FCisok ; From supervisor state...
1811 rlwinm. r1,r1,0,enaUsrFCallb,enaUsrFCallb ; Are they valid?
1812 beq++ PassUp ; No, treat as a normal one...
1814 FCisok: beq++ cr2,EatRupt ; This is a CutTrace system call, we are done with it...
1817 ; Here is where we call the firmware. If it returns T_IN_VAIN, that means
1818 ; that it has handled the interruption. Remember: thou shalt not trash R13
1819 ; while you are away. Anything else is ok.
1822 lwz r3,saver3+4(r13) ; Restore the first parameter
1823 b EXT(FirmwareCall) ; Go handle the firmware call....
1826 ; Here is where we return from the firmware call
1830 .globl EXT(FCReturn)
1833 cmplwi r3,T_IN_VAIN ; Was it handled?
1834 beq++ EatRupt ; Interrupt was handled...
1835 mr r11,r3 ; Put the rupt code into the right register
1836 b Redrive ; Go through the filter again...
1840 ; Here is where we return from the PTE miss and segment exception handler
1849 mfsprg r2,0 ; (BRINGUP)
1850 lwz r0,savedsisr(r13) ; (BRINGUP)
1851 andis. r0,r0,hi16(dsiAC) ; (BRINGUP)
1852 beq++ didnthit ; (BRINGUP)
1853 lwz r0,20(0) ; (BRINGUP)
1854 mr. r0,r0 ; (BRINGUP)
1855 bne-- didnthit ; (BRINGUP)
1858 stw r0,20(0) ; (BRINGUP)
1859 lis r0,hi16(Choke) ; (BRINGUP)
1860 ori r0,r0,lo16(Choke) ; (BRINGUP)
1864 lwz r4,savesrr0+4(r13) ; (BRINGUP)
1865 lwz r8,savesrr1+4(r13) ; (BRINGUP)
1866 lwz r6,savedar+4(r13) ; (BRINGUP)
1867 rlwinm. r0,r8,0,MSR_IR_BIT,MSR_IR_BIT ; (BRINGUP)
1868 mfmsr r9 ; (BRINGUP)
1869 ori r0,r9,lo16(MASK(MSR_DR)) ; (BRINGUP)
1870 beq-- hghg ; (BRINGUP)
1871 mtmsr r0 ; (BRINGUP)
1874 hghg: lwz r5,0(r4) ; (BRINGUP)
1875 beq-- hghg1 ; (BRINGUP)
1876 mtmsr r9 ; (BRINGUP)
1879 hghg1: rlwinm r7,r5,6,26,31 ; (BRINGUP)
1880 rlwinm r27,r5,14,24,28 ; (BRINGUP)
1881 addi r3,r13,saver0+4 ; (BRINGUP)
1882 lwzx r3,r3,r27 ; (BRINGUP)
1885 lwz r27,patcharea+4(r2) ; (BRINGUP)
1886 mr. r3,r3 ; (BRINGUP)
1887 bne++ nbnbnb ; (BRINGUP)
1888 addi r27,r27,1 ; (BRINGUP)
1889 stw r27,patcharea+4(r2) ; (BRINGUP)
1893 rlwinm. r28,r8,0,MSR_DR_BIT,MSR_DR_BIT ; (BRINGUP)
1894 rlwinm r27,r6,0,0,29 ; (BRINGUP)
1895 ori r28,r9,lo16(MASK(MSR_DR)) ; (BRINGUP)
1896 mfspr r10,dabr ; (BRINGUP)
1898 mtspr dabr,r0 ; (BRINGUP)
1899 cmplwi cr1,r7,31 ; (BRINGUP)
1900 beq-- qqq0 ; (BRINGUP)
1901 mtmsr r28 ; (BRINGUP)
1905 lwz r27,0(r27) ; (BRINGUP) - Get original value
1907 bne cr1,qqq1 ; (BRINGUP)
1909 rlwinm r5,r5,31,22,31 ; (BRINGUP)
1910 cmplwi cr1,r5,151 ; (BRINGUP)
1911 beq cr1,qqq3 ; (BRINGUP)
1912 cmplwi cr1,r5,407 ; (BRINGUP)
1913 beq cr1,qqq2 ; (BRINGUP)
1914 cmplwi cr1,r5,215 ; (BRINGUP)
1915 beq cr1,qqq0q ; (BRINGUP)
1916 cmplwi cr1,r5,1014 ; (BRINGUP)
1917 beq cr1,qqqm1 ; (BRINGUP)
1919 lis r0,hi16(Choke) ; (BRINGUP)
1920 ori r0,r0,lo16(Choke) ; (BRINGUP)
1923 qqqm1: rlwinm r7,r6,0,0,26 ; (BRINGUP)
1924 stw r0,0(r7) ; (BRINGUP)
1925 stw r0,4(r7) ; (BRINGUP)
1926 stw r0,8(r7) ; (BRINGUP)
1927 stw r0,12(r7) ; (BRINGUP)
1928 stw r0,16(r7) ; (BRINGUP)
1929 stw r0,20(r7) ; (BRINGUP)
1930 stw r0,24(r7) ; (BRINGUP)
1931 stw r0,28(r7) ; (BRINGUP)
1934 qqq1: cmplwi r7,38 ; (BRINGUP)
1935 bgt qqq2 ; (BRINGUP)
1936 blt qqq3 ; (BRINGUP)
1938 qqq0q: stb r3,0(r6) ; (BRINGUP)
1941 qqq2: sth r3,0(r6) ; (BRINGUP)
1944 qqq3: stw r3,0(r6) ; (BRINGUP)
1948 rlwinm r7,r6,0,0,29 ; (BRINGUP)
1949 lwz r0,0(r7) ; (BRINGUP) - Get newest value
1951 lis r7,hi16(0x000792B8) ; (BRINGUP)
1952 ori r7,r7,lo16(0x000792B8) ; (BRINGUP)
1953 lwz r0,0(r7) ; (BRINGUP) - Get newest value
1955 mtmsr r9 ; (BRINGUP)
1956 mtspr dabr,r10 ; (BRINGUP)
1960 lwz r28,patcharea+12(r2) ; (BRINGUP)
1961 mr. r28,r28 ; (BRINGUP)
1962 bne++ qqq12 ; (BRINGUP)
1963 lis r28,0x4000 ; (BRINGUP)
1965 qqq12: stw r27,0(r28) ; (BRINGUP)
1966 lwz r6,savedar+4(r13) ; (BRINGUP)
1967 stw r0,4(r28) ; (BRINGUP)
1968 stw r4,8(r28) ; (BRINGUP)
1969 stw r6,12(r28) ; (BRINGUP)
1970 addi r28,r28,16 ; (BRINGUP)
1971 mr. r3,r3 ; (BRINGUP)
1972 stw r28,patcharea+12(r2) ; (BRINGUP)
1973 lwz r10,patcharea+8(r2) ; (BRINGUP)
1974 lwz r0,patcharea+4(r2) ; (BRINGUP)
1978 stw r0,patcharea(r2) ; (BRINGUP)
1982 xor r28,r0,r27 ; (BRINGUP) - See how much it changed
1983 rlwinm r28,r28,24,24,31 ; (BRINGUP)
1984 cmplwi r28,1 ; (BRINGUP)
1986 ble++ qqq10 ; (BRINGUP)
1988 mr r7,r0 ; (BRINGUP)
1990 stw r0,20(0) ; (BRINGUP)
1991 lis r0,hi16(Choke) ; (BRINGUP)
1992 ori r0,r0,lo16(Choke) ; (BRINGUP)
1997 qqq10: addi r4,r4,4 ; (BRINGUP)
1998 stw r4,savesrr0+4(r13) ; (BRINGUP)
2000 li r11,T_IN_VAIN ; (BRINGUP)
2001 b EatRupt ; (BRINGUP)
2003 didnthit: ; (BRINGUP)
2006 lwz r0,20(0) ; (BRINGUP)
2007 mr. r0,r0 ; (BRINGUP)
2008 beq++ opopop ; (BRINGUP)
2010 stw r0,20(0) ; (BRINGUP)
2011 lis r0,hi16(Choke) ; (BRINGUP)
2012 ori r0,r0,lo16(Choke) ; (BRINGUP)
2016 lwz r0,savesrr1+4(r13) ; Get the MSR in use at exception time
2017 cmplwi cr1,r11,T_IN_VAIN ; Was it handled?
2018 rlwinm. r4,r0,0,MSR_PR_BIT,MSR_PR_BIT ; Are we trapping from supervisor state?
2019 beq++ cr1,EatRupt ; Yeah, just blast back to the user...
2021 mfsprg r2,0 ; Get back per_proc
2022 lwz r1,spcFlags(r2) ; Load spcFlags
2023 rlwinm r1,r1,1+FamVMmodebit,30,31 ; Extract FamVMenabit and FamVMmodebit
2024 cmpi cr0,r1,2 ; Check FamVMena set without FamVMmode
2026 lwz r6,FAMintercept(r2) ; Load exceptions mask to intercept
2028 srwi r1,r11,2 ; divide r11 by 4
2029 oris r5,r5,0x8000 ; Set r5 to 0x80000000
2030 srw r1,r5,r1 ; Set bit for current exception
2031 and. r1,r1,r6 ; And current exception with the intercept mask
2032 beq++ NoFamPf ; Is it FAM intercept
2036 NoFamPf: andi. r4,r0,lo16(MASK(MSR_RI)) ; See if the recover bit is on
2037 lis r0,0x8000 ; Get 0xFFFFFFFF80000000
2038 add r0,r0,r0 ; Get 0xFFFFFFFF00000000
2039 beq++ PassUpTrap ; Not on, normal case...
2041 ; Here is where we handle the "recovery mode" stuff.
2042 ; This is set by an emulation routine to trap any faults when it is fetching data or
2045 ; If we get a fault, we turn off RI, set CR0_EQ to false, bump the PC, and set R0
2046 ; and R1 to the DAR and DSISR, respectively.
2048 lwz r3,savesrr0(r13) ; Get the failing instruction address
2049 lwz r4,savesrr0+4(r13) ; Get the failing instruction address
2050 lwz r5,savecr(r13) ; Get the condition register
2051 or r4,r4,r0 ; Fill the high part with foxes
2052 lwz r0,savedar(r13) ; Get the DAR
2053 addic r4,r4,4 ; Skip failing instruction
2054 lwz r6,savedar+4(r13) ; Get the DAR
2055 addze r3,r3 ; Propagate carry
2056 rlwinm r5,r5,0,3,1 ; Clear CR0_EQ to let emulation code know we failed
2057 lwz r7,savedsisr(r13) ; Grab the DSISR
2058 stw r3,savesrr0(r13) ; Save resume address
2059 stw r4,savesrr0+4(r13) ; Save resume address
2060 stw r5,savecr(r13) ; And the resume CR
2061 stw r0,saver0(r13) ; Pass back the DAR
2062 stw r6,saver0+4(r13) ; Pass back the DAR
2063 stw r7,saver1+4(r13) ; Pass back the DSISR
2064 b EatRupt ; Resume emulated code
2067 ; Here is where we handle the context switch firmware call. The old
2068 ; context has been saved. The new savearea is in kind of hokey, the high order
2069 ; half is stored in saver7 and the low half is in saver3. We will just
2070 ; muck around with the savearea pointers, and then join the exit routine
2076 li r0,0xFFF ; Get page boundary
2077 mr r29,r13 ; Save the save
2078 andc r30,r13,r0 ; Round down to page boundary (64-bit safe)
2079 lwz r5,saver3+4(r13) ; Switch to the new savearea
2080 bf-- pf64Bitb,xcswNo64 ; Not 64-bit...
2081 lwz r6,saver7+4(r13) ; Get the high order half
2082 sldi r6,r6,32 ; Position high half
2083 or r5,r5,r6 ; Merge them
2085 xcswNo64: lwz r30,SACvrswap+4(r30) ; get real to virtual translation
2086 mr r13,r5 ; Switch saveareas
2087 li r0,0 ; Clear this
2088 xor r27,r29,r30 ; Flip to virtual
2089 stw r0,saver3(r5) ; Push the new virtual savearea to the switch to routine
2090 stw r27,saver3+4(r5) ; Push the new virtual savearea to the switch to routine
2091 b EatRupt ; Start it up...
2094 ; Handle machine check here.
2103 bt++ pf64Bitb,mck64 ; ?
2105 lwz r27,savesrr1+4(r13) ; Pick up srr1
2108 ; Check if the failure was in
2109 ; ml_probe_read. If so, this is expected, so modify the PC to
2110 ; ml_proble_read_mck and then eat the exception.
2112 lwz r30,savesrr0+4(r13) ; Get the failing PC
2113 lis r28,hi16(EXT(ml_probe_read_mck)) ; High order part
2114 lis r27,hi16(EXT(ml_probe_read)) ; High order part
2115 ori r28,r28,lo16(EXT(ml_probe_read_mck)) ; Get the low part
2116 ori r27,r27,lo16(EXT(ml_probe_read)) ; Get the low part
2117 cmplw r30,r28 ; Check highest possible
2118 cmplw cr1,r30,r27 ; Check lowest
2119 bge- PassUpTrap ; Outside of range
2120 blt- cr1,PassUpTrap ; Outside of range
2122 ; We need to fix up the BATs here because the probe
2123 ; routine messed them all up... As long as we are at it,
2124 ; fix up to return directly to caller of probe.
2127 lis r11,hi16(EXT(shadow_BAT)+shdDBAT) ; Get shadow address
2128 ori r11,r11,lo16(EXT(shadow_BAT)+shdDBAT) ; Get shadow address
2130 lwz r30,0(r11) ; Pick up DBAT 0 high
2131 lwz r28,4(r11) ; Pick up DBAT 0 low
2132 lwz r27,8(r11) ; Pick up DBAT 1 high
2133 lwz r18,16(r11) ; Pick up DBAT 2 high
2134 lwz r11,24(r11) ; Pick up DBAT 3 high
2137 mtdbatu 0,r30 ; Restore DBAT 0 high
2138 mtdbatl 0,r28 ; Restore DBAT 0 low
2139 mtdbatu 1,r27 ; Restore DBAT 1 high
2140 mtdbatu 2,r18 ; Restore DBAT 2 high
2141 mtdbatu 3,r11 ; Restore DBAT 3 high
2144 lwz r28,savelr+4(r13) ; Get return point
2145 lwz r27,saver0+4(r13) ; Get the saved MSR
2146 li r30,0 ; Get a failure RC
2147 stw r28,savesrr0+4(r13) ; Set the return point
2148 stw r27,savesrr1+4(r13) ; Set the continued MSR
2149 stw r30,saver3+4(r13) ; Set return code
2150 b EatRupt ; Yum, yum, eat it all up...
2153 ; 64-bit machine checks
2159 ; NOTE: WE NEED TO RETHINK RECOVERABILITY A BIT - radar 3167190
2162 ld r23,savesrr0(r13) ; Grab the SRR0 in case we need bad instruction
2163 ld r20,savesrr1(r13) ; Grab the SRR1 so we can decode the thing
2164 lwz r21,savedsisr(r13) ; We might need this in a bit
2165 ld r22,savedar(r13) ; We might need this in a bit
2167 lis r8,AsyMCKSrc ; Get the Async MCK Source register address
2168 mfsprg r19,2 ; Get the feature flags
2169 ori r8,r8,0x8000 ; Set to read data
2170 rlwinm. r0,r19,0,pfSCOMFixUpb,pfSCOMFixUpb ; Do we need to fix the SCOM data?
2174 mtspr scomc,r8 ; Request the MCK source
2175 mfspr r24,scomd ; Get the source
2176 mfspr r8,scomc ; Get back the status (we just ignore it)
2180 lis r8,AsyMCKRSrc ; Get the Async MCK Source AND mask address
2181 li r9,0 ; Get and AND mask of 0
2185 mtspr scomd,r9 ; Set the AND mask to 0
2186 mtspr scomc,r8 ; Write the AND mask and clear conditions
2187 mfspr r8,scomc ; Get back the status (we just ignore it)
2191 lis r8,cFIR ; Get the Core FIR register address
2192 ori r8,r8,0x8000 ; Set to read data
2196 mtspr scomc,r8 ; Request the Core FIR
2197 mfspr r25,scomd ; Get the source
2198 mfspr r8,scomc ; Get back the status (we just ignore it)
2202 lis r8,cFIRrst ; Get the Core FIR AND mask address
2206 mtspr scomd,r9 ; Set the AND mask to 0
2207 mtspr scomc,r8 ; Write the AND mask and clear conditions
2208 mfspr r8,scomc ; Get back the status (we just ignore it)
2212 lis r8,l2FIR ; Get the L2 FIR register address
2213 ori r8,r8,0x8000 ; Set to read data
2217 mtspr scomc,r8 ; Request the L2 FIR
2218 mfspr r26,scomd ; Get the source
2219 mfspr r8,scomc ; Get back the status (we just ignore it)
2223 lis r8,l2FIRrst ; Get the L2 FIR AND mask address
2227 mtspr scomd,r9 ; Set the AND mask to 0
2228 mtspr scomc,r8 ; Write the AND mask and clear conditions
2229 mfspr r8,scomc ; Get back the status (we just ignore it)
2233 lis r8,busFIR ; Get the Bus FIR register address
2234 ori r8,r8,0x8000 ; Set to read data
2238 mtspr scomc,r8 ; Request the Bus FIR
2239 mfspr r27,scomd ; Get the source
2240 mfspr r8,scomc ; Get back the status (we just ignore it)
2244 lis r8,busFIRrst ; Get the Bus FIR AND mask address
2248 mtspr scomd,r9 ; Set the AND mask to 0
2249 mtspr scomc,r8 ; Write the AND mask and clear conditions
2250 mfspr r8,scomc ; Get back the status (we just ignore it)
2254 ; Note: bug in early chips where scom reads are shifted right by 1. We fix that here.
2255 ; Also note that we will lose bit 63
2257 beq++ mckNoFix ; No fix up is needed
2258 sldi r24,r24,1 ; Shift left 1
2259 sldi r25,r25,1 ; Shift left 1
2260 sldi r26,r26,1 ; Shift left 1
2261 sldi r27,r27,1 ; Shift left 1
2263 mckNoFix: std r24,savexdat0(r13) ; Save the MCK source in case we pass the error
2264 std r25,savexdat1(r13) ; Save the Core FIR in case we pass the error
2265 std r26,savexdat2(r13) ; Save the L2 FIR in case we pass the error
2266 std r27,savexdat3(r13) ; Save the BUS FIR in case we pass the error
2268 rlwinm. r0,r20,0,mckIFUE-32,mckIFUE-32 ; Is this some kind of uncorrectable?
2271 rlwinm. r0,r20,0,mckLDST-32,mckLDST-32 ; Some kind of load/store error?
2272 bne mckHandleLDST ; Yes...
2274 rldicl. r0,r20,46,62 ; Get the error cause code
2275 beq mckNotSure ; We need some more checks for this one...
2277 cmplwi r0,2 ; Check for TLB parity error
2278 blt mckSLBparity ; This is an SLB parity error...
2279 bgt mckhIFUE ; This is an IFetch tablewalk reload UE...
2281 ; IFetch TLB parity error
2284 tlbiel r23 ; Locally invalidate TLB entry for iaddr
2286 b ceMck ; All recovered...
2288 ; SLB parity error. This could be software caused. We get one if there is
2289 ; more than 1 valid SLBE with a matching ESID. That one we do not want to
2290 ; try to recover from. Search for it and if we get it, panic.
2293 crclr cr0_eq ; Make sure we are not equal so we take correct exit
2295 la r3,emvr0(r2) ; Use this to keep track of valid ESIDs we find
2296 li r5,0 ; Start with index 0
2298 mckSLBck: la r4,emvr0(r2) ; Use this to keep track of valid ESIDs we find
2299 slbmfee r6,r5 ; Get the next SLBE
2300 andis. r0,r6,0x0800 ; See if valid bit is on
2301 beq mckSLBnx ; Skip invalid and go to next
2303 mckSLBck2: cmpld r4,r3 ; Have we reached the end of the table?
2304 beq mckSLBne ; Yes, go enter this one...
2305 ld r7,0(r4) ; Pick up the saved ESID
2306 cmpld r6,r7 ; Is this a match?
2307 beq mckSLBrec ; Whoops, I did bad, recover and pass up...
2308 addi r4,r4,8 ; Next table entry
2309 b mckSLBck2 ; Check the next...
2311 mckSLBnx: addi r5,r5,1 ; Point to next SLBE
2312 cmplwi r5,64 ; Have we checked all of them?
2313 bne++ mckSLBck ; Not yet, check again...
2314 b mckSLBrec ; We looked at them all, go recover...
2316 mckSLBne: std r6,0(r3) ; Save this ESID
2317 addi r3,r3,8 ; Point to the new slot
2318 b mckSLBnx ; Go do the next SLBE...
2320 ; Recover an SLB error
2322 mckSLBrec: li r0,0 ; Set an SLB slot index of 0
2323 slbia ; Trash all SLB entries (except for entry 0 that is)
2324 slbmfee r7,r0 ; Get the entry that is in SLB index 0
2325 rldicr r7,r7,0,35 ; Clear the valid bit and the rest
2326 slbie r7 ; Invalidate it
2328 li r3,0 ; Set the first SLBE
2330 mckSLBclr: slbmte r0,r3 ; Clear the whole entry to 0s
2331 addi r3,r3,1 ; Bump index
2332 cmplwi cr1,r3,64 ; Have we done them all?
2333 bne++ cr1,mckSLBclr ; Yup....
2335 sth r3,ppInvSeg(r2) ; Store non-zero to trigger SLB reload
2336 bne++ ceMck ; This was not a programming error, all recovered...
2337 b ueMck ; Pass the software error up...
2340 ; Handle a load/store unit error. We need to decode the DSISR
2344 rlwinm. r0,r21,0,mckL1DCPE,mckL1DCPE ; An L1 data cache parity error?
2345 bne++ mckL1D ; Yeah, we dealt with this back in the vector...
2347 rlwinm. r0,r21,0,mckL1DTPE,mckL1DTPE ; An L1 tag error?
2348 bne++ mckL1T ; Yeah, we dealt with this back in the vector...
2350 rlwinm. r0,r21,0,mckUEdfr,mckUEdfr ; Is the a "deferred" UE?
2351 bne mckDUE ; Yeah, go see if expected...
2353 rlwinm. r0,r21,0,mckUETwDfr,mckUETwDfr ; Is the a "deferred" tablewalk UE?
2354 bne mckDTW ; Yeah, no recovery...
2356 rlwinm. r0,r21,0,mckSLBPE,mckSLBPE ; SLB parity error?
2357 bne mckSLBparity ; Yeah, go attempt recovery....
2359 ; This is a recoverable D-ERAT or TLB error
2361 la r9,hwMckERCPE(r2) ; Get DERAT parity error count
2364 tlbiel r22 ; Locally invalidate the TLB entry
2367 lwz r21,0(r9) ; Get count
2368 addi r21,r21,1 ; Count this one
2369 stw r21,0(r9) ; Stick it back
2371 b ceMck ; All recovered...
2374 ; When we come here, we are not quite sure what the error is. We need to
2375 ; dig a bit further.
2377 ; R24 is interrupt source
2380 ; Note that both have been cleared already.
2384 rldicl. r0,r24,AsyMCKfir+1,63 ; Something in the FIR?
2385 bne-- mckFIR ; Yup, go check some more...
2387 rldicl. r0,r24,AsyMCKhri+1,63 ; Hang recovery?
2388 bne-- mckHangRcvr ; Yup...
2390 rldicl. r0,r24,AsyMCKext+1,63 ; External signal?
2391 bne-- mckExtMck ; Yup...
2394 ; We really do not know what this one is or what to do with it...
2397 mckUnk: lwz r21,hwMckUnk(r2) ; Get unknown error count
2398 addi r21,r21,1 ; Count it
2399 stw r21,hwMckUnk(r2) ; Stuff it
2400 b ueMck ; Go south, young man...
2403 ; Hang recovery. This is just a notification so we only count.
2407 lwz r21,hwMckHang(r2) ; Get hang recovery count
2408 addi r21,r21,1 ; Count this one
2409 stw r21,hwMckHang(r2) ; Stick it back
2410 b ceMck ; All recovered...
2413 ; Externally signaled MCK. No recovery for the moment, but we this may be
2414 ; where we handle ml_probe_read problems eventually.
2417 lwz r21,hwMckHang(r2) ; Get hang recovery count
2418 addi r21,r21,1 ; Count this one
2419 stw r21,hwMckHang(r2) ; Stick it back
2420 b ceMck ; All recovered...
2423 ; Machine check cause is in a FIR. Suss it out here.
2424 ; Core FIR is in R25 and has been cleared in HW.
2427 mckFIR: rldicl. r0,r25,cFIRICachePE+1,63 ; I-Cache parity error?
2428 la r19,hwMckICachePE(r2) ; Point to counter
2429 bne mckInvICache ; Go invalidate I-Cache...
2431 rldicl. r0,r25,cFIRITagPE0+1,63 ; I-Cache tag parity error?
2432 la r19,hwMckITagPE(r2) ; Point to counter
2433 bne mckInvICache ; Go invalidate I-Cache...
2435 rldicl. r0,r25,cFIRITagPE1+1,63 ; I-Cache tag parity error?
2436 la r19,hwMckITagPE(r2) ; Point to counter
2437 bne mckInvICache ; Go invalidate I-Cache...
2439 rldicl. r0,r25,cFIRIEratPE+1,63 ; IERAT parity error?
2440 la r19,hwMckIEratPE(r2) ; Point to counter
2441 bne mckInvERAT ; Go invalidate ERATs...
2443 rldicl. r0,r25,cFIRIFUL2UE+1,63 ; IFetch got L2 UE?
2444 bne mckhIFUE ; Go count and pass up...
2446 rldicl. r0,r25,cFIRDCachePE+1,63 ; D-Cache PE?
2447 bne mckL1D ; Handled, just go count...
2449 rldicl. r0,r25,cFIRDTagPE+1,63 ; D-Cache tag PE?
2450 bne mckL1T ; Handled, just go count...
2452 rldicl. r0,r25,cFIRDEratPE+1,63 ; DERAT PE?
2453 la r19,hwMckDEratPE(r2) ; Point to counter
2454 bne mckInvERAT ; Go invalidate ERATs...
2456 rldicl. r0,r25,cFIRTLBPE+1,63 ; TLB PE?
2457 la r9,hwMckTLBPE(r2) ; Get TLB parity error count
2458 bne mckInvDAR ; Go recover...
2460 rldicl. r0,r25,cFIRSLBPE+1,63 ; SLB PE?
2461 bne mckSLBparity ; Cope with it...
2463 b mckUnk ; Have not a clue...
2466 ; General recovery for I-Cache errors. Just flush it completely.
2469 .align 7 ; Force into cache line
2472 lis r0,0x0080 ; Get a 0x0080 (bit 9 >> 32)
2473 mfspr r21,hid1 ; Get the current HID1
2474 sldi r0,r0,32 ; Get the "forced ICBI match" bit
2475 or r0,r0,r21 ; Set forced match
2478 mtspr hid1,r0 ; Stick it
2479 mtspr hid1,r0 ; Stick it again
2482 li r6,0 ; Start at 0
2484 mckIcbi: icbi 0,r6 ; Kill I$
2485 addi r6,r6,128 ; Next line
2486 andis. r5,r6,1 ; Have we done them all?
2487 beq++ mckIcbi ; Not yet...
2490 mtspr hid1,r21 ; Restore original HID1
2491 mtspr hid1,r21 ; Stick it again
2494 lwz r5,0(r19) ; Get the counter
2495 addi r5,r5,1 ; Count it
2496 stw r5,0(r19) ; Stuff it back
2497 b ceMck ; All recovered...
2500 ; General recovery for ERAT problems - handled in exception vector already
2502 mckInvERAT: lwz r21,0(r19) ; Get the exception count spot
2503 addi r21,r21,1 ; Count this one
2504 stw r21,0(r19) ; Save count
2505 b ceMck ; All recovered...
2507 ; General hang recovery - this is a notification only, just count.
2510 lwz r21,hwMckHang(r2) ; Get hang recovery count
2511 addi r21,r21,1 ; Count this one
2512 stw r21,hwMckHang(r2) ; Stick it back
2513 b ceMck ; All recovered...
2517 ; These are the uncorrectable errors, just count them then pass it along.
2520 mckUE: lwz r21,hwMckUE(r2) ; Get general uncorrectable error count
2521 addi r21,r21,1 ; Count it
2522 stw r21,hwMckUE(r2) ; Stuff it
2523 b ueMck ; Go south, young man...
2525 mckhIFUE: lwz r21,hwMckIUEr(r2) ; Get I-Fetch TLB reload uncorrectable error count
2526 addi r21,r21,1 ; Count it
2527 stw r21,hwMckIUEr(r2) ; Stuff it
2528 b ueMck ; Go south, young man...
2530 mckDUE: lwz r21,hwMckDUE(r2) ; Get deferred uncorrectable error count
2531 addi r21,r21,1 ; Count it
2532 stw r21,hwMckDUE(r2) ; Stuff it
2535 ; Right here is where we end up after a failure on a ml_probe_read_64.
2536 ; We will check if that is the case, and if so, fix everything up and
2539 lis r8,hi16(EXT(ml_probe_read_64)) ; High of start
2540 lis r9,hi16(EXT(ml_probe_read_mck_64)) ; High of end
2541 ori r8,r8,lo16(EXT(ml_probe_read_64)) ; Low of start
2542 ori r9,r9,lo16(EXT(ml_probe_read_mck_64)) ; Low of end
2543 cmpld r23,r8 ; Too soon?
2544 cmpld cr1,r23,r9 ; Too late?
2546 cror cr0_lt,cr0_lt,cr1_gt ; Too soon or too late?
2547 ld r3,saver12(r13) ; Get the original MSR
2548 ld r5,savelr(r13) ; Get the return address
2549 li r4,0 ; Get fail code
2550 blt-- ueMck ; This is a normal machine check, just pass up...
2551 std r5,savesrr0(r13) ; Set the return MSR
2553 std r3,savesrr1(r13) ; Set the return address
2554 std r4,saver3(r13) ; Set failure return code
2555 b ceMck ; All recovered...
2557 mckDTW: lwz r21,hwMckDTW(r2) ; Get deferred tablewalk uncorrectable error count
2558 addi r21,r21,1 ; Count it
2559 stw r21,hwMckDTW(r2) ; Stuff it
2560 b ueMck ; Go south, young man...
2562 mckL1D: lwz r21,hwMckL1DPE(r2) ; Get data cache parity error count
2563 addi r21,r21,1 ; Count it
2564 stw r21,hwMckL1DPE(r2) ; Stuff it
2565 b ceMck ; All recovered...
2567 mckL1T: lwz r21,hwMckL1TPE(r2) ; Get TLB parity error count
2568 addi r21,r21,1 ; Count it
2569 stw r21,hwMckL1TPE(r2) ; Stuff it
2571 ceMck: lwz r21,mckFlags(0) ; Get the flags
2572 li r0,1 ; Set the recovered flag before passing up
2573 rlwinm. r21,r21,0,31,31 ; Check if we want to log recoverables
2574 stw r0,savemisc3(r13) ; Set it
2575 beq++ EatRupt ; No log of recoverables wanted...
2576 b PassUpTrap ; Go up and log error...
2578 ueMck: li r0,0 ; Set the unrecovered flag before passing up
2579 stw r0,savemisc3(r13) ; Set it
2580 b PassUpTrap ; Go up and log error and probably panic
2584 * Here's where we come back from some instruction emulator. If we come back with
2585 * T_IN_VAIN, the emulation is done and we should just reload state and directly
2586 * go back to the interrupted code. Otherwise, we'll check to see if
2587 * we need to redrive with a different interrupt, i.e., DSI.
2588 * Note that this we are actually not redriving the rupt, rather changing it
2589 * into a different one. Thus we clear the redrive bit.
2593 .globl EXT(EmulExit)
2597 cmplwi cr1,r11,T_IN_VAIN ; Was it emulated?
2598 lis r1,hi16(SAVredrive) ; Get redrive request
2599 beq++ cr1,EatRupt ; Yeah, just blast back to the user...
2600 lwz r4,SAVflags(r13) ; Pick up the flags
2602 and. r0,r4,r1 ; Check if redrive requested
2604 beq++ PassUpTrap ; No redrive, just keep on going...
2606 b Redrive ; Redrive the exception...
2609 ; Jump into main handler code switching on VM at the same time.
2611 ; We assume kernel data is mapped contiguously in physical
2612 ; memory, otherwise we would need to switch on (at least) virtual data.
2613 ; SRs are already set up.
2618 PassUpTrap: lis r20,hi16(EXT(thandler)) ; Get thandler address
2619 ori r20,r20,lo16(EXT(thandler)) ; Get thandler address
2620 b PassUp ; Go pass it up...
2622 PassUpRupt: lis r20,hi16(EXT(ihandler)) ; Get ihandler address
2623 ori r20,r20,lo16(EXT(ihandler)) ; Get ihandler address
2624 b PassUp ; Go pass it up...
2628 PassUpFPU: lis r20,hi16(EXT(fpu_switch)) ; Get FPU switcher address
2629 ori r20,r20,lo16(EXT(fpu_switch)) ; Get FPU switcher address
2630 b PassUp ; Go pass it up...
2632 PassUpVMX: lis r20,hi16(EXT(vec_switch)) ; Get VMX switcher address
2633 ori r20,r20,lo16(EXT(vec_switch)) ; Get VMX switcher address
2634 bt++ featAltivec,PassUp ; We have VMX on this CPU...
2635 li r11,T_PROGRAM ; Say that it is a program exception
2636 li r20,8 ; Set invalid instruction
2637 stw r11,saveexception(r13) ; Set the new the exception code
2638 sth r20,savesrr1+4(r13) ; Set the invalid instruction SRR code
2640 b PassUpTrap ; Go pass it up...
2645 lis r20,hi16(EXT(chandler)) ; Get choke handler address
2646 ori r20,r20,lo16(EXT(chandler)) ; Get choke handler address
2647 b PassUp ; Go pass it up...
2653 mfspr r29,pmc1 ; INSTRUMENT - saveinstr[11] - Take stamp at passup or eatrupt
2654 stw r29,0x6100+(11*16)+0x0(0) ; INSTRUMENT - Save it
2655 mfspr r29,pmc2 ; INSTRUMENT - Get stamp
2656 stw r29,0x6100+(11*16)+0x4(0) ; INSTRUMENT - Save it
2657 mfspr r29,pmc3 ; INSTRUMENT - Get stamp
2658 stw r29,0x6100+(11*16)+0x8(0) ; INSTRUMENT - Save it
2659 mfspr r29,pmc4 ; INSTRUMENT - Get stamp
2660 stw r29,0x6100+(11*16)+0xC(0) ; INSTRUMENT - Save it
2663 lwz r10,SAVflags(r13) ; Pick up the flags
2665 li r0,0xFFF ; Get a page mask
2666 li r2,MASK(MSR_BE)|MASK(MSR_SE) ; Get the mask to save trace bits
2667 andc r5,r13,r0 ; Back off to the start of savearea block
2668 mfmsr r3 ; Get our MSR
2669 rlwinm r10,r10,0,SAVredriveb+1,SAVredriveb-1 ; Clear the redrive before we pass it up
2670 li r21,MSR_SUPERVISOR_INT_OFF ; Get our normal MSR value
2671 and r3,r3,r2 ; Clear all but trace
2672 lwz r5,SACvrswap+4(r5) ; Get real to virtual conversion
2673 or r21,r21,r3 ; Keep the trace bits if they are on
2674 stw r10,SAVflags(r13) ; Set the flags with the cleared redrive flag
2676 xor r4,r13,r5 ; Pass up the virtual address of context savearea
2677 mfsprg r29,0 ; Get the per_proc block back
2678 rlwinm r4,r4,0,0,31 ; Clean top half of virtual savearea if 64-bit
2680 mr r3,r21 ; Pass in the MSR we will go to
2681 bl EXT(switchSegs) ; Go handle the segment registers/STB
2684 mfspr r30,pmc1 ; INSTRUMENT - saveinstr[7] - Take stamp afer switchsegs
2685 stw r30,0x6100+(7*16)+0x0(0) ; INSTRUMENT - Save it
2686 mfspr r30,pmc2 ; INSTRUMENT - Get stamp
2687 stw r30,0x6100+(7*16)+0x4(0) ; INSTRUMENT - Save it
2688 mfspr r30,pmc3 ; INSTRUMENT - Get stamp
2689 stw r30,0x6100+(7*16)+0x8(0) ; INSTRUMENT - Save it
2690 mfspr r30,pmc4 ; INSTRUMENT - Get stamp
2691 stw r30,0x6100+(7*16)+0xC(0) ; INSTRUMENT - Save it
2693 lwz r3,saveexception(r13) ; Recall the exception code
2695 mtsrr0 r20 ; Set up the handler address
2696 mtsrr1 r21 ; Set up our normal MSR value
2698 bt++ pf64Bitb,puLaunch ; Handle 64-bit machine...
2700 rfi ; Launch the exception handler
2702 puLaunch: rfid ; Launch the exception handler
2705 * This routine is the main place where we return from an interruption.
2707 * This is also where we release the quickfret list. These are saveareas
2708 * that were released as part of the exception exit path in hw_exceptions.
2709 * In order to save an atomic operation (which actually will not work
2710 * properly on a 64-bit machine) we use holdQFret to indicate that the list
2711 * is in flux and should not be looked at here. This comes into play only
2712 * when we take a PTE miss when we are queuing a savearea onto qfret.
2713 * Quite rare but could happen. If the flag is set, this code does not
2714 * release the list and waits until next time.
2716 * All we need to remember here is that R13 must point to the savearea
2717 * that has the context we need to load up. Translation and interruptions
2720 * This code always loads the context in the savearea pointed to
2721 * by R13. In the process, it throws away the savearea. If there
2722 * is any tomfoolery with savearea stacks, it must be taken care of
2723 * before we get here.
2729 EatRupt: mfsprg r29,0 ; Get the per_proc block back
2730 mr r31,r13 ; Move the savearea pointer to the far end of the register set
2731 mfsprg r27,2 ; Get the processor features
2733 lwz r3,holdQFret(r29) ; Get the release hold off flag
2735 bt++ pf64Bitb,eat64a ; Skip down to the 64-bit version of this
2738 ; This starts the 32-bit version
2741 mr. r3,r3 ; Should we hold off the quick release?
2742 lwz r30,quickfret+4(r29) ; Pick up the quick fret list, if any
2743 la r21,saver0(r31) ; Point to the first thing we restore
2744 bne- ernoqfret ; Hold off set, do not release just now...
2746 erchkfret: mr. r3,r30 ; Any savearea to quickly release?
2747 beq+ ernoqfret ; No quickfrets...
2748 lwz r30,SAVprev+4(r30) ; Chain back now
2750 bl EXT(save_ret_phys) ; Put it on the free list
2751 stw r30,quickfret+4(r29) ; Dequeue previous guy (really, it is ok to wait until after the release)
2752 b erchkfret ; Try the next one...
2758 mfspr r30,pmc1 ; INSTRUMENT - saveinstr[5] - Take stamp at saveareas released
2759 stw r30,0x6100+(5*16)+0x0(0) ; INSTRUMENT - Save it
2760 mfspr r30,pmc2 ; INSTRUMENT - Get stamp
2761 stw r30,0x6100+(5*16)+0x4(0) ; INSTRUMENT - Save it
2762 mfspr r30,pmc3 ; INSTRUMENT - Get stamp
2763 stw r30,0x6100+(5*16)+0x8(0) ; INSTRUMENT - Save it
2764 mfspr r30,pmc4 ; INSTRUMENT - Get stamp
2765 stw r30,0x6100+(5*16)+0xC(0) ; INSTRUMENT - Save it
2768 dcbt 0,r21 ; Touch in the first thing we need
2771 ; Here we release the savearea.
2773 ; Important!!!! The savearea is released before we are done with it. When the
2774 ; local free savearea list (anchored at lclfree) gets too long, save_ret_phys
2775 ; will trim the list, making the extra saveareas allocatable by another processor
2776 ; The code in there must ALWAYS leave our savearea on the local list, otherwise
2777 ; we could be very, very unhappy. The code there always queues the "just released"
2778 ; savearea to the head of the local list. Then, if it needs to trim, it will
2779 ; start with the SECOND savearea, leaving ours intact.
2783 mr r3,r31 ; Get the exiting savearea in parm register
2784 bl EXT(save_ret_phys) ; Put it on the free list
2786 mfspr r3,pmc1 ; INSTRUMENT - saveinstr[6] - Take stamp afer savearea released
2787 stw r3,0x6100+(6*16)+0x0(0) ; INSTRUMENT - Save it
2788 mfspr r3,pmc2 ; INSTRUMENT - Get stamp
2789 stw r3,0x6100+(6*16)+0x4(0) ; INSTRUMENT - Save it
2790 mfspr r3,pmc3 ; INSTRUMENT - Get stamp
2791 stw r3,0x6100+(6*16)+0x8(0) ; INSTRUMENT - Save it
2792 mfspr r3,pmc4 ; INSTRUMENT - Get stamp
2793 stw r3,0x6100+(6*16)+0xC(0) ; INSTRUMENT - Save it
2796 lwz r3,savesrr1+4(r31) ; Pass in the MSR we are going to
2797 bl EXT(switchSegs) ; Go handle the segment registers/STB
2799 mfspr r30,pmc1 ; INSTRUMENT - saveinstr[10] - Take stamp afer switchsegs
2800 stw r30,0x6100+(10*16)+0x0(0) ; INSTRUMENT - Save it
2801 mfspr r30,pmc2 ; INSTRUMENT - Get stamp
2802 stw r30,0x6100+(10*16)+0x4(0) ; INSTRUMENT - Save it
2803 mfspr r30,pmc3 ; INSTRUMENT - Get stamp
2804 stw r30,0x6100+(10*16)+0x8(0) ; INSTRUMENT - Save it
2805 mfspr r30,pmc4 ; INSTRUMENT - Get stamp
2806 stw r30,0x6100+(10*16)+0xC(0) ; INSTRUMENT - Save it
2808 li r3,savesrr1+4 ; Get offset to the srr1 value
2810 lhz r9,PP_CPU_FLAGS(r29) ; Get the processor flags
2811 lwarx r26,r3,r31 ; Get destination MSR and take reservation along the way (just so we can blow it away)
2813 rlwinm r25,r26,27,22,22 ; Move PR bit to BE
2815 cmplw cr3,r14,r14 ; Set that we do not need to stop streams
2817 rlwinm r9,r9,(((31-MSR_BE_BIT)+(traceBEb+16+1))&31),MSR_BE_BIT,MSR_BE_BIT ; Set BE bit if special trace is on
2818 li r21,emfp0 ; Point to the fp savearea
2819 and r9,r9,r25 ; Clear BE if supervisor state
2820 or r26,r26,r9 ; Flip on the BE bit for special trace if needed
2821 stwcx. r26,r3,r31 ; Blow away any reservations we hold (and set BE)
2823 lwz r25,savesrr0+4(r31) ; Get the SRR0 to use
2825 la r28,saver4(r31) ; Point to the 32-byte line with r4-r7
2826 dcbz r21,r29 ; Clear a work area
2827 lwz r0,saver0+4(r31) ; Restore R0
2828 dcbt 0,r28 ; Touch in r4-r7
2829 lwz r1,saver1+4(r31) ; Restore R1
2830 lwz r2,saver2+4(r31) ; Restore R2
2831 la r28,saver8(r31) ; Point to the 32-byte line with r8-r11
2832 lwz r3,saver3+4(r31) ; Restore R3
2833 andis. r6,r27,hi16(pfAltivec) ; Do we have altivec on the machine?
2834 dcbt 0,r28 ; touch in r8-r11
2835 lwz r4,saver4+4(r31) ; Restore R4
2836 la r28,saver12(r31) ; Point to the 32-byte line with r12-r15
2837 mtsrr0 r25 ; Restore the SRR0 now
2838 lwz r5,saver5+4(r31) ; Restore R5
2839 mtsrr1 r26 ; Restore the SRR1 now
2840 lwz r6,saver6+4(r31) ; Restore R6
2842 dcbt 0,r28 ; touch in r12-r15
2845 lwz r7,saver7+4(r31) ; Restore R7
2846 lwz r8,saver8+4(r31) ; Restore R8
2847 lwz r9,saver9+4(r31) ; Restore R9
2849 dcbt 0,r28 ; touch in r16-r19
2852 lwz r10,saver10+4(r31) ; Restore R10
2853 lwz r11,saver11+4(r31) ; Restore R11
2855 dcbt 0,r28 ; touch in r20-r23
2856 la r28,savevscr(r31) ; Point to the status area
2858 lwz r12,saver12+4(r31) ; Restore R12
2859 lwz r13,saver13+4(r31) ; Restore R13
2861 la r14,savectr+4(r31)
2862 dcbt 0,r28 ; Touch in VSCR and FPSCR
2863 dcbt 0,r14 ; touch in CTR, DAR, DSISR, VRSAVE, and Exception code
2865 lwz r26,next_savearea+4(r29) ; Get the exception save area
2868 lwz r14,saver14+4(r31) ; Restore R14
2869 lwz r15,saver15+4(r31) ; Restore R15
2872 stfd f0,emfp0(r29) ; Save FP0
2873 lwz r27,savevrsave(r31) ; Get the vrsave
2874 dcbt 0,r28 ; touch in r24-r27
2875 la r28,savevscr(r31) ; Point to the status area
2876 lfd f0,savefpscrpad(r31) ; Get the fpscr
2878 mtfsf 0xFF,f0 ; Restore fpscr
2879 lfd f0,emfp0(r29) ; Restore the used register
2881 beq noavec3 ; No Altivec on this CPU...
2883 stvxl v0,r21,r29 ; Save a vector register
2884 lvxl v0,0,r28 ; Get the vector status
2885 mtspr vrsave,r27 ; Set the vrsave
2886 mtvscr v0 ; Set the vector status
2887 lvxl v0,r21,r29 ; Restore work vector register
2889 noavec3: dcbt 0,r22 ; touch in r28-r31
2891 lwz r23,spcFlags(r29) ; Get the special flags from per_proc
2892 la r17,savesrr0(r31)
2893 la r26,saver0(r26) ; Point to the first part of the next savearea
2894 dcbt 0,r17 ; touch in SRR0, SRR1, CR, XER, LR
2895 lhz r28,pfrptdProc(r29) ; Get the reported processor type
2897 lwz r16,saver16+4(r31) ; Restore R16
2898 lwz r17,saver17+4(r31) ; Restore R17
2899 lwz r18,saver18+4(r31) ; Restore R18
2900 lwz r19,saver19+4(r31) ; Restore R19
2901 lwz r20,saver20+4(r31) ; Restore R20
2902 lwz r21,saver21+4(r31) ; Restore R21
2903 lwz r22,saver22+4(r31) ; Restore R22
2905 cmpwi cr1,r28,CPU_SUBTYPE_POWERPC_750 ; G3?
2907 dcbz 0,r26 ; Clear and allocate next savearea we use in the off chance it is still in when we next interrupt
2909 andis. r23,r23,hi16(perfMonitor) ; Is the performance monitor enabled?
2910 lwz r23,saver23+4(r31) ; Restore R23
2911 cmpwi cr2,r28,CPU_SUBTYPE_POWERPC_7400 ; Yer standard G4?
2912 lwz r24,saver24+4(r31) ; Restore R24
2913 lwz r25,saver25+4(r31) ; Restore R25
2914 lwz r26,saver26+4(r31) ; Restore R26
2915 lwz r27,saver27+4(r31) ; Restore R27
2917 beq+ noPerfMonRestore32 ; No perf monitor...
2919 beq- cr1,perfMonRestore32_750 ; This is a G3...
2920 beq- cr2,perfMonRestore32_7400 ; Standard G4...
2922 lwz r28,savepmc+16(r31)
2923 lwz r29,savepmc+20(r31)
2924 mtspr pmc5,r28 ; Restore PMC5
2925 mtspr pmc6,r29 ; Restore PMC6
2927 perfMonRestore32_7400:
2928 lwz r28,savemmcr2+4(r31)
2929 mtspr mmcr2,r28 ; Restore MMCR2
2931 perfMonRestore32_750:
2932 lwz r28,savepmc+0(r31)
2933 lwz r29,savepmc+4(r31)
2934 mtspr pmc1,r28 ; Restore PMC1
2935 mtspr pmc2,r29 ; Restore PMC2
2936 lwz r28,savepmc+8(r31)
2937 lwz r29,savepmc+12(r31)
2938 mtspr pmc3,r28 ; Restore PMC3
2939 mtspr pmc4,r29 ; Restore PMC4
2940 lwz r28,savemmcr1+4(r31)
2941 lwz r29,savemmcr0+4(r31)
2942 mtspr mmcr1,r28 ; Restore MMCR1
2943 mtspr mmcr0,r29 ; Restore MMCR0
2946 lwz r28,savecr(r31) ; Get CR to restore
2947 lwz r29,savexer+4(r31) ; Get XER to restore
2948 mtcr r28 ; Restore the CR
2949 lwz r28,savelr+4(r31) ; Get LR to restore
2950 mtxer r29 ; Restore the XER
2951 lwz r29,savectr+4(r31) ; Get the CTR to restore
2952 mtlr r28 ; Restore the LR
2953 lwz r28,saver30+4(r31) ; Get R30
2954 mtctr r29 ; Restore the CTR
2955 lwz r29,saver31+4(r31) ; Get R31
2956 mtsprg 2,r28 ; Save R30 for later
2957 lwz r28,saver28+4(r31) ; Restore R28
2958 mtsprg 3,r29 ; Save R31 for later
2959 lwz r29,saver29+4(r31) ; Restore R29
2961 mfsprg r31,0 ; Get per_proc
2962 mfsprg r30,2 ; Restore R30
2963 lwz r31,pfAvailable(r31) ; Get the feature flags
2964 mtsprg 2,r31 ; Set the feature flags
2965 mfsprg r31,3 ; Restore R31
2967 rfi ; Click heels three times and think very hard that there is no place like home...
2969 .long 0 ; Leave this here
2980 ; This starts the 64-bit version
2985 eat64a: ld r30,quickfret(r29) ; Pick up the quick fret list, if any
2987 mr. r3,r3 ; Should we hold off the quick release?
2988 la r21,saver0(r31) ; Point to the first thing we restore
2989 bne-- ernoqfre64 ; Hold off set, do not release just now...
2991 erchkfre64: mr. r3,r30 ; Any savearea to quickly release?
2992 beq+ ernoqfre64 ; No quickfrets...
2993 ld r30,SAVprev(r30) ; Chain back now
2995 bl EXT(save_ret_phys) ; Put it on the free list
2997 std r30,quickfret(r29) ; Dequeue previous guy (really, it is ok to wait until after the release)
2998 b erchkfre64 ; Try the next one...
3002 ernoqfre64: dcbt 0,r21 ; Touch in the first thing we need
3005 ; Here we release the savearea.
3007 ; Important!!!! The savearea is released before we are done with it. When the
3008 ; local free savearea list (anchored at lclfree) gets too long, save_ret_phys
3009 ; will trim the list, making the extra saveareas allocatable by another processor
3010 ; The code in there must ALWAYS leave our savearea on the local list, otherwise
3011 ; we could be very, very unhappy. The code there always queues the "just released"
3012 ; savearea to the head of the local list. Then, if it needs to trim, it will
3013 ; start with the SECOND savearea, leaving ours intact.
3017 li r3,lgKillResv ; Get spot to kill reservation
3018 stdcx. r3,0,r3 ; Blow away any reservations we hold
3020 mr r3,r31 ; Get the exiting savearea in parm register
3021 bl EXT(save_ret_phys) ; Put it on the free list
3023 lwz r3,savesrr1+4(r31) ; Pass in the MSR we will be going to
3024 bl EXT(switchSegs) ; Go handle the segment registers/STB
3026 lhz r9,PP_CPU_FLAGS(r29) ; Get the processor flags
3027 ld r26,savesrr1(r31) ; Get destination MSR
3028 cmplw cr3,r14,r14 ; Set that we do not need to stop streams
3029 rlwinm r25,r26,27,22,22 ; Move PR bit to BE
3031 rlwinm r9,r9,(((31-MSR_BE_BIT)+(traceBEb+16+1))&31),MSR_BE_BIT,MSR_BE_BIT ; Set BE bit if special trace is on
3032 li r21,emfp0 ; Point to a workarea
3033 and r9,r9,r25 ; Clear BE if supervisor state
3034 or r26,r26,r9 ; Flip on the BE bit for special trace if needed
3036 ld r25,savesrr0(r31) ; Get the SRR0 to use
3037 la r28,saver16(r31) ; Point to the 128-byte line with r16-r31
3038 dcbz128 r21,r29 ; Clear a work area
3039 ld r0,saver0(r31) ; Restore R0
3040 dcbt 0,r28 ; Touch in r16-r31
3041 ld r1,saver1(r31) ; Restore R1
3042 ld r2,saver2(r31) ; Restore R2
3043 ld r3,saver3(r31) ; Restore R3
3044 mtcrf 0x80,r27 ; Get facility availability flags (do not touch CR1-7)
3045 ld r4,saver4(r31) ; Restore R4
3046 mtsrr0 r25 ; Restore the SRR0 now
3047 ld r5,saver5(r31) ; Restore R5
3048 mtsrr1 r26 ; Restore the SRR1 now
3049 ld r6,saver6(r31) ; Restore R6
3051 ld r7,saver7(r31) ; Restore R7
3052 ld r8,saver8(r31) ; Restore R8
3053 ld r9,saver9(r31) ; Restore R9
3055 la r28,savevscr(r31) ; Point to the status area
3057 ld r10,saver10(r31) ; Restore R10
3058 ld r11,saver11(r31) ; Restore R11
3059 ld r12,saver12(r31) ; Restore R12
3060 ld r13,saver13(r31) ; Restore R13
3062 ld r26,next_savearea(r29) ; Get the exception save area
3064 ld r14,saver14(r31) ; Restore R14
3065 ld r15,saver15(r31) ; Restore R15
3066 lwz r27,savevrsave(r31) ; Get the vrsave
3068 bf-- pfAltivecb,noavec2s ; Skip if no VMX...
3070 stvxl v0,r21,r29 ; Save a vector register
3071 lvxl v0,0,r28 ; Get the vector status
3072 mtvscr v0 ; Set the vector status
3074 lvxl v0,r21,r29 ; Restore work vector register
3076 noavec2s: mtspr vrsave,r27 ; Set the vrsave
3078 lwz r28,saveexception(r31) ; Get exception type
3079 stfd f0,emfp0(r29) ; Save FP0
3080 lfd f0,savefpscrpad(r31) ; Get the fpscr
3081 mtfsf 0xFF,f0 ; Restore fpscr
3082 lfd f0,emfp0(r29) ; Restore the used register
3083 ld r16,saver16(r31) ; Restore R16
3084 lwz r30,spcFlags(r29) ; Get the special flags from per_proc
3085 ld r17,saver17(r31) ; Restore R17
3086 ld r18,saver18(r31) ; Restore R18
3087 cmplwi cr1,r28,T_RESET ; Are we returning from a reset?
3088 ld r19,saver19(r31) ; Restore R19
3089 ld r20,saver20(r31) ; Restore R20
3090 li r27,0 ; Get a zero
3091 ld r21,saver21(r31) ; Restore R21
3092 la r26,saver0(r26) ; Point to the first part of the next savearea
3093 andis. r30,r30,hi16(perfMonitor) ; Is the performance monitor enabled?
3094 ld r22,saver22(r31) ; Restore R22
3095 ld r23,saver23(r31) ; Restore R23
3096 bne++ cr1,er64rrst ; We are not returning from a reset...
3097 stw r27,lo16(EXT(ResetHandler)-EXT(ExceptionVectorsStart)+RESETHANDLER_TYPE)(br0) ; Allow resets again
3099 er64rrst: ld r24,saver24(r31) ; Restore R24
3101 dcbz128 0,r26 ; Clear and allocate next savearea we use in the off chance it is still in when we next interrupt
3103 ld r25,saver25(r31) ; Restore R25
3104 ld r26,saver26(r31) ; Restore R26
3105 ld r27,saver27(r31) ; Restore R27
3107 beq++ noPerfMonRestore64 ; Nope...
3109 lwz r28,savepmc+0(r31)
3110 lwz r29,savepmc+4(r31)
3111 mtspr pmc1_gp,r28 ; Restore PMC1
3112 mtspr pmc2_gp,r29 ; Restore PMC2
3113 lwz r28,savepmc+8(r31)
3114 lwz r29,savepmc+12(r31)
3115 mtspr pmc3_gp,r28 ; Restore PMC3
3116 mtspr pmc4_gp,r29 ; Restore PMC4
3117 lwz r28,savepmc+16(r31)
3118 lwz r29,savepmc+20(r31)
3119 mtspr pmc5_gp,r28 ; Restore PMC5
3120 mtspr pmc6_gp,r29 ; Restore PMC6
3121 lwz r28,savepmc+24(r31)
3122 lwz r29,savepmc+28(r31)
3123 mtspr pmc7_gp,r28 ; Restore PMC7
3124 mtspr pmc8_gp,r29 ; Restore PMC8
3125 ld r28,savemmcr1(r31)
3126 ld r29,savemmcr2(r31)
3127 mtspr mmcr1_gp,r28 ; Restore MMCR1
3128 mtspr mmcra_gp,r29 ; Restore MMCRA
3129 ld r28,savemmcr0(r31)
3131 mtspr mmcr0_gp,r28 ; Restore MMCR0
3134 mfsprg r30,0 ; Get per_proc
3135 lwz r28,savecr(r31) ; Get CR to restore
3136 ld r29,savexer(r31) ; Get XER to restore
3137 mtcr r28 ; Restore the CR
3138 ld r28,savelr(r31) ; Get LR to restore
3139 mtxer r29 ; Restore the XER
3140 ld r29,savectr(r31) ; Get the CTR to restore
3141 mtlr r28 ; Restore the LR
3142 ld r28,saver30(r31) ; Get R30
3143 mtctr r29 ; Restore the CTR
3144 ld r29,saver31(r31) ; Get R31
3145 mtspr hsprg0,r28 ; Save R30 for later
3146 ld r28,saver28(r31) ; Restore R28
3147 mtsprg 3,r29 ; Save R31 for later
3148 ld r29,saver29(r31) ; Restore R29
3150 lwz r31,pfAvailable(r30) ; Get the feature flags
3151 ld r30,UAW(r30) ; Get the User Assist DoubleWord
3152 mtsprg 2,r31 ; Set the feature flags
3153 mfsprg r31,3 ; Restore R31
3154 mtsprg 3,r30 ; Set the UAW
3155 mfspr r30,hsprg0 ; Restore R30
3157 rfid ; Click heels three times and think very hard that there is no place like home...
3162 * exception_exit(savearea *)
3165 * ENTRY : IR and/or DR and/or interruptions can be on
3166 * R3 points to the virtual address of a savearea
3170 .globl EXT(exception_exit)
3172 LEXT(exception_exit)
3174 mfsprg r29,2 ; Get feature flags
3175 mr r31,r3 ; Get the savearea in the right register
3176 mtcrf 0x04,r29 ; Set the features
3177 li r0,1 ; Get this just in case
3178 mtcrf 0x02,r29 ; Set the features
3179 lis r30,hi16(MASK(MSR_VEC)|MASK(MSR_FP)|MASK(MSR_ME)) ; Set up the MSR we will use throughout. Note that ME come on here if MCK
3180 rlwinm r4,r3,0,0,19 ; Round down to savearea block base
3181 lis r1,hi16(SAVredrive) ; Get redrive request
3182 mfsprg r2,0 ; Get the per_proc block
3183 ori r30,r30,lo16(MASK(MSR_VEC)|MASK(MSR_FP)|MASK(MSR_ME)) ; Rest of MSR
3184 bt++ pf64Bitb,eeSixtyFour ; We are 64-bit...
3186 lwz r4,SACvrswap+4(r4) ; Get the virtual to real translation
3188 bt pfNoMSRirb,eeNoMSR ; No MSR...
3190 mtmsr r30 ; Translation and all off
3191 isync ; Toss prefetch
3197 ld r4,SACvrswap(r4) ; Get the virtual to real translation
3198 rldimi r30,r0,63,MSR_SF_BIT ; Set SF bit (bit 0)
3199 mtmsrd r30 ; Set 64-bit mode, turn off EE, DR, and IR
3200 isync ; Toss prefetch
3205 eeNoMSR: li r0,loadMSR ; Get the MSR setter SC
3206 mr r3,r30 ; Get new MSR
3209 eeNoMSRx: xor r31,r31,r4 ; Convert the savearea to physical addressing
3210 lwz r4,SAVflags(r31) ; Pick up the flags
3211 mr r13,r31 ; Put savearea here also
3214 mfspr r5,pmc1 ; INSTRUMENT - saveinstr[8] - stamp exception exit
3215 stw r5,0x6100+(8*16)+0x0(0) ; INSTRUMENT - Save it
3216 mfspr r5,pmc2 ; INSTRUMENT - Get stamp
3217 stw r5,0x6100+(8*16)+0x4(0) ; INSTRUMENT - Save it
3218 mfspr r5,pmc3 ; INSTRUMENT - Get stamp
3219 stw r5,0x6100+(8*16)+0x8(0) ; INSTRUMENT - Save it
3220 mfspr r5,pmc4 ; INSTRUMENT - Get stamp
3221 stw r5,0x6100+(8*16)+0xC(0) ; INSTRUMENT - Save it
3225 and. r0,r4,r1 ; Check if redrive requested
3227 dcbt br0,r2 ; We will need this in just a sec
3229 beq+ EatRupt ; No redrive, just exit...
3231 0: mftbu r2 ; Avoid using an obsolete timestamp for the redrive
3238 stw r4,SAVtime+4(r13)
3240 lwz r11,saveexception(r13) ; Restore exception code
3241 b Redrive ; Redrive the exception...
3245 .align 12 ; Force page alignment
3247 .globl EXT(ExceptionVectorsEnd)
3248 EXT(ExceptionVectorsEnd): /* Used if relocating the exception vectors */
3254 ; Here is where we keep the low memory globals
3259 .ascii "Hagfish " ; 5000 Unique eyecatcher
3261 .long 0 ; 500C Zero cont...
3262 .long EXT(PerProcTable) ; 5010 pointer to per_proc_entry table
3265 .globl EXT(mckFlags)
3267 .long 0 ; 5018 Machine check flags
3269 .long EXT(version) ; 501C Pointer to kernel version string
3270 .long 0 ; 5020 physical memory window virtual address
3271 .long 0 ; 5024 physical memory window virtual address
3272 .long 0 ; 5028 user memory window virtual address
3273 .long 0 ; 502C user memory window virtual address
3274 .long 0 ; 5030 VMM boot-args forced feature flags
3275 .long 0 ; 5034 reserved
3276 .long 0 ; 5038 reserved
3277 .long 0 ; 503C reserved
3278 .long 0 ; 5040 reserved
3279 .long 0 ; 5044 reserved
3280 .long 0 ; 5048 reserved
3281 .long 0 ; 504C reserved
3282 .long 0 ; 5050 reserved
3283 .long 0 ; 5054 reserved
3284 .long 0 ; 5058 reserved
3285 .long 0 ; 505C reserved
3286 .long 0 ; 5060 reserved
3287 .long 0 ; 5064 reserved
3288 .long 0 ; 5068 reserved
3289 .long 0 ; 506C reserved
3290 .long 0 ; 5070 reserved
3291 .long 0 ; 5074 reserved
3292 .long 0 ; 5078 reserved
3293 .long 0 ; 507C reserved
3297 .long 0 ; 5080 The next trace entry to use
3299 .long 0xFFFFFFFF ; 5084 All enabled
3301 .long 0x00000000 ; 5084 All disabled on non-debug systems
3303 .long 0 ; 5088 Start of the trace table
3304 .long 0 ; 508C End (wrap point) of the trace
3305 .long 0 ; 5090 Saved mask while in debugger
3306 .long 0 ; 5094 Size of trace table (1 - 256 pages)
3307 .long 0 ; 5098 traceGas[0]
3308 .long 0 ; 509C traceGas[1]
3310 .long 0 ; 50A0 reserved
3311 .long 0 ; 50A4 reserved
3312 .long 0 ; 50A8 reserved
3313 .long 0 ; 50AC reserved
3314 .long 0 ; 50B0 reserved
3315 .long 0 ; 50B4 reserved
3316 .long 0 ; 50B8 reserved
3317 .long 0 ; 50BC reserved
3318 .long 0 ; 50C0 reserved
3319 .long 0 ; 50C4 reserved
3320 .long 0 ; 50C8 reserved
3321 .long 0 ; 50CC reserved
3322 .long 0 ; 50D0 reserved
3323 .long 0 ; 50D4 reserved
3324 .long 0 ; 50D8 reserved
3325 .long 0 ; 50DC reserved
3326 .long 0 ; 50E0 reserved
3327 .long 0 ; 50E4 reserved
3328 .long 0 ; 50E8 reserved
3329 .long 0 ; 50EC reserved
3330 .long 0 ; 50F0 reserved
3331 .long 0 ; 50F4 reserved
3332 .long 0 ; 50F8 reserved
3333 .long 0 ; 50FC reserved
3335 .globl EXT(saveanchor)
3337 EXT(saveanchor): ; 5100 saveanchor
3340 .long 0 ; 5140 reserved
3341 .long 0 ; 5144 reserved
3342 .long 0 ; 5148 reserved
3343 .long 0 ; 514C reserved
3344 .long 0 ; 5150 reserved
3345 .long 0 ; 5154 reserved
3346 .long 0 ; 5158 reserved
3347 .long 0 ; 515C reserved
3348 .long 0 ; 5160 reserved
3349 .long 0 ; 5164 reserved
3350 .long 0 ; 5168 reserved
3351 .long 0 ; 516C reserved
3352 .long 0 ; 5170 reserved
3353 .long 0 ; 5174 reserved
3354 .long 0 ; 5178 reserved
3355 .long 0 ; 517C reserved
3357 .long 0 ; 5180 tlbieLock
3359 .long 0 ; 5184 reserved
3360 .long 0 ; 5188 reserved
3361 .long 0 ; 518C reserved
3362 .long 0 ; 5190 reserved
3363 .long 0 ; 5194 reserved
3364 .long 0 ; 5198 reserved
3365 .long 0 ; 519C reserved
3366 .long 0 ; 51A0 reserved
3367 .long 0 ; 51A4 reserved
3368 .long 0 ; 51A8 reserved
3369 .long 0 ; 51AC reserved
3370 .long 0 ; 51B0 reserved
3371 .long 0 ; 51B4 reserved
3372 .long 0 ; 51B8 reserved
3373 .long 0 ; 51BC reserved
3374 .long 0 ; 51C0 reserved
3375 .long 0 ; 51C4 reserved
3376 .long 0 ; 51C8 reserved
3377 .long 0 ; 51CC reserved
3378 .long 0 ; 51D0 reserved
3379 .long 0 ; 51D4 reserved
3380 .long 0 ; 51D8 reserved
3381 .long 0 ; 51DC reserved
3382 .long 0 ; 51E0 reserved
3383 .long 0 ; 51E4 reserved
3384 .long 0 ; 51E8 reserved
3385 .long 0 ; 51EC reserved
3386 .long 0 ; 51F0 reserved
3387 .long 0 ; 51F4 reserved
3388 .long 0 ; 51F8 reserved
3389 .long 0 ; 51FC reserved
3394 .long 0 ; 5200 dgLock
3395 .long 0 ; 5204 dgFlags
3396 .long 0 ; 5208 dgMisc0
3397 .long 0 ; 520C dgMisc1
3398 .long 0 ; 5210 dgMisc2
3399 .long 0 ; 5214 dgMisc3
3400 .long 0 ; 5218 dgMisc4
3401 .long 0 ; 521C dgMisc5
3403 .globl EXT(LcksOpts)
3405 .long 0 ; 5220 lcksWork
3406 .long 0 ; 5224 reserved
3407 .long 0 ; 5228 reserved
3408 .long 0 ; 522C reserved
3409 .long 0 ; 5230 reserved
3410 .long 0 ; 5234 reserved
3411 .long 0 ; 5238 reserved
3412 .long 0 ; 523C reserved
3413 .long 0 ; 5240 reserved
3414 .long 0 ; 5244 reserved
3415 .long 0 ; 5248 reserved
3416 .long 0 ; 524C reserved
3417 .long 0 ; 5250 reserved
3418 .long 0 ; 5254 reserved
3419 .long 0 ; 5258 reserved
3420 .long 0 ; 525C reserved
3421 .long 0 ; 5260 reserved
3422 .long 0 ; 5264 reserved
3423 .long 0 ; 5268 reserved
3424 .long 0 ; 526C reserved
3425 .long 0 ; 5270 reserved
3426 .long 0 ; 5274 reserved
3427 .long 0 ; 5278 reserved
3428 .long 0 ; 527C reserved
3432 .long 0x80000000 | (12 << 8) | 12 ; 5280 pcfDefPcfg - 4k
3433 .long 0 ; 5284 pcfLargePcfg
3434 .long 0 ; 5288 Non-primary page configurations
3435 .long 0 ; 528C Non-primary page configurations
3436 .long 0 ; 5290 Non-primary page configurations
3437 .long 0 ; 5294 Non-primary page configurations
3438 .long 0 ; 5298 Non-primary page configurations
3439 .long 0 ; 529C Non-primary page configurations
3441 .long 0 ; 52A0 reserved
3442 .long 0 ; 52A4 reserved
3443 .long 0 ; 52A8 reserved
3444 .long 0 ; 52AC reserved
3445 .long 0 ; 52B0 reserved
3446 .long 0 ; 52B4 reserved
3447 .long 0 ; 52B8 reserved
3448 .long 0 ; 52BC reserved
3449 .long 0 ; 52C0 reserved
3450 .long 0 ; 52C4 reserved
3451 .long 0 ; 52C8 reserved
3452 .long 0 ; 52CC reserved
3453 .long 0 ; 52D0 reserved
3454 .long 0 ; 52D4 reserved
3455 .long 0 ; 52D8 reserved
3456 .long 0 ; 52DC reserved
3457 .long 0 ; 52E0 reserved
3458 .long 0 ; 52E4 reserved
3459 .long 0 ; 52E8 reserved
3460 .long 0 ; 52EC reserved
3461 .long 0 ; 52F0 reserved
3462 .long 0 ; 52F4 reserved
3463 .long 0 ; 52F8 reserved
3464 .long 0 ; 52FC reserved
3466 .globl EXT(killresv)
3469 .long 0 ; 5300 Used to kill reservations
3470 .long 0 ; 5304 Used to kill reservations
3471 .long 0 ; 5308 Used to kill reservations
3472 .long 0 ; 530C Used to kill reservations
3473 .long 0 ; 5310 Used to kill reservations
3474 .long 0 ; 5314 Used to kill reservations
3475 .long 0 ; 5318 Used to kill reservations
3476 .long 0 ; 531C Used to kill reservations
3477 .long 0 ; 5320 Used to kill reservations
3478 .long 0 ; 5324 Used to kill reservations
3479 .long 0 ; 5328 Used to kill reservations
3480 .long 0 ; 532C Used to kill reservations
3481 .long 0 ; 5330 Used to kill reservations
3482 .long 0 ; 5334 Used to kill reservations
3483 .long 0 ; 5338 Used to kill reservations
3484 .long 0 ; 533C Used to kill reservations
3485 .long 0 ; 5340 Used to kill reservations
3486 .long 0 ; 5344 Used to kill reservations
3487 .long 0 ; 5348 Used to kill reservations
3488 .long 0 ; 534C Used to kill reservations
3489 .long 0 ; 5350 Used to kill reservations
3490 .long 0 ; 5354 Used to kill reservations
3491 .long 0 ; 5358 Used to kill reservations
3492 .long 0 ; 535C Used to kill reservations
3493 .long 0 ; 5360 Used to kill reservations
3494 .long 0 ; 5364 Used to kill reservations
3495 .long 0 ; 5368 Used to kill reservations
3496 .long 0 ; 536C Used to kill reservations
3497 .long 0 ; 5370 Used to kill reservations
3498 .long 0 ; 5374 Used to kill reservations
3499 .long 0 ; 5378 Used to kill reservations
3500 .long 0 ; 537C Used to kill reservations
3502 .long 0 ; 5380 reserved
3503 .long 0 ; 5384 reserved
3504 .long 0 ; 5388 reserved
3505 .long 0 ; 538C reserved
3506 .long 0 ; 5390 reserved
3507 .long 0 ; 5394 reserved
3508 .long 0 ; 5398 reserved
3509 .long 0 ; 539C reserved
3510 .long 0 ; 53A0 reserved
3511 .long 0 ; 53A4 reserved
3512 .long 0 ; 53A8 reserved
3513 .long 0 ; 53AC reserved
3514 .long 0 ; 53B0 reserved
3515 .long 0 ; 53B4 reserved
3516 .long 0 ; 53B8 reserved
3517 .long 0 ; 53BC reserved
3518 .long 0 ; 53C0 reserved
3519 .long 0 ; 53C4 reserved
3520 .long 0 ; 53C8 reserved
3521 .long 0 ; 53CC reserved
3522 .long 0 ; 53D0 reserved
3523 .long 0 ; 53D4 reserved
3524 .long 0 ; 53D8 reserved
3525 .long 0 ; 53DC reserved
3526 .long 0 ; 53E0 reserved
3527 .long 0 ; 53E4 reserved
3528 .long 0 ; 53E8 reserved
3529 .long 0 ; 53EC reserved
3530 .long 0 ; 53F0 reserved
3531 .long 0 ; 53F4 reserved
3532 .long 0 ; 53F8 reserved
3533 .long 0 ; 53FC reserved
3534 .long 0 ; 5400 reserved
3535 .long 0 ; 5404 reserved
3536 .long 0 ; 5408 reserved
3537 .long 0 ; 540C reserved
3538 .long 0 ; 5410 reserved
3539 .long 0 ; 5414 reserved
3540 .long 0 ; 5418 reserved
3541 .long 0 ; 541C reserved
3542 .long 0 ; 5420 reserved
3543 .long 0 ; 5424 reserved
3544 .long 0 ; 5428 reserved
3545 .long 0 ; 542C reserved
3546 .long 0 ; 5430 reserved
3547 .long 0 ; 5434 reserved
3548 .long 0 ; 5438 reserved
3549 .long 0 ; 543C reserved
3550 .long 0 ; 5440 reserved
3551 .long 0 ; 5444 reserved
3552 .long 0 ; 5448 reserved
3553 .long 0 ; 544C reserved
3554 .long 0 ; 5450 reserved
3555 .long 0 ; 5454 reserved
3556 .long 0 ; 5458 reserved
3557 .long 0 ; 545C reserved
3558 .long 0 ; 5460 reserved
3559 .long 0 ; 5464 reserved
3560 .long 0 ; 5468 reserved
3561 .long 0 ; 546C reserved
3562 .long 0 ; 5470 reserved
3563 .long 0 ; 5474 reserved
3564 .long 0 ; 5478 reserved
3565 .long 0 ; 547C reserved
3567 ; The "shared page" is used for low-level debugging
3571 .globl EXT(sharedPage)
3573 EXT(sharedPage): ; Per processor data area
3574 .long 0xC24BC195 ; Comm Area validity value
3575 .long 0x87859393 ; Comm Area validity value
3576 .long 0xE681A2C8 ; Comm Area validity value
3577 .long 0x8599855A ; Comm Area validity value
3578 .long 0xD74BD296 ; Comm Area validity value
3579 .long 0x8388E681 ; Comm Area validity value
3580 .long 0xA2C88599 ; Comm Area validity value
3581 .short 0x855A ; Comm Area validity value
3582 .short 1 ; Comm Area version number
3583 .fill 1016*4,1,0 ; (filled with 0s)
3587 .globl EXT(exception_end)
3589 .long EXT(ExceptionVectorsEnd) -EXT(ExceptionVectorsStart) /* phys fn */