]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/ppc/Firmware.s
xnu-344.23.tar.gz
[apple/xnu.git] / osfmk / ppc / Firmware.s
index 21743295a41658a9927bdf4c1ca365076f2e5cd8..3c16dd1dfbc330ed82f0a438222e6562d7fe0c43 100644 (file)
@@ -3,22 +3,19 @@
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
+ * 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.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * This 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, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
@@ -43,6 +40,7 @@
 #include <ppc/asm.h>
 #include <ppc/proc_reg.h>
 #include <ppc/spec_reg.h>
+#include <ppc/POWERMAC/mp/MPPlugIn.h>
 #include <ppc/exception.h>
 #include <mach/machine/vm_param.h>
 #include <assym.s>
@@ -82,57 +80,54 @@ EXT(FWtable):
  *                     R3 is as passed in by the user.  All others must be gotten from the save area
  */
 
-
-                       .align  5
-                       .globl  EXT(FirmwareCall)
-
-LEXT(FirmwareCall)
+ENTRY(FirmwareCall, TAG_NO_FRAME_USED)
                
                        rlwinm  r1,r0,2,1,29                                    /* Clear out bit 0 and multiply by 4 */
                        lis             r12,HIGH_ADDR(EXT(FWtable))             /* Get the high part of the firmware call table */
                        cmplwi  r1,EXT(FirmwareCnt)*4                   /* Is it a valid firmware call number */
+                       mflr    r11                                                             /* Save the return */
                        ori             r12,r12,LOW_ADDR(EXT(FWtable))  /* Now the low part */
                        ble+    goodCall                                                /* Yeah, it is... */
                        
                        li              r3,T_SYSTEM_CALL                                /* Tell the vector handler that we know nothing */
-                       b               EXT(FCReturn)                                   ; Bye dudes...
+                       blr                                                                             /* Return for errors... */
                        
 goodCall:      mfsprg  r10,0                                                   /* Make sure about the per_proc block */
                        lwzx    r1,r1,r12                                               /* Pick up the address of the routine */
-                       lwz             r4,saver4+4(r13)                                /* Pass in caller's R4 */
-                       lwz             r5,saver5+4(r13)                                /* Pass in caller's R5 */
+                       lwz             r4,saver4(r13)                                  /* Pass in caller's R4 */
+                       lwz             r5,saver5(r13)                                  /* Pass in caller's R5 */
                        rlwinm. r1,r1,0,0,29                                    /* Make sure the flag bits are clear */
+                       stw             r11,PP_TEMPWORK1(r10)                   /* Save our return point */
 
                        mtlr    r1                                                              /* Put it in the LR */
                        beq-    callUnimp                                               /* This one was unimplimented... */
 
                        blrl                                                                    /* Call the routine... */
 
-                       stw             r3,saver3+4(r13)                                /* Pass back the return code to caller */
+                       mfsprg  r10,0                                                   /* Make sure about the per_proc again */
+                       stw             r3,saver3(r13)                                  /* Pass back the return code to caller */
+                       lwz             r11,PP_TEMPWORK1(r10)                   /* Get our return point */
                        li              r3,T_IN_VAIN                                    /* Tell the vector handler that we took care of it */
-                       b               EXT(FCReturn)                                   ; Bye dudes...
+                       mtlr    r11                                                             /* Set the return */
+                       blr                                                                             /* Bye, dudes... */
        
-callUnimp:     li              r3,T_SYSTEM_CALL                                /* Tell the vector handler that we know nothing */
-                       b               EXT(FCReturn)                                   ; Bye dudes...
+callUnimp:     lwz             r11,PP_TEMPWORK1(r10)                   /* Restore the return address */
+                       li              r3,T_SYSTEM_CALL                                /* Tell the vector handler that we know nothing */
+                       mtlr    r11                                                             /* Restore the LR */
+                       blr                                                                             /* Return for errors... */
 
 /*
  *                     This routine is used to store using a real address. It stores parmeter1 at parameter2.
  */
 
-                       .align  5
-                       .globl  EXT(StoreReal)
-
-LEXT(StoreReal)
+ENTRY(StoreReal, TAG_NO_FRAME_USED)
 
                        lis             r0,HIGH_ADDR(StoreRealCall)             /* Get the top part of the SC number */
                        ori             r0,r0,LOW_ADDR(StoreRealCall)   /* and the bottom part */
                        sc                                                                              /* Do it to it */
                        blr                                                                             /* Bye bye, Birdie... */
                        
-                       .align  5
-                       .globl  EXT(StoreRealLL)
-
-LEXT(StoreRealLL)
+ENTRY(StoreRealLL, TAG_NO_FRAME_USED)
 
                        stw             r3,0(r4)                                                /* Store the word */
                        blr                                                                             /* Leave... */
@@ -140,22 +135,15 @@ LEXT(StoreRealLL)
 /*
  *                     This routine is used to clear a range of physical pages.
  */
-                       
-                       .align  5
-                       .globl  EXT(ClearReal)
 
-LEXT(ClearReal)
+ENTRY(ClearReal, TAG_NO_FRAME_USED)
 
                        lis             r0,HIGH_ADDR(ClearRealCall)             /* Get the top part of the SC number */
                        ori             r0,r0,LOW_ADDR(ClearRealCall)   /* and the bottom part */
                        sc                                                                              /* Do it to it */
                        blr                                                                             /* Bye bye, Birdie... */
                        
-                       
-                       .align  5
-                       .globl  EXT(ClearRealLL)
-
-LEXT(ClearRealLL)
+ENTRY(ClearRealLL, TAG_NO_FRAME_USED)
 
 /*
  *                     We take the first parameter as a physical address.  The second is the length in bytes.
@@ -184,56 +172,30 @@ clrloop:  subi    r4,r4,32                                                /* Back off a cache line */
 /*
  *                     This routine will read in 32 byte of real storage.
  */
-                       
-                       .align  5
-                       .globl  EXT(ReadReal)
-
-LEXT(ReadReal)
-
-                       mfsprg  r9,2                                                    ; Get the features
-                       mfmsr   r0                                                              ; Get the MSR 
-                       li              r8,lo16(MASK(MSR_DR))                   ; Get the DR bit
-                       rlwinm. r9,r9,0,pf64Bitb,pf64Bitb               ; Are we 64-bit?
-                       ori             r8,r8,lo16(MASK(MSR_EE))                ; Add in the EE bit
-                       li              r7,1                                                    ; Get set for it
-                       andc    r8,r0,r8                                                ; Turn off EE and DR
-                       bt--    cr0_eq,rr32a                                    ; Yes, we are...
-                       
-                       rldimi  r8,r7,63,MSR_SF_BIT                             ; Set SF bit (bit 0)
-                       sldi    r3,r3,32                                                ; Slide on over for true 64-bit address
-                       mtmsrd  r8
-                       isync
-                       or              r3,r3,r4                                                ; Join top and bottom of address
-                       mr              r4,r5                                                   ; Set destination address
-                       b               rrJoina                                                 ; Join on up...
-                       
-rr32a:         mr              r3,r4                                                   ; Position bottom of long long
-                       mr              r4,r5                                                   ; Set destination address
-                       mtmsr   r8                                                              /* Disable EE and DR */
+ENTRY(ReadReal, TAG_NO_FRAME_USED)
+
+                       mfmsr   r0                                                              /* Get the MSR */
+                       rlwinm  r5,r0,0,28,26                                   /* Clear DR bit */
+                       rlwinm  r5,r5,0,17,15                                   /* Clear EE bit */
+                       mtmsr   r5                                                              /* Disable EE and DR */
                        isync                                                                   /* Just make sure about it */
                        
-rrJoina:       lwz             r5,0(r3)                                                /* Get word 0 */
+                       lwz             r5,0(r3)                                                /* Get word 0 */
                        lwz             r6,4(r3)                                                /* Get word 1 */
                        lwz             r7,8(r3)                                                /* Get word 2 */
                        lwz             r8,12(r3)                                               /* Get word 3 */
-                       lis             r2,hi16(MASK(MSR_VEC))                  ; Get the vector enable 
+                       rlwinm  r0,r0,0,MSR_FP_BIT+1,MSR_FP_BIT-1       ; Force floating point off
                        lwz             r9,16(r3)                                               /* Get word 4 */
-                       ori             r2,r2,lo16(MASK(MSR_FP))                ; Get the FP enable 
                        lwz             r10,20(r3)                                              /* Get word 5 */
-                       andc    r0,r0,r2                                                ; Clear VEC and FP enables
+                       rlwinm  r0,r0,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1     ; Force vectors off
                        lwz             r11,24(r3)                                              /* Get word 6 */
                        lwz             r12,28(r3)                                              /* Get word 7 */
                        
-                       bt--    cr0_eq,rr32b                                    ; We are not 64-bit...
-
-                       mtmsrd  r0
-                       isync
-                       b               rrJoinb                                                 ; Join on up...
-
-rr32b:         mtmsr   r0                                                              /* Restore original machine state */
+                       mtmsr   r0                                                              /* Restore original machine state */
                        isync                                                                   /* Insure goodness */
                        
-rrJoinb:       stw             r5,0(r4)                                                /* Set word 0 */
+                       stw             r5,0(r4)                                                /* Set word 0 */
                        stw             r6,4(r4)                                                /* Set word 1 */
                        stw             r7,8(r4)                                                /* Set word 2 */
                        stw             r8,12(r4)                                               /* Set word 3 */
@@ -248,12 +210,8 @@ rrJoinb:   stw             r5,0(r4)                                                /* Set word 0 */
 /*
  *                     This routine is used to load all 4 DBATs.
  */
-                       
-                       .align  5
-                       .globl  EXT(LoadDBATs)
-
-LEXT(LoadDBATs)
 
+ENTRY(LoadDBATs, TAG_NO_FRAME_USED)
 
                        lis             r0,HIGH_ADDR(LoadDBATsCall)             /* Top half of LoadDBATsCall firmware call number */
                        ori             r0,r0,LOW_ADDR(LoadDBATsCall)   /* Bottom half */
@@ -261,11 +219,7 @@ LEXT(LoadDBATs)
 
                        blr                                                                             /* Bye bye, Birdie... */
                        
-                       
-                       .align  5
-                       .globl  EXT(xLoadDBATsLL)
-
-LEXT(xLoadDBATsLL)
+ENTRY(xLoadDBATsLL, TAG_NO_FRAME_USED)
 
                        lwz             r4,0(r3)                                                /* Get DBAT 0 high */
                        lwz             r5,4(r3)                                                /* Get DBAT 0 low */
@@ -294,21 +248,14 @@ LEXT(xLoadDBATsLL)
  *                     This routine is used to load all 4 IBATs.
  */
 
-                       .align  5
-                       .globl  EXT(LoadIBATs)
-
-LEXT(LoadIBATs)
-
+ENTRY(LoadIBATs, TAG_NO_FRAME_USED)
 
                        lis             r0,HIGH_ADDR(LoadIBATsCall)             /* Top half of LoadIBATsCall firmware call number */
                        ori             r0,r0,LOW_ADDR(LoadIBATsCall)   /* Bottom half */
                        sc                                                                              /* Do it to it */
                        blr                                                                             /* Bye bye, Birdie... */
                        
-                       .align  5
-                       .globl  EXT(xLoadIBATsLL)
-
-LEXT(xLoadIBATsLL)
+ENTRY(xLoadIBATsLL, TAG_NO_FRAME_USED)
 
                        lwz             r4,0(r3)                                                /* Get IBAT 0 high */
                        lwz             r5,4(r3)                                                /* Get IBAT 0 low */
@@ -337,11 +284,8 @@ LEXT(xLoadIBATsLL)
 /*
  *                     This is the glue to call the CutTrace firmware call
  */
-                       
-                       .align  5
-                       .globl  EXT(dbgTrace)
-
-LEXT(dbgTrace)
+ENTRY(dbgTrace, TAG_NO_FRAME_USED)
                        
                        lis             r0,HIGH_ADDR(CutTrace)                  /* Top half of CreateFakeIO firmware call number */
                        ori             r0,r0,LOW_ADDR(CutTrace)                /* Bottom half */
@@ -351,11 +295,8 @@ LEXT(dbgTrace)
 /*
  *                     This is the glue to create a fake I/O interruption
  */
-                       
-                       .align  5
-                       .globl  EXT(CreateFakeIO)
-
-LEXT(CreateFakeIO)
+ENTRY(CreateFakeIO, TAG_NO_FRAME_USED)
                        
                        lis             r0,HIGH_ADDR(CreateFakeIOCall)  /* Top half of CreateFakeIO firmware call number */
                        ori             r0,r0,LOW_ADDR(CreateFakeIOCall)        /* Bottom half */
@@ -365,18 +306,14 @@ LEXT(CreateFakeIO)
 /*
  *                     This is the glue to create a fake Dec interruption
  */
-                       
-                       .align  5
-                       .globl  EXT(CreateFakeDEC)
-
-LEXT(CreateFakeDEC)
+ENTRY(CreateFakeDEC, TAG_NO_FRAME_USED)
                        
 #if 0
                        mflr    r4                                                              ; (TEST/DEBUG)
                        bl              EXT(ml_sense_nmi)                               ; (TEST/DEBUG)
                        mtlr    r4                                                              ; (TEST/DEBUG)
-#endif                 
-                       
+#endif
                        lis             r0,HIGH_ADDR(CreateFakeDECCall) /* Top half of CreateFakeDEC firmware call number */
                        ori             r0,r0,LOW_ADDR(CreateFakeDECCall)       /* Bottom half */
                        sc                                                                              /* Do it to it */
@@ -387,10 +324,7 @@ LEXT(CreateFakeDEC)
  *                     This is the glue to create a shutdown context
  */
  
-                       .align  5
-                       .globl  EXT(CreateShutdownCTX)
-
-LEXT(CreateShutdownCTX)
+ENTRY(CreateShutdownCTX, TAG_NO_FRAME_USED)
                        
                        lis             r0,HIGH_ADDR(CreateShutdownCTXCall)     /* Top half of CreateFakeIO firmware call number */
                        ori             r0,r0,LOW_ADDR(CreateShutdownCTXCall)   /* Bottom half */
@@ -400,11 +334,8 @@ LEXT(CreateShutdownCTX)
 /*
  *                     This is the glue to choke system
  */
-  
-                       .align  5
-                       .globl  EXT(ChokeSys)
-
-LEXT(ChokeSys)
+ENTRY(ChokeSys, TAG_NO_FRAME_USED)
                        
                        lis             r0,HIGH_ADDR(Choke)                             /* Top half of Choke firmware call number */
                        ori             r0,r0,LOW_ADDR(Choke)                   /* Bottom half */
@@ -415,11 +346,8 @@ LEXT(ChokeSys)
  *                     Used to initialize the SCC for debugging output
  */
 
-  
-                       .align  5
-                       .globl  EXT(fwSCCinit)
 
-LEXT(fwSCCinit)
+ENTRY(fwSCCinit, TAG_NO_FRAME_USED)
                
                        mfmsr   r8                                                                              /* Save the MSR */
                        mr.             r3,r3                                                                   /* See if printer or modem */
@@ -704,11 +632,8 @@ wSCCrdy:   eieio                                                                                   /* Barricade it */
  *                     This routine is used to write debug output to either the modem or printer port.
  *                     parm 1 is printer (0) or modem (1); parm 2 is ID (printed directly); parm 3 converted to hex
  */
-  
-                       .align  5
-                       .globl  EXT(dbgDisp)
 
-LEXT(dbgDisp)
+ENTRY(dbgDisp, TAG_NO_FRAME_USED)
 
                        mr              r12,r0                                                                  /* Keep R0 pristene */
                        lis             r0,HIGH_ADDR(dbgDispCall)                               /* Top half of dbgDispCall firmware call number */
@@ -721,10 +646,7 @@ LEXT(dbgDisp)
                        
 /*                     Here's the low-level part of dbgDisp                    */
 
-                       .align  5
-                       .globl  EXT(dbgDispLL)
-
-LEXT(dbgDispLL)
+ENTRY(dbgDispLL, TAG_NO_FRAME_USED)
 
 dbgDispInt:    mfmsr   r8                                                                              /* Save the MSR */
 
@@ -1107,22 +1029,21 @@ hexTab:         STRINGD "0123456789ABCDEF"                                              /* Convert hex numbers to printable hex
  */
  
 
-                       .align  5
-                       .globl  EXT(dbgRegsLL)
-
-LEXT(dbgRegsLL)
+ENTRY(dbgRegsLL, TAG_NO_FRAME_USED)
 
-                       b               EXT(FCReturn)                                   ; Bye dudes...
-#if 0
                        li              r3,0                                                                    /* ? */
                        bl              dbgRegsCm                                                               /* Join on up... */
-                       b               EXT(FCReturn)                                   ; Bye dudes...
-                       
-                       
-                       .align  5
-                       .globl  EXT(dbgRegs)
 
-LEXT(dbgRegs)
+/*
+ *                     Note that we bypass the normal return 'cause we don't wanna mess up R3
+ */
+                       mfsprg  r11,0                                                                   /* Get the per_proc */
+                       lwz             r11,PP_TEMPWORK1(r11)                                   /* Get our return point */
+                       li              r3,T_IN_VAIN                                                    /* Tell the vector handler that we took care of it */
+                       mtlr    r11                                                                             /* Set the return */
+                       blr                                                                                             /* Bye, dudes... */
+                       
+ENTRY(dbgRegs, TAG_NO_FRAME_USED)
 
 dbgRegsCm:     mfmsr   r8                                                                              /* Save the MSR */
                        mr.             r3,r3                                                                   /* ? */
@@ -1507,17 +1428,14 @@ ddwait1:        lwarx   r5,0,r3                                                                 /* Get the lock */
                        mtmsr   r8                                                                              /* Restore the MSR */
                        isync                                                                                   /* Wait for it */
                        blr                                                                                             /* Leave... */
-#endif                 
+                       
                        
 /*
  *                     Used for debugging to leave stuff in 0x380-0x3FF (128 bytes).
  *                     Mapping is V=R.  Stores and loads are real.
  */
-                       
-                       .align  5
-                       .globl  EXT(dbgCkpt)
 
-LEXT(dbgCkpt)
+ENTRY(dbgCkpt, TAG_NO_FRAME_USED)
 
                        mr              r12,r0                                                                  /* Keep R0 pristene */
                        lis             r0,HIGH_ADDR(dbgCkptCall)                               /* Top half of dbgCkptCall firmware call number */
@@ -1530,11 +1448,7 @@ LEXT(dbgCkpt)
                        
 /*                     Here's the low-level part of dbgCkpt                    */
 
-                       .align  5
-                       .globl  EXT(dbgCkptLL)
-
-LEXT(dbgCkptLL)
-
+ENTRY(dbgCkptLL, TAG_NO_FRAME_USED)
 
                        li              r12,0x380                                                               /* Point to output area */
                        li              r1,32                                                                   /* Get line size */
@@ -1639,14 +1553,14 @@ LEXT(dbgCkptLL)
  *                     Do Preemption.  Forces a T_PREEMPT trap to allow a preemption to occur.
  */
 
-                       .align  5
-                       .globl  EXT(DoPreemptLL)
-
-LEXT(DoPreemptLL)
+ENTRY(DoPreemptLL, TAG_NO_FRAME_USED)
 
+                       mfsprg  r11,0                                                   /* Get the per_proc address */
+                       lwz             r11,PP_TEMPWORK1(r11)                   /* Restore the return address */
                        li              r3,T_PREEMPT                                    /* Set preemption interrupt value */
+                       mtlr    r11                                                             /* Restore the LR */
                        stw             r3,saveexception(r13)                   /* Modify the exception type to preemption */
-                       b               EXT(FCReturn)                                   ; Bye dudes...
+                       blr                                                                             /* Return to interrupt handler */
 
                        
 /*
@@ -1656,14 +1570,14 @@ LEXT(DoPreemptLL)
  *                     Forces a T_CSWITCH
  */
 
-                       .align  5
-                       .globl  EXT(SwitchContextLL)
-
-LEXT(SwitchContextLL)
+ENTRY(SwitchContextLL, TAG_NO_FRAME_USED)
 
+                       mfsprg  r11,0                                                   /* Get the per_proc address */
+                       lwz             r11,PP_TEMPWORK1(r11)                   /* Restore the return address */
                        li              r3,T_CSWITCH                                    /* Set context switch value */
+                       mtlr    r11                                                             /* Restore the LR */
                        stw             r3,saveexception(r13)                   /* Modify the exception type to switch context */
-                       b               EXT(FCReturn)                                   ; Bye dudes...
+                       blr                                                                             /* Return to interrupt handler */
 
                        
 /*
@@ -1671,106 +1585,92 @@ LEXT(SwitchContextLL)
  *                     Forces a T_INTERRUPT trap to pretend that an actual I/O interrupt occurred.
  */
 
-                       .align  5
-                       .globl  EXT(CreateFakeIOLL)
-
-LEXT(CreateFakeIOLL)
+ENTRY(CreateFakeIOLL, TAG_NO_FRAME_USED)
 
+                       mfsprg  r11,0                                                   /* Get the per_proc address */
+                       lwz             r11,PP_TEMPWORK1(r11)                   /* Restore the return address */
                        li              r3,T_INTERRUPT                                  /* Set external interrupt value */
+                       mtlr    r11                                                             /* Restore the LR */
                        stw             r3,saveexception(r13)                   /* Modify the exception type to external */
-                       b               EXT(FCReturn)                                   ; Bye dudes...
+                       blr                                                                             /* Return to interrupt handler */
                        
 /*
  *                     Create a shutdown context
  *                     Forces a T_SHUTDOWN trap.
  */
 
-                       .align  5
-                       .globl  EXT(CreateShutdownCTXLL)
-
-LEXT(CreateShutdownCTXLL)
+ENTRY(CreateShutdownCTXLL, TAG_NO_FRAME_USED)
 
+                       mfsprg  r11,0                                                   /* Get the per_proc address */
+                       lwz             r11,PP_TEMPWORK1(r11)                   /* Restore the return address */
                        li              r3,T_SHUTDOWN                                   /* Set external interrupt value */
+                       mtlr    r11                                                             /* Restore the LR */
                        stw             r3,saveexception(r13)                   /* Modify the exception type to external */
-                       b               EXT(FCReturn)                                   ; Bye dudes...
+                       blr                                                                             /* Return to interrupt handler */
                        
 /*
  *                     Create a fake decrementer 'rupt.  
  *                     Forces a T_DECREMENTER trap to pretend that an actual decrementer interrupt occurred.
  */
 
-                       .align  5
-                       .globl  EXT(CreateFakeDECLL)
-
-LEXT(CreateFakeDECLL)
+ENTRY(CreateFakeDECLL, TAG_NO_FRAME_USED)
 
+                       mfsprg  r11,0                                                   /* Get the per_proc address */
+                       lwz             r11,PP_TEMPWORK1(r11)                   /* Restore the return address */
                        li              r3,T_DECREMENTER                                /* Set decrementer interrupt value */
+                       mtlr    r11                                                             /* Restore the LR */
                        stw             r3,saveexception(r13)                   /* Modify the exception type to external */
-                       b               EXT(FCReturn)                                   ; Bye dudes...
+                       blr                                                                             /* Return to interrupt handler */
 
 /*
  *                     Choke the system.  
  */
 
-                       .align  5
-                       .globl  EXT(DoChokeLL)
-
-LEXT(DoChokeLL)
+ENTRY(DoChokeLL, TAG_NO_FRAME_USED)
 
+                       mfsprg  r11,0                                                   ; Get the per_proc address 
+                       lwz             r11,PP_TEMPWORK1(r11)                   ; Restore the return address 
                        li              r3,T_CHOKE                                              ; Set external interrupt value
+                       mtlr    r11                                                             ; Restore the LR 
                        stw             r3,saveexception(r13)                   ; Modify the exception type to external
-                       b               EXT(FCReturn)                                   ; Bye dudes...
-
+                       blr                                                                             ; Return to interrupt handler 
+                       
 /*
- *                     Null firmware call 
+ *                     Set the low level trace flags 
  */
+ENTRY(LLTraceSet, TAG_NO_FRAME_USED)
 
-                       .align  5
-                       .globl  EXT(NullLL)
-
-LEXT(NullLL)
-
-                       li              r3,T_IN_VAIN                                    ; Set to just ignore this one
-                       b               EXT(FCReturn)                                   ; Bye dudes...
-
-;
-;                      Null firmware call 
-;
-
-                       .align  5
-                       .globl  EXT(iNullLL)
-
-LEXT(iNullLL)
+                       mfsprg  r6,2                                                    ; Get feature flags 
+                       mfmsr   r12                                                             /* Get the MSR */
+                       mr              r4,r3                                                   /* Save the new value */
+                       andi.   r3,r12,0x01C0                                   /* Clear interrupts and translation */
+                       mtcrf   0x04,r6                                                 ; Set the features                      
+                       bt              pfNoMSRirb,ltsNoMSR                             ; Use MSR...
 
-                       mfspr   r4,pmc1                                                 ; Get stamp
-                       stw             r4,0x6100+(9*16)+0x0(0)                 ; Save it
-#if 1
-                       mfspr   r4,pmc2                                                 ; Get stamp
-                       stw             r4,0x6100+(9*16)+0x4(0)                 ; Save it
-                       mfspr   r4,pmc3                                                 ; Get stamp
-                       stw             r4,0x6100+(9*16)+0x8(0)                 ; Save it
-                       mfspr   r4,pmc4                                                 ; Get stamp
-                       stw             r4,0x6100+(9*16)+0xC(0)                 ; Save it
-#endif
-                       li              r3,T_IN_VAIN                                    ; Set to just ignore this one
-                       b               EXT(FCReturn)                                   ; Bye dudes...
+                       mtmsr   r3                                                              ; Translation and all off
+                       isync                                                                   ; Toss prefetch
+                       b               ltsNoMSRx
                        
-;
-;                      Set the low level trace flags 
-;
-                       .align  5
-                       .globl  EXT(LLTraceSet)
+ltsNoMSR:      li              r0,loadMSR                                              ; Get the MSR setter SC
+                       sc                                                                              ; Set it
 
-LEXT(LLTraceSet)
-
-                       mr              r4,r3                                                   ; Save the new value 
+ltsNoMSRx:
+                       
+                       lis             r5,hi16(EXT(trcWork))                   ; Get trace area
+                       rlwinm  r12,r12,0,MSR_FP_BIT+1,MSR_FP_BIT-1     ; Force floating point off
+                       ori             r5,r5,lo16(EXT(trcWork))                ; again
+                       
+                       lwz             r3,traceMask(r5)                                /* Get the old trace flags to pass back */
+                       rlwinm  r12,r12,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1   ; Force vectors off
+                       stw             r4,traceMask(r5)                                /* Replace with the new ones */
+                       
+                       mtmsr   r12                                                             /* Restore the MSR */
+                       isync
                        
-                       lwz             r3,traceMask(0)                                 ; Get the old trace flags to pass back 
-                       stw             r4,traceMask(0)                                 ; Replace with the new ones
-                       blr                                                                             ; Leave... 
+                       blr                                                                             /* Leave... */
 
-#if 0
+#if 1
        
 /*
 ; ***************************************************************************
@@ -1795,11 +1695,7 @@ LEXT(LLTraceSet)
 #define GDfromright 20
 #define GDfontsize 16
 
-                       .align  5
-                       .globl  EXT(GratefulDeb)
-
-LEXT(GratefulDeb)
-
+ENTRY(GratefulDeb,TAG_NO_FRAME_USED)
                        mfspr   r6,pir                                                  /* Get the PIR */
                        lis             r5,HIGH_ADDR(EXT(GratefulDebWork))      /* Point to our work area */
                        rlwinm  r6,r6,8,23,23                                   /* Get part of the offset to our processors area */
@@ -1929,10 +1825,7 @@ GDbailout:       mr              r1,r31                                                  /* Move the workarea base */
  */
 
 
-                       .align  5
-                       .globl  EXT(GratefulDebDisp)
-
-LEXT(GratefulDebDisp)
+ENTRY(GratefulDebDisp,TAG_NO_FRAME_USED)
 
                        mfmsr   r9                                                              /* Save the current MSR */
                        mflr    r7                                                              /* Save the return */
@@ -1953,26 +1846,22 @@ LEXT(GratefulDebDisp)
  */
 
 
-                       .align  5
-                       .globl  EXT(checkNMI)
-
-LEXT(checkNMI)
+ENTRY(checkNMI,TAG_NO_FRAME_USED)
                
                        mfmsr   r9                                                              /* Save it */
                        andi.   r8,r9,0x7FCF                                    /* Clear it */
                        mtmsr   r8                                                              /* Disable it */
                        isync                                                                   /* Fence it */
                        lis             r7,0xF300                                               /* Find it */
-                       lis             r2,hi16(MASK(MSR_VEC))                  ; Get the vector enable 
                        ori             r7,r7,0x0020                                    /* Find it */
-                       ori             r2,r2,lo16(MASK(MSR_FP))                ; Get the FP enable 
                        dcbi    0,r7                                                    /* Toss it */
                        sync                                                                    /* Sync it */
-                       andc    r9,r9,r2                                                ; Clear VEC and FP enables
+                       rlwinm  r9,r9,0,MSR_FP_BIT+1,MSR_FP_BIT-1       ; Force floating point off
                        eieio                                                                   /* Get it */
                        lwz             r6,0x000C(r7)                                   /* Check it */
                        eieio                                                                   /* Fence it */
                        dcbi    0,r7                                                    /* Toss it */
+                       rlwinm  r9,r9,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1     ; Force vectors off
                        rlwinm. r4,r6,0,19,19                                   /* Check it */
                        rlwinm  r6,r6,0,20,18                                   /* Clear it */
                        sync                                                                    /* Sync it */
@@ -1995,6 +1884,193 @@ xnonmi:                                                                                         /* Label it */
                        isync                                                                   /* Hold it */
                        blr                                                                             /* Return from it */
 
+
+/*
+ *                     Early debug code
+ */
+dumpr7:                lis             r9,HIGH_ADDR(hexTab)    /* (TEST/DEBUG) */
+                       li              r5,8                                    /* (TEST/DEBUG) */
+                       ori             r9,r9,LOW_ADDR(hexTab)  /* (TEST/DEBUG) */
+
+dumpr7n:       rlwinm  r7,r7,4,0,31            /* (TEST/DEBUG) */
+                       mr              r6,r7                           /* (TEST/DEBUG) */
+                       andi.   r6,r6,15                        /* (TEST/DEBUG) */
+                       lbzx    r6,r9,r6                        /* (TEST/DEBUG) */
+                       lis             r10,0xF301                      /* (TEST/DEBUG) */
+                       ori             r10,r10,0x2000          /* (TEST/DEBUG) */
+
+#if 0
+xqrw2:         eieio                                           /* (TEST/DEBUG) */
+                       lbz             r7,0(r10)                       /* (TEST/DEBUG) */
+                       dcbi    0,r10                           /* (TEST/DEBUG) */
+                       sync                                            /* (TEST/DEBUG) */
+                       andi.   r7,r7,0x04                      /* (TEST/DEBUG) */
+                       beq             xqrw2                           /* (TEST/DEBUG) */
+#endif
+                       
+                       dcbf    0,r10                           /* (TEST/DEBUG) */
+                       sync                                            /* (TEST/DEBUG) */
+                       dcbi    0,r10                           /* (TEST/DEBUG) */
+                       eieio                                           /* (TEST/DEBUG) */
+                       stb             r6,4(r10)                       /* (TEST/DEBUG) */
+                       
+                       lis             r6,10                           /* (TEST/DEBUG) */
+dumpr7d:       addi    r6,r6,-1                        /* (TEST/DEBUG) */
+                       mr.             r6,r6                           /* (TEST/DEBUG) */
+                       bne-    dumpr7d                         /* (TEST/DEBUG) */
+                       dcbf    0,r10                           /* (TEST/DEBUG) */
+                       sync                                            /* (TEST/DEBUG) */
+                       dcbi    0,r10                           /* (TEST/DEBUG) */
+                       eieio                                           /* (TEST/DEBUG) */
+               
+                       addic.  r5,r5,-1                        /* (TEST/DEBUG) */
+                       bne+    dumpr7n                         /* (TEST/DEBUG) */
+
+                       blr                                                     /* (TEST/DEBUG) */
+
+;                      
+;                      Log a special entry in physical memory.
+;                      This assumes that memory size has been significantly lowered using
+;                      the maxmem boot option. The buffer starts just after the end of mem_size.
+;
+;                      This is absolutely for special tracing cases. Do not ever leave in...
+;
+
+ENTRY(dbgLog,TAG_NO_FRAME_USED)
+
+                       li              r11,0                           ; Clear callers callers callers return
+                       li              r10,0                           ; Clear callers callers callers callers return
+                       li              r9,0                            ; Clear callers callers callers callers callers return
+                       lwz             r2,0(r1)                        ; Get callers callers stack frame
+                       lis             r0,0x4000                       ; First invalid address
+                       lwz             r12,8(r2)                       ; Get our callers return
+                       lwz             r2,0(r2)                        ; Back chain
+
+                       mr.             r2,r2                           ; End of chain?
+                       cmplw   cr1,r2,r0                       ; Valid kernel address?
+                       beq-    nosavehere                      ; Yes, end of chain...
+                       bge-    cr1,nosavehere          ; No...
+                       lwz             r11,8(r2)                       ; Get our callers return
+                       lwz             r2,0(r2)                        ; Back chain
+
+                       mr.             r2,r2                           ; End of chain?
+                       cmplw   cr1,r2,r0                       ; Valid kernel address?
+                       beq-    nosavehere                      ; Yes, end of chain...
+                       bge-    cr1,nosavehere          ; No...
+                       lwz             r10,8(r2)                       ; Get our callers return
+                       lwz             r2,0(r2)                        ; Back chain
+
+                       mr.             r2,r2                           ; End of chain?
+                       cmplw   cr1,r2,r0                       ; Valid kernel address?
+                       beq-    nosavehere                      ; Yes, end of chain...
+                       bge-    cr1,nosavehere          ; No...
+                       lwz             r9,8(r2)                        ; Get our callers return
+
+nosavehere:    mfmsr   r8                                      ; Get the MSR   
+                       lis             r2,hi16(EXT(DebugWork)) ; High part of area
+                       lis             r7,hi16(EXT(mem_actual))        ; High part of actual
+                       andi.   r0,r8,0x7FCF            ; Interrupts and translation off
+                       ori             r2,r2,lo16(EXT(DebugWork))      ; Get the entry
+                       mtmsr   r0                                      ; Turn stuff off
+                       ori             r7,r7,lo16(EXT(mem_actual))     ; Get the actual
+                       isync
+               
+                       lwz             r0,4(r2)                        ; Get the flag
+                       mr.             r0,r0                           ; Should we log?
+                       lwz             r0,0(r7)                        ; Get the end of memory
+                       lwz             r7,0(r2)                        ; Get the position
+                       bne-    waytoofar                       ; No logging...
+                       mr.             r7,r7                           ; Is this the first? 
+                       bne+    gotspot                         ; Nope...
+                       
+                       lis             r7,hi16(EXT(mem_size))  ; High part of defined memory
+                       ori             r7,r7,lo16(EXT(mem_size))       ; Low part of defined memory
+                       lwz             r7,0(r7)                        ; Make it end of defined
+                       
+gotspot:       cmplw   r7,r0                           ; Do we fit in memory
+                       addi    r0,r7,0x0020            ; Next slot
+                       bge-    waytoofar                       ; No fit...
+                       
+                       stw             r0,0(r2)                        ; Set next time slot
+                       dcbz    0,r7                            ; Zap it
+                       
+                       stw             r3,0(r7)                        ; First data
+                       li              r3,32                           ; Disp to next line
+                       stw             r4,4(r7)                        ; Second data
+                       dcbz    r3,r7                           ; Zap it
+                       stw             r5,8(r7)                        ; Third data
+                       stw             r6,12(r7)                       ; Fourth data
+                       
+                       stw             r12,16(r7)                      ; Callers callers
+                       stw             r11,20(r7)                      ; Callers callers caller
+                       stw             r10,24(r7)                      ; Callers callers callers caller
+                       stw             r9,28(r7)                       ; Callers callers callers callers caller
+
+waytoofar:     mtmsr   r8                                      ; Back to normal
+                       isync
+                       blr
+
+;
+;                      Same as the other, but no traceback and 16 byte entry
+;                      Trashes R0, R2, R10, R12
+;
+
+                       .align  5
+                       .globl  EXT(dbgLog2)
+
+LEXT(dbgLog2)
+
+
+                       mfmsr   r10                                     ; Get the MSR   
+                       lis             r2,hi16(EXT(DebugWork)) ; High part of area
+                       lis             r12,hi16(EXT(mem_actual))       ; High part of actual
+                       andi.   r0,r10,0x7FCF           ; Interrupts and translation off
+                       ori             r2,r2,lo16(EXT(DebugWork))      ; Get the entry
+                       mtmsr   r0                                      ; Turn stuff off
+                       ori             r12,r12,lo16(EXT(mem_actual))   ; Get the actual
+                       isync
+               
+                       lwz             r0,4(r2)                        ; Get the flag
+                       mr.             r0,r0                           ; Should we log?
+                       lwz             r0,0(r12)                       ; Get the end of memory
+                       lwz             r12,0(r2)                       ; Get the position
+                       bne-    waytoofar2                      ; No logging...
+                       mr.             r12,r12                         ; Is this the first? 
+                       bne+    gotspot2                        ; Nope...
+                       
+                       lis             r12,hi16(EXT(mem_size)) ; High part of defined memory
+                       ori             r12,r12,lo16(EXT(mem_size))     ; Low part of defined memory
+                       lwz             r12,0(r12)                      ; Make it end of defined
+                       
+gotspot2:      cmplw   cr1,r12,r0                      ; Do we fit in memory
+                       rlwinm. r0,r12,0,27,27          ; Are we on a new line?
+                       bge-    cr1,waytoofar2          ; No fit...
+                       addi    r0,r12,0x0010           ; Next slot
+                       
+                       bne+    nonewline                       ; Not on a new line...
+                       dcbz    br0,r12                         ; Clear it so we do not fetch it
+                       
+nonewline:     cmplwi  r3,68                           ; Special place for time stamp?
+                       
+                       stw             r0,0(r2)                        ; Set next time slot
+                       bne+    nospcts                         ; Nope...
+
+                       lwz             r0,0x17C(br0)           ; Get special saved time stamp
+                       b               nospctt                         ; Skip...
+                       
+nospcts:       mftb    r0                                      ; Get the current time
+                                               
+nospctt:       stw             r3,4(r12)                       ; First data
+                       stw             r4,8(r12)                       ; Second data
+                       stw             r5,12(r12)                      ; Third data
+                       stw             r0,0(r12)                       ; Time stamp
+
+waytoofar2:    mtmsr   r10                                     ; Back to normal
+                       isync
+                       blr
+
+
 ;
 ;                      Saves floating point registers
 ;
@@ -2004,19 +2080,13 @@ xnonmi:                                                                                         /* Label it */
 
 LEXT(stFloat)
 
-                       lis             r2,hi16(MASK(MSR_VEC))                  ; Get the vector enable 
-                       li              r4,0
-                       ori             r2,r2,lo16(MASK(MSR_FP))                ; Get the FP enable 
-                       ori             r4,r4,lo16(MASK(MSR_EE))                ; Get the EE bit
-
-                       mfmsr   r0                                                              ; Save the MSR
-
-                       andc    r4,r0,r4                                                ; Clear EE
-                       ori             r4,r4,lo16(MASK(MSR_FP))                ; Enable floating point
+                       mfmsr   r0                                      ; Save the MSR
+                       rlwinm  r0,r0,0,MSR_FP_BIT+1,MSR_FP_BIT-1       ; Force floating point off
+                       rlwinm  r0,r0,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1     ; Force vectors off
+                       rlwinm  r4,r0,0,MSR_EE_BIT,MSR_EE_BIT   ; Turn off interruptions
+                       ori             r4,r4,lo16(MASK(MSR_FP))        ; Enable floating point
                        mtmsr   r4
                        isync
-
-                       andc    r0,r0,r2                                                ; Clear VEC and FP enables
                        
                        stfd    f0,0x00(r3)
                        stfd    f1,0x08(r3)
@@ -2067,10 +2137,6 @@ LEXT(stFloat)
 
 LEXT(stVectors)
 
-                       lis             r2,hi16(MASK(MSR_VEC))                  ; Get the vector enable 
-                       li              r4,0
-                       ori             r2,r2,lo16(MASK(MSR_FP))                ; Get the FP enable 
-                       ori             r4,r4,lo16(MASK(MSR_EE))                ; Get the EE bit
                        
                        mfsprg  r6,2                            ; Get features
                        mr              r5,r3                           ; Save area address
@@ -2079,15 +2145,13 @@ LEXT(stVectors)
                        beqlr-                                          ; No...
                        
                        mfmsr   r0                                      ; Save the MSR
-       
-                       andc    r4,r0,r4                        ; Clear EE
-
+                       rlwinm  r0,r0,0,MSR_FP_BIT+1,MSR_FP_BIT-1       ; Force floating point off
+                       rlwinm  r0,r0,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1     ; Force vectors off
+                       rlwinm  r4,r0,0,MSR_EE_BIT,MSR_EE_BIT   ; Turn off interruptions
                        oris    r4,r4,hi16(MASK(MSR_VEC))       ; Enable vectors
                        mtmsr   r4
                        isync
                        
-                       andc    r0,r0,r2                        ; Clear FP and VEC
-                       
                        stvxl   v0,0,r5
                        addi    r5,r5,16
                        stvxl   v1,0,r5
@@ -2171,16 +2235,10 @@ LEXT(stVectors)
 
 LEXT(stSpecrs)
 
-
-                       lis             r2,hi16(MASK(MSR_VEC))                  ; Get the vector enable 
-                       li              r4,0
-                       ori             r2,r2,lo16(MASK(MSR_FP))                ; Get the FP enable 
-                       ori             r4,r4,lo16(MASK(MSR_EE))                ; Get the EE bit
-
-
                        mfmsr   r0                                      ; Save the MSR
-                       andc    r0,r0,r2                        ; Turn of VEC and FP
-                       andc    r4,r0,r4                        ; And EE
+                       rlwinm  r0,r0,0,MSR_FP_BIT+1,MSR_FP_BIT-1       ; Force floating point off
+                       rlwinm  r0,r0,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1     ; Force vectors off
+                       rlwinm  r4,r0,0,MSR_EE_BIT,MSR_EE_BIT   ; Turn off interruptions
                        mtmsr   r4
                        isync
                        
@@ -2244,6 +2302,9 @@ stSnsr:           mfsrin  r6,r5
                        addi    r4,r4,4
                        bne+    stSnsr
 
+                       cmplwi  cr1,r12,PROCESSOR_VERSION_604e          
+                       cmplwi  cr5,r12,PROCESSOR_VERSION_604ev
+                       cror    cr1_eq,cr1_eq,cr5_eq                    ; Set if 604 type
                        cmplwi  r12,PROCESSOR_VERSION_750
                        mfspr   r4,hid0
                        stw             r4,(39*4)(r3)
@@ -2252,13 +2313,15 @@ stSnsr:         mfsrin  r6,r5
                        li              r5,0
                        li              r6,0
                        li              r7,0
+                       beq-    cr1,before750
+                       blt-    before750
                        
                        mfspr   r4,hid1
                        mfspr   r5,l2cr
                        mfspr   r6,msscr0
                        mfspr   r7,msscr1
 
-                       stw             r4,(40*4)(r3)
+before750:     stw             r4,(40*4)(r3)
                        stw             r6,(42*4)(r3)
                        stw             r5,(41*4)(r3)
                        stw             r7,(43*4)(r3)
@@ -2273,6 +2336,7 @@ isis750:  stw             r4,0(r3)
                        li              r5,0
                        li              r6,0
                        li              r7,0
+                       beq-    cr1,b4750
                        blt-    b4750
                        
                        mfspr   r4,thrm1
@@ -2286,11 +2350,9 @@ b4750:           stw             r4,(44*4)(r3)
                        stw             r7,(47*4)(r3)
                        
                        li              r4,0
-                       li              r6,0
                        cmplwi  r12,PROCESSOR_VERSION_7400
                        bne             nnmax
                        
-                       mfspr   r6,dabr
                        mfpvr   r5
                        rlwinm  r5,r5,0,16,31
                        cmplwi  r5,0x1101
@@ -2301,167 +2363,8 @@ b4750:          stw             r4,(44*4)(r3)
 gnmax:         mfspr   r4,1016
 
 nnmax:         stw             r4,(48*4)(r3)
-                       stw             r6,(49*4)(r3)
                        
                        mtmsr   r0
                        isync
 
                        blr
-
-
-;
-;                      fwEmMck - this forces the hardware to emulate machine checks
-;                      Only valid on 64-bit machines
-;                      Note: we want interruptions disabled here
-;
-
-                       .globl  EXT(fwEmMck)
-                       
-                       .align  5
-
-LEXT(fwEmMck)
-
-
-                       rlwinm  r3,r3,0,1,0                                             ; Copy low of high high - scomd
-                       rlwinm  r5,r5,0,1,0                                             ; Copy low of high high - hid1
-                       rlwinm  r7,r7,0,1,0                                             ; Copy low of high high - hid4
-                       rlwimi  r3,r4,0,0,31                                    ; Copy low of low low
-                       rlwimi  r5,r6,0,0,31                                    ; Copy low of low low
-                       rlwimi  r7,r8,0,0,31                                    ; Copy low of low low
-
-                       lis             r9,3                                                    ; Start forming hid1 error inject mask
-                       lis             r10,hi16(0x01084083)                    ; Start formaing hid4 error inject mask
-                       ori             r9,r9,0xC000                                    ; Next bit
-                       ori             r10,r10,lo16(0x01084083)                ; Next part
-                       sldi    r9,r9,32                                                ; Shift up high
-                       sldi    r10,r10,8                                               ; Shift into position
-                       
-                       mfspr   r0,hid1                                                 ; Get hid1
-                       mfspr   r2,hid4                                                 ; and hid4
-                       
-                       and             r5,r5,r9                                                ; Keep only error inject controls - hid1
-                       and             r7,r7,r10                                               ; Keep only error inject controls - hid4
-                       
-                       andc    r0,r0,r9                                                ; Clear error inject controls hid1
-                       andc    r2,r2,r10                                               ; Clear error inject controls hid4
-                       
-                       or              r0,r0,r5                                                ; Add in the new controls hid1
-                       or              r2,r2,r7                                                ; Add in the new controls hid4
-                       
-/* ? */
-#if 0
-                       lis             r12,CoreErrI                                    ; Get the error inject controls
-                       sync
-
-                       mtspr   scomd,r3                                                ; Set the error inject controls
-                       mtspr   scomc,r12                                               ; Request error inject
-                       mfspr   r11,scomc                                               ; Get back the status (we just ignore it)
-#endif
-                       sync
-                       isync                                                   
-                       
-                       mtspr   hid1,r0                                                 ; Move in hid1 controls
-                       mtspr   hid1,r0                                                 ; We need to do it twice
-                       isync
-                       
-                       sync
-                       mtspr   hid4,r2                                                 ; Move in hid4 controls
-                       isync
-                       
-                       blr                                                                             ; Leave...
-
-;
-;                      fwSCOMrd - read/write SCOM
-;
-                       .align  5
-                       .globl  EXT(fwSCOM)
-
-LEXT(fwSCOM)
-
-                       lhz             r12,scomfunc(r3)                                ; Get the function
-                       lwz             r4,scomreg(r3)                                  ; Get the register
-                       rldicr  r4,r4,8,47                                              ; Position for SCOM
-
-                       mr.             r12,r12                                                 ; See if read or write
-                       bne             fwSCwrite                                               ; Go do a write
-
-                       mfsprg  r0,2                                                    ; Get the feature flags
-                       ori             r4,r4,0x8000                                    ; Set to read data
-                       rlwinm. r0,r0,pfSCOMFixUpb+1,31,31              ; Set shift if we need a fix me up
-                       sync
-
-                       mtspr   scomc,r4                                                ; Request the register
-                       mfspr   r11,scomd                                               ; Get the register contents
-                       mfspr   r10,scomc                                               ; Get back the status
-                       sync
-                       isync                                                   
-
-                       sld             r11,r11,r0                                              ; Fix up if needed
-                       
-                       std             r11,scomdata(r3)                                ; Save result
-                       eieio
-                       std             r10,scomstat(r3)                                ; Save status
-
-                       blr
-
-fwSCwrite:     ld              r5,scomdata(r3)                                 ; Get the data
-                       
-                       sync
-
-                       mtspr   scomd,r5                                                ; Set the data
-                       mtspr   scomc,r4                                                ; Set it
-                       mfspr   r10,scomc                                               ; Get back the status
-                       sync
-                       isync                                                   
-
-                       std             r10,scomstat(r3)                                ; Save status
-                       
-                       blr
-
-;
-;                      diagTrap - this is used to trigger checks from user space
-;                      any "twi 31,r31,0xFFFx" will come here (x = 0 to F).
-;                      On entry R3 points to savearea.
-;                      R4 is the "x" from instruction;
-;                      Pass back 1 to no-op twi and return to user
-;                      Pass back 0 to treat as normal twi.
-;
-
-                       .globl  EXT(diagTrap)
-                       
-                       .align  5
-
-LEXT(diagTrap)
-
-                       li              r3,0                                                    ; Ignore TWI
-                       blr                                                                             ; Leave...
-
-
-
-
-;
-;                      setPmon - this is used to manipulate MMCR0 and MMCR1
-
-                       .globl  EXT(setPmon)
-                       
-                       .align  5
-
-LEXT(setPmon)
-
-                       li              r0,0
-                       isync
-                       mtspr   mmcr0,r0                                                ; Clear MMCR0
-                       mtspr   mmcr1,r0                                                ; Clear MMCR1
-                       mtspr   pmc1,r0
-                       mtspr   pmc2,r0
-                       mtspr   pmc3,r0
-                       mtspr   pmc4,r0
-
-                       isync
-
-                       mtspr   mmcr0,r3                                                ; Set MMCR0
-                       mtspr   mmcr1,r4                                                ; Set MMCR1
-                       isync
-                       blr                                                                             ; Leave...
-
-