TITLE MONPFH DEFAULT PAGE FAULT HANDLER V050
SUBTTL Tarl Neustaedter/TARL 5 MAR 86
SEARCH F,S
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
.CPYRT<1984,1986>
;COPYRIGHT (c) 1984,1986 BY
;DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
;ALL RIGHTS RESERVED.
;
XP VPFH,050
ENTRY PFH
Comment @
Loose ends outside of this module
GETWRY, make it understand FLTSX returning success
PUTWRY, make it understand FLTSX returning success, and test for write
locked loseg pages (spy pages).
@
PTRTYP: POINT 3,T1,2 ;BPT TO EXTRACT TYPE OF PAGE MAP POINTER
PTRIPT: POINT 9,T1,17 ;INDIRECT INDEX INTO PAGE
;Stack offsets used in range-checking cannot-be-paged-out ('CBPO') pages.
PFPHLB==-1 ;[SHARABLE] HISEG BEGIN PAGE
PFPHLE==-0 ;[SHARABLE] HISEG END PAGE
PFPJLB==-3 ;.JBINT BLOCK BEGIN PAGE
PFPJLE==-2 ;.JBINT BLOCK END PAGE
PFPILE==-5 ;I/O RANGE BEGIN PAGE
PFPILB==-4 ;I/O RANGE END PAGE
PFPBPT==-6 ;DDT'S UNSOLICITED BREAKPOINT TRAP ADDRESS
PFPOFS==-7 ;OFFSET ON STACK
IFN FTPI,<
PFPPLB==PFPOFS-1 ;PSI VECTOR BEGIN PAGE
PFPPLE==PFPOFS-0 ;PSI VECTOR END PAGE
PFPOFS==PFPOFS-2 ;OFFSET ON STACK
>
;Called from USRFL1. Page fault, no PFH loaded. ;Relevant ACs, T3/ KL form page fail word or zero if time fault ; ;Return ; CPOPJ, No implicit access to page, ill mem ref ; CPOPJ1, Page is now accessible. PFH:: IFN FTNET,<NTDBUG NO,EITHER> ;MAKE SURE WE DON'T HAVE THE NETSER INTERLOCK SE1ENT ;XADDR JUMPE T3,PFHTIM ;TIME FAULT, DON'T WORRY ABOUT FAULT WORDS TDNN T3,[MXSECN,,777000] ;MAKE SURE OUT OF PAGE ZERO STOPCD .,JOB,PFHZER, ;++ PAGE FAULT ON PAGE ZERO DMOVE T1,.USPFP ;PC OF LAST PAGE FAULT (IF FROM USRFLT) DMOVEM T1,.USPFF ;SAVE AS PFH PAGE FAULT PC PUSHJ P,SAVE1## ;SOMEWHERE TO PRESERVE PAGE FAULT WORD MOVE P1,T3 ;ADDRESS DESIRED AOS T1,.USPFU ;UP COUNT OF PAGE FAULTS CAIL T1,^D1000 ;ALLOW UP TO ONE THOUSAND PAGE FAULTS WITHOUT JRST PFHABO ; FINISHING UUO. MOVE T1,.USLFT ;LAST FAULT TIME JUMPE T1,PFH1 ;JUMP IF NOT FIRST FAULT FOR THIS PROGRAM PUSHJ P,FNDPDS## ;ADDRESS OF THE PDB MOVEI T1,^D60 ;60 TICS BEFORE A TIME FAULT HRRZM T1,.PDTMC##(W) ;STORE IN THE TIME COUNTER HRRM T1,.PDTMI##(W) ;AND INCREMENT PFH1: PUSHJ P,PFHPAG ;PAGE THE PAGE IN POPJ P, ;NO CAN DO, GIVE AN ILL MEM REF PFHEXI: TLNN P1,(PF.BAD) ;WAS THIS A MONITOR UUO? JRST PFHEX2 ;NO, RE-EXECUTE THE INSTRUCTION DMOVE T1,.JDAT+JOBPD1## ;[GETPC] GET RETURN PC OF UUO SUBI T2,1 ;DECREMENT TO PC OF UUO DMOVEM T1,.USPFF ;[PUTPC] STASH AS PC TO RETURN TO CAIA ;SKIP INTO FINAL RETURN TO USER PFHEX2: SETZM .USPFU ;CLEAR RECURSION TRAPPER SINCE USER PAGE FAULT USERAC ;SET THE AC SET TO USER XJEN .USPFF ;RETURN TO USER PC
;Here on lots of page faults - assume the worst PFHABO: SETZM .USPFU ;ZERO FAULT COUNTER (GIVE HIM A CHANCE) TLO P1,400000 ;PRETEND WE PAGED SOMETHING OUT PUSHJ P,TTYFUW## ;SET UP FOR TYPEOUT ON USER'S TERMINAL PUSHJ P,INLMES## ;TYPE OUT A MESSAGE ASCIZ \? ?Page fault loop. Try larger core limit and type CONTINUE \ PUSHJ P,HOLD0## ;STOP JOB IN CONTINUABLE STATE PUSHJ P,WSCHED## JRST PFHEXI ;AND EXIT, TO RE-EXECUTE PAGE FAULT INSTRUCTION
;Here on a timer fault ;Return non-skip so TIMFLT will return to user PFHTIM: MOVEI T1,(J) ;GET JOB # IN T1 PUSHJ P,FPDBT1## ;GET ADDRESS OF PDB POPJ P, ;THIS IS ALL UNINTERESTING IF NONE HLRZ T1,.PDMVL##(T1) ;GET JOB'S MAXIMUM VIRTUAL LIMIT JUMPE T1,CPOPJ## ;IF NONE, CAN'T PAGE ANYWAY SO DON'T DO THIS PUSHJ P,SAVE4## ;SAVE SOME P REGISTERS PUSHJ P,PGRUPD## ;UPDATE PAGE RATES MOVEI P1,1 ;START AT PAGE 1 MOVEI P4,HLGPNO ;COUNTER SETOB P2,P3 ;NO LAST PAGE, NO STARTING PAGE PFHTM1: MOVE T1,@[IW UMAPSN,UMAPS(P1)] TLC T1,(PM.COR) ;INVERT PAGE-IN-CORE BIT TLNN T1,(PM.COR!1B1!PM.AAB) ;IS IT IN CORE AND AA OFF? PUSHJ P,OUTPAG ;PAGE OUT THIS PAGE AOS P1 ;INCREMENT PAGE # SOJG P4,PFHTM1 ;AND LOOP IF MORE IN SECTION LSH P1,P2SLSH## ;SECTION # PFHTM2: CAILE P1,MXSECN ;EXCEED MAX SECTION? JRST PFHTM3 ;YES, WE ARE DONE HERE SKIPE T1,.UPMP+SECTAB(P1) ;GET POINTER IF THERE IS ONE TLNE T1,(<<PM.DCD^!PM.ACD>B2>) ;INDEPENDENT SECTION? AOJA P1,PFHTM2 ;NON-EX OR INDIRECT LSH P1,S2PLSH## ;PAGE # MOVEI P4,HLGPNO+1 ;SET COUNTER AGAIN JRST PFHTM1 PFHTM3: SETZ P1, ;FLAG END PUSHJ P,OUTPAG ;AND FLUSH ANY PENDING PAGES ;SET UP RANGE CHECKS FOR LEGAL-TO-PAGE-OUT PAGE IFN FTPI,< PUSHJ P,GETPLM ;FIND RANGE OF PAGES FOR PSI VECTOR PUSH P,T1 ;BOTTOM PAGE OF PSI VECTOR PUSH P,T2 ;TOP PAGE OF PSI VECTOR > PUSHJ P,GETHLM ;GET RANGE OF HIGH SEGMENT PAGES PUSH P,T1 ;SAVE BOTTOM OF THE HIGH SEGMENT PUSH P,T2 ;AND THE TOP PUSHJ P,GETBLM ;GET BREAKPOINT TRAP PAGE PUSH P,T1 ;SAVE IT PUSHJ P,GETJLM ;GET RANGE OF PAGES FOR JOBINT BLOCK PUSH P,T1 ;START OF JBINT BLOCK PUSH P,T2 ;END OF JBINT BLOCK ;TURN OFF AA FOR ALL PAGES IN CORE MOVEI P1,1 ;START AT PAGE 1 SETZB P2,P3 ;NO LAST PAGE, NO STARTING PAGE MOVEI P4,HLGPNO ;IGNORING PAGE 0 PUSH P,[-1] ;FLAG OF WHETHER IOWAIT CALLED PFHTM4: MOVE T1,@[IW UMAPSN,UMAPS(P1)] TLC T1,(PM.COR!PM.WRT!PM.AAB) ;ALL THESE BITS MUST BE ON TLCE T1,(PM.COR!PM.WRT!PM.AAB!1B1) ;WERE THEY? JRST PFHTM5 ;NOPE, TRY NEXT PAGE CAME P1,-2(P) ;IS THIS FIRST PAGE OF .JBINT BLOCK? CAMN P1,-1(P) ;OR LAST PAGE OF .JBINT? JRST PFHTM5 ;YES, LEAVE IT ALONE CAMN P1,-3(P) ;IS THIS THE BREAKPOINT TRAP ADDRESS? JRST PFHTM5 ;YES, LEAVE IT ALONE CAML P1,-5(P) ;BELOW THE HIGH SEGMENT? CAMLE P1,-4(P) ;NO, IN THE HIGH SEGMENT RANGE? JRST PFHT4A ;NO, PAGE IS OK ADD P4,P1 ;SKIP HIGH SEG - SUBTRACT # PGS SKIPPED MOVE P1,-4(P) ;SKIP THE HIGH SEGMENT SUB P4,P1 JRST PFHTM5 ;NEXT PAGE PFHT4A: IFN FTPI,< CAML P1,-7(P) ;IS THIS PAGE BELOW RANGE OF PSI VECTOR CAMLE P1,-6(P) ;OR ABOVE IT? TRNA ;NOT IN RANGE OF PSI VECTOR JRST PFHTM5 ;IN PSI VECTOR, LEAVE IT ALONE > AOSG (P) ;CALLED IOWAIT ALREADY? S0PSHJ IOWAIT## ;NO, WAIT FOR ALL I/O TO STOP BEFORE DINKING BITS MOVSI T1,(<PM.DCD>B2!PM.AAB) ;CLEAR ACCESS ALLOWED ANDCAM T1,@[IW UMAPSN,UMAPS(P1)] ;CLEAR THE BITS AOS .USANA ;INCREMENT INACCESSIBLE PAGES PFHTM5: AOS P1 ;PRE-INCREMENT PAGE # SOJG P4,PFHTM4 ;MORE THIS SECTION, CONTINUE LSH P1,P2SLSH## ;CONVERT TO SECTION # PFHTM6: CAILE P1,MXSECN ;OVER THE TOP? JRST PFHTM7 ;YES SKIPE T1,.UPMP+SECTAB(P1) ;THIS SECTION EXIST? TLNE T1,(<<PM.DCD^!PM.ACD>B2>) ;YES, IS IT INDEPENDENT? AOJA P1,PFHTM6 ;NON-EXISTENT OR INDIRECT LSH P1,S2PLSH## ;BACK TO PAGE # MOVEI P4,HLGPNO+1 ;RESET COUNTER JRST PFHTM4 ;AND CONTINUE PFHTM7: ADJSP P,-6-IFN FTPI,<2> ;THROW AWAY RANGE CHECK WORDS ON STACK PUSHJ P,ADJANA## ;ADJUST .USANA CLRPGT (0) ;CLEAR PAGING MEMORY POPJ P, ;AND RETURN
;OUTPAG - Utility routine for PFHTIM. ;Call ; P1/ Page to page out ;or P1/ -1 indicating we should flush cache ; P2/ Last page OUTPAG was called for ; P3/ First page in current group ; P4/ Flag that a PAGE. UUO was done - avoid extra calls to IOWAIT ;return ; Non skip always OUTPAG: AOJLE P2,OUTPA1 ;PREINCREMENT LAST PAGE CALLED CAIN P2,(P1) POPJ P, ;YES, RETURN MOVE T1,[XWD 0,JOBUAL##] ;PAGE. ARG BLOCK MOVE T2,P3 ;FIRST PAGE THAT WILL BE DONE SUB T2,P2 ;MAKE IT NEGATIVE COUNT OF PAGES TO DO MOVE T3,P3 ;STARTING PAGE TO PAGE OUT TLO T3,(PG.GAF) ;FLAG PAGES ARE TO GO OUT PUSHJ P,DOPAGE ;PAGE THEM OUT OUTPA1: JUMPE P1,CPOPJ## ;(FLUSH CALL) HRRE P3,P1 ;SET UP FIRST PAGE IN GROUP HRRE P2,P1 ;SET UP LAST PAGE IN GROUP POPJ P, ;RETURN
;PFHPAG - Page in a page which has caused a page fault ;Call ; P1/ Page fail word (direct from .USPFW) ;Return ; RET Can't do, no room, no such page ; RETSKP page is accessible ; PFHPAG: LDB T3,[POINT UPGWID,P1,26] ;GET VIRTUAL PAGE NUMBER MOVE T1,T3 ;COPY TO T1 LSH T1,P2SLSH## ;GET SECTION # SKIPN .UPMP+SECTAB(T1) ;DOES SECTION EXIST? POPJ P, ;NO, DON'T GENERATE A SECOND PAGE FAULT ADD T3,[UMAPSN+UMAPS];POINT TO PAGE MAP ENTRY FOR PAGE SKIPN T1,(T3) ;GET PAGE MAP ENTRY POPJ P, ;ILL MEM REF IF PAGE IS NON-EXISTANT TDNN T1,[PM.ADR-PM.ZER];ALLOCATED BUT ZERO PAGE? JUMPN T1,PFHABZ ;YES, CREATE IT. LDB T2,PTRTYP ;GET TYPE OF POINTER JUMPN T2,CPOPJ## ;[PM.NCD] IF POINTER EXISTS, NOTHING TO DO TLNN T1,(PM.COR) ;PAGE IN CORE? JRST PFHOUT ;NOPE, IT'S PAGED OUT. TLNN T1,(PM.AAB) ;ACCESS ALLOWED ON? JUMPN T1,PFHAAF ;YES, IS ACCESS ALLOWED FAULT POPJ P, ;NOT SOLVABLE FAULT
;Here when page is allocated but zero. ;Call ; P1/ Virtual address desired (With some flags) ;Return ; CPOPJ, no room for page. ; CPOPJ1, page has been allocated. ; PFHABZ: PUSHJ P,CHKLIM ;GET US ENOUGH ROOM TO CREATE THE PAGE JRST PFHABO ;LOOP IN PFH DMOVE T1,[1,,JOBUAL## ;.PAGCD,,AC 1 1] ;ONE PAGE LDB T3,[POINT UPGWID,P1,26] ;GET PAGE NUMBER PUSHJ P,DOPAGE ;CREATE THE PAGE SETZM .USPFU ;RESTART PAGE FAULT COUNT--WE'RE NOT LOOPING YET JRST PFHXCN ;COUNT FAULT AND EXIT
;Here when page has access allowed turned off ;Call ; P1/ Virtual address desired (with some flags) ; T3/ Pointer to map slot ;Return ; CPOPJ, never. ; CPOPJ1, aa turned on PFHAAF: SOS .USANA ;DECR NO OF NOT-ACCESSABLE PAGES MOVSI T2,(<PM.DCD>B2+PM.AAB) ;ACCESS ALLOWED IORM T2,(T3) ;TURN ON IN PAGE MAP ENTRY CLRPGT (0) ;REFRESH THE PAGER'S ASSOC MEMORY PUSHJ P,ADJANA## ;ADJUST .USVRT JRST PFHXCI ;COUNT FAULT AND RETURN TO USER
;Here when page is paged out ;Call ; P1/ Virtual address desired (with some flags) ;Return ; CPOPJ, no room for page ; CPOPJ1, page has been paged in PFHOUT: PUSHJ P,CHKLIM ;MAKE ROOM FOR PAGE WE WILL HAVE TO PAGE IN JRST PFHABO ;LOOP IN PFH DMOVE T1,[0,,JOBUAL## ;.PAGIO,,AC 1 1] ;ONE PAGE, IN. LDB T3,[POINT UPGWID,P1,26] ;GET PAGE NUMBER PUSHJ P,DOPAGE ;PAGE HIM IN JRST PFHXCN ;COUNT FAULT AND CONTINUE
;Here to put us one page below limit
;Call
;Return
; RET ;Can't make room for another page
; RETSKP ;There is now room for at least one page
CHKLIM: PUSHJ P,SAVE1## ;PRESERVE ACS USED
;Set up for range checks for cannot-be-paged-out ('CBPO') pages
ADJSP P,-PFPOFS ;MAKE ROOM FOR LIMIT BI-WORDS
PUSHJ P,GETHLM ;GET HIGH SEGMENT LIMITS
DMOVEM T1,PFPHLB(P) ;SET UP FOR CBPO RANGE CHECK
PUSHJ P,GETJLM ;GET RANGE OF PAGES FOR JOBINT BLOCK
DMOVEM T1,PFPJLB(P) ;SET UP FOR CBPO RANGE CHECK
PUSHJ P,GETBLM ;GET BREAKPOINT TRAP PAGE
MOVEM T1,PFPBPT(P) ;SAVE FOR CBPO RANGE CHECK
IFN FTPI,<
PUSHJ P,GETPLM ;FIND RANGE OF PAGES FOR PSI VECTOR
DMOVEM T1,PFPPLB(P) ;SET UP FOR CBPO RANGE CHECK
>
LDB P1,IMGIN## ;LOSEG SIZE = COUNT OF CANDIDATE PAGES
;Continued on next page
;Continued from previous page CHKLI1: MOVEI T3,1 ;WE WILL BE INCREASING BY ONE PAGE PUSHJ P,GSIZI## ;WILL WE STILL FIT IN CORE? JFCL ;WILL NEVER FIT TRNA ;LESSER THAN LIMITS JRST CHKLI8 ;WILL FIT, RETURN NOW ;Here when we will have to page things out. CHKLI2: SOJLE P1,CHKLI9 ;GIVE UP AFTER CHECKING ALL CANDIDATE PAGES CHKLI3: SOSG T3,.USPFL ;GET PAGE WE LAST PAGED OUT JRST [MOVEI T3,HLGPGS+1 ;RE-START AT TOP PAGE JRST CHKLI5] ;AND CONTINUE FROM THE TOP LDB T2,[POINT 5,T3,26] ;GET SECTION NUMBER LDB T2,[POINT 3,.UPMP+SECTAB(T2),2] ;GET POINTER TYPE CAIN T2,PM.DCD ;DIRECT POINTER JRST CHKLI6 ;YES, TRY IT TRZ T3,HLGPNO ;ROUND DOWN TO BOTTOM OF BAD SECTION CHKLI5: MOVEM T3,.USPFL ;AND SAVE IT JRST CHKLI3 ;AND LOOP CHKLI6: MOVE T2,@[IW UMAPSN,UMAPS(T3)] ;GET PAGE MAP ENTRY TLC T2,(PM.COR) ;IN-CORE BIT TLNE T2,(PM.COR!1B1) ;IS IT IN CORE? JRST CHKLI3 ;NO, TRY AGAIN CAML T3,PFPHLB(P) ;BELOW FIRST PAGE OF SHARABLE HIGH SEGMENT? CAMLE T3,PFPHLE(P) ;OR ABOVE HIGHEST PAGE? JRST CHKLI7 ;NOT A PAGE IN A SHARABLE HIGH SEGMENT MOVE T3,PFPHLB(P) ;IN HISEG, GET BEGINING OF HISEG JRST CHKLI5 ;AND SET AS LAST CANDIDATE PAGE CHKLI7: CAME T3,PFPJLB(P) ;IS THIS FIRST PAGE OF .JBINT BLOCK? CAMN T3,PFPJLE(P) ;OR LAST PAGE OF .JBINT? JRST CHKLI2 ;YES, LEAVE IT ALONE CAMN T3,PFPBPT(P) ;BREAKPOINT TRAP ADDRESS? JRST CHKLI2 ;YES, LEAVE IT FOR DDT IFN FTPI,< CAML T3,PFPPLB(P) ;IS THIS PAGE BELOW RANGE OF PSI VECTOR CAMLE T3,PFPPLE(P) ;OR ABOVE IT? TRNA ;NOT IN RANGE OF PSI VECTOR JRST CHKLI2 ;IN PSI VECTOR, LEAVE IT ALONE > TLO T3,(PG.GAF) ;FLAG THAT THIS PAGE GETS PAGED OUT DMOVE T1,[0,,JOBUAL## ;.PAGIO,, AC 1 1] ;ONE PAGE PUSHJ P,DOPAGE ;AND PAGE IT OUT PUSHJ P,SCDCHK## ;LET OTHER USERS RUN JUST IN CASE JRST CHKLI1 ;MAKE SURE WE ARE BELOW LIMIT NOW CHKLI8: AOS PFPOFS(P) ;SET UP FOR SKIP RETURN CHKLI9: ADJSP P,PFPOFS ;THROW AWAY CHECK WORDS ON STACK POPJ P, ;RETURN
;Subroutine to get starting and ending page number of pages which can't be ; paged out (SPY segment and sharable high segment). Returns results in T1, T2. GETHLM: SKIPL T3,JBTSGN##(J) ;A SPY SEGMENT? JRST GETHL1 ;NO HRRZ T2,T3 ;YES, LENGTH OF SPY SEGMENT HLRZ T1,JBTADR##(J) ;LENGTH OF LOW SEGMENT TRNN T1,400000 ;LOW SEGMENT GREATER THAN 128K? MOVEI T1,377777 ;NO, THE SPY SEGMENT STARTS AT 400000 AOS T1 ;NEXT PAGE BOUNDARY ADD T2,T1 ;HIGHEST ADDRESS IN SPY SEGMENT JRST GETHL2 ;CONVERT TO REAL SECTION NUMBERS (NOT @) AND RETURN GETHL1: TLNN T3,SHRSEG ;AND IS IT SHARABLE? TDZA T1,T1 ;NO, OK TO PAGE OUT PAGES PUSHJ P,GETHSA## ;GET 30-BIT STARTING ADDRESS OF THE HIGH SEGMENT SKIPN T2,T1 ;SKIP IF NOT A SHARABLE HIGH SEGMENT PJRST GETHL2 ;CONVERT AND CONTINUE HRRZS T3 ;CLEAR POSSIBLE CRUFT HLRZ T3,JBTADR##(T3) ;SIZE OF THE HIGH SEGMENT ADD T2,T3 ;HIGHEST ADDRESS IN THE HIGH SEGMENT GETHL2: LSHC T1,W2PLSH## ;CONVERT TO PAGE NUMBERS PJRST GETRSN ;CONVERT TO REAL SECTION NUMBERS (NOT @) AND RETURN ;Subroutine to get starting and ending page number of pages which can't be ; paged out (JOBINT block). Returns results in T1, T2 GETJLM: HRRZ T1,.JDAT+JOBINT##;GET ADDRESS OF JOBINT BLOCK HRRZI T2,3(T1) ;END ADDRESS OF JOBINT BLOCK TRZ T1,PAGSIZ##-1 ;MAKE START ADDRESS A PAGE BOUNDARY LSHC T1,W2PLSH## ;CONVERT BOTH TO PAGE NUMBERS POPJ P, ;AND RETURN
;Subroutine to get page number of DDT breakpoint trap word (for JSR) GETBLM: MOVE T1,.JDAT+.JBBPT## ;FETCH JSR TARGET ADDRESS LSH T1,W2PLSH## ;CONVERT TO PAGE NUMBER MOVE T2,T1 ;DON'T CONFUSE GETRSN PJRST GETRSN ;RETURN INDPENDENT PAGE NUMBER ;Subroutine to get starting and ending page number of pages which can't be ; paged out (PSI vector). Returns results in T1, T2 GETPLM: PUSHJ P,PSIIVR## ;FIND RANGE OF PAGES FOR PSI VECTOR HLRZ T2,T1 ;GET ENDING PAGE HRRZS T1 ;MAKE THIS STARTING PAGE ONLY ; PJRST GETRSN ;CONVERT TO REAL SECTION NUMBERS AND RETURN ;Subroutine to convert page numbers in T1 andd T2 to page numbers with all ; section indirection resolved (real section numbers) GETRSN: PUSH P,T2 ;THE INTERFACE TO RSECT4 IS WIERD PUSH P,T4 ;IT WANTS THE ARGUMENT IN T4 LDB T4,[POINT 5,T1,26] ;SECTION SPECIFIED PUSHJ P,RSECT4## ;FOLLOW ANY INDIRECT SECTION POINTERS TO A DIRECT POINTER JFCL ;I TOLD YOU THE INTERFACE WAS WIERD DPB T4,[POINT 5,T1,26] ;STORE REAL SECTION NUMBER ;DOING THIS ASSUMES THAT A BLOCK COULD CROSS A SECTION BOUNDARY WHICH IT CAN'T, ; BUT MIGHT AS WELL BE GENERAL LDB T4,[POINT 5,-1(P),26] ;FOR T2 ARGUMENT AS WELL PUSHJ P,RSECT4## ;FOLLOW ANY INDIRECT SECTION POINTERS TO A DIRECT POINTER JFCL ;I TOLD YOU THE INTERFACE WAS WIERD DPB T4,[POINT 5,-1(P),26] ;STORE ANSWER POP P,T4 ;RESTORE T4 JRST T2POPJ## ;RESTORE T2 AND RETURN
;Do a page uuo. ;Call ; T1/ Function,, JOBUAL## ; T2/ Number of pages to do (1 or negative number) ; T3/ Page to do, possibly with PG.GAF lit. ;Return ; RET, done ;If the page uuo fails, this routine stopcodes and does not return DOPAGE: MOVE T4,T1 ;SAVE FUNCTION MOVEI T1,0 ;SET PCS TO ZERO PUSHJ P,SVPCS## ;SINCE ARGUMENT LIST WILL BE AT JOBUAL IN SECTION 0 MOVE T1,T4 ;RESTORE T1 PUSHJ P,SAVUM## ;TRASHED BY VMSER MOVEI T4,JS.ASA ;SHADOW ACS BIT TDNE T4,JBTSTS##(J) ;IS IT SET? JRST DOPAG1 ;YES, USE SHADOW AREA UMOVE T4,0 ;GET USER AC ZERO UMOVEM T1,0 ;SET UP USER AC JRST DOPAG2 ;STORE ARGS DOPAG1: MOVE T4,.JDAT ;SAVE SHADOW AC 0 MOVEM T1,.JDAT ;STORE FUNCTION,,ADDRESS DOPAG2: DMOVEM T2,.JDAT+JOBUAL## ;STASH ARGS IN WORK AREA PUSH P,T4 ;SAVE USER'S AC ZERO PUSH P,F ;SAVE OUR DDB POINTER PUSH P,S ;AND DEVIOS SETZ M, ;LOOK IN AC 0 FOR ARGS S0PSHJ UPAGE.## ;AND DO THE PAGE. STOPCD .,JOB,PFHUUO, ;++ PAGE UUO FAILED ; UMOVE T1,0 ;GET ERROR CODE POP P,S ;RESTORE DEVIOS POP P,F ;RESTORE DDB POINTER POP P,T4 ;GET BACK USER'S AC ZERO MOVEI T1,JS.ASA ;ACS IN THE SHADOW AREA BIT TDNE T1,JBTSTS##(J) ;ARE THEY? JRST DOPAG3 ;YES, RESTORE THERE UMOVEM T4,0 ;STASH AWAY AGAIN POPJ P, ;RETURN DOPAG3: MOVEM T4,.JDAT ;STASH AWAY AGAIN POPJ P, ;AND RETURN
;Here to count an in working set page fault PFHXCI: SKIPA T1,[1] ;COUNTS IN THE RIGHT HALF ;Here to count a not in working set page fault PFHXCN: MOVSI T1,1 ;COUNTS IN THE LEFT HALF ADDM T1,.USVCT ;UPDATE USER TOTAL ADDM T1,SYSVCT## ;AND SYSTEM TOTAL RETSKP ;PFHGWD - GETWRD routine specifically for PFH. Make sure that we fault ; gently, and pull the page in without trying to re-start the uuo. PFHGWD::TRNN M,777760 ;AN AC REFERENCE? JRST GETWRA## ;YES, GET THE WORD FROM THE AC OR SHADOW AREA SE1ENT ;NO, USE SECTION 1 FOR ADDRESSING JRST PFHGW1 ;GO FETCH PFHGWF: POP P,M ;RESTORE M (PUSHED BELOW) SE1ENT ;MUST BE IN SECTION 1 PUSH P,P1 ;SAVE AN AC MOVE P1,.USPFW ;GET PAGE FAIL CODE TLNN P1,(PF.BAD) ;DON'T BOTHER IF SOMETHING REALLY BAD PUSHJ P,PFHPAG ;PAGE IT IN JRST P1POPJ## ;ERROR IN ADDRESS POP P,P1 ;GET BACK SAVED AC PFHGW1: PUSH P,M ;SAVE M TLZ M,^-<(SECMSK)> ;CLEAR POSSIBLE CRUFT UMOVE T1,(M) ;GET THE WORD FROM USER MEMORY ERJMP PFHGWF ;FAILED, TRY TO PAGE IT IN POP P,M ;RESTORE M RETSKP ;AND RETURN SUCCESS ;PFHMWD - like PFHGWD but gets the word from section specified by M PFHMWD::TDNN M,[<(SECMSK)>^!1,,^-17] ;AC REFERENCE? PJRST GETWRA## ;YES, DO IT THE EASY WAY SE1ENT ;NO, WE WANT NZS ADDRESSING LDB T1,[POINT 5,M,17] ;WHAT PCS SHOULD BE TO FETCH THE WORD PUSHJ P,SVPCS## ;SAVE PCS AND SET PCS TO VALUE FROM M JRST PFHGW1 ;GET THE WORD
;PFHDMP - Dump mode IO. This routine replaces DMPIO. ;Call ; T1/ IO routine ; F,U,M/ UUO normal ;Return ; RET, I/O has been done. ; ;If an error occurrs at any point, it returns then and there, ;to let the higher levels catch it. PFDBAS==0 ;BASE ADDRESS OF IOWDS PFDISP==1 ;DISPATCH ADDRESS PFDCNT==2 ;COUNT OF IOWDS PROCESSED PFDEVM==3 ;AMOUNT OF EVM USED LAST TIME, IF ANY PFDRSN==4 ;REASON NOT IN CORE PFDSNI==5 ;STARTING PAGE NOT IN CORE PFDPNI==6 ;PREVIOUS PAGE NOT IN CORE PFDSIZ==7 ;SIZE OF BLOCK TO ALLOCATE (used by pfhmsi) PFHDMP::SE1ENT ;WE TOUCH PAGE MAPS, RUN IN SECTION 1 PUSHJ P,SAVE4## ;SAVE PERM ACS THAT WE USE TLO F,(1B0) ;TURN ON THE SIGN BIT FOR INDEXING (UINITB) MOVE P1,T1 ;SAVE DEVICE DISPATCH ADDRESS HRRZ T1,DEVISN(F) ;IO SECTION NUMBER PUSHJ P,SVPCS## ;SAVE PCS AND SET UP XMOVEI P4,1(P) ;POINT AT AVAILABLE STACK AREA ADJSP P,PFDSIZ ;RESERVE ROOM FOR DATA ON STACK MOVEM P1,PFDISP(P4) ;SAVE DISPATCH ADDRESS SETZM PFDEVM(P4) ;NO EVM YET MOVEI T1,^D1000 ;MAXIMUM NUMBER OF IOWDS TO ALLOW MOVEM T1,PFDCNT(P4) ;STORE THAT PFHDM1: PUSHJ P,PFHGWD ;GET IOWD JRST UADERR## ;SHOULDN'T HAPPEN JUMPE T1,PFHDM4 ;DONE, CLEAN UP TLNN T1,-1 ;A GOTO WORD? JRST [HRRI M,(T1) ;YES, POINT TO NEXT IOWD JRST PFHDM3] ;AND CONTINUE HLRO P2,T1 ;SIZE OF IOWD MOVEI T1,1(T1) ;POINT TO FIRST WORD TOUCHED BY IO HRL T1,DEVISN(F) ;GET SECTION NUMBER MOVEM T1,PFDBAS(P4) ;STASH WHERE PFHIOD CAN FIND IT MOVE P1,PFDBAS(P4) ;POINT AT FIRST WORD AFFECTED BY IO SETCA P2, ;COUNT OF WORDS AFFECTED ADD P2,PFDBAS(P4) ;POINT AT LAST WORD AFFECTED BY IO SETZ P3, ;NOTHING ACCUMULATED YET PUSHJ P,PFHIOD ;DO THE IO FOR THIS IOWD JRST PFHDM4 ;DIDN'T MAKE IT, LET TOP LEVEL FIND ERROR HRRI M,1(M) ;POINT TO NEXT IOWD PFHDM3: SOSL PFDCNT(P4) ;DECREMENT COUNT OF IOWDS JRST PFHDM1 ;GET NEXT IOWD IN LIST JRST ADRERR## ;MORE THAN A THOUSAND IOWDS, PROBABLY LOOP PFHDM4: ADJSP P,-PFDSIZ ;GIVE BACK STORAGE ON STACK S0PSHJ WAIT1## ;WAIT FOR DEVICE TO QUIESCE S0JRST RTNEVM## ;RETURN ANY EVM LEFT OVER
;PFHMSI - Multi section I/O ;This routine breaks down a multi-section io list into chunks small ;enough for filser to handle them, at the same time making sure the ;right amounts of everything is paged in. ;Call ; T1/ IO routine ; F,U,M/ UUO normal ;Return ; RET, IO has been done ;If an IO error occurrs, we stop io then and there, and return to top level PFHMSI::SE1ENT ;WE TOUCH MAPS, RUN IN SECTION 1 PUSHJ P,SAVE4## ;SAVE PERM ACS THAT WE USE TLO F,(1B0) ;TURN ON THE SIGN BIT FOR INDEXING (UINITB) MOVE P1,T1 ;SAVE DEVICE DISPATCH ADDRESS HRRZ T1,DEVISN(F) ;IO SECTION NUMBER PUSHJ P,SVPCS## ;SAVE AND SET UP PCS XMOVEI P4,1(P) ;POINT AT AVAILABLE STACK AREA ADJSP P,PFDSIZ+1 ;RESERVE ROOM FOR DATA ON STACK MOVEM P1,PFDISP(P4) ;SAVE DISPATCH ADDRESS MOVEI T1,^D1000 ;MAXIMUM NUMBER OF IOWDS TO ALLOW MOVEM T1,PFDCNT(P4) ;STORE THAT SETZM PFDEVM(P4) ;NO EVM YET PFHMS1: PUSHJ P,PFHMWD ;GET FIRST HALF OF EXTENDED IOWD JRST UADERR## ;SHOULDN'T HAPPEN MOVE P2,T1 ;SAVE AS SIZE OF IOWD AOS M ;POINT M AT SECOND HALF PUSHJ P,PFHMWD ;GET SECOND HALF OF EXTENDED IOWD JRST UADERR## ;SHOULDN'T HAPPEN JUMPE P2,PFHMS2 ;A GOTO WORD? MOVEM T1,PFDBAS(P4) ;STASH WHERE PFHIOD CAN FIND IT PFHM1A: MOVE P1,PFDBAS(P4) ;FIRST WORD AFFECTED BY IO MOVEM P2,PFDSIZ(P4) ;STASH TOTAL IOWD SIZE CAILE P2,400000 ;MAXIMUM IOWD SIZE MOVEI P2,400000 ;MAKE SURE WE DON'T EXCEED IT ADD P2,PFDBAS(P4) ;POINT AT LAST WORD PLUS ONE SOS P2 ;LAST WORD AFFECTED BY IO SETZ P3, ;NOTHING ACCUMULATED YET PUSHJ P,PFHIOD ;DO THE IO FOR THIS IOWD JRST PFHMS4 ;DIDN'T MAKE IT, LET TOP LEVEL FIND ERROR MOVE P2,PFDSIZ(P4) ;GET SIZE OF THAT IOWD SUBI P2,400000 ;DECREMENT MAX AMOUNT WE WOULD HAVE DONE JUMPG P2,PFHM1A ;AND LOOP IF ANYTHING LEFT TO DO AOSA T1,M ;POINT TO NEXT IOWD PFHMS2: JUMPE T1,PFHMS4 ;GOTO ZERO MEANS END OF IOWD LIST DPB T1,[POINT 23,M,35] ;POINT AT NEXT IOWD PFHMS3: SOSL PFDCNT(P4) ;DECREMENT COUNT OF IOWDS JRST PFHMS1 ;GET NEXT IOWD IN LIST JRST ADRERR## ;MORE THAN A THOUSAND IOWDS, PROBABLY LOOP PFHMS4: ADJSP P,-PFDSIZ-1 ;GIVE BACK STORAGE ON STACK S0PSHJ WAIT1## ;WAIT FOR DEVICE TO QUIET DOWN S0JRST RTNEVM## ;RETURN ANY EVM LEFT OVER
SUBTTL PFHIOD - Dump mode iowds. Comment @ Loose description of dump mode i/o breakdown algorithm. check iowd pages set current address to starting io address call next iowd page return next iowd page look at page if aa off, make aa on if not in core, request pagein if end, do accumulated pagein, do accumulated io and return incr current address to start of next page go back to next iowd page request pagein if reason not in core different than previous reason or current page different than previous page + 1, do accumulated pagein stash starting page not in core stash reason not in core and current page return do accumulated pagein if enough room for all pages, page them in and return make room, and go back to do accumulated pagein make room preserve end accumulated io pointer, to be restored on return loop from .uspfl down accumulating valid pages to page out (not in iowd or vectors) if gsizi cries uncle, page out accumulated pageout and return until looped over entire image page out accumulated pageout binary search from number of pages we want in, calling gsizi until we find out how much maximum will fit page in that many pages set starting page not in core to first page not paged in set up end accumulated io pointer to within last page we paged in do accumulated io and return do accumulated io do io from starting io address to ending io address set starting io address to ending io address + 1 return @
;PFHIOD - Dump mode iowds
;Here to check paged-in dump i/o lists.
;Call
; P4/ Pointer to block of stack space with
; PFDBAS(P4)/ Address of first word touched by this IOWD
; PFDISP(P4)/ Address of routine to call to do IO
; P3/ undefined
; P2/ Last word affected by IO
; P1/ First word affected by IO
;Return
; RET Some error occurred, propagate it to top
; RETSKP IO done, no problems yet
;
;Note that all addresses are full 30 bit addresses - Even if you want to do
;local addressing, you must supply a full extended address.
PFHIOD: PUSHJ P,SAVUM## ;WE USE UP M IN HERE
SETZM PFDRSN(P4) ;NO CURRENT PAGED-OUT-REASON
SETZM PFDPNI(P4) ;NO PREVIOUS PAGE
PUSHJ P,PFHNXI ;DO THIS IOWD
SKIPA ;HMM. ERROR RETURN
AOS (P) ;PROPAGATE SKIP RETURN
POPJ P, ;AND RETURN
PFHNXI: LDB T2,[POINT UPGWID,P1,26] ;GET VIRTUAL PAGE NUMBER
MOVE T1,@[IW UMAPSN,UMAPS(T2)] ;GET PAGE MAP ENTRY
ERJMP PFHIOX ;ILL MEM REF
JUMPE T1,PFHIOX ;ILL MEM REF
MOVSI T3,(<<PM.DCD>B2>!PM.AAB) ;BE SURE ACCESS ALLOWED IS ON
TLC T1,(PM.COR) ;IN CORE BIT
TLNN T1,(PM.COR!1B1) ;IS THIS PAGE IN CORE?
JRST PFHNX2 ;YES, USE IT
PUSHJ P,PFHPIN ;NO, FILE A REQUEST TO PAGE IT IN
POPJ P, ;HMM. AN ERROR OF SOME VARIETY. CUTE.
LDB T2,[POINT UPGWID,P1,26] ;GET VIRTUAL PAGE NUMBER
MOVE T1,@[IW UMAPSN,UMAPS(T2)] ;GET PAGE MAP ENTRY
ERJMP PFHIOX ;ILL MEM REF
JUMPE T1,PFHIOX ;ILL MEM REF
MOVSI T3,(PM.AAB) ;BE SURE DCD COMES ON WHEN PAGE COMES IN
PFHNX2: TLNE T1,(PM.AAB) ;DOES PAGE HAVE ACCESS ALLOWED ON?
JRST PFHNX3 ;YES, JUST USE IT
IORM T3,@[IW UMAPSN,UMAPS(T2)] ;TURN ON IN MAP
SOS .USANA ;DECREMENT NUMBER OF NON-ACCESSIBLE PAGES
PUSHJ P,ADJANA## ;ADJUST .USVRT
PFHNX3: TRO P1,PG.BDY## ;BUMP UP TO PAGE BOUNDARY
ADDI P1,1 ;AND UP TO FIRST WORD OF NEXT PAGE
CAMLE P1,P2 ;DID WE OVERFLOW?
SKIPA P1,P2 ;YES, BACK DOWN TO LAST WORD
JRST PFHNXI ;NO, LOOP CHECKING PAGES
AOS PFDPNI(P4) ;PROTOCOL REQUIRES BUMPING THIS COUNTER
PUSHJ P,PFHACP ;DO ACCUMULATED PAGE IN
POPJ P, ;ARGH. ERROR
JRST PFDOIO ;DO THE I/O AND RETURN
;PFHPIN - Request page-in of a page ;Call ; T1/ Contents of map for page ; T2/ Page number ; P1/ Virtual address we are looking at ; P4/ ; PFDBAS(P4)/ Start word of io ; PFDRSN(P4)/ Reason previous page was paged out ; PFDSNI(P4)/ Start not-in-core page ; PFDPNI(P4)/ Previous not-in-core page ;Return ; RET An I/O error of some sort ; RETSKP With request filed (and possibly some pages paged in); ; or I/O done up to previous page and PFDBAS adjusted to reflect ; the fact. PFHPIN: TDNN T1,[PM.ADR-PM.ZER] ;IS PAGE ABZ? SKIPA P3,[1,,JOBUAL##] ;ABZ, .PAGCD,,AT JOBUAL MOVE P3,[0,,JOBUAL##] ;OUT, .PAGIO,,AT JOBUAL AOS T3,PFDPNI(P4) ;YES, ASSUME THIS IS EXACT NEXT PAGE CAME P3,PFDRSN(P4) ;IS REASON SAME AS EXISTING STUFF? JRST PFHPI2 ;NO, FLUSH PENDING PAGEINS CAMN T3,T2 ;IS THIS THAT EXACT PAGE? RETSKP ;YES, ALL DONE. PFHPI2: PUSHJ P,PFHACP ;DO ACCUMULATED PAGEIN POPJ P, ;SOMETHING FAILED DEEP DOWN MOVEM P3,PFDRSN(P4) ;STASH NEW REASON/FUNCTION LDB T1,[POINT UPGWID,P1,26] ;GET THIS PAGE'S NUMBER MOVEM T1,PFDSNI(P4) ;SAVE AS STARTING PAGE NOT IN CORE MOVEM T1,PFDPNI(P4) ;SAVE AS PREVIOUS PAGE NOT IN CORE RETSKP ;AND RETURN
;PFHACP - Do accumulated pagein ;Call ; P4/ ; PFDRSN - Function code to use for page. uuo ; PFDSNI - Starting page for page. ; PFDPNI - Last page to do plus one ;Return ; RET I/O error deep down ; RETSKP pages are in core (may have done i/o and paged stuff out) ; PFHACP: SKIPN PFDRSN(P4) ;MAKE SURE THERE IS SOMETHING TO DO RETSKP ;NOPE, JUST RETURN MOVE T3,PFDPNI(P4) ;GET LAST PLUS ONE PAGE SUB T3,PFDSNI(P4) ;COMPUTE NUMBER OF PAGES COMING IN PUSHJ P,GSIZI## ;MAKE SURE WE HAVE ENOUGH ROOM JFCL ;WILL NEVER FIT JRST PFHAC2 ;DO CURRENTLY ACCUMULATED I/O FIRST MOVE T1,PFDRSN(P4) ;GET FUNCTION CODE MOVN T2,T3 ;NUMBER OF PAGES TO DO MOVE T3,PFDSNI(P4) ;GET STARTING PAGE NUMBER PUSHJ P,DOPAGE ;DO THE PAGE UUO RETSKP ;DONE, RETURN PFHAC2: PUSHJ P,PFHMKR ;MAKE ROOM POPJ P, ;URP. I/O ERROR IN BOWELS. JRST PFHACP ;AND LOOP TRYING TO PAGE THEM IN
;PFHMKR - Make room for pagein by paging other unused stuff out
;Call
; P4/
; PFDBAS/ Starting place of IO
; PFDRSN/ Function to page pages in
; PFDSNI/ Start not-in-core page
; PFDPNI/ Last not-in-core page plus 1
; P1/ Highest virtual address currently being looked-at
;Return
; RET Some type of i/o error
; RETSKP pages up to PFDPNI have been paged in, we might have
; had to do some i/o and page out earlier pages
PFHMKR: PUSHJ P,SAVE3## ;SAVE SOME WORK REGISTERS
;Set up for range checks for cannot-be-paged-out ('CBPO') pages
ADJSP P,-PFPOFS ;MAKE ROOM FOR CBPO BI-WORDS
PUSHJ P,GETHLM ;GET HIGH SEGMENT LIMITS
DMOVEM T1,PFPHLB(P) ;SET UP FOR CBPO RANGE CHECK
PUSHJ P,GETJLM ;GET RANGE OF PAGES FOR JOBINT BLOCK
DMOVEM T1,PFPJLB(P) ;SET UP FOR CBPO RANGE CHECK
LDB T1,[POINT UPGWID,PFDBAS(P4),26] ;STARTING PAGE OF IOWD
MOVEM T1,PFPILB(P) ;SAVE LOWER-LIMIT OF IOWD-ADDRESSED RANGE
LSH P1,W2PLSH## ;CONVERT TO HIGHEST PAGE
MOVEM P1,PFPILE(P) ;SAVE UPPER-LIMIT OF IOWD-ADDRESSED RANGE
IFN FTPI,<
PUSHJ P,GETPLM ;FIND RANGE OF PAGES FOR PSI VECTOR
DMOVEM T1,PFPPLB(P) ;SET UP FOR CBPO RANGE CHECK
>
LDB P1,IMGIN## ;LOSEG SIZE = COUNT OF CANDIDATE PAGES
SETZB T2,T3 ;NO PAGES TO PAGE OUT ACCUMULATED YET
;Continued on next page
;Continued from previous page ;Loop trying to find pages to page out PFHMK1: SOJLE P1,PFHBRK ;AFTER TRYING ALL PAGES, BREAK THE IOWD DOWN PFHMK2: SOSG P2,.USPFL ;GET PAGE WE LAST PAGED OUT JRST [MOVEI P2,HLGPGS+1 ;RE-START AT TOP PAGE JRST PFHMK3] ;AND CONTINUE FROM THE TOP LDB T1,[POINT 5,P2,26] ;GET SECTION NUMBER LDB T1,[POINT 3,.UPMP+SECTAB(T1),2] ;GET POINTER TYPE OF SECTION CAIN T1,PM.DCD ;A DIRECT POINTER JRST PFHMK4 ;YES, TRY IT TRZ P2,HLGPNO ;ROUND DOWN TO BOTTOM OF BAD SECTION PFHMK3: MOVEM P2,.USPFL ;SET NEW "LAST" CANDIDATE PAGE NUMBER JRST PFHMK2 ;AND LOOP PFHMK4: MOVE T1,@[IW UMAPSN,UMAPS(P2)] ;GET PAGE MAP ENTRY TLC T1,(PM.COR) ;IN-CORE BIT TLNE T1,(PM.COR!1B1) ;IS IT IN CORE? JRST PFHMK2 ;NO, TRY AGAIN CAML P2,PFPHLB(P) ;BELOW FIRST PAGE OF SHARABLE HIGH SEGMENT? CAMLE P2,PFPHLE(P) ;OR ABOVE HIGHEST PAGE? JRST PFHMK5 ;NOT A PAGE IN A SHARABLE HIGH SEGMENT MOVE P2,PFPHLB(P) ;IN A HISEG, SKIP TO START OF HISEG JRST PFHMK3 ;AND CONTINUE SEARCHING FROM THERE PFHMK5: CAML P2,PFPILB(P) ;IS THIS PAGE BELOW RANGE OF OUR IOWD? CAMLE P2,PFPILE(P) ;OR ABOVE IT? JRST PFHMK6 ;NOT WITHIN IOWD-ADDRESSED RANGE JRST PFHMK1 ;TRY NEXT PAGE (CAN'T SKIP IOWD SINCE COUNTED IN P1) PFHMK6: CAME P2,PFPJLB(P) ;IS THIS FIRST PAGE OF .JBINT BLOCK? CAMN P2,PFPJLE(P) ;OR LAST PAGE OF .JBINT? JRST PFHMK1 ;YES, LEAVE IT ALONE IFN FTPI,< CAML P2,PFPPLB(P) ;IS THIS PAGE BELOW RANGE OF PSI VECTOR CAMLE P2,PFPPLE(P) ;OR ABOVE IT? TRNA ;NOT IN RANGE OF PSI VECTOR JRST PFHMK1 ;IN PSI VECTOR, LEAVE IT ALONE > ;Continued on next page
;Continued from previous page ;Here when we have a page to page out PFHMK7: CAIE T3,1(P2) ;IS THIS PAGE DIRECTLY BELOW PREVIOUS PAGE? PUSHJ P,PFHMKO ;NO, OUTPUT ACCUMULATION SOS T2 ;INCREMENT NUMBER OF PAGES TO PAGE OUT MOVE T3,PFDPNI(P4) ;GET LAST PAGE NEEDED PLUS ONE SUB T3,PFDSNI(P4) ;GET NUMBER OF PAGES INCREASE WE NEED ADD T3,T2 ;MINUS PAGES WE CAN PAGE OUT PUSHJ P,GSIZI## ;WILL WE FIT NOW? JFCL ;STILL NOT TRNA ;STILL NOT JRST PFHMK9 ;WE WILL FIT IF WE DO ACCUMULATED PAGEOUT MOVE T3,P2 ;NEW LOWEST PAGE JRST PFHMK1 ;AND LOOP LOOKING FOR MORE PAGES PFHMK9: MOVE T3,P2 ;RE SET UP LOWEST PAGE ADJSP P,PFPOFS ;RETURN CHECK WORDS TO STACK PUSHJ P,PFHMKO ;PAGE OUT ACCUMULATION RETSKP ;AND RETURN SUCCESS PFHMKO: JUMPE T2,CPOPJ## ;IF NOTHING TO PAGE OUT, JUST RETURN MOVE T1,[.PAGIO,,JOBUAL##] ;PAGE UUO ARGUMENT TLO T3,(PG.GAF) ;INDICATE PAGING OUT PUSHJ P,DOPAGE ;DO THE PAGE UUO SETZ T2, ;INDICATE NO PAGES ACCUMULATED YET POPJ P, ;RETURN
;At this point, we have paged out everything possible and we STILL don't ;have enough room. We will page in everything we possibly can, and then ;do as much io as we can into those pages. This is where we finally have ;to break down and split up the iowd. PFHBRK: ADJSP P,PFPOFS ;RETURN PFHMKR'S CHECK WORDS TO STACK PUSHJ P,PFHMKO ;PAGE OUT ACCUMULATION MOVE T3,PFDPNI(P4) ;GET LAST PAGE NEEDED PLUS ONE SUB T3,PFDSNI(P4) ;GET NUMBER OF PAGES INCREASE WE NEED ADDI T3,1 ;PREINCREMENT BEFORE BINARY SEARCH SETUP JFFO T3,.+1 ;FIND HIGH ORDER BIT MOVSI T3,(1B0) ;A BIT MOVNS T4 ;MAKE THIS NEGATIVE SHIFT LSH T3,(T4) ;AND GET STARTING QUANTITY TO USE MOVE T2,T3 ;COPY STARTING QUANTITY PFHBR0: ASH T2,-1 ;HALF QUANTITY PUSHJ P,GSIZI## ;CAN WE FIT THIS MUCH IN? JFCL ;NO JRST PFHBR1 ;DECREMENT AMOUNT WE ARE ASKING FOR ADD T3,T2 ;IT FITS, TRY FOR SOME MORE JUMPN T2,PFHBR0 ;AND LOOP JRST PFHBR2 ;DONE, JOIN COMMON CODE PFHBR1: SUB T3,T2 ;DOESN'T FIT, TRY A LITTLE LESS JUMPN T2,PFHBR0 ;AND LOOP TRYING TO FIND IDEAL SIZE SUBI T3,1 ;DIDN'T FIT, BACK IT DOWN TO PREVIOUS SIZE JUMPE T3,CPOPJ## ;ERROR IF NOTHING FOUND TO PAGE OUT ;BRING WHAT WE CAN INTO CORE PFHBR2: MOVE T1,PFDRSN(P4) ;FUNCTION CODE FOR PAGE. UUO MOVN T2,T3 ;NUMBER OF PAGES TO DO ADD T3,PFDSNI(P4) ;POINT TO FIRST PAGE AFTER WHAT WE WILL DO EXCH T3,PFDSNI(P4) ;STARTING PAGE TO PAGE IN PUSHJ P,DOPAGE ;DO THE PAGE UUO MOVE T1,PFDSNI(P4) ;GET FIRST INACCESSIBLE PAGE SUBI T1,1 ;MAKE IT LAST ACCESSIBLE PAGE MOVE P1,PFDBAS(P4) ;GET STARTING LOCATION FOR DUMP IO DPB T1,[POINT UPGWID,P1,26] ;MAKE A POINTER TO LAST ACCESSIBLE PAGE CAMG P1,PFDBAS(P4) ;MAKE SURE WE ENDED UP WITH SOMETHING HIGHER STOPCD .,JOB,PFNOIO, ;++ PFH HAS NO IO TO DO (I'M STUCK!) SOS P1 ;BACK DOWN TO DO EXACT MULTIPLE OF PAGESIZE PUSHJ P,PFDOIO ;DO THE I/O POPJ P, ;SOME KIND OF I/O ERROR RETSKP ;AND RETURN
;PFDOIO - Do accumulated IO. ;Call ; P4/ Block, with ; PFHBAS(P4)/ First word affected by IO. Updated at end of call. ; PFDEVM(P4)/ Amount of EVM we have, if any. Updated if necessary. ; PFDISP(P4)/ Address of filio routine to dispatch to ; P1/ Last address checked ;Return ; RET On an IO error of some kind ; RETSKP everything o.k., PFDBAS points at new address PFDOIO: PUSH P,P3 ;SAVE P REGISTER THAT WE TRASH MOVE P3,P1 ;LAST WORD CHECKED SUB P3,PFDBAS(P4) ;NUMBER OF WORDS TO DO MINUS ONE HLRZ T1,PFDBAS(P4) ;GET SECTION NUMBER HRRM T1,DEVISN(F) ;STASH IT IN DDB MOVEI T1,DEPEVM ;"DOES NOT NEED EVM" BIT TDNN T1,DEVTYP(F) ;DO WE NEED TO GET EVM? CAML P3,PFDEVM(P4) ;YES, DO WE ALREADY HAVE ENOUGH? JRST DOIO2 ;SAFE, JUST DO THE IO PUSHJ P,RTNEVM## ;CURRENT EVM ISN'T ENOUGH, GIVE IT BACK MOVEI T1,1(P3) ;AMOUNT OF EVM WE WILL NEED MOVE T3,PFDBAS(P4) ;WHERE WE ARE GOING TO DO IO PUSHJ P,GTEVBF## ;GET EVM FOR IT JRST UADERR## ;NO CAN GET, BOMB OUT MOVEM P3,PFDEVM(P4) ;INDICATE HOW MUCH EVM WE HAVE DOIO2: HRRZ T1,PFDBAS(P4) ;FIRST WORD TOUCHED BY I/O ADDM P3,PFDBAS(P4) ;POINT TO ENDING WORD AOS PFDBAS(P4) ;POINT TO FIRST WORD BEYOND THIS TRANSFER HRLO P3,P3 ;NUMBER OF WORDS TO DO EQV T1,P3 ;MAKE AN IOWD OUT OF IT HRRI T1,-1(T1) ;IOWD POINTS AT ADDR-1 SETZ T2, ;IOWD TERMINATOR DMOVEM T1,.JDAT+JOBUAL## ;STASH FOR FILIO LDB T1,PJOBN## ;GET JOB NUMBER FOR THIS DEVICE CAME T1,.CPJOB## ;MAKE SURE IT BELONGS TO US STOPCD .,JOB,PFHJOB, ;++ WRONG JOB OWNS DEVICE MOVE T1,PFDISP(P4) ;GET DISPATCH ADDRESS MOVEI M,JOBUAL## ;POINT TO IOWD S0PSHJ 0(T1) ;AND DISPATCH. MOVE J,.CPJOB## ;GET BACK JOB NUMBER (TRASHED BY IO ROUTINES) MOVE R,JBTADR##(J) ;DITTO PUSHJ P,WAIT1## ;LET THINGS QUIET DOWN POP P,P3 ;RESTORE TRASHED P REGISTER, FIXUP STACK TRNE S,IOBKTL+IODTER+IODERR+IOIMPM+IODEND ;ANY ERRORS? POPJ P, ;UH OH, AN ERROR, RETURN NON-SKIP RETSKP ;DONE, EVERYTHING HUNKY DORY
;PFHIOX - Cause an ill addr in uuo ;Call ; P1/ Address which we believe will cause an ill mem ref ;Return ; you can't. PFHIOX: MOVE M,P1 ;ADDRESS WHICH FAILS PJRST UADERR## ;GIVE THE USER THE BAD NEWS
SUBTTL MIGRATION ;ROUTINE TO HANDLE BAD PAGE MIGRATION. CALLED AT CLOCK LEVEL PFHMIG:: PUSHJ P,SVEUB## SKIPN .USVRT ;VIRTUAL? JRST CPOPJ1## ;NO, CAN'T HAVE ANY BAD PAGES THEN SE1ENT PUSHJ P,SAVE4## ;SAVE SOME ACS PUSHJ P,SAVT## MOVE R,JBTADR##(J) ;LOAD R FOR UPAGE. SETZB M,.USSPT ;START WITH SECTION 0 PFHMI0: PUSHJ P,NXTNWS## ;GET A NON-WORKING SET PAGE CAIA ;(FIRST TIME AROUND) PFHMI1: PUSHJ P,NXTNW3## ;GET NEXT NON-WORKING SET PAGE JUMPE T4,PFHMI6 ;DONE THIS SECTION PUSHJ P,TSTUN## ;ON BAD UNIT? CAIA ;YES, NEED TO DO SOMETHING JRST PFHMI1 ;NOT ON BAD UNIT, LOOK AGAIN TLOE M,2 ;SET WE NEED TO DO SOMETHING JRST PFHM5A ;DON'T DO THIS STUFF AGAIN PUSH P,T1 ;SAVE ACS USED BY SIMCHK PUSH P,T2 PUSHJ P,SIMCHK## ;CAN JOB BE STOPPED NOW (OK TO DIDDLE WS)? JRST PFHMI5 ;OK TO STOP JOB ADJSP P,-2 ;FIX STACK TLO J,400000 ;SET SIGN BIT JRST CPOPJ1## PFHMI5: SETOB P2,P3 ;ACS FOR OUTPAG MOVEI P4,-1(P) ;BLOCK FOR SAVING WORKING SET INFO ADJSP P,5-2 ;T1-T3,M,.USSPT PUSHJ P,EXCHT1 ;SAVE THE INFO PUSHJ P,GETPLM ;PSI VECTOR PUSH P,T1 PUSH P,T2 ;SAVE START, END PUSHJ P,GETJLM ;JOBINT VECTOR PUSH P,T1 PUSH P,T2 HRRZ T1,.USPFH ;USER PFH, IF ANY PUSH P,T1 HLRZ T1,.USPFH PUSH P,T1 MOVE T1,JBTIMI##(J) ;SAVE JBTIMI NOW PUSH P,T1 SETZB M,.USSPT ;JUNK STORED BY EXCHT PUSHJ P,NXTWSB## ;START LOOKING FOR LEGIT PAGE-OUT PAGES CAIA ;(ALREADY EXCH'D) PFHM5A: PUSHJ P,EXCHT ;SAVE NWS INFO, GET WS INFO PFHMI2: PUSHJ P,NXTWS3## ;GET NEXT WORKING SET PAGE ;(SKIP REAL PAGE 0 ONLY) PFHMI3: TRNE M,<-1^!HLGPNO> ;USER PAGE? JRST PFHMI4 ;NO MOVE P1,.USSPT ;SECTION LSH P1,S2PLSH## ;PAGE IORI P1,(M) CAML P1,-6(P) ;IN THE PSI VECTOR? CAMLE P1,-5(P) CAIA ;NO JRST PFHMI2 CAML P1,-4(P) CAMLE P1,-3(P) ;OR THE JOBINT VECTOR? SKIPA T4,(T4) ;GET PAGE MAP ENTRY FOR NEXT TEST JRST PFHMI2 CAML P1,-2(P) ;FINALLY A USER PFH CAMLE P1,-1(P) TLNN T4,(PM.COR) ;IS PAGE IN CORE (OR DID WE SET TO PAGE THIS IN) JRST PFHMI2 TLO M,1 ADJSP P,3 DMOVEM T1,-2(P) MOVEM T3,(P) PUSHJ P,OUTPAG DMOVE T1,-2(P) MOVE T3,(P) ;AND T3 PUSHJ P,EXCHT ;NWS ACS PUSHJ P,BTCOM## ;SET BIT DMOVEM T1,-2(P) ;SAVE T1, T2 MOVEM T3,(P) ;AND T3 MOVE T1,.USSPT LSH T1,S2PLSH## IORI T1,(M) ;PAGE # PUSHJ P,INCHJ## POP P,T3 POP P,T2 POP P,T1 JRST PFHMI1 ;LOOP FOR ANOTHER NWS PAGE PFHMI4: SKIPL .USBTS ;AN EXTENDED USER? JRST PFHMI8 ;NO, CAN'T DO ANYTHING FOR HIM PFHM4A: AOS T4,.USSPT ;INCREMENT SECTION CAILE T4,MXSECN ;OVER THE TOP? JRST PFHMI8 ;YES, CAN'T DO ANYTHING THEN SKIPE T1,.UPMP+SECTAB(T4) ;SECTION EXISTS? TLNE T1,(<PM.ACD^!PM.DCD>B2) ;INDIRECT? JRST PFHM4A ;NO PUSHJ P,NXTWSB## ;GET NEXT WORKING SET BIT JRST PFHMI3 ;AND LOOK AT IT PFHMI6: SKIPL .USBTS ;EXTENDED USER? JRST PFHMI7 ;NO, DONE PFHM6A: AOS T4,.USSPT ;INCREMENT SECTION CAILE T4,MXSECN ;BELOW MAX? JRST PFHMI7 ;NO SKIPE T1,.UPMP+SECTAB(T4) ;EXIST? TLNE T1,(<PM.DCD^!PM.ACD>B2) ;INDIRECT? JRST PFHM6A JRST PFHMI0 PFHMI7: TLNN M,2 ;WANT TO DO ANYTHING JRST CPOPJ1## ;NO, NOTHING TO DO PUSHJ P,EXCHT ;GET THE WS ACS BACK PFHMI8: TLNE M,1 ;DO ANYTHING INTERESTING? JRST PFHMI9 ;YES PUSHJ P,EXCHT ;GET NWS ACS TLNN M,2 ;WANT TO DO ANYTHING INTERESTING JRST CPOPJ1## ;NOTHING TO DO PUSHJ P,BTCOM## ;SET BIT AOS (P) ;INCREMENT SAVED IMGIN .CREF IMGIN MOVE T1,.USSPT LSH T1,S2PLSH## IORI T1,(M) ;PAGE # PUSHJ P,INCHJ## JRST PFHM10 PFHMI9: SETO P1, PUSHJ P,OUTPAG ;FLUSH PAGES PFHM10: LDB T1,IMGIN## ;SIZE-PAGES PAGED OUT DPB T1,IMGOUT## POP P,JBTIMI##(J) ;(# OF MAPS HASN'T CHANGED) .CREF IMGIN ADJSP P,-<5+6> ;FIX STACK POPJ P, ;SUBROUTINE TO SAVE RELEVANT WORKING SET INFO EXCHT: EXCH T1,(P4) EXCH T2,1(P4) EXCHT1: EXCH T3,2(P4) EXCH M,3(P4) PUSH P,.USSPT PUSH P,4(P4) POP P,.USSPT POP P,4(P4) POPJ P,
END