]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/ppc/lowmem_vectors.s
xnu-792.6.56.tar.gz
[apple/xnu.git] / osfmk / ppc / lowmem_vectors.s
index 9bdf98f95b292b1c5b3a28631ef21afec9515b9f..658eda39b228b81fc04bc7e439580072242d4cef 100644 (file)
@@ -3,19 +3,20 @@
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
@@ -354,10 +355,11 @@ notDCache:        mtcrf   255,r13                                                 ; Restore CRs
 
 ;           System Calls (sc instruction)
 ;
-;           The syscall number is in r0.  All we do here is munge the number into a
-;           7-bit index into the "scTable", and dispatch on it to handle the Ultra
+;           The syscall number is in r0.  All we do here is munge the number into an
+;           8-bit index into the "scTable", and dispatch on it to handle the Ultra
 ;           Fast Traps (UFTs.)  The index is:
 ;
+;               0x80 - set if syscall number is 0x80000000 (CutTrace)
 ;               0x40 - set if syscall number is 0x00006004
 ;               0x20 - set if upper 29 bits of syscall number are 0xFFFFFFF8
 ;               0x10 - set if upper 29 bits of syscall number are 0x00007FF0
@@ -373,7 +375,11 @@ notDCache: mtcrf   255,r13                                                 ; Restore CRs
             addi    r11,r11,8                       ; make a 0 iff this is a 0xFFFFFFF8 trap
             cntlzw  r13,r13                         ; set bit 0x20 iff a 0x7FFx trap
             cntlzw  r11,r11                         ; set bit 0x20 iff a 0xFFFFFFF8 trap
+                       xoris   r0,r0,0x8000                                    ; Flip bit to make 0 iff 0x80000000
             rlwimi  r11,r13,31,0x10                 ; move 0x7FFx bit into position
+                       cntlzw  r13,r0                                                  ; Set bit 0x20 iff 0x80000000
+                       xoris   r0,r0,0x8000                                    ; Flip bit to restore R0
+                       rlwimi  r11,r13,2,0x80                                  ; Set bit 0x80 iff CutTrace
             xori    r13,r0,0x6004                   ; start to check for 0x6004
             rlwimi  r11,r0,1,0xE                    ; move in low 3 bits of syscall number
             cntlzw  r13,r13                         ; set bit 0x20 iff 0x6004
@@ -650,7 +656,8 @@ EXT(exception_entry):
  * 3. If (syscall & 0xFFFFFFF0) == 0xFFFFFFF0, then it is also a UFT and is dispatched here.
  *
  * 4. If (syscall & 0xFFFFF000) == 0x80000000, then it is a "firmware" call and is dispatched in
- *    Firmware.s, though the special "Cut Trace" trap (0x80000000) is handled here in xcpSyscall.
+ *    Firmware.s, though the special "Cut Trace" trap (0x80000000) is handled here as an ultra
+ *    fast trap.
  *
  * 5. If (syscall & 0xFFFFF000) == 0xFFFFF000, and it is not one of the above, then it is a Mach
  *    syscall, which are dispatched in hw_exceptions.s via "mach_trap_table".
@@ -672,62 +679,162 @@ EXT(exception_entry):
  * "scTable" is an array of 2-byte addresses, accessed using a 7-bit index derived from the syscall
  * number as follows:
  *
- *      0x40 (A) - set if syscall number is 0x00006004
- *      0x20 (B) - set if upper 29 bits of syscall number are 0xFFFFFFF8
- *      0x10 (C) - set if upper 29 bits of syscall number are 0x00007FF0
- *      0x0E (D) - low three bits of syscall number
+ *      0x80 (A) - set if syscall number is 0x80000000
+ *      0x40 (B) - set if syscall number is 0x00006004
+ *      0x20 (C) - set if upper 29 bits of syscall number are 0xFFFFFFF8
+ *      0x10 (D) - set if upper 29 bits of syscall number are 0x00007FF0
+ *      0x0E (E) - low three bits of syscall number
  *
  * If you define another UFT, try to use a number in one of the currently decoded ranges, ie one marked
  * "unassigned" below.  The dispatch table and the UFT handlers must reside in the first 32KB of
  * physical memory.
  */
  
-            .align  7                               ; start this table on a cache line
-scTable:                                            ; ABC D
-            .short  uftNormalSyscall-baseR          ; 000 0  these syscalls are not in a reserved range
-            .short  uftNormalSyscall-baseR          ; 000 1  these syscalls are not in a reserved range
-            .short  uftNormalSyscall-baseR          ; 000 2  these syscalls are not in a reserved range
-            .short  uftNormalSyscall-baseR          ; 000 3  these syscalls are not in a reserved range
-            .short  uftNormalSyscall-baseR          ; 000 4  these syscalls are not in a reserved range
-            .short  uftNormalSyscall-baseR          ; 000 5  these syscalls are not in a reserved range
-            .short  uftNormalSyscall-baseR          ; 000 6  these syscalls are not in a reserved range
-            .short  uftNormalSyscall-baseR          ; 000 7  these syscalls are not in a reserved range
-
-            .short  uftNormalSyscall-baseR          ; 001 0  0x7FF0 is unassigned
-            .short  uftNormalSyscall-baseR          ; 001 1  0x7FF1 is Set Thread Info Fast Trap (pass up)
-            .short  uftThreadInfo-baseR             ; 001 2  0x7FF2 is Thread Info
-            .short  uftFacilityStatus-baseR         ; 001 3  0x7FF3 is Facility Status
-            .short  uftLoadMSR-baseR                ; 001 4  0x7FF4 is Load MSR
-            .short  uftNormalSyscall-baseR          ; 001 5  0x7FF5 is the Null FastPath Trap (pass up)
-            .short  uftNormalSyscall-baseR          ; 001 6  0x7FF6 is unassigned
-            .short  uftNormalSyscall-baseR          ; 001 7  0x7FF7 is unassigned
-
-            .short  uftNormalSyscall-baseR          ; 010 0  0xFFFFFFF0 is unassigned
-            .short  uftNormalSyscall-baseR          ; 010 1  0xFFFFFFF1 is unassigned
-            .short  uftNormalSyscall-baseR          ; 010 2  0xFFFFFFF2 is unassigned
-            .short  uftNormalSyscall-baseR          ; 010 3  0xFFFFFFF3 is unassigned
-            .short  uftNormalSyscall-baseR          ; 010 4  0xFFFFFFF4 is unassigned
-            .short  uftNormalSyscall-baseR          ; 010 5  0xFFFFFFF5 is unassigned
-            .short  uftIsPreemptiveTaskEnv-baseR    ; 010 6  0xFFFFFFFE is Blue Box uftIsPreemptiveTaskEnv
-            .short  uftIsPreemptiveTask-baseR       ; 010 7  0xFFFFFFFF is Blue Box IsPreemptiveTask
-
-            .short  WhoaBaby-baseR                  ; 011 0  impossible combination
-            .short  WhoaBaby-baseR                  ; 011 1  impossible combination
-            .short  WhoaBaby-baseR                  ; 011 2  impossible combination
-            .short  WhoaBaby-baseR                  ; 011 3  impossible combination
-            .short  WhoaBaby-baseR                  ; 011 4  impossible combination
-            .short  WhoaBaby-baseR                  ; 011 5  impossible combination
-            .short  WhoaBaby-baseR                  ; 011 6  impossible combination
-            .short  WhoaBaby-baseR                  ; 011 7  impossible combination
-
-            .short  WhoaBaby-baseR                  ; 100 0  0x6000 is an impossible index (diagCall)
-            .short  WhoaBaby-baseR                  ; 100 1  0x6001 is an impossible index (vmm_get_version)
-            .short  WhoaBaby-baseR                  ; 100 2  0x6002 is an impossible index (vmm_get_features)
-            .short  WhoaBaby-baseR                  ; 100 3  0x6003 is an impossible index (vmm_init_context)
-            .short  uftVMM-baseR                    ; 100 4  0x6004 is vmm_dispatch (only some of which are UFTs)
-            .short  WhoaBaby-baseR                  ; 100 5  0x6005 is an impossible index (bb_enable_bluebox)
-            .short  WhoaBaby-baseR                  ; 100 6  0x6006 is an impossible index (bb_disable_bluebox)
-            .short  WhoaBaby-baseR                  ; 100 7  0x6007 is an impossible index (bb_settaskenv)
+            .align  8                               ; start this table on a 256-byte boundry
+scTable:                                            ; ABCD E
+                       .short  uftNormalSyscall-baseR                  ; 0000 0  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0000 1  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0000 2  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0000 3  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0000 4  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0000 5  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0000 6  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0000 7  these syscalls are not in a reserved range
+
+                       .short  uftNormalSyscall-baseR                  ; 0001 0  0x7FF0 is unassigned
+                       .short  uftNormalSyscall-baseR                  ; 0001 1  0x7FF1 is Set Thread Info Fast Trap (pass up)
+                       .short  uftThreadInfo-baseR                             ; 0001 2  0x7FF2 is Thread Info
+                       .short  uftFacilityStatus-baseR                 ; 0001 3  0x7FF3 is Facility Status
+                       .short  uftLoadMSR-baseR                                ; 0001 4  0x7FF4 is Load MSR
+                       .short  uftNormalSyscall-baseR                  ; 0001 5  0x7FF5 is the Null FastPath Trap (pass up)
+                       .short  uftNormalSyscall-baseR                  ; 0001 6  0x7FF6 is unassigned
+                       .short  uftNormalSyscall-baseR                  ; 0001 7  0x7FF7 is unassigned
+
+                       .short  uftNormalSyscall-baseR                  ; 0010 0  0xFFFFFFF0 is unassigned
+                       .short  uftNormalSyscall-baseR                  ; 0010 1  0xFFFFFFF1 is unassigned
+                       .short  uftNormalSyscall-baseR                  ; 0010 2  0xFFFFFFF2 is unassigned
+                       .short  uftNormalSyscall-baseR                  ; 0010 3  0xFFFFFFF3 is unassigned
+                       .short  uftNormalSyscall-baseR                  ; 0010 4  0xFFFFFFF4 is unassigned
+                       .short  uftNormalSyscall-baseR                  ; 0010 5  0xFFFFFFF5 is unassigned
+                       .short  uftIsPreemptiveTaskEnv-baseR    ; 0010 6  0xFFFFFFFE is Blue Box uftIsPreemptiveTaskEnv
+                       .short  uftIsPreemptiveTask-baseR               ; 0010 7  0xFFFFFFFF is Blue Box IsPreemptiveTask
+
+                       .short  WhoaBaby-baseR                                  ; 0011 0  impossible combination
+                       .short  WhoaBaby-baseR                                  ; 0011 1  impossible combination
+                       .short  WhoaBaby-baseR                                  ; 0011 2  impossible combination
+                       .short  WhoaBaby-baseR                                  ; 0011 3  impossible combination
+                       .short  WhoaBaby-baseR                                  ; 0011 4  impossible combination
+                       .short  WhoaBaby-baseR                                  ; 0011 5  impossible combination
+                       .short  WhoaBaby-baseR                                  ; 0011 6  impossible combination
+                       .short  WhoaBaby-baseR                                  ; 0011 7  impossible combination
+
+                       .short  WhoaBaby-baseR                                  ; 0100 0  0x6000 is an impossible index (diagCall)
+                       .short  WhoaBaby-baseR                                  ; 0100 1  0x6001 is an impossible index (vmm_get_version)
+                       .short  WhoaBaby-baseR                                  ; 0100 2  0x6002 is an impossible index (vmm_get_features)
+                       .short  WhoaBaby-baseR                                  ; 0100 3  0x6003 is an impossible index (vmm_init_context)
+                       .short  uftVMM-baseR                                    ; 0100 4  0x6004 is vmm_dispatch (only some of which are UFTs)
+                       .short  WhoaBaby-baseR                                  ; 0100 5  0x6005 is an impossible index (bb_enable_bluebox)
+                       .short  WhoaBaby-baseR                                  ; 0100 6  0x6006 is an impossible index (bb_disable_bluebox)
+                       .short  WhoaBaby-baseR                                  ; 0100 7  0x6007 is an impossible index (bb_settaskenv)
+
+                       .short  uftNormalSyscall-baseR                  ; 0101 0  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0101 1  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0101 2  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0101 3  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0101 4  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0101 5  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0101 6  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0101 7  these syscalls are not in a reserved range
+                       
+                       .short  uftNormalSyscall-baseR                  ; 0110 0  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0110 1  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0110 2  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0110 3  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0110 4  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0110 5  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0110 6  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0110 7  these syscalls are not in a reserved range
+                       
+                       .short  uftNormalSyscall-baseR                  ; 0111 0  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0111 1  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0111 2  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0111 3  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0111 4  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0111 5  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0111 6  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 0111 7  these syscalls are not in a reserved range
+
+                       .short  uftCutTrace-baseR                               ; 1000 0  CutTrace
+                       .short  uftNormalSyscall-baseR                  ; 1000 1  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1000 2  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1000 3  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1000 4  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1000 5  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1000 6  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1000 7  these syscalls are not in a reserved range
+
+                       .short  uftNormalSyscall-baseR                  ; 1001 0  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1001 1  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1001 2  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1001 3  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1001 4  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1001 5  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1001 6  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1001 7  these syscalls are not in a reserved range
+
+                       .short  uftNormalSyscall-baseR                  ; 1010 0  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1010 1  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1010 2  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1010 3  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1010 4  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1010 5  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1010 6  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1010 7  these syscalls are not in a reserved range
+
+                       .short  uftNormalSyscall-baseR                  ; 1011 0  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1011 1  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1011 2  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1011 3  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1011 4  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1011 5  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1011 6  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1011 7  these syscalls are not in a reserved range
+
+                       .short  uftNormalSyscall-baseR                  ; 1100 0  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1100 1  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1100 2  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1100 3  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1100 4  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1100 5  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1100 6  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1100 7  these syscalls are not in a reserved range
+                       
+                       .short  uftNormalSyscall-baseR                  ; 1101 0  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1101 1  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1101 2  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1101 3  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1101 4  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1101 5  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1101 6  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1101 7  these syscalls are not in a reserved range
+                       
+                       .short  uftNormalSyscall-baseR                  ; 1110 0  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1110 1  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1110 2  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1110 3  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1110 4  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1110 5  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1110 6  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1110 7  these syscalls are not in a reserved range
+                       
+                       .short  uftNormalSyscall-baseR                  ; 1111 0  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1111 1  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1111 2  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1111 3  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1111 4  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1111 5  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1111 6  these syscalls are not in a reserved range
+                       .short  uftNormalSyscall-baseR                  ; 1111 7  these syscalls are not in a reserved range
 
             .align  2                               ; prepare for code
 
@@ -823,7 +930,7 @@ uftRFI:
 LEXT(uft_nop_if_32bit)
             b       uftX64                          ; patched to NOP if 32-bit processor
                        
-                       lwz             r11,pfAvailable(r11)                    ; Get the feature flags
+uftX32:                lwz             r11,pfAvailable(r11)                    ; Get the feature flags
                        mfsprg  r13,2                                                   ; Restore R13
                        mtsprg  2,r11                                                   ; Set the feature flags
                        mfsprg  r11,3                                                   ; Restore R11
@@ -839,6 +946,277 @@ uftX64:           mtspr   hsprg0,r14                                              ; Save a register in a Hypervisor SPRG
                        mfspr   r14,hsprg0                                              ; Restore R14
                        rfid                                                                    ; Back to our guy...
 
+;
+;                      Quickly cut a trace table entry for the CutTrace firmware call.
+;
+;                      All registers except R11 and R13 are unchanged.
+;
+;                      Note that this code cuts a trace table entry for the CutTrace call only.
+;                      An identical entry is made during normal interrupt processing.  Any entry
+;                      format entry changes made must be done in both places.
+;
+
+                       .align  5
+                       
+                       .globl  EXT(uft_cuttrace)
+LEXT(uft_cuttrace)
+uftCutTrace:
+                       b               uftct64                                                 ; patched to NOP if 32-bit processor
+
+                       stw             r20,tempr0(r11)                                 ; Save some work registers
+                       lwz             r20,dgFlags(0)                                  ; Get the flags
+                       stw             r21,tempr1(r11)                                 ; Save some work registers
+                       mfsrr1  r21                                                             ; Get the SRR1
+                       rlwinm  r20,r20,MSR_PR_BIT-enaUsrFCallb,MASK(MSR_PR)    ; Shift the validity bit over to pr bit spot
+                       stw             r25,tempr2(r11)                                 ; Save some work registers
+                       orc             r20,r20,r21                                             ; Get ~PR | FC
+                       mfcr    r25                                                             ; Save the CR
+                       stw             r22,tempr3(r11)                                 ; Save some work registers
+                       lhz             r22,PP_CPU_NUMBER(r11)                  ; Get the logical processor number
+                       andi.   r20,r20,MASK(MSR_PR)                    ; Set cr0_eq is we are in problem state and the validity bit is not set
+                       stw             r23,tempr4(r11)                                 ; Save some work registers
+                       lwz             r23,traceMask(0)                                ; Get the trace mask
+                       stw             r24,tempr5(r11)                                 ; Save some work registers
+                       beq-    ctbail32                                                ; Can not issue from user...
+                       
+
+                       addi    r24,r22,16                                              ; Get shift to move cpu mask to syscall mask
+                       rlwnm   r24,r23,r24,12,12                               ; Shift cpu mask bit to rupt type mask
+                       and.    r24,r24,r23                                             ; See if both are on
+
+;
+;                      We select a trace entry using a compare and swap on the next entry field.
+;                      Since we do not lock the actual trace buffer, there is a potential that
+;                      another processor could wrap an trash our entry.  Who cares?
+;
+
+                       li              r23,trcWork                                             ; Get the trace work area address
+                       lwz             r21,traceStart(0)                               ; Get the start of trace table
+                       lwz             r22,traceEnd(0)                                 ; Get end of trace table
+                       
+                       beq--   ctdisa32                                                ; Leave because tracing is disabled...                                  
+
+ctgte32:       lwarx   r20,0,r23                                               ; Get and reserve the next slot to allocate
+                       addi    r24,r20,LTR_size                                ; Point to the next trace entry
+                       cmplw   r24,r22                                                 ; Do we need to wrap the trace table?
+                       bne+    ctgte32s                                                ; No wrap, we got us a trace entry...
+                       
+                       mr              r24,r21                                                 ; Wrap back to start
+
+ctgte32s:      stwcx.  r24,0,r23                                               ; Try to update the current pointer
+                       bne-    ctgte32                                                 ; Collision, try again...
+                       
+#if ESPDEBUG
+                       dcbf    0,r23                                                   ; Force to memory
+                       sync
+#endif
+                       
+                       dcbz    0,r20                                                   ; Clear and allocate first trace line
+                       li              r24,32                                                  ; Offset to next line
+                       
+ctgte32tb:     mftbu   r21                                                             ; Get the upper time now
+                       mftb    r22                                                             ; Get the lower time now
+                       mftbu   r23                                                             ; Get upper again
+                       cmplw   r21,r23                                                 ; Has it ticked?
+                       bne-    ctgte32tb                                               ; Yes, start again...
+
+                       dcbz    r24,r20                                                 ; Clean second line
+
+;
+;                      Let us cut that trace entry now.
+;
+;                      Note that this code cuts a trace table entry for the CutTrace call only.
+;                      An identical entry is made during normal interrupt processing.  Any entry
+;                      format entry changes made must be done in both places.
+;
+
+                       lhz             r24,PP_CPU_NUMBER(r11)                  ; Get the logical processor number
+                       li              r23,T_SYSTEM_CALL                               ; Get the system call id
+                       mtctr   r13                                                             ; Restore the caller's CTR
+                       sth             r24,LTR_cpu(r20)                                ; Save processor number
+                       li              r24,64                                                  ; Offset to third line
+                       sth             r23,LTR_excpt(r20)                              ; Set the exception code
+                       dcbz    r24,r20                                                 ; Clean 3rd line
+                       mfspr   r23,dsisr                                               ; Get the DSISR
+                       stw             r21,LTR_timeHi(r20)                             ; Save top of time stamp
+                       li              r24,96                                                  ; Offset to fourth line
+                       mflr    r21                                                             ; Get the LR
+                       dcbz    r24,r20                                                 ; Clean 4th line
+                       stw             r22,LTR_timeLo(r20)                             ; Save bottom of time stamp
+                       mfsrr0  r22                                                             ; Get SRR0
+                       stw             r25,LTR_cr(r20)                                 ; Save CR
+                       mfsrr1  r24                                                             ; Get the SRR1
+                       stw             r23,LTR_dsisr(r20)                              ; Save DSISR
+                       stw             r22,LTR_srr0+4(r20)                             ; Save SRR0
+                       mfdar   r23                                                             ; Get DAR
+                       stw             r24,LTR_srr1+4(r20)                             ; Save SRR1
+                       stw             r23,LTR_dar+4(r20)                              ; Save DAR
+                       stw             r21,LTR_lr+4(r20)                               ; Save LR
+
+                       stw             r13,LTR_ctr+4(r20)                              ; Save CTR
+                       stw             r0,LTR_r0+4(r20)                                ; Save register
+                       stw             r1,LTR_r1+4(r20)                                ; Save register
+                       stw             r2,LTR_r2+4(r20)                                ; Save register
+                       stw             r3,LTR_r3+4(r20)                                ; Save register
+                       stw             r4,LTR_r4+4(r20)                                ; Save register
+                       stw             r5,LTR_r5+4(r20)                                ; Save register
+                       stw             r6,LTR_r6+4(r20)                                ; Save register
+
+#if 0
+                       lwz             r21,FPUowner(r11)                               ; (TEST/DEBUG) Get the current floating point owner
+                       stw             r21,LTR_rsvd0(r20)                              ; (TEST/DEBUG) Record the owner
+#endif
+                       
+#if ESPDEBUG
+                       addi    r21,r20,32                                              ; Second line
+                       addi    r22,r20,64                                              ; Third line
+                       dcbst   0,r20                                                   ; Force to memory
+                       dcbst   0,r21                                                   ; Force to memory
+                       addi    r21,r22,32                                              ; Fourth line
+                       dcbst   0,r22                                                   ; Force to memory
+                       dcbst   0,r21                                                   ; Force to memory
+                       sync                                                                    ; Make sure it all goes
+#endif
+
+ctdisa32:      mtcrf   0x80,r25                                                ; Restore the used condition register field
+                       lwz             r20,tempr0(r11)                                 ; Restore work register
+                       lwz             r21,tempr1(r11)                                 ; Restore work register
+                       lwz             r25,tempr2(r11)                                 ; Restore work register
+                       mtctr   r13                                                             ; Restore the caller's CTR
+                       lwz             r22,tempr3(r11)                                 ; Restore work register
+                       lwz             r23,tempr4(r11)                                 ; Restore work register
+                       lwz             r24,tempr5(r11)                                 ; Restore work register
+                       b               uftX32                                                  ; Go restore the rest and go...
+
+ctbail32:      mtcrf   0x80,r25                                                ; Restore the used condition register field
+                       lwz             r20,tempr0(r11)                                 ; Restore work register
+                       lwz             r21,tempr1(r11)                                 ; Restore work register
+                       lwz             r25,tempr2(r11)                                 ; Restore work register
+                       mtctr   r13                                                             ; Restore the caller's CTR
+                       lwz             r22,tempr3(r11)                                 ; Restore work register
+                       lwz             r23,tempr4(r11)                                 ; Restore work register
+                       b               uftNormalSyscall                                ; Go pass it on along...
+
+;
+;                      This is the 64-bit version.
+;
+
+uftct64:       std             r20,tempr0(r11)                                 ; Save some work registers
+                       lwz             r20,dgFlags(0)                                  ; Get the flags
+                       std             r21,tempr1(r11)                                 ; Save some work registers
+                       mfsrr1  r21                                                             ; Get the SRR1
+                       rlwinm  r20,r20,MSR_PR_BIT-enaUsrFCallb,MASK(MSR_PR)    ; Shift the validity bit over to pr bit spot
+                       std             r25,tempr2(r11)                                 ; Save some work registers
+                       orc             r20,r20,r21                                             ; Get ~PR | FC
+                       mfcr    r25                                                             ; Save the CR
+                       std             r22,tempr3(r11)                                 ; Save some work registers
+                       lhz             r22,PP_CPU_NUMBER(r11)                  ; Get the logical processor number
+                       andi.   r20,r20,MASK(MSR_PR)                    ; Set cr0_eq when we are in problem state and the validity bit is not set
+                       std             r23,tempr4(r11)                                 ; Save some work registers
+                       lwz             r23,traceMask(0)                                ; Get the trace mask
+                       std             r24,tempr5(r11)                                 ; Save some work registers
+                       beq--   ctbail64                                                ; Can not issue from user...
+
+                       addi    r24,r22,16                                              ; Get shift to move cpu mask to syscall mask
+                       rlwnm   r24,r23,r24,12,12                               ; Shift cpu mask bit to rupt type mask
+                       and.    r24,r24,r23                                             ; See if both are on
+                       
+;
+;                      We select a trace entry using a compare and swap on the next entry field.
+;                      Since we do not lock the actual trace buffer, there is a potential that
+;                      another processor could wrap an trash our entry.  Who cares?
+;
+
+                       li              r23,trcWork                                             ; Get the trace work area address
+                       lwz             r21,traceStart(0)                               ; Get the start of trace table
+                       lwz             r22,traceEnd(0)                                 ; Get end of trace table
+                       
+                       beq--   ctdisa64                                                ; Leave because tracing is disabled...                                  
+
+ctgte64:       lwarx   r20,0,r23                                               ; Get and reserve the next slot to allocate
+                       addi    r24,r20,LTR_size                                ; Point to the next trace entry
+                       cmplw   r24,r22                                                 ; Do we need to wrap the trace table?
+                       bne++   ctgte64s                                                ; No wrap, we got us a trace entry...
+                       
+                       mr              r24,r21                                                 ; Wrap back to start
+
+ctgte64s:      stwcx.  r24,0,r23                                               ; Try to update the current pointer
+                       bne--   ctgte64                                                 ; Collision, try again...
+                       
+#if ESPDEBUG
+                       dcbf    0,r23                                                   ; Force to memory
+                       sync
+#endif
+                       
+                       dcbz128 0,r20                                                   ; Zap the trace entry
+                       
+                       mftb    r21                                                             ; Get the time
+
+;
+;                      Let us cut that trace entry now.
+;
+;                      Note that this code cuts a trace table entry for the CutTrace call only.
+;                      An identical entry is made during normal interrupt processing.  Any entry
+;                      format entry changes made must be done in both places.
+;
+
+                       lhz             r24,PP_CPU_NUMBER(r11)                  ; Get the logical processor number
+                       li              r23,T_SYSTEM_CALL                               ; Get the system call id
+                       sth             r24,LTR_cpu(r20)                                ; Save processor number
+                       sth             r23,LTR_excpt(r20)                              ; Set the exception code
+                       mfspr   r23,dsisr                                               ; Get the DSISR
+                       std             r21,LTR_timeHi(r20)                             ; Save top of time stamp
+                       mflr    r21                                                             ; Get the LR
+                       mfsrr0  r22                                                             ; Get SRR0
+                       stw             r25,LTR_cr(r20)                                 ; Save CR
+                       mfsrr1  r24                                                             ; Get the SRR1
+                       stw             r23,LTR_dsisr(r20)                              ; Save DSISR
+                       std             r22,LTR_srr0(r20)                               ; Save SRR0
+                       mfdar   r23                                                             ; Get DAR
+                       std             r24,LTR_srr1(r20)                               ; Save SRR1
+                       std             r23,LTR_dar(r20)                                ; Save DAR
+                       std             r21,LTR_lr(r20)                                 ; Save LR
+
+                       std             r13,LTR_ctr(r20)                                ; Save CTR
+                       std             r0,LTR_r0(r20)                                  ; Save register
+                       std             r1,LTR_r1(r20)                                  ; Save register
+                       std             r2,LTR_r2(r20)                                  ; Save register
+                       std             r3,LTR_r3(r20)                                  ; Save register
+                       std             r4,LTR_r4(r20)                                  ; Save register
+                       std             r5,LTR_r5(r20)                                  ; Save register
+                       std             r6,LTR_r6(r20)                                  ; Save register
+                       
+#if 0
+                       lwz             r21,FPUowner(r11)                               ; (TEST/DEBUG) Get the current floating point owner
+                       stw             r21,LTR_rsvd0(r20)                              ; (TEST/DEBUG) Record the owner
+#endif
+
+#if ESPDEBUG
+                       dcbf    0,r20                                                   ; Force to memory                       
+                       sync                                                                    ; Make sure it all goes
+#endif
+
+ctdisa64:      mtcrf   0x80,r25                                                ; Restore the used condition register field
+                       ld              r20,tempr0(r11)                                 ; Restore work register
+                       ld              r21,tempr1(r11)                                 ; Restore work register
+                       ld              r25,tempr2(r11)                                 ; Restore work register
+                       mtctr   r13                                                             ; Restore the caller's CTR
+                       ld              r22,tempr3(r11)                                 ; Restore work register
+                       ld              r23,tempr4(r11)                                 ; Restore work register
+                       ld              r24,tempr5(r11)                                 ; Restore work register
+                       b               uftX64                                                  ; Go restore the rest and go...
+
+ctbail64:      mtcrf   0x80,r25                                                ; Restore the used condition register field
+                       ld              r20,tempr0(r11)                                 ; Restore work register
+                       ld              r21,tempr1(r11)                                 ; Restore work register
+                       ld              r25,tempr2(r11)                                 ; Restore work register
+                       mtctr   r13                                                             ; Restore the caller's CTR
+                       ld              r22,tempr3(r11)                                 ; Restore work register
+                       ld              r23,tempr4(r11)                                 ; Restore work register
+                       li              r11,T_SYSTEM_CALL|T_FAM                 ; Set system code call
+                       b               extEntry64                                              ; Go straight to the 64-bit code...
+
+
 
 ;           Handle a system call that is not a UFT and which thus goes upstairs.
 
@@ -1227,6 +1605,10 @@ gotTrcEnt:       stwcx.  r22,0,r23                                               ; Try to update the current pointer
 
 ;
 ;                      Let us cut that trace entry now.
+;
+;                      Note that this code cuts a trace table entry for everything but the CutTrace call.
+;                      An identical entry is made during normal CutTrace processing.  Any entry
+;                      format changes made must be done in both places.
 ;
 
                        lwz             r16,ruptStamp(r2)                               ; Get top of time base
@@ -1551,7 +1933,7 @@ trcselSF: lwarx   r20,0,r23                                               ; Get and reserve the next slot to allocate
                        
                        addi    r22,r20,LTR_size                                ; Point to the next trace entry
                        cmplw   r22,r26                                                 ; Do we need to wrap the trace table?
-                       bne+    gotTrcEntSF                                             ; No wrap, we got us a trace entry...
+                       bne++   gotTrcEntSF                                             ; No wrap, we got us a trace entry...
                        
                        mr              r22,r25                                                 ; Wrap back to start
 
@@ -1566,6 +1948,10 @@ gotTrcEntSF:
 
 ;
 ;                      Let us cut that trace entry now.
+;
+;                      Note that this code cuts a trace table entry for everything but the CutTrace call.
+;                      An identical entry is made during normal CutTrace processing.  Any entry
+;                      format changes made must be done in both places.
 ;
 
                        dcbz128 0,r20                                                   ; Zap the trace entry
@@ -1608,6 +1994,10 @@ gotTrcEntSF:
                        std             r13,LTR_save(r20)                               ; Save the savearea 
                        stw             r17,LTR_dsisr(r20)                              ; Save the DSISR
                        sth             r11,LTR_excpt(r20)                              ; Save the exception type 
+#if 0
+                       lwz             r17,FPUowner(r2)                                ; (TEST/DEBUG) Get the current floating point owner
+                       stw             r17,LTR_rsvd0(r20)                              ; (TEST/DEBUG) Record the owner
+#endif
 
 #if ESPDEBUG
                        dcbf    0,r20                                                   ; Force to memory                       
@@ -3272,8 +3662,16 @@ EXT(mckFlags):
                        .long   0                                                               ; 5028 user memory window virtual address
                        .long   0                                                               ; 502C user memory window virtual address
                        .long   0                                                               ; 5030 VMM boot-args forced feature flags
-                       .long   0                                                               ; 5034 reserved
-                       .long   0                                                               ; 5038 reserved
+
+                       .globl  EXT(maxDec)
+EXT(maxDec):
+                       .long   0x7FFFFFFF                                              ; 5034 maximum decrementer value
+                       
+
+                       .globl  EXT(pmsCtlp)
+EXT(pmsCtlp):
+                       .long   0                                                               ; 5038 Pointer to power management stepper control
+                       
                        .long   0                                                               ; 503C reserved
                        .long   0                                                               ; 5040 reserved
                        .long   0                                                               ; 5044 reserved