Trailing-Edge
-
PDP-10 Archives
-
bb-bt99h-bb
-
lokcon.x14
There are 3 other files named lokcon.x14 in the archive. Click here to see a list.
TITLE LOKCON - MODULE FOR LOCKING JOBS IN CORE - V301
SUBTTL J. FLEMMING TS 17 JUN 86
SEARCH F,S
$RELOC
$HIGH
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
; OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
.CPYRT<1973,1986>
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986
;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL RIGHTS RESERVED.
XP VKILOK,301 ;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
LKERR1==1
LKERR2==2
LKERR3==3
LKERR4==4
LKERR5==5
LKERR6==6
LKB==1
LKEB==2
LKPB==4
LKCB==10
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
LOCK3: SKIPGE T1,@[IW MS.MEM,PAGTAB(P3)] ;PAGE ON THE FREE CORE LIST?
JRST LOCK13 ;YES, LOOP ON
IFN FTIPCF,<
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 P1,P3 ;NO, PAGE NUMBER TO P1
JRST LOCK13 ;LOOK AT THE NEXT PAGE
LSH P1,P2WLSH## ;CONVERT PAGE NUMBER TO AN ABSOLUTE ADDRESS
PUSHJ P,CPIASN## ;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 LOCK13 ;YES, NO ACTION NECESSARY
CAIG J,JOBMAX## ;IS THE SEGMENT CONTAINING THE PAGE WHICH
; MUST BE MOVED A HIGH SEGMENT?
JRST LOCK10 ;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 LOCK6 ;NO, MUST SWAP OUT THE LOW SEGMENTS SHARING
; IT TO MAKE IT GO AWAY
LOCK5: 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
LOCK6: MOVE T2,J ;SAVE HIGH SEGMENT NUMBER
MOVE J,HIGHJB## ;FIND A JOB SHARING IT
LOCK7: SKIPLE T1,JBTSGN##(J) ;THIS JOB HAVE A HIGH SEGMENT?
CAIE T2,(T1) ;YES, IS IT THE ONE WE WANT TO SWAP?
JRST LOCK9 ;NO, LOOK AT NEXT JOB
SKIPE JBTADR##(J) ;IS JOB IN CORE?
JRST LOCK8 ;YES, GO SEE IF IT CAN BE SWAPPED OUT
MOVE T2,J ;SAVE JOB NUMBER BEFORE CALLING DECCNT
EXCH J,T1 ;J=HIGH SEG T1=JOB
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,LOCK5 ;NO MORE JOBS SO SWAP OUT HIGH SEG
EXCH J,T2 ;GET READY TO LOOK AT NEXT JOB
JRST LOCK9 ;GO DO IT
LOCK8: 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 LOCK9 ;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 LOCK11 ;NO, SWAP OUT THE JOB
LOCK9: SOJG J,LOCK7 ;LOOK AT NEXT JOB
STOPCD .,STOP,SSO, ;++SEGMENT SWAPPED OUT
LOCK10:
IFN FTMP,<
PUSHJ P,ANYRUN## ;RUNNING ON CPU1?
JRST LOCK12 ;YES
>
LOCK11: 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
LOCK12: MOVEM J,SW0JOB## ;TELL CPU1 TO STOP RUNNING THE JOB
POPJ P, ;AND RETURN
LOCK13: 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
HRRZ J,LOCK## ;SEGMENT NUMBER OF SEGMENT BEING LOCKED
SKIPN JBTADR##(J) ;IS THIS SEGMENT IN CORE?
JRST [HRRZ J,LASLOK## ;NO, GO CAUSE IT TO BE SWAPPED IN
S0JRST FIT1##]
;ALLOCATE CORE, BLT SEGMENT INTO PLACE, AND LOCK IT
CAILE J,JOBMAX## ;IS IT A HIGH SEGMENT?
JRST LOCK14 ;NO, 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
LOCK14: MOVE R,JBTADR##(J) ;ANYACT REQUIRES THAT R BE SETUP
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
CAILE J,JOBMAX## ;IS THIS SEGMENT A LOW SEGMENT?
JRST LOCK16 ;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
CAIN T1,(P2) ;IS THE UPMP ALREADY IN PLACE?
TDZA P3,P3 ;YES, DOESN'T NEED TO BE MOVED
PUSHJ P,PAGMOV ;MOVE THE UPMP TO THE DESIRED POSITION
MOVSI T1,(P2.LIP) ;IN CASE PAGMOVE NOT CALLED
ANDCAM T1,@[IW MS.MEM,PT2TAB(P2)] ;CLEAR P2.LIP ON THIS PAGE
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 LOCK15 ;NO
MOVE T1,.CPMAP##
MOVE T1,.ECKSM/PAGSIZ##(T1)
;(PM.CSH OFF ALREADY)
MOVEM T1,.EUPMP+.UMJDT
DPB T1,JBYLSA##
LOCK15: 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
PUSHJ P,STEUB## ;AND MAKE THE UPMP ADDRESSABLE THROUGH
; THE PER PROCESS MAP (CLEAR THE AM)
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
LOCK16: LDB P3,IMGIN## ;NUMBER OF PAGES IN THE SEGMENT
CAILE J,JOBMAX##
JRST LOCK17
LDB T1,NFYPGS##
ADDI P3,-UPMPSZ##(T1)
LDB T1,NZSSCN##
ADDI P3,(T1)
SETZM .USSPT
MOVSI P4,400000
LOC16A: PUSHJ P,NXTWSB##
JRST LOC19D
LOCK17: MOVE T2,P1
PUSHJ P,SNPAGS##
CAIE T1,(P2)
PUSHJ P,PAGMOV
JUMPN P1,LOCK19
DPB P2,JBYHSA##
JRST LOCK19
LOCK18: CAIN T4,.UPMP+.UMUPT ;IS THIS THE UPT
JRST LOC19C ;YES, ALREADY DONE
PUSHJ P,PGMOVE
JUMPN P1,LOCK19
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
LOCK19: 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,LOCK20
CAILE J,JOBMAX##
JRST LOCK17
PUSHJ P,FPNSHS
LOC19C: PUSHJ P,NXTWS3##
LOC19D: 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 LOCK18 ;YES, STOP ON COUNT EXHAUSTED
TRNN M,<-1^!HLGPNO> ;IS IT A USER PAGE #?
JRST LOCK18 ;NO, JUST CONTINUE THEN
SKIPE T4,.USSPT ;JUST DO S0?
AOJA T4,LOC19A ;INCREMENT SECTION
PUSH P,M ;SAVE THINGS TO DO FUNNY SPACE LATER
PUSH P,T1
PUSH P,T2
PUSH P,T3 ;..
AOJA T4,LOC19B
LOC19A: CAILE T4,MXSECN ;ANY MORE TO DO?
SETO T4, ;NO, BACK TO S0 FOR FUNNY SPACE (2ND TIME)
LOC19B: MOVEM T4,.USSPT
JUMPGE T4,LOC16A ;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 LOCK18 ;AND CONTINUE
LOCK20: 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 LOCK21 ;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)]
LOCK21:
HLRZS J,LOCK## ;GET THE SEGMENT NUMBER OF THE LOW SEGMENT
; IF THERE IS ONE LEFT TO BE LOCKED
JUMPE J,LOCK22 ;JUMP IF DONE
HLRZS LOKREL## ;STARTING PAGE NUMBER FOR THE LOW SEGMENT
JRST LOCK1 ;AND GO TRY TO LOCK IT
LOCK22: 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
MOVSI T1,SWP ;ASSUME THE HIGH SEGMENT GOT SWAPPED WHILE
; LOCKING THE LOW SEGMENT
SKIPG T2,JBTSGN##(J) ;DOES THE JOB HAVE A REAL HIGH SEGMENT?
POPJ P, ;NO, RETURN
HRRZS T2 ;CLEAN OUT LH OF JBTSGN SO WE CAN INDEX
SKIPN JBTADR##(T2) ;IS THE HIGH SEGMENT IN CORE
IORM T1,JBTSTS##(J) ;TURN ON SWP SO THE SCHEDULAR WON'T RUN
; THE JOB UNTIL THE HIGH SEGMENT GETS SWAPPED IN
MOVE T1,HIGHJB## ;HIGHEST NUMBERED JOB
MOVSI T3,SEGMB ;SIGNAL TO MAP HIGH SEGMENT
LOCK23: SKIPLE T4,JBTSGN##(T1) ;GET HIGH SEGMENT OF ALL JOBS
SKIPN JBTADR##(T1) ;IGNORE IF NOT IN CORE
JRST LOCK24
CAME J,T1 ;DON'T DO IT TO OUR JOB
CAIE T2,(T4) ;SAME HIGH SEGMENT AS OURS?
JRST LOCK24 ;NO. LOOK AT NEXT ONE
IORM T3,JBTSGN##(T1)
LOCK24: SOJG T1,LOCK23 ;LOOP FOR ALL JOBS
POPJ P, ;AND RETURN
IFN FTIPCF,<
;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 SETM14 ;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 SETM14 ;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 SETM13 ;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
PUSH P,@[IW MS.MEM,PAGTAB(T1)] ;SAVE PAGE DESCRIPTOR BITS
PUSHJ P,PAGFRE ;MOVE THE PAGE AND FIX PAGTAB
STOPCD .,STOP,CMP ;++CAN'T MOVE PAGE
POP P,T1 ;GET BACK PAGE DESCRIPTOR BITS
HLLM T1,@[IW MS.MEM,PAGTAB(P2)] ;FIX UP DESTINATION PAGTAB ENTRY
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
SETM13: 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
SETM14: 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
SETM15: 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 SETM16 ;YES
AOBJN P3,SETM15 ;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
SETM16: 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 SETM16 ;NO, LOOK AT THE NEXT CANDIDATE
HRRZ T1,P3 ;PART OF P3 TO BE USED AS AN INDEX
PUSH P,@[IW MS.MEM,PAGTAB(T1)] ;SAVE BITS FOR THIS PAGE
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
POP P,T1 ;MONITOR PAGE+CACHE BITS
HRRZ T2,P2 ;GET INDEX INTO PAGTAB (LH P2 MAY HAVE JUNK)
HLLM T1,@[IW MS.MEM,PAGTAB(T2)] ;REMEMBER THAT
SOJLE P4,SETM17 ;JUMP IF WE'VE MOVED THE LAST PAGE
SKIPLE .CPHTM## ;ONCE/SECOND TIME CREEPING UP ON US?
JRST SETM15 ;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,MONORG## ;NUMBER OF WORDS (BOTTOM OF HISEG)
LSH T1,W2PLSH## ;NUMBER OF PAGES TO WORRY ABOUT
MOVE T2,[POINT 36,MONORG##/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.
JUMPN T1,ADJMP3 ;JUMP IF IT IS
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
PAGFR2: SKIPE P1
HRRZ T4,@[IW MS.MEM,PT2TAB(T1)]
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
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
HRRM 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)]
HRRM 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,T2 ;SET PREDECESSOR
JUMPE T3,CPOPJ## ;ERROR IF LAST PAGE OF SEGMENT
HRRZ T2,@[IW MS.MEM,PAGTAB(T3)] ;NOT LAST, GET NEXT PAGE
CAIN T2,(T1)
HRR T4,T3
CAIN T2,(P2) ;IS THIS THE TARGET PAGE?
HRL T4,T3
SKIPE P1
TRNE T4,-1
TLNN T4,-1
JRST PAGFD1 ;NO, TRY AGAIN
SKIPGE T2,@[IW MS.MEM,PAGTAB(T1)] ;GET SUCCESSOR TO CURRENT PAGE
STOPCD .,STOP,NPF, ;++NEXT PAGE FREE
HLRZ T3,T4
ADD T3,[EXP MS.MEM+PAGTAB]
PUSHJ P,FIXPTB
PAGFD2: CAIG J,JOBMAX## ;IF A LOW SEGMENT,
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 (0) ;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+PAGSIZ##-1
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
MOVNI T1,PAGSIZ## ;- THE NUMBER OF WORDS TO EXCHANGE
HRLZS T1 ;T1 = AN AOBJN POINTER
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
;RETURN HERE - THE SOURCE PAGE HAS BEEN MOVED TO THE TARGET DESTINATION
PAGMOV: 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
POPJ P, ;PAGE IS 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
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
POPJ P, ;RETURN
;SUBROUTINE TO DETERMINE IF THE CURRENT PAGE MUST BE MOVED AND IF SO,
; MOVE IT
PGMOVE: PUSHJ P,SAVT##
MOVE T1,(T4)
TLZ T1,(PM.NAD)
PUSH P,T4
CAIE T1,(P2)
PUSHJ P,PAGMOV
MOVE T1,(P)
MOVE T1,(T1)
AND T1,[-1,,760000]
IORI T1,(P2)
HRRZ T2,M
MOVSI T3,(JS.NCS)
CAIGE T2,.MCFV/PAGSIZ##
TDNN T3,JBTST2##(J)
CAIA
TDZ 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: PUSHJ P,SAVT## ;SAVE THE TS AGAIN
PUSH P,M
PUSH P,.USSPT
FIXMA8: CAIE M,.UPMVP/PAGSIZ## ;FLAG THAT WE'RE MOVING UPT
JRST FIXMA9 ;NOT MOVING UPT, START WHERE PAGE CURRENTLY IS
SETZM .USSPT
FIXMA0: PUSHJ P,NXTWSB## ;START
JRST FIXMA7 ;..
FIXMA9: MOVE M,.USTMP ;ACS SAVED FOR US
DMOVE T1,.USTMP+1
MOVE T3,.USTMP+3
FIXMA1: PUSHJ P,NXTWS3## ;NEXT PAGE
FIXMA7: SKIPGE .USBTS ;IS USER EXTENDED?
SKIPGE .USSPT ;YES, DOING FUNNY SPACE (2ND TIME THROUGH S0)
JRST FIXMA3 ;YES
TRNN M,<-1^!HLGPNO> ;USER PAGE?
JRST FIXMA3 ;YES
SKIPE T4,.USSPT ;START NON-ZERO SECTIONS?
AOJA T4,FIXMA4 ;NO, ALREADY STARTED
PUSH P,M
PUSH P,T1
PUSH P,T2
PUSH P,T3
AOJA T4,FIXMA5
FIXMA4: CAILE T4,MXSECN
SETO T4, ;START FUNNY SPACE
FIXMA5: MOVEM T4,.USSPT
JUMPGE T4,FIXMA0
POP P,T3
POP P,T2
POP P,T1
POP P,M
MOVEI T4,(M)
PUSHJ P,GMPTR##
FIXMA3: 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 FIXMA1 ;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
;SUBROUTINE TO FIX UP PAGTAB AFTER EXCHANGING PAGES
;ARGS:
; T3=PREDECESSOR *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 NONE
HRRM P2,PAGTAB(T4)
HRRM T4,@[IW MS.MEM,PT2TAB(P2)]
HRRM T1,(T3)
MOVEI T4,-PAGTAB(T3)
CAIN T4,PAGPTR-PAGTAB
SETZ T4,
HRRM T4,@[IW MS.MEM,PT2TAB(T1)]
MOVE T4,(P) ;GET BACK ORIGINAL T4
HLRZM T2,(P) ;SAVE T2
CAIE P2,(T2)
TLZA T2,-1 ;CLEAR JUNK IN LH
HRRZ T2,T1
HRRZM T2,@[IW MS.MEM,PAGTAB(P2)]
HRRZM P2,@[IW MS.MEM,PT2TAB(T2)]
POP P,T2 ;RESTORE T2
CAIN T2,(T1)
MOVE T2,P2
HRRM T2,@[IW MS.MEM,PAGTAB(T1)]
HRRM T1,@[IW MS.MEM,PT2TAB(T2)]
POPJ P,
SUBTTL ERRCON - ERROR HANDLING CODE
;ROUTINE TO CHECK IF JOB HAS BOTH SEG LOCKED
;CALL: MOVE J,JOB NUMBER
; PUSHJ P,LOKCHK
; BOTH LOCKED - J PRESERVED
; NEITHER OR ONLY ONE LOCKED - J PRESERVED
LOKCHK::SE1ENT ;JUST TO MARK THAT ALL LOKCON RUNS EXTENDED
PUSHJ P,SAVE2## ;SAVE P1-P2
MOVSI P1,NSHF!NSWP ;NO SHUFFLING OR SWAPPING BITS
TDNE P1,JBTSTS##(J) ;LOW SEG LOCKED?
POPJ P, ;YES
SKIPG P2,JBTSGN##(J) ;NO, DOES JOB HAVE A HIGH SEG?
JRST CPOPJ1 ;NO, THAT MEANS IT CAN'T BE LOCKED
HRRZS P2 ;CLEAN OUT LEFT HALF SO CAN USE AS INDEX
TDNN P1,JBTSTS##(P2) ;HAS HISEG, IS IT LOCKED?
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
MOVE T2,.USVRT ;VIRTUALOSITY
SKIPLE T3,JBTSGN##(J) ; A HIGH SEGMENT?
TLNE T3,SHRSEG ;YES, IS IT SHARABLE?
JRST [TRNE T1,-1 ;YES, LOCKING THE LOW SEGMENT?
JUMPN T2,RTZER## ;NOT IMPLEMENTED IF VIRTUAL
JRST LOKJO1] ;SEE IF SEGMENT(S) CAN BE LOCKED
JUMPN T2,RTZER## ;NOT IMLEMENTED IF VIRTUAL
TLNE T1,LKB ;A NON-SHARABLE HIGH SEGMENT
TRNN T1,LKB ;ARE BOTH SEGMENTS TO BE LOCKED?
JRST RTZER## ;NO, NOT IMPLEMENTED
LOKJO1: PUSHJ P,SAVE4## ;SAVE T1-T4
MOVSI T1,PVLOCK ;BIT DENOTING PRIVILEDGES TO LOCK
PUSHJ P,PRVBIT## ;IS THIS USER A SUFFICIENT WHEEL?
SKIPA ;YES, PROCEED
JRST ERROR1 ;NO, NOT PRIVILEGED ERROR RETURN
LOKJ0Z: PUSHJ P,GETTAC## ;RESTORE THE USER'S ARGUMENT
JUMPL T1,[PUSHJ P,LOKARG ;JUMP IF NEW STYLE ARGUMENT LIST
JRST STOTAC## ;MALFORMED ARGUMENT LIST, GIVE ERROR RETURN
JRST .+1] ;CONTINUE PROCESSING
LOKRET: MOVSI P1,NSHF!NSWP ;LOCKED BITS
MOVE T2,J ;SAVE JOB NUMBER
MOVEI T3,0 ;ASSUME NO HIGH SEGMENT ADDRESS
SKIPG J,JBTSGN##(J) ;GRAB HIGH SEGMENT NUMBER IF ANY
JRST LOKJO2 ;NO HIGH SEGMENT
TLO J,(1B0) ;MAKE THIS AC A VALID INDEX. THIS WORKS SINCE
;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,JBTSGN##(T2)
PUSHJ P,CHKCS2 ;SET CACHE BIT IN JBTSGN
PUSHJ P,MAPHGH## ;COPY CACHE BIT TO UPMP
JRST LOKJ0Z ;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
LOKJO2: EXCH J,T2 ;J=JOB, T2=HIGH SEGMENT NUMBER
TRNN T1,LKB ;LOCK THE LOW SEGMENT?
JRST LOKJO3 ;NO
TDNN P1,JBTSTS##(J) ;IS THE LOW SEGMENT ALREADY LOCKED?
JRST LOKJO4 ;YES
LOKJO3: TLNN T1,LKB ;LOCK THE HIGH SEGMENT?
JRST ERROR0 ;NO, NOTHING TO DO
JUMPE T3,ERROR0 ;JUMP IF NO HIGH SEGMENT
TDNE P1,JBTSTS##(T2) ;ALREADY LOCKED?
JRST ERROR0 ;YES, GO CHECK OUT LOW SEGMENT
HRRZ J,T2 ;SAVE HIGH SEGMENT NUMBER
LOKJO4: TLZ T1,-1-<LKB>
MOVEI F,0 ;INDICATE NO DDB
PUSHJ P,CAWAIT## ;YES, WAIT UNTIL ITS DONE
SETZB P4,T4 ;ZERO LARGEST JOB SEEN SO FAR
PUSH P,J ;SAVE J
MOVEI J,1 ;FIND THE LARGEST JOB NOT LOCKED
LOKJO5: CAMN J,.CPJOB## ;DON'T CONSIDER JOB BEING LOCKED
JRST LOKJO7
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
SKIPG J,JBTSGN##(J) ;DOES IT HAVE A REAL HIGH SEGMENT?
JRST LOKJO6 ;NO
HRRZS J
MOVSI P2,NSWP!NSHF
MOVE P1,.CPJOB## ;GET OUR JOB #
HRRZ P1,JBTSGN##(P1) ;GET OUR HISEG #
TLNE T1,LKB ;IF LOCKING OUR HISEG
CAIE P1,(J) ;AND HE IS USING IT
TDNE P2,JBTSTS##(J) ;OR IT IS ALREADY LOCKED
JRST LOKJO6 ;THEN IGNORE THIS HISEG
MOVE P2,T2 ;COUNT THE SIZE OF THE HIGH SEGMENT
PUSHJ P,SEGSIZ##
ADDI T2,(P2) ;T2_SIZE OF THE JOB
LOKJO6: LSH T2,P2WLSH##
CAMLE T2,P4 ;LARGEST SO FAR?
MOVE P4,T2 ;YES, SAVE ITS SIZE
POP P,J ;RESTORE JOB NUMBER
LOKJO7: CAMGE J,HIGHJB## ;LOOKED AT ALL JOBS YET?
AOJA J,LOKJO5 ;NO
MOVE J,(P)
PUSHJ P,SEGSIZ## ;SIZE OF THIS SEGMENT IN PAGES
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 LOKJO8 ;YES, JUST LOCK THE HIGH SEGMENT
MOVSI P2,NSHF!NSWP ;HIGH SEGMENT MAY ALREADY BE LOCKED
SKIPG P1,JBTSGN##(J) ;DOES THE JOB HAVE A HIGH SEGMENT?
JRST LOKJO8 ;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 LOKJO8 ;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
LOKJO8: PUSHJ P,LRGHOL ;COMPUTE THE NUMBER OF PHYSICAL PAGES AVAILABLE
; FOR LOCKING
POP P,P1 ;RESTORE JOB#,,HIGH SEGMENT#
SUBI T2,1(T1) ;T2 = AMOUNT OF CORE LEFT IF THIS JOB IS LOCKED
CAMGE T2,P4 ;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 P1,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
PUSHJ P,GETTAC## ;RESTORE THE USER'S ARGUMENT
JUMPL T1,LOKEXT ;IF NEGATIVE, PROCESS NEW STYLE ARGUMENT LIST
;DISPATCH TO DO VARIOUS TYPES OF LOCK FOR EACH SEGMENT
PUSHJ P,CHKCSH ;CHECK WHETHER THE CACHE SHOULD BE ON OR OFF
CAIG P1,JOBMAX## ;IS THE HIGH SEGMENT TO BE LOCKED?
JRST LOKJO9 ;NO
TLCE T1,LKB+LKEB+LKPB;DOES THE USER WANT IT LOCKED IN PLACE?
TLNE T1,LKB+LKEB+LKPB; ..
JRST LOKJO9 ;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,LOKJ17 ;JUMP IF LOW SEGMENT ISN'T TO BE LOCKED
LOKJO9: PUSHJ P,GETTAC## ;RESTORE THE USER'S ARGUMENT
TRCE T1,LKB+LKEB+LKPB;DOES THE USER WANT THE LOW SEGMENT LOCKED
TRNE T1,LKB+LKEB+LKPB; IN PLACE?
JRST LOKJ10 ;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 LOKJ17 ;AND FINISH UP
LOKJ10: PUSHJ P,GETTAC## ;RESTORE USER'S ARGUMENT
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 T1,T2 ;EITHER SEGMENT TO BE LOCKED PHYSICALLY CONTIGUOUS?
JRST LOKJ14 ;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
LOKJ14: MOVEI T1,0 ;INDICATE THAT NEITHER SEGMENT IS ALREADY
; LOCKED IN EVM
LOKJ15: MOVE P2,T1 ;P2 = SEGMENTS ADDRESSES IF LOCKED ALREADY
PUSHJ P,GETTAC## ;RESTORE THE USER'S ARGUMENT
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 LOKJ17 ;ALL DONE
PUSHJ P,GETTAC## ;RESTORE USER'S ARGUMENT
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 LOKJ16 ;GO CHECK THE LOW SEGMENT
TLNE P2,LKEB ;LOCK THE HIGH SEGMENT VIRTUALLY CONTIGUOUS?
JRST LOKJ16 ;NO
PUSH P,T1 ;SAVE THE ADDRESS OF THE LOW SEGMENT
HRRZ J,P1 ;J = THE HIGH SEGMENT NUMBER
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,LOKJ17 ;ALL DONE IF NOT LOCKING LOW SEGMENT
LOKJ16: TRNN P2,LKEB ;LOCK THE LOW SEGMENT VIRTUALLY CONTIGUOUS?
TRNE T1,-1 ;YES, IS THE LOW SEGMENT ALREADY LOCKED IN EVM?
JRST LOKJ17 ;YES, FINISH UP
PUSH P,T1 ;SAVE THE ADDRESSES OF THE SEGMENTS
MOVE J,.CPJOB## ;J = LOW SEGMENT NUMBER
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
LOKJ17: PUSHJ P,CAFREE## ;RETURN THE LOCK RESOURCE
S0PSHJ SETRLH##
PUSHJ P,GETTAC##
JUMPGE T1,LOKRET ;GO IF NO LOCK EXTENSION
PUSHJ P,RASBAD ;GET PHYSICAL PAGE NUMBER
JFCL ;RASBAD SKIPS
PJRST STOTC1## ;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
LOKARG: HRRI M,(T1) ;POINT AT USER'S ARGUMENT LIST
HLRE T2,T1 ;- LENGTH OF THE ARGUMENT LIST
CAME T2,[-2] ;MUST BE EXACTLY 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
AOS (P) ;SET FOR GOOD 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,,0
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 ;YES, INDICATE HIGH SEGMENT TO BE LOCKED
TRZE T1,-1 ;LOCK THE LOW SEGMENT AT A SPECIFIED ADDRESS?
TRO T1,LKB ;YES, INDICATE LOW SEGMENT TO BE LOCKED
POPJ P, ;AND RETURN
;SUBROUTINE TO LOCK A SEGMENT CONTIGUOUSLY IN EXEC VIRTUAL MEMORY
;CALLING SEQUENCE:
; 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
PUSH P,T1 ;SAVE THAT
CAIG J,JOBMAX## ;A LOW SEGMENT?
ADDI T1,UPMPSZ## ;YES, UPMP MUST BE MAPPED TOO
MOVEI T2,EVMPTR## ;POINT TO BIT MAP OF SLOTS IN THE EXEC MAP
; USED FOR LOCKING IN EVM
MOVE 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
MOVE 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 LOKEV1 ;NO
POP P,T2
PUSHJ P,SAVE4##
DMOVE P1,T1
ADDI T1,UPMPSZ##
PUSH P,T1
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
LOKEV5: PUSHJ P,NXTWSB##
CAIA
LOKEV0: PUSHJ P,NXTWS3##
TRNN M,<-1^!HLGPNO> ;PAGE NOT IN USER SPACE?
JRST LOKEV4 ;USER PAGE
AOS .USSPT ;PROCEED TO NEXT SECTION
JRST LOKEV5
LOKEV4: PUSHJ P,FPNSHS
PUSH P,T3
MOVE T3,(T4)
TDZ T3,[PM.CSH]
MOVEM T3,(T4)
IDPB T3,P1
IFN FTMP,<
PUSHJ P,MAPUC##
>
POP P,T3
SOJG P2,LOKEV0
POP P,M
JRST LOKEV2
LOKEV1: 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
>
LOKEV2: 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: HRRI M,(T1) ;POINT M AT THE USER'S ARGUMENT LIST
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 LKSPH2 ;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 LKSPH2 ;NO, ALL IS WELL SO FAR
JRST ERROR6
LKSPH2: 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 LKSPH3]
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,LKSPH4 ;ALL DONE IF NOT LOCKING THE LOW SEGMENT
LKSPH3: 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
LKSPH4: MOVE J,.CPJOB## ;CURRENT JOB NUMBER
PUSHJ P,LOCKIT ;LOCK THE SEGMENTS REQUESTED WHERE REQUESTED
JFCL ;CAN'T HAPPEN
JRST LOKJ17 ;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: IORM T4,@[IW MS.MEM,PT2TAB(T1)] ;SET IT
SKIPL T3,@[IW MS.MEM,PAGTAB(T1)] ;IS PAGE FREE?
JRST SETLI4 ;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
SOS BIGHOL##
SETLI4: 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 AND CLEAR P2.LIP. 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
JRST CLRLQ2 ;BE SURE P2.LIP CLEAR
CLRLQ1: SSX P2,MS.MEM ;WHERE PT2TAB ETC. LIVE
HRRZ P3,P2 ;SAVE
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##
CLRLQ2: MOVE P1,LOKREL## ;FIRST PAGE
SSX P1,MS.MEM ;PT2TAB SECTION
LDB P3,IMGIN## ;SIZE
CAILE J,JOBMAX## ;LOW SEG?
JRST CLRLQ3
LDB P2,NFYPGS## ;ADD FUNNY PAGES IF LOW SEG
ADDI P3,(P2)
LDB P2,NZSSCN##
ADDI P3,(P2)
CLRLQ3: MOVSI P2,(P2.LIP) ;LOCK-IN-PROGRESS BIT
CLRLQ4: ANDCAM P2,PT2TAB(P1)
SOSL P3
AOJA P1,CLRLQ4
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: 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 LOKPH0
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
LOKPH0: 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,UPMM## ;MUST HAVE THE MM RESOURCE WHEN SCANNING PAGTAB
>
LOKPH1: TDZA T4,T4 ;LARGEST HOLE SEEN SO FAR
LOKPH2: ADDI T4,1 ;INCREMENT SIZE OF LARGEST HOLE
CAIN T3,(T2) ;LOOKED AT ALL OR 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,LOKPH2 ;NO, COUNT IT IN THIS HOLE
CAMG T4,T1 ;IS THIS HOLE BIG ENOUGH?
AOJA T2,LOKPH1 ;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,
>
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
IFN FTMP,<
PUSHJ P,DWNMM## ;RETURN MM
>
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
LOCKIT: MOVEM P1,LOCK## ;STORE SEGMENT NUMBERS FOR LOCK
MOVE J,.CPJOB##
MOVEI T1,LOK ;MAKE THE JOB UNRUNNABLE UNTIL LOCKING
IORM T1,JBTSTS##(J) ; IS COMPLETE
PUSHJ P,WSCHED## ;RESCHEDULE, RETURN WHEN JOB IS LOCKED
RASBAD: LDB T1,JBYLSA## ;STARTING PAGE NUMBER OF THE LOW SEGMENT
SKIPG J,JBTSGN##(J) ;JOB HAVE A REAL HIGH SEGMENT?
PJRST CPOPJ1## ;NO HISEG, GIVE LOCKED RETURN (T1 = LOSEG ADDR)
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
;
UNLOKH::SE1ENT ;LOKCON ALWAYS RUNS EXTENDED
MOVE J,-2(P) ;GET JOB NUMBER
MOVSI T1,LKB ;UNLOCK THE HIGH SEGMENT
JRST UNLO00 ;UNLOCK IT IF NOT LOCKED FOR SOME OTHER JOB
UNLOK.::SE1ENT ;RUN THIS EXTENDED.
TDCN T1,[LKB,,LKB] ;NOT UNLOCKING ANYTHING?
JRST CPOPJ1## ;YES, ALWAYS LEGAL
TDCE T1,[LKB,,LKB] ;YES, UNLOCKING BOTH SEGMENTS?
SKIPG T2,JBTSGN##(J) ;REAL HIGH SEG?
JRST UNLOK1 ;NO HIGH SEGMENT OR UNLOCKING BOTH
TLNE T2,SHRSEG ;HIGH SEGMENT SHARABLE?
JRST UNLOK1 ;YES, PROCEED TO UNLOCK
TLNN T2,LOKSEG+NCSH ;NO, IS IT ACTUALLY LOCKED?
JRST CPOPJ1## ;NO, NOT REALLY LOCKED
;(WE CAN RETURN SUCCESSFULLY BECAUSE TH
;LOW SEGMENT CANNOT BE LOCKED IN THIS CASE.)
POPJ P, ;YES, CANNOT UNLOCK ONLY ONE SEGMENT
UNLOK1: AOSA (P) ;GIVE SKIP RETURN
UNLOCK::MOVE T1,[XWD LKB,LKB];UNLOCK BOTH LOW AND HIGH SEGMENTS
UNLO00: SE1ENT ;CALL COROUTINE PUSHING ACS ON STACK
PUSHJ P,SAVE4## ;PRESERVE ACCUMULATORS
PUSH P,T1 ;SAVE ARGUMENT WHILE UNLOCKING
ZZ==. ;PLACE ON STACK FOR ARGUMENT (T1)
PUSH P,J ;SAVE JOB NUMBER
ZZ==.-ZZ ;DEPTH ON STACK FOR ARGUMENT (T1)
MOVSI P4,NSHF!NSWP
MOVEI J,(J) ;CLEAR POSSIBLE LEFT HALF BITS
CAILE J,JOBMAX## ;IS THIS A HIGH SEGMENT?
JRST UNLO04 ;YES IF CALLED FROM SEGCON OR LOKINI
TRNE T1,LKB ;UNLOCK THE LOW SEGMENT?
TDNN P4,JBTSTS##(J) ;IS IT LOCKED?
JRST UNLO01 ;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)
UNLO01: TLNN T1,LKB ;UNLOCK THE HIGH SEGMENT?
JRST UNLO05 ;NO
MOVSI P2,LOKSEG+NCSH
SKIPLE P3,JBTSGN##(J) ;DOES THE JOB HAVE A REAL HIGH SEGMENT
TDNN P2,JBTSGN##(J) ;AND IS IT LOCKED
JRST UNLO05 ;NO
ANDCAM P2,JBTSGN##(J) ;TURN OFF HIGH SEGMENT LOCKED FOR THIS JOB
S0PSHJ MAPHGH## ;TURN ON CACHE BITS IN THE MAP
MOVE T1,HIGHJB## ;IS ANOTHER JOB SHARING THE HIGH SEGMENT?
UNLO02: SKIPG JBTSGN##(T1) ;A REAL HIGH SEGMENT?
JRST UNLO03 ;NO
HRRZ P1,JBTSGN##(T1)
CAME T1,(P) ;CURRENT JOB?
CAIE P1,(P3) ;SAME HIGH SEGMENT?
JRST UNLO03 ;THIS SEGENT DOESN'T STOP UNLOCKING
TDNE P2,JBTSGN##(T1) ;IS THE LOW SEGMENT SHARING LOCKED?
JRST UNLO05 ;YES, CAN'T UNLOCK THE HIGH SEGMENT
UNLO03: SOJG T1,UNLO02
HRRZ J,P3
UNLO04: TDNN P4,JBTSTS##(J) ;IS HIGH SEGMENT LOCKED?
JRST UNLO05 ;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
UNLO05: 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
FRELOK: ANDCAM P4,JBTSTS##(J) ;TURN OFF NSHF AND NSWP
LDB T1,JBYLSA## ;PAGE NUMBER OF FIRST PAGE OF THE LOW SEGMENT
CAILE J,JOBMAX## ;IS IT A HIGH SEGMENT?
LDB T1,JBYHSA## ;PAGE NUMBER OF FIRST PAGE OF THE HIGH 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
PUSHJ P,FSTPG ;GET THE PAGE NUMBER OF THE FIRST PAGE 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: SKIPLE T3,JBTSGN##(J) ;DOES THE JOB HAVE A REAL HIGH SEGMENT?
TLNN T3,LOKSEG ;AND IS IT LOCKED?
JRST CKLJB ;NO, LOOK AT THE NEXT JOB
HRRZS T3 ;CLEAR LH BITS, SO WE CAN USE AS INDEX
LDB T3,[POINT 13,JBTHSA##(T3),35]
PUSHJ P,CKPGS ;SEE IF THE HIGH SEGMENT PAGES OVERLAP THE RANGE
JRST CPOPJ1## ;THEY DO, TELL THE CALLER
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
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
MEMOF2: 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
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
>
MOVE T1,[.CSCMF,,.ERCSC] ;MEMORY OFF-LINE INDICATOR
PUSH P,J ;SAVE J FOR COMRET
PUSHJ P,DAEEIM## ;TELL DAEMON ABOUT THE MEMORY CONFIGURATION CHANGE
POP P,J ;RESTORE J
PJRST SETEDV## ;RESET EDV POINTERS AND RETURN
;SUBROUTINE TO SLEEP A TICK AND THEN RETRY AN OPERATION. ALWAYS RETURNS TO
; CALL MINUS ONE
DELAY1: PUSHJ P,SAVT## ;DON'T CLOBBER CALLERS ACS
MOVEI T1,0 ;SLEEP 1 TIC
S0PSHJ SLEEPF## ;SLEEP BUT DON'T CLOBBER F
SOS -5(P) ;BACK UP PC TO THE TEST
SOS -5(P) ; ..
POPJ P, ;RETURN TO CHECK AGAIN
;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 RETURN THE FIRST PAGE OF A LOW SEGMENT
FSTPG: LDB T3,JBYLSA## ;PAGE ZERO OF THE JOB
POPJ P, ;RETURN THE FIRST PAGE OF THE JOB
;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,
ERROR0: LDB P1,JBYLSA## ;LOW SEGMENT PHYSICAL ADDRESS
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 STOTC1## ;RETURN TO USER WITH ADDRESSES
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 CHKCS3
MOVSI T2,(JS.NCS)
IORM T2,JBTST2##(J)
CHKCS2: MOVE J,.CPJOB##
CHKCS3: SKIPG JBTSGN##(J)
POPJ P,
TLNE T1,LKB
TLNE T1,LKCB
POPJ P,
MOVSI T2,NCSH
IORM T2,JBTSGN##(J)
POPJ P,
;SUBROUTINE TO SEE IF THIS IS THE FIRST PAGE OF
; A SHARABLE HIGH SEGMENT
FPNSHS: SKIPN P4
POPJ P,
ADDI P4,PAGSIZ##
PUSHJ P,SAVT##
LDB T1,JBYSG2## ;SECTION HI SEG IS IN
CAME T1,.USSPT
POPJ P, ;NOT IN THIS SECTION
HRRZ T1,M
PUSHJ P,TPAHS##
SKIPA T4,T1
POPJ P,
PUSH P,J
HRRZ J,JBTSGN##(J)
SKIPL P4
HRRM P4,JBTADR##(J)
PUSHJ P,MAPHI##
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
CSHLS0: PUSHJ P,NXTWSB##
CAIA
CSHLS1: PUSHJ P,NXTWS3##
TRNE M,<-1^!HLGPNO> ;USER PAGE?
AOSA .USSPT
SKIPA P2,(T4)
JRST CSHLS0
TDO P2,[PM.CSH]
MOVEM P2,(T4)
SOJG P1,CSHLS1
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
LOKEND: END