.L_handler600:
mtsprg 2,r13 /* Save R13 */
mtsprg 3,r11 /* Save R11 */
- li r11,T_ALIGNMENT /* Set 'rupt code */
+ li r11,T_ALIGNMENT|T_FAM /* Set 'rupt code */
b .L_exception_entry /* Join common... */
/*
.L_handler700:
mtsprg 2,r13 /* Save R13 */
mtsprg 3,r11 /* Save R11 */
- li r11,T_PROGRAM /* Set 'rupt code */
+ li r11,T_PROGRAM|T_FAM /* Set 'rupt code */
b .L_exception_entry /* Join common... */
/*
mfsprg r13,0 ; Get the per_proc_area
bt- 0,uftInKern ; We are in the kernel...
+ lwz r13,spcFlags(r13) ; Get the special flags
+ rlwimi r13,r13,runningVMbit+1,31,31 ; Move VM flag after the 3 blue box flags
+ mtcrf 1,r13 ; Set BB and VMM flags in CR7
+ bt- 31,ufpVM ; fast paths running VM ...
cmplwi cr5,r0,0x7FF2 ; Ultra fast path cthread info call?
cmpwi cr6,r0,0x7FF3 ; Ultra fast path facility status?
cror cr1_eq,cr5_lt,cr6_gt ; Set true if not 0x7FF2 and not 0x7FF3 and not negative
- lwz r13,spcFlags(r13) ; Get the special flags
bt- cr1_eq,notufp ; Exit if we can not be ultra fast...
- rlwimi r13,r13,runningVMbit+1,31,31 ; Move VM flag after the 3 blue box flags
not. r0,r0 ; Flip bits and kind of subtract 1
- mtcrf 1,r13 ; Set BB and VMM flags in CR7
cmplwi cr1,r0,1 ; Is this a bb fast path?
not r0,r0 ; Restore to entry state
- bt- 31,notufp ; No fast paths if running VM (assume not)...
bf- bbNoMachSCbit,ufpUSuft ; We are not running BlueBox...
bgt cr1,notufp ; This can not be a bb ufp...
#if 0
rfi ; Bail back...
;
notufp: mtcrf 0xFF,r11 ; Restore the used CRs
- li r11,T_SYSTEM_CALL ; Set interrupt code
+ li r11,T_SYSTEM_CALL|T_FAM ; Set interrupt code
b .L_exception_entry ; Join common...
uftInKern: cmplwi r0,0x7FF4 ; Ultra fast path loadMSR?
bne+ specbrtr ; Yeah...
notspectr: mtcr r11 ; Restore CR
- li r11,T_TRACE ; Set interrupt code
+ li r11,T_TRACE|T_FAM ; Set interrupt code
b .L_exception_entry ; Join common...
;
li r11,T_RUNMODE_TRACE /* Set 'rupt code */
b .L_exception_entry /* Join common... */
+
+/*
+ * Filter Ultra Fast Path syscalls for VMM
+ */
+ufpVM:
+ cmpwi cr6,r0,0x6004 ; Is it vmm_dispatch
+ bne cr6,notufp ; Exit If not
+ cmpwi cr5,r3,kvmmResumeGuest ; Compare r3 with kvmmResumeGuest
+ cmpwi cr6,r3,kvmmSetGuestRegister ; Compare r3 with kvmmSetGuestRegister
+ cror cr1_eq,cr5_lt,cr6_gt ; Set true if out of VMM Fast syscall range
+ bt- cr1_eq,notufp ; Exit if out of range
+ rlwinm r13,r13,1+FamVMmodebit,30,31 ; Extract FamVMenabit and FamVMmodebit
+ cmpwi cr0,r13,3 ; Are FamVMena and FamVMmode set
+ bne+ notufp ; Exit if not in FAM
+ b EXT(vmm_ufp) ; Ultra Fast Path syscall
+
/*
* .L_exception_entry(type)
*
;
; Remember, we are setting up CR6 with feature flags
;
-skipz1: lwz r1,pfAvailable(r2) ; Get the CPU features flags
+skipz1:
+ andi. r1,r11,T_FAM ; Check FAM bit
stw r3,saver3(r13) ; Save this one
+ stw r4,saver4(r13) ; Save this one
+ andc r11,r11,r1 ; Clear FAM bit
+ beq+ noFAM ; Is it FAM intercept
+ mfsrr1 r3 ; Load srr1
+ rlwinm. r3,r3,0,MSR_PR_BIT,MSR_PR_BIT ; Are we trapping from supervisor state?
+ beq+ noFAM ; From supervisor state
+ lwz r1,spcFlags(r2) ; Load spcFlags
+ rlwinm r1,r1,1+FamVMmodebit,30,31 ; Extract FamVMenabit and FamVMmodebit
+ cmpwi cr0,r1,2 ; Check FamVMena set without FamVMmode
+ bne+ noFAM ; Can this context be FAM intercept
+ lwz r4,FAMintercept(r2) ; Load exceptions mask to intercept
+ srwi r1,r11,2 ; divide r11 by 4
+ lis r3,0x8000 ; Set r3 to 0x80000000
+ srw r1,r3,r1 ; Set bit for current exception
+ and. r1,r1,r4 ; And current exception with the intercept mask
+ beq+ noFAM ; Is it FAM intercept
+ b EXT(vmm_fam_handler)
+noFAM:
+ lwz r1,pfAvailable(r2) ; Get the CPU features flags
la r3,savesrr0(r13) ; Point to the last line
mtcrf 0xE0,r1 ; Put the features flags (that we care about) in the CR
- stw r4,saver4(r13) ; Save this one
stw r6,saver6(r13) ; Save this one
crmove featSMP,pfSMPcapb ; See if we have a PIR
stw r8,saver8(r13) ; Save this one
lwz r0,savesrr1(r13) ; Get the MSR in use at exception time
mfsprg r2,0 ; Get back per_proc
cmplwi cr1,r3,T_IN_VAIN ; Was it handled?
- andi. r4,r0,lo16(MASK(MSR_RI)) ; See if the recover bit is on
+ rlwinm. r4,r0,0,MSR_PR_BIT,MSR_PR_BIT ; Are we trapping from supervisor state?
mr r11,r3 ; Put interrupt code back into the right register
beq+ cr1,EatRupt ; Yeah, just blast back to the user...
+ beq- NoFamPf
+ lwz r1,spcFlags(r2) ; Load spcFlags
+ rlwinm r1,r1,1+FamVMmodebit,30,31 ; Extract FamVMenabit and FamVMmodebit
+ cmpi cr0,r1,2 ; Check FamVMena set without FamVMmode
+ bne- cr0,NoFamPf
+ lwz r6,FAMintercept(r2) ; Load exceptions mask to intercept
+ srwi r1,r11,2 ; divide r11 by 4
+ lis r5,0x8000 ; Set r5 to 0x80000000
+ srw r1,r5,r1 ; Set bit for current exception
+ and. r1,r1,r6 ; And current exception with the intercept mask
+ beq+ NoFamPf ; Is it FAM intercept
+ bl EXT(vmm_fam_pf_handler)
+ b EatRupt
+NoFamPf:
+ andi. r4,r0,lo16(MASK(MSR_RI)) ; See if the recover bit is on
beq+ PassUp ; Not on, normal case...
;
; Here is where we handle the "recovery mode" stuff.