-setenaa: stw r12,savesrr1(r3) ; Turn facility on or off
-
- mfdec r24 ; Get decrementer
- lwz r22,qactTimer(r8) ; Get high order quick activation timer
- mr. r24,r24 ; See if it has popped already...
- lwz r23,qactTimer+4(r8) ; Get low order qact timer
- ble- chkenax ; We have popped or are just about to...
-
-segtb: mftbu r20 ; Get the upper time base
- mftb r21 ; Get the low
- mftbu r19 ; Get upper again
- or. r0,r22,r23 ; Any time set?
- cmplw cr1,r20,r19 ; Did they change?
- beq+ chkenax ; No time set....
- bne- cr1,segtb ; Timebase ticked, get them again...
-
- subfc r6,r21,r23 ; Subtract current from qact time
- li r0,0 ; Make a 0
- subfe r5,r20,r22 ; Finish subtract
- subfze r0,r0 ; Get a 0 if qact was bigger than current, -1 otherwise
- andc. r12,r5,r0 ; Set 0 if qact has passed
- andc r13,r6,r0 ; Set 0 if qact has passed
- bne chkenax ; If high order is non-zero, this is too big for a decrementer
- cmplw r13,r24 ; Is this earlier than the decrementer? (logical compare takes care of high bit on)
- bge+ chkenax ; No, do not reset decrementer...
-
- mtdec r13 ; Set our value
-
-chkenax: lwz r6,SAVflags(r3) ; Pick up the flags of the old savearea
+#if FPVECDBG
+ lis r0,HIGH_ADDR(CutTrace) ; (TEST/DEBUG)
+ li r2,0x3401 ; (TEST/DEBUG)
+ oris r0,r0,LOW_ADDR(CutTrace) ; (TEST/DEBUG)
+ sc ; (TEST/DEBUG)
+#endif
+
+vmxhscdq: lwarx r0,0,r9 ; Pick up the old chain head
+ stw r0,SAVprev(r22) ; Move it to the current guy
+ stwcx. r3,0,r9 ; Save it
+ bne- vmxhscdq ; Someone chaged the list...
+
+vmxsetlvl: stw r21,VMXlevel(r20) ; Save the level
+
+;
+; Here we check if we are at the right level
+;
+
+vmxchkena: lwz r21,VMXowner(r31) ; Get the ID of the live context
+ lwz r23,VMXlevel(r26) ; Get the level ID
+ cmplw r26,r21 ; Do we have the live context?
+ lwz r24,VMXcpu(r26) ; Get the CPU that the context was last dispatched on
+ bne- setena ; No, can not possibly enable...
+ cmplw r30,r23 ; Are we about to launch the live level?
+ cmplw cr1,r19,r24 ; Was facility used on this processor last?
+ bne- setena ; No, not live...
+ bne- cr1,setena ; No, wrong cpu, have to enable later....
+
+ lwz r24,VMXsave(r26) ; Get the first savearea
+ mr. r24,r24 ; Any savearea?
+ beq+ vmxena ; Nope...
+ lwz r25,SAVlevel(r24) ; Get the level of savearea
+ lwz r0,SAVprev(r24) ; Get the previous
+ cmplw r30,r25 ; Is savearea for the level we are launching?
+ bne+ vmxena ; No, just go enable...
+
+ stw r0,VMXsave(r26) ; Pop the chain
+
+ rlwinm r3,r24,0,0,19 ; Find main savearea header
+ lwz r3,SACvrswap(r3) ; Get the virtual to real conversion
+ la r9,quickfret(r31) ; Point to the quickfret chain header
+ xor r3,r24,r3 ; Convert to physical
+
+#if FPVECDBG
+ lis r0,HIGH_ADDR(CutTrace) ; (TEST/DEBUG)
+ li r2,0x3402 ; (TEST/DEBUG)
+ oris r0,r0,LOW_ADDR(CutTrace) ; (TEST/DEBUG)
+ sc ; (TEST/DEBUG)
+#endif
+
+vmxckcdq: lwarx r0,0,r9 ; Pick up the old chain head
+ stw r0,SAVprev(r24) ; Move it to the current guy
+ stwcx. r3,0,r9 ; Save it
+ bne- vmxckcdq ; Someone chaged the list...
+
+vmxena: oris r29,r29,hi16(MASK(MSR_VEC)) ; Enable facility
+
+
+setena: rlwinm. r0,r29,0,MSR_PR_BIT,MSR_PR_BIT ; Are we about to launch user state?
+ rlwinm r20,r29,(((31-vectorCngbit)+(MSR_VEC_BIT+1))&31),vectorCngbit,vectorCngbit ; Set flag if we enabled vector
+ stw r29,savesrr1(r27) ; Turn facility on or off
+ crmove cr7_eq,cr0_eq ; Remember if we are going to user state
+ lwz r19,deferctx(r28) ; Get any deferred facility context switch
+ rlwimi. r20,r29,(((31-floatCngbit)+(MSR_FP_BIT+1))&31),floatCngbit,floatCngbit ; Set flag if we enabled floats
+ beq setenaa ; Neither float nor vector turned on....
+
+ lwz r5,ACT_MACT_SPF(r28) ; Get activation copy
+ lwz r6,spcFlags(r31) ; Get per_proc copy
+ or r5,r5,r20 ; Set vector/float changed bits in activation
+ or r6,r6,r20 ; Set vector/float changed bits in per_proc
+ stw r5,ACT_MACT_SPF(r28) ; Set activation copy
+ stw r6,spcFlags(r31) ; Set per_proc copy
+
+setenaa: mfdec r24 ; Get decrementer
+ bf+ cr2_eq,nodefer ; No deferred to switch to...
+
+ li r20,0 ; Clear this
+ stw r26,curctx(r28) ; Make the facility context current
+ stw r20,deferctx(r28) ; Clear deferred context
+
+nodefer: lwz r22,qactTimer(r28) ; Get high order quick activation timer
+ mr. r24,r24 ; See if it has popped already...
+ lwz r23,qactTimer+4(r28) ; Get low order qact timer
+ ble- chkenax ; We have popped or are just about to...
+
+segtb: mftbu r20 ; Get the upper time base
+ mftb r21 ; Get the low
+ mftbu r19 ; Get upper again
+ or. r0,r22,r23 ; Any time set?
+ cmplw cr1,r20,r19 ; Did they change?
+ beq+ chkenax ; No time set....
+ bne- cr1,segtb ; Timebase ticked, get them again...
+
+ subfc r6,r21,r23 ; Subtract current from qact time
+ li r0,0 ; Make a 0
+ subfe r5,r20,r22 ; Finish subtract
+ subfze r0,r0 ; Get a 0 if qact was bigger than current, -1 otherwise
+ andc. r12,r5,r0 ; Set 0 if qact has passed
+ andc r13,r6,r0 ; Set 0 if qact has passed
+ bne chkenax ; If high order is non-zero, this is too big for a decrementer
+ cmplw r13,r24 ; Is this earlier than the decrementer? (logical compare takes care of high bit on)
+ bge+ chkenax ; No, do not reset decrementer...
+
+ mtdec r13 ; Set our value
+
+chkenax: