如果是影视专业,拍摄跟后期为主,推荐机器主要有三台:
1、佳能R6:推荐理由其实很简单,4K60P10bit422,八档五轴防抖,双核对焦,这几样加持之下,让佳能R6成为实力相当强悍的相机,无论是拍照还是视频,至于视频过热的问题,如果需要长时间录制,可以考虑松下。一般来说,佳能R6足够好用,如果想一步到位,上佳能R5。
2、索尼A7m4,一样的4K60p10bit422,只不过是裁切实现的,靠谱的对焦系统,庞大的镜头群,反正只要你能原价买到索尼a7m4就是好东西,溢价不推荐购买,如果你想一步到位,那就索尼a7s3。
3、松下S5,最具性价比的选择,一万能买到最好的视频机,一样的4k60p10bit22,可以外录raw,视频后期天花板很高,当然不足也有就是,对焦没佳能索尼靠谱,就是这样简单,如果你想一步到位,那就买松下s1h,推荐买二手,性价比无敌。
我们可以得出结论:如影sc完全支持索尼a6000系列相机。使用如影sc可以进一步提升摄影体验,扩展摄影的可能性。通过多角度拍摄、防抖功能以及外部闪光灯和麦克风等附件的连接,摄影者可以创造更加出色的作品。
全自动对焦:大疆sc佳能200d配备了佳能200D官方支持的全自动对焦功能,可以自动对焦并获得清晰的图像。
大疆sc佳能200d是一种很好的适配器,可以满足非专业用户进行航拍和拍摄的需求,同时,创意工作者也可以将其连接到佳能200D上进行摄影创作。由于这款适配器可以与大疆的相机控制器无缝连接,因此你可以轻松地开始航拍和拍摄。
大疆sc是大疆无人机公司的相机控制器,它可以在大疆无人机上将摄像机连接到图传系统上,使用户能够远程控制和拍摄航拍。它还支持有线或无线远程视频传输,可以用于监控、搜索和救援等任务。
lwzr0,PP_INTSTACK_TOP_SS(r6)
lwzr11,PP_CPU_DATA(r6)
stwr0,PP_ISTACKPTR(r6)
stwr3,CPU_ACTIVE_THREAD(r11)
/*Findthenewstackandstoreitinactive_stacks*/
lwzr12,PP_ACTIVE_STACKS(r6)
lwzr1,THREAD_KERNEL_STACK(r3)
lwzr9,THREAD_TOP_ACT(r3)/*Pointtotheactiveactivation*/
stwr1,0(r12)
lir0,0/*Cleararegister*/
lwzr8,ACT_MACT_PCB(r9)/*Getthesaveareaused*/
lwzr10,SAVflags(r8)/*Getthesaveareaflags*/
rlwinmr10,r10,0,1,31/*Removetheattachedflag*/
stwr0,saver3(r8)/*Makesurewepassina0forthecontinuation*/
lwzr7,SACvrswap(r7)/*Getthetranslationfromvirtualtoreal*/
stwr0,FM_BACKPTR(r1)/*zerobackptr*/
stwr5,savesrr1(r8)/*PassourMSRtothenewguy*/
stwr10,SAVflags(r8)/*Passbacktheflags*/
*Makethenewthreadthecurrentthread.
*/lwzr11,PP_CPU_DATA(r6)
stwr7,THREAD_KERNEL_STACK(r3)
stwr5,CPU_ACTIVE_THREAD(r11)
lwzr11,THREAD_KERNEL_STACK(r5)
lwzr5,THREAD_TOP_ACT(r5)
lwzr10,PP_ACTIVE_STACKS(r6)
lwzr7,CTHREAD_SELF(r5);Pickuptheuserassistword
lwzr8,ACT_MACT_PCB(r5);GetthePCBforthenewguystwr11,0(r10);Savethekernelstackaddress
stwr7,UAW(r6);Savetheassistwordforthe"ultrafastpath"lwzr11,ACT_MACT_BTE(r5);GetBlueBoxTaskEnvironmentlwzr7,ACT_MACT_SPF(r5);Getthespecialflagslwzr10,ACT_KLOADED(r5)
stwr11,ppbbTaskEnv(r6);Savethebbtaskenv
lir0,0cmpwicr0,r10,0
lwzr10,PP_ACTIVE_KLOADED(r6)
stwr7,spcFlags(r6);Setper_proccopyofthespecialflags
beqcr0,.L_sw_ctx_not_kldstwr5,0(r10)
lir10,MSR_SUPERVISOR_INT_OFF/*Gettheswitcher'sMSR*/
lwzr9,SAVflags(r8)/*Gettheflags*/
stwr10,savesrr1(r8)/*Setupforswitchin*/
*/blr/*Jumpintothenewthread*/
1:stwr5,savesrr0(r8)/*gotorealpc*/
stwr4,saver3(r8)/*mustpassbackoldthread*/
lir8,MSR_VM_OFF/*Settoeverythingoff*/
lwzr9,THREAD_TOP_ACT(r4)/*GettheswitchedfromACT*/
lwzr5,saver5(r3)/*Getthesrr0value*/
lwzr10,ACT_MACT_PCB(r9)/*GetthetopPCBontheoldthread*/
lwzr6,saver6(r3)/*Getthesrr1value*/
stwr3,ACT_MACT_PCB(r9)/*Putthenewoneontop*/
stwr10,SAVprev(r3)/*Chainontheoldone*/
;Contextdownload(operatesonowner'sdata):;
;0)enablefacility;1)ifnoownerexittocontextrestore
;2)ifcontextprocessor!=currentprocessorexittocontextrestore;3)ifcurrentactivation==owneractivation:
;1)ifcurrlevel==activelevel:;1)iftopfacilitysaveareaexists:
;invalidatesaveareabysettinglevelto1;2)enablefacilityforuser
;3)exit;
;2)elsegoto5;
;4)ifcurrlevel==activelevel:;1)iftopfacilitysaveareaexists:
;1)iftopsavelevel==activelevelexittocontextrestore;
;5)allocatesavearea;1)ifthereisafacilitysaveanditisinvalid,selectit,andbreak
;2)scannormallistforfreefacilityarea,selectiffound,andbreak;3)scanotherfacilityforfreesave:select,iffound,andbreak
;4)allocateanewsavearea;
;6)savecontext;7)markfacilitysavewithcurrlevel
;Contextrestore/upload(operatesoncurrentactivation'sdata):;
;1)setcurrenttoactivation;2)setactiveleveltocurrentlevel
;3)setcontextprocessortocurrentprocessor;4)ifnofacilitysaveareaortopsavelevel!=currlevel
;initializefacilityregisterstoemptyvalue;5)else
;1)loadregistersfromsavearea;2)invalidatesaveareabysettinglevelto1
;;6)enablefacilityforuser
;7)exittointerruptreturn;
;;Contextsave(operatesonspecifiedactivation'sdata):;1)ifnoownerexit
;2)ifowner!=specifiedactivationexit;3)ifcontextprocessor!=currentprocessor
;1)clearowner;2)exit
;;4)iffacilitytopsavearealevelexistsand==activelevelexit
;5)ifcurrlevel!=activelevelexit;6)allocatesavearea
;1)ifthereisafacilitysaveanditisinvalid,selectit,andbreak;2)scannormallistforfreefacilityarea,selectiffound,andbreak
;Exceptionexit(hw_exceptions):;
;1)disablereturnfacility;2)ifreturningsavearea!=activelevel
;1)ifowner!=currentactivationexit;2)ifcontextprocessor!=currentprocessor:
;1)clearowner;2)exit
;;3)ifnewlevel!=activelevelexit
;4)enablereturnfacility;5)exit
;;3)ifnofacilitysaveareaexit
;4)iftopsavelevel==activeortopisinvalid;1)dequeuetopfacilitysavearea
;2)setactiveleveltonewtopsavearea'slevel;3)releasesavearea
;4)ifowner==currentactivationclearowner;5)exit
lir2,0x6F00;(TEST/DEBUG)lir5,0;(TEST/DEBUG)
beq-noowneryet;(TEST/DEBUG)lwzr4,ACT_MACT_FPUlvl(r12);(TEST/DEBUG)
lwzr5,ACT_MACT_FPU(r12);(TEST/DEBUG)
lir3,0;Assumeweneedafix-me-upbeq-cr1,fsgoodcpu;Facilitylastusedonthisprocessor...
stwr3,PP_FPU_THREAD(r6);Clearownerbecauseitwasreallyontheotherprocessorbfsret;Bailnowwithnosave...fsgoodcpu:lwzr3,ACT_MACT_FPU(r12);GetthecurrentFPUsaveareaforthethread
lwzr9,ACT_MACT_FPUlvl(r12);Getourcurrentlevelindicatorcmplwicr1,r3,0;Haveweeversavedthisfacilitycontext?
beq-cr1,fsneedone;Neversavedit,soweneedanarea...lwzr8,SAVlvlfp(r3);Getthelevelthissaveareaisfor
blfpsrchsave;Findafreesaveareamfsprgr6,0;Getbackper_processorblock
orisr7,r7,hi16(SAVfpuvalid);Settheallocatedbitlwzr12,PP_FPU_THREAD(r6);Getbackourthread
mtlrr2;Restorereturnlwzr8,ACT_MACT_FPU(r12);Getthecurrenttopfloatingpointsavearea
lwzr9,ACT_MACT_FPUlvl(r12);Getourcurrentlevelindicatoragainstwr3,ACT_MACT_FPU(r12);SetthisasthelatestFPUsaveareaforthethread
stwr8,SAVprefp(r3);Andthenchainthisinfrontstwr7,SAVflags(r3);Setthevalidityflags
stwr12,SAVact(r3);Makesurewepointtotherightguy
fsusespare:stwr9,SAVlvlfp(r3);Andsetthelevelthissaveareaisfor;
;SavethecurrentFPUstateintothePCBofthethreadthatownsit.;lar11,savefp0(r3);Pointtothe1stline
dcbz0,r11;Allocatethefirstsavearealinelar11,savefp4(r3)/*Pointtothe2ndline*/
stfdf0,savefp0(r3)
dcbz0,r11/*allocateit*/
stfdf1,savefp1(r3)
stfdf2,savefp2(r3)
lar11,savefp8(r3)/*Pointtothe3rdline*/
stfdf3,savefp3(r3)
dcbz0,r11/*allocateit*/
stfdf4,savefp4(r3)
stfdf5,savefp5(r3)
stfdf6,savefp6(r3)
lar11,savefp12(r3)/*Pointtothe4thline*/
stfdf7,savefp7(r3)
dcbz0,r11/*allocateit*/
stfdf8,savefp8(r3)
stfdf9,savefp9(r3)
stfdf10,savefp10(r3)
lar11,savefp16(r3)/*Pointtothe5thline*/
stfdf11,savefp11(r3)
dcbz0,r11/*allocateit*/
stfdf12,savefp12(r3)
stfdf13,savefp13(r3)
stfdf14,savefp14(r3)
lar11,savefp20(r3)/*Pointtothe6thline*/
stfdf15,savefp15(r3)
stfdf16,savefp16(r3)
stfdf17,savefp17(r3)
stfdf18,savefp18(r3)
lar11,savefp24(r3)/*Pointtothe7thline*/
stfdf19,savefp19(r3)
dcbz0,r11/*allocateit*/
stfdf20,savefp20(r3)
lwzr10,liveFPSCR(r6);GetthepreviouslysavedFPSCR
stfdf21,savefp21(r3)stfdf22,savefp22(r3)
dcbz0,r11/*allocateit*/
stfdf24,savefp24(r3)
stfdf25,savefp25(r3)
stfdf26,savefp26(r3)
stfdf27,savefp27(r3)
stfdf28,savefp28(r3)
;inthe"normal"contextareaofthesavearea.
stwr9,savefpscrpad(r3);SavetheFPSCRpad
stwr10,savefpscr(r3);SavetheFPSCRstfdf29,savefp29(r3)
stfdf30,savefp30(r3)
stfdf31,savefp31(r3)
lfdf0,savefp0(r3);WeneedtorestoreF0becauseweusedit
lar9,savefp0(r3);(TEST/DEBUG)
lar10,savefp31(r3);(TEST/DEBUG)chkkillmedead:
lhar8,0(r9);(TEST/DEBUG)
ble+cr1,chkkillmedead;(TEST/DEBUG)#endif
fsret:lwzr4,ACT_MACT_FPUcpu(r12);GetbacktheownerCPU
rlwinmr4,r4,0,fvChkb+1,31;Clearlocksyncstwr4,ACT_MACT_FPUcpu(r12);Unlockthecontextfsretnr:mtmsrr0;Putinterruptsoniftheywereandfloatingpointoff
mfsprgr6,0;Gettheper_processorblock
mfmsrr19;GetthecurrentMSRlwzr10,PP_CPU_DATA(r6);GettheCPUdatapointer
lwzr12,PP_FPU_THREAD(r6);GetthethreadthatownstheFPUlwzr10,CPU_ACTIVE_THREAD(r10);Getthepointertotheactivethread
orir19,r19,lo16(MASK(MSR_FP));Enablethefloatingpointfeaturelwzr17,THREAD_TOP_ACT(r10);Nowgettheactivationthatisrunning;R12hasthe"old"activation
bne-fsSpin1;Someoneismessingrightnow
isync;Makesureweseeeverythinglwzr15,ACT_MACT_PCB(r12);Getthecurrentlevelofthe"old"one
cmplwr18,r19;ChecktheCPUthattheoldcontextisliveonlwzr14,ACT_MACT_FPU(r12);Pointtothetopoftheoldcontextstack
bne-fsnosaverel;ContextisnotliveifusedonadifferentCPU...lwzr13,ACT_MACT_FPUlvl(r12);Getthe"old"activelevel;
sc;(TEST/DEBUG)#endif
blfpsrchsave;Findafreesaveareastwr3,ACT_MACT_FPU(r12);Setthisasthelatestcontextsaveareaforthethread
mfsprgr6,0;Getbackper_processorblockstwr14,SAVprefp(r3);Andthenchainthisinfront
orisr7,r7,hi16(SAVfpuvalid);Settheallocatedbitstwr12,SAVact(r3);Makesurewepointtotherightguy
stwr7,SAVflags(r3);Settheallocationflags
fsusecache:lar11,savefp0(r3);Pointtothe1stlineinarea
stwr13,SAVlvlfp(r3);Setthiscontextlevel#ifFPVECDBG
;Nowwewillactuallysavetheoldcontext;dcbz0,r11;Allocatetheoutputarealar11,savefp4(r3);Pointtothe2ndline
stfdf0,savefp0(r3)dcbz0,r11;Allocatecache
stfdf1,savefp1(r3)stfdf2,savefp2(r3)
lar11,savefp8(r3);Pointtothe3rdline
stfdf3,savefp3(r3)dcbz0,r11;Allocatecache
stfdf4,savefp4(r3)stfdf5,savefp5(r3)
stfdf6,savefp6(r3)
lar11,savefp12(r3);Pointtothe4thline
stfdf7,savefp7(r3)dcbz0,r11;Allocatecache
stfdf8,savefp8(r3)stfdf9,savefp9(r3)
stfdf10,savefp10(r3)
lar11,savefp16(r3);Pointtothe5thline
stfdf11,savefp11(r3)dcbz0,r11;Allocatecache
stfdf12,savefp12(r3)stfdf13,savefp13(r3)
stfdf14,savefp14(r3)
lir14,0;Clearthisfornow
lwzr15,liveFPSCR(r6);GetthepreviouslysavedFPSCR
stfdf21,savefp21(r3)
stfdf22,savefp22(r3)
lar11,savefp28(r3);Pointtothe8thline
stfdf23,savefp23(r3)dcbz0,r11;allocateit
stfdf24,savefp24(r3)stfdf25,savefp25(r3)
stfdf26,savefp26(r3)
lar11,savefpscrpad(r3);Pointtothe9thline
stfdf27,savefp27(r3)dcbz0,r11;allocateit
stfdf28,savefp28(r3)stfdf29,savefp29(r3)
stfdf30,savefp30(r3)
stfdf31,savefp31(r3)
;inthe"normal"contextareaofthesavearea.
stwr14,savefpscrpad(r3);SavetheFPSCRpad
stwr15,savefpscr(r3);SavetheFPSCR
bne-fsSpin2;Someoneismessingrightnow
isync;Makesureweseeeverythinglwzr15,ACT_MACT_PCB(r17);Getthecurrentlevelofthe"new"one
lwzr14,ACT_MACT_FPU(r17);Pointtothetopofthe"new"contextstacklwzr13,ACT_MACT_FPUlvl(r17);Getthe"new"activelevel
cmplwicr1,r14,0;Dowepossiblyhavesomecontexttoload?
stwr15,ACT_MACT_FPUlvl(r17);Setthe"new"activelevellar11,savefp0(r14);Pointtofirstlinetobringin
stwr17,PP_FPU_THREAD(r6);Storecurrentthreadaddressinfpu_threadtoclaimfpuforthreadbeq+cr1,MakeSureThatNoTerroristsCanHurtUsByGod;No"new"contexttoload...
lwzr0,SAVlvlfp(r14);Gettheleveloffirstfacilitysaveareacmplwr0,r15;Toplevelcorrecttoload?
dcbt0,r11;Touchlinein
lir0,1;Getthelevelinvalidindicationlar11,savefp4(r14);Pointtonextline
dcbt0,r11;Touchlineinlfdf0,savefp0(r14)
lfdf1,savefp1(r14)
stwr0,SAVlvlfp(r14);Markthesaveareainvalidbecauseweareactivatingagain
lfdf2,savefp2(r14)lar11,savefp8(r14);Pointtonextline
lfdf3,savefp3(r14)dcbt0,r11;Touchlinein
lfdf4,savefp4(r14)lfdf5,savefp5(r14)
lfdf6,savefp6(r14)
lar11,savefp12(r14);Pointtonextline
lfdf7,savefp7(r14)dcbt0,r11;Touchlinein
lfdf8,savefp8(r14)lfdf9,savefp9(r14)
lfdf10,savefp10(r14)
lar11,savefp16(r14);Pointtonextline
lfdf11,savefp11(r14)dcbt0,r11;Touchlinein
lfdf12,savefp12(r14)lfdf13,savefp13(r14)
dcbt0,r11;Touchlinein
lfdf24,savefp24(r14)lfdf25,savefp25(r14)
lfdf26,savefp26(r14)
lfdf27,savefp27(r14)
lfdf28,savefp28(r14)
lfdf29,savefp29(r14)
lfdf30,savefp30(r14)
lfdf31,savefp31(r14)
fsenablexx:sync;Makesureallissaved
stwr18,ACT_MACT_FPUcpu(r17);SettheactiveCPUandrelease
fsenable:lwzr9,SAVflags(r4)/*Gettheflagsofthecurrentsavearea*/
lwzr8,savesrr1(r4);Getthemsroftheinterruptedguy
rlwinmr5,r4,0,0,19/*Getthepageaddressofthesavearea*/orir8,r8,MASK(MSR_FP);Enablethefloatingpointfeature
lwzr10,ACT_MACT_SPF(r17);Getthespecialflagslisr7,hi16(SAVattach)/*Gettheattachedflag*/
lwzr5,SACvrswap(r5)/*GetVirtualtoRealtranslation*/
lwzr6,ACT_MACT_PCB(r12);Getthefirst"normal"saveareafpsrnorm:mr.r5,r6;Isthereanother?
beq-fpsrvect;No,searchthevectorsaveareas...lwzr7,SAVflags(r5);Gettheflagsforthisguy
lwzr6,SAVprev(r5);Gettheprevioussavearea,justincaseandis.r8,r7,hi16(SAVfpuvalid);HavewefoundanemptyFPUsaveinnormal?
beq+fpsrgot;Wefoundone...bfpsrnorm;Searchagain...fpsrvect:lwzr6,ACT_MACT_VMX(r12);Getthefirst"vector"saveareafpsrvectx:mr.r5,r6;Isthereanother?
beq-fpsrget;No,trytoallocateone...lwzr7,SAVflags(r5);Gettheflagsforthisguy
lwzr6,SAVprevec(r5);Gettheprevioussavearea,justincaseandis.r8,r7,hi16(SAVfpuvalid);HavewefoundanemptyFPUsaveinvector?
lir2,0x5F00;(TEST/DEBUG)lir5,0;(TEST/DEBUG)
beq-noowneryeu;(TEST/DEBUG)lwzr4,ACT_MACT_VMXlvl(r12);(TEST/DEBUG)
lwzr5,ACT_MACT_VMX(r12);(TEST/DEBUG)
lir3,0;Assumeweneedafix-me-upbeq-cr1,vsgoodcpu;Facilitylastusedonthisprocessor...
stwr3,PP_VMX_THREAD(r6);Clearownerbecauseitwasreallyontheotherprocessorbvsret;Bailnowwithnosave...vsgoodcpu:lwzr3,ACT_MACT_VMX(r12);Getthecurrentvectorsaveareaforthethread
lwzr9,ACT_MACT_VMXlvl(r12);Getourcurrentlevelindicatorcmplwicr1,r3,0;Haveweeversavedthisfacilitycontext?
beq-cr1,vsneedone;Neversavedit,soweneedanarea...lwzr8,SAVlvlvec(r3);Getthelevelthissaveareaisfor
blvsrchsave;Findafreesaveareamfsprgr6,0;Getbackper_processorblock
orisr7,r7,hi16(SAVvmxvalid);Settheallocatedbitlwzr12,PP_VMX_THREAD(r6);Getbackourthread
mtlrr2;Restorereturnlwzr8,ACT_MACT_VMX(r12);Getthecurrenttopvectorsavearea
lwzr9,ACT_MACT_VMXlvl(r12);Getourcurrentlevelindicatoragainstwr3,ACT_MACT_VMX(r12);Setthisasthelatestvectorsaveareaforthethread
stwr8,SAVprevec(r3);Andthenchainthisinfrontstwr7,SAVflags(r3);Settheallocationflags
stwr12,SAVact(r3);Makesurewepointtotherightguy
vsusespare:stwr9,SAVlvlvec(r3);Andsetthelevelthissaveareaisfor
mfcrr2;Savenon-volatileCRslwzr10,liveVRS(r6);GettherightVRSaveregister
lisr9,0x5555;Maskwithoddbitssetrlwinmr11,r10,1,0,31;Shiftover1
orir9,r9,0x5555;Finishmaskorr4,r10,r11;Afterthis,evenbitsshowwhichlinestozapandcr11,r4,r9;Clearoutoddbitslar6,savevr0(r3);Pointtoline0
rlwinmr4,r11,15,0,15;Moveline8-15flagstohighorderoddbitslar9,savevrvalid(r3);Pointtothesavedregistermaskfield
;bit2isline1,bit3isline9,etc.dcbabr0,r9;Allocatethecacheforit
rlwimir4,r10,16,16,31;Putvrsave0-15intopositions16-31lar7,savevr2(r3);Pointtoline1
mtcrf255,r4;LoaduptheCRsstwr10,savevrvalid(r3);Savethevalidityinformation
lir11,16;Getoffsetforoddregisters
bf16,snovr0;DonotsaveVR0...stvxlv0,br0,r8;SaveVR0snovr0:
lar9,savevr2(r3);PointtoV2/V3pair
bf17,snovr1;DonotsaveVR1...stvxlv1,r11,r8;SaveVR1snovr1:
lar6,savevr8(r3);Pointtoline4
bf6,snol3;Noline3todo...dcbabr0,r7;Allocatecacheline3snol3:
lar8,savevr4(r3);PointtoV4/V5pair
bf18,snovr2;DonotsaveVR2...stvxlv2,br0,r9;SaveVR2snovr2:
bf19,snovr3;DonotsaveVR3...
dcbabr0,r6;Allocatecacheline4snol4:
lar9,savevr6(r3);PointtoR6/R7pair
bf20,snovr4;DonotsaveVR4...stvxlv4,br0,r8;SaveVR4snovr4:
bf21,snovr5;DonotsaveVR5...
dcbabr0,r7;Allocatecacheline5snol5:
lar8,savevr8(r3);PointtoV8/V9pair
bf22,snovr6;DonotsaveVR6...stvxlv6,br0,r9;SaveVR6snovr6:
bf23,snovr7;DonotsaveVR7...
dcbabr0,r6;Allocatecacheline6snol6:
lar9,savevr10(r3);PointtoV10/V11pair
bf24,snovr8;DonotsaveVR8...stvxlv8,br0,r8;SaveVR8snovr8:
bf25,snovr9;DonotsaveVR9...
dcbabr0,r7;Allocatecacheline7snol7:
lar8,savevr12(r3);PointtoV12/V13pair
bf26,snovr10;DonotsaveVR10...stvxlv10,br0,r9;SaveVR10snovr10:
bf27,snovr11;DonotsaveVR11...
dcbabr0,r6;Allocatecacheline8snol8:
lar9,savevr14(r3);PointtoV14/V15pair
bf28,snovr12;DonotsaveVR12...stvxlv12,br0,r8;SaveVR12snovr12:
bf29,snovr13;DonotsaveVR13...
dcbabr0,r7;Allocatecacheline9snol9:
lar8,savevr16(r3);PointtoV16/V17pair
bf30,snovr14;DonotsaveVR14...stvxlv14,br0,r9;SaveVR14snovr14:
bf31,snovr15;DonotsaveVR15...
dcbabr0,r6;Allocatecacheline10snol10:
lar9,savevr18(r3);PointtoV18/V19pair
bf16,snovr16;DonotsaveVR16...stvxlv16,br0,r8;SaveVR16snovr16:
bf17,snovr17;DonotsaveVR17...
bf7,snol11;Noline11todo...dcbabr0,r7;Allocatecacheline11snol11:
lar8,savevr20(r3);PointtoV20/V21pair
bf18,snovr18;DonotsaveVR18...stvxlv18,br0,r9;SaveVR18snovr18:
bf19,snovr19;DonotsaveVR19...
bf9,snol12;Noline12todo...dcbabr0,r6;Allocatecacheline12snol12:
lar9,savevr22(r3);PointtoV22/V23pair
bf20,snovr20;DonotsaveVR20...stvxlv20,br0,r8;SaveVR20snovr20:
bf21,snovr21;DonotsaveVR21...
bf11,snol13;Noline13todo...dcbabr0,r7;Allocatecacheline13snol13:
lar8,savevr24(r3);PointtoV24/V25pair
bf22,snovr22;DonotsaveVR22...stvxlv22,br0,r9;SaveVR22snovr22:
bf23,snovr23;DonotsaveVR23...
bf13,snol14;Noline14todo...dcbabr0,r6;Allocatecacheline14snol14:
lar9,savevr26(r3);PointtoV26/V27pair
bf24,snovr24;DonotsaveVR24...stvxlv24,br0,r8;SaveVR24snovr24:
bf25,snovr25;DonotsaveVR25...
stvxlv27,r11,r9;SaveVR27snovr27:
lar7,savevr30(r3);PointtoV30/V31pair
bf28,snovr28;DonotsaveVR28...stvxlv28,br0,r8;SaveVR28snovr28:
bf29,snovr29;DonotsaveVR29...
lvxlv27,br0,r11;RestoreorloademptyvalueintoV27becauseweusedit
;Savethecurrentvectorstateintothesaveareaofthethreadthatownsit.;vsret:lwzr4,ACT_MACT_VMXcpu(r12);GetbacktheownerCPU
rlwinmr4,r4,0,fvChkb+1,31;Clearlocksyncstwr4,ACT_MACT_VMXcpu(r12);Unlockthecontextvsretnr:mtmsrr0;Putinterruptsoniftheywereandvectoroff
mfmsrr19/*GetthecurrentMSR*/
lwzr10,PP_CPU_DATA(r6)/*GettheCPUdatapointer*/
lwzr12,PP_VMX_THREAD(r6)/*Getthethreadthatownsthevector*/
lwzr10,CPU_ACTIVE_THREAD(r10)/*Getthepointertotheactivethread*/
bne-vsSpin1;Someoneismessingrightnow
isync;Makesureweseeeverythinglwzr15,ACT_MACT_PCB(r12);Getthecurrentlevelofthe"old"one
cmplwr18,r19;ChecktheCPUthattheoldcontextisliveonlwzr14,ACT_MACT_VMX(r12);Pointtothetopoftheoldcontextstack
bne-vsnosaverel;ContextisnotliveifusedonadifferentCPU...lwzr13,ACT_MACT_VMXlvl(r12);Getthe"old"activelevel;
blvsrchsave;Findafreesaveareastwr3,ACT_MACT_VMX(r12);Setthisasthelatestcontextsaveareaforthethread
mfsprgr6,0;Getbackper_processorblockstwr14,SAVprevec(r3);Andthenchainthisinfront
orisr7,r7,hi16(SAVvmxvalid);Settheallocatedbitstwr12,SAVact(r3);Makesurewepointtotherightguy
stwr7,SAVflags(r3);Settheallocationflags
vsusecache:lar11,savevr0(r3);Pointtothe1stlineinarea
stwr13,SAVlvlvec(r3);Setthiscontextlevel#ifFPVECDBG
lisr9,0x5555;Maskwithoddbitssetrlwinmr11,r10,1,0,31;Shiftover1
orir9,r9,0x5555;Finishmaskorr21,r10,r11;Afterthis,evenbitsshowwhichlinestozapstwr13,SAVlvlvec(r3);Setthesavearealevel
andcr13,r21,r9;Clearoutoddbitslar20,savevr0(r3);Pointtoline0
rlwinmr24,r13,15,0,15;Moveline8-15flagstohighorderoddbitslar23,savevrvalid(r3);Pointtothesavedregistermaskfield
;bit2isline1,bit3isline9,etc.dcbabr0,r23;Allocatethecacheforit
rlwimir24,r10,16,16,31;Putvrsave0-15intopositions16-31lar21,savevr2(r3);Pointtoline1
mtcrf255,r24;LoaduptheCRsstwr10,savevrvalid(r3);Savethevalidityinformation
lir30,16;Getoffsetforoddregisters
bf16,novr0;DonotsaveVR0...stvxlv0,br0,r22;SaveVR0novr0:
lar23,savevr2(r3);PointtoV2/V3pair
bf17,novr1;DonotsaveVR1...stvxlv1,r30,r22;SaveVR1novr1:
lar20,savevr8(r3);Pointtoline4
bf6,nol3;Noline3todo...dcbabr0,r21;Allocatecacheline3nol3:
lar22,savevr4(r3);PointtoV4/V5pair
bf18,novr2;DonotsaveVR2...stvxlv2,br0,r23;SaveVR2novr2:
bf19,novr3;DonotsaveVR3...
dcbabr0,r20;Allocatecacheline4nol4:
lar23,savevr6(r3);PointtoR6/R7pair
bf20,novr4;DonotsaveVR4...stvxlv4,br0,r22;SaveVR4novr4:
bf21,novr5;DonotsaveVR5...
dcbabr0,r21;Allocatecacheline5nol5:
lar22,savevr8(r3);PointtoV8/V9pair
bf22,novr6;DonotsaveVR6...stvxlv6,br0,r23;SaveVR6novr6:
bf23,novr7;DonotsaveVR7...
dcbabr0,r20;Allocatecacheline6nol6:
lar23,savevr10(r3);PointtoV10/V11pair
bf24,novr8;DonotsaveVR8...stvxlv8,br0,r22;SaveVR8novr8:
bf25,novr9;DonotsaveVR9...
dcbabr0,r21;Allocatecacheline7nol7:
lar22,savevr12(r3);PointtoV12/V13pair
bf26,novr10;DonotsaveVR10...stvxlv10,br0,r23;SaveVR10novr10:
bf27,novr11;DonotsaveVR11...
dcbabr0,r20;Allocatecacheline8nol8:
lar23,savevr14(r3);PointtoV14/V15pair
bf28,novr12;DonotsaveVR12...stvxlv12,br0,r22;SaveVR12novr12:
bf29,novr13;DonotsaveVR13...
dcbabr0,r21;Allocatecacheline9nol9:
lar22,savevr16(r3);PointtoV16/V17pair
bf30,novr14;DonotsaveVR14...stvxlv14,br0,r23;SaveVR14novr14:
bf31,novr15;DonotsaveVR15...
dcbabr0,r20;Allocatecacheline10nol10:
lar23,savevr18(r3);PointtoV18/V19pair
bf16,novr16;DonotsaveVR16...stvxlv16,br0,r22;SaveVR16novr16:
bf17,novr17;DonotsaveVR17...
bf7,nol11;Noline11todo...dcbabr0,r21;Allocatecacheline11nol11:
lar22,savevr20(r3);PointtoV20/V21pair
bf18,novr18;DonotsaveVR18...stvxlv18,br0,r23;SaveVR18novr18:
bf19,novr19;DonotsaveVR19...
bf9,nol12;Noline12todo...dcbabr0,r20;Allocatecacheline12nol12:
lar23,savevr22(r3);PointtoV22/V23pair
bf20,novr20;DonotsaveVR20...stvxlv20,br0,r22;SaveVR20novr20:
bf21,novr21;DonotsaveVR21...
bf11,nol13;Noline13todo...dcbabr0,r21;Allocatecacheline13nol13:
lar22,savevr24(r3);PointtoV24/V25pair
bf22,novr22;DonotsaveVR22...stvxlv22,br0,r23;SaveVR22novr22:
bf23,novr23;DonotsaveVR23...
bf13,nol14;Noline14todo...dcbabr0,r20;Allocatecacheline14nol14:
lar23,savevr26(r3);PointtoV26/V27pair
bf24,novr24;DonotsaveVR24...stvxlv24,br0,r22;SaveVR24novr24:
bf25,novr25;DonotsaveVR25...
stvxlv27,r30,r23;SaveVR27novr27:
lar23,savevr30(r3);PointtoV30/V31pair
bf28,novr28;DonotsaveVR28...stvxlv28,br0,r22;SaveVR28novr28:
mfvscrv27;GettheVSCR
bf29,novr29;DonotsaveVR29...stvxlv29,r30,r22;SaveVR29novr29:
lar22,savevscr(r3);PointtotheVSCRsavearea
bf30,novr30;DonotsaveVR30...stvxlv30,br0,r23;SaveVR30novr30:
bne-vsSpin2;Someoneismessingrightnow
isync;Makesureweseeeverythinglwzr15,ACT_MACT_PCB(r17);Getthecurrentlevelofthe"new"one
lwzr14,ACT_MACT_VMX(r17);Pointtothetopofthe"new"contextstacklwzr13,ACT_MACT_VMXlvl(r17);Getthe"new"activelevel#ifFPVECDBG
cmplwicr1,r14,0;Dowepossiblyhavesomecontexttoload?
stwr15,ACT_MACT_VMXlvl(r17);Setthe"new"activelevellar23,savevscr(r14);PointtotheVSCR
lar20,savevr0(r14);Pointtofirstlinetobringinstwr17,PP_VMX_THREAD(r6);Storecurrentthreadaddressinvmx_threadtoclaimvectorforthread
beq-cr1,ProtectTheAmericanWay;Nothingtorestore,firsttimeuse...lwzr0,SAVlvlvec(r14);Gettheleveloffirstfacilitysavearea
orir9,r9,0x5555;Finishmaskrlwinmr11,r10,1,0,31;Shiftover1
stwr0,SAVlvlvec(r14);Markthesaveareainvalidbecauseweareactivatingagainorr12,r10,r11;Afterthis,evenbitsshowwhichlinestotouch
dcbtbr0,r23;TouchintheVSCRandcr13,r12,r9;Clearoutoddbitslar20,savevr0(r14);Pointtoline0
rlwinmr3,r13,15,0,15;Moveline8-15flagstohighorderoddbitslar21,savevr2(r3);Pointtoline1
lir30,16;Getoffsetforoddregisters
bf16,lnovr0;DonotrestoreVR0...lvxlv0,br0,r22;RestoreVR0lnovr0:
lar23,savevr2(r14);PointtoV2/V3pair
bf17,lnovr1;DonotrestoreVR1...lvxlv1,r30,r22;RestoreVR1lnovr1:
lar20,savevr8(r14);Pointtoline4
bf6,lnol3;Noline3todo...dcbtbr0,r21;Touchcacheline3lnol3:
lar22,savevr4(r14);PointtoV4/V5pair
bf18,lnovr2;DonotrestoreVR2...lvxlv2,br0,r23;RestoreVR2lnovr2:
bf19,lnovr3;DonotrestoreVR3...
dcbtbr0,r20;Touchcacheline4lnol4:
lar23,savevr6(r14);PointtoR6/R7pair
bf20,lnovr4;DonotrestoreVR4...lvxlv4,br0,r22;RestoreVR4lnovr4:
bf21,lnovr5;DonotrestoreVR5...
dcbtbr0,r21;Touchcacheline5lnol5:
lar22,savevr8(r14);PointtoV8/V9pair
bf22,lnovr6;DonotrestoreVR6...lvxlv6,br0,r23;RestoreVR6lnovr6:
bf23,lnovr7;DonotrestoreVR7...
dcbtbr0,r20;Touchcacheline6lnol6:
lar23,savevr10(r14);PointtoV10/V11pair
bf24,lnovr8;DonotrestoreVR8...lvxlv8,br0,r22;RestoreVR8lnovr8:
bf25,lnovr9;DonotsaveVR9...
dcbtbr0,r21;Touchcacheline7lnol7:
lar22,savevr12(r14);PointtoV12/V13pair
bf26,lnovr10;DonotrestoreVR10...lvxlv10,br0,r23;RestoreVR10lnovr10:
bf27,lnovr11;DonotrestoreVR11...
dcbtbr0,r20;Touchcacheline8lnol8:
lar23,savevr14(r14);PointtoV14/V15pair
bf28,lnovr12;DonotrestoreVR12...lvxlv12,br0,r22;RestoreVR12lnovr12:
bf29,lnovr13;DonotrestoreVR13...
dcbtbr0,r21;Touchcacheline9lnol9:
lar22,savevr16(r14);PointtoV16/V17pair
bf30,lnovr14;DonotrestoreVR14...lvxlv14,br0,r23;RestoreVR14lnovr14:
bf31,lnovr15;DonotrestoreVR15...
dcbtbr0,r20;Touchcacheline10lnol10:
lar23,savevr18(r14);PointtoV18/V19pair
bf16,lnovr16;DonotrestoreVR16...lvxlv16,br0,r22;RestoreVR16lnovr16:
bf17,lnovr17;DonotrestoreVR17...
bf7,lnol11;Noline11todo...dcbtbr0,r21;Touchcacheline11lnol11:
lar22,savevr20(r14);PointtoV20/V21pair
bf18,lnovr18;DonotrestoreVR18...lvxlv18,br0,r23;RestoreVR18lnovr18:
bf19,lnovr19;DonotrestoreVR19...
bf9,lnol12;Noline12todo...dcbtbr0,r20;Touchcacheline12lnol12:
lar23,savevr22(r14);PointtoV22/V23pair
bf20,lnovr20;DonotrestoreVR20...lvxlv20,br0,r22;RestoreVR20lnovr20:
bf21,lnovr21;DonotrestoreVR21...
bf11,lnol13;Noline13todo...dcbtbr0,r21;Touchcacheline13lnol13:
lar22,savevr24(r14);PointtoV24/V25pair
bf22,lnovr22;DonotrestoreVR22...lvxlv22,br0,r23;RestoreVR22lnovr22:
bf23,lnovr23;DonotrestoreVR23...
bf13,lnol14;Noline14todo...dcbtbr0,r20;Touchcacheline14lnol14:
lar23,savevr26(r14);PointtoV26/V27pair
bf24,lnovr24;DonotrestoreVR24...lvxlv24,br0,r22;RestoreVR24lnovr24:
bf25,lnovr25;DonotrestoreVR25...
lvxlv27,r30,r23;RestoreVR27lnovr27:
lar23,savevr30(r14);PointtoV30/V31pair
bf28,lnovr28;DonotrestoreVR28...lvxlv28,br0,r22;RestoreVR28lnovr28:
bf29,lnovr29;DonotrestoreVR29...
vrenablexx:sync;Makesureallissaved
stwr18,ACT_MACT_VMXcpu(r17);SettheactiveCPUandreleasevrenable:
lwzr9,SAVflags(r4)/*Gettheflagsofthecurrentsavearea*/
lwzr8,savesrr1(r4);Getthemsroftheinterruptedguy
rlwinmr5,r4,0,0,19/*Getthepageaddressofthesavearea*/orisr8,r8,hi16(MASK(MSR_VEC));Enablethevectorfacility
lwzr10,ACT_MACT_SPF(r17);Getthespecialflagslisr7,hi16(SAVattach)/*Gettheattachedflag*/
lwzr5,SACvrswap(r5)/*GetVirtualtoRealtranslation*/
;andR3is0,anewareaisallocated.IfR3isnon-zero,itcontains;apointertoavectorsaveareathatisfree.
vsrchsave:lwzr6,ACT_MACT_PCB(r12);Getthefirst"normal"saveareavsrnorm:mr.r5,r6;Isthereanother?
beq-vsrvect;No,searchthefloatingpointsaveareas...lwzr7,SAVflags(r5);Gettheflagsforthisguy
lwzr6,SAVprev(r5);Gettheprevioussavearea,justincaseandis.r8,r7,hi16(SAVvmxvalid);Havewefoundanemptyvectorsaveinnormal?
beq+vsrgot;Wefoundone...bvsrnorm;Searchagain...vsrvect:lwzr6,ACT_MACT_FPU(r12);Getthefirst"floatingpoint"saveareavsrvectx:mr.r5,r6;Isthereanother?
beq-vsrget;No,trytoallocateone...lwzr7,SAVflags(r5);Gettheflagsforthisguy
lwzr6,SAVprefp(r5);Gettheprevioussavearea,justincaseandis.r8,r7,hi16(SAVvmxvalid);Havewefoundanemptyvectorsaveinfloat?
**/ENTRY(lfs,TAG_NO_FRAME_USED)
lfsf1,0(r3)
stfdf1,0(r4)
**/ENTRY(stfs,TAG_NO_FRAME_USED)
lfdf1,0(r3)
stfsf1,0(r4)
lwzr11,SAVprev(r8)/*Gettheprevioussavearea*/
mfmsrr5/*Sincewearepassingcontrol,getourMSRvalues*/
lwzr1,saver1(r8)/*Loadnewstackpointer*/
rlwinmr10,r10,0,1,31/*Removetheattachedflag*/
stwr0,saver3(r8)/*Makesurewepassina0forthecontinuation*/
lwzr7,SACvrswap(r7)/*Getthetranslationfromvirtualtoreal*/
stwr0,FM_BACKPTR(r1)/*zerobackptr*/
stwr5,savesrr1(r8)/*PassourMSRtothenewguy*/
stwr10,SAVflags(r8)/*Passbacktheflags*/
xorr3,r7,r8/*Getthephysicaladdressofthenewcontextsavearea*/
stwr11,ACT_MACT_PCB(r9)/*Unstackoursavearea*/
bEXT(exception_exit)/*Goenditall...*/
/*structthread_shuttle*Switch_context(structthread_shuttle*old,
*void(*cont)(void),
*structthread_shuttle*new)
**Switchfromonethreadtoanother.Ifacontinuationissupplied,then
*wedonotneedtosavecalleesaveregisters.
**/
/*voidCall_continuation(void(*continuation)(void),vm_offset_tstack_ptr)
*/
ENTRY(Call_continuation,TAG_NO_FRAME_USED)
mtlrr3
mrr1,r4/*Loadnewstackpointer*/
blr/*Jumptothecontinuation*/
/*
*Gettheoldkernelstack,andstoreintothethreadstructure.
*Seeifacontinuationissupplied,andskipstatesaveifso.
*NB.Continuationsarenolongerused,sothistestisomitted,
*asshouldthesecondargument,butitisingenericcode.
*Wealwayssavestate.Thisdoesnothurtevenifcontinuations
*areputbackin.
*/
/*Contextswitchesaredoublejumps.Wepassthefollowingtothe
*contextswitchfirmwarecall:
**R3=switchee'ssavearea
*R4=oldthread
*R5=newSRR0
*R6=newSRR1
**savesrr0issettogotoswitch_in
*savesrr1issettouninterruptiblewithtranslationon
*/
ENTRY(Switch_context,TAG_NO_FRAME_USED)
mfsprgr6,0/*Gettheper_procblock*/
lwzr12,PP_ACTIVE_STACKS(r6)
#ifDEBUG
lwzr11,PP_ISTACKPTR(r6);(DEBUG/TRACE)makesurewearenot
mr.r11,r11;(DEBUG/TRACE)ontheinterruptbne+notonintstack;(DEBUG/TRACE)stack
BREAKPOINT_TRAPnotonintstack:
#endif
stwr4,THREAD_CONTINUATION(r3)
cmpwicr1,r4,0/*usedwaaaaydownbelow*/
lwzr7,0(r12)
/*
*Makethenewthreadthecurrentthread.
*/lwzr11,PP_CPU_DATA(r6)
stwr7,THREAD_KERNEL_STACK(r3)
stwr5,CPU_ACTIVE_THREAD(r11)
lwzr11,THREAD_KERNEL_STACK(r5)
lwzr5,THREAD_TOP_ACT(r5)
lwzr10,PP_ACTIVE_STACKS(r6)
lwzr7,CTHREAD_SELF(r5);Pickuptheuserassistword
lwzr8,ACT_MACT_PCB(r5);GetthePCBforthenewguystwr11,0(r10);Savethekernelstackaddress
stwr7,UAW(r6);Savetheassistwordforthe"ultrafastpath"lwzr11,ACT_MACT_BTE(r5);GetBlueBoxTaskEnvironmentlwzr7,ACT_MACT_SPF(r5);Getthespecialflagslwzr10,ACT_KLOADED(r5)
stwr11,ppbbTaskEnv(r6);Savethebbtaskenv
lir0,0cmpwicr0,r10,0
lwzr10,PP_ACTIVE_KLOADED(r6)
stwr7,spcFlags(r6);Setper_proccopyofthespecialflags
beqcr0,.L_sw_ctx_not_kldstwr5,0(r10)
b.L_sw_ctx_cont
.L_sw_ctx_not_kld:
stwr0,0(r10)/*act_kloaded=0*/
.L_sw_ctx_cont:
lisr10,hi16(EXT(trcWork));Gettopoftracemask
rlwinmr7,r8,0,0,19/*Switchtosaveareabase*/orir10,r10,lo16(EXT(trcWork));Getbottomofmask
lwzr11,SAVprev(r8)/*Getthepreviousoftheswitchee'ssavearea*/lwzr10,traceMask(r10);Gettheenabledtraces
lisr0,hi16(CutTrace);TraceFWcallmr.r10,r10;Anytracinggoingon?
orir0,r0,lo16(CutTrace);TraceFWcallbeq+cswNoTrc;Notracetoday,dude...
mrr10,r3;Saveacrosstracelwzr2,THREAD_TOP_ACT(r3);Traceoldactivation
mrr3,r11;Traceprevsaveareasc;Cuttraceentryofcontextswitch
mrr3,r10;RestorecswNoTrc:mfmsrr6/*GettheMSRbecausetheswitchedtothreadshouldinheritit*/
lwzr7,SACvrswap(r7)/*Getthetranslationfromvirtualtoreal*/
lisr0,hi16(SwitchContextCall)/*Toppartofswitchcontext*/
lisr9,hi16(EXT(switch_in))/*Gettopofswitchinroutine*/
stwr11,ACT_MACT_PCB(r5)/*Dequeuethesaveareawe'reswitchingto*/
rlwinmr6,r6,0,MSR_FP_BIT+1,MSR_FP_BIT-1/*TurnofftheFP*/
orir9,r9,lo16(EXT(switch_in))/*Bottomhalfofswitchin*/
lwzr5,savesrr0(r8)/*SetupthenewSRR0*/
rlwinmr6,r6,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1/*Turnoffthevector*/
mrr4,r3/*Saveouroldthreadtopassback*/
stwr9,savesrr0(r8)/*Makeusjumptotheswitchinroutine*/
lir10,MSR_SUPERVISOR_INT_OFF/*Gettheswitcher'sMSR*/
lwzr9,SAVflags(r8)/*Gettheflags*/
stwr10,savesrr1(r8)/*Setupforswitchin*/
rlwinmr9,r9,0,15,13/*Resetthesyscallflag*/
orir0,r0,lo16(SwitchContextCall)/*Bottompartofswitchcontext*/
rlwinmr9,r9,0,1,31/*Cleartheattachedflag*/
xorr3,r7,r8/*Getthephysicaladdressofthenewcontextsavearea*/
stwr9,SAVflags(r8)/*Settheflags*/
/*ifblockingoncontinuationavoidsavingstate*/
bnecr1,1f
sc/*Switchtothenewcontext*/
/*Wecomebackhereinthenewthreadcontext
*R4wassettoholdtheoldthreadpointer,butswitch_inwillputitinto
*R3whereitbelongs.
*/blr/*Jumpintothenewthread*/
1:stwr5,savesrr0(r8)/*gotorealpc*/
stwr4,saver3(r8)/*mustpassbackoldthread*/
bEXT(exception_exit)/*blockingoncontinuation,avoidstatesave*/
/*
*Allswitchedtothreadscomeherefirsttocleanuptheoldthread.
*Weneedtodothefollowingcontortionsbecauseweneedtokeep
*theLRclean.Andbecauseweneedtomanipulatethesaveareachain
*withtranslationon.Ifwecould,thisshouldbedoneinlowmem_vectors
*beforetranslationisturnedon.Butwecan't,dangit!
**R3=switcher'ssavearea
*saver4=oldthreadinswitcher'ssave
*saver5=newSRR0inswitcher'ssave
*saver6=newSRR1inswitcher'ssave
*/ENTRY(switch_in,TAG_NO_FRAME_USED)
lwzr4,saver4(r3)/*Gettheoldthread*/
lir8,MSR_VM_OFF/*Settoeverythingoff*/
lwzr9,THREAD_TOP_ACT(r4)/*GettheswitchedfromACT*/
lwzr5,saver5(r3)/*Getthesrr0value*/
lwzr10,ACT_MACT_PCB(r9)/*GetthetopPCBontheoldthread*/
lwzr6,saver6(r3)/*Getthesrr1value*/
stwr3,ACT_MACT_PCB(r9)/*Putthenewoneontop*/
stwr10,SAVprev(r3)/*Chainontheoldone*/
mrr3,r4/*Passbacktheoldthread*/
mtsrr0r5/*Setreturnpoint*/
mtsrr1r6/*SetreturnMSR*/
rfi/*Jam...*/
.long0
.long0
.long0
.long0
.long0
.long0
.long0
.long0
/*
*voidfpu_save(thread_act_tact)
**TodothefloatingpointandVMX,wekeepthreethreadpointers:one
*tothecurrentthread,onetothethreadthathasthefloatingpointcontext
*loadedintotheFPUregisters,andonefortheVMXowner.
**EachofthesethreadshasthreePCBpointers.ThenormalPCB,theFPUpcb,
*andtheVMXpcb.Thereisalsoabitforeachinthesaveareaflags.
*Whenwetakeanexception,orneedtousetheFPU/VMXinthekernel,wecall
*thisroutine.Itcheckstoseeifthereisanownerthreadforthefacility.
*Ifso,itsavesthefacility'sstateinformationinthenormalPCB.Then,it
*turnsontheappropriateflaginthesaveareatoindicatethatthestateis
*inthatparticularsavearea.Also,thethreadpointerfortheownerin
*theper_processorblockiscleared.Notethatwedon'thavetoworryaboutthe
*PCBpointersinthethreadbecausewheneverthestateisloaded,theassociated
*saveareaisreleasedandthepointercleared.Thisisdonesothatthefacility
*contextalwaysmigratestothenormalsavearea/PCB.Thisalwaysinsuresthat
*nomorethan2saveareasareusedforathread.
**Whenthecontextisloadedintothefacility,theassociatedPCBisreleasedif
*itsusageflagsindicatethatitisempty.(Notethatreturnfromexceptionand
*contextswitchhonortheseflagsandwon'treleaseasaveareaifthereisunrestored
*facilitycontext.)Theper_processorissettopointtothefacilityowner's
*threadandtheassociatedPCBpointerwithinthethreadisclearedbecause
*thePCBhasbeenreleased.
**Partofloadingacontextistoreleasethesavearea.Ifthesaveareacontains
*othercontext,thesaveareacannotbereleased.So,whatwe'releftwithis
*thattherewillbenonormalcontextsavearea,butonefortheas-not-yet
*restoredfacilitysavearea.Again,whenthatcontextisreloaded,thePCB
*isreleased,andwhenitisagainstored,itgoesintothe"normal"savearea.
**So,whatdowedowhenthereisnogeneralcontext,andwehavesomeFPU/VMX
*statetosave?HeckifIknow,butithappenswhenweswitchthreadswhen
*weshortcutsystemcalls.Thequestionis:doesthetargetthreadcarrythe
*FPU/VMXcontextwithitornot?Actually,itdon'tmatter,notonelittlebit.
*Ifweareaskedtosaveit,wegotta.It'sareallylousywaytodoit,but
*shortofstartingoverwithFPUs,it'swhat'swhat.Therefore,we'll
*allocateanFPUcontextsaveandattachit.
**Actually,it'snotquitethatsimple:sincewearen'tin
*ininterrupthandlercontext(that'sonlyinfpu_switch)wecan'tuse
*quickfrettomergeFPUintogeneralcontext.So,ifthereisanFPU
*savearea,weneedtousethat.Sowhatwedois:ifthereisFPUcontext
*usethat.Ifthereisageneralcontext,thenusethat.Ifneither,
*allocateasaveareaandmakethattheFPUcontext.
**Thenextthingwehavetodoistoallowthekerneltouseboththe
*floatingpointandAltivec.Itisnotrecommended,buttheremaybea
*goodreasontodoso.So,whatweneedtodoistotreateachofthe
*threetypesofcontextthesame,bykeepingaLIFOchainofstates.
*Wedohaveaproblemwiththatinthattherecanbemultiplelevelsof
*kernelcontext.Forexample,weareusingfloatingpointandwetakea
*pagefault,andsomehowstartusingtheFPU,andtakeanotherpagefault,
*etc.
**Anyway,wewillhopethatweonlyreasonablyusefloatingpointandvectorsin
*thekernel.Andtrytopackthecontextinasfewsaveareasaspossible.
**Thewaywekeepthese"levels"offloatingpointorvectorcontextstraightis
*torememberthetopofthenormalsaveareachainwhenweactivatethe
*facilitywhenitisfirstused.Then,whenwesavethatcontext,thisvalue
*issavedinitslevelfield.
**Whatthelevelconceptgivesusisawaytodistinguishbetweenmultiple
*independentcontextsunderthesamethreadactivation.Anytimewetake
*anykindofinterruption(trap,systemcall,I/Ointerruption),weare,
*ineffect,runningwithadifferentcontexteventhoughweareinthe
*samethread.Thetopsaveareaaddressisusedonlyasamarker.Itdoesnot
*pointtoanycontextassociatedwiththefloatorvectorcontext.Forexample,
*thetopsaveareapointerwillalwaysbe0fortheusercontext,becausethere
*ititalwayslastonthelist.
**Asnormalcontextisunstacked,thefirstfacilitycontextischeckedand
*ifthereisamatch,thefacilitysaveareaisreleased.Thisisbecausewe
*arereturningtoalevelbeforethefacilitysavedtherewasused.Ineffect,
*thisallowsustounwindthefacilitycontextsaveareasatdifferentrates.
**Inconjunctionwiththecurrentactivation,thesemarkersarealsousedto
*determinethestateofthefacilityenablement.Wheneverthefacilitycontextis
*"live,"i.e.,loadedinthehardwareregistersandbelongingtothecurrently
*runningcontext,thefacilityisenabledbeforedispatch.
**Thereisnothingspecialaboutusingfloatingpointorvectorfacilities,
*nopreliminarysaving,enabling,ordisabling.Youjustusethem.Theonlyexception
*isduringcontextswitchingonanSMPsystem.Inthiscase,thecontextmust
*besavedasthereisnoguaranteethatthethreadwillresumeonthesame
*processor.Thisisnotagoodthing,notatall.
**Wheneverweswitchoutathreadwithadirtycontext,wealwaysneedtosaveit
*becauseitcanwakeuponadifferentprocessor.However,oncethecontexthas
*beensaved,wedon'tneedtosaveitagainuntilitgetsdirty,nordoweneed
*toreloaditunlesssomeoneelse'scontexthasbeenloaded.Tohandlethis
*optimization,weneed3things.Weneedtoknowwhatprocessorthesavedcontext
*waslastloadedon,whethertheloadedcontextcouldbedirty,andifwe'vealready
*savedit.
**Wheneverthefacilityisenabled,theprocessorIDissavedintheactivation.This
*willshowwhichprocessorhasdirtydata.Whenacontextswitchoccurs,thefacility
*contextsaresaved,butarestillrememberedaslive.Thenexttimeweneedto
*contextswitch,wefirstcheckifthestateislive,andifnot,donostate
*saving.Thenwecheckifthestatehasalreadybeensaveandifnot,saveit.
*Thefacilityisalwaysdisabledonacontextswitch.OnaUP,thissavefunction
*doesnotoccur.
*Wheneverafacilityunavailableinterruptionoccurs,thecurrentstateissaved
*ifitisliveandunsaved.However,ifthelivestateisthesameasthenew
*onetobeloaded,theprocessorIDischeckedandifitisthecurrentprocessor
*thestatedoesnotneedtobeloadedorsaved.Thefacilityissimplyenabled.
*Onceallocated,facilitysaveareasarenotreleaseduntilareturnismadetoa
*previouslevel.Onceafacilityhasbeenenabled,thereisnowaytotellif
*itwilleverbeusedagain,butitislikely.Therefore,discardingasavearea
*whenitscontextismadeliveisextraoverhead.So,wedon'tdoit,butwe
*domarkthesaveareacontentsasinvalid.
*/
/*
;Thefollowingistheactualwayitisimplemented.Itdoesn'tquitematch
;theabovetext.Ineedtogoandfixthat.;
;Contextdownload(operatesonowner'sdata):;
;0)enablefacility;1)ifnoownerexittocontextrestore
;2)ifcontextprocessor!=currentprocessorexittocontextrestore;3)ifcurrentactivation==owneractivation:
;1)ifcurrlevel==activelevel:;1)iftopfacilitysaveareaexists:
;invalidatesaveareabysettinglevelto1;2)enablefacilityforuser
;3)exit;
;2)elsegoto5;
;4)ifcurrlevel==activelevel:;1)iftopfacilitysaveareaexists:
;1)iftopsavelevel==activelevelexittocontextrestore;
;5)allocatesavearea;1)ifthereisafacilitysaveanditisinvalid,selectit,andbreak
;2)scannormallistforfreefacilityarea,selectiffound,andbreak;3)scanotherfacilityforfreesave:select,iffound,andbreak
;4)allocateanewsavearea;
;6)savecontext;7)markfacilitysavewithcurrlevel
;8)ifreusingcachedsavearea(case#1)exittocontextrestore;9)setfacilitysavebackchaintofacilitytopsavearea
;10)setfacilitytoptosavearea;11)exittocontextrestore
;;
;Contextrestore/upload(operatesoncurrentactivation'sdata):;
;1)setcurrenttoactivation;2)setactiveleveltocurrentlevel
;3)setcontextprocessortocurrentprocessor;4)ifnofacilitysaveareaortopsavelevel!=currlevel
;initializefacilityregisterstoemptyvalue;5)else
;1)loadregistersfromsavearea;2)invalidatesaveareabysettinglevelto1
;;6)enablefacilityforuser
;7)exittointerruptreturn;
;;Contextsave(operatesonspecifiedactivation'sdata):;1)ifnoownerexit
;2)ifowner!=specifiedactivationexit;3)ifcontextprocessor!=currentprocessor
;1)clearowner;2)exit
;;4)iffacilitytopsavearealevelexistsand==activelevelexit
;5)ifcurrlevel!=activelevelexit;6)allocatesavearea
;1)ifthereisafacilitysaveanditisinvalid,selectit,andbreak;2)scannormallistforfreefacilityarea,selectiffound,andbreak
;3)scanotherfacilityforfreesave:select,iffound,andbreak;4)allocateanewsavearea
;7)savecontext;8)markfacilitysaveareawithcurrlevel
;9)ifreusingcachedsavearea(case#1)exit;10)setfacilitysavebackchaintofacilitytopsavearea
;11)setfacilitytoptosavearea;12)exit
;;
;Exceptionexit(hw_exceptions):;
;1)disablereturnfacility;2)ifreturningsavearea!=activelevel
;1)ifowner!=currentactivationexit;2)ifcontextprocessor!=currentprocessor:
;1)clearowner;2)exit
;;3)ifnewlevel!=activelevelexit
;4)enablereturnfacility;5)exit
;;3)ifnofacilitysaveareaexit
;4)iftopsavelevel==activeortopisinvalid;1)dequeuetopfacilitysavearea
;2)setactiveleveltonewtopsavearea'slevel;3)releasesavearea
;4)ifowner==currentactivationclearowner;5)exit
;;
;;
;if(owner==activation)&&(currlevel==activelevel);&&(activationprocessor==currentprocessor)::=contextlive
*/
ENTRY(fpu_save,TAG_NO_FRAME_USED)
mfmsrr0;GettheMSR
rlwinmr0,r0,0,MSR_FP_BIT+1,MSR_FP_BIT-1;Turnofffloatingpointforeverrlwinmr2,r0,0,MSR_EE_BIT+1,MSR_EE_BIT-1;Butdointerruptsonlyfornow
orir2,r2,MASK(MSR_FP);Enablethefloatingpointfeaturefornowalsomtmsrr2;SettheMSR
isyncmfsprgr6,0;Gettheper_processorblock
lwzr12,PP_FPU_THREAD(r6);GetthethreadthatownstheFPU#ifFPVECDBG
mrr7,r0;(TEST/DEBUG)
lir4,0;(TEST/DEBUG)mrr10,r3;(TEST/DEBUG)
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)mr.r3,r12;(TEST/DEBUG)
lir2,0x6F00;(TEST/DEBUG)lir5,0;(TEST/DEBUG)
beq-noowneryet;(TEST/DEBUG)lwzr4,ACT_MACT_FPUlvl(r12);(TEST/DEBUG)
lwzr5,ACT_MACT_FPU(r12);(TEST/DEBUG)
noowneryet:orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)
sc;(TEST/DEBUG)mrr0,r7;(TEST/DEBUG)
mrr3,r10;(TEST/DEBUG)#endif
mflrr2;Savethereturnaddress
lhzr11,PP_CPU_NUMBER(r6);GetourCPUnumbermr.r12,r12;AnyoneowntheFPU?
cmplwcr1,r3,r12;Isthespecifiedthreadtheowner?beq-fsretnr;NobodyownstheFPU,nosaverequired...lir4,ACT_MACT_FPUcpu;PointtotheCPUindication/lockword
bne-cr1,fsretnr;Facilitybelongstosomeotheractivation...fsvSpin2:lwarxr9,r4,r12;GetandreservethelastusedCPU
mr.r9,r9;Isitchangingnow?orisr3,r9,hi16(fvChk);Setthe"changing"flag
blt-fsvSpin2;Spinifchangingstwcx.r3,r4,r12;Lockitup
bne-fsvSpin2;Someoneismessingrightnow
isync;Makesureweseeeverythingcmplwcr1,r9,r11;Wasthecontextforthisprocessor?
lir3,0;Assumeweneedafix-me-upbeq-cr1,fsgoodcpu;Facilitylastusedonthisprocessor...
stwr3,PP_FPU_THREAD(r6);Clearownerbecauseitwasreallyontheotherprocessorbfsret;Bailnowwithnosave...fsgoodcpu:lwzr3,ACT_MACT_FPU(r12);GetthecurrentFPUsaveareaforthethread
lwzr9,ACT_MACT_FPUlvl(r12);Getourcurrentlevelindicatorcmplwicr1,r3,0;Haveweeversavedthisfacilitycontext?
beq-cr1,fsneedone;Neversavedit,soweneedanarea...lwzr8,SAVlvlfp(r3);Getthelevelthissaveareaisfor
cmplwir8,1;Seeifitisasparecmplwcr1,r9,r8;Correctlevel?
beq+fsusespare;Wehaveasparetouse...beq-cr1,fsret;Thecurrentlevelisalreadysaved,bailout...fsneedone:lir3,0;Telltheroutinetoallocateanareaifnonefound
blfpsrchsave;Findafreesaveareamfsprgr6,0;Getbackper_processorblock
orisr7,r7,hi16(SAVfpuvalid);Settheallocatedbitlwzr12,PP_FPU_THREAD(r6);Getbackourthread
mtlrr2;Restorereturnlwzr8,ACT_MACT_FPU(r12);Getthecurrenttopfloatingpointsavearea
lwzr9,ACT_MACT_FPUlvl(r12);Getourcurrentlevelindicatoragainstwr3,ACT_MACT_FPU(r12);SetthisasthelatestFPUsaveareaforthethread
stwr8,SAVprefp(r3);Andthenchainthisinfrontstwr7,SAVflags(r3);Setthevalidityflags
stwr12,SAVact(r3);Makesurewepointtotherightguy
fsusespare:stwr9,SAVlvlfp(r3);Andsetthelevelthissaveareaisfor;
;SavethecurrentFPUstateintothePCBofthethreadthatownsit.;lar11,savefp0(r3);Pointtothe1stline
dcbz0,r11;Allocatethefirstsavearealinelar11,savefp4(r3)/*Pointtothe2ndline*/
stfdf0,savefp0(r3)
dcbz0,r11/*allocateit*/
stfdf1,savefp1(r3)
stfdf2,savefp2(r3)
lar11,savefp8(r3)/*Pointtothe3rdline*/
stfdf3,savefp3(r3)
dcbz0,r11/*allocateit*/
stfdf4,savefp4(r3)
stfdf5,savefp5(r3)
stfdf6,savefp6(r3)
lar11,savefp12(r3)/*Pointtothe4thline*/
stfdf7,savefp7(r3)
dcbz0,r11/*allocateit*/
stfdf8,savefp8(r3)
stfdf9,savefp9(r3)
stfdf10,savefp10(r3)
lar11,savefp16(r3)/*Pointtothe5thline*/
stfdf11,savefp11(r3)
dcbz0,r11/*allocateit*/
stfdf12,savefp12(r3)
stfdf13,savefp13(r3)
stfdf14,savefp14(r3)
lar11,savefp20(r3)/*Pointtothe6thline*/
stfdf15,savefp15(r3)
stfdf16,savefp16(r3)
stfdf17,savefp17(r3)
stfdf18,savefp18(r3)
lar11,savefp24(r3)/*Pointtothe7thline*/
stfdf19,savefp19(r3)
dcbz0,r11/*allocateit*/
stfdf20,savefp20(r3)
lwzr10,liveFPSCR(r6);GetthepreviouslysavedFPSCR
stfdf21,savefp21(r3)stfdf22,savefp22(r3)
lir9,0;Justclearthisout
lar11,savefp28(r3)/*Pointtothe8thline*/stfdf23,savefp23(r3)
dcbz0,r11/*allocateit*/
stfdf24,savefp24(r3)
stfdf25,savefp25(r3)
stfdf26,savefp26(r3)
stfdf27,savefp27(r3)
stfdf28,savefp28(r3)
;NotethatwejustsavetheFPSCRhereforease.Itisreallyalreadysaved
;inthe"normal"contextareaofthesavearea.
stwr9,savefpscrpad(r3);SavetheFPSCRpad
stwr10,savefpscr(r3);SavetheFPSCRstfdf29,savefp29(r3)
stfdf30,savefp30(r3)
stfdf31,savefp31(r3)
lfdf0,savefp0(r3);WeneedtorestoreF0becauseweusedit
;togettheFPSCR#if0
lar9,savefp0(r3);(TEST/DEBUG)
lar10,savefp31(r3);(TEST/DEBUG)chkkillmedead:
lhar8,0(r9);(TEST/DEBUG)
addir9,r9,8;(TEST/DEBUG)cmpwir8,-8;(TEST/DEBUG)
cmplwcr1,r9,r10;(TEST/DEBUG)bne+dontkillmedead;(TEST/DEBUG)
BREAKPOINT_TRAP;(TEST/DEBUG)
dontkillmedead:;(TEST/DEBUG)
ble+cr1,chkkillmedead;(TEST/DEBUG)#endif
fsret:lwzr4,ACT_MACT_FPUcpu(r12);GetbacktheownerCPU
rlwinmr4,r4,0,fvChkb+1,31;Clearlocksyncstwr4,ACT_MACT_FPUcpu(r12);Unlockthecontextfsretnr:mtmsrr0;Putinterruptsoniftheywereandfloatingpointoff
isync
blr
/*
*fpu_switch()
**Enteredtohandlethefloating-pointunavailableexceptionand
*switchfpucontext
**Thiscodeisruninvirtualaddressmodeonwithinterruptsoff.
**Uponexit,thecodereturnstotheuserscontextwiththefloating
*pointfacilityturnedon.
**ENTRY:VMswitchedON
*InterruptsOFF
*StateissavedinsaveareapointedtobyR4.
*Allotherregistersarefree.
*/
ENTRY(fpu_switch,TAG_NO_FRAME_USED)
#ifDEBUG
#ifGDDBG
mrr7,r4;Saveinputparameter
lisr3,hi16(EXT(fpu_trap_count));GetaddressofFPtrapcounterorir3,r3,lo16(EXT(fpu_trap_count));GetaddressofFPtrapcounter
lwzr1,0(r3)lisr5,hi16(EXT(GratefulDeb));Pointtotopofdisplay
orir5,r5,lo16(EXT(GratefulDeb));Putinbottompartaddir1,r1,1
mtlrr5;Setlinkregister
stwr1,0(r3)mrr4,r1
lir3,0
blrl;Displaycount
mrr4,r7;Restoretheparameter#else
lisr3,hi16(EXT(fpu_trap_count));GetaddressofFPtrapcounter
orir3,r3,lo16(EXT(fpu_trap_count));GetaddressofFPtrapcounterlwzr1,0(r3)
addir1,r1,1
stwr1,0(r3)
#endif
#endif/*DEBUG*/
mfsprgr6,0;Gettheper_processorblock
mfmsrr19;GetthecurrentMSRlwzr10,PP_CPU_DATA(r6);GettheCPUdatapointer
lwzr12,PP_FPU_THREAD(r6);GetthethreadthatownstheFPUlwzr10,CPU_ACTIVE_THREAD(r10);Getthepointertotheactivethread
orir19,r19,lo16(MASK(MSR_FP));Enablethefloatingpointfeaturelwzr17,THREAD_TOP_ACT(r10);Nowgettheactivationthatisrunning;R12hasthe"old"activation
;R17hasthe"new"activation
#ifFPVECDBG
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x7F01;(TEST/DEBUG)mrr3,r12;(TEST/DEBUG)
mrr5,r17;(TEST/DEBUG)orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)
sc;(TEST/DEBUG)#endif
mr.r12,r12;SeeifthereisanyliveFPstatuslhzr18,PP_CPU_NUMBER(r6);GetthecurrentCPU,wewillneeditlatermtmsrr19;Enablefloatingpointinstructions
isyncbeq-fsnosave;Nolivecontext,sonothingtosave...lir20,ACT_MACT_FPUcpu;PointtotheCPUindication/lockwordfsSpin1:lwarxr19,r20,r12;GetandreservethelastusedCPU
mr.r19,r19;Isitchangingnow?orisr21,r19,hi16(fvChk);Setthe"changing"flag
blt-fsSpin1;Spinifchangingstwcx.r21,r20,r12;Lockitup
bne-fsSpin1;Someoneismessingrightnow
isync;Makesureweseeeverythinglwzr15,ACT_MACT_PCB(r12);Getthecurrentlevelofthe"old"one
cmplwr18,r19;ChecktheCPUthattheoldcontextisliveonlwzr14,ACT_MACT_FPU(r12);Pointtothetopoftheoldcontextstack
bne-fsnosaverel;ContextisnotliveifusedonadifferentCPU...lwzr13,ACT_MACT_FPUlvl(r12);Getthe"old"activelevel;
;First,checktoseeifallwearedoingisenablingbecausethe;"new"contextislive.
;#ifFPVECDBG
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x7F02;(TEST/DEBUG)mrr1,r15;(TEST/DEBUG)
mrr3,r13;(TEST/DEBUG)mrr5,r14;(TEST/DEBUG)
orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)sc;(TEST/DEBUG)
#endif
cmplwcr1,r12,r17;Arethe"old"activationandthe"new"thesame?
cmplwicr2,r14,0;Isthereanysavedcontextonthe"old"activation?bne+cr1,fsmstsave;Theactivationsaredifferentso"old"contextmustbesaved...;
;Hereweknowthatboththe"old"and"new"activationsarethesame.Wewill;checkthecurrentlevelandactivelevels.Iftheyarethesame,thecontextis
;alreadylive,soallwedoisturnonthefacilityandinvalidatethetop;savearea.
;;Ifthecurrentlevel,theactivelevel,andthetopsavearealevelarethe
;same,thenthecontextwassavedaspartofathreadcontextswitchandneither;needssavingorrestoration.
;;Inallothercases,thecontextmustbesavedunlesswearejustre-enabling
;floatingpoint.;cmplwr13,r15;Arethelevelsthesame?
cmplwicr2,r14,0;Isthereanysavedcontext?bne-fsmstsave;Levelsaredifferent,weneedtosave...beq-cr2,fsenableret;Nosavedcontextatall,enableandgo...lwzr20,SAVlvlfp(r14);Getthelevelofthetopsavearea#ifFPVECDBG
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x7F03;(TEST/DEBUG)mrr3,r15;(TEST/DEBUG)
mrr5,r20;(TEST/DEBUG)orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)
sc;(TEST/DEBUG)#endif
cmplwr15,r20;Isthetoplevelthesameasthecurrent?
lir0,1;Gettheinvalidflagbne-fsenableret;Notthesame,justenableandgo...stwr0,SAVlvlfp(r14);Invalidatethattopsavearea
fsenableret:sync;Makesureeverythingissaved
stwr19,ACT_MACT_FPUcpu(r12);Saywearenotusingthecontextanymore
bfsenable;Thenenableandgo...;
;Weneedtosavethe"old"contexthere.TheLIFOqueueingschemeworks;outforallcasesbecauseifboththe"new"and"old"activationsarethe
;same,therecannotbeanysavedstatetoload.the"new"levelis;truelynew.
;;Whenwesavethecontext,weeitheruseanewsavearea,orthefree
;onethatiscachedattheheadofthelist.fsmstsave:beq-cr2,fsgetsave;Thereisnopossiblecachedsavearealwzr5,SAVlvlfp(r14);Gettheleveloffirstfacilitysavearea
#ifFPVECDBGlisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x7F04;(TEST/DEBUG)mrr3,r15;(TEST/DEBUG)
orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)sc;(TEST/DEBUG)
#endifmrr3,r14;Assumeweareinvalid
cmplwir5,1;Isitinvalid?cmplwcr1,r5,r13;IstheSAleveltheactiveone?
beq+fsusecache;Invalid,justuseit...beq-cr1,fsnosaverel;TheSAlevelisactive,itisalreadysaved...fsgetsave:mrr3,r4;Usetheinterruptsaveasthecontextsaveareaifnonecached
#ifFPVECDBGlisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x7F05;(TEST/DEBUG)orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)
sc;(TEST/DEBUG)#endif
blfpsrchsave;Findafreesaveareastwr3,ACT_MACT_FPU(r12);Setthisasthelatestcontextsaveareaforthethread
mfsprgr6,0;Getbackper_processorblockstwr14,SAVprefp(r3);Andthenchainthisinfront
orisr7,r7,hi16(SAVfpuvalid);Settheallocatedbitstwr12,SAVact(r3);Makesurewepointtotherightguy
stwr7,SAVflags(r3);Settheallocationflags
fsusecache:lar11,savefp0(r3);Pointtothe1stlineinarea
stwr13,SAVlvlfp(r3);Setthiscontextlevel#ifFPVECDBG
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x7F06;(TEST/DEBUG)mrr5,r13;(TEST/DEBUG)
orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)sc;(TEST/DEBUG)
#endif
;Nowwewillactuallysavetheoldcontext;dcbz0,r11;Allocatetheoutputarealar11,savefp4(r3);Pointtothe2ndline
stfdf0,savefp0(r3)dcbz0,r11;Allocatecache
stfdf1,savefp1(r3)stfdf2,savefp2(r3)
lar11,savefp8(r3);Pointtothe3rdline
stfdf3,savefp3(r3)dcbz0,r11;Allocatecache
stfdf4,savefp4(r3)stfdf5,savefp5(r3)
stfdf6,savefp6(r3)
lar11,savefp12(r3);Pointtothe4thline
stfdf7,savefp7(r3)dcbz0,r11;Allocatecache
stfdf8,savefp8(r3)stfdf9,savefp9(r3)
stfdf10,savefp10(r3)
lar11,savefp16(r3);Pointtothe5thline
stfdf11,savefp11(r3)dcbz0,r11;Allocatecache
stfdf12,savefp12(r3)stfdf13,savefp13(r3)
stfdf14,savefp14(r3)
lar11,savefp20(r3);Pointtothe6thline
stfdf15,savefp15(r3)dcbz0,r11;Allocatecache
stfdf16,savefp16(r3)stfdf17,savefp17(r3)
stfdf18,savefp18(r3)
lar11,savefp24(r3);Pointtothe7thline
stfdf19,savefp19(r3)dcbz0,r11;Allocatecache
stfdf20,savefp20(r3)
lir14,0;Clearthisfornow
lwzr15,liveFPSCR(r6);GetthepreviouslysavedFPSCR
stfdf21,savefp21(r3)
stfdf22,savefp22(r3)
lar11,savefp28(r3);Pointtothe8thline
stfdf23,savefp23(r3)dcbz0,r11;allocateit
stfdf24,savefp24(r3)stfdf25,savefp25(r3)
stfdf26,savefp26(r3)
lar11,savefpscrpad(r3);Pointtothe9thline
stfdf27,savefp27(r3)dcbz0,r11;allocateit
stfdf28,savefp28(r3)stfdf29,savefp29(r3)
stfdf30,savefp30(r3)
stfdf31,savefp31(r3)
;NotethatwejustsavetheFPSCRhereforease.Itisreallyalreadysaved
;inthe"normal"contextareaofthesavearea.
stwr14,savefpscrpad(r3);SavetheFPSCRpad
stwr15,savefpscr(r3);SavetheFPSCR
;Thecontextisallsavednowandthefacilityisfree.;
;Nowcheckoutthe"new"andseeifweneedtoloaduphiscontext.;Ifwedo(andthisshouldbethenormalcase),doitandtheninvalidatethe
;savearea.(Thiswillkeepitcachedforquickaccessnexttimearound.);
;Ifwedonot(remember,wealreadytookcareofthecasewherewejustenable;theFPU),weneedtofilltheregisterswithjunk,becausethislevelhas
;neverusedthembeforeandsomethievingbastardcouldhacktheoldvalues;ofsomethread!Justimaginewhatwouldhappeniftheycould!Why,nothing
;wouldbesafe!MyGod!Itisterrifying!;
fsnosaverel:
sync;Makesureeverythingissaved
stwr19,ACT_MACT_FPUcpu(r12);Saywearenotusingthecontextanymorefsnosave:
lir20,ACT_MACT_FPUcpu;PointtotheCPUindication/lockwordfsSpin2:lwarxr19,r20,r17;GetandreservethelastusedCPU
mr.r19,r19;Isitchangingnow?orisr21,r19,hi16(fvChk);Setthe"changing"flag
blt-fsSpin2;Spinifchangingstwcx.r21,r20,r17;Lockitup
bne-fsSpin2;Someoneismessingrightnow
isync;Makesureweseeeverythinglwzr15,ACT_MACT_PCB(r17);Getthecurrentlevelofthe"new"one
lwzr14,ACT_MACT_FPU(r17);Pointtothetopofthe"new"contextstacklwzr13,ACT_MACT_FPUlvl(r17);Getthe"new"activelevel
#ifFPVECDBGlisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x7F07;(TEST/DEBUG)mrr1,r15;(TEST/DEBUG)
mrr3,r14;(TEST/DEBUG)mrr5,r13;(TEST/DEBUG)
orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)sc;(TEST/DEBUG)
#endif
cmplwicr1,r14,0;Dowepossiblyhavesomecontexttoload?
stwr15,ACT_MACT_FPUlvl(r17);Setthe"new"activelevellar11,savefp0(r14);Pointtofirstlinetobringin
stwr17,PP_FPU_THREAD(r6);Storecurrentthreadaddressinfpu_threadtoclaimfpuforthreadbeq+cr1,MakeSureThatNoTerroristsCanHurtUsByGod;No"new"contexttoload...
lwzr0,SAVlvlfp(r14);Gettheleveloffirstfacilitysaveareacmplwr0,r15;Toplevelcorrecttoload?
bne-MakeSureThatNoTerroristsCanHurtUsByGod;No,goinitialize...#ifFPVECDBG
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x7F08;(TEST/DEBUG)orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)
sc;(TEST/DEBUG)#endif
dcbt0,r11;Touchlinein
lir0,1;Getthelevelinvalidindicationlar11,savefp4(r14);Pointtonextline
dcbt0,r11;Touchlineinlfdf0,savefp0(r14)
lfdf1,savefp1(r14)
stwr0,SAVlvlfp(r14);Markthesaveareainvalidbecauseweareactivatingagain
lfdf2,savefp2(r14)lar11,savefp8(r14);Pointtonextline
lfdf3,savefp3(r14)dcbt0,r11;Touchlinein
lfdf4,savefp4(r14)lfdf5,savefp5(r14)
lfdf6,savefp6(r14)
lar11,savefp12(r14);Pointtonextline
lfdf7,savefp7(r14)dcbt0,r11;Touchlinein
lfdf8,savefp8(r14)lfdf9,savefp9(r14)
lfdf10,savefp10(r14)
lar11,savefp16(r14);Pointtonextline
lfdf11,savefp11(r14)dcbt0,r11;Touchlinein
lfdf12,savefp12(r14)lfdf13,savefp13(r14)
lfdf14,savefp14(r14)
lar11,savefp20(r14);Pointtonextline
lfdf15,savefp15(r14)dcbt0,r11;Touchlinein
lfdf16,savefp16(r14)lfdf17,savefp17(r14)
lfdf18,savefp18(r14)
lar11,savefp24(r14);Pointtonextline
lfdf19,savefp19(r14)dcbt0,r11;Touchlinein
lfdf20,savefp20(r14)lfdf21,savefp21(r14)
lar11,savefp28(r14);Pointtonextline
lfdf22,savefp22(r14)lfdf23,savefp23(r14)
dcbt0,r11;Touchlinein
lfdf24,savefp24(r14)lfdf25,savefp25(r14)
lfdf26,savefp26(r14)
lfdf27,savefp27(r14)
lfdf28,savefp28(r14)
lfdf29,savefp29(r14)
lfdf30,savefp30(r14)
lfdf31,savefp31(r14)
fsenablexx:sync;Makesureallissaved
stwr18,ACT_MACT_FPUcpu(r17);SettheactiveCPUandrelease
fsenable:lwzr9,SAVflags(r4)/*Gettheflagsofthecurrentsavearea*/
lwzr8,savesrr1(r4);Getthemsroftheinterruptedguy
rlwinmr5,r4,0,0,19/*Getthepageaddressofthesavearea*/orir8,r8,MASK(MSR_FP);Enablethefloatingpointfeature
lwzr10,ACT_MACT_SPF(r17);Getthespecialflagslisr7,hi16(SAVattach)/*Gettheattachedflag*/
lwzr5,SACvrswap(r5)/*GetVirtualtoRealtranslation*/
orisr10,r10,hi16(floatUsed|floatCng);Setthatweusedfloatingpoint
mr.r15,r15;Seeifwearedoingthisforuserstatestwr8,savesrr1(r4);Setthemsroftheinterruptedguy
andcr9,r9,r7/*Cleartheattachedbit*/xorr3,r4,r5/*Gettherealaddressofthesavearea*/
bne-fsnuser;Wearenotuserstate...
stwr10,ACT_MACT_SPF(r17);Settheactivationcopystwr10,spcFlags(r6);Setper_proccopyfsnuser:
#ifFPVECDBG
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x7F0A;(TEST/DEBUG)orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)
sc;(TEST/DEBUG)#endif
stwr9,SAVflags(r4)/*Settheflagsofthecurrentsavearea*/
bEXT(exception_exit)/*Exitfromthefray...*/
/*
*Initializetheregisterstosomebogusvalue
*/
MakeSureThatNoTerroristsCanHurtUsByGod:
#if0
lwzr10,savesrr1(r4);(TEST/DEBUG)
rlwinm.r10,r10,0,MSR_PR_BIT,MSR_PR_BIT;(TEST/DEBUG)beq-nxxxxxx;(TEST/DEBUG)
lwzr10,ACT_MACT_SPF(r17);(TEST/DEBUG)rlwinm.r10,r10,0,1,1;(TEST/DEBUG)
beq+nxxxxxxBREAKPOINT_TRAP;(TEST/DEBUG)
nxxxxxx:#endif
#ifFPVECDBG
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x7F09;(TEST/DEBUG)orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)
sc;(TEST/DEBUG)#endif
lisr5,hi16(EXT(FloatInit))/*Gettopsecretfloatingpointinitvalueaddress*/
orir5,r5,lo16(EXT(FloatInit))/*Slambottom*/
lfdf0,0(r5)/*InitializeFP0*/
fmrf1,f0;Dothemall
fmrf2,f0fmrf3,f0
fmrf4,f0
fmrf5,f0
fmrf6,f0
fmrf7,f0
fmrf8,f0
fmrf9,f0
fmrf10,f0
fmrf11,f0
fmrf12,f0
fmrf13,f0
fmrf14,f0
fmrf15,f0
fmrf16,f0
fmrf17,f0
fsubf31,f31,f31;GetsettoinitializetheFPSCR
fmrf18,f0fmrf19,f0
fmrf20,f0
mtfsf0xff,f31;ClearallFPSCRexceptioneanbles
fmrf21,f0fmrf22,f0
fmrf23,f0
fmrf24,f0
fmrf25,f0
fmrf26,f0
fmrf27,f0
fmrf28,f0
fmrf29,f0
fmrf30,f0
fmrf31,f0
bfsenablexx;Finishsettingitallup...;
;Findsanunusedfloatingpointareaintheactivationpointed;tobyR12ssavedcontexts.Ifnonearefound(unlikelybutpossible)
;andR3is0,anewareaisallocated.IfR3isnon-zero,itcontains;apointertoanfloatingpointsaveareathatisfree.
;fpsrchsave:
lwzr6,ACT_MACT_PCB(r12);Getthefirst"normal"saveareafpsrnorm:mr.r5,r6;Isthereanother?
beq-fpsrvect;No,searchthevectorsaveareas...lwzr7,SAVflags(r5);Gettheflagsforthisguy
lwzr6,SAVprev(r5);Gettheprevioussavearea,justincaseandis.r8,r7,hi16(SAVfpuvalid);HavewefoundanemptyFPUsaveinnormal?
beq+fpsrgot;Wefoundone...bfpsrnorm;Searchagain...fpsrvect:lwzr6,ACT_MACT_VMX(r12);Getthefirst"vector"saveareafpsrvectx:mr.r5,r6;Isthereanother?
beq-fpsrget;No,trytoallocateone...lwzr7,SAVflags(r5);Gettheflagsforthisguy
lwzr6,SAVprevec(r5);Gettheprevioussavearea,justincaseandis.r8,r7,hi16(SAVfpuvalid);HavewefoundanemptyFPUsaveinvector?
bne-fpsrvectx;Searchagain...fpsrgot:mrr3,r5;Getthesaveareaintotherightregister
blr;Return...
fpsrget:mr.r5,r3;Doweallocateoruseexisting?
beq+fpsrallo;Allocateone...lwzr7,SAVflags(r3);Getthepassedinareaflags
blr;Return...;
;NOTE:save_getwillreturndirectlyandsetR7to0...;
fpsrallo:bEXT(save_get);Getafreshsavearea
/*
*Altivecstuffishere.Thetechniquesusedareprettyidenticalto
*thefloatingpoint.ExceptthatwewillhonortheVRSAVEregister
*settingswhenloadingandrestoringregisters.
**TherearetwoindicationsofsavedVRs:theVRSAVEregisterandthevrvalid
*mask.VRSAVEissetbythevectoruserandrepresentstheVRsthatthey
*saythattheyareusing.Thevrvalidmaskindicateswhichvectorregisters
*aresavedinthesavearea.Whenevercontextissaved,itissavedaccording
*totheVRSAVEregister.ItisloadedbasedonVRSAVEandedwith
*vrvalid(allotherregistersaresplattedwith0s).Thisisdonebecausewe
*don'twanttoloadanyregisterswedon'thaveacopyof,wewanttosetthem
*tozeroinstead.
**/
ENTRY(vec_save,TAG_NO_FRAME_USED)
mfmsrr0;GettheMSR
rlwinmr0,r0,0,MSR_VEC_BIT+1,MSR_VEC_BIT-1;Turnoffvectorforeverrlwinmr2,r0,0,MSR_EE_BIT+1,MSR_EE_BIT-1;Butdointerruptsonlyfornow
orisr2,r2,hi16(MASK(MSR_VEC));Enablethevectorfacilityfornowalsomtmsrr2;SettheMSR
isyncmfsprgr6,0;Gettheper_processorblock
lwzr12,PP_VMX_THREAD(r6);Getthethreadthatownsthevector#ifFPVECDBG
mrr7,r0;(TEST/DEBUG)
lir4,0;(TEST/DEBUG)mrr10,r3;(TEST/DEBUG)
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)mr.r3,r12;(TEST/DEBUG)
lir2,0x5F00;(TEST/DEBUG)lir5,0;(TEST/DEBUG)
beq-noowneryeu;(TEST/DEBUG)lwzr4,ACT_MACT_VMXlvl(r12);(TEST/DEBUG)
lwzr5,ACT_MACT_VMX(r12);(TEST/DEBUG)
noowneryeu:orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)
sc;(TEST/DEBUG)mrr0,r7;(TEST/DEBUG)
mrr3,r10;(TEST/DEBUG)#endif
mflrr2;Savethereturnaddress
lhzr11,PP_CPU_NUMBER(r6);GetourCPUnumbermr.r12,r12;Anyoneownthevector?
cmplwcr1,r3,r12;Isthespecifiedthreadtheowner?beq-vsretnr;Nobodyownsthevector,nosaverequired...lir4,ACT_MACT_VMXcpu;PointtotheCPUindication/lockword
bne-cr1,vsretnr;Facilitybelongstosomeotheractivation...vsvSpin2:lwarxr9,r4,r12;GetandreservethelastusedCPU
mr.r9,r9;Isitchangingnow?orisr3,r9,hi16(fvChk);Setthe"changing"flag
blt-vsvSpin2;Spinifchangingstwcx.r3,r4,r12;Lockitup
bne-vsvSpin2;Someoneismessingrightnow
isync;Makesureweseeeverythingcmplwcr1,r9,r11;Wasthecontextforthisprocessor?
lir3,0;Assumeweneedafix-me-upbeq-cr1,vsgoodcpu;Facilitylastusedonthisprocessor...
stwr3,PP_VMX_THREAD(r6);Clearownerbecauseitwasreallyontheotherprocessorbvsret;Bailnowwithnosave...vsgoodcpu:lwzr3,ACT_MACT_VMX(r12);Getthecurrentvectorsaveareaforthethread
lwzr9,ACT_MACT_VMXlvl(r12);Getourcurrentlevelindicatorcmplwicr1,r3,0;Haveweeversavedthisfacilitycontext?
beq-cr1,vsneedone;Neversavedit,soweneedanarea...lwzr8,SAVlvlvec(r3);Getthelevelthissaveareaisfor
cmplwir8,1;Seeifthisisasparecmplwcr1,r9,r8;Correctlevel?
beq+vsusespare;Itisstilllive...beq-cr1,vsret;Thecurrentlevelisalreadysaved,bailout...vsneedone:lir3,0;Telltheroutinetoallocateanareaifnonefound
blvsrchsave;Findafreesaveareamfsprgr6,0;Getbackper_processorblock
orisr7,r7,hi16(SAVvmxvalid);Settheallocatedbitlwzr12,PP_VMX_THREAD(r6);Getbackourthread
mtlrr2;Restorereturnlwzr8,ACT_MACT_VMX(r12);Getthecurrenttopvectorsavearea
lwzr9,ACT_MACT_VMXlvl(r12);Getourcurrentlevelindicatoragainstwr3,ACT_MACT_VMX(r12);Setthisasthelatestvectorsaveareaforthethread
stwr8,SAVprevec(r3);Andthenchainthisinfrontstwr7,SAVflags(r3);Settheallocationflags
stwr12,SAVact(r3);Makesurewepointtotherightguy
vsusespare:stwr9,SAVlvlvec(r3);Andsetthelevelthissaveareaisfor
mfcrr2;Savenon-volatileCRslwzr10,liveVRS(r6);GettherightVRSaveregister
lisr9,0x5555;Maskwithoddbitssetrlwinmr11,r10,1,0,31;Shiftover1
orir9,r9,0x5555;Finishmaskorr4,r10,r11;Afterthis,evenbitsshowwhichlinestozapandcr11,r4,r9;Clearoutoddbitslar6,savevr0(r3);Pointtoline0
rlwinmr4,r11,15,0,15;Moveline8-15flagstohighorderoddbitslar9,savevrvalid(r3);Pointtothesavedregistermaskfield
orr4,r11,r4;Settheoddbits;(bit0isline0,bit1isline8,
;bit2isline1,bit3isline9,etc.dcbabr0,r9;Allocatethecacheforit
rlwimir4,r10,16,16,31;Putvrsave0-15intopositions16-31lar7,savevr2(r3);Pointtoline1
mtcrf255,r4;LoaduptheCRsstwr10,savevrvalid(r3);Savethevalidityinformation
mrr8,r6;Startregistersoff;
;Savethecurrentvectorstate;bf0,snol0;Noline0todo...
dcbabr0,r6;Allocatecacheline0snol0:
lar6,savevr4(r3);Pointtoline2
bf2,snol1;Noline1todo...dcbabr0,r7;Allocatecacheline1snol1:
lar7,savevr6(r3);Pointtoline3
bf4,snol2;Noline2todo...dcbabr0,r6;Allocatecacheline2snol2:
lir11,16;Getoffsetforoddregisters
bf16,snovr0;DonotsaveVR0...stvxlv0,br0,r8;SaveVR0snovr0:
lar9,savevr2(r3);PointtoV2/V3pair
bf17,snovr1;DonotsaveVR1...stvxlv1,r11,r8;SaveVR1snovr1:
lar6,savevr8(r3);Pointtoline4
bf6,snol3;Noline3todo...dcbabr0,r7;Allocatecacheline3snol3:
lar8,savevr4(r3);PointtoV4/V5pair
bf18,snovr2;DonotsaveVR2...stvxlv2,br0,r9;SaveVR2snovr2:
bf19,snovr3;DonotsaveVR3...
stvxlv3,r11,r9;SaveVR3snovr3:
;Note:CR4isnowfree;
lar7,savevr10(r3);Pointtoline5bf8,snol4;Noline4todo...
dcbabr0,r6;Allocatecacheline4snol4:
lar9,savevr6(r3);PointtoR6/R7pair
bf20,snovr4;DonotsaveVR4...stvxlv4,br0,r8;SaveVR4snovr4:
bf21,snovr5;DonotsaveVR5...
stvxlv5,r11,r8;SaveVR5snovr5:
mtcrf0x08,r10;SetCRsforregisters16-19
lar6,savevr12(r3);Pointtoline6bf10,snol5;Noline5todo...
dcbabr0,r7;Allocatecacheline5snol5:
lar8,savevr8(r3);PointtoV8/V9pair
bf22,snovr6;DonotsaveVR6...stvxlv6,br0,r9;SaveVR6snovr6:
bf23,snovr7;DonotsaveVR7...
stvxlv7,r11,r9;SaveVR7snovr7:
;Note:CR5isnowfree;
lar7,savevr14(r3);Pointtoline7bf12,snol6;Noline6todo...
dcbabr0,r6;Allocatecacheline6snol6:
lar9,savevr10(r3);PointtoV10/V11pair
bf24,snovr8;DonotsaveVR8...stvxlv8,br0,r8;SaveVR8snovr8:
bf25,snovr9;DonotsaveVR9...
stvxlv9,r11,r8;SaveVR9snovr9:
mtcrf0x04,r10;SetCRsforregisters20-23
lar6,savevr16(r3);Pointtoline8bf14,snol7;Noline7todo...
dcbabr0,r7;Allocatecacheline7snol7:
lar8,savevr12(r3);PointtoV12/V13pair
bf26,snovr10;DonotsaveVR10...stvxlv10,br0,r9;SaveVR10snovr10:
bf27,snovr11;DonotsaveVR11...
stvxlv11,r11,r9;SaveVR11snovr11:
;Note:CR6isnowfree;
lar7,savevr18(r3);Pointtoline9bf1,snol8;Noline8todo...
dcbabr0,r6;Allocatecacheline8snol8:
lar9,savevr14(r3);PointtoV14/V15pair
bf28,snovr12;DonotsaveVR12...stvxlv12,br0,r8;SaveVR12snovr12:
bf29,snovr13;DonotsaveVR13...
stvxlv13,r11,r8;SaveVR13snovr13:
mtcrf0x02,r10;SetCRsforregisters24-27
lar6,savevr20(r3);Pointtoline10bf3,snol9;Noline9todo...
dcbabr0,r7;Allocatecacheline9snol9:
lar8,savevr16(r3);PointtoV16/V17pair
bf30,snovr14;DonotsaveVR14...stvxlv14,br0,r9;SaveVR14snovr14:
bf31,snovr15;DonotsaveVR15...
stvxlv15,r11,r9;SaveVR15snovr15:
;Note:CR7isnowfree;
lar7,savevr22(r3);Pointtoline11bf5,snol10;Noline10todo...
dcbabr0,r6;Allocatecacheline10snol10:
lar9,savevr18(r3);PointtoV18/V19pair
bf16,snovr16;DonotsaveVR16...stvxlv16,br0,r8;SaveVR16snovr16:
bf17,snovr17;DonotsaveVR17...
stvxlv17,r11,r8;SaveVR17snovr17:
mtcrf0x01,r10;SetCRsforregisters28-31
;;Note:AllregistershavebeenorareaccountedforinCRs
;lar6,savevr24(r3);Pointtoline12
bf7,snol11;Noline11todo...dcbabr0,r7;Allocatecacheline11snol11:
lar8,savevr20(r3);PointtoV20/V21pair
bf18,snovr18;DonotsaveVR18...stvxlv18,br0,r9;SaveVR18snovr18:
bf19,snovr19;DonotsaveVR19...
stvxlv19,r11,r9;SaveVR19snovr19:
lar7,savevr26(r3);Pointtoline13
bf9,snol12;Noline12todo...dcbabr0,r6;Allocatecacheline12snol12:
lar9,savevr22(r3);PointtoV22/V23pair
bf20,snovr20;DonotsaveVR20...stvxlv20,br0,r8;SaveVR20snovr20:
bf21,snovr21;DonotsaveVR21...
stvxlv21,r11,r8;SaveVR21snovr21:
lar6,savevr28(r3);Pointtoline14
bf11,snol13;Noline13todo...dcbabr0,r7;Allocatecacheline13snol13:
lar8,savevr24(r3);PointtoV24/V25pair
bf22,snovr22;DonotsaveVR22...stvxlv22,br0,r9;SaveVR22snovr22:
bf23,snovr23;DonotsaveVR23...
stvxlv23,r11,r9;SaveVR23snovr23:
lar7,savevr30(r3);Pointtoline15
bf13,snol14;Noline14todo...dcbabr0,r6;Allocatecacheline14snol14:
lar9,savevr26(r3);PointtoV26/V27pair
bf24,snovr24;DonotsaveVR24...stvxlv24,br0,r8;SaveVR24snovr24:
bf25,snovr25;DonotsaveVR25...
stvxlv25,r11,r8;SaveVR25snovr25:
bf15,snol15;Noline15todo...
dcbabr0,r7;Allocatecacheline15snol15:
;Note:Allcachelinesallocatednow;
lar8,savevr28(r3);PointtoV28/V29pairbf26,snovr26;DonotsaveVR26...
stvxlv26,br0,r9;SaveVR26
snovr26:
bf27,snovr27;DonotsaveVR27...
stvxlv27,r11,r9;SaveVR27snovr27:
lar7,savevr30(r3);PointtoV30/V31pair
bf28,snovr28;DonotsaveVR28...stvxlv28,br0,r8;SaveVR28snovr28:
bf29,snovr29;DonotsaveVR29...
stvxlv29,r11,r8;SaveVR29snovr29:
mfvscrv27;GettheVSCR
lar8,savevscr(r3);PointtotheVSCRsaveareabf30,snovr30;DonotsaveVR30...
stvxlv30,br0,r7;SaveVR30snovr30:
dcbabr0,r8;AllocateVSCRsavearea
bf31,snovr31;DonotsaveVR31...stvxlv31,r11,r7;SaveVR31snovr31:
addr11,r11,r9;PointtoV27ssavedvalue
stvxlv27,br0,r8;SavetheVSCRbt27,v27ok;V27hasbeensavedandismarkedaswantedlisr11,hi16(EXT(QNaNbarbarian));V27isnotwanted,sogetemptyvalue
orir11,r11,lo16(EXT(QNaNbarbarian))
v27ok:mtcrf255,r2;Restoreallnon-volatileCRs
lvxlv27,br0,r11;RestoreorloademptyvalueintoV27becauseweusedit
;Savethecurrentvectorstateintothesaveareaofthethreadthatownsit.;vsret:lwzr4,ACT_MACT_VMXcpu(r12);GetbacktheownerCPU
rlwinmr4,r4,0,fvChkb+1,31;Clearlocksyncstwr4,ACT_MACT_VMXcpu(r12);Unlockthecontextvsretnr:mtmsrr0;Putinterruptsoniftheywereandvectoroff
isync
blr
/*
*vec_switch()
**Enteredtohandlethevectorunavailableexceptionand
*switchvectorcontext
**Thiscodeisrunwithvirtualaddressmodeonandinterruptsoff.
**Uponexit,thecodereturnstotheuserscontextwiththevector
*facilityturnedon.
**ENTRY:VMswitchedON
*InterruptsOFF
*StateissavedinsaveareapointedtobyR4.
*Allotherregistersarefree.
*/
ENTRY(vec_switch,TAG_NO_FRAME_USED)
#ifDEBUG
#ifGDDBG
mrr7,r4;Saveinputparameter
lisr3,hi16(EXT(vec_trap_count));Getaddressofvectortrapcounterorir3,r3,lo16(EXT(vec_trap_count));Getaddressofvectortrapcounter
lwzr1,0(r3)lisr5,hi16(EXT(GratefulDeb));Pointtotopofdisplay
orir5,r5,lo16(EXT(GratefulDeb));Putinbottompartaddir1,r1,1
mtlrr5;Setlinkregister
stwr1,0(r3)mrr4,r1
lisr3,1
blrl;Displaycount
mrr4,r7;Restoretheparameter#else
lisr3,hi16(EXT(vec_trap_count));Getaddressofvectortrapcounter
orir3,r3,lo16(EXT(vec_trap_count));Getaddressofvectortrapcounterlwzr1,0(r3)
addir1,r1,1
stwr1,0(r3)
#endif
#endif/*DEBUG*/
mfsprgr6,0/*Gettheper_processorblock*/
mfmsrr19/*GetthecurrentMSR*/
lwzr10,PP_CPU_DATA(r6)/*GettheCPUdatapointer*/
lwzr12,PP_VMX_THREAD(r6)/*Getthethreadthatownsthevector*/
lwzr10,CPU_ACTIVE_THREAD(r10)/*Getthepointertotheactivethread*/
orisr19,r19,hi16(MASK(MSR_VEC))/*Enablethevectorfeature*/
lwzr17,THREAD_TOP_ACT(r10)/*Nowgettheactivationthatisrunning*/
;R12hasthe"old"activation
;R17hasthe"new"activation
#ifFPVECDBG
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x5F01;(TEST/DEBUG)mrr3,r12;(TEST/DEBUG)
mrr5,r17;(TEST/DEBUG)orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)
sc;(TEST/DEBUG)#ifGDDBG
lisr3,hi16(EXT(GratefulDeb));Pointtotopofdisplay
mrr18,r4;Savethisorir3,r3,lo16(EXT(GratefulDeb));Putinbottompart
mrr4,r2;Setvaluemtlrr3;Setlinkregister
lir3,1;Displayaddressblrl;Displayit
mrr4,r18;Restoreitmfsprgr6,0;Gettheper_processorblockback
#endif#endif
mr.r12,r12;Seeifthereisanylivevectorstatuslhzr18,PP_CPU_NUMBER(r6);GetourCPUnumbermtmsrr19/*Setvectoravailable*/
isyncbeq-vsnosave;Nolivecontext,sonothingtosave...lir20,ACT_MACT_VMXcpu;PointtotheCPUindication/lockwordvsSpin1:lwarxr19,r20,r12;GetandreservethelastusedCPU
mr.r19,r19;Isitchangingnow?orisr21,r19,hi16(fvChk);Setthe"changing"flag
blt-vsSpin1;Spinifchangingstwcx.r21,r20,r12;Lockitup
bne-vsSpin1;Someoneismessingrightnow
isync;Makesureweseeeverythinglwzr15,ACT_MACT_PCB(r12);Getthecurrentlevelofthe"old"one
cmplwr18,r19;ChecktheCPUthattheoldcontextisliveonlwzr14,ACT_MACT_VMX(r12);Pointtothetopoftheoldcontextstack
bne-vsnosaverel;ContextisnotliveifusedonadifferentCPU...lwzr13,ACT_MACT_VMXlvl(r12);Getthe"old"activelevel;
;First,checktoseeifallwearedoingisenablingbecausethe;"new"contextislive.
;#ifFPVECDBG
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x5F02;(TEST/DEBUG)mrr1,r15;(TEST/DEBUG)
mrr3,r13;(TEST/DEBUG)mrr5,r14;(TEST/DEBUG)
orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)sc;(TEST/DEBUG)
#ifGDDBGlisr3,hi16(EXT(GratefulDeb));Pointtotopofdisplay
mrr8,r4;Savethisorir3,r3,lo16(EXT(GratefulDeb));Putinbottompart
mrr4,r2;Setvaluemtlrr3;Setlinkregister
lir3,1;Displayaddressblrl;Displayit
mrr4,r8;Restoreit#endif
#endif
cmplwcr1,r12,r17;Isthe"old"activationandthe"new"thesame?
cmplwicr2,r14,0;Isthereanysavedcontextonthe"old"activation?bne+cr1,vsmstsave;Theactivationsaredifferentso"old"contextmustbesaved...;
;Hereweknowthatboththe"old"and"new"activationsarethesame.Wewill;checkthecurrentlevelandactivelevels.Iftheyarethesame,thecontextis
;alreadylive,soallwedoisturnonthefacilityandinvalidatethetop;savearea.
;;Ifthecurrentlevel,theactivelevel,andthetopsavearealevelarethe
;same,thenthecontextwassavedaspartofathreadcontextswitchandneither;needssavingorrestoration.
;;Inallothercases,thecontextmustbesavedunlesswearejustre-enabling
;vector.;cmplwr13,r15;Arethelevelsthesame?
cmplwicr2,r14,0;Isthereanysavedcontext?bne-vsmstsave;Levelsaredifferent,weneedtosave...beq-cr2,vrenableret;Nosavedcontextatall,enableandgo...lwzr20,SAVlvlvec(r14);Getthelevelofthetopsavearea#ifFPVECDBG
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x5F03;(TEST/DEBUG)mrr3,r15;(TEST/DEBUG)
mrr5,r20;(TEST/DEBUG)orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)
sc;(TEST/DEBUG)#ifGDDBG
lisr3,hi16(EXT(GratefulDeb));Pointtotopofdisplay
mrr8,r4;Savethisorir3,r3,lo16(EXT(GratefulDeb));Putinbottompart
mrr4,r2;Setvaluemtlrr3;Setlinkregister
lir3,1;Displayaddressblrl;Displayit
mrr4,r8;Restoreit#endif
#endif
cmplwr15,r20;Isthetoplevelthesameasthecurrent?
lir0,1;Gettheinvalidflagbne-vrenableret;Notthesame,justenableandgo...stwr0,SAVlvlvec(r14);Invalidatethattopsaveareavrenableret:
sync;Makesureeverythingissaved
stwr19,ACT_MACT_VMXcpu(r12);Saywearenotusingthecontextanymorebvrenable;Thenenableandgo...;
;Weneedtosavethe"old"contexthere.TheLIFOqueueingschemeworks;outforallcasesbecauseifboththe"new"and"old"activationsarethe
;same,therecannotbeanysavedstatetoload.the"new"levelis;truelynew.
;;Whenwesavethecontext,weeitheruseanewsavearea,orthefree
;onethatiscachedattheheadofthelist.vsmstsave:beq-cr2,vsgetsave;Thereisnopossiblecachedsavearealwzr5,SAVlvlvec(r14);Gettheleveloffirstfacilitysavearea
#ifFPVECDBGlisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x5F04;(TEST/DEBUG)mrr3,r15;(TEST/DEBUG)
orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)sc;(TEST/DEBUG)
#ifGDDBGlisr3,hi16(EXT(GratefulDeb));Pointtotopofdisplay
mrr8,r4;Savethismrr7,r5;Savethis
orir3,r3,lo16(EXT(GratefulDeb));Putinbottompartmrr4,r2;Setvalue
mtlrr3;Setlinkregisterlir3,1;Displayaddress
blrl;Displayitmrr4,r8;Restoreit
mrr5,r7;Restoreit#endif
#endif
mrr3,r14;Assumeweareinvalid
cmplwir5,1;Isitinvalid?cmplwcr1,r5,r13;IstheSAleveltheactiveone?
beq+vsusecache;Invalid,justuseit...beq-cr1,vsnosaverel;TheSAlevelisactive,itisalreadysaved...vsgetsave:mrr3,r4;Usetheinterruptsaveasthecontextsaveareaifnonecached
#ifFPVECDBGlisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x5F05;(TEST/DEBUG)orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)
sc;(TEST/DEBUG)#ifGDDBG
lisr3,hi16(EXT(GratefulDeb));Pointtotopofdisplay
mrr8,r4;Savethisorir3,r3,lo16(EXT(GratefulDeb));Putinbottompart
mrr4,r2;Setvaluemtlrr3;Setlinkregister
lir3,1;Displayaddressblrl;Displayit
mrr4,r8;Restoreitmrr3,r8;Thistoo
#endif#endif
blvsrchsave;Findafreesaveareastwr3,ACT_MACT_VMX(r12);Setthisasthelatestcontextsaveareaforthethread
mfsprgr6,0;Getbackper_processorblockstwr14,SAVprevec(r3);Andthenchainthisinfront
orisr7,r7,hi16(SAVvmxvalid);Settheallocatedbitstwr12,SAVact(r3);Makesurewepointtotherightguy
stwr7,SAVflags(r3);Settheallocationflags
vsusecache:lar11,savevr0(r3);Pointtothe1stlineinarea
stwr13,SAVlvlvec(r3);Setthiscontextlevel#ifFPVECDBG
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x5F06;(TEST/DEBUG)mrr5,r13;(TEST/DEBUG)
orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)sc;(TEST/DEBUG)
#ifGDDBGmrr10,r3
lisr3,hi16(EXT(GratefulDeb));Pointtotopofdisplay
mrr8,r4;Savethisorir3,r3,lo16(EXT(GratefulDeb));Putinbottompart
mrr4,r2;Setvaluemtlrr3;Setlinkregister
lir3,1;Displayaddressblrl;Displayit
mrr4,r8;Restoreitmrr3,r10
mfsprgr6,0;Getbackper_processorblock
#endif#endif
vsgotsave:
lwzr10,liveVRS(r6);GettherightVRSaveregister
lisr9,0x5555;Maskwithoddbitssetrlwinmr11,r10,1,0,31;Shiftover1
orir9,r9,0x5555;Finishmaskorr21,r10,r11;Afterthis,evenbitsshowwhichlinestozapstwr13,SAVlvlvec(r3);Setthesavearealevel
andcr13,r21,r9;Clearoutoddbitslar20,savevr0(r3);Pointtoline0
rlwinmr24,r13,15,0,15;Moveline8-15flagstohighorderoddbitslar23,savevrvalid(r3);Pointtothesavedregistermaskfield
orr24,r13,r24;Settheoddbits;(bit0isline0,bit1isline8,
;bit2isline1,bit3isline9,etc.dcbabr0,r23;Allocatethecacheforit
rlwimir24,r10,16,16,31;Putvrsave0-15intopositions16-31lar21,savevr2(r3);Pointtoline1
mtcrf255,r24;LoaduptheCRsstwr10,savevrvalid(r3);Savethevalidityinformation
mrr22,r20;Startregistersoff;
;Savethecurrentvectorstate;bf0,nol0;Noline0todo...
dcbabr0,r20;Allocatecacheline0nol0:
lar20,savevr4(r3);Pointtoline2
bf2,nol1;Noline1todo...dcbabr0,r21;Allocatecacheline1nol1:
lar21,savevr6(r3);Pointtoline3
bf4,nol2;Noline2todo...dcbabr0,r20;Allocatecacheline2nol2:
lir30,16;Getoffsetforoddregisters
bf16,novr0;DonotsaveVR0...stvxlv0,br0,r22;SaveVR0novr0:
lar23,savevr2(r3);PointtoV2/V3pair
bf17,novr1;DonotsaveVR1...stvxlv1,r30,r22;SaveVR1novr1:
lar20,savevr8(r3);Pointtoline4
bf6,nol3;Noline3todo...dcbabr0,r21;Allocatecacheline3nol3:
lar22,savevr4(r3);PointtoV4/V5pair
bf18,novr2;DonotsaveVR2...stvxlv2,br0,r23;SaveVR2novr2:
bf19,novr3;DonotsaveVR3...
stvxlv3,r30,r23;SaveVR3novr3:
;Note:CR4isnowfree;
lar21,savevr10(r3);Pointtoline5bf8,nol4;Noline4todo...
dcbabr0,r20;Allocatecacheline4nol4:
lar23,savevr6(r3);PointtoR6/R7pair
bf20,novr4;DonotsaveVR4...stvxlv4,br0,r22;SaveVR4novr4:
bf21,novr5;DonotsaveVR5...
stvxlv5,r30,r22;SaveVR5novr5:
mtcrf0x08,r10;SetCRsforregisters16-19
lar20,savevr12(r3);Pointtoline6bf10,nol5;Noline5todo...
dcbabr0,r21;Allocatecacheline5nol5:
lar22,savevr8(r3);PointtoV8/V9pair
bf22,novr6;DonotsaveVR6...stvxlv6,br0,r23;SaveVR6novr6:
bf23,novr7;DonotsaveVR7...
stvxlv7,r30,r23;SaveVR7novr7:
;Note:CR5isnowfree;
lar21,savevr14(r3);Pointtoline7bf12,nol6;Noline6todo...
dcbabr0,r20;Allocatecacheline6nol6:
lar23,savevr10(r3);PointtoV10/V11pair
bf24,novr8;DonotsaveVR8...stvxlv8,br0,r22;SaveVR8novr8:
bf25,novr9;DonotsaveVR9...
stvxlv9,r30,r22;SaveVR9novr9:
mtcrf0x04,r10;SetCRsforregisters20-23
lar20,savevr16(r3);Pointtoline8bf14,nol7;Noline7todo...
dcbabr0,r21;Allocatecacheline7nol7:
lar22,savevr12(r3);PointtoV12/V13pair
bf26,novr10;DonotsaveVR10...stvxlv10,br0,r23;SaveVR10novr10:
bf27,novr11;DonotsaveVR11...
stvxlv11,r30,r23;SaveVR11novr11:
;Note:CR6isnowfree;
lar21,savevr18(r3);Pointtoline9bf1,nol8;Noline8todo...
dcbabr0,r20;Allocatecacheline8nol8:
lar23,savevr14(r3);PointtoV14/V15pair
bf28,novr12;DonotsaveVR12...stvxlv12,br0,r22;SaveVR12novr12:
bf29,novr13;DonotsaveVR13...
stvxlv13,r30,r22;SaveVR13novr13:
mtcrf0x02,r10;SetCRsforregisters24-27
lar20,savevr20(r3);Pointtoline10bf3,nol9;Noline9todo...
dcbabr0,r21;Allocatecacheline9nol9:
lar22,savevr16(r3);PointtoV16/V17pair
bf30,novr14;DonotsaveVR14...stvxlv14,br0,r23;SaveVR14novr14:
bf31,novr15;DonotsaveVR15...
stvxlv15,r30,r23;SaveVR15novr15:
;Note:CR7isnowfree;
lar21,savevr22(r3);Pointtoline11bf5,nol10;Noline10todo...
dcbabr0,r20;Allocatecacheline10nol10:
lar23,savevr18(r3);PointtoV18/V19pair
bf16,novr16;DonotsaveVR16...stvxlv16,br0,r22;SaveVR16novr16:
bf17,novr17;DonotsaveVR17...
stvxlv17,r30,r22;SaveVR17novr17:
mtcrf0x01,r10;SetCRsforregisters28-31
;;Note:AllregistershavebeenorareaccountedforinCRs
;lar20,savevr24(r3);Pointtoline12
bf7,nol11;Noline11todo...dcbabr0,r21;Allocatecacheline11nol11:
lar22,savevr20(r3);PointtoV20/V21pair
bf18,novr18;DonotsaveVR18...stvxlv18,br0,r23;SaveVR18novr18:
bf19,novr19;DonotsaveVR19...
stvxlv19,r30,r23;SaveVR19novr19:
lar21,savevr26(r3);Pointtoline13
bf9,nol12;Noline12todo...dcbabr0,r20;Allocatecacheline12nol12:
lar23,savevr22(r3);PointtoV22/V23pair
bf20,novr20;DonotsaveVR20...stvxlv20,br0,r22;SaveVR20novr20:
bf21,novr21;DonotsaveVR21...
stvxlv21,r30,r22;SaveVR21novr21:
lar20,savevr28(r3);Pointtoline14
bf11,nol13;Noline13todo...dcbabr0,r21;Allocatecacheline13nol13:
lar22,savevr24(r3);PointtoV24/V25pair
bf22,novr22;DonotsaveVR22...stvxlv22,br0,r23;SaveVR22novr22:
bf23,novr23;DonotsaveVR23...
stvxlv23,r30,r23;SaveVR23novr23:
lar21,savevr30(r3);Pointtoline15
bf13,nol14;Noline14todo...dcbabr0,r20;Allocatecacheline14nol14:
lar23,savevr26(r3);PointtoV26/V27pair
bf24,novr24;DonotsaveVR24...stvxlv24,br0,r22;SaveVR24novr24:
bf25,novr25;DonotsaveVR25...
stvxlv25,r30,r22;SaveVR25novr25:
bf15,nol15;Noline15todo...
dcbabr0,r21;Allocatecacheline15nol15:
;Note:Allcachelinesallocatednow;
lar22,savevr28(r3);PointtoV28/V29pairbf26,novr26;DonotsaveVR26...
stvxlv26,br0,r23;SaveVR26novr26:
bf27,novr27;DonotsaveVR27...
stvxlv27,r30,r23;SaveVR27novr27:
lar23,savevr30(r3);PointtoV30/V31pair
bf28,novr28;DonotsaveVR28...stvxlv28,br0,r22;SaveVR28novr28:
mfvscrv27;GettheVSCR
bf29,novr29;DonotsaveVR29...stvxlv29,r30,r22;SaveVR29novr29:
lar22,savevscr(r3);PointtotheVSCRsavearea
bf30,novr30;DonotsaveVR30...stvxlv30,br0,r23;SaveVR30novr30:
dcbabr0,r22;AllocateVSCRsavearea
bf31,novr31;DonotsaveVR31...stvxlv31,r30,r23;SaveVR31novr31:
stvxlv27,br0,r22;SavetheVSCR
/*
*Nowcheckoutthecurrentthreadandseeifweneedtoloaduphiscontext.
*Ifwedo(andthisshouldbethenormalcase),doitandthenreleasethe
*savearea.
*Ifwedon't(remember,wealreadytookcareofthecasewherewejustenable
*thevector),weneedtofilltheregisterswithgarbage,becausethisthreadhas
*neverusedthembeforeandsomethievingbastardcouldhacktheoldvalues
*ofsomethread!Justimaginewhatwouldhappeniftheycould!Why,nothing
*wouldbesafe!MyGosh!It'sterrifying!
*/
vsnosaverel:
sync;Makesureeverythingissaved
stwr19,ACT_MACT_VMXcpu(r12);Saywearenotusingthecontextanymore
vsnosave:
lir20,ACT_MACT_VMXcpu;PointtotheCPUindication/lockwordvsSpin2:lwarxr19,r20,r17;GetandreservethelastusedCPU
mr.r19,r19;Isitchangingnow?orisr21,r19,hi16(fvChk);Setthe"changing"flag
blt-vsSpin2;Spinifchangingstwcx.r21,r20,r17;Lockitup
bne-vsSpin2;Someoneismessingrightnow
isync;Makesureweseeeverythinglwzr15,ACT_MACT_PCB(r17);Getthecurrentlevelofthe"new"one
lwzr14,ACT_MACT_VMX(r17);Pointtothetopofthe"new"contextstacklwzr13,ACT_MACT_VMXlvl(r17);Getthe"new"activelevel#ifFPVECDBG
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x5F07;(TEST/DEBUG)mrr1,r15;(TEST/DEBUG)
mrr3,r14;(TEST/DEBUG)mrr5,r13;(TEST/DEBUG)
orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)sc;(TEST/DEBUG)
#endif
cmplwicr1,r14,0;Dowepossiblyhavesomecontexttoload?
stwr15,ACT_MACT_VMXlvl(r17);Setthe"new"activelevellar23,savevscr(r14);PointtotheVSCR
lar20,savevr0(r14);Pointtofirstlinetobringinstwr17,PP_VMX_THREAD(r6);Storecurrentthreadaddressinvmx_threadtoclaimvectorforthread
beq-cr1,ProtectTheAmericanWay;Nothingtorestore,firsttimeuse...lwzr0,SAVlvlvec(r14);Gettheleveloffirstfacilitysavearea
cmplwr0,r15;Toplevelcorrecttoload?bne-ProtectTheAmericanWay;No,goinitialize...#ifFPVECDBG
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x5F08;(TEST/DEBUG)orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)
sc;(TEST/DEBUG)#ifGDDBG
mrr8,r3
lisr3,hi16(EXT(GratefulDeb));Pointtotopofdisplay
mrr22,r4;Savethisorir3,r3,lo16(EXT(GratefulDeb));Putinbottompart
mrr4,r2;Setvaluemtlrr3;Setlinkregister
lir3,1;Displayaddressblrl;Displayit
mrr4,r22;Restoreitmrr3,r8
#endif
#endif
lir0,1;Getthelevelinvalidindication
lwzr22,savevrsave(r4);GetthemostcurrentVRSAVElwzr10,savevrvalid(r14);GetthevalidVRsinthesavearea
lisr9,0x5555;Maskwithoddbitssetandr10,r10,r22;Figureoutjustwhatregistersneedtobeloaded
orir9,r9,0x5555;Finishmaskrlwinmr11,r10,1,0,31;Shiftover1
stwr0,SAVlvlvec(r14);Markthesaveareainvalidbecauseweareactivatingagainorr12,r10,r11;Afterthis,evenbitsshowwhichlinestotouch
dcbtbr0,r23;TouchintheVSCRandcr13,r12,r9;Clearoutoddbitslar20,savevr0(r14);Pointtoline0
rlwinmr3,r13,15,0,15;Moveline8-15flagstohighorderoddbitslar21,savevr2(r3);Pointtoline1
orr3,r13,r3;Settheoddbits;(bit0isline0,bit1isline8,
;bit2isline1,bit3isline9,etc.lvxlv31,br0,r23;GettheVSCR
rlwimir3,r10,16,16,31;Putvrsave0-15intopositions16-31mtvscrv31;SlamtheVSCRvalue
mtcrf255,r3;LoaduptheCRsmrr22,r20;Startregistersoff
;;Loadthenewvectorstate
;bf0,lnol0;Noline0todo...
dcbtbr0,r20;Touchcacheline0lnol0:
lar20,savevr4(r14);Pointtoline2
bf2,lnol1;Noline1todo...dcbtbr0,r21;Touchcacheline1lnol1:
lar21,savevr6(r14);Pointtoline3
bf4,lnol2;Noline2todo...dcbtbr0,r20;Touchcacheline2lnol2:
lir30,16;Getoffsetforoddregisters
bf16,lnovr0;DonotrestoreVR0...lvxlv0,br0,r22;RestoreVR0lnovr0:
lar23,savevr2(r14);PointtoV2/V3pair
bf17,lnovr1;DonotrestoreVR1...lvxlv1,r30,r22;RestoreVR1lnovr1:
lar20,savevr8(r14);Pointtoline4
bf6,lnol3;Noline3todo...dcbtbr0,r21;Touchcacheline3lnol3:
lar22,savevr4(r14);PointtoV4/V5pair
bf18,lnovr2;DonotrestoreVR2...lvxlv2,br0,r23;RestoreVR2lnovr2:
bf19,lnovr3;DonotrestoreVR3...
lvxlv3,r30,r23;RestoreVR3lnovr3:
;Note:CR4isnowfree;
lar21,savevr10(r14);Pointtoline5bf8,lnol4;Noline4todo...
dcbtbr0,r20;Touchcacheline4lnol4:
lar23,savevr6(r14);PointtoR6/R7pair
bf20,lnovr4;DonotrestoreVR4...lvxlv4,br0,r22;RestoreVR4lnovr4:
bf21,lnovr5;DonotrestoreVR5...
lvxlv5,r30,r22;RestoreVR5lnovr5:
mtcrf0x08,r10;SetCRsforregisters16-19
lar20,savevr12(r14);Pointtoline6bf10,lnol5;Noline5todo...
dcbtbr0,r21;Touchcacheline5lnol5:
lar22,savevr8(r14);PointtoV8/V9pair
bf22,lnovr6;DonotrestoreVR6...lvxlv6,br0,r23;RestoreVR6lnovr6:
bf23,lnovr7;DonotrestoreVR7...
lvxlv7,r30,r23;RestoreVR7lnovr7:
;Note:CR5isnowfree;
lar21,savevr14(r14);Pointtoline7bf12,lnol6;Noline6todo...
dcbtbr0,r20;Touchcacheline6lnol6:
lar23,savevr10(r14);PointtoV10/V11pair
bf24,lnovr8;DonotrestoreVR8...lvxlv8,br0,r22;RestoreVR8lnovr8:
bf25,lnovr9;DonotsaveVR9...
lvxlv9,r30,r22;RestoreVR9lnovr9:
mtcrf0x04,r10;SetCRsforregisters20-23
lar20,savevr16(r14);Pointtoline8bf14,lnol7;Noline7todo...
dcbtbr0,r21;Touchcacheline7lnol7:
lar22,savevr12(r14);PointtoV12/V13pair
bf26,lnovr10;DonotrestoreVR10...lvxlv10,br0,r23;RestoreVR10lnovr10:
bf27,lnovr11;DonotrestoreVR11...
lvxlv11,r30,r23;RestoreVR11lnovr11:
;Note:CR6isnowfree;
lar21,savevr18(r14);Pointtoline9bf1,lnol8;Noline8todo...
dcbtbr0,r20;Touchcacheline8lnol8:
lar23,savevr14(r14);PointtoV14/V15pair
bf28,lnovr12;DonotrestoreVR12...lvxlv12,br0,r22;RestoreVR12lnovr12:
bf29,lnovr13;DonotrestoreVR13...
lvxlv13,r30,r22;RestoreVR13lnovr13:
mtcrf0x02,r10;SetCRsforregisters24-27
lar20,savevr20(r14);Pointtoline10bf3,lnol9;Noline9todo...
dcbtbr0,r21;Touchcacheline9lnol9:
lar22,savevr16(r14);PointtoV16/V17pair
bf30,lnovr14;DonotrestoreVR14...lvxlv14,br0,r23;RestoreVR14lnovr14:
bf31,lnovr15;DonotrestoreVR15...
lvxlv15,r30,r23;RestoreVR15lnovr15:
;Note:CR7isnowfree;
lar21,savevr22(r14);Pointtoline11bf5,lnol10;Noline10todo...
dcbtbr0,r20;Touchcacheline10lnol10:
lar23,savevr18(r14);PointtoV18/V19pair
bf16,lnovr16;DonotrestoreVR16...lvxlv16,br0,r22;RestoreVR16lnovr16:
bf17,lnovr17;DonotrestoreVR17...
lvxlv17,r30,r22;RestoreVR17lnovr17:
mtcrf0x01,r10;SetCRsforregisters28-31
;;Note:AllregistershavebeenorareaccountedforinCRs
;lar20,savevr24(r14);Pointtoline12
bf7,lnol11;Noline11todo...dcbtbr0,r21;Touchcacheline11lnol11:
lar22,savevr20(r14);PointtoV20/V21pair
bf18,lnovr18;DonotrestoreVR18...lvxlv18,br0,r23;RestoreVR18lnovr18:
bf19,lnovr19;DonotrestoreVR19...
lvxlv19,r30,r23;RestoreVR19lnovr19:
lar21,savevr26(r14);Pointtoline13
bf9,lnol12;Noline12todo...dcbtbr0,r20;Touchcacheline12lnol12:
lar23,savevr22(r14);PointtoV22/V23pair
bf20,lnovr20;DonotrestoreVR20...lvxlv20,br0,r22;RestoreVR20lnovr20:
bf21,lnovr21;DonotrestoreVR21...
lvxlv21,r30,r22;RestoreVR21lnovr21:
lar20,savevr28(r14);Pointtoline14
bf11,lnol13;Noline13todo...dcbtbr0,r21;Touchcacheline13lnol13:
lar22,savevr24(r14);PointtoV24/V25pair
bf22,lnovr22;DonotrestoreVR22...lvxlv22,br0,r23;RestoreVR22lnovr22:
bf23,lnovr23;DonotrestoreVR23...
lvxlv23,r30,r23;RestoreVR23lnovr23:
lar21,savevr30(r14);Pointtoline15
bf13,lnol14;Noline14todo...dcbtbr0,r20;Touchcacheline14lnol14:
lar23,savevr26(r14);PointtoV26/V27pair
bf24,lnovr24;DonotrestoreVR24...lvxlv24,br0,r22;RestoreVR24lnovr24:
bf25,lnovr25;DonotrestoreVR25...
lvxlv25,r30,r22;RestoreVR25lnovr25:
bf15,lnol15;Noline15todo...
dcbtbr0,r21;Touchcacheline15lnol15:
;Note:Allneededcachelineshavebeentouchednow;
lar22,savevr28(r14);PointtoV28/V29pairbf26,lnovr26;DonotrestoreVR26...
lvxlv26,br0,r23;RestoreVR26lnovr26:
bf27,lnovr27;DonotrestoreVR27...
lvxlv27,r30,r23;RestoreVR27lnovr27:
lar23,savevr30(r14);PointtoV30/V31pair
bf28,lnovr28;DonotrestoreVR28...lvxlv28,br0,r22;RestoreVR28lnovr28:
bf29,lnovr29;DonotrestoreVR29...
lvxlv29,r30,r22;RestoreVR29lnovr29:
bf30,lnovr30;DonotrestoreVR30...
lvxlv30,br0,r23;RestoreVR30lnovr30:
;EverythingisrestorednowexceptforVR31.Weneedittoget;theQNaNBarbarianvaluetoputintoidlevectorregisters
;lisr5,hi16(EXT(QNaNbarbarian));Getaddressofemptyvalue
cmpwir10,-1;Handlethequickcaseofallregistersinuseorir5,r5,lo16(EXT(QNaNbarbarian));Getlowaddressofemptyvalue
beq-mstlvr31;Notlikely,butallareinuse...mtcrf255,r10;Getmaskofvalidregisters
lvxlv31,br0,r5;InitializeVR31totheemptyvalue
bt0,ni0;Registerisokalready...
vorv0,v31,v31;Copyintothenextregisterni0:
bt1,ni1;Registerisokalready...
vorv1,v31,v31;Copyintothenextregisterni1:
bt2,ni2;Registerisokalready...
vorv2,v31,v31;Copyintothenextregisterni2:
bt3,ni3;Registerisokalready...
vorv3,v31,v31;Copyintothenextregisterni3:
bt4,ni4;Registerisokalready...
vorv4,v31,v31;Copyintothenextregisterni4:
bt5,ni5;Registerisokalready...
vorv5,v31,v31;Copyintothenextregisterni5:
bt6,ni6;Registerisokalready...
vorv6,v31,v31;Copyintothenextregisterni6:
bt7,ni7;Registerisokalready...
vorv7,v31,v31;Copyintothenextregisterni7:
bt8,ni8;Registerisokalready...
vorv8,v31,v31;Copyintothenextregisterni8:
bt9,ni9;Registerisokalready...
vorv9,v31,v31;Copyintothenextregisterni9:
bt10,ni10;Registerisokalready...
vorv10,v31,v31;Copyintothenextregisterni10:
bt11,ni11;Registerisokalready...
vorv11,v31,v31;Copyintothenextregisterni11:
bt12,ni12;Registerisokalready...
vorv12,v31,v31;Copyintothenextregisterni12:
bt13,ni13;Registerisokalready...
vorv13,v31,v31;Copyintothenextregisterni13:
bt14,ni14;Registerisokalready...
vorv14,v31,v31;Copyintothenextregisterni14:
bt15,ni15;Registerisokalready...
vorv15,v31,v31;Copyintothenextregisterni15:
bt16,ni16;Registerisokalready...
vorv16,v31,v31;Copyintothenextregisterni16:
bt17,ni17;Registerisokalready...
vorv17,v31,v31;Copyintothenextregisterni17:
bt18,ni18;Registerisokalready...
vorv18,v31,v31;Copyintothenextregisterni18:
bt19,ni19;Registerisokalready...
vorv19,v31,v31;Copyintothenextregisterni19:
bt20,ni20;Registerisokalready...
vorv20,v31,v31;Copyintothenextregisterni20:
bt21,ni21;Registerisokalready...
vorv21,v31,v31;Copyintothenextregisterni21:
bt22,ni22;Registerisokalready...
vorv22,v31,v31;Copyintothenextregisterni22:
bt23,ni23;Registerisokalready...
vorv23,v31,v31;Copyintothenextregisterni23:
bt24,ni24;Registerisokalready...
vorv24,v31,v31;Copyintothenextregisterni24:
bt25,ni25;Registerisokalready...
vorv25,v31,v31;Copyintothenextregisterni25:
bt26,ni26;Registerisokalready...
vorv26,v31,v31;Copyintothenextregisterni26:
bt27,ni27;Registerisokalready...
vorv27,v31,v31;Copyintothenextregisterni27:
bt28,ni28;Registerisokalready...
vorv28,v31,v31;Copyintothenextregisterni28:
bt29,ni29;Registerisokalready...
vorv29,v31,v31;Copyintothenextregisterni29:
bt30,ni30;Registerisokalready...
vorv30,v31,v31;Copyintothenextregisterni30:
bf31,lnovr31;R31isempty,noneedtorestore...mstlvr31:lvxlv31,r30,r23;RestoreVR31lnovr31:
vrenablexx:sync;Makesureallissaved
stwr18,ACT_MACT_VMXcpu(r17);SettheactiveCPUandreleasevrenable:
lwzr9,SAVflags(r4)/*Gettheflagsofthecurrentsavearea*/
lwzr8,savesrr1(r4);Getthemsroftheinterruptedguy
rlwinmr5,r4,0,0,19/*Getthepageaddressofthesavearea*/orisr8,r8,hi16(MASK(MSR_VEC));Enablethevectorfacility
lwzr10,ACT_MACT_SPF(r17);Getthespecialflagslisr7,hi16(SAVattach)/*Gettheattachedflag*/
lwzr5,SACvrswap(r5)/*GetVirtualtoRealtranslation*/
orisr10,r10,hi16(vectorUsed|vectorCng);Setthatweusedvectors
mr.r15,r15;Seeifwearedoingthisforuserstatestwr8,savesrr1(r4);Setthemsroftheinterruptedguy
andcr9,r9,r7/*Cleartheattachedbit*/xorr3,r4,r5/*Gettherealaddressofthesavearea*/
stwr9,SAVflags(r4)/*Settheflagsofthecurrentsavearea*/
bne-vrnuser;Wearenotuserstate...
stwr10,ACT_MACT_SPF(r17);Settheactivationcopystwr10,spcFlags(r6);Setper_proccopyvrnuser:
#ifFPVECDBG
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x5F0A;(TEST/DEBUG)orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)
sc;(TEST/DEBUG)#ifGDDBG
mrr8,r3;Savethis
lisr3,hi16(EXT(GratefulDeb));Pointtotopofdisplayorir3,r3,lo16(EXT(GratefulDeb));Putinbottompart
mrr4,r2;Setvaluemtlrr3;Setlinkregister
lir3,1;Displayaddressblrl;Displayit
mrr3,r8;Restoreit#endif
#endif
bEXT(exception_exit)/*Exitfromthefray...*/
/*
*Initializetheregisterstosomebogusvalue
*Wemakesurethatnon-Javamodeisthedefaulthere
*/
ProtectTheAmericanWay:
#if0
lwzr10,savesrr1(r4);(TEST/DEBUG)
rlwinm.r10,r10,0,MSR_PR_BIT,MSR_PR_BIT;(TEST/DEBUG)beq-nxxxxxx2;(TEST/DEBUG)
lwzr10,ACT_MACT_SPF(r17);(TEST/DEBUG)rlwinm.r10,r10,0,2,2;(TEST/DEBUG)
beq+nxxxxxx2BREAKPOINT_TRAP;(TEST/DEBUG)
nxxxxxx2:#endif
#ifFPVECDBG
lisr0,HIGH_ADDR(CutTrace);(TEST/DEBUG)
lir2,0x5F09;(TEST/DEBUG)orisr0,r0,LOW_ADDR(CutTrace);(TEST/DEBUG)
sc;(TEST/DEBUG)#ifGDDBG
lisr3,hi16(EXT(GratefulDeb));Pointtotopofdisplay
mrr8,r4;Savethisorir3,r3,lo16(EXT(GratefulDeb));Putinbottompart
mrr4,r2;Setvaluemtlrr3;Setlinkregister
lir3,1;Displayaddressblrl;Displayit
mrr4,r8;Restoreit#endif
#endif
lisr5,hi16(EXT(QNaNbarbarian));Getaddressofemptyvalue
vspltishv1,1;Turnonthenon-Javabitandsaturateorir5,r5,lo16(EXT(QNaNbarbarian));Getlowaddressofemptyvalue
vspltiswv2,1;Turnonthesaturatebitlvxlv0,br0,r5;InitializeVR0
vxorv1,v1,v2;Turnoffsaturatevorv2,v0,v0;Copyintothenextregister
mtvscrv1;Clearthevectorstatusregistervorv3,v0,v0;Copyintothenextregister
vorv1,v0,v0;Copyintothenextregistervorv4,v0,v0;Copyintothenextregister
vorv5,v0,v0;Copyintothenextregistervorv6,v0,v0;Copyintothenextregister
vorv7,v0,v0;Copyintothenextregistervorv8,v0,v0;Copyintothenextregister
vorv9,v0,v0;Copyintothenextregistervorv10,v0,v0;Copyintothenextregister
vorv11,v0,v0;Copyintothenextregistervorv12,v0,v0;Copyintothenextregister
vorv13,v0,v0;Copyintothenextregistervorv14,v0,v0;Copyintothenextregister
vorv15,v0,v0;Copyintothenextregistervorv16,v0,v0;Copyintothenextregister
vorv17,v0,v0;Copyintothenextregistervorv18,v0,v0;Copyintothenextregister
vorv19,v0,v0;Copyintothenextregistervorv20,v0,v0;Copyintothenextregister
vorv21,v0,v0;Copyintothenextregistervorv22,v0,v0;Copyintothenextregister
vorv23,v0,v0;Copyintothenextregistervorv24,v0,v0;Copyintothenextregister
vorv25,v0,v0;Copyintothenextregistervorv26,v0,v0;Copyintothenextregister
vorv27,v0,v0;Copyintothenextregistervorv28,v0,v0;Copyintothenextregister
vorv29,v0,v0;Copyintothenextregistervorv30,v0,v0;Copyintothenextregister
vorv31,v0,v0;Copyintothenextregisterbvrenablexx;Finishsettingitallup...;
;Findsaunusedvectorareaintheactivationpointed;tobyR12ssavedcontexts.Ifnonearefound(unlikelybutpossible)
;andR3is0,anewareaisallocated.IfR3isnon-zero,itcontains;apointertoavectorsaveareathatisfree.
vsrchsave:lwzr6,ACT_MACT_PCB(r12);Getthefirst"normal"saveareavsrnorm:mr.r5,r6;Isthereanother?
beq-vsrvect;No,searchthefloatingpointsaveareas...lwzr7,SAVflags(r5);Gettheflagsforthisguy
lwzr6,SAVprev(r5);Gettheprevioussavearea,justincaseandis.r8,r7,hi16(SAVvmxvalid);Havewefoundanemptyvectorsaveinnormal?
beq+vsrgot;Wefoundone...bvsrnorm;Searchagain...vsrvect:lwzr6,ACT_MACT_FPU(r12);Getthefirst"floatingpoint"saveareavsrvectx:mr.r5,r6;Isthereanother?
beq-vsrget;No,trytoallocateone...lwzr7,SAVflags(r5);Gettheflagsforthisguy
lwzr6,SAVprefp(r5);Gettheprevioussavearea,justincaseandis.r8,r7,hi16(SAVvmxvalid);Havewefoundanemptyvectorsaveinfloat?
bne-vsrvectx;Searchagain...vsrgot:mrr3,r5;Getthesaveareaintotherightregister
blr;Return...
vsrget:mr.r5,r3;Doweallocateoruseexisting?
beq+vsrallo;Allocateone...lwzr7,SAVflags(r3);Getthepassedinareaflags
blr;Return...;
;NOTE:save_getwillreturndirectlyandsetR7to0...;
vsrallo:bEXT(save_get);Getafreshsavearea