1
0
mirror of https://github.com/PDP-10/stacken.git synced 2026-03-01 01:19:17 +00:00
Files
Lars Brinkhoff 6e18f5ebef Extract files from tape images.
Some tapes could not be extracted.
2021-01-29 10:47:33 +01:00

2366 lines
87 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
TITLE LOKCON - MODULE FOR LOCKING JOBS IN CORE - V336
SUBTTL J. FLEMMING TS 28-JUNE-88
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,336 ;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
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
>
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 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