*
* @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@
*/
#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>
* 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... */
/*
* 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.
/*
* 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 */
/*
* 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 */
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 */
* 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 */
/*
* 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 */
/*
* 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 */
/*
* 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 */
* 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 */
/*
* 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 */
* 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 */
* 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 */
/* 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 */
*/
- .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 /* ? */
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 */
/* 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 */
* 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 */
/*
* 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 */
/*
* 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
/*
; ***************************************************************************
#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 */
*/
- .align 5
- .globl EXT(GratefulDebDisp)
-
-LEXT(GratefulDebDisp)
+ENTRY(GratefulDebDisp,TAG_NO_FRAME_USED)
mfmsr r9 /* Save the current MSR */
mflr r7 /* Save the return */
*/
- .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 */
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
;
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)
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
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
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
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)
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)
li r5,0
li r6,0
li r7,0
+ beq- cr1,b4750
blt- b4750
mfspr r4,thrm1
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
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...
-
-