Trailing-Edge
-
PDP-10 Archives
-
bb-jr93k-bb
-
10,7/mon/lokcon.mac
There are 8 other files named lokcon.mac in the archive. Click here to see a list.
TITLE LOKCON - MODULE FOR LOCKING JOBS IN CORE - V337
SUBTTL J. FLEMMING TS 29-AUG-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
;1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986,1988.
;ALL RIGHTS RESERVED.
.CPYRT<1973,1988>
XP VLOKCN,337 ;PUT VERSION NUMBER IN STORAGE MAP
ENTRY LOKCON ;ENTRY POINT SYMBOL SO LOADER WILL LOAD LOKCON
; IN A LIBRARY SEARCH
LOKCON::;ENTRY POINT SYMBOL TO CAUSE LOADING OF LOKCON
SUBTTL SWAP - USER PROGRAM SWAPPING ROUTINES
;ROUTINE TO MOVE A JOB TO A PREDETERMINED PLACE IN CORE AND LOCK IT THERE
;CALLING SEQUENCE:
; HRRZ AC,JOB NUMBER
; HRL AC,HIGH SEGMENT NUMBER
; MOVSM AC,LOCK
;OR IF LOW SEGMENT ONLY JOB
; HRRZ AC,JOB NUMBER
; MOVEM AC,LOCK
;AND
; MOVEI P1,LOK
; IORM P1,JBTSTS(AC) ;SO SCHEDULAR WON'T RUN THE JOB
;AND
; MOVE AC,DESIRED PROTECTION/RELOCATION FOR HIGH SEGMENT OR JOB IF NONE
; MOVEM AC,LOKREL
; PUSHJ P,WSCHED
;RETURN HERE WHEN JOB (BOTH LOW AND HIGH SEGMENTS) ARE IN PLACE AND LOCKED
;NOTE: LOW SEGMENT GOES
; ABOVE THE HIGH SEGMENT
;
;CALLED FROM SCHED WHEN SWAPPER IS IDLE
LOCK0:: SE1ENT ;LOCK MUST RUN IN SECTION 1, SINCE PAGTAB AND
;MEMTAB SIT IN ANOTHER SECTION (MS.MEM)
PUSHJ P,BPSLST## ;MAKE EVERYTHING ON PAGE QUEUES GO OUT
SKIPE PAGIPQ## ;I/O IN PROGRESS NOW?
POPJ P, ;YES, WAIT UNTIL ITS DONE
PUSHJ P,FLSOPQ## ;FLUSH "OUT" QUEUE - PUT PAGES ON FREE CORE LIST
;HERE WHEN ALL OF THE PAGE QUEUES ARE EMPTY - ALL PAGES ON FREE CORE LIST
MOVE J,LOCK## ;-1 IF SETTING MEMORY OFF LINE
AOJE J,[HLRZ P2,LOKREL##
SKIPN MOFLPG##
JRST LOCK2 ;GO IF NOT SETTING MONITOR MEMORY OFF-LINE
LDB P2,[POINT 14,MEMSIZ##,26]
LDB P3,[POINT 9,SYSSIZ##,26]
SUB P2,P3 ;FORCE EVERYTHING OUT IF SETTING MONITOR MEMORY OFF
JRST LOCK3]
HRRZ J,LOCK## ;SEGMENT NUMBER OF SEGMENT TO BE LOCKED
LOCK1: LDB P2,IMGIN## ;NUMBER OF PAGES IN THE SEGMENT
CAILE J,JOBMAX## ;IS THIS A LOW SEGMENT?
JRST LOCK2
MOVSI T1,(JS.SIP) ;SWAPPING COULD BE IN PROGRESS
TDNE T1,JBTST2##(J) ;IS IT?
POPJ P, ;YES,WAIT UNTIL SWAPPING I/O IS DONE
LDB T1,NFYPGS##
ADD P2,T1 ;YES, ACCOUNT FOR THE UPMP SIZE
LDB T1,NZSSCN## ;AND NZS MAPS
ADD P2,T1
LOCK2: HRRZ P3,LOKREL## ;PAGE NUMBER OF STARTING PAGE THIS SEGMENT
; IS TO BE LOCKED IN
TRZE P3,PAGLOK## ;IS THIS PAGE FORMAT LOCK?
JRST LOCK31 ;YES, MUST PROCESS DIFFERENTLY
LOCK3: SKIPGE T1,@[IW MS.MEM,PAGTAB(P3)] ;PAGE ON THE FREE CORE LIST?
JRST LOCK14 ;YES, LOOP ON
TLNE T1,IPCBIT ;AN IPCF PAGE?
JRST DELIPP ;YES, SWAP IT OUT
SKIPGE LOCK## ;SETTING MEMORY OFF-LINE?
TLNN T1,LKBITS ;YES, IGNORE MONITOR AND NON-EXISTANT PAGES
SKIPA T1,P3 ;NO, PAGE NUMBER TO T1
JRST LOCK14 ;LOOK AT THE NEXT PAGE
PUSHJ P,CPIASP## ;FIND THE SEGMENT NUMBER OF THE SEGMENT
; CONTAINING THIS PAGE
STOPCD .,STOP,SNF, ;++SEGMENT NOT FOUND
MOVMS J
LOCK4: HRRZ T1,LOCK## ;T1 = SEGMENT NUMBER OF SEGMENT BEING LOCKED
CAIN T1,(J) ;PAGE FOUND CONTAINED IN SEGMENT BEING LOCKED?
JRST LOCK14 ;YES, NO ACTION NECESSARY
LOCK5: CAIG J,JOBMAX## ;IS THE SEGMENT CONTAINING THE PAGE WHICH
; MUST BE MOVED A HIGH SEGMENT?
JRST LOCK11 ;NO, JUST SWAP THIS SEGMENT OUT
MOVE P1,JBTSTS##(J) ;P1 = INCORE COUNT FOR THIS HIGH SEGMENT
TLNE P1,SWP ;ALREADY SWAPPING THIS HI SEG OUT?
POPJ P, ;YES, GO AWAY UNTIL THE SWAP COMPLETES
TRNE P1,ICCMSK ;IS THIS A DORMANT OR IDLE HIGH SEGMENT?
JRST LOCK7 ;NO, MUST SWAP OUT THE LOW SEGMENTS SHARING
; IT TO MAKE IT GO AWAY
LOCK6: S0PSHJ FREC4## ;ITS DORMANT OR IDLE - GO DELETE IT FROM CORE
S0JRST FORIDL## ;IDLE WITH NO COPY ON THE DISK - WRITE ENABLED
JRST LOCK0 ;THE SEGMENT HAS BEEN DELETED FROM CORE - TRY AGAIN
LOCK7: MOVE T2,J ;SAVE HIGH SEGMENT NUMBER
MOVE J,HIGHJB## ;FIND A JOB SHARING IT
LOCK8: MOVEI T1,(T2) ;SEGMENT #
PUSHJ P,FNDHSB## ;DOES THIS JOB OWN THIS SEGMENT?
JRST LOCK10 ;NO
SKIPE JBTADR##(J) ;IS JOB IN CORE?
JRST LOCK9 ;YES, GO SEE IF IT CAN BE SWAPPED OUT
MOVE T2,J ;SAVE JOB NUMBER BEFORE CALLING DECCNT
EXCH J,T1 ;J=HIGH SEG BLOCK ADDR T1=JOB
MOVE J,.HBSGN(J) ;AND SEGMENT WORD
S0PSHJ DECCNT## ;MAKE SURE IN-CORE COUNT IS DECREMENTED
JFCL ;ALREADY DECREMENTED OR JUST WENT TO ZERO
HRRZS J ;GET RID OF HIGH SEGMENT FLAGS
JUMPE T1,LOCK6 ;NO MORE JOBS SO SWAP OUT HIGH SEG
EXCH J,T2 ;GET READY TO LOOK AT NEXT JOB
JRST LOCK10 ;GO DO IT
LOCK9: MOVE T1,JBTSTS##(J) ;GET JOB STATUS
TLCE T1,SWP!NSWP ;IS IT LOCKED AND SWAPPED?
TLNE T1,SWP!NSWP ;IF BOTH, SWAPPING IT WON'T HELP
CAIA
JRST LOCK10 ;SO LOOK AT NEXT JOB
TRNE P1,ICCMSK-1 ;IN CORE COUNT = 1?
CAME J,LOCK## ;IF NOT, IS THIS THE JOB WE'RE LOCKING?
JRST LOCK12 ;NO, SWAP OUT THE JOB
LOCK10: SOJG J,LOCK8 ;LOOK AT NEXT JOB
STOPCD .,STOP,SSO, ;++SEGMENT SWAPPED OUT
LOCK11:
IFN FTMP,<
PUSHJ P,ANYRUN## ;RUNNING ON CPU1?
JRST LOCK13 ;YES
>
LOCK12: MOVSI T1,(JS.SIP) ;SWAPPING I/O IN PROGRESS BIT
TDNE T1,JBTST2##(J) ;JOB CURRENTLY BEING SWAPPED?
POPJ P, ;YES, WAIT FOR I/O TO COMPLETE
S0JRST FORCE0## ;NO, SWAP HIM NOW
LOCK13: MOVEM J,SW0JOB## ;TELL CPU1 TO STOP RUNNING THE JOB
POPJ P, ;AND RETURN
LOCK14: AOS P3 ;NEXT PHYSICAL PAGE WHICH MUST BE FREED
SOJG P2,LOCK3 ;LOOP UNTIL ALL NECESSARY PAGES ARE AVAILABLE
SKIPGE T1,LOCK## ;LOCK IS -1 IF SETTING MEMORY OFF
AOJE T1,SETMFL ;GO MOVE THE MONITOR AND SET MEMORY OFF
LOCK15: HRRZ J,LOCK## ;SEGMENT NUMBER OF SEGMENT BEING LOCKED
SKIPN JBTADR##(J) ;IS THIS SEGMENT IN CORE?
SKIPA J,LASLOK## ;NO, GO CAUSE IT TO BE SWAPPED IN
SKIPA T1,LOKREL## ;SWAPPED IN, SEE IF LOCKING PAGES
TLZA J,-1 ;CLEAR LEFT HALF
SKIPA R,JBTADR##(J) ;SET UP R
S0JRST FIT1## ;GO SWAP JOB IN
;ALLOCATE CORE, BLT SEGMENT INTO PLACE, AND LOCK IT
TRNN T1,PAGLOK## ;?
CAILE J,JOBMAX## ;NO, IS IT A HIGH SEGMENT?
JRST LOCK16 ;PAGES OR HS, DON'T NEED TO ADDRESS THE UPMP
CAME J,.CPJOB## ;IS THIS THE CURRENT JOB? IF SO UPMP IS ADDRESSABLE
PUSHJ P,SVEUB## ;MAKE THE UPMP ADDRESSABLE
LOCK16: S0PSHJ ANYACT## ;ANY ACTIVE I/O?
POPJ P, ;YES, TRY AGAIN NEXT CLOCK TICK
HRRZ J,LOCK## ;SEGMENT NUMBER OF SEGMENT BEING LOCKED
PUSHJ P,CLRLOQ ;ALL PAGES AVAILABLE, MOVE LOKCON'S
;QUEUE TO THE FREE QUEUE
MOVEI P1,0 ;P1 = RELATIVE PAGE NUMBER WITHIN THE SEGMENT
; START AT RELATIVE PAGE ZERO
HRRZ P2,LOKREL## ;P2 = DESIRED PHYSICAL PAGE NUMBER
TRNE P2,PAGLOK## ;IF PAGES
JRST LOCK34 ;THEN GO DO THAT
CAILE J,JOBMAX## ;IS THIS SEGMENT A LOW SEGMENT?
JRST LOCK18 ;NO, NEEDN'T WORRY ABOUT MOVING THE UPMP
HRRZ T1,JBTUPM##(J) ;PAGE NUMBER OF UPMP
PUSHJ P,SETMAP
PUSHJ P,SCPAGS## ;FIND LAST PAGE IN PAGTAB CHAIN
HRRZ T2,JBTUPM##(J) ;PAGE NUMBER OF PROCESS TABLE
HRRZ T3,@[IW MS.MEM,PAGTAB(T2)] ;PAGE MAP PAGE
HRRM T3,@[IW MS.MEM,PAGTAB(T1)] ;LINK PAGE MAP PAGE TO THE END
; OF PAGTAB CHAIN
HRRM T1,@[IW MS.MEM,PT2TAB(T3)] ;FIX UP PT2TAB ALSO
HLLZS @[IW MS.MEM,PAGTAB(T2)] ;UNLINK IT FROM PROCESS TABLE CHAIN
HRRZ T1,JBTUPM##(J)
LDB P3,JBYLSA## ;PAGE NUMBER OF FIRST PAGE OF THE JOB
MOVEI M,.UPMVP/PAGSIZ ;TELL FIXMAP TO CALL NXTWSB
CONO PI,PI.OFF ;TURN OFF THE PIS WHILE CONFUSION REIGNS
PUSHJ P,PAGMOV ;MOVE THE UPMP TO THE DESIRED POSITION
SETZ P3, ;(CALLED EVEN IF IN PLACE TO CLEAR P2.LIP)
MOVE T1,P2
HRLI T1,(<PM.DCD>B2+PM.WRT+PM.PUB)
MOVEM T1,.EUPMP+.UMUPT
IFN FTMP,<
TLO T1,(PM.CSH) ;TURN CACHE ON IF FTMP
>
MOVEM T1,.EUPMP+.UMUUP
CAIE P2,(P3) ;WAS THE UPMP EXCHANGED WITH THE FIRST PAGE
; OF THE LOW SEGMENT (PAGE CONTAINING JOB
; DATA AREA)?
JRST LOCK17 ;NO
MOVE T1,.CPMAP##
MOVE T1,.ECKSM/PAGSIZ(T1)
;(PM.CSH OFF ALREADY)
MOVEM T1,.EUPMP+.UMJDT
DPB T1,JBYLSA##
LOCK17: MOVEI T1,UPMPSZ## ;+ SIZE OF THE UPMP IN THE RIGHT HALF
ADDM T1,LOKREL## ;UPDATE LOKREL TO REFLECT THE FACT THAT
; THE UPMP IS IN PLACE AND LOCKED
HLLZS @[IW MS.MEM,PAGTAB(P2)] ;SIGNAL ONLY THIS PAGE IS ALLOCATED
MOVSI T1,LOKPHB ;AND INDICATE THAT THE UPMP IS LOCKED
IORM T1,@[IW MS.MEM,PAGTAB(P2)] ; IN PHYSICAL MEMORY
HRRM P2,JBTUPM##(J) ;STORE THE NEW PAGE NUMBER OF THE UPMP
HRRM P2,@.CPSPT## ;SET UP THE SPT
IFN FTKL10,<TDO P2,[LG.LUB!LG.KPM!LG.IAM]> ;REQUEST LOADING OF UBR, INHIBIT
; ACCOUNTING METER UPDATE
IFN FTKS10,<TLO P2,(SG.LUB)> ;REQUEST LOADING OF UBR
DATAO PAG,P2 ;MAKE THE UPT ADDRESSABLE AND CLEAR THE A.M.
CONO PI,PI.ON ;OK TO TURN ON PIS NOW
HRRZ P2,LOKREL## ;P2 = PHYSICAL PAGE WHERE FIRST PAGE OF THE
; LOW SEGMENT SHOULD GO
LOCK18: LDB P3,IMGIN## ;NUMBER OF PAGES IN THE SEGMENT
CAILE J,JOBMAX##
JRST LOCK20
LDB T1,NFYPGS##
ADDI P3,-UPMPSZ##(T1)
LDB T1,NZSSCN##
ADDI P3,(T1)
SETZM .USSPT
MOVSI P4,400000
LOCK19: PUSHJ P,NXTWSB##
JRST LOCK24
LOCK20: PUSHJ P,ZERSWP## ;CLEAR DISK COPY OF HIGH SEG (BECAUSE MEMTAB
;IS GOING TO GET SCRAMBLED)
MOVE T2,P1
PUSHJ P,SNPAGS##
PUSHJ P,PAGMOV
JFCL ;PAGE WAS IN PLACE
SKIPN T1,P1 ;FIRST TIME?
DPB P2,JBYHSA## ;YES
ADD T1,JBTVAD##(J) ;POINT TO HIGH SEG MAP
MOVSI T2,(PM.NAD) ;GET BITS FOR PAGE
ANDM T2,(T1) ;CLEAR ALL BUT BITS
IORM P2,(T1) ;SET NEW PAGE
JRST LOCK22
LOCK21: CAIN T4,.UPMP+.UMUPT ;IS THIS THE UPT
JRST LOCK23 ;YES, ALREADY DONE
PUSHJ P,PGMOVE
JUMPN P1,LOCK22
MOVE T4,P2
HRLI T4,(<PM.DCD>B2+PM.WRT+PM.PUB)
MOVEM T4,.UPMP+.UMJDT
DPB T4,JBYLSA##
PUSHJ P,NEWMAP ;CLEAR THE AM SO NEW MAPPING IS IN EFFECT
LOCK22: MOVSI T4,LOKPHB ;INDICATE THIS PAGE IS LOCKED IN PHYSICAL MEMORY
SUBI P2,1 ;BACK DOWN TEMPORARILY
SKIPE P1 ;SKIP IF FIRST PAGE OF THE SEGMENT
IORM T4,@[IW MS.MEM,PAGTAB(P2)] ; CONTIGIOUSLY
ADDI P1,1 ;NEXT RELATIVE PAGE WITHIN THE SEGMENT
ADDI P2,2 ;STEP TO NEXT TARGET PAGE, AND BACK UP AGAIN
SOJE P3,LOCK27
CAILE J,JOBMAX##
JRST LOCK20
PUSHJ P,FPNSHS
LOCK23: PUSHJ P,NXTWS3##
LOCK24: MOVEM M,.USTMP ;SAVE ACS FOR FIXMAP
DMOVEM T1,.USTMP+1
MOVEM T3,.USTMP+3
SKIPGE .USBTS ;EXTENDED USER?
SKIPGE .USSPT ;YES, ALREADY DID NZS?
JRST LOCK21 ;YES, STOP ON COUNT EXHAUSTED
TRNN M,<-1^!HLGPNO> ;IS IT A USER PAGE #?
JRST LOCK21 ;NO, JUST CONTINUE THEN
SKIPE T4,.USSPT ;JUST DO S0?
AOJA T4,LOCK25 ;INCREMENT SECTION
PUSH P,M ;SAVE THINGS TO DO FUNNY SPACE LATER
PUSH P,T1
PUSH P,T2
PUSH P,T3 ;..
AOJA T4,LOCK26
LOCK25: CAILE T4,MXSECN ;ANY MORE TO DO?
SETO T4, ;NO, BACK TO S0 FOR FUNNY SPACE (2ND TIME)
LOCK26: MOVEM T4,.USSPT
JUMPGE T4,LOCK19 ;START NEW SECTION UNLESS FUNNY SPACE
POP P,T3
POP P,T2
POP P,T1
POP P,M ;RESTORE FUNNY SPACE VALUES
MOVEI T4,(M) ;RESET THE BYTE POINTER
PUSHJ P,GMPTR##
JRST LOCK21 ;AND CONTINUE
LOCK27: SUBI P2,1 ;BACK DOWN TEMPORARILY
IORM T4,@[IW MS.MEM,PAGTAB(P2)] ;INDICATE LAST PAGE OF SEGMENT
ADDI P2,1 ;UN BACK DOWN TEMPORARILY
MOVSI T1,NSHF!NSWP ;AFTER ALL THAT WORK
IORM T1,JBTSTS##(J) ; MAKE SURE THE SEGMENT DOESN'T SWAP
CAILE J,JOBMAX## ;LOCKING A LOW SEGMENT?
JRST LOCK28 ;NO
MOVE T2,.UPMP+.UMUPM ;PAGE MAP
TLO T2,(PM.PUB+PM.CSH) ;ALWAYS CACHED AND PUBLIC IN SECTION TABLE
MOVEM T2,.UPMP+SECTAB+0 ;STORE AS POINTER TO SECTION 0 PAGE MAP
PUSHJ P,NEWMAP ;ZAP PAGING MEMORY
HRRZS T2 ;JUST PAGE NUMBER
PUSHJ P,LKPSF## ;FIND AND LINK AROUND IT
HLLZS @[IW MS.MEM,PAGTAB(T2)] ;LAST PAGE IN LOW SEGMENT CHAIN
HRRZ T1,JBTUPM##(J) ;PROCESS TABLE
HRRM T2,@[IW MS.MEM,PAGTAB(T1)] ;LINK PAGE MAP ONTO
; PROCESS TABLE CHAIN
HRRM T1,@[IW MS.MEM,PT2TAB(T2)]
LOCK28: HLRZS J,LOCK## ;GET THE SEGMENT NUMBER OF THE LOW SEGMENT
; IF THERE IS ONE LEFT TO BE LOCKED
JUMPE J,LOCK29 ;JUMP IF DONE
HLRZS LOKREL## ;STARTING PAGE NUMBER FOR THE LOW SEGMENT
JRST LOCK1 ;AND GO TRY TO LOCK IT
LOCK29: MOVEI T1,LOK ;SET TO MAKE JOB RUNABLE AGAIN
HRRZ J,LASLOK## ;GET THE JOB NUMBER OF JOB ISSUING LOCK UUO
ANDCAM T1,JBTSTS##(J) ;TURN OFF LOK SO SCHEDULAR WILL RUN THE JOB AGAIN
SETZ T1, ;START AT THE BEGINNING
LOCK30: PUSHJ P,GNXHSB## ;GET NEXT SEGMENT
POPJ P, ;NO MORE
SKIPLE T2,.HBSGN(T1) ;IS THIS A REAL HIGH SEG
TLNN T2,SHRSEG ;WHICH IS SHARABLE?
JRST LOC30A ;SEE ABOUT NON-SHARABLE HIGH SEGS
HRRZS T2 ;CLEAR JUNK IN LEFT HALF
SKIPE JBTADR##(T2) ;IS THIS HIGH SEG IN CORE?
JRST LOCK30 ;YES, JUST LOOP ON TO NEXT
MOVSI T3,SWP ;DON'T LET SCHEDULAR RUN JOB
IORM T3,JBTSTS##(J) ;UNTIL ALL HIGH SEGS IN CORE
POPJ P, ;RETURN
LOC30A: JUMPLE T2,LOCK30 ;IF NOT A REAL HIGH SEG AT ALL
MOVSI T3,LOKSEG ;MUST TURN ON LOKSEG...
IORM T3,.HBSGN(T1) ;FOR NON-SHARABLE HIGH SEGS HERE
JRST LOCK30 ;AS NO ONE ELSE WILL
;HERE FOR LOCK SPECIFIED PAGES FORMAT
LOCK31: SKIPN JBTADR##(J) ;IS JOB IN CORE?
S0JRST FIT1## ;NO, PUT IT THERE
PUSHJ P,SVEUB## ;JOB MUST BE MAPPABLE
MOVEI T1,JS.ASA ;NOW THAT JOB IS BLOCKED, SET ASA
CAME J,.CPJOB## ;USER'S ACS NOT DUMPED YET IF STILL CURRENT
IORM T1,JBTSTS##(J)
MOVE M,.JDAT##+JOBDAC##+M ;LOAD USER UUO M
PUSHJ P,FSTPAG## ;POINT TO START OF ARG LST
PUSH P,.JDAT+JOBDAC##+P2 ;UUO LVL P2 HAS # OF ARGS
SETZ P2, ;COUNT OF CONTIG PAGES NEEDED
LOCK32: PUSHJ P,NXTLPG## ;GET NEXT PAGE
JUMPL T1,LOCK33 ;NO MORE
TRNN T1,-1 ;SPECIFIC PAGE REQUESTED?
AOJA P2,LOCK33 ;NO, CHECK IT LATER
SSX T1,MS.MEM ;POINT TO PAGTAB SECTION
.CREF FREPAG ;SEE IF IT'S FREE
SKIPGE PAGTAB(T1) ;IS IT?
JRST LOCK33 ;YES, CHECK MORE
PUSHJ P,CPIASP## ;IS PAGE IN THIS JOB?
XCT SNF ;..NOT FOUND
MOVMS J ;DON'T CARE IF IT'S THE UPT
CAME J,.USJOB ;IS IT US?
JRST LOCK5 ;NO, SWAP HIM OUT
LOCK33: SOSLE (P) ;MORE ARGS?
JRST LOCK32 ;YES
POP P,(P) ;FIX STACK
JUMPE P2,LOCK15 ;NO MORE PAGES TO CHECK (ONLY SPECIFICS)
JRST LOCK3 ;CHECK CONTIG PAGES
;HERE TO COMPLETE LOCK SPECIFIED PAGES WHEN ALL PAGES ARE ON THE FREE LIST
;OR ARE PART OF THE JOB BEING LOCKED.
LOCK34: MOVEI T1,PAGLOK## ;CLEAR BIT
ANDCAM T1,LOKREL##
PUSHJ P,FSTPAG## ;M LOADED FROM PREVIOUS PATH THROUGH LOCK31
PUSH P,.JDAT+JOBDAC##+P2 ;# OF ARGS
HRRZ P1,JBTUPM##(J) ;SET P1 NON-ZERO; REMEMBER UPT PAGE
LOCK35: PUSHJ P,NXTLPG## ;GET NEXT
JUMPL T1,LOCK38 ;UNLOCK ARG
MOVE T2,T1 ;SAVE ARG
TRNN T1,-1 ;SPECIFIC PAGE?
AOSA T1,LOKREL## ;NO, GET NEXT PHYS PAGE AVAILABLE
TLZA T1,-1 ;CLEAR LEFT HALF
SOSA P2,T1 ;GET REAL TARGET PAGE
MOVE P2,T1 ;AND REAL SOURCE PAGE
HLRZ T1,T2 ;GET VIRT PAGE INVOLVED
ANDI T1,HLGPGS ;MASK OUT BITS
PUSHJ P,GTPME## ;GET ENTRY
PUSH P,T1 ;SAVE VIRT PAGE #
MOVE T1,T2 ;PAGE THIS PAGE IS AT NOW
TLZ T1,(PM.NAD) ;CLEAR BITS
CAIN P1,(P2) ;EXCHANGING WITH THE UPT?
CONO PI,PI.OFF ;YES, TURN OFF THE PIS
PUSHJ P,PAGMOV ;MOVE THE PAGE
JRST LOCK37 ;WAS ALREADY IN PLACE
CAIE P1,(P2) ;EXCHANGE WITH THE UPT?
JRST LOCK36 ;NO
HRRM P2,JBTUPM##(J) ;UPDATE JBTUPM
HRRM P2,@.CPSPT## ;SET UP THE SPT
HRRZ T1,P2 ;GET PAGE NUMBER OF NEW UPT
IFN FTKL10,<TDO T1,[LG.LUB!LG.KPM!LG.IAM]> ;REQUEST LOADING OF UBR, INHIBIT
; ACCOUNTING METER UPDATE
IFN FTKS10,<TLO T1,(SG.LUB)> ;REQUEST LOADING OF UBR
DATAO PAG,T1 ;MAKE THE UPT ADDRESSABLE AND CLEAR THE A.M.
CONO PI,PI.ON ;TURN ON PIS AGAIN
JRST LOCK37 ;CONTINUE
LOCK36: MOVE T1,(P) ;GET VIRT PAGE #
PUSHJ P,GTPME## ;GET PAGE
AND T2,[PM.NAD] ;KEEP BITS
IOR T2,P2 ;PAGE # OF NEW PAGE
TLO T2,(PM.LOK) ;TURN ON "LOCKED PAGE" BIT
MOVEM T2,(T4) ;UPDATE MAP POINTER
LDB T1,JBYLSA## ;GET START OF LOW SEGMENT
CAIE T1,(P2) ;TARGET PAGE WAS FIRST PAGE OF LOW SEG?
JRST LOCK37 ;NO
SETZ T1, ;GET FIRST PAGE OF JOB
PUSHJ P,GTPME## ;GET ENTRY
TLZ T2,(PM.CSH) ;TURN OFF CACHE
MOVEM T2,.UPMP+.UMJDT ;SET NEW .JDAT POINTER
DPB T2,JBYLSA## ;AND NEW FIRST PAGE OF JOB
LOCK37: MOVE T2,P2 ;PHYSICAL PAGE
PUSHJ P,LKPSF## ;REMOVE PAGE FROM JOB'S REGULAR CHAIN
EXCH T2,.USLPG ;PUT ON CHAIN OF LOCKED PAGES JOB HAS
SSX P2,MS.MEM
HRRM T2,PAGTAB(P2) ;LINK REST OF CHAIN TO US
SKIPE T2 ;AND IF THERE WAS A REST OF CHAIN
HRRM P2,@[IW MS.MEM,PT2TAB(T2)] ;LINK US TO IT
POP P,T1 ;RESTORE VIRT PAGE # AGAIN
DPB T1,NVPNP2## ;STORE WHAT VIRT PAGE THIS PHYS PAGE MAPS TO
HLLZS PT2TAB(P2)
PUSHJ P,TSWST## ;GET WORKING SET BIT
STOPCD .+1,DEBUG,PSC, ;++PAGE SHOULD BE IN CORE
ANDCAM T2,(T4) ;PAGE NOT IN WORKING SET
.CREF IMGIN ;AND DECREMENT # OF WORKING SET PAGES
SOS JBTIMI##(J)
LOCK38: SOSLE (P) ;MORE ARGS?
JRST LOCK35 ;YES
MOVEI T1,LOK+JS.ASA ;SET TO MAKE JOB RUNABLE AGAIN
ANDCAM T1,JBTSTS##(J) ;TURN OFF LOK SO SCHEDULAR WILL RUN THE JOB AGAIN
SETZM LOCK## ;CLEAR LOCKING FLAG
JRST TPOPJ## ;FIX STACK AND RETURN
;HERE WHEN AN IPCF PAGE WAS IN THE ROAD
DELIPP: TLNE T1,LOKPHB ;TURNED ON WHILE SWAPPING I/O IS IN PROGRESS
; SO WE DON'T TRY TO SWAP OUT THE PAGE TWICE
POPJ P, ;I/O IN PROGRESS, WAIT FOR IT TO COMPLETE
HRRZ T2,P3 ;ARGUMENT FOR IPCSSP
PUSHJ P,IPCSSP## ;GET SWAPPING SPACE
S0PSHJ MAKSLE## ;MAKE THE SWPLST ENTRY
HRRZ T2,P3 ;RESTORE PHYSICAL PAGE NUMBER
S0PSHJ LOKIPC## ;FIND ENTRY IN AN IPCF QUEUE AND REPLACE PHYSICAL
; PAGE WITH DISK ADDRESS
STOPCD .,STOP,IPU ;++IPCF PAGE UNOWNED
S0JRST SQOUT## ;START THE PAGING IO
; WAIT FOR THE PAGE TO GO AWAY
;HERE TO MOVE THE MONITOR IF NECESSARY
SETMFL: SKIPN P4,MOFLPG## ;ANY OF THE PAGES BEING SET OFF CONTAIN MONITOR CODE?
JRST SETM17 ;NO, THEN THIS IS EASY
;FIRST, MOVE ANY PAGES WHICH ARE REALLY MONITOR PAGES BUT DON'T
; APPEAR IN ANY MAP (UNMAPPED PHYSICAL PAGES)
PUSHJ P,MOVUMP ;MOVE UNMAPPED PHYSICAL PAGES
SKIPN P4,MOFLPG## ;ANY PAGES LEFT OVER?
JRST SETM17 ;NO
;NEXT, MOVE ANY PAGES WHICH MUST REMAIN PHYSICALLY CONTIGUOUS
SETMF1: MOVEI T1,0 ;STARTING AT PAGE 0
LDB T2,[POINT 14,MEMSIZ##,26] ;LOOK TO THE TOP OF CORE
SETMF2: MOVE T3,@[IW MS.MEM,PAGTAB(T1)] ;CURRENT PAGTAB ENTRY
TLNE T3,CONTGB ;MUST THIS RANGE OF PAGES REMAIN PHYSICALLY CONTIGUOUS?
JRST SETMF4 ;YES
SETMF3: HRRZS T1 ;CLEAR LEFT HALF JUNK - USED AS A TEMP BELOW
CAIGE T1,-1(T2) ;REACHED TOP OF MEMORY?
AOJA T1,SETMF2 ;NO, LOOK ON
JRST SETM12 ;YES, ALL PAGES HAVE BEEN MOVED
;FOUND FIRST, NOW DETERMINE THE RANGE
SETMF4: HRLS T1 ;FIRST PAGE SEEN IN THE LEFT HALF
SETMF5: CAIN T2,1(T1) ;AT THE TOP OF MEMORY?
AOJA T1,SETMF6 ;YES, HIGHEST PAGE + 1 IN THE RANGE
HRRZ T3,T1 ;INDEX INTO PAGTAB
MOVE T3,@[IW MS.MEM,PAGTAB(T3)] ;NEXT PAGTAB ENTRY
TLNE T3,CONTGB ;ALSO A PAGE WHICH MUST REMAIN PHYSICALLY CONTIGUOUS?
AOJA T1,SETMF5 ;YES
;HERE WHEN THE RANGE OF PAGES HAS BEEN DETERMINED, SEE IF THEY OVERLAP THE
; RANGE OF PAGES BEING SET OFF-LINE
SETMF6: HRRZ T3,LOKREL## ;FIRST PAGE BEING SET OFF-LINE
HLRZ T4,LOKREL## ;NUMBER OF PAGES BEING SET OFF-LINE
ADDI T4,(T3) ;HIGHEST PAGE + 1 BEING SET OFF-LINE
CAIL T3,(T1) ;BOTTOM OF MOFFL .LE. TOP OF CONTIGUOUS PAGES?
JRST SETMF3 ;YES, THEY DON'T OVERLAP SO LOOK ON
MOVSS T1 ;BOTTOM PAGE IN CONTIGUOUS PAGE RANGE
CAIG T4,(T1) ;LOWEST PAGE ABOVE RANGE BEING SET OFF-LINE?
JRST SETM12 ;YES, DONE SINCE ABOVE REGION BEING SET OFF
;HERE TO COMPUTE THE NUMBER OF CONTIGUOUS PAGES WHICH OVERLAP THE MEMORY
;OFF-LINE RANGE
HRRZ P1,T1 ;LOWEST CONTIGUOUS PAGE
HLRZ P2,T1 ;HIGHEST CONTIGUOUS PAGE
SETMF7: CAIL P1,(T3) ;BELOW RANGE BEING SET OFF-LINE?
CAIL P1,(T4) ;OR ABOVE RANGE BEING SET OFF-LINE?
CAIA ;NOT IN OFF-LINE RANGE
SOS P4 ;DECREMENT NUMBER OF MONITOR PAGES BEING SET OFF
CAIE P1,-1(P2) ;LOOKED AT THE ENTIRE RANGE OF CONTIGUOUS PAGES
AOJA P1,SETMF7 ;NO, LOOK AT THE NEXT PAGE
HLRZ P1,T1 ;HIGHEST CONTIGUOUS PAGE
SUBI P1,(T1) ;NUMBER OF PAGES TO MOVE (MUST MOVE THEM ALL
; EVEN IF ONLY A FEW OVERLAP SINCE PHYSICAL
; CONTIGUITY MUST BE MAINTAINED)
LDB P2,[POINT 14,SYSSIZ##,26] ;STARTING AT SYSSIZ
SETMF8: MOVEI P3,0 ;NUMBER OF CONTIGUOUS FREE PAGES SEEN
SETMF9: HRRZ T2,P2 ;MAKE AN INDEX INTO PAGTAB
CAML T2,T3 ;ABOVE RANGE BEING SET OFF-LINE?
CAML T2,T4 ;NO, WITHIN RANGE BEING SET OFF-LINE?
SKIPL @[IW MS.MEM,PAGTAB(T2)] ;NOT WITHIN RANGE, IS THE PAGE FREE?
JRST SETM11 ;NO, LOOK HIGHER UP
TLNN P2,-1 ;FIRST PAGE OF THE HOLE?
HRLS P2 ;YES, REMEMBER START OF HOLE
AOS P3 ;NUMBER OF PAGES SEEN SO FAR IN THIS HOLE
CAIGE P3,(P1) ;ENOUGH PAGES SEEN TO MOVE THE CONTIGUOUS PAGES?
AOJA P2,SETMF9 ;NO, SEE IF THERE ARE MORE PAGES AVAILABLE
;HERE WHEN ENOUGH FREE PAGES HAVE BEEN FOUND TO MOVE THE CONTIGUOUS PAGES
; T1 = TOP,,BOTTOM OF CONTIGUOUS PAGES, P1 = NUMBER OF PAGES TO MOVE,
; P2 = BOTTOM,,TOP OF HOLE
PUSH P,P1 ;SAVE COUNT (NEED P1 FOR PAGFRE)
MOVEI P1,0 ;NEVER A PREDECESSOR IN PAGFRE
HLRZS P2 ;STARTING DESTINATION PAGE
HRRZ P3,T1 ;STARTING SOURCE PAGE
SETM10: HRRZ T1,P3 ;NEXT SOURCE PAGE
PUSHJ P,PAGFRE ;MOVE THE PAGE AND FIX PAGTAB
STOPCD .,STOP,CMP ;++CAN'T MOVE PAGE
PUSHJ P,ADJMAP ;ADJUST EXEC MAP TO ACCOUNT FOR MOVED PAGE
AOS P2 ;NEXT DESTINATION PAGE
SOSLE (P) ;ALL THE CONTIGUOUS PAGES BEEN MOVED?
AOJA P3,SETM10 ;NO, MOVE THE NEXT SOURCE PAGE
POP P,(P) ;POP OFF JUNK
JRST SETMF1 ;THESE PAGES HAVE BEEN MOVED, LOOK FOR MORE
SETM11: HRRZS P2 ;NEXT FREE PAGE IS THE BEGINNING OF A HOLE
LDB T2,[POINT 14,MEMSIZ##,26]
CAIE P2,-1(T2) ;REACHED THE TOP OF MEMORY
AOJA P2,SETMF8 ;NO, LOOK FOR THE NEXT HOLE
STOPCD .,STOP,NCC ;++NOT ENOUGH CONTIGUOUS FREE CORE
SETM12: JUMPE P4,SETM17 ;GO IF ALL PAGES SET OFF WERE CONTIGUOUS
MOVEI P1,0 ;FOR PAGFRE
LDB P2,[POINT 14,MEMSIZ##,26]
HLRZ P3,LOKREL## ;NUMBER OF PAGES TO BE SET OFF
MOVNS P3 ;MAKE IT NEGATIVE
HRL P3,LOKREL## ;STARTING PAGE NUMBER
MOVSS P3 ;MAKE AN AOBJN POINTER
SETM13: HRRZ T1,P3 ;COPY PAGE NUMBER
MOVE T1,@[IW MS.MEM,PAGTAB(T1)] ;GET PAGTAB ENTRY FOR THIS PAGE
TLNE T1,MONTRB ;DOES THIS PAGE CONTAIN MONITOR CODE?
JRST SETM14 ;YES
AOBJN P3,SETM13 ;NO, LOOK AT THE NEXT PAGE
STOPCD .,STOP,MMR, ;++MOVING MONITOR PAGE NOT REQUIRED
;HERE WHEN A MONITOR PAGE HAS BEEN FOUND WITHIN THE RANGE BEING SET
; OFF-LINE, MOVE THE PAGE TO THE HIGHEST POSSIBLE FREE PAGE WHICH DOES
; NOT OVERLAP THE PAGES BEING SET OFF-LINE. THIS TENDS TO KEEP THE MONITOR
; AS HIGH IN CORE AS POSSIBLE SO THAT MORE SPACE IS AVAILABLE FOR
; LOCKING BELOW 112K AND HELPS TO KEEP THE MONITOR FROM BEING WRITTEN
; INTO WITH AN ABSOLUTE ADDRESS WHICH CAN ONLY BE DONE IF ITS BELOW 112K
SETM14: HRRZ T1,LOKREL## ;LOWEST PAGE BEING SET OFF LINE
HLRZ T2,LOKREL## ;NUMBER OF PAGES BEING SET OFF LINE
ADDI T2,-1(T1) ;HIGHEST PAGE BEING SET OFF LINE
SUBI P2,1 ;CANDIDATE FOR WHERE TO MOVE THIS PAGE
CAIL P2,(T1) ;IS CANDIDATE BELOW FIRST PAGE BEING SET OFF?
CAILE P2,(T2) ;OR ABOVE LAST BEING SET OFF?
SKIPL @[IW MS.MEM,PAGTAB(P2)] ;YES, IS THE CANDIDATE PAGE FREE?
; IF NOT, IT MUST CONTAIN A PAGE OF THE MONITOR
JRST SETM14 ;NO, LOOK AT THE NEXT CANDIDATE
HRRZ T1,P3 ;SOURCE PAGE
PUSHJ P,PAGFRE ;MOVE THE PAGE
STOPCD .,STOP,FPN, ;++FREE PAGE NOT FOUND
PUSHJ P,ADJMAP ;ADJUST EXEC MAP TO ACCOUNT FOR MOVED PAGE
HRRZ T1,P3 ;SOURCE PAGE AGAIN
SETZ J, ;CLEAR J (FIRST TIME)
SETM15: PUSHJ P,CKHMAP## ;IS IT SOME HIGH SEGS MAP?
JRST SETM16 ;YES
HRRM P2,JBTUPM##(J) ;STORE NEW MAP (SOMEONE ELSE WILL DO DATAO PAG)
JRST SETM15 ;CHECK FOR OTHER MAPS THIS PAGE
SETM16: SOJLE P4,SETM17 ;JUMP IF WE'VE MOVED THE LAST PAGE
SKIPLE .CPHTM## ;ONCE/SECOND TIME CREEPING UP ON US?
JRST SETM13 ;NOT YET, GO TWIDDLE SOME MORE PAGES
MOVEM P4,MOFLPG## ;SAVE NEW NUMBER OF PAGES TO MOVE
POPJ P, ;DO ONCE/SECOND CODE (POKE DTE'S)
;HERE WHEN ALL PAGES TO BE SET OFF LINE ARE FREE AND ANY MONITOR
; PAGES WHICH NEEDED TO BE HAVE BEEN MOVED
SETM17: HRRZ T1,LOKREL## ;FIRST PAGE TO BE SET OFF LINE
IDIVI T1,^D36 ;BIT POSITION AND WORD NUMBER WITHIN NXMTAB
; CORESPONDING TO THE FIRST PAGE SET OFF
MOVE T2,BITTBL##(T2) ;BIT MASK CORRESPONDING TO BIT POSITION
HLRZ T3,LOKREL## ;NUMBER OF PAGES TO SET OFF
SETM18: IORM T2,NXMTAB##(T1) ;MAKE THE PAGE APPEAR TO BE NON-EXISTANT
ROT T2,-1 ;NEXT BIT POSITION IN NXMTAB
SKIPGE T2 ;PASSED A WORD BOUNDARY?
ADDI T1,1 ;YES, BUMP TO THE NEXT WORD IN NXMTAB
SOJG T3,SETM18 ;MARK ALL PAGES IN THE REQUEST AS OFF LINE
MOVE T1,BOOTVA## ;GET VIRTUAL ADDRESS OF BOOTSTRAP
MAP T1,(T1) ;GET (POSSIBLY) NEW PHYSICAL ADDRESS
TLZ T1,(MP.NAD) ;CLEAR NON-ADDRESS BITS
MOVEM T1,BOOTPA ;(MAYBE) RESET PHYSICAL ADDRESS OF BOOTSTRAP
SETZM LOCK## ;INDICATE SUCCESS
MOVEI T1,LOK ;ALLOW JOB TO RUN AND/OR COMMAND TO COMPLETE
HRRZS J,LASLOK## ;JOB NUMBER OF JOB SETTING MEMORY OFF
ANDCAM T1,JBTSTS##(J) ;CLEAR THE BIT
PJRST CPINXF## ;FIXUP PAGTAB, CORTAL, BIGHOL, CORMAX, MAXMAX, ETC.
;ROUTINE TO MOVE UNMAPPED PHYSICAL PAGES
;CALLS WHOEVER USES UNMAPPED PHYSICAL MEMORY WITH:
; P1/ FIRST PAGE BEING SET OFFLINE
; P2/ LAST PAGE BEING SET OFFLINE
;IF THEY HAVE A PAGE IN THAT RANGE THEY SHOULD CALL MOVPAG
;TO MOVE THE PAGE.
MOVUMP: HRRZ P1,LOKREL## ;GET FIRST PAGE TO BE SET OFFLINE
HLRZ P2,LOKREL## ;GET NUMBER OF PAGES BEING SET OFFLINE
ADDI P2,-1(P1) ;P1 HAS FIRST PAGE GOING OFFLINE, P2 HAS LAST
MOVSI P3,-MOVTBL ;-VE LENGTH OF TABLE
JUMPE P3,CPOPJ## ;OF COURSE, THERE MIGHT NOT BE ANYONE!
PUSHJ P,@MOVTAB(P3) ;CALL A ROUTINE
JFCL ;HANDLE SILLINESS ON CALLEE'S PART
AOBJN P3,.-2 ;LOOP FOR ALL
POPJ P, ;RETURN
;TABLE OF WHO TO CALL TO MOVE UNMAPPED PHYSICAL PAGES
MOVTAB:
IFN FTDECNET,<
IFIW DCNMOV## ;DECnet NAME/ADDRESS MAP PAGES
>; END IFN FTDECNET
;IF YOU HAVE SOME UNMAPPED PAGES TO MOVE, YOU TOO CAN ADD AN ENTRY
;TO THIS TABLE
MOVTBL==.-MOVTAB ;LENGTH OF TABLE
;ROUTINE TO MOVE A PAGE BEING SET OFFLINE
;CALL WITH NUMBER OF PAGE BEING SET OFFLINE IN T1, WILL
;MOVE THE PAGE SOMEPLACE OUT OF THE RANGE AND RETURN THE
;NUMBER OF THE NEW PAGE IN T1.
MOVPAG::HRRZ T2,LOKREL## ;GET LOWEST PAGE BEING SET OFFLINE
HLRZ T3,LOKREL## ;GET NUMBER OF PAGES BEING SET OFFLINE
ADDI T3,-1(T2) ;GET FIRST PAGE IN T2, LAST PAGE IN T3
CAML T1,T2 ;SUSPECT PAGE IN RANGE OF PAGES GOING OFFLINE?
CAMLE T1,T3 ;...
STOPCD .,STOP,SMP, ;++SHOULDN'T MOVE PAGE
PUSHJ P,SAVE2## ;FREE UP THE AC'S WE'LL NEED
HRRZ P2,CORLST## ;GET END OF PAGTAB
SUBI P2,PAGTAB ;COMPUTE HIGHEST OFFSET
MOVPG1: CAML P2,T2 ;THIS PAGE IN RANGE BEING SET OFFLINE?
CAMLE P2,T3 ;...
SKIPL @[IW MS.MEM,PAGTAB(P2)] ;NOT IN RANGE, IS PAGE FREE?
SOJG P2,MOVPG1 ;NO, OR IN RANGE, KEEP LOOKING
SKIPN P2 ;DID WE FIND A PAGE?
XCT NCC ;++NOT ENOUGH CONTIGUOUS FREE CORE
PUSH P,@[IW MS.MEM,PAGTAB(T1)] ;SAVE PAGE DESCRIPTOR BITS
MOVEI P1,0 ;NO PREDECESSOR FOR PAGFRE
PUSHJ P,PAGFRE ;MOVE THE PAGE
XCT CMP ;++CAN'T MOVE PAGE
POP P,T1 ;RESTORE PAGE DESCRIPTOR BITS
HLLM T1,@[IW MS.MEM,PAGTAB(P2)] ;SET BITS FOR NEW PAGE
SOSGE MOFLPG## ;DECREASE COUNT OF PAGES BEING SET OFFLINE
STOPCD .,STOP,MCW, ;++MOFLPG COUNT WRONG
HRRZ T1,P2 ;GET PAGE NUMBER
POPJ P, ;RETURN
;HERE WITH SOURCE PAGE IN RH(P3), DESTINATION PAGE IN P2, FIND THE
; SOURCE PAGE IN THE EXEC MAP AND MAP THE DESTINATION PAGE THROUGH THAT
; MAP SLOT
ADJMAP: MOVE T1,MONVFF## ;1ST VIRTUAL ADDRESS ABOVE MONITOR
SUBI T1,CSBORG## ;NUMBER OF WORDS (BOTTOM OF HISEG)
LSH T1,W2PLSH ;NUMBER OF PAGES TO WORRY ABOUT
MOVE T2,[POINT 36,CSBORG##/PAGSIZ]
ADD T2,.CPMAP##
ADJMP1: ILDB T3,T2 ;GET THE NEXT MAP ENTRY
TLZ T3,(PM.NAD) ;CLEAR ACCESS BITS
CAIN T3,(P3) ;IS THIS THE PAGE WHICH WAS JUST MOVED?
JRST ADJMP8 ;YES
SOJG T1,ADJMP1 ;LOOP OVER ALL OF THE MONITORS PAGES
HRROI T1,ADJSMP ;SUBROUTINE TO CALL TO SEE IF ITS IN SOME OTHER
PUSHJ P,CPUAPP## ; CPU'S SECTION TABLE. CHECK.
SKIPE T1 ;WAS IT FOUND IN SOME OTHER CPU'S SECTION MAP?
PUSHJ P,ADJMP3 ;YES, STORE THE CORRECT NUMBER THERE AND LOOK HERE AS WELL
MOVE T1,.CPEPT## ;PAGE MAY BE IN A NON-ZERO SECTION
ADDI T1,(MS.FMD) ;START AT SECTION 2
ADJMP2: SKIPN T2,SECTAB(T1) ;SECTION EXIST?
JRST ADJMP7 ;NO
MOVE T3,.CPMAP## ;ADDRESS OF OUR MAP
MOVEM T2,.EUPMP/PAGSIZ(T3) ;MAKE THE SECTION MAP ADDRESSABLE
TLZ T2,(PM.NAD) ;CLEAR ACCESS BITS
CAIE T2,(P3) ;IS THIS THE PAGE BEING SET OFF-LINE?
JRST ADJMP4 ;NO
ADJMP3: MOVSI T2,(POINT 36,0,35) ;YES, SECTION MAP IS BEING SET OFF-LINE
HRRI T2,SECTAB(T1) ;BYTE POINTER TO THE SLOT IN THE SECTION TABLE
JRST ADJMP8 ;REMAP THE PAGE
ADJMP4: PUSHJ P,NEWMAP ;TO LOOK AT THE SECTION MAP
MOVE T2,[POINT 36,.EUPMP] ;BYTE POINTER TO THE SECTION MAP
MOVEI T3,^D512 ;512 PAGES/SECTION
ADJMP5: ILDB T4,T2 ;NEXT ENTRY IN THE SECTION MAP
LDB T4,[POINT 3,T4,2] ;POINTER TYPE
CAIE T4,PM.DCD ;IGNORE ANYTHING EXCEPT DIRECT POINTERS
JRST ADJMP6 ; ..
LDB T4,T2 ;GET POINTER BACK AGAIN
TLZ T4,(PM.NAD) ;CLEAR ACCESS BITS
CAIN T4,(P3) ;PAGE THATS BEING SET OFF-LINE?
JRST ADJMP8 ;YES
ADJMP6: SOJG T3,ADJMP5 ;NO, LOOP OVER THE ENTIRE SECTION
ADJMP7: MOVE T3,.CPEPT## ;ADDRESS OF OUR PROCESS TABLE
CAIGE T1,MXSECN-1(T3) ;LOOKED AT ALL SECTIONS? (SECTION 37 IS SPECIAL)
AOJA T1,ADJMP2 ;NO, LOOK AT THE NEXT ONE
STOPCD .,STOP,MPN, ;++MONITOR PAGE NOT FOUND
;HERE WITH THE BYTE POINTER TO THE EXEC MAP SLOT IN T2
ADJMP8: LDB T1,T2 ;GET THE CURRENT CONTENTS OF THE MAP SLOT
AND T1,[-1,,760000] ;GET THE ACCESS BITS
ADDI T1,(P2) ;NEW PAGE NUMBER PLUS ACCESS BITS
DPB T1,T2 ;STORE NEW PHYSICAL PAGE NUMBER
PJRST NEWMAP ;CAUSE NEW MAPPING TO BE IN EFFECT SINCE
; PAGTAB MAY HAVE BEEN MOVED
;SUBROUTINE TO SEE IF THE SOURCE PAGE IS IN SOME OTHER CPU'S SECTION MAP
; RH(P3) IS THE SOURCE PAGE
;CALL:
; HRROI T1,ADJSMP
; PUSHJ P,ADJSMP
;RETURNS WITH T1=0 IF NOT IN A SECTION MAP, T1=POINTER TO SLOT IF IT IS
ADJSMP: JUMPG T1,CPOPJ## ;EXIT IF PAGE ALREADY FOUND
MOVE T1,.CPEPT##-.CPCDB##(P1) ;THIS CPU'S EPT
ADDI T1,(MS.FMD) ;START AT SECTION 2
ADJSM1: SKIPN T2,SECTAB(T1) ;SECTION POINTER
JRST ADJSM2 ;NON-EXISTANT
TLZ T2,(PM.NAD) ;ISOLATE PHYSICAL PAGE NUMBER
CAIN T2,(P3) ;SAME AS SOURCE PAGE?
POPJ P, ;YES, FOUND RETURN (T1 POSITIVE)
ADJSM2: MOVE T2,.CPEPT##-.CPCDB##(P1) ;ADDRESS OF THIS CPU'S EPT
CAIGE T1,MXSECN-1(T2) ;LOOKED AT ALL SECTIONS? (SECTION 37 IS SPECIAL)
AOJA T1,ADJSM1 ;NO, KEEP LOOKING
SETZ T1, ;INDICATE NOT FOUND
POPJ P, ;AND RETURN
;SUBROUTINE TO SEE IF TARGET PAGE IS ON THE FREE CORE LIST AND
; EXCHANGE IT WITH THE CURRENT PAGE IF SO
;ENTER WITH T1= CURRENT PAGE WHERE JOB IS
; ENTER P2= PAGE WE WANT TO PUT JOB AT
;EXIT CPOPJ1 IF THE TARGET PAGE IS ON THE FREE CORE LIST AND THE
; EXCHANGE HAS TAKEN PLACE
PAGFRE: SKIPL @[IW MS.MEM,PAGTAB(P2)] ;DOES PAGE SAY IT'S FREE?
POPJ P, ;NO
HRRZ T3,@[IW MS.MEM,PT2TAB(P2)] ;GET PREDECESSOR
IFN FTXMON,<
SKIPE T3 ;IS THERE ONE?
TLOA T3,(MS.MEM) ;YES
MOVEI T3,PAGPTR## ;NO, THEN THIS IS PREDECESSOR
.CREF PAGTAB ;(WHICH IS AT SECTION RELATIVE 0)
>
IFE FTXMON,<
SKIPN T3 ;IS THERE A PREDECESSOR?
SKIPA T3,[PAGPTR##] ;NO, THIS IS IT THEN
ADDI T3,PAGTAB ;POINT TO PAGTAB
>
;HERE WHEN TARGET PAGE IS ON THE FREE-PAGE LIST
;EXCHANGE TARGET PAGE AND CURRENT PAGE ON THE FREE LIST
SKIPE P1
HRRZ T4,@[IW MS.MEM,PT2TAB(T1)]
MOVSI T2,(P2.LIP) ;BE SURE P2.LIP GETS CLEARED
ANDCAM T2,@[IW MS.MEM,PT2TAB(P2)]
MOVE T2,@[IW MS.MEM,PAGTAB(T1)]
PUSHJ P,FIXPTB
MOVSI T2,FREPAG
HLLM T2,@[IW MS.MEM,PAGTAB(T1)]
PUSHJ P,BLTPAG ;MOVE CURRENT PAGE TO TARGET PAGE (DATA)
PJRST CPOPJ1## ;AND SKIP-RETURN
;CALL THIS ROUTINE WHEN THE TARGET PAGE ISN'T ON FREE-LIST
;NOTE THAT THE PAGE IS THEREFORE IN THIS SEGMENT'S MAP
;P1 IS ZERO/NON-ZERO FLAG FOR THERE "IS NOT"/"IS" A PREDECESSOR TO DEAL WITH
;P2 IS TARGET PAGE, T1 IS CURRENT PAGE
PAGFND: LDB T2,JBYLSA## ;ASSUME ITS A LOW SEGMENT
CAILE J,JOBMAX## ;IS IT?
LDB T2,JBYHSA## ;NO
SETZ T4, ;NO PREDECESSORS YET
CAIE T2,(P2) ;IS THE TARGET PAGE THE 1ST PAGE OF THE SEG?
JRST PAGFD1 ;NO
MOVE T2,@[IW MS.MEM,PAGTAB(T1)] ;YES, GET SUCC TO CURRENT PAGE
EXCH T2,@[IW MS.MEM,PAGTAB(P2)] ;STORE AS SUCC TO TARGET PAGE
MOVEM T2,@[IW MS.MEM,PAGTAB(T1)] ;SUCC TO TARGET TO CURRENT SUCC
MOVE T2,@[IW MS.MEM,PT2TAB(T1)]
EXCH T2,@[IW MS.MEM,PT2TAB(P2)]
MOVEM T2,@[IW MS.MEM,PT2TAB(T1)]
JRST PAGFD2 ;AND SKIP SOME MAGIC
;HERE WHEN THE TARGET PAGE ISN'T THE 1ST PAGE OF THE SEGMENT
PAGFD1: HRRZ T3,@[IW MS.MEM,PT2TAB(P2)] ;PREDEDESSOR TO TARGET
ADD T3,[EXP MS.MEM+PAGTAB] ;CONVERT TO ADDR
HRRZ T4,@[IW MS.MEM,PT2TAB(T1)] ;PREDECESSOR TO CURRENT
HRRZ T2,@[IW MS.MEM,PAGTAB(T1)] ;SUCCESSOR TO CURRENT
PUSHJ P,FIXPTB
PAGFD2: PUSHJ P,FIXMAP ;FIND THE DESTINATION PAGE AND FIX THE MAP
PUSHJ P,EXCHPG ;EXCHANGE DATA OF CURRENT AND TARGET PAGES
JRST CPOPJ1## ;AND GIVE GOOD RETURN
;SUBROUTINE TO MAKE TARGET AND SOURCE PAGES ADDRESSABLE IN EXEC
; VIRTUAL MEMORY
;CALLING SEQUENCE:
; MOVE T1,ABSOLUTE PAGE NUMBER OF SOURCE PAGE
; MOVE P2,ABSOLUTE PAGE NUMBER OF TARGET PAGE
; PUSHJ P,SETMAP
;RETURN HERE, SOURCE AND TARGET PAGES ADDRESSABLE THROUGH .ECKSM AND
; .EUPMP RESPECTIVILY
SETMAP: PUSHJ P,SAVE1##
MOVE P1,.CPMAP##
HRLI T1,(<PM.DCD>B2+PM.WRT+PM.PUB)
MOVEM T1,.ECKSM/PAGSIZ(P1)
HRR T1,P2
MOVEM T1,.EUPMP/PAGSIZ(P1)
; PJRST NEWMAP
NEWMAP: CLRPGT ;CLEAR THE ASSOCIATIVE MEMORY
; SO THE NEW MAPPING WILL BE IN EFFECT
POPJ P, ;RETURN
;SUBROUTINE TO BLT SOURCE PAGE TO TARGET PAGE WHICH WAS ON THE FREE CORE LIST
;CALLING SEQUENCE:
; MOVE T1,ABSOLUTE PAGE NUMBER OF THE SOURCE PAGE
; MOVE P2,ABSOLUTE PAGE NUMBER OF THE TARGET PAGE
; PUSHJ P,BLTPAG
;RETURN HERE, SOURCE PAGE BLTED TO TARGET PAGE FROM FREE CORE LIST
BLTPAG: PUSHJ P,SETMAP ;MAKE THE SOURCE AND DESTINATION PAGES ADDRESSABLE
MOVSI T1,.ECKSM ;ADDRESS OF THE SOURCE PAGE
HRRI T1,.EUPMP ;ADDRESS OF THE DESTINATION PAGE
;THIS LABEL IS TO DETECT MEMORY PARITY ERROR IN EXEC MODE DURING BLT OF USER CORE
LOKINS::BLT T1,.EUPMP+PG.BDY
POPJ P, ;MOVE THE PAGE AND RETURN
;SUBROUTINE TO EXCHANGE SOURCE AND TARGET PAGES WHEN THEY ARE BOTH CONTAINED
; WITHIN THE CURRENT SEGMENT
;CALLING SEQUENCE:
; MOVE T1,ABSOLUTE PAGE NUMBER OF THE SOURCE PAGE
; MOVE P2,ABSOLUTE PAGE NUMBER OF THE TARGET PAGE
; PUSHJ P,EXCHPG
;RETURN HERE, SOURCE AND TARGET PAGES HAVE BEEN EXCHANGED
EXCHPG: PUSHJ P,SETMAP ;MAKE THE SOURCE AND DESTINATION PAGES ADDRESSABLE
MOVSI T1,-PAGSIZ ;AOBJN COUNTER FOR NUMBER OF WORDS TO EXCHANGE
EXCHP1: MOVE T2,.EUPMP(T1) ;GET A DATA WORD FORM THE DESTINATION PAGE
EXCH T2,.ECKSM(T1) ;EXCHANGE IT WITH THE WORD FROM THE SOURCE PAGE
MOVEM T2,.EUPMP(T1) ;WORD FROM SOURCE PAGE TO DESTINATION PAGE
AOBJN T1,EXCHP1 ;EXCHANGE THE ENTIRE PAGES
POPJ P, ;AND RETURN
;SUBROUTINE TO FIND THE TARGET PAGE ON THE FREE CORE LIST OR WITHIN
; THE CURRENT SEGMENT AND MOVE/EXCHANGE THE SOURCE TO/WITH THE TARGET AS
; APPROPRIATE
;CALLING SEQUENCE:
; MOVE T1,ABSOLUTE PAGE NUMBER OF THE SOURCE PAGE
; MOVE P2,ABSOLUTE PAGE NUMBER OF THE TARGET PAGE
;P1 IS ZERO/NON-ZERO FLAG FOR THERE "IS NOT"/"IS" A PREDECESSOR TO DEAL WITH
;NON-SKIP RETURN - PAGE WAS IN PLACE ALREADY (P2.LIP CLEARED, THOUGH)
;SKIP RETURN - THE SOURCE PAGE HAS BEEN MOVED TO THE TARGET DESTINATION
PAGMOV: CAIE T1,(P2) ;IS IT ALREADY IN PLACE?
PUSHJ P,PAGFRE ;IS THE DESTINATION PAGE ON THE FREE CORE
; LIST? IF SO, MOVE SOURCE PAGE TO DESTINATION
; PAGE AND FIXUP PAGTAB
SKIPA T2,[P2.LIP] ;TARGET PAGE NOT ON FREE CORE LIST
JRST CPOPJ1## ;PAGE IS NOW IN PLACE
ANDCAM T2,@[IW MS.MEM,PT2TAB(P2)] ;CLEAR P2.LIP SINCE IT WASN'T ON
;FREE CORE LIST AND CLRLOQ THEREFORE DIDN'T
CAIN T1,(P2) ;IF PAGE WAS IN PLACE
POPJ P, ;RETURN
PUSHJ P,PAGFND ;THE DESTINATION PAGE IS NOT ON THE FREE
; CORE LIST SO IT MUST BELONG TO THIS SEGMENT
; FIND IT WITHIN THE SEGMENT, FIXUP PAGTAB
; AND EXCHANGE THE SOURCE AND TARGET PAGES
STOPCD .,STOP,PNP, ;++PAGE NOT PRESENT
AOS (P) ;PAGE WASN'T IN PLACE
POPJ P, ;RETURN
;SUBROUTINE TO DETERMINE IF THE CURRENT PAGE MUST BE MOVED AND IF SO,
; MOVE IT
;T4 CONTAINS MAP POINTER FOR VIRTUAL PAGE TO MOVE, P2 HAS TARGET PAGE
;P1 ZERO/NON-ZERO FLAG FOR THERE "IS NOT"/"IS" A PREDECESSOR
;TO BE DEALT WITH
;P2=TARGET, T1=CURRENT PAGES
PGMOVE: PUSHJ P,SAVT##
MOVE T1,(T4)
TLZ T1,(PM.NAD)
PUSH P,T4
PUSHJ P,PAGMOV
JFCL ;DON'T CARE IF IT WAS IN PLACE
MOVE T1,(P)
MOVE T1,(T1)
AND T1,[PM.NAD] ;SAVE ALL BUT ADDRESS
IORI T1,(P2)
HRRZ T2,M
MOVSI T3,(JS.NCS)
CAIGE T2,.MCFV/PAGSIZ
TDNN T3,JBTST2##(J)
CAIA
TLZ T1,(PM.CSH)
EXCH T1,(P)
POP P,(T1)
PJRST NEWMAP
;SUBROUTINE TO FIND THE PAGE A PAGE WAS EXCHED WITH AND FIX THE
; MAP SLOT FOR THAT PAGE
FIXMAP: CAILE J,JOBMAX## ;JOB?
JRST FIXHMP ;NO, FIX A HIGH SEG MAP THEN
PUSHJ P,SAVT## ;SAVE THE TS AGAIN
PUSH P,M
PUSH P,.USSPT
FIXMA1: CAIE M,.UPMVP/PAGSIZ ;FLAG THAT WE'RE MOVING UPT
JRST FIXMA3 ;NOT MOVING UPT, START WHERE PAGE CURRENTLY IS
SETZM .USSPT
FIXMA2: PUSHJ P,NXTWSB## ;START
JRST FIXMA5 ;..
FIXMA3: MOVE M,.USTMP ;ACS SAVED FOR US
DMOVE T1,.USTMP+1
MOVE T3,.USTMP+3
FIXMA4: PUSHJ P,NXTWS3## ;NEXT PAGE
FIXMA5: SKIPGE .USBTS ;IS USER EXTENDED?
SKIPGE .USSPT ;YES, DOING FUNNY SPACE (2ND TIME THROUGH S0)
JRST FIXMA8 ;YES
TRNN M,<-1^!HLGPNO> ;USER PAGE?
JRST FIXMA8 ;YES
SKIPE T4,.USSPT ;START NON-ZERO SECTIONS?
AOJA T4,FIXMA6 ;NO, ALREADY STARTED
PUSH P,M
PUSH P,T1
PUSH P,T2
PUSH P,T3
AOJA T4,FIXMA7
FIXMA6: CAILE T4,MXSECN
SETO T4, ;START FUNNY SPACE
FIXMA7: MOVEM T4,.USSPT
JUMPGE T4,FIXMA2
POP P,T3
POP P,T2
POP P,T1
POP P,M
MOVEI T4,(M)
PUSHJ P,GMPTR##
FIXMA8: MOVEI P4,(M)
CAILE P4,<<.UPMVP/PAGSIZ>+MXSECN>
STOPCD .,STOP,XPW ;++EXCHANGED PAGE WENT AWAY
MOVE P4,(T4) ;GET MAP POINTER
TLZ P4,(PM.NAD) ;FIND OUT WHICH PHYSICAL PAGE THIS WAS
CAIE P4,(P2) ;IS THIS THE PHYSICAL PAGE WE ARE LOOKING FOR?
JRST FIXMA4 ;NOPE, TRY NEXT ONE.
MOVE T1,(T4)
AND T1,[PM.NAD] ;WE ONLY WANT HIS FLAGS
IOR T1,-3(P) ;NEW PAGE (SAVED T1)
MOVEM T1,(T4) ;AND PUT IT BACK IN THE MAP
HRRZS M ;SEE IF PAGE WAS .UPMAP
CAIN M,<.UPMVP/PAGSIZ>-1
MOVEM T1,.UPMP+SECTAB+0 ;YES, SET S0 POINTER TOO
SKIPLE .USSPT ;FIND PAGE IN NZS?
ADJSP P,-4 ;YES, CLEAR STACK JUNK
POP P,.USSPT ;RESTORE THINGS
POP P,M
PJRST NEWMAP ;AND CLEAR THE PAGER
;HERE FOR HIGH SEG
FIXHMP: PUSHJ P,SAVE4## ;SAVE ACS
MOVE P1,JBTVAD##(J) ;START OF MAP
LDB P3,IMGIN## ;SIZE OF SEGMENT
TLO P1,(<GIDX(P3)>) ;INDEX
SOS P3 ;HIGHEST RELATIVE PAGE IN SEGMENT
FIXHM1: MOVE P4,@P1 ;GET MAP ENTRY
TLZ P4,(PM.NAD) ;CLEAR BITS
CAIE P4,(P2) ;PAGE WE WANT?
SOJGE P3,FIXHM1 ;NO
SKIPGE P3 ;FALL OFF END OF MAP?
XCT XPW ;YES, SOMEONE IS CONFUSED
MOVSI P4,(PM.NAD) ;SAVE BITS IN ENTRY
AND P4,@P1
IORI P4,(T1) ;NEW PAGE #
IORM T1,@P1 ;UPDATE MAP
POPJ P, ;AND RETURN
;SUBROUTINE TO FIX UP PAGTAB AFTER EXCHANGING PAGES
;ARGS:
; T3=PREDECESSOR-TO-TARGET ADDRESS
; T1=CURRENT PAGE #
; P2=TARGET PAGE #
; T4=PREDECESSOR-TO-CURRENT PAGE #
; T2=SUCCESSOR-CURRENT-PAGE #
;NOTE THAT T3 IS LOADED WITH THE ACTUAL ADDRESS OF AN ENTRY IN PAGTAB,
;AND NOT AN OFFSET INTO PAGTAB.
;NOTE THAT LH(T1) CANNOT CONTAIN ANY JUNK
FIXPTB: HRL T2,@[IW MS.MEM,PAGTAB(P2)]
PUSH P,T4 ;SAVE WHILE WE MANGLE IT
SSX T4,MS.MEM ;SECTION PAGTAB IS IN
SKIPN P1
TDZA T4,T4 ;SET PREDECESSOR TO ZERO IF THERE IS TO BE NONE
HRRM P2,PAGTAB(T4) ;PRED-TO-CURR-->TARGET
HRRM T4,@[IW MS.MEM,PT2TAB(P2)] ;PRED-TO-CUR<--TARGET
HRRM T1,(T3) ;PRED-TO-TARGET-->CURRENT
CAIN T3,PAGPTR## ;IS THERE NO PRED-TO-TARGET PAGE?
TDZA T4,T4 ;YES, SET PRED-TO-TARGET PAGE TO 0
MOVEI T4,-PAGTAB(T3) ;ELSE GET PAGE # FOR PRED-TO-TARGET
HRRM T4,@[IW MS.MEM,PT2TAB(T1)] ;PRED-TO-TARGET<--CURRENT
MOVE T4,(P) ;RESTORE T4
HLRZM T2,(P) ;SAVE SUCCESSOR TO TARGET
CAIE P2,(T2) ;EXCHANGING TARGET WITH SUCCESSOR TO CURRENT?
TLZA T2,-1 ;NO, JUST CLEAR JUNK IN LH
HRRZ T2,T1 ;IF YES, SET CURRENT AS SUCCESSOR TO CURRENT
HRRM T2,@[IW MS.MEM,PAGTAB(P2)] ;TARGET-->SUCCESSOR TO CURRENT
TRNE T2,-1 ;IS THERE A REAL SUCCESSOR TO CURRENT?
HRRM P2,@[IW MS.MEM,PT2TAB(T2)] ;TARGET<--SUCCESSOR TO CURRENT
HLL T2,@[IW MS.MEM,PAGTAB(P2)] ;EXCHANGE BITS FOR
HLR T2,@[IW MS.MEM,PAGTAB(T1)] ;CURRENT AND TARGET PAGES
HLLM T2,@[IW MS.MEM,PAGTAB(T1)] ;..
HRLM T2,@[IW MS.MEM,PAGTAB(P2)] ;..
MOVE T2,@[IW MS.MEM,MEMTAB(T1)] ;EXCH MEMTABS IN CASE HIGH SEG
EXCH T2,@[IW MS.MEM,MEMTAB(P2)]
MOVEM T2,@[IW MS.MEM,MEMTAB(T1)]
POP P,T2 ;RESTORE SUCCESSOR TO TARGET
CAIN T2,(T1) ;IF SUCCESSOR TO TARGET IS CURRENT
MOVE T2,P2 ;THEN SUCCESSOR TO TARGET IS TARGET
HRRM T2,@[IW MS.MEM,PAGTAB(T1)] ;TARGET-->SUCCESSOR TO CURRENT
TRNE T2,-1 ;DO NOTHING ELSE IF NO SUCCESSOR
HRRM T1,@[IW MS.MEM,PT2TAB(T2)] ;TARGET<--SUCCESSOR TO CURRENT
POPJ P,
SUBTTL ERRCON - ERROR HANDLING CODE
;ROUTINE TO CHECK IF JOB HAS SOME SEG LOCKED
;CALL: MOVE J,JOB NUMBER
; PUSHJ P,LOKCHK
; SOME LOCKED - J PRESERVED
; NONE LOCKED - J PRESERVED
LOKCHK::PUSHJ P,SAVE2## ;SAVE P1-P2
MOVSI P1,NSHF!NSWP ;NO SHUFFLING OR SWAPPING BITS
MOVSI P2,LOKSEG ;LOCKED HIGH SEG SOMEWHERE?
TDNN P1,JBTSTS##(J) ;LOW SEG LOCKED?
TDNE P2,JBTSGN##(J) ;OR A LOCKED HIGH SEG SOMEWHERE?
POPJ P, ;YES
AOS (P) ;NEITHER LOCKED, SKIP RETURN
POPJ P,
;SUBROUTINE TO DETERMINE IF A SEGMENT IS LOCKED IN CONTIGUOUS EXEC
; VIRTUAL MEMORY
;CALLING SEQUENCE:
; MOVE J,SEGMENT NUMBER
; PUSHJ P,LOKEVC
; ... RETURN HERE IF SEGMENT IS NOT LOCKED IN EVM
; ... RETURN HERE IF SEGMENT IS LOCKED IN EVM
LOKEVC::SE1ENT ;HAVE TO LOOK AT PAGTAB
PUSHJ P,SAVE2## ;SAVE P1-P2
LDB P1,JBYLSA## ;ASSUME A LOW SEGMENT (GET ABSOLUTE PAGE NUMBER
; OF FIRST PAGE OF THE LOW SEGMENT)
CAILE J,JOBMAX## ;IS IT A HIGH SEGMENT
LDB P1,JBYHSA## ;YES, GET ABSOLUTE PAGE NUMBER OF FIRST PAGE
; OF THE HIGH SEGMENT
MOVSI P2,LOKEVB ;BIT INDICATING PAGE IS LOCKED IN EVM
TDNE P2,@[IW MS.MEM,PAGTAB(P1)] ;IS IT?
; (IF FIRST PAGE IS LOCKED ALL MUST BE)
AOS (P) ;YES
POPJ P, ;GIVE LOCKED OR NOT LOCKED RETURN
SUBTTL UUOCON - UUO HANDLING ROUTINES
;ROUTINE TO SET UP CALL TO SWAPPER FOR LOCKING A JOB IN CORE
;CHECKS VALIDITY OF REQUEST AND TRIES TO FIND A PLACE TO PUT THE
;JOB IN CORE.
;THE CALLING JOB IS PUT AS LOW CORE IN AS
;POSSIBLE.
;CALLING SEQUENCE
; PUSHJ P,LOKJOB
; ERROR RETURN
; NORMAL RETURN (NSHF+NSWP SET)
LOKJOB::SE1ENT ;MARK THE FACT THAT LOKCON RUNS EXTENDED
JUMPL T1,LOKJO2 ;SKIP CHECKS HERE FOR FORMAT 2
TRNE T1,-1 ;LOCKING THE LOW SEG?
SKIPN .USVRT ;YES, IS JOB VIRTUAL?
SKIPE .USLPG ;NOT VIRTUAL, ANY LOCKED PAGES?
JRST RTZER## ;CAN'T LOCK VIRTUAL LOW SEG
PUSHJ P,NSHCHK ;CHECK FOR NON-SHARABLE SEG PROBLEM
JRST RTZER## ;NOT IMPLEMENTED
LOKJO2: PUSHJ P,SAVE4## ;SAVE P1-P4
PUSHJ P,SAVU## ;SAVE U
MOVSI T1,PVLOCK ;BIT DENOTING PRIVILEDGES TO LOCK
PUSHJ P,PRVBIT## ;IS THIS USER A SUFFICIENT WHEEL?
SKIPA P4,JBTSGN##(J) ;YES, PROCEED (POINT TO FIRST HIGH SEG)
JRST ERROR1 ;NO, NOT PRIVILEGED ERROR RETURN
SETZ P1, ;INDICATE FIRST TIME
PUSHJ P,GETTAC## ;GET THE ARGUMENT
PUSH P,T1 ;SAVE ON STACK
LOKJ2A: PUSHJ P,LOKJO3 ;LOCK THIS HIGH SEG AND JOB
JRST LOKERR ;FAILURE; FIX UP THINGS AND FINISH UP
MOVE T2,(P) ;USER'S AC
EXCH T1,T2 ;VALUE TO RETURN
PUSHJ P,LOKVAL ;RETURN VALUE TO USER AS APPROPRIATE
JUMPL P4,LOKJ2A ;LOOP IF EXTENDED FORMAT
JUMPE P4,LOKJ2B ;OR EXIT IF DONE
HRRZ P4,.HBLNK(P4) ;POINT TO NEXT
JUMPN P4,LOKJ2A ;LOOP AROUND FOR THIS HIGH SEG
LOKJ2B: POP P,(P) ;THROW USER'S ARG AWAY
JRST CPOPJ1## ;DONE IF NO MORE HIGH SEG
;HERE TO PROCESS ONE LOCK FOR EITHER A LOW SEG (PERHAPS PLUS HIGH SEG)
;OR A HIGH SEG ONLY (J ALWAYS SHOULD HAVE THE LOW SEG FOR WHOM THE
;HIGH SEG IS BEING LOCKED)
;AC USAGE THROUGH THIS:
;P3=USER'S ARG
;P4=ADDRESS OF HIGH SEG DATA BLOCK FOR HIGH SEG TO BE LOCKED (0 IF NONE)
LOKJO3: PUSHJ P,SAVE1## ;SAVE P1
LOKJ3A: MOVE P3,T1 ;ARG SAVED IN P3
JUMPL P3,LOKFM2 ;PROCESS NEW STYLE ARG LIST
LOKRET: MOVSI P1,NSHF!NSWP ;LOCKED BITS
MOVE T2,J ;SAVE JOB NUMBER
MOVEI T3,0 ;ASSUME NO HIGH SEGMENT ADDRESS
SKIPE P4 ;A HIGH SEG?
SKIPG J,.HBSGN(P4) ;REALLY A REAL HIGH SEG?
JRST LOKJO4 ;NO
TLO J,(IFIW) ;MAKE THIS AC A VALID INDEX. THIS WORKS SINCE
.CREF SPYSEG ;1B0 IS SPYSEG, WHICH NOONE TESTS FURTHER DOWN.
LDB T3,JBYHSA## ;PHYSICAL ADDRESS OF HIGH SEGMENT
TLNE T1,LKB ;USER LOCKING HIGH SEGMENT?
TDNN P1,JBTSTS##(J) ;ALREADY LOCKED?
JRST HGHADR ;NO. GET ADDRESS ANYWAY
MOVE T4,@[IW MS.MEM,PAGTAB(T3)] ;GET STATUS OF LOCKED SEGMENT
PUSHJ P,ARGCK1 ;OK TO LOCK AGAIN?
JRST ERROR7 ;NOT OK. ARGUMENT IS INCORRECT
TLNE J,LOKSEG ;ALREADY LOCKED, BUT FOR THIS JOB?
JRST HGHADR ;YES, ALREADY LOCKED FOR THIS JOB
MOVSI T4,LOKSEG ;NO, WELL NOW IT IS
IORM T4,.HBSGN(P4)
PUSHJ P,CHKCS1 ;SET CACHE BIT IN JBTSGN
PUSHJ P,MAPHGH## ;COPY CACHE BIT TO UPMP
JRST LOKJ3A ;RESTORE AC'S AND START OVER
HGHADR: TLNN T1,LKEB ;LOCKED IN EVM?
LDB T3,[POINT 9,JBTADR##(J),26] ;YES, PROVIDE EVA TO USER
LOKJO4: EXCH J,T2 ;J=JOB, T2=HIGH SEGMENT NUMBER
TRNN T1,LKB ;LOCK THE LOW SEGMENT?
JRST LOKJO5 ;NO
TDNN P1,JBTSTS##(J) ;IS THE LOW SEGMENT ALREADY LOCKED?
JRST LOKJO6 ;YES
LOKJO5: TLNN T1,LKB ;LOCK THE HIGH SEGMENT?
JRST GETLOW ;NO, CHECK OUT LOW EG
JUMPE T3,GETLOW ;JUMP IF NO HIGH SEGMENT
TDNE P1,JBTSTS##(T2) ;ALREADY LOCKED?
JRST GETLOW ;YES, GO CHECK OUT LOW SEGMENT
HRRZ J,T2 ;SAVE HIGH SEGMENT NUMBER
LOKJO6: TLZ T1,-1-<LKB>
MOVEI F,0 ;INDICATE NO DDB
PUSHJ P,CAWAIT## ;YES, WAIT UNTIL ITS DONE
CHKLPG:: ;ENTER HERE FOR CHECK ON LOCK PAGES FUNCTION
SETZB U,T4 ;ZERO LARGEST JOB SEEN SO FAR
PUSH P,P1 ;SAVE CURRENT P1 (IN CASE CHKLPG)
PUSH P,J ;SAVE J
MOVEI J,1 ;FIND THE LARGEST JOB NOT LOCKED
MOVE P1,T1 ;SAVE ARG
LOKJO7: CAMN J,.CPJOB## ;DON'T CONSIDER JOB BEING LOCKED
JRST LOKJ12
MOVE T2,JBTSTS##(J) ;IS THIS JOB LOCKED?
TLNE T2,NSHF!NSWP
TDZA T2,T2
PUSHJ P,SEGSIZ## ;NOT LOCKED, FIND OUT HOW BIG IT IS
PUSH P,J ;SAVE LOW SEGMENT NUMBER
PUSH P,T1 ;SAVE HIGH SEGMENT LKB
SETZ T1, ;FIND HIGH SEGS THIS JOB HAS
LOKJO8: PUSHJ P,GNXHSB## ;DOES HE HAVE ANY (MORE)?
JRST LOKJ11 ;NO
PUSH P,T1 ;SAVE HIGH SEG DATA BLOCK ADDR
SKIPG T1,.HBSGN(T1) ;IS THIS A REAL HIGH SEG?
JRST LOKJ10 ;NO
HRRZS T1 ;CLEAR JUNK
TLNN P1,LKB ;ARE WE LOCKING A HIGH SEG?
JRST LOKJO9 ;NO
MOVE P2,JBTSTS##(T1) ;GET THAT SEGMENT'S STATUS WORD
JUMPE P4,LOKJO9
SKIPLE J,.HBSGN(P4) ;GET OUR SEGMENT #
CAIE T1,(J) ;IS THIS THE SEGMENT IN QUESTION?
LOKJO9: TLNE P2,NSHF!NSWP ;OR IS THIS SEGMENT ALREADY LOCKED?
JRST LOKJ10 ;ALREADY LOCKED OR SEGMENT BEING LOCKED; IGNORE
MOVE P2,T2 ;SUMMATION SO FAR
HRRZS J ;CLEAR JUNK
PUSHJ P,SEGSIZ## ;SIZE OF THAT SEGMENT
ADDI T2,(P2) ;INCLUDE IN SUM
LOKJ10: POP P,T1 ;RESTORE HIGH SEG DATA BLOCK ADDR
JRST LOKJO8 ;AND CONTINUE LOOKING AT THIS JOB'S HIGH SEGS
LOKJ11: POP P,T1 ;RESTORE HIGH SEGMENT LKB
LSH T2,P2WLSH
CAMLE T2,U ;LARGEST SO FAR?
MOVE U,T2 ;YES, SAVE ITS SIZE
POP P,J ;RESTORE JOB NUMBER
LOKJ12: CAMGE J,HIGHJB## ;LOOKED AT ALL JOBS YET?
AOJA J,LOKJO7 ;NO
MOVE J,(P)
SKIPN T3,P1 ;SAVE ARGS
JRST [MOVE T1,-1(P) ;# OF PAGES TO LOCK ON LOCK PAGES FCN
SOJA T1,LOKJ13] ;CHECK
LSH T2,P2WLSH ;SIZE IN WORDS
HRRI T1,-1(T2) ;SIZE-1 OF HIGH OR LOW SEGMENT
TLZE T1,LKB ;HIGH SEGMENT TO BE LOCKED?
CAILE J,JOBMAX## ;LOW SEGMENT ALREADY LOCKED?
JRST LOKJ13 ;YES, JUST LOCK THE HIGH SEGMENT
MOVSI P2,NSHF!NSWP ;HIGH SEGMENT MAY ALREADY BE LOCKED
JUMPE P4,LOKJ13
SKIPG P1,.HBSGN(P4) ;REALLY ANY HIGH SEG?
JRST LOKJ13 ;NO, DON'T WORRY ABOUT IT.
HRRZ T2,P1 ;MAKE AN INDEX WITH SEGMENT NUMBER
TDNE P2,JBTSTS##(T2) ;IS THE HIGH SEGMENT ALREADY LOCKED?
JRST LOKJ13 ;NEEDN'T BE CONCERNED ABOUT THE HIGH SEGMENT
HRLI P1,(J) ;P1_JOB#,,HIGH SEGMENT#
MOVEM P1,(P) ;SAVE IT
HLRZ P1,JBTADR##(T2) ;SIZE OF THE HIGH SEGMENT
ADDI T1,1(P1) ;ADD IT TO THE TOTAL
LOKJ13: PUSHJ P,LRGHOL ;COMPUTE THE NUMBER OF PHYSICAL PAGES AVAILABLE
; FOR LOCKING
POP P,P2 ;RESTORE JOB#,,HIGH SEGMENT#
POP P,P1 ;IN CASE WE RETURN
SUBI T2,1(T1) ;T2 = AMOUNT OF CORE LEFT IF THIS JOB IS LOCKED
CAMGE T2,U ;WILL ALL EXISTING JOBS BE ABLE TO RUN IN
; THE AMOUNT OF CORE WHICH WILL REMAIN?
JRST ERROR2 ;NO, CAN'T LOCK THE JOB
CAMGE T2,CORMIN## ;WOULD LOCKING THIS JOB MAKE CORMAX .LT.
; CORMIN?
JRST ERROR3 ;YES, TELL THE USER HE LOST
MOVEM T2,MAXMAX## ;LARGEST LEGAL CORMAX
HRRZ T1,CORLIM## ;UPPER BOUND ON CORMAX
LSH T1,P2WLSH ;CONVERT TO NUMBER OF WORDS MAX
CAMLE T1,T2 ;NUMBER OF PHYSICAL PAGES WHICH WILL REMAIN
; AFTER LOCKING .GT. MAX CORMAX?
MOVE T1,T2 ;YES, NEW CORMAX = NUMBER OF PHYSICAL PAGES
; LEFT AFTER LOCKING
MOVEM T1,CORMAX## ;STORE THE UPDATED VALUE OF CORMAX
SUBI T2,NWMCP+PAGSIZ ;ACCOUNT FOR FUNNY SPACE
MOVEM T2,RMCMAX## ;SET "REAL" MAXIMUM VALUE OF CORMAX
MOVE J,.CPJOB## ;CURRENT JOB NUMBER
MOVSI T1,LOKSEG ;ASSUME THE HIGH SEGMENT IS BEING LOCKED
CAILE P2,JOBMAX## ;IS IT?
IORM T1,JBTSGN##(J) ;YES, INDICATE HIGH SEGMENT IS LOCKED FOR
; THIS JOB
MOVEM J,LASLOK## ;REMEMBER THE JOB NUMBER OF THE LAST JOB
; ISSUING A LOCK UUO
JUMPE T3,CPOPJ1## ;IF CALLED FROM LOKPGS, RETURN THERE NOW
MOVE P1,P2 ;REFILL P1 NOW THAT WE KNOW IT'S NOT CHKLPG
MOVE T1,P3 ;DESTROYABLE COPY
JUMPGE P3,LKJ13A ;PROCEED IF OLD FORMAT LOCK
HRRZ M,(P3) ;POINT TO USER'S ARG LIST
PUSHJ P,GETWDU## ;GET FUNCTION
CAIN T1,.LKPPN ;IF SPECIFIED PAGE FUNCTION,
JRST LOKEXT ;PROCESS IT
;DISPATCH TO DO VARIOUS TYPES OF LOCK FOR EACH SEGMENT
LKJ13A: PUSHJ P,CHKCSH ;CHECK WHETHER THE CACHE SHOULD BE ON OR OFF
CAIG P1,JOBMAX## ;IS THE HIGH SEGMENT TO BE LOCKED?
JRST LOKJ14 ;NO
TLCE T1,LKB+LKEB+LKPB;DOES THE USER WANT IT LOCKED IN PLACE?
TLNE T1,LKB+LKEB+LKPB; ..
JRST LOKJ14 ;NO, SOME OTHER VARIETY OF LOCKING
HRRZ J,P1 ;YES, J = HIGH SEGMENT NUMBER
PUSHJ P,LOKINP ;LOCK THE HIGH SEGMENT IN PLACE
HLRZS P1 ;P1 = LOW SEGMENT NUMBER OR ZERO IF THE
; LOW SEGMENT ISN'T TO BE LOCKED
JUMPE P1,LOKJ19 ;JUMP IF LOW SEGMENT ISN'T TO BE LOCKED
LOKJ14: MOVE T1,P3 ;GET A DESTROYABLE COPY OF USER'S AC
TRCE T1,LKB+LKEB+LKPB;DOES THE USER WANT THE LOW SEGMENT LOCKED
TRNE T1,LKB+LKEB+LKPB; IN PLACE?
JRST LOKJ15 ;NO, TRY SOME OTHER VARITY OF LOCKING
HRRZ J,P1 ;YES, J = LOW SEGMENT NUMBER
PUSHJ P,LOKINP ;LOCK THE LOW SEGMENT IN PLACE
JRST LOKJ19 ;AND FINISH UP
LOKJ15: MOVEI T2,0 ;ASSUME ONLY THE HIGH SEGMENT IS TO BE LOCKED
TLNE P1,-1 ;LOCKING BOTH SEGMENT?
MOVE T2,[XWD LKPB,LKPB]
CAIG P1,JOBMAX## ;LOCKING ONLY THE LOW SEGMENT?
MOVEI T2,LKPB ;YES
SKIPN T2 ;SKIP IF LOCKING ONLY LOW SEGMENT OR BOTH
MOVSI T2,LKPB ;LOCKING ONLY THE HIGH SEGMENT
TDNE P3,T2 ;EITHER SEGMENT TO BE LOCKED PHYSICALLY CONTIGUOUS?
JRST LOKJ16 ;THE USER DOES NOT REQUIRE PHYSICAL CONTIGUITY,
; CHECK FOR CONTIGUOUS IN EVM
PUSHJ P,LOKPHY ;ATTEMPT TO LOCK THE JOB IN PHYSICALLY CONTIGUOUS
; MEMORY
JRST ERROR5 ;COULDN'T MAKE IT, GIVE THE USER AN ERROR RETURN
LOKJ16: MOVEI T1,0 ;INDICATE THAT NEITHER SEGMENT IS ALREADY
; LOCKED IN EVM
LOKJ17: MOVE P2,T1 ;P2 = SEGMENTS ADDRESSES IF LOCKED ALREADY
MOVE T1,P3 ;DESTRUCTABLE COPY
TDCE T1,[XWD LKEB,LKEB]
TDNE T1,[XWD LKEB,LKEB]
SKIPA ;THE USER WANTS ONE OR BOTH SEGMENTS
; LOCKED IN CONTIGUOUS EXEC VIRTUAL MEMORY
JRST LOKJ19 ;ALL DONE
MOVE T1,P3 ;COPY TO PLAY AROUND WITH
EXCH T1,P2 ;T1 REFLECTS THE PROGRESS SO FAR
CAILE P1,JOBMAX## ;LOCKING ONLY THE LOW SEGMENT?
TLNE T1,-1 ;NO, IS THE HIGH SEGMENT ALREADY LOCKED?
JRST LOKJ18 ;GO CHECK THE LOW SEGMENT
TLNE P2,LKEB ;LOCK THE HIGH SEGMENT VIRTUALLY CONTIGUOUS?
JRST LOKJ18 ;NO
PUSH P,T1 ;SAVE THE ADDRESS OF THE LOW SEGMENT
HRRZ J,P1 ;J = THE HIGH SEGMENT NUMBER
MOVSI T1,(PM.CSH) ;ASSUME WANT CACHE OFF
SETZ T2,
TLNE P2,LKCB ;WANT CACHE OFF?
EXCH T1,T2 ;NO, WANT IT ON
DMOVEM T1,.USTMP ;SET FLAGS FOR LOKEVM
PUSHJ P,LOKEVM ;ATTEMPT TO LOCK THE HIGH SEGMENT IN EVM
JRST ERROR4 ;NOT ENOUGH EVM
HRLM T1,(P) ;STORE THE EVA OF THE HIGH SEGMENT
POP P,T1 ;RESTORE THE ADDRESSES OF THE SEGMENTS
HLRZS P1 ;P1 = LOW SEGMENT NUMBER OF LOW SEGMENT IS
; TO BE LOCKED
JUMPE P1,LOKJ19 ;ALL DONE IF NOT LOCKING LOW SEGMENT
LOKJ18: TRNN P2,LKEB ;LOCK THE LOW SEGMENT VIRTUALLY CONTIGUOUS?
TRNE T1,-1 ;YES, IS THE LOW SEGMENT ALREADY LOCKED IN EVM?
JRST LOKJ19 ;YES, FINISH UP
PUSH P,T1 ;SAVE THE ADDRESSES OF THE SEGMENTS
MOVE J,.CPJOB## ;J = LOW SEGMENT NUMBER
MOVSI T1,(PM.CSH) ;ASSUME WANT CACHE OFF
SETZ T2,
TRNE P2,LKCB ;WANT CACHE OFF?
EXCH T1,T2 ;NO, WANT IT ON
DMOVEM T1,.USTMP ;SET FLAGS FOR LOKEVM
PUSHJ P,LOKEVM ;ATTEMPT TO LOCK THE LOW SEGMENT IN EVM
JRST ERROR4 ;NOT ENOUGH EVM
HRRM T1,(P) ;STORE THE EVA OF THE LOW SEGMENT
POP P,T1 ;RESTORE THE ADDRESSES OF THE SEGMENTS
LOKJ19: PUSHJ P,CAFREE## ;RETURN THE LOCK RESOURCE
S0PSHJ SETRLH##
JUMPGE P3,LOKRET ;PICK UP ARGS ELSEWHERE IF OLD FMT
PUSHJ P,RASBAD ;GET PHYSICAL PAGE NUMBER
JFCL ;RASBAD SKIPS
PJRST CPOPJ1## ;STORE ANSWER, SKIP RETURN
;SUBROUTINE TO LOCK A SEGMENT IN PLACE
;CALLING SEQUENCE:
; MOVE J,SEGMENT NUMBER OF SEGMENT TO BE LOCKED IN PLACE
; PUSHJ P,LOKINP
;RETURN HERE, SEGMENT IS LOCKED IN PLACE
LOKINP: MOVEI T3,LOKIPB ;BIT INDICATING PAGE IS LOCKED IN PLACE
PUSHJ P,LOKBTS ;TURN IT ON FOR EVERY PAGE IN THE SEGMENT
MOVEI T1,0 ;ADDRESS WHERE SEGMENT IS LOCKED IS ZERO
; SINCE NOTHING ELSE IS MEANINGFUL
POPJ P, ;RETURN
;HERE FOR FORMAT 2 TYPE LOCKS
LOKFM2: PUSHJ P,LOKARG ;JUMP IF NEW STYLE ARGUMENT LIST
JRST STOTAC## ;MALFORMED ARGUMENT LIST, GIVE ERROR RETURN
JRST LOKRET ;CONTINUE PROCESSING
LOKARG: HRRI M,(T1) ;POINT AT USER'S ARGUMENT LIST
HLRE T2,T1 ;- LENGTH OF THE ARGUMENT LIST
CAMLE T2,[-2] ;MUST BE AT LEAST 2 WORDS LONG
JRST LOKAR1 ;BAD ARGUMENT LIST
PUSHJ P,GETWDU## ;GET THE FIRST ARGUMENT (FUNCTION)
JUMPL T1,LOKAR1 ;CAN'T BE NEGATIVE
CAIL T1,MXLFCN ;IS IT A LEGAL FUNCTION?
JRST LOKAR1 ;NO, BAD ARGUMENT LIST
ROT T1,-1 ;DIVIDE BY 2, SAVE THE REMAINDER IN HIGH BIT
SKIPGE T1 ;SKIP IF AN EVEN FUNCTION
SKIPA T1,LOKFCN(T1) ;ODD FUNCTION, GET DISPATCH ADDRESS
MOVS T1,LOKFCN(T1) ;EVEN FUNCTION, GET DISPATCH ADDRESS
TRNN T1,-1 ;IMPLIMENTED FUNCTION?
JRST LOKAR1 ;NO, GIVE BAD ARGUMENT LIST RETURN
HRRZS T1 ;CLEAR LEFT-HALF BITS, SO WE DON'T JRST BOONIES
JRST (T1) ;DISPATCH TO THE FUNCTION PROCESSOR
LOKAR1: MOVEI T1,LKERR5 ;BAD ARGUMENT LIST ERROR CODE
POPJ P, ;NON-SKIP RETURN TO CALLER
LOKFCN: LOKHPH,,LOKSGN
MXLFCN==2*<.-LOKFCN>
LOKHPH: PUSHJ P,GETWD1## ;GET THE SECOND WORD OF THE ARGUMENT LIST
TLZE T1,-1 ;LOCK THE HIGH SEGMENT AT A SPECIFIED ADDRESS?
TLO T1,LKB!LKAB ;YES, INDICATE HIGH SEGMENT TO BE LOCKED
TRZE T1,-1 ;LOCK THE LOW SEGMENT AT A SPECIFIED ADDRESS?
TRO T1,LKB!LKAB ;YES, INDICATE LOW SEGMENT TO BE LOCKED
AOS (P) ;SET FOR GOOD RETURN
POPJ P, ;AND RETURN
LOKSGN: JUMPL P4,LOKSG3 ;IS THIS THE FIRST TIME?
HRL P4,T2 ;SET COUNT OF ARGS (+1) IN LEFT HALF OF P4)
LOKSG3: AOBJP P4,LOKSGR ;RETURN SUCCESS
PUSHJ P,GETWDU## ;GET NEXT LOCK ARG
TRNN T1,L2SGN ;IS THIS JOB OR A SEGMENT?
JRST LOKSGL ;LOW SEG
PUSH P,T1 ;SAVE ARG
PUSHJ P,FNDHSB## ;GET HIGH SEG BLOCK ADDRESS
JRST TPOPJ## ;NO SUCH HIGH SEG
HRRI P4,(T1) ;SET WHICH HIGH SEG TO FIDDLE WITH
MOVSI T1,LKB ;SAY TO LOCK THE HIGH SEG
POP P,T2 ;NOW FIGURE OUT HOW TO DO IT
JRST CPOPJ1## ;GOOD RETURN
LOKSGL: MOVE T2,T1 ;PUT ARG BITS IN T2
MOVEI T1,LKB ;SET TO LOCK LOW SEG
JRST CPOPJ1## ;AND GOOD RETURN
LOKSGR: SETZB T1,P4 ;STOP ALL ARG PROCESSING
JRST CPOPJ1## ;AND RETURN
;SUBROUTINE TO RETURN LOCK ARGUMENT (IN T2) INTO THE APPROPRIATE PLACE
;T1 CONTAINS THE USER'S AC
LOKVAL: JUMPL P4,LOKVLE ;EXTENDED FORMAT
MOVE T1,T2 ;FOR OLD FORMAT, PUT IN AC
PJRST STOTAC## ;AND DO IT
LOKVLE: MOVEI M,(P4) ;WHERE TO PUT IT
PUSHJ P,GETWDU## ;GET ARG FROM USER
TRNE T2,L2SGN ;LOW OR HIGH SEG?
MOVSS T2 ;HIGH SEG, PUT ADDRESS IN RIGHT HALF
LSH T2,W2PLSH ;CONVERT TO PAGE #
ANDI T2,(L2PPN) ;KEEP ONLY PAGE #
TLO T1,(T2) ;PUT IN THE VALUE
PJRST PUTWDU##
;HERE TO UNLOCK EVERYTHING WE TRIED TO LOCK (ERROR IN MIDDLE OF LIST)
LOKERR: MOVEM T1,(P) ;DON'T NEED USER'S AC ANYMORE
MOVE T1,P3 ;GET USER'S AC
AOBJP T1,TPOPJ## ;(ASSUME OLD FORMAT TAKES CARE OF ITSELF)
PUSHJ P,UUNLOK ;UNLOCK THIS LIST (IGNORE ERRORS...
JFCL ;...SINCE SOME THINGS MAY NOT BE LOCKED ANYWAY)
POP P,T1 ;RESTORE ERROR CODE
PJRST STOTAC## ;AND RETURN IT TO USER
;SUBROUTINE TO LOCK A SEGMENT CONTIGUOUSLY IN EXEC VIRTUAL MEMORY
;CALLING SEQUENCE:
; DMOVEM ,.USTMP ;.USTMP: BITS TO ANDCAM WITH PAGE MAP ENTRY
;(E.G. PM.CSH)
;.USTMP+1: BITS TO IOR WITH PAGE MAP ENTRY
;(E.G. PM.CSH)
; MOVE J,SEGMENT NUMBER OF SEGMENT TO BE LOCKED IN EVM
; PUSHJ P,LOKEVM
;RETURN HERE IF NOT ENOUGH EVM TO LOCK THE SEGMENT
;RETURN HERE, SEGMENT IS LOCKED IN EVM - T1 = EV PAGE NUMBER OF SEGMENT
LOKEVM: LDB T1,IMGIN## ;SIZE OF THE SEGMENT
LOKEVX::PUSH P,T1 ;SAVE THAT
JUMPLE T1,LOKEV1 ;IF PAGES, FORGET UPT
CAIG J,JOBMAX## ;A LOW SEGMENT?
ADDI T1,UPMPSZ## ;YES, UPMP MUST BE MAPPED TOO
LOKEV1: MOVEI T2,EVMPTR## ;POINT TO BIT MAP OF SLOTS IN THE EXEC MAP
; USED FOR LOCKING IN EVM
MOVMS T3,T1 ;AMOUNT OF EVM NEEDED
ADD T3,.C0EVU## ;AMOUNT ALREADY IN USE
CAMG T3,.C0EVM## ;GREATER THAN TOTAL AVAILABLE?
PUSHJ P,GETBIT## ;GET, SET BITS IN THE EVL TABLE
PJRST TPOPJ## ;NOT ENOUGH SLOTS AVAILABLE
MOVM T2,(P) ;NUMBER OF PAGES IN THIS SEGMENT
CAIG J,JOBMAX##
ADDI T2,UPMPSZ##
ADDM T2,.C0EVU## ;COUNT EVM IN USE FOR LOCKING
CAILE J,JOBMAX## ;LOW SEG?
JRST LOKEV8 ;NO
POP P,T2
PUSHJ P,SAVE4##
MOVE P1,T1 ;SAVE T1 IN P1 (FOR LOKEV3)
SKIPL P2,T2 ;AND AMOUNT OF EVM IN P2
ADDI T1,UPMPSZ##
PUSH P,T1
JUMPL P2,LOKEV3 ;IF FROM LOKPGS
PUSH P,M
LSH T1,P2WLSH
HRRM T1,JBTADR##(J)
MOVEI P4,(T1)
MOVE P3,.CPMAP##
HRLI P1,(POINT 36,(P3),35)
MOVE T3,.UPMP+.UMUPT
DPB T3,P1
IFN FTMP,<
PUSHJ P,MAPUC##
>
SETZM .USSPT ;START
LOKEV2: PUSHJ P,NXTWSB##
JRST LOKEV6
LOKEV3: PUSHJ P,FSTPAG## ;POINT TO FIRST PAGE
HRRI T1,(P1) ;START OF EVM
LSH T1,W2PLSH ;CONVERT TO PAGE #
HRLM T1,.USLPG ;STORE FOR LATER RETURN
MOVMS P2 ;MAKE POSITIVE
LOKEV4: SKIPGE (P) ;PAGES FORMAT?
JRST LOKEV5 ;NO
PUSHJ P,NXTWS3##
JRST LOKEV6
LOKEV5: PUSHJ P,NXTLPG## ;GET NEXT PAGE
TLNE T1,(PG.SLO!PG.GAF) ;THIS ARG REQUIRE EVM?
JRST LOKEV5 ;NO
PUSHJ P,GTPME##
MOVE T3,T2 ;GET MAP ENTRY
TLZ T3,(PM.NAD) ;KEEP ONLY PAGE #
MOVSI T1,LOKEVB ;TURN ON LOCKED IN EVM BIT
IORM T1,@[IW MS.MEM,PAGTAB(T3)]
MOVEI T1,1(P1)
MOVEM T1,@[IW MS.MEM,MEMTAB(T3)] ;STORE EVM FOR RETURN
.CREF MT.EVM ;...
JRST LOKEV7 ;CONTINUE
LOKEV6: TRNN M,<-1^!HLGPNO> ;PAGE NOT IN USER SPACE?
JRST LOKEV7 ;USER PAGE
AOS .USSPT ;PROCEED TO NEXT SECTION
JRST LOKEV2
LOKEV7: PUSHJ P,FPNSHS
PUSH P,T3
MOVE T3,(T4)
TDZ T3,.USTMP ;TURN OFF CACHE BIT IF ASKED TO
TDO T3,.USTMP+1 ;OR ON IF ASKED TO
MOVEM T3,(T4)
IDPB T3,P1
IFN FTMP,<
PUSHJ P,MAPUC##
>
POP P,T3
SOJG P2,LOKEV4
POP P,M
JRST LOKEV9
LOKEV8: MOVE T3,T1 ;SAVE STARTING PAGE IN THE EXEC MAP
PUSH P,J ;SAVE HIGH SEGMENT NUMBER
MOVE J,.CPJOB## ;JOB NUMBER
PUSHJ P,HSVAD## ;COMPUTE STARTING VIRTUAL ADDRESS OF THE HIGH SEGMENT
POP P,J
MOVE T1,T3 ;RESTORE T1
MOVE T3,T2 ;T3=VIRTUAL ADDRESS OF HIGH SEGMENT
MOVE T2,(P) ;NUMBER OF PAGES TO MAP IN THE EXEC MAP
IFN FTMP,<
PUSH P,T3 ;SAVE UVA
>
S0PSHJ MAPUEV## ;COPY THE USER'S MAP INTO THE EXEC MAP
HRRM T3,JBTADR##(J) ;STORE THE EVA OF THIS SEGMENT
IFN FTMP,<
POP P,T3 ;RESTORE UVA
>
MOVE T2,T1 ;T2=EXEC VIRTUAL PAGE NUMBER OF THE SEGMENT
EXCH T2,(P) ;SAVE THAT, RESTORE NUMBER OF PAGES TO BE MAPPED
IFN FTMP,<
S0PSHJ MAPUEC## ;COPY USER'S MAP TO CPU1'S MAP
>
LOKEV9: MOVEI T3,LOKEVB ;BIT INDICATING PAGE IS LOCKED IN EVM
PUSHJ P,LOKBTS ;TURN IT ON FOR EACH PAGE IN THE SEGMENT
PUSHJ P,CONEVA ;COMPLETE LARGEST HOLE IN EVM
PUSHJ P,CSDMP##
MOVE T1,.CPJOB##
MOVSI T2,(JS.NCS)
IORM T2,JBTST2##(T1)
PJRST TPOPJ1## ;RESTORE EV PAGE NUMBER AND GIVE SUCCESS RETURN
LOKEXT: PUSHJ P,LOKHPH ;GET THE USER'S FIRST ARGUMENT
PUSHJ P,CHKCSH ;SEE IF CACHE SHOULD BE OFF OR ON
PUSHJ P,GETWDU##
;HERE WITH T1= WHERE HIGH SEGMENT IS TO BE LOCKED,,WHERE LOW SEGMENT
; IS TO BE LOCKED, P1= LOW SEGMENT NUMBER,,HIGH SEGMENT NUMBER
MOVE P2,T1 ;SAVE WHERE,,WHERE
SETZM LOKREL## ;INITIALIZE FOR IORM
TLNN P1,-1 ;LOCKING BOTH SEGMENTS?
JRST LKSPH1 ;NO
HLRZ T2,T1 ;WHERE THE HIGH SEGMENT IS TO BE LOCKED
HRRZ T3,T1 ;WHERE THE LOW SEGMENT IS TO BE LOCKED
LDB T4,PCORSZ## ;HIGHEST PAGE IN THE LOW SEGMENT
ADDI T4,1+UPMPSZ##(T3)
CAIL T2,(T3) ;IF LOCKED AS REQUESTED,
CAIL T2,(T4) ; WILL THE HIGH AND LOW SEGMENTS OVERLAP?
CAIA ;NO
JRST ERROR6 ;YES, ERROR RETURN
LDB T4,[POINT 9,JBTADR##(P1),8]
ADDI T4,1(T2) ;TOP PAGE IN HIGH SEGMENT AFTER LOCKING
CAIL T3,(T2) ;IF LOCKED AS REQUESTED,
CAIL T3,(T4) ; WILL THE HIGH AND LOW SEGMENTS OVERLAP?
JRST LKSPH1 ;NO, ALL IS WELL SO FAR
JRST ERROR6
LKSPH1: HLRZ J,P1 ;LOW SEGMENT NUMBER IF LOCKING BOTH SEGMENTS
CAIG P1,JOBMAX## ;LOCKING BOTH SEGMENTS OR JUST THE HIGH SEGMENT?
JRST [HRRZ J,P1 ;NO, ONLY LOCKING THE LOW SEGMENT
JRST LKSPH2]
HLRZS T1 ;WHERE THE HIGH SEGMENT IS TO BE LOCKED
HRRZ J,P1 ;HIGH SEGMENT NUMBER
PUSHJ P,PHYPF ;ARE THE PAGES AVAILABLE FOR LOCKING?
JRST ERROR6 ;NO, ERROR RETURN
HRRZM T1,LOKREL## ;STORE WHERE THE HIGH SEGMENT IS TO BE LOCKED
HLRZ J,P1 ;LOW SEGMENT NUMBER IF LOCKING THE LOW SEGMENT
JUMPE J,LKSPH3 ;ALL DONE IF NOT LOCKING THE LOW SEGMENT
LKSPH2: HRRZ T1,P2 ;WHERE THE LOW SEGMENT IS TO BE LOCKED
PUSHJ P,PHYPF ;SEE IF THOSE PAGES ARE AVAILABLE FOR LOCKING
JRST ERROR6 ;NOT, LOSE
SKIPE LOKREL## ;HIGH SEGMENT TO BE LOCKED?
HRLZS T1 ;YES, PAGE NUMBER TO THE LEFT HALF WORD
IORM T1,LOKREL## ;WHERE LOW,,WHERE HIGH
LKSPH3: MOVE J,.CPJOB## ;CURRENT JOB NUMBER
PUSHJ P,LOCKIT ;LOCK THE SEGMENTS REQUESTED WHERE REQUESTED
JFCL ;CAN'T HAPPEN
JRST LOKJ19 ;GIVE JOB LOCKED RETURN
;SUBROUTINE TO DETERMINE IF A SEGMENT CAN BE LOCKED IN A SPECIFIC
; PLACE IN PHYSICAL MEMORY. I.E., DETERMINE THAT THE PAGES REQUIRED ARE
; EXISTANT, NOT LOCKED, AND NOT PART OF THE MONITOR.
;CALLING SEQUENCE:
; MOVE T1,STARTING PHYSICAL PAGE #
; MOVE J,SEGMENT #
; PUSHJ P,PHYPF
;RETURN CPOPJ, T1=LKERR6 IF THE PAGES ARE NOT AVAILABLE
; CPOPJ1 IF THEY ARE, T1 PRESERVED
PHYPF: LDB T2,[POINT 9,SYSSIZ##,26]
LDB T3,[POINT 14,MEMSIZ##,26]
CAIL T1,(T2) ;ABOVE THE MONITOR?
CAIL T1,(T3) ;AND BELOW THE TOP OF MEMORY?
POPJ P, ;NO, LOSE
LDB T2,PCORSZ## ;HIGHEST PAGE IN THE SEGMENT
ADDI T2,1 ;NUMBER OF PAGES IN THE SEGMENT
CAIG J,JOBMAX## ;IF A LOW SEGMENT,
ADDI T2,UPMPSZ## ;ACCOUNT FOR THE LOW SEGMENT SIZE
MOVE T3,T1 ;STARTING PAGE FOR LOCKING THE SEGMENT
IFN FTMP,<
PUSHJ P,GGVMM## ;MUST HAVE THE MM RESOURCE WHILE LOOKING AT PAGTAB
>
PHYPF1: MOVE T4,@[IW MS.MEM,PAGTAB(T3)] ;PAGTAB ENTRY REPRESENTING
; THIS PHYSICAL PAGE
TLNE T4,LKBITS ;LOCKED OR NON-EXISTANT PAGE?
POPJ P, ;YES, LOSE
SOSE T2 ;LOOKED AT ALL THE PAGES REQUIRED TO LOCK THE SEGMENT?
AOJA T3,PHYPF1 ;NO, CHECK THE NEXT PHYSICAL PAGE
AOS (P) ;SKIP RETURN (ALL PAGES FREEABLE)
LDB T2,PCORSZ## ;SIZE
PJRST SETLIP ;SET LOCK IN PROGRESS
;SUBROUTINE TO SET "LOCK IN PROGRESS" ON ALL PAGES WHERE A PHYSICALLY
;CONTIGUOUS LOCK IS BEING PERFORMED. MUST BE CALLED WITH MM
;CALL:
; MOVE T1,STARTING PAGE #
; MOVE T2,# OF PAGES TO SET FOR
; PUSHJ P,SETLIP
; RETURN
;PRESERVES ALL
SETLIP: SE1ENT ;MUST RUN IN S1 FOR PAGTAB/MEMTAB
PUSHJ P,SAVT##
PUSH P,T2 ;SAVE COUNT
MOVSI T4,(P2.LIP) ;LOCK IN PROGRESS
SETLI1: SKIPL T3,@[IW MS.MEM,PAGTAB(T1)] ;IS PAGE FREE?
JRST SETLI3 ;NO, CONTINUE
HRRZ T2,@[IW MS.MEM,PT2TAB(T1)] ;GET BACK LINK
TRNE T3,-1 ;IF THERE IS A SUCCESSOR,
HRRM T2,@[IW MS.MEM,PT2TAB(T3)] ;THEN SET PREDECESSOR
JUMPE T2,[HRRZM T3,PAGPTR## ;IF IT WAS THE FIRST ON THE FREE LIST
JRST SETLI2 ]
HRRM T3,@[IW MS.MEM,PAGTAB(T2)] ;DELINK FROM THE FREE LIST
SETLI2: HRRZ T2,LOKPTR## ;PUT IT ON LOKCON'S LIST
HRRM T2,@[IW MS.MEM,PAGTAB(T1)]
SKIPE T2
HRRM T1,@[IW MS.MEM,PT2TAB(T2)]
HLLZS @[IW MS.MEM,PT2TAB(T1)]
HRRZM T1,LOKPTR##
AOS LOKHOL## ;COUNT THE PAGE IN LOKHOL
AOS LOKTAL## ;AND IN LOKTAL
SOS CORTAL## ;DON'T COUNT TWICE
SOSA BIGHOL##
SETLI3: IORM T4,@[IW MS.MEM,PT2TAB(T1)] ;SET P2.LIP
SOSLE (P) ;MORE TO GO?
AOJA T1,SETLI1 ;YES
POP P,(P) ;CLEAR STACK
POPJ P,
;SUBROUTINE TO MOVE ALL PAGES FROM LOKCON'S QUEUE (LOKPTR) TO THE
;FREE QUEUE. THIS SHOULD BE CALLED JUST BEFORE
;THE ACTUAL LOCK IS DONE. CALL WITH J=SEGMENT #
CLRLOQ: PUSHJ P,SAVE3## ;SAVE SOME ACS
SKIPN P2,LOKPTR## ;GET LOKCON QUEUE
POPJ P, ;ALREADY MOVED
;* MOVSI P1,(P2.LIP) ;CLEAR THIS BIT
CLRLQ1: SSX P2,MS.MEM ;WHERE PT2TAB ETC. LIVE
HRRZ P3,P2 ;SAVE
;* ANDCAM P1,PT2TAB(P2) ;CLEAR P2.LIP IN ALL FREE PAGES
HRRZ P2,PAGTAB(P2) ;NEXT
JUMPN P2,CLRLQ1 ;CLEAR IT
MOVE P1,PAGPTR## ;START OF THE FREE LIST
SSX P3,MS.MEM ;SECTION
HRRM P1,PAGTAB(P3)
SSX P1,MS.MEM
HRRM P3,PT2TAB(P1)
MOVE P2,LOKPTR##
MOVEM P2,PAGPTR## ;NEW HEAD OF FREE LIST
MOVE P1,LOKTAL## ;COUNT
ADDM P1,CORTAL##
MOVE P1,LOKHOL##
ADDM P1,BIGHOL## ;PAGES ARE BACK ON THE FREE LIST
SETZM LOKHOL##
SETZM LOKTAL##
SETZM LOKPTR##
POPJ P,
;SUBROUTINE TO LOCK A JOB (ONE OR BOTH SEGMENTS) IN CONTIGUOUS
; PHYSICAL MEMORY
;CALLING SEQUENCE:
; MOVE P1,0,,LOW SEGMENT NUMBER IF LOCKING ONLY LOW SEGMENT, OR
; MOVE P1,0,,HIGH SEGMENT NUMBER IF LOCKING ONLY HIGH SEGMENT, OR
; MOVE P1,LOW SEGMENT NUMBER,,HIGH SEGMENT NUMBER IF LOCKING BOTH
; PUSHJ P,LOKPHY
;RETURN HERE IF NO HOLE IN PHYSICAL MEMORY IS BIG ENOUGH
;RETURN HERE, REQUESTED SEGMENTS ARE LOCKED IN CONTIGUOUS PHYSICAL MEMORY
LOKPHY::JUMPL P1,LOKPH1 ;IF LOCKING PAGES
HRRZ T2,P1 ;MAKE A USABLE INDEX
MOVE T2,JBTSTS##(T2) ;HIGH SEGMENT STATUS IF LOCKING THE HIGH SEGMENT
CAILE P1,JOBMAX## ;LOCKING THE HIGH SEGMENT?
TLNE T2,SHRSEG ;YES, IS IT SHARABLE?
CAIA ;YES
HLRZS P1 ;NO, LOCK LOW AND HIGH SEGMENT ALL AT ONCE
HLRZ J,P1 ;LOW SEGMENT NUMBER (OR ZERO)
LDB T1,IMGIN## ;SIZE OF THE LOW SEGMENT (OR ZERO)
LDB T2,NFYPGS## ;NUMBER OF FUNNY PAGES (OR ZERO)
ADD T1,T2 ;TOTAL
LDB T2,NZSSCN##
ADD T1,T2 ;# OF NZS MAPS
HRRZ J,P1 ;HISEG NUMBER (OR MAYBE LOWSEG)
LDB T2,IMGIN## ;SIZE OF IT
ADD T1,T2 ;TOTAL
CAILE J,JOBMAX## ;IS IT A LOWSEG?
JRST LOKPH1
LDB T2,NFYPGS## ;NUMBER OF FUNNY PAGES (IF IT'S A LOWSEG)
ADD T1,T2 ;YES, COUNT THAT TOO
LDB T2,NZSSCN##
ADD T1,T2
LOKPH1: JUMPE T1,LOKPH5 ;LOCK PAGES, ONLY SPECIFIC PAGES LISTED
MOVE T2,SYSSIZ## ;LOOK FOR A PLACE TO LOCK IT STARTING AT
; THE TOP OF THE MONITOR
LSH T2,W2PLSH ;CONVERT SYSSIZ TO PAGES
MOVE T3,MEMSIZ## ;LOOK THROUGH ALL OF USER CORE
LSH T3,W2PLSH ; A PAGE AT A TIME
IFN FTMP,<
PUSHJ P,MMOWN## ;IN CASE OWN MM ALREADY (LOCKING PAGES)
PUSHJ P,UPMM## ;MUST HAVE THE MM RESOURCE WHEN SCANNING PAGTAB
>
LOKPH2: TDZA T4,T4 ;LARGEST HOLE SEEN SO FAR
LOKPH3: ADDI T4,1 ;INCREMENT SIZE OF LARGEST HOLE
CAIN T3,(T2) ;LOOKED AT ALL OF CORE?
JRST LOKPH4 ;YES, SEE IF A BIG ENOUGH HOLE WAS FOUND
MOVE S,@[IW MS.MEM,PAGTAB(T2)] ;STATUS OF THIS PAGE
TLNN S,LKBITS ;IS IT LOCKED OR NON-EXISTANT?
AOJA T2,LOKPH3 ;NO, COUNT IT IN THIS HOLE
CAMG T4,T1 ;IS THIS HOLE BIG ENOUGH?
AOJA T2,LOKPH2 ;NO, LOOK HIGHER UP
LOKPH4: CAMG T4,T1 ;IS THE HOLE FOUND BIG ENOUGH?
IFN FTMP,<
PJRST DWNMM## ;NO, ERROR RETURN
>
IFE FTMP,<
POPJ P,
>
CAIG T2,PAGSIZ ;WILL THE JOB BE IN THE FIRST 256K OF CORE?
JRST LOKPH9 ;YES, WE'RE GOLDEN
JUMPL P1,LOKPH9 ;PAGE. USERS CAN TAKE CARE OF THEMSELVES
CAILE P1,JOBMAX## ;DOING JUST A LOWSEG?
SKIPA T3,P3 ;NO, KEEP BITS WHERE THEY WERE
MOVS T3,P3 ;YES, MOVE THEM FOR MY CONVENIENCE
TLNN P1,-1 ;DOING BOTH?
HLRS T3 ;NO, MAKE BOTH HALVES LOOK THE SAME
TRNE T3,LKAB!LKPB ;IF EITHER HALF
TLNN T3,LKAB!LKPB ;CARES,
IFN FTMP,<JRST DWNMM##> ;THEN IT LOSES
IFE FTMP,<POPJ P,> ;SO FAIL IT
LOKPH9: SUBI T2,(T4) ;STARTING PAGE NUMBER OF THE HOLE
HRRZM T2,LOKREL## ;SAVE THAT FOR LOCK
EXCH T1,T2
PUSHJ P,SETLIP ;SET "LOCK IN PROGRESS" AND MOVE PAGES
JUMPG P1,LOKPH8 ;IF ACTUALLY LOCKING ENTIRE JOB
LOKPH5: PUSHJ P,FSTPAG## ;;DO SPECIFIC LOCK PAGES ARGS
MOVN T3,P1 ;COUNT OF ARGS
LOKPH6: PUSHJ P,NXTLPG## ;GET NEXT PAGE
JUMPL T1,LOKPH7 ;AN UNLOCK PAGE
TRNN T1,-1 ;SPECIFIC PAGE REQUESTED?
JRST LOKPH7 ;NO, TOOK CARE OF THIS EARLIER
SSX T1,MS.MEM ;MAKE PAGTAB INDEX
SKIPL T2,PAGTAB(T1) ;IS PAGE FREE?
JRST [MOVSI T4,(P2.LIP) ;NO, JUST SET LOCK IN PROGRESS
IORM T4,PT2TAB(T1)
JRST LOKPH7] ;AND CONTINUE
HRRZ T4,PT2TAB(T1) ;PREVIOUS PAGE TO OURS (IF ANY)
SSX T2,MS.MEM ;PAGTAB IDX
TRNE T2,-1 ;IF THERE IS A SUCCESSOR TO US
HRRM T4,PT2TAB(T2) ;YES POINT US AT HIS PREDECESSOR (OR NONE)
SKIPE T4 ;IS THERE A PREDECESSOR
TLOA T4,(MS.MEM) ;YES, SET INDEX UP
MOVEI T4,PAGPTR-PAGTAB ;ELSE PREDECESSOR IS PAGTAB
HRRM T2,PAGTAB(T4) ;POINT PREDECESSOR AT SUCCESSOR
HRR T2,LOKPTR ;CURRENT 1ST PAGE IN LOKQUE
HRRZM T1,LOKPTR ;NEW 1ST PAGE IN LOKQUE
HLLZS PT2TAB(T1) ;WHICH HAS NO PREDECESSOR
HRRM T2,PAGTAB(T1) ;OUR SUCCESSOR
TRNE T2,-1
HRRM T1,PT2TAB(T2) ;POINT HIM AT US
AOS LOKHOL## ;DO THE BOOKEEPING
SOS BIGHOL##
AOS LOKTAL##
SOS CORTAL##
LOKPH7: SOJG T3,LOKPH6
LOKPH8:
IFN FTMP,<
PUSHJ P,DWNMM## ;RETURN MM
>
JUMPL P1,LOCKP
HRRZ J,P1 ;SIZE OF THE FIRST SEGMENT TO BE LOCKED
LDB T1,IMGIN##
CAIG P1,JOBMAX## ;LOCKING HIGH SEGMENT?
ADDI T1,UPMPSZ## ;NO, ACCOUNT FOR THE UPMP
ADD T1,LOKREL## ;STORE THAT FOR LOCK
TLNE P1,-1 ;LOCKING BOTH SEGMENTS?
HRLM T1,LOKREL## ;WHERE TO LOCK THE OTHER SEGMENT
CAILE P1,JOBMAX## ;LOCKING A HIGH SEG?
SKIPG J,.HBSGN(P4) ;YES, BE SURE IT'S A REAL SEG
JRST LOCKIT ;NO
TLNN J,SHRSEG ;AND THAT IT'S SHARABLE
JRST LOCKIT ;NOT SHARABLE
HRRZS J ;CLEAR JUNK
MOVEI T1,HSTOP## ;YES, FORCE OTHER USERS OF HIGH SEG TO STOP
TLO T1,(1B0) ;DON'T APPLY TO US
PUSHJ P,HGHAPP##
JRST LOCKIT ;NOW LOCK JOB
LOCKP: MOVN P2,P1 ;SAVE # OF ARGS IN P2 FOR CLOCK LEVEL
MOVE P1,.CPJOB##
MOVEI T1,PAGLOK## ;SET RH SIGN BIT TO INDICATE PAGE FORMAT
IORM T1,LOKREL##
LOCKIT: MOVEI T1,LOK ;MAKE THE JOB UNRUNNABLE UNTIL LOCKING
MOVE J,.CPJOB## ;(JOB # IN QUESTION)
IORM T1,JBTSTS##(J) ; IS COMPLETE
MOVEM P1,LOCK## ;STORE #S FOR LOCK
PUSHJ P,WSCHED## ;RESCHEDULE, RETURN WHEN JOB IS LOCKED
RASBAD: LDB T1,JBYLSA## ;STARTING PAGE NUMBER OF THE LOW SEGMENT
JUMPE P4,CPOPJ1## ;DONE IF NO HIGH SEG
SKIPG J,.HBSGN(P4) ;JOB HAVE A REAL HIGH SEGMENT?
PJRST CPOPJ1## ;NO HISEG, GIVE LOCKED RETURN (T1 = LOSEG ADDR)
TLNN J,SHRSEG ;SHARABLE?
JRST RASBD1 ;NO
HRRZS J ;CLEAR JUNK
MOVEI T1,HGO## ;..
TLO T1,(1B0) ;DON'T APPLY TO US
PUSHJ P,HGHAPP##
MOVE J,.HBSGN(P4) ;RELOAD J
RASBD1: TLO J,(1B0) ;MAKE J A REASONABLE INDEX
LDB T2,JBYHSA## ;STARTING PAGE NUMBER OF THE HIGH SEGMENT
HRL T1,T2 ;HIGH SEGMENT ADDRESS,,LOW SEGMENT ADDRESS
PJRST CPOPJ1## ;AND GIVE LOCKED RETURN
;
;ROUTINE TO FREE CORE GIVEN UP BY A LOCKED JOB
;CALLED FROM UUOCON ON RESET UUO FROM USER OR
;ON A CALL TO RESET FROM COMCON
;ALSO CALLED FROM KILHGH IN SEGCON
;
UNLOCK::MOVE T1,[XWD LKB,LKB];UNLOCK BOTH LOW AND HIGH SEGMENTS
UUNLOK::SE1ENT ;MUST BE RUN IN S1
PUSHJ P,SAVE4## ;SAVE P1-P4
SKIPGE P1,T1 ;INIT ARG POINTER; EXTENDED FORMAT LIST?
JRST UNLOKX ;YES, PROCESS IT
UNLRET: PUSHJ P,NSHCHK ;CHECK NON-SHARABLE PROBLEMS
JRST RTZER## ;NOT IMPLEMENTED
CAILE J,JOBMAX## ;JOB?
TDZA P4,P4 ;NO, NO HIGHER SEG THEN
HRRZ P4,JBTSGN##(J) ;IF JOB, POINT TO FIRST HIGH SEG
UNLOK1: PUSHJ P,UNLOK2 ;UNLOCK
JUMPL P1,UNLOX1 ;EXTENDED
JUMPE P4,CPOPJ1## ;NO, WE ARE DONE
HRRZ P4,.HBLNK(P4) ;IS THERE ANOTHER?
JUMPE P4,CPOPJ1## ;DONE
UNLOC1: SKIPLE T2,.HBSGN(P4) ;IS THIS A REAL HIGH SEG?
TLNN T2,SHRSEG!LOKSEG!NCSH ;SHARABLE OR REALLY LOCKED?
JRST UNLOC2 ;NO
HRRZS T2 ;CLEAR JUNK
MOVE T2,JBTSTS##(T2) ;GET STATUS WORD
TLNN T2,NSHF!NSWP ;LOCKED?
JRST UNLOC2 ;NO
PUSH P,J ;SAVE J
PUSHJ P,UNLOKH ;UNLOCK THAT SEGMENT
POP P,J ;RESTORE J
UNLOC2: HRRZ P4,.HBLNK(P4) ;NEXT
JUMPN P4,UNLOC1
AOS (P)
POPJ P,
UNLOKH::SE1ENT ;ENTER S1 HERE
MOVSI T1,LKB ;UNLOCK HIGH SEG
UNLOK2: PUSHJ P,SAVE4## ;PRESERVE ACCUMULATORS
PUSH P,T1 ;SAVE ARUMENT WHILE UNLOCKING
ZZ==. ;PLACE ON STACK FOR ARGUMENT (T1)
PUSH P,J ;SAVE JOB NUMBER
ZZ==.-ZZ ;DEPTH ON STACK FOR ARGUMENT (T1)
MOVSI P3,NSHF!NSWP
MOVEI J,(J) ;CLEAR POSSIBLE LEFT HALF BITS
CAILE J,JOBMAX## ;IS THIS A HIGH SEGMENT?
JRST UNLOK6 ;YES IF CALLED FROM SEGCON OR LOKINI
TRNE T1,LKB ;UNLOCK THE LOW SEGMENT?
TDNN P3,JBTSTS##(J) ;IS IT LOCKED?
JRST UNLOK3 ;NO
IFN FTRTTRP,<
S0PSHJ RTREL## ;RESET REAL TIME
>
PUSHJ P,FRELOK ;UNLOCK THE LOW SEGMENT
MOVSI P2,(JS.NCS) ;DON'T CACHE BIT
TDNE P2,JBTST2##(J)
PUSHJ P,CSHLSG
ANDCAM P2,JBTST2##(J) ;TURN THE CACHE ON AGAIN
MOVE T1,-ZZ(P) ;RESTORE ARGUMENT
HRROS -ZZ(P) ;FLAG THAT CORE HAS CHANGED (SO CALL LRGHOL)
UNLOK3: TRNE P4,-1 ;IS THERE A HIGH SEG TO UNLOCK?
TLNN T1,LKB ;UNLOCK THE HIGH SEGMENT?
JRST UNLOK7 ;NO
MOVSI P2,LOKSEG ;BIT TO TEST
ANDCAM P2,.HBSGN(P4) ;CLEAR LOCKED BIT FOR THIS SEG
SETZ T1, ;START AT THE BEGINNING
UNLO3A: PUSHJ P,GNXHSB## ;GT NEXT HIGH SEG BLOCK
JRST [ANDCAM P2,JBTSGN##(J)
JRST UNLO3C] ;ALL HIGH SEGS UNLOCKED
CAIE T1,(P4) ;IS IT THIS BLOCK?
TDNN P2,.HBSGN(T1) ;IS THIS SEGMENT LOCKED?
JRST UNLO3A ;THIS SEGMENT OR IT ISN'T LOCKED, CHECK NEXT
UNLO3C: MOVEI T1,(P4) ;HIGH SEG DATA BLOCK
S0PSHJ MAPHGH## ;TURN ON CACHE BITS IN THE MAP
SKIPGE .HBSGN(P4) ;SPY SEGMENT?
JRST UNLOK7 ;IGNORE THIS ONE
HRRZ J,.HBSGN(P4) ;SEGMENT #
LDB T1,JBYVAD## ;GET MAP ADDRESS
JUMPE T1,UNLOK7 ;NON-SHARABLE HIGH SEG
SOSLE .M2LCN-.M2MAX(T1) ;DECREMENT LOCKERS
JRST UNLOK7 ;DON'T UNLOCK IF OTHERE LOCKERS
UNLOK6: MOVSI T1,NSHF!NSWP ;IS HIGH SEGMENT LOCKED?
TDNN T1,JBTSTS##(J) ;?
JRST UNLOK7 ;NO, DO NOT UNLOCK HIGH SEGMENT
HRROS -ZZ(P) ;YES, FLAG FACT THAT A SEGMENT HAS
; BEEN UNLOCKED
PUSHJ P,FRELOK ;NO OTHER LOCKED JOB SHARING, UNLOCK IT
UNLOK7: HRRZ J,(P) ;GET INDEX INTO JOB TABLES
MOVE R,JBTADR##(J) ;RESTORE R
POP P,J ;RESTORE JOB NUMBER
POP P,T1 ;HAS CORE CHANGED?
JUMPGE T1,CPOPJ## ;NO, REMOVE ARGUMENT AND RETURN
;FALL INTO COMLIM
;SUBROUTINE TO RECOMPUTE CORMAX AND MAXMAX
COMLIM: PUSHJ P,LRGHOL ;SET EXTENT OF THE LARGEST HOLE
MOVEM T2,MAXMAX## ;LARGEST LEGAL CORMAX
SUBI T2,NWMCP+PAGSIZ ;ACCOUNT FOR FUNNY SPACE
MOVEM T2,RMCMAX## ;SET "REAL" MAXIMUM VALUE OF CORMAX
HRRZ P1,CORLIM## ;AND ADJUST CORMAX
ASH P1,P2WLSH
CAMLE P1,T2 ;TO CORLIM OR SIZE OF HOLE
MOVE P1,T2 ;WHICH EVER IS SMALLER
MOVEM P1,CORMAX##
POPJ P, ;RETURN
;ROUTINE TO PROCESS EXTENDED FORMAT UNLOCK
UNLOKX:
UNLOX1: AOBJP P1,CPOPJ1## ;EXIT SUCCESS IF DONE
HRRZ T1,P1 ;GET NEXT ARG
PUSHJ P,GETWDU## ;FRUM USER
TRNN T1,L2SGN ;JOB OR SEGMENT?
JRST UNLOXL ;LOW SEG
PUSHJ P,FNDHSB## ;POINT TO THE HIGH SEG BLOCK
JRST RTZER## ;NOT FOUND ***SHOULD USE REAL ERROR***
MOVE P4,T1 ;PUT BLOCK ADDR IN P4
MOVSI T1,LKB ;FLAG TO UNLOCK HIGH SEG
JRST UNLRET ;AND RETURN
UNLOXL: SETZ P4, ;NO HIGH SEG
MOVEI T1,LKB ;UNLOCK LOW SEG
JRST UNLRET ;AND DO THE UNLOCK
FRELOK: MOVSI T1,NSHF!NSWP
ANDCAM T1,JBTSTS##(J) ;TURN OFF NSHF AND NSWP
CAILE J,JOBMAX## ;IS IT A HIGH SEGMENT?
JRST FRELK0 ;NO, IF THIS IS A LOW SEG...
SETZ T1, ;THEN ALL NON-SHARABLE
FRELKA: PUSHJ P,GNXHSB## ;HIGH SEGS ARE ALSO BEING UNLOCKED NOW
JRST FRELK0 ;DONE IF NO MORE
SKIPLE T2,.HBSGN(T1) ;IS THIS A REAL HIGH SEG?
TLOE T2,<(IFIW)>!SHRSEG ;AND IS IT NON-SHARABLE
.CREF SPYSEG ;(TURN ON IFIW WHICH IS ALSO SPYSEG
;AND MUST BE OFF TO BE HERE)?
JRST FRELKA ;SPY OR SHARABLE, LOOP ON
MOVSI T3,NSHF!NSWP
ANDCAM T3,JBTSTS##(T2) ;CLEAR LOCKED BITS FOR HIGH SEG
MOVSI T3,LOKSEG
ANDCAM T3,.HBSGN(T1) ;AND IN THIS HIGH SEG BLOCK
JRST FRELKA ;AND GO ON
FRELK0: LDB T1,JBYSSA## ;PAGE NUMBER OF FIRST PAGE OF THE SEGMENT
MOVSI T2,LOKEVB ;BIT INDICATING LOCKED IN EVM
TDNN T2,@[IW MS.MEM,PAGTAB(T1)] ;IS IT?
JRST FRELK2 ;NO, PROCEED
PUSH P,T1 ;SAVE STARTING PAGE NUMBER
LDB T1,IMGIN##
HRRZ T3,JBTADR##(J) ;EVA OF SEGMENT
LSH T3,W2PLSH ;STARTING PAGE NUMBER
CAILE J,JOBMAX## ;A LOW SEGMENT?
JRST [PUSHJ P,SEGSIZ##
MOVE T1,T2
JRST FRELK1] ;NO, SKIP ON
ADDI T1,UPMPSZ## ;YES ACCOUNT FOR THE MAP
SUBI T3,UPMPSZ## ; WHICH IS ALSO MAPPED
FRELK1: MOVN T4,T1 ;GET THE NUMBER OF PAGES IN SEGMENT
ADDM T4,.C0EVU## ;AND INDICATE THAT EVM IS NO LONGER USED
MOVE T2,EVMPTR## ;AOBJN POINTER FOR RETURNING SLOTS
S0PSHJ ZERBTS## ;RETURN EVM
PUSHJ P,CONEVA
POP P,T1 ;RESTORE STARTING PAGE NUMBER
FRELK2: MOVE R,JBTADR##(J) ;EVA OF SEGMENT
HRRI R,.VJDT ;ASSUME ITS A HIGH SEGMENT
CAILE J,JOBMAX## ;IS IT?
JRST FRELK3 ;YES
HRRI R,.JDAT ;ITS A LOW SEGMENT - EVA OF THE JOB DATA AREA
CAMN J,.CPJOB## ;ONLY UPDATE .CPADR IF IT'S THIS JOB
MOVEM R,.CPADR## ;RESET SOFTWARE RELOCATION INFO
HRRZ T3,P ;DIDDLE THE PUSH DOWN LIST POINTER
MOVEI T2,PDLPNO## ;PAGE NUMBER (EVA) OF THE PUSH DOWN LIST
CAMLE T3,SYSSIZ## ;IS THE PUSH DOWN LIST IN THE MONITOR?
DPB T2,[POINT 9,P,26];NO, AJUST RELOCATION
FRELK3: MOVEM R,JBTADR##(J) ;UPDATE JBTADR
FRELK4: MOVSI T2,LKBITS ;BITS INDICATING A PAGE IS LOCKED
ANDCAB T2,@[IW MS.MEM,PAGTAB(T1)] ;CLEAR THEM
HRRZ T1,T2 ;NEXT PAGE IN THE SEGMENT
JUMPN T1,FRELK4 ;LOOP IF MORE PAGES IN THE SEGMENT
CAILE J,JOBMAX## ;IS THIS A LOW SEGMENT?
POPJ P, ;NO, RETURN
HRRZ T1,JBTUPM##(J) ;YES, UNLOCK THE UPMP
MOVSI T2,LKBITS ;BITS INDICATING PAGES IS LOCKED
ANDCAM T2,@[IW MS.MEM,PAGTAB(T1)] ;CLEAR THEM FOR THE UPMP
HRRZ T1,@[IW MS.MEM,PAGTAB(T1)] ;GET THE MAP PAGE TOO.
ANDCAM T2,@[IW MS.MEM,PAGTAB(T1)]
POPJ P, ;AND RETURN
;SUBROUTINE TO DETERMINE IF A RANGE OF MEMORY OVERLAPS LOCKED JOBS
; AND IF SO, RETURN ALL THE JOBS WHICH OVERLAP THE RANGE
CKLJB:: SE1ENT ;NEED TO BE EXTENDED TO LOOK AT PAGTAB
ADDI J,1 ;NEXT JOB
CAMLE J,HIGHJB## ;UP TO THE HIGHEST JOB IN THE SYSTEM?
POPJ P, ;YES, ALL DONE
MOVE T3,JBTSTS##(J) ;JOB STATUS FOR THE CURRENT JOB
TLNN T3,NSHF!NSWP ;IS IT LOCKED?
JRST CKLJB1 ;NO, CHECK ITS HIGH SEGMENT
HRRZ T3,JBTUPM##(J) ;ADDRESS OF THE JOBS PAGE MAP
PUSHJ P,CKRNG ;SEE IF THATS WITHIN THE RANGE
JRST CPOPJ1## ;YES, INDICATE OVERLAP
LDB T3,JBYLSA## ;PAGE ZERO OF THE JOB
PUSHJ P,CKPGS ;SEE IF ANY OF THE JOBS PAGES OVERLAP THE RANGE
JRST CPOPJ1## ;YES, INDICATE THAT TO THE CALLER
CKLJB1: MOVSI T3,LOKSEG ;THIS JOB HAVE A LOCKED HIGH SEG?
TDNN T3,JBTSGN##(J) ;?
JRST CKLJB ;NO, LOOK AT THE NEXT JOB
PUSH P,T1 ;SAVE T1 (LOWER BOUND)
SETZ T1, ;FIRST CALL
CKLJB2: PUSHJ P,GNXHSB## ;GET NEXT HIGH SEG BLOCK
JRST CKLJB3 ;NO MORE
TDNN T3,.HBSGN(T1) ;IS THIS SEGMENT LOCKED?
JRST CKLJB2 ;NO, LOOK AT NEXT
HRRZ T3,.HBSGN(T1) ;GET SEGMENT #
LDB T3,[POINT 13,JBTHSA##(T3),35]
EXCH T1,(P) ;SAVE CURRENT HS BLOCK, GET LIMIT
PUSHJ P,CKPGS ;SEE IF THE HIGH SEGMENT PAGES OVERLAP THE RANGE
JRST T3POJ1## ;THEY DO, TELL THE CALLER
EXCH T1,(P) ;STORE LIMIT, GET HIGH SEG BLOCK BACK
JRST CKLJB2 ;CHECK ANOTHER HIGH SEG
CKLJB3: POP P,T1 ;RESTORE T1
JRST CKLJB ;THEY DON'T SO LOOK AT THE NEXT JOB
;SUBROUTINE TO DETERMINE IF ATTEMPTING TO SET MONITOR PAGES OFF-LINE
CKMOL:: SE1ENT ;TO INDICATE THE ENTIRE MODULE RUNS EXTENDED
LDB T3,[POINT 9,SYSSIZ##,26]
CAIL T1,(T3) ;LOWER BOUND BELOW SYSSIZ?
AOS (P) ;NO, INDICATE GOODNESS
POPJ P, ;RETURN
;SUBROUTINE TO COMPUTE THE VALUE CORMAX WOULD HAVE IF A RANGE OF PAGES
; WERE TO BE SET OFF LINE
NEWCMX::SE1ENT ;MUST BE EXTENDED TO LOOK AT PAGTAB
MOVEI T3,0 ;NUMBER OF ON LINE PAGES IN THE RANGE
MOVSI T4,NXMBIT ;BIT INDICATING PAGE IS NON-EXISTANT
NEWCM1: TDNN T4,@[IW MS.MEM,PAGTAB(T1)] ;IS THIS PAGE NOW ON LINE
ADDI T3,PAGSIZ ;YES, COUNT IT
CAIE T1,-1(T2) ;LOOKED AT ALL THE PAGES IN THE RANGE?
AOJA T1,NEWCM1 ;NO, LOOK AT THE NEXT PAGE
MOVE T1,MAXMAX## ;CURRENT MAXIMUM VALUE FOR CORMAX
SUB T1,T3 ;NEW MAXIMUM VALUE FOR CORMAX IF PAGES
; IN THE RANGE WERE SET OFF
POPJ P, ;RETURN THE NUMBER TO THE CALLER
;HERE TO SET MEMORY OFF LINE (T1 = FIRST PAGE TO SET OFF, T2 = HIGHEST
; PAGE TO SET OFF)
MEMOFL::HRRZ S,T1 ;LOWER BOUND
HRL S,T2 ;UPPER BOUND
JSP T2,SAVCTD## ;GET TO UUO LEVEL
HRRZ T1,S ;RESTORE LOWER BOUND
HLRZ T2,S ;AND UPPER BOUND
MEMOFU::SKIPE LOCK## ;LOCKING IN PROGRESS?
PUSHJ P,DELAY1## ;YES, WAIT A WHILE AND TRY AGAIN
MOVE T3,[NXMTAB##,,OLDNXM##] ;SET UP BLT TO COPY NXMTAB
BLT T3,NXMTAB##+NXMTBL##-1 ;MAKE "OLD" COPY OF ERROR LOGGING
LDB T3,[POINT 14,MEMSIZ##,26]
CAIL T1,(T3) ;TRYING TO SET MEMORY OFF ABOVE THE TOP OF MEMORY?
POPJ P, ;YES, IT'S ALREADY OFF
CAIL T2,(T3) ;HIGH PAGE ABOVE THE TOP OF MEMORY?
MOVE T2,T3 ;YES, SET HIGH PAGE TO LAST PAGE OF MEMORY
MOVEM T1,LOKREL## ;FIRST PAGE TO SET OFF
SUB T2,T1 ;COMPUTE THE NUMBER OF PAGES IN THE RANGE
HRLM T2,LOKREL## ;STORE THAT FOR LOCK
MOVEI T3,0 ;ASSUME NO MONITOR PAGES TO MOVE AND NO
; ON LINE PAGES TO SET OFF
SE1ENT ;GO INTO SECTION 1 NOW, TO LOOK AT PAGTAB..
MEMOF1: MOVE T4,@[IW MS.MEM,PAGTAB(T1)] ;PAGE DESCRIPTOR BITS
TLNE T4,MONTRB ;DOES THIS PAGE CONTAIN MONITOR CODE?
AOSA T3 ;YES, COUNT UP THE NUMBER OF MONITOR PAGES
TLNN T4,NXMBIT ;DOES THIS PAGE EXIST (IS IT ON LINE)?
TLO T3,-1 ;YES, INDICATE AT LEAST ONE ON LINE PAGE SEEN
ADDI T1,1 ;NEXT PAGE IN THE RANGE
SOJG T2,MEMOF1 ;LOOK AT EVERY PAGE IN THE RANGE
JUMPGE T3,CPOPJ## ;EXIT IF NO ONLINE PAGES SEEN
PUSHJ P,CAWAIT## ;GET THE CA RESOURCE
HRROM J,LASLOK## ;INDICATE SETTING MEMORY OFF-LINE AND SAVE JOB NUMBER
IFN FTMP,<
PUSHJ P,ONCPU0## ;MAKE SURE ON THE BOOT CPU
>; END IFN FTMP
TRNN T3,-1 ;MOVING MONITOR PAGES?
JRST MEMOF2 ;NO, GO SET THE PAGES OFF
PUSH P,T3 ;SAVE THE NUMBER OF MONITOR PAGES BEING SET OFF
IFN FTENET&FTKL10,<
PUSHJ P,KNIMOF## ;INFORM KLNI ABOUT MEMORY GOING OFFLINE
>; END IFN FTENET&FTKL10
IFN FTSCA,<
PUSHJ P,PPDMFL## ;DO PHYSICAL PORT DRIVER MEMORY OFFLINE CHECKS
>; END IFN FTSCA
MOVEI T1,3 ;SLEEP 3 SECONDS TO LET THINGS SETTLE DOWN
S0PSHJ SLEEPF## ;ZZZZZZ
POP P,T3 ;RESTORE NUMBER OF MONITOR PAGES
HRRZM T3,MOFLPG## ;STORE THE NUMBER OF MONITOR PAGES WHICH MUST BE MOVED
IFN FTMP,<
PUSHJ P,CP1STP## ;ASK CPU1 TO JUMP INTO ITS ACS
PUSHJ P,DELAY1## ;AND WAIT UNTIL IT DOES
>; END IFN FTMP
MEMOF2: SETOM LOCK## ;INDICATE SETTING PAGES OFF LINE IS IN PROGRESS
MOVEI T1,LOK ;PREVENT THE JOB FROM RUNNING UNTIL DONE
IORM T1,JBTSTS##(J) ; ..
PUSHJ P,USCHED## ;COME BACK WHEN THE MEMORY HAS BEEN SET OFF
PUSHJ P,CAFREE## ;MAKE THE LOCK RESOURCE AVAILABLE
IFN FTENET&FTKL10,<
PUSHJ P,KNIMON## ;LET KLNI KNOW THE COAST IS CLEAR
>; END IFN FTENET&FTKL10
IFN FTSCA,<
PUSHJ P,PPDMON## ;LET PHYSICAL PORT DRIVER CLEAN UP AS REQUIRED
>; END IFN FTSCA
IFN FTMP,<
HRROI T1,[MOVEM T2,.CPOK##-.CPCDB##(P1)
POPJ P,]
MOVN T2,TICSEC## ;ONE SECOND TO GET THEIR OWN OK WORDS GOING AGAIN
PUSHJ P,CPUAPP## ;GIVE THE OTHER CPUS THIS MUCH TIME
SETZM MOFLPG## ;NOT SETTING MONITOR PAGES OFF LINE
>
MOVEI T1,.CSCMF ;CONFIG STATUS CHANGE CODE
PUSHJ P,MEMELG## ;MAKE AN ERROR LOG ENTRY
PJRST SETEDV## ;RESET EDV POINTERS AND RETURN
;SUBROUTINE TO CHECK IF A PAGE LIES WITHIN THE RANGE SPECIFIED BY T1 AND T2
CKRNG: CAIL T3,(T1) ;LESS THAN THE LOWER BOUND?
CAIL T3,(T2) ;OR GREATER THAN THE UPPER BOUND?
AOS (P) ;YES, NOT IN THE RANGE
POPJ P, ;RETURN
;SUBROUTINE TO CHECK IF ANY OF THE PAGES BELONGING TO A SEGMENT LIE
; WITHIN THE RANGE SPECIFIED BY T1 AND T2
CKPGS: PUSHJ P,CKRNG ;CHECK THIS PAGE
POPJ P, ;ITS WITHIN THE RANGE
HRRZ T3,@[IW MS.MEM,PAGTAB(T3)] ;GET THE NEXT PAGE OF THE SEGMENT
JUMPE T3,CPOPJ1## ;GOOD RETURN IF THIS IS THE LAST PAGE OF THE SEGMNET
JRST CKPGS ;CHECK THE NEXT PAGE
;SUBROUTINE TO CHECK IF LOCKING/UNLOCKING JUST HIGH OR LOW SEG OF
;JOB WITH A NON-SHARABLE HIGH SEG. RETURN CPOPJ IF ARE, CPOPJ1 IF NOT (OK CASE)
;USES T2
NSHCHK: PUSH P,T1 ;SAVE T1
HLRZ T2,T1 ;GET HIGH SEG LOCK BITS
XORI T2,(T1) ;ARE BOTH SEGS TO BE LOCKED/UNLOCKED?
TRNN T2,LKB ;?
JRST TPOPJ1## ;YES, NO SWEAT
SETZ T1, ;START LOOP
MOVSI T2,SHRSEG!SPYSEG ;MUST BE SHARABLE
NSHCK0: PUSHJ P,GNXHSB## ;NEXT HIGH SEG
JRST TPOPJ1## ;ALL IS CLEAR
TDNE T2,.HBSGN(T1) ;IS THIS HIGH SEG SHARABLE?
JRST NSHCK0 ;YES, ALL STILL OK
POP P,T1 ;RESTORE T1
POPJ P, ;HAS A NON-SHARABLE HIGH SEG
;SUBROUTINE TO DETERMINE THE NUMBER OF UNLOCKED PAGES IN USER CORE
LRGHOL: PUSHJ P,SAVE3##
MOVEI T2,0
MOVE P1,MEMSIZ##
SUB P1,SYSSIZ##
LSH P1,W2PLSH
MOVE P2,SYSSIZ##
LSH P2,W2PLSH
LRGHL1: MOVE P3,@[IW MS.MEM,PAGTAB(P2)]
TLNN P3,LKBITS
ADDI T2,PAGSIZ
ADDI P2,1
SOJG P1,LRGHL1
POPJ P,
;SUBROUTINE TO TURN ON BITS INDICATING A PAGE IS LOCKED IN A SPECIFIED WAY
LOKBTS: MOVSI T1,NSHF!NSWP
IORM T1,JBTSTS##(J)
LDB T1,JBYHSA##
CAILE J,JOBMAX##
JRST LOKBT1
HRRZ T1,JBTUPM##(J)
MOVSI T2,(T3)
IORM T2,@[IW MS.MEM,PAGTAB(T1)]
LDB T1,JBYLSA##
LOKBT1: MOVSI T2,(T3)
IORB T2,@[IW MS.MEM,PAGTAB(T1)]
HRRZ T1,T2
JUMPN T1,LOKBT1
POPJ P,
GETLOW: LDB P1,JBYLSA## ;LOW SEGMENT PHYSICAL ADDRESS
MOVE T1,P3 ;COPY OF ARG
TRNN T1,LKB ;LOCKING LOW SEGMENT?
JRST LOWADR ;NO, GET ADDRESS ANYWAY
MOVE T4,@[IW MS.MEM,PAGTAB(P1)] ;LOCK STATUS
MOVSS T1 ;SET UP FOR CHECKING USER ARGUMENT
PUSHJ P,ARGCK1 ;IS LOCK POSSIBLE?
JRST ERROR7 ;NO. USER ARGUMENT IS INVALID
LOWADR: TLNN T1,LKEB ;LOCKED IN EVM?
LDB P1,[POINT 9,JBTADR##(J),26] ;YES. LOAD EVA FOR USER.
MOVE T1,P1 ;LOW ADDRESS
HRL T1,T3 ;HIGH ADDRESS
PJRST CPOPJ1## ;RETURN WITH VALUES IN T1
ERROR1: MOVEI T1,LKERR1
PJRST STOTAC##
ERROR2: MOVEI T1,LKERR2
PJRST ERRRET
ERROR3: MOVEI T1,LKERR3
PJRST ERRRET
ERROR4: POP P,T1
ERROR5: PUSHJ P,UNLOCK
PUSHJ P,COMLIM ;RECOMPUTE CORMAX/MAXMAX
MOVEI T1,LKERR4
PJRST ERRRET
ERROR6: MOVEI T1,LKERR6
ERRRET: PUSHJ P,STOTAC##
PJRST CAFREE##
;SUBROUTINE TO FIND THE LARGEST CONTIGUOUS CHECK
ERROR7: MOVEI T1,7 ;ATTEMPTED TO CHANGE LOCK STATUS
PJRST STOTAC## ;WITH A LOCK UUO
;SUBROUTINE TO CHECK USER'S ARGUMENT WHEN SEGMENT IS ALREADY LOCKED
ARGCK1: TLNN T4,LOKPHB ;PHYSICALLY CONTIGUOUS?
TLNE T1,LKPB ;ASKING FOR IT?
SKIPA ;NO. SO FAR SO GOOD
POPJ P, ;CAN'T MAKE IT CONTIGUOUS
TLNN T4,LOKEVB ;LOCKED IN EVM?
TLNE T1,LKEB ;ASKING FOR IT?
JRST CPOPJ1## ;NO. ALL IS WELL
POPJ P, ;NOT IN EVM, SO USER CAN'T LOCK IT
;SUBROUTINE TO FIND THE LARGEST CONTIGUOUS CHUNK
; OF EVM AVAILABLE FOR MAPPING BUFFERS
CONEVA::PUSHJ P,SAVE4##
MOVE P1,EVMPTR##
MOVEI P2,0
MOVEI P3,-1
PUSHJ P,GETZ##
MOVEM P2,EVBMAX##
POPJ P,
;SUBROUTINE TO CHECK WHETHER THE CACHE SHOULD BE ON OR OFF
CHKCSH: MOVE J,.CPJOB##
TRNE T1,LKB
TRNE T1,LKCB
JRST CHKCS2
MOVSI T2,(JS.NCS)
IORM T2,JBTST2##(J)
CHKCS1: MOVE J,.CPJOB##
CHKCS2: SKIPG .HBSGN(P4)
POPJ P,
TLNE T1,LKB
TLNE T1,LKCB
POPJ P,
MOVSI T2,NCSH
IORM T2,.HBSGN(P4)
POPJ P,
;SUBROUTINE TO SEE IF THIS IS THE FIRST PAGE OF
; A NON-SHARABLE HIGH SEGMENT
FPNSHS: SKIPN P4
POPJ P,
ADDI P4,PAGSIZ
PUSHJ P,SAVT##
PUSHJ P,SAVE1## ;SAVE P1
MOVE P1,.USSPT
SETZ T1,
FPNSH1: PUSHJ P,NXSSP1## ;GET NEXT SEGMENT THIS SECTION
POPJ P, ;NONE
PUSH P,T1 ;SAVE T1
HRRZ T1,M
PUSHJ P,TPAHS##
SKIPA T4,T1
JRST TPOPJ## ;NOT SHARABLE
POP P,T1 ;RESTORE T1
PUSH P,J
HRRZ J,.HBSGN(T1) ;GET SEGMENT NUMBER
SKIPL P4
HRRM P4,JBTADR##(J)
DPB T4,JBYHSA##
MOVSI T1,NSHF!NSWP
IORM T1,JBTSTS##(J)
MOVEI P4,0
JRST JPOPJ##
;SUBROUTINE TO CACHE THE LOW SEGMENT
CSHLSG: PUSHJ P,SAVE2##
PUSH P,M
LDB P1,IMGIN##
SETZM .USSPT
CSHLS1: PUSHJ P,NXTWSB##
CAIA
CSHLS2: PUSHJ P,NXTWS3##
TRNE M,<-1^!HLGPNO> ;USER PAGE?
AOSA .USSPT
SKIPA P2,(T4)
JRST CSHLS1
TLO P2,(PM.CSH)
MOVEM P2,(T4)
SOJG P1,CSHLS2
JRST MPOPJ##
SUBTTL SEGCON - ROUTINES TO HANDLE HIGH SEGMENTS
;
;ROUTINE TO DETERMINE WHETHER THE IDLE HIGH SEGMENT FOR THE JOB CURRENTLY
; BEING SWAPPED CAN BE SWAPPED
;
; CALLING SEQUENCE
;
; MOVE J,HIGH SEGMENT NUMBER
; PUSHJ P,SWPHGH
; ... ;RETURN HERE TO SWAP ONLY THE LOW SEGMENT SINCE
; ; THE HIGH SEGMENT IS LOCKED OR BEING LOCKED
; ; T1 CONTAINS THE LOW SEGMENT NUMBER
; ... ;RETURN HERE IF HIGH SEGMENT CAN BE SWAPPED
;
LOKHGH::PUSH P,SWPOUT## ;JOB NUMBER OF JOB BEING SWAPPED - MUST
; BE SETUP FOR INCREMENTING IN CORE COUNT
; IF HIGH SEGMENT CANNOT BE SWAPPED
MOVE T1,LOCK## ;GET HIGH SEGMENT NUMBER IF LOCKING ONLY
; A HIGH SEGMENT
MOVSI T2,NSHF!NSWP ;CANNOT SWAP THE HIGH SEGMENT IF ITS LOCKED
CAIE T1,(J) ;IS THIS A HIGH SEGMENT WHICH IS CURRENTLY
; BEING LOCKED?
TDNE T2,JBTSTS##(J) ;IS IT LOCKED
JRST TPOPJ## ;YES, GIVE DON'T SWAP RETURN (T1=JOB #)
HLRZ T1,LOCK## ;JOB NUMBER OF JOB BEING LOCKED
CAME T1,SWPOUT## ;SAME AS JOB BEING SWAPPED?
AOS -1(P) ;NO, OK TO SWAP THE HIGH SEGMENT
JRST T2POPJ## ;POP OFF JUNK AND GIVE SKIP OR NON-SKIP RETURN
SUBTTL INITIALIZATION
$INIT
LOKINI::HRREI T1,LOKMAX## ;SET GUARANTEED CORE FOR T-S JOBS
SKIPGE DEBUGF## ;DEBUGGING?
MOVEI T1,0 ;THE SKY'S THE LIMIT
JUMPL T1,LOKIN1
ASH T1,P2WLSH ;MAKE PAGES INTO WORDS
CAML T1,MEMSIZ##
LOKIN1: MOVE T1,CORMAX## ;CORMIN_CORMAX
MOVEM T1,CORMIN## ;SAVE IT FOR TESTING
POPJ P, ;RETURN
$HIGH
LOKEND: END