/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
*/
-#include <cpus.h>
#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
*/
-ENTRY(FirmwareCall, TAG_NO_FRAME_USED)
+
+ .align 5
+ .globl EXT(FirmwareCall)
+
+LEXT(FirmwareCall)
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 */
- blr /* Return for errors... */
+ b EXT(FCReturn) ; Bye dudes...
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(r13) /* Pass in caller's R4 */
- lwz r5,saver5(r13) /* Pass in caller's R5 */
+ lwz r4,saver4+4(r13) /* Pass in caller's R4 */
+ lwz r5,saver5+4(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... */
- 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 */
+ stw r3,saver3+4(r13) /* Pass back the return code to caller */
li r3,T_IN_VAIN /* Tell the vector handler that we took care of it */
- mtlr r11 /* Set the return */
- blr /* Bye, dudes... */
+ 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... */
+callUnimp: li r3,T_SYSTEM_CALL /* Tell the vector handler that we know nothing */
+ b EXT(FCReturn) ; Bye dudes...
/*
* This routine is used to store using a real address. It stores parmeter1 at parameter2.
*/
-ENTRY(StoreReal, TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(StoreReal)
+
+LEXT(StoreReal)
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... */
-ENTRY(StoreRealLL, TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(StoreRealLL)
+
+LEXT(StoreRealLL)
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)
-ENTRY(ClearReal, TAG_NO_FRAME_USED)
+LEXT(ClearReal)
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... */
-ENTRY(ClearRealLL, TAG_NO_FRAME_USED)
+
+ .align 5
+ .globl EXT(ClearRealLL)
+
+LEXT(ClearRealLL)
/*
* 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.
*/
-
-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 */
+
+ .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 */
isync /* Just make sure about it */
- lwz r5,0(r3) /* Get word 0 */
+rrJoina: 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 */
- rlwinm r0,r0,0,MSR_FP_BIT+1,MSR_FP_BIT-1 ; Force floating point off
+ lis r2,hi16(MASK(MSR_VEC)) ; Get the vector enable
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 */
- rlwinm r0,r0,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1 ; Force vectors off
+ andc r0,r0,r2 ; Clear VEC and FP enables
lwz r11,24(r3) /* Get word 6 */
lwz r12,28(r3) /* Get word 7 */
- mtmsr r0 /* Restore original machine state */
+ bt-- cr0_eq,rr32b ; We are not 64-bit...
+
+ mtmsrd r0
+ isync
+ b rrJoinb ; Join on up...
+
+rr32b: mtmsr r0 /* Restore original machine state */
isync /* Insure goodness */
- stw r5,0(r4) /* Set word 0 */
+rrJoinb: 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... */
-ENTRY(xLoadDBATsLL, TAG_NO_FRAME_USED)
+
+ .align 5
+ .globl EXT(xLoadDBATsLL)
+
+LEXT(xLoadDBATsLL)
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.
*/
-ENTRY(LoadIBATs, TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(LoadIBATs)
+
+LEXT(LoadIBATs)
+
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... */
-ENTRY(xLoadIBATsLL, TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(xLoadIBATsLL)
+
+LEXT(xLoadIBATsLL)
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
+ * dbgTrace(id, p1, p2, p3, p4)
*/
-
-ENTRY(dbgTrace, TAG_NO_FRAME_USED)
+
+ .align 5
+ .globl EXT(dbgTrace)
+
+LEXT(dbgTrace)
+ mr r2,r3
+ mr r3,r4
lis r0,HIGH_ADDR(CutTrace) /* Top half of CreateFakeIO firmware call number */
+ mr r4,r5
+ mr r5,r6
ori r0,r0,LOW_ADDR(CutTrace) /* Bottom half */
+ mr r6,r7
sc /* Do it to it */
blr /* Bye bye, Birdie... */
/*
* This is the glue to create a fake I/O interruption
*/
-
-ENTRY(CreateFakeIO, TAG_NO_FRAME_USED)
+
+ .align 5
+ .globl EXT(CreateFakeIO)
+
+LEXT(CreateFakeIO)
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
*/
-
-ENTRY(CreateFakeDEC, TAG_NO_FRAME_USED)
+
+ .align 5
+ .globl EXT(CreateFakeDEC)
+
+LEXT(CreateFakeDEC)
#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
*/
-ENTRY(CreateShutdownCTX, TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(CreateShutdownCTX)
+
+LEXT(CreateShutdownCTX)
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
*/
-
-ENTRY(ChokeSys, TAG_NO_FRAME_USED)
+
+ .align 5
+ .globl EXT(ChokeSys)
+
+LEXT(ChokeSys)
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)
-ENTRY(fwSCCinit, TAG_NO_FRAME_USED)
+LEXT(fwSCCinit)
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)
-ENTRY(dbgDisp, TAG_NO_FRAME_USED)
+LEXT(dbgDisp)
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 */
-ENTRY(dbgDispLL, TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(dbgDispLL)
+
+LEXT(dbgDispLL)
dbgDispInt: mfmsr r8 /* Save the MSR */
*/
-ENTRY(dbgRegsLL, TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(dbgRegsLL)
+
+LEXT(dbgRegsLL)
+ b EXT(FCReturn) ; Bye dudes...
+#if 0
li r3,0 /* ? */
bl dbgRegsCm /* Join on up... */
-
-/*
- * 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... */
+ b EXT(FCReturn) ; Bye dudes...
-ENTRY(dbgRegs, TAG_NO_FRAME_USED)
+
+ .align 5
+ .globl EXT(dbgRegs)
+
+LEXT(dbgRegs)
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)
-ENTRY(dbgCkpt, TAG_NO_FRAME_USED)
+LEXT(dbgCkpt)
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 */
-ENTRY(dbgCkptLL, TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(dbgCkptLL)
+
+LEXT(dbgCkptLL)
+
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.
*/
-ENTRY(DoPreemptLL, TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(DoPreemptLL)
+
+LEXT(DoPreemptLL)
- 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 */
- blr /* Return to interrupt handler */
+ b EXT(FCReturn) ; Bye dudes...
/*
* Forces a T_CSWITCH
*/
-ENTRY(SwitchContextLL, TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(SwitchContextLL)
+
+LEXT(SwitchContextLL)
- 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 */
- blr /* Return to interrupt handler */
+ b EXT(FCReturn) ; Bye dudes...
/*
* Forces a T_INTERRUPT trap to pretend that an actual I/O interrupt occurred.
*/
-ENTRY(CreateFakeIOLL, TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(CreateFakeIOLL)
+
+LEXT(CreateFakeIOLL)
- 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 */
- blr /* Return to interrupt handler */
+ b EXT(FCReturn) ; Bye dudes...
/*
* Create a shutdown context
* Forces a T_SHUTDOWN trap.
*/
-ENTRY(CreateShutdownCTXLL, TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(CreateShutdownCTXLL)
+
+LEXT(CreateShutdownCTXLL)
- 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 */
- blr /* Return to interrupt handler */
+ b EXT(FCReturn) ; Bye dudes...
/*
* Create a fake decrementer 'rupt.
* Forces a T_DECREMENTER trap to pretend that an actual decrementer interrupt occurred.
*/
-ENTRY(CreateFakeDECLL, TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(CreateFakeDECLL)
+
+LEXT(CreateFakeDECLL)
- 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 */
- blr /* Return to interrupt handler */
+ b EXT(FCReturn) ; Bye dudes...
/*
* Choke the system.
*/
-ENTRY(DoChokeLL, TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(DoChokeLL)
+
+LEXT(DoChokeLL)
- 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
- blr ; Return to interrupt handler
-
+ b EXT(FCReturn) ; Bye dudes...
+
/*
- * Set the low level trace flags
+ * Null firmware call
*/
-
-ENTRY(LLTraceSet, TAG_NO_FRAME_USED)
- 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...
+ .align 5
+ .globl EXT(NullLL)
+
+LEXT(NullLL)
- mtmsr r3 ; Translation and all off
- isync ; Toss prefetch
- b ltsNoMSRx
-
-ltsNoMSR: li r0,loadMSR ; Get the MSR setter SC
- sc ; Set it
+ li r3,T_IN_VAIN ; Set to just ignore this one
+ b EXT(FCReturn) ; Bye dudes...
-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 */
+;
+; Null firmware call
+;
+
+ .align 5
+ .globl EXT(iNullLL)
+
+LEXT(iNullLL)
+
+ 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 r12 /* Restore the MSR */
- isync
+;
+; Set the low level trace flags
+;
+
+ .align 5
+ .globl EXT(LLTraceSet)
+
+LEXT(LLTraceSet)
+
+ mr r4,r3 ; Save the new value
- blr /* Leave... */
+ lwz r3,traceMask(0) ; Get the old trace flags to pass back
+ stw r4,traceMask(0) ; Replace with the new ones
+ blr ; Leave...
-#if 1
+#if 0
/*
; ***************************************************************************
#define GDfromright 20
#define GDfontsize 16
-ENTRY(GratefulDeb,TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(GratefulDeb)
+
+LEXT(GratefulDeb)
+
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 */
*/
-ENTRY(GratefulDebDisp,TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(GratefulDebDisp)
+
+LEXT(GratefulDebDisp)
mfmsr r9 /* Save the current MSR */
mflr r7 /* Save the return */
*/
-ENTRY(checkNMI,TAG_NO_FRAME_USED)
+ .align 5
+ .globl EXT(checkNMI)
+
+LEXT(checkNMI)
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 */
- rlwinm r9,r9,0,MSR_FP_BIT+1,MSR_FP_BIT-1 ; Force floating point off
+ andc r9,r9,r2 ; Clear VEC and FP enables
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)
- 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
+ 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
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
- 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
+
+ andc r4,r0,r4 ; Clear EE
+
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)
- 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
+
+ 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 r9,2 ; Get feature flags
+ mtcrf 0x02,r9 ; move pf64Bit cr6
+
+ mfmsr r0 ; Save the MSR
+ andc r0,r0,r2 ; Turn off VEC and FP
+ andc r4,r0,r4 ; And EE
mtmsr r4
isync
stw r12,4(r3)
rlwinm r12,r12,16,16,31
+ bt++ pf64Bitb,stsSF1 ; skip if 64-bit (only they take the hint)
+
mfdbatu r4,0
mfdbatl r5,0
mfdbatu r6,1
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
-before750: stw r4,(40*4)(r3)
+ 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
+
+stsSF1: mfsprg r4,0
+ mfsprg r5,1
+ mfsprg r6,2
+ mfsprg r7,3
+ std r4,(18*4)(r3)
+ std r5,(20*4)(r3)
+ std r6,(22*4)(r3)
+ std r7,(24*4)(r3)
+
+ mfsdr1 r4
+ std r4,(26*4)(r3)
+
+ mfspr r4,hid0
+ std r4,(28*4)(r3)
+ mfspr r4,hid1
+ std r4,(30*4)(r3)
+ mfspr r4,hid4
+ std r4,(32*4)(r3)
+ mfspr r4,hid5
+ std r4,(34*4)(r3)
+
+
+stsSF2: li r5,0
+ la r4,(80*4)(r3)
+
+stsslbm: slbmfee r6,r5
+ slbmfev r7,r5
+ std r6,0(r4)
+ std r7,8(r4)
+ addi r5,r5,1
+ cmplwi r5,64
+ addi r4,r4,16
+ blt stsslbm
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,1 ; 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...
+
+