Trailing-Edge
-
PDP-10 Archives
-
BB-JR93K-BB_1990
-
10,7/mon/monpfh.mac
There are 10 other files named monpfh.mac in the archive. Click here to see a list.
TITLE MONPFH DEFAULT PAGE FAULT HANDLER V074
SUBTTL Tarl Neustaedter/TARL 14 MAR 89
SEARCH F,S
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION 1984,1986,1988.
;ALL RIGHTS RESERVED.
.CPYRT<1984,1988>
XP VPFH,074
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.
PFPJLB==-1 ;.JBINT BLOCK BEGIN PAGE
PFPJLE==-0 ;.JBINT BLOCK END PAGE
PFPILE==-3 ;I/O RANGE BEGIN PAGE
PFPILB==-2 ;I/O RANGE END PAGE
PFPBPT==-4 ;DDT'S UNSOLICITED BREAKPOINT TRAP ADDRESS
PFPOFS==-5 ;OFFSET ON STACK
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
SKIPE .PDTMI##(W) ;IF USER SUPPLIED A VALUE,
JRST PFH1 ; USE IT INSTEAD
MOVEI T1,M.PFHT## ;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
SETOB P2,P3 ;NO LAST PAGE, NO STARTING PAGE
SETZ P4, ;SECTION 0 IN CASE NOT A BIG USER
;Set up for range checks for cannot-be-paged-out ('CBPO') pages
ADJSP P,-PFPOFS ;MAKE ROOM FOR LIMIT BI-WORDS
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
PUSHJ P,GETPLM ;FIND RANGE OF PAGES FOR PSI VECTOR
DMOVEM T1,PFPPLB(P) ;SET UP FOR CBPO RANGE CHECK
;Page out all pages with AA off and turn off AA for all pages in core
PUSH P,[-1] ;FLAG OF WHETHER IOWAIT CALLED
SKIPL .USBTS ;BIG USER?
JRST PFHTI4 ;NO, NO NEED TO LOOK AT EXTENDED SECTIONS
MOVEI P4,MXSECN ;SECTIONS MXSECN THROUGH 1
PFHTI1: SKIPE T1,.UPMP+SECTAB(P4) ;NEXT SECTION POINTER
TLNE T1,(<<PM.DCD^!PM.ACD>B2>) ;INDEPENDENT SECTION?
JRST PFHTI3 ;NON-EXISTANT OR INDIRECT, MOVE ON TO NEXT
MOVE T1,P4 ;SECTION NUMBER
IMULI T1,WSBTBL ;COMPUTE WHICH WSBTAB TO USE
MOVEI T1,.WSBNZ-WSBTBL(T1)
MOVEI T2,HLGPNO ;HIGHEST PAGE IN THE SECTION
PUSHJ P,NXTWSP ;FIND THE HIGHEST PAGE IN THE SECTION
JRST PFHTI3 ;THERE AREN'T ANY
PUSHJ P,TOUTPG ;PAGE OUT THE PAGE IF AA OFF
PUSHJ P,TCLRAA ;CLEAR AA IF IN CORE AND NOT CBPO PAGE
PFHTI2: PUSHJ P,NXTWSC ;GET NEXT PAGE IN SECTION
JRST PFHTI3 ;NO MORE LEFT
PUSHJ P,TOUTPG ;PAGE OUT THE PAGE IF AA OFF
PUSHJ P,TCLRAA ;CLEAR AA IF IN CORE AND NOT CBPO PAGE
JRST PFHTI2 ;NEXT PAGE
PFHTI3: SOJG P4,PFHTI1 ;NEXT SECTION
;Here to do section zero
PFHTI4: MOVEI T1,WSBTAB ;SECTION ZERO WORKING SET TABLE
MOVEI T2,HLGPNO ;HIGHEST PAGE IN THE SECTION
PUSHJ P,NXTWSP ;GET HIGHEST PAGE IN THE SECTION
JFCL ;THERE HAS TO BE AT LEAST 1, NAMELY PAGE 0
JUMPE T2,PFHTI6 ;DONE IF THATS THE ONLY PAGE
PUSHJ P,TOUTPG ;PAGE OUT THE PAGE IF AA OFF
PUSHJ P,TCLRAA ;CLEAR AA IF IN CORE AND NOT CBPO PAGE
PFHTI5: PUSHJ P,NXTWSC ;GET NEXT WORKING SET PAGE
JRST PFHTI6 ;CAN'T HAPPEN
JUMPE T2,PFHTI6 ;ALL DONE IF THIS IS PAGE 0
PUSHJ P,TOUTPG ;PAGE OUT THE PAGE IF AA OFF
PUSHJ P,TCLRAA ;CLEAR AA IF IN CORE AND NOT CBPO PAGE
JRST PFHTI5 ;LOOP OVER ALL PAGES IN SECTION 0
PFHTI6: ADJSP P,PFPOFS-1 ;THROW AWAY RANGE CHECK WORDS ON STACK
SETZ P1, ;FLAG END
PUSHJ P,OUTPAG ;AND FLUSH ANY PENDING PAGES
PJRST ADJANA## ;ADJUST .USANA AND RETURN
;Clear access allowed if possible
TCLRAA: MOVE T2,@[IW MS.MAP,UMAPS(P1)]
TLC T2,(PM.COR!PM.AAB) ;ALL THESE BITS MUST BE ON
TLCE T2,(PM.COR!PM.AAB!1B1) ;WERE THEY?
POPJ P, ;NOPE, TRY NEXT PAGE
CAME P1,PFPJLB-2(P) ;IS THIS FIRST PAGE OF .JBINT BLOCK?
CAMN P1,PFPJLE-2(P) ;OR LAST PAGE OF .JBINT?
POPJ P, ;YES, LEAVE IT ALONE
CAMN P1,PFPBPT-2(P) ;IS THIS THE BREAKPOINT TRAP ADDRESS?
POPJ P, ;YES, CAN'T PAGE OUT
CAML P1,PFPPLB-2(P) ;IS THIS PAGE BELOW RANGE OF PSI VECTOR
CAMLE P1,PFPPLE-2(P) ;OR ABOVE IT?
TRNA ;NOT IN RANGE OF PSI VECTOR
POPJ P, ;IN PSI VECTOR, LEAVE IT ALONE
PUSHJ P,SAVT## ;SAVE VOLATLE ACS
AOSG -6(P) ;CALLED IOWAIT ALREADY?
S0PSHJ IOWAIT## ;NO, WAIT FOR ALL I/O TO STOP BEFORE DINKING BITS
MOVSI T2,(<PM.DCD>B2!PM.AAB) ;CLEAR ACCESS ALLOWED
ANDCAM T2,@[IW MS.MAP,UMAPS(P1)] ;CLEAR THE BITS
MOVE T2,P1 ;PAGE NUMBER
LSH T2,P2WLSH## ;VIRTUAL ADDRESS
EXCTUU <CLRPT (T2)> ;FLUSH PAGING MEMORY'S REMEMBERANCE OF THIS PAGE
AOS .USANA ;INCREMENT INACCESSIBLE PAGES
POPJ P, ;RETURN
;Output page if access allowed off (returns CPOPJ1 if a page was paged out)
TOUTPG: MOVE P1,P4 ;SECTION NUMBER
LSH P1,S2PLSH ;POSITION IT TO SECTION NUMBER FIELD
IOR P1,T2 ;PAGE NUMBER
MOVE T2,@[IW MS.MAP,UMAPS(P1)]
TLC T2,(PM.COR) ;INVERT PAGE-IN-CORE BIT
TLNE T2,(PM.COR!1B1!PM.AAB) ;IS IT IN CORE AND AA OFF?
POPJ P, ;NO
PUSHJ P,SAVT## ;YES, SAVE VOLATILE ACS AND FALL INTO OUTPAG
AOS (P) ;SKIP CALL TO TCLRAA
; PJRST OUTPAG ;PAGE OUT THIS PAGE
;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
;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
;Subroutine to find the next bit in a table scanning table from right to left.
; Call first time at NXTWSP, T1=address of table, T2=starting bit position
; within table, call subsequent times at NXTWSC with T1, T3, and T4 preserved
; from previous call. Returns CPOPJ1 with T2=position of next non-zero bit in
; the table, CPOPJ if no more bits.
NXTWSP: MOVEM T1,.USTMP+5 ;SAVE ADDRESS OF TABLE
MOVE T3,T2 ;STARTING BIT POSITION
IDIVI T3,^D36 ;WORD WITHIN THE TABLE
ADD T3,T1 ;WHERE TO START IN THE TABLE
SUBI T4,^D35 ;NUMBER OF BITS TO THE LEFT
MOVE T1,(T3) ;GET STARTING WORD FROM TABLE
LSH T1,(T4) ;POSITION IT (STARTING BIT = LSB)
MOVMS T4 ;BIT NUMBER
JRST NXTWSC ;SEE IF THERE ARE INY IN THIS WORD
NXTWP1: SKIPN T1,(T3) ;NEXT WORD, DOES IT CONTAIN ANY BITS?
JRST NXTWP2 ;NO
SETZ T4, ;YES, STARTING AT THE LSB
NXTWSC: JUMPE T1,NXTWP2 ;JUMP IF NO MORE BITS IN THIS WORD
LSHC T1,-1 ;SHIFT LSB INTO SIGN BIT OF T2
JUMPL T2,NXTWP3 ;JUMP IF THE BIT IS ON
AOJA T4,NXTWSC ;COUNT THIS ZERO BIT AND NEXT BIT
NXTWP2: CAMLE T3,.USTMP+5 ;LOOKED AT ENTIRE TABLE?
SOJA T3,NXTWP1 ;NO, LOOK ON
POPJ P, ;NO BITS FOUND
NXTWP3: MOVEI T2,1(T3) ;CALCULATE BIT POSITION WITHIN TABLE
SUB T2,.USTMP+5 ;WORD WITHIN TABLE
IMULI T2,^D36 ;36 BITS PER WORD
SUBI T2,1(T4) ;SINCE REALLY COUNTING FROM 1 TO 44
AOJA T4,CPOPJ1## ;NEXT BIT NEXT TIME
;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,[MS.MAP+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: PUSHJ P,SAVE1## ;P1 NEEDS TO BE PRESERVED
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
TLZ P1,-1-MXSECN ;CLEAR EXTRANEOUS BITS
EXCTUU <CLRPT (P1)> ;REFRESH PAGER'S ASSOC MEMORY, THIS PAGE ONLY
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 n pages below limit
;Call
; MOVEI T3,amount of increase ;Only for call to CHKLIN
; PUSHJ P,CHKLIM/CHKLIN ;CHKLIM assumes one page increase
;Return
; RET ;Can't make room for another page
; RETSKP ;There is now room for at least one page
CHKLIM: MOVEI T3,1 ;ONE PAGE OF INCREASE
CHKLIN::SE1ENT ;MUST BE IN SECTION 1
PUSHJ P,SAVE3## ;PRESERVE ACS USED
MOVE P2,T3 ;SAVE IN MORE PERMANENT PLACE
SETZ P3, ;FIRST TIME THROUGH
;Set up for range checks for cannot-be-paged-out ('CBPO') pages
ADJSP P,-PFPOFS ;MAKE ROOM FOR LIMIT BI-WORDS
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
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,(P2) ;AMOUNT OF INCREASE
PUSHJ P,GSIZI## ;WILL WE STILL FIT IN CORE?
JFCL ;WILL NEVER FIT
TRNA ;LESSER THAN LIMITS
JRST CHKL10 ;WILL FIT, RETURN NOW
;Here when we will have to page things out.
CHKLI2: SOJLE P1,CHKL11 ;GIVE UP AFTER CHECKING ALL CANDIDATE PAGES
CHKLI3: SOSG T2,.USPFL ;GET PAGE WE LAST PAGED OUT
JRST [SKIPL .USBTS ;A BIG USER?
SKIPA T2,[HLGPNO+1] ;NO, JUST LOOK AT SECTION 0
MOVEI T2,HLGPGS+1 ;RE-START AT TOP PAGE
JRST CHKLI5] ;AND CONTINUE FROM THE TOP
LDB T2,[POINT 5,T2,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
CHKLI4: MOVE T2,.USPFL ;GET LAST PAGE PAGED OUT
TRZ T2,HLGPNO ;ROUND DOWN TO BOTTOM OF BAD SECTION
CHKLI5: MOVEM T2,.USPFL ;AND SAVE IT
JRST CHKLI3 ;AND LOOP
CHKLI6: MOVE T2,.USPFL ;PAGE TO CONSIDER
TRC T2,PG.BDY ;STARTING A NEW SECTION?
TRCE T2,PG.BDY ; ..
JUMPN P3,CHKLI7 ;OR NOT THE FIRST TIME THROUGH?
LDB T1,[POINT 5,T2,26] ;GET SECTION NUMBER
SKIPE T1 ;SECTION ZERO IS DIFFERENT
JRST [IMULI T1,WSBTBL;COMPUTE WHICH WSBTAB TO USE
MOVEI T1,.WSBNZ-WSBTBL(T1)
JRST .+2] ;AND CONTINUE
MOVEI T1,WSBTAB ;SECTION 0 WSBTAB
ANDI T2,PG.BDY ;STARTING PAGE WITHIN SECTION
PUSHJ P,NXTWSP ;GET FIRST PAGE IN THIS SECTION
JRST CHKLI4 ;THERE AREN'T ANY
JRST CHKLI8 ;SEE IF ITS A CANDIDATE
CHKLI7: PUSHJ P,NXTWSC ;GET NEXT WORKING SET PAGE
JRST CHKLI4 ;NO MORE IN THIS SECTION
;This is just a sanity check which set P3 non-zero. If its in the WS,
; its in core.
CHKLI8: DPB T2,[POINT 9,.USPFL,35] ;STORE PAGE NUMBER IN .USPFL
MOVE T2,.USPFL ;GET EXTENDED PAGE NUMBER
JUMPE T2,CHKLI3 ;GO IF THIS IS PAGE 0 IN SECTION 0
MOVE P3,@[IW MS.MAP,UMAPS(T2)] ;GET PAGE MAP ENTRY
TLC P3,(PM.COR) ;IN-CORE BIT
TLNE P3,(PM.COR!1B1) ;IS IT IN CORE?
JRST CHKLI3 ;NO, TRY AGAIN
CHKLI9: CAME T2,PFPJLB(P) ;IS THIS FIRST PAGE OF .JBINT BLOCK?
CAMN T2,PFPJLE(P) ;OR LAST PAGE OF .JBINT?
JRST CHKLI2 ;YES, LEAVE IT ALONE
CAMN T2,PFPBPT(P) ;BREAKPOINT TRAP ADDRESS?
JRST CHKLI2 ;YES, LEAVE IT FOR DDT
CAML T2,PFPPLB(P) ;IS THIS PAGE BELOW RANGE OF PSI VECTOR
CAMLE T2,PFPPLE(P) ;OR ABOVE IT?
TRNA ;NOT IN RANGE OF PSI VECTOR
JRST CHKLI2 ;IN PSI VECTOR, LEAVE IT ALONE
PUSHJ P,CKLDPG ;DO THE PAGE OUT
JRST CHKLI1 ;MAKE SURE WE ARE BELOW LIMIT NOW
CHKL10: AOS PFPOFS(P) ;SET UP FOR SKIP RETURN
CHKL11: ADJSP P,PFPOFS ;THROW AWAY CHECK WORDS ON STACK
POPJ P, ;RETURN
;Here to page out the page, page number in T2.
CKLDPG: PUSHJ P,SAVT## ;MUST SAVE T1 ACS FOR NXTWSC
MOVEM T2,.USPFL ;REMEMBER AS LAST PAGE PAGED OUT
MOVE T3,T2 ;FOR DOPAGE
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
PJRST SCDCHK## ;LET OTHER USERS RUN JUST IN CASE
;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,PG.BDY ;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:
IFN FTXMON,<
MOVE T4,T1 ;SAVE FUNCTION
MOVEI T1,0 ;SET PCS TO ZERO
PUSHJ P,SVPCS## ;SINCE ARGUMENT LIST WILL BE AT JOBUAL IN S0
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.
JRST DOPAG4 ;ANALYZE THE ERROR
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 analyze the error code returned from the PAGE. UUO.
DOPAG4:
; UMOVE T1,0 ;GET ERROR CODE
CAIE T1,PAGIO% ;PAGING I/O ERROR? ANYTHING ELSE IS FATAL
STOPCD .,JOB,PFHUUO, ;++ PAGE UUO FAILED
JSP T1,ERRPNT## ;TELL THE USER ABOUT THE PROBLEM
ASCIZ \Paging I/O error\
PJRST PCSTOP## ;TELL THE USER THE PC AND STOP THE JOB
;Here to count an in working set page fault
PFHXCI: AOSA SYSIWS## ;COUNT "IN WORKING SET" FAULT
;Here to count a not in working set page fault
PFHXCN: AOSA SYSNIW## ;COUNT "NOT IN WORKING SET" FAULT
SKIPA T1,[1] ;COUNTS IN THE RIGHT HALF
MOVSI T1,1 ;COUNTS IN THE LEFT HALF
ADDM T1,.USVCT ;UPDATE USER TOTAL
ADDM T1,SYSVCT## ;TALLY UP OLD COUNTER TOO
JRST CPOPJ1## ;RETURN
;PFHGWD - GETWRD routine specifically for PFH. Make sure that we fault
; gently, and pull the page in without trying to re-start the uuo.
PFHGW1::HRRI M,1(M) ;BUMP THE ADDRESS
PFHGWD::TRNN M,^-17 ;IS THIS AN AC REFERENCE?
PJRST GETWRD## ;YES, DO IT THE OLD WAY
SE1ENT ;NO, USE SECTION 1 FOR ADDRESSING
PUSH P,M ;SAVE M
HRLI M,(IFIW) ;MAKE VALID IW
PUSHJ P,PFHXW0 ;FETCH
JRST MPOPJ## ;PROPAGATE FAILURE
JRST MPOPJ1## ;AND SUCCESS
PFHGWF: 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
PFHXW0: UMOVE T1,@M ;GET THE WORD FROM USER MEMORY
ERJMP PFHGWF ;FAILED, TRY TO PAGE IT IN
RETSKP ;AND RETURN SUCCESS
IFN FTXMON,<
PFHXW1::SKIPL M ;IS THIS AN IFIW?
AOSA M ;NO, BUMP GLOBALLY
HRRI M,1(M) ;YES, BUMP LOCALLY
TRNN M,-1 ;IF HIT A SECTION BOUNDARY,
SKIPGE M ;AND DIDN'T WRAP,
JRST PFHXWD ; (NO)
PUSHJ P,SMPCS## ;THEN MAKE SURE IT'S VALID
POPJ P, ;PROPAGATE FAILURE
;FALL INTO PFHXWD
;PFHXWD - The PFH version of GETXWD
PFHXWD::TDNN M,[^-<IFIW!<1,,17>>] ;IS THIS AN AC REFERENCE?
PJRST GETWRD## ;YES, HANDLE IT THE OLD WAY
SE1ENT ;MUST BE IN S1
JRST PFHXW0 ;GO FETCH IT
;PFHMWD - like PFHGWD but gets the word from section specified by M
PFHMWD::SE1ENT ;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 PFHGWD ;GET THE WORD
> ;END IFN FTXMON
;PFHPWD - The PFH version of PUTWRD
PFHPW1::HRRI M,1(M) ;ADVANCE THE POINTER
PFHPWD::PUSH P,T1 ;SAVE VALUE TO DEPOSIT
PUSHJ P,PFHGWD ;MAKE SURE THE WORD IS IN CORE
JRST TPOPJ## ;PROPAGATE FAILURE
POP P,T1 ;RESTORE VALUE TO STORE
PJRST PUTWRD## ;NOW GO STUFF IT IN
IFN FTXMON,<
;PFHPMW - The PFH version of PUTMWD
PFHPMW::PUSH P,T1 ;SAVE VALUE TO DEPOSIT
PUSHJ P,PFHMWD ;MAKE SURE THE WORD IS IN CORE
JRST TPOPJ## ;PROPAGATE FAILURE
POP P,T1 ;RESTORE VALUE TO STORE
PJRST PUTMWD## ;NOW GO STUFF IT IN
;PFHPXW - The PFH version of PUTEWD
PFHPX1::SKIPL M ;AN IFIW?
AOSA M ;NO, ADVANCE GLOBALLY
HRRI M,1(M) ;YES, ADVANCE LOCALLY
TRNN M,-1 ;IF HIT A SECTION BOUNDARY,
SKIPGE M ;AND CROSSED IT
JRST PFHPXW ;(NO)
PUSHJ P,SMPCS## ;MAKE SURE IT'S VALID
POPJ P, ;PROPAGATE FAILURE
PFHPXW::PUSH P,T1 ;SAVE VALUE TO STORE
PUSHJ P,PFHXWD ;MAKE SURE THE WORD'S IN CORE
JRST TPOPJ## ;PROPAGATE FAILURE
POP P,T1 ;RESTORE VALUE TO DEPOSIT
PJRST PUTEWD## ;AND GO STUFF IT IN
> ;END IFN FTXMON
IFE FTXMON,<
XP PFHMWD,PFHGWD
XP PFHXWD,PFHGWD
XP PFHXW1,PFHGW1
XP PFHPMW,PFHPWD
XP PFHPXW,PFHPWD
XP PFHPX1,PFHPW1
> ;END IFE FTXMON
;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
MOVE P1,T1 ;SAVE DEVICE DISPATCH ADDRESS
IFN FTXMON,<
TLO F,(1B0) ;TURN ON THE SIGN BIT FOR INDEXING (UINITB)
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
XOR T1,P2 ;SEE IF SECTIONS CHANGED
TLNE T1,-1 ;IF SO, THIS IS BAD FOR AN OLD-STYLE IOWD
S0JRST ADRERR## ;SO GIVE HIM THE BAD NEWS
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
MOVE P1,T1 ;SAVE DEVICE DISPATCH ADDRESS
IFN FTXMON,<
TLO F,(1B0) ;TURN ON THE SIGN BIT FOR INDEXING (UINITB)
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 MS.MAP,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
TLNE T1,(PM.COR!<<PM.ACD^!PM.DCD>B2>) ;IN CORE OR INDIRECT?
;(IF IT PASSED THIS FAR, LET IT THROUGH)
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 MS.MAP,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.ACD^!PM.DCD>B2!PM.AAB) ;DOES PAGE HAVE ACCESS ALLOWED ON?
JRST PFHNX3 ;YES, JUST USE IT
IORM T3,@[IW MS.MAP,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
PJRST 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,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
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
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 P2,P3 ;NO PAGES TO PAGE OUT ACCUMULATED YET
TLO P4,400000 ;FIRST TIME THROUGH FLAG
;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 T2,.USPFL ;GET PAGE WE LAST PAGED OUT
JRST [SKIPL .USBTS ;A BIG USER?
SKIPA T2,[HLGPNO+1] ;NO, JUST LOOK AT SECTION 0
MOVEI T2,HLGPGS+1 ;RE-START AT TOP PAGE
JRST PFHMK4] ;AND CONTINUE FROM THE TOP
LDB T2,[POINT 5,T2,26] ;GET SECTION NUMBER
LDB T2,[POINT 3,.UPMP+SECTAB(T2),2] ;GET POINTER TYPE OF SECTION
CAIN T2,PM.DCD ;A DIRECT POINTER
JRST PFHMK5 ;YES, TRY IT
PFHMK3: MOVE T2,.USPFL ;GET PAGE NUMBER AGAIN
TRZ T2,HLGPNO ;ROUND DOWN TO BOTTOM OF BAD SECTION
PFHMK4: MOVEM T2,.USPFL ;SET NEW "LAST" CANDIDATE PAGE NUMBER
JRST PFHMK2 ;AND LOOP
PFHMK5: MOVE T2,.USPFL ;PAGE TO CONSIDER
TRC T2,PG.BDY ;STARTING A NEW SECTION?
TRCE T2,PG.BDY ; ..
JUMPGE P4,PFHMK6 ;OR NOT THE FIRST TIME THROUGH?
TLZ P4,400000 ;NOT FIRST TIME NEXT TIME
LDB T1,[POINT 5,T2,26] ;GET SECTION NUMBER
SKIPE T1 ;SECTION ZERO IS DIFFERENT
JRST [IMULI T1,WSBTBL;COMPUTE WHICH WSBTAB TO USE
MOVEI T1,.WSBNZ-WSBTBL(T1)
JRST .+2] ;AND CONTINUE
MOVEI T1,WSBTAB ;SECTION 0 WSBTAB
ANDI T2,PG.BDY ;STARTING PAGE WITHIN SECTION
PUSHJ P,NXTWSP ;GET FIRST PAGE IN THIS SECTION
JRST PFHMK3 ;NONE THERE
JRST PFHMK7 ;SET IF CAN PAGE THIS ONE OUT
PFHMK6: PUSHJ P,NXTWSC ;GET NEXT WORKING SET PAGE
JRST PFHMK3 ;NO MORE IN THIS SECTION
PFHMK7: DPB T2,[POINT 9,.USPFL,35] ;STORE PAGE NUMBER WITHIN SECTION
MOVE T2,.USPFL ;GET EXTENDED PAGE NUMBER
JUMPE T2,PFHMK2 ;NEXT PAGE IF THIS IS REALLY PAGE 0
CAML T2,PFPILB(P) ;IS THIS PAGE BELOW RANGE OF OUR IOWD?
CAMLE T2,PFPILE(P) ;OR ABOVE IT?
JRST PFHMK8 ;NOT WITHIN IOWD-ADDRESSED RANGE
JRST PFHMK1 ;TRY NEXT PAGE (CAN'T SKIP IOWD SINCE COUNTED IN P1)
PFHMK8: CAME T2,PFPJLB(P) ;IS THIS FIRST PAGE OF .JBINT BLOCK?
CAMN T2,PFPJLE(P) ;OR LAST PAGE OF .JBINT?
JRST PFHMK1 ;YES, LEAVE IT ALONE
CAMN T2,PFPBPT(P) ;BREAKPOINT TRAP ADDRESS?
JRST PFHMK1 ;YES, LEAVE IT FOR DDT
CAML T2,PFPPLB(P) ;IS THIS PAGE BELOW RANGE OF PSI VECTOR
CAMLE T2,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
MOVEM T2,.USPFL ;STORE THIS PAGE FOR NEXT TIME THROUGH
CAIE P3,1(T2) ;IS THIS PAGE DIRECTLY BELOW PREVIOUS PAGE?
PUSHJ P,PFHMKO ;NO, OUTPUT ACCUMULATION
SOS P2 ;INCREMENT NUMBER OF PAGES TO PAGE OUT
PUSHJ P,PFGSI ;CHECK FOR A FIT
JRST PFHMK9 ;IT DOES, PAGE OUT ACCUMULATION
MOVE P3,T2 ;NEW LOWEST PAGE
JRST PFHMK1 ;AND LOOP LOOKING FOR MORE PAGES
PFHMK9: MOVE P3,T2 ;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 P2,CPOPJ## ;IF NOTHING TO PAGE OUT, JUST RETURN
PUSHJ P,SAVT## ;SAVE T ACS FOR NXTWS?
MOVE T1,[.PAGIO,,JOBUAL##] ;PAGE UUO ARGUMENT
DMOVE T2,P2 ;NUMBER OF PAGES, LOWEST PAGE
TLO T3,(PG.GAF) ;INDICATE PAGING OUT
PUSHJ P,DOPAGE ;DO THE PAGE UUO
SETZ P2, ;INDICATE NO PAGES ACCUMULATED YET
POPJ P, ;RETURN
PFGSI: PUSHJ P,SAVT## ;SAVE ACS FOR NXTWS?
MOVE T3,PFDPNI(P4) ;GET LAST PAGE NEEDED PLUS ONE
SUB T3,PFDSNI(P4) ;GET NUMBER OF PAGES INCREASE WE NEED
ADD T3,P2 ;MINUS PAGES WE CAN PAGE OUT
PUSHJ P,GSIZI## ;WILL WE FIT NOW?
JRST CPOPJ1## ;STILL NOT
JRST CPOPJ1## ;STILL NOT
POPJ P, ;WE WILL FIT IF WE DO ACCUMULATED PAGEOUT
;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: MOVE T1,PFPILE(P) ;GET UPPER LIMIT OF IOWD-ADDRESSED SPACE
ADJSP P,PFPOFS ;RETURN PFHMKR'S CHECK WORDS TO STACK
JUMPN P2,PFHBR1 ;IF SOMETHING COULD BE PAGED OUT, WORK WITH THAT
MOVE P3,PFDPNI(P4) ;FIRST IN-CORE PAGE
MOVE P2,P3 ;COPY IT
SUB P2,T1 ;PAGES IN IOWD SPACE TO PAGE OUT TO MAKE ROOM
JUMPGE P2,PFHBR5 ;IF NOTHING COULD BE PAGED OUT, NOTHING CAN BE
; PAGED IN. DO WHAT I/O CAN BE DONE
MOVEM T1,PFDPNI(P4) ;SET TO TOP OF IOWD
PFHBR1: 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
PFHBR2: ASH T2,-1 ;HALF QUANTITY
PUSHJ P,GSIZI## ;CAN WE FIT THIS MUCH IN?
JFCL ;NO
JRST PFHBR3 ;DECREMENT AMOUNT WE ARE ASKING FOR
ADD T3,T2 ;IT FITS, TRY FOR SOME MORE
JUMPN T2,PFHBR2 ;AND LOOP
JRST PFHBR4 ;DONE, JOIN COMMON CODE
PFHBR3: SUB T3,T2 ;DOESN'T FIT, TRY A LITTLE LESS
JUMPN T2,PFHBR2 ;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
PFHBR4: 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
PFHBR5: 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
; PJRST PFDOIO ;FALL INTO PFDOIO, DO THE IO 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:
IFN FTXMON,<
HRRZ T1,DEVISN(F) ;SECTION NUMBER FOR I/O
PUSHJ P,STPCS## ;SETUP PCS FOR THAT SECTION
>
HRRZ T1,PFDBAS(P4) ;FIRST WORD TOUCHED BY I/O
ADDM P3,PFDBAS(P4) ;POINT TO ENDING WORD
SKIPGE USRHCU## ;IF SAVE IN PROGRESS,
JRST DOIO3 ;ASSUME COMCON KNOW'S WHAT IT'S DOING
MOVE T2,T1 ;COPY RELATIVE STARTING ADDRESS
ADD T2,P3 ;MAKE RELATIVE ENDING ADDRESS FOR ZRNGE
PUSH P,T1 ;ZRNGE CLOBBERS T1
SKIPE .USWLP ;IF ANY WRITE LOCKED PAGES,
PUSHJ P,ZRNGE## ;MAKE SURE THEY ARE ALL WRITE ENABLED
JFCL ;ALLOW FOR SKIP RETURN
IFN FTXMON,<
HRRZ T1,DEVISN(F) ;GET STARTING SECTION AGAIN
SKIPN T1 ;IF FROM S0,
TLNN T2,-1 ;AND CROSSED A SECTION BOUNDARY
TRNA ;(NSZ OR SINGLE-SECTION IS OK)
S0JRST ADRERR## ;COMPLAIN ABOUT I/O TO THE ACS
> ;END IFN FTXMON
POP P,T1 ;RESTORE T1
DOIO3: 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
IFN FTXMON,<
SETZ T1, ;JOBUAL IS IN S0
PUSHJ P,STPCS## ;MAKE SURE DRIVER KNOWS THAT
>
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 information.
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