TITLE DATMAN - DATA BASE MANAGER V177 SUBTTL D BLACK/DAL/JBS 21-JUNE-88 SEARCH F,S $RELOC $CSUB ;ENTIRE MODULE IN COMMON PSECT ;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 VDATMN,177 ENTRY DATMAN DATMAN:: ;CAUSE DATMAN TO LOAD IF IN LIBRARY FILE XP LISTSN,1 ;CAUSE S.MAC AND F.MAC TO BE LISTED HERE ; (USED TO BE IN COMMON WHICH IS NOW TOO BIG). REPEAT 0,< The DATA BASE MANAGER contains both subroutines to manipulate monitor's data base and formats of various components of the data base. The DATA BASE MANAGER should be the only module which modifies the data base; all other modules should call DATMAN. This scheme has a number of advantages: 1. It provides a good chance for comments. 2. It provides good conventions for future growth. 3. It provides good locality. 4. It helps reentrancy by having only one module maintain impure code. DATMAN will also control writing in users' core too. PROCESS and SEGMENT are important components in the data base being introduced at this time. A SEGMENT is one logical collection of data, either program data or code, and is the building block of a program. Segments are really the same as previously. A PROCESS is a virtual machine; it has a hardware state associated with it: a virtual memory, a processor, typically one PC, a stack, etc. A process's virtual memory will contain a number of segments. Several processes may run either serially or in parallel as one overall program or user. Monitor data will be organized on a per segment and a per process basis. Part of per segment and part of per process data must be resident, other parts could be swappable; the data breaks up into four components. The following abbreviations and definitions will be used: PRB Process Resident Block - the resident process information. This will be very small, about 8 or 12 words. PDB Process Data Block - the not necessarily resident (swappable) process data. This will be most of the process data and may grow to fill a page or more. SRB Segment Resident Block - the resident segment information. This will be very small, about 8 or 12 words. SDB Segment Data Block - the not necessarily resident segment data. This may grow to fill a page or more. Conventions about symbols: symbols will consist of a three letter prefix and a three letter suffix. The prefix will determine to what type of data base component the entry belongs, and the particular usage of the entry. For example, a word entry in the PDB would be .PDxxx. The suffix is a three letter mnemonic describing the entry. Thus the PDB entry SIZ containing the size of the PDB would be .PDSIZ. DATMAN is organized in the following manner: First are the definitions of the various data base components. These will be in alphabetical order so they can be found easily. Second are subroutines for manipulating the data base, grouped by function. Code should go down the page, as in 5 series monitor conventions, until concern for locality becomes more important. > ;END REPEAT 0 SUBTTL PDB LOGIC ;SUBROUTINE TO FIND A PDB OR HALT ;CALL WITH: ; MOVE J,PROCESS-NUMBER ; PUSHJ P,FNPDBS ; RETURN HERE WITH W POINTING TO A PDB ; FNDPDS::JUMPL J,NPJSTP HRRZ W,JBTPDB##(J) ;GET PDB CAIG J,JOBMAX## ;LEGAL JOB # JUMPN W,CPOPJ## ;RETURN IF PDB EXISTS NPJSTP::STOPCD .,STOP,NPJ, ;++NO PDB FOR JOB ;SUBROUTINE TO FIND PDB FOR PROCESS IN T1 ; PUSHJ P,FPDBT1 ; HERE IF NO PDB ; HERE WITH T1 POINTING TO PDB ;RETURNS WITH T1 UNCHANGED IF NO PDB FPDBT1::PUSH P,J ;SAVE J AND W PUSH P,W ; .. HRRZ J,T1 ;COPY PDB HANDLE PUSHJ P,FNDPDB ;FIND THE PDB SOSA -2(P) ;CAUSE NON-SKIP RETURN MOVE T1,W ;COPY CORE ADDRESS POP P,W ;RESTORE AC'S JRST JPOPJ1## ;RETURN ;SUBROUTINE TO FIND A PDB ;CALL WITH: ; MOVE J,PROCESS-NUMBER ; PUSHJ P,FNDPDB ; RETURN HERE IF NO PDB (W = 0) ; RETURN HERE WITH W POINTING TO PDB FNDPDB::PUSH P,T1 ;SAVE T1 PUSHJ P,LGJPR1 ;SEE IF A LEGAL PROCESS (INCLUDING ZERO) JRST TPOPJ## ;NOT, LOSE HRRZ W,JBTPDB##(J) ;GET PDB ADDRESS JUMPN W,TPOPJ1## ;IF W IS NON-ZERO GIVE THE SKIP RETURN JRST TPOPJ## ; ELSE FAIL SUBTTL CX RESOURCE ROUTINES ;ROUTINES TO MANIPULATE THE CX RESOURCE FOR A JOB. THE CX RESOURCE IS USED ;TO INTERLOCK PDB OR CONTEXT BLOCK REFERENCES. ;UPCX TO GET THE CX RESOURCE FOR THE JOB IN T1 (.CPJOB CONTAINS OUR JOB) ;UPCX WILL BLOCK IF THE REQUESTED CX RESOURCE ISN'T AVAILABLE UPCX:: PUSH P,T2 ;SAVE EVERYTHING PUSH P,J ;SAVE J MOVE J,.CPJOB## SKIPN T2,T1 ;WHO WE WANT SOS T2 ;IF JOB 0, SAY -1 HRLM T2,JBTCX##(J) ;FLAG WHO WE WANT/OWN JUMPE T1,UPCXR ;NO REAL INTERLOCKING FOR JOB 0 SYSPIF ;GUARD RACES HRRZ T2,JBTCX(T1) ;GET THE OWNER OF HIS CX RESOURCE JUMPN T2,CXWAIT ;WAIT IF IT ISN'T AVAILABLE HRRM J,JBTCX##(T1) ;WE OWN HIS CX SYSPIN UPCXR: POP P,J JRST T2POPJ## ;RETURN CXWAIT: SYSPIN MOVEI T2,CXQ## ;THE QUEUE DPB T2,PJBSTS## ;SAY IN CX WAIT POP P,J ;RESTORE J POP P,T2 ;RESTORE T2 PJRST WSCHED## ;WAIT FOR RESOURCE ;HERE TO TRY AND GET CX RESOURCE AT INTERRUPT LEVEL. RETURN CPOPJ1 ;IF WE HAVE IT, CPOPJ OTHERWISE. CALLER'S RESPONSIBILITY TO WAIT GETCX:: PUSH P,T1 ;SAVE T1 SYSPIF HRRZ T1,JBTCX##(J) ;GET OWNER OF CX RESOURCE WE DESIRE JUMPN T1,GETCXR ;OWNED BY SOMEONE ELSE MOVEM J,.CPCXJ## ;SAVE WE OWN IT SKIPN J ;JOB 0? SOSA .CPCXJ ;YES, FLAG OWN NUL JOB HLLOS JBTCX##(J) ;SAY A CPU OWNS IT AOS -1(P) ;GIVE GOOD RETURN GETCXR: SYSPIN JRST TPOPJ## ;COROUTINE TO GET AND GIVE THE CX RESOURCE (UUO LEVEL) GGVCX:: PUSHJ P,UPCX ;GET CX RESOURCE POP P,(P) PUSHJ P,@1(P) ;CALL BACK CAIA AOS (P) ; PJRST DWNCX ;(FALL INTO DWNCX) ;HERE TO RELEASE THE CX RESOURCE WE (THE JOB IN J) OWNS ;CALL GIVCX FOR INTERRUPT LEVEL (OWNED BY CPU), OR ;DWNCX *FOR UUO LEVEL ONLY* (OWNED BY JOB IN .CPJOB) DWNCX:: PUSH P,J ;SAVE J PUSH P,F ;SAVE F MOVE J,.CPJOB## ;GET JOB WHO IS RUNNING SYSPIF ;INTERLOCK HLRE F,JBTCX##(J) ;GET WHO WE OWN HRRZS JBTCX##(J) ;WE NO LONGER OWN HIM DWNCX1: SKIPL F ;IF OWNED NUL JOB HLLZS JBTCX##(F) ;HE IS NO LONGER OWNED SYSPIN JUMPL F,DWNCXR ;RETURN IF NUL SETZ F, ;**NO EVM** PUSHJ P,[PUSH P,T1 ;SAVE T1 PUSH P,J ;AND J PJRST SRFRCX##] DWNCXR: POP P,F POP P,J POPJ P, GIVCX:: PUSH P,J ;SAVE J PUSH P,F ;SAVE F SETZB F,J ;GET & CLEAR SYSPIF EXCH F,.CPCXJ## ;GET JOB JRST DWNCX1 ;HERE TO UNWIND CX RESOURCE AT SCHEDULAR LEVEL ;CALL WITH JOB WHOSE CX WE WANT IN J, RETURN WITH OWNER (IF ANY) IN T3 UNWCX:: HLRE T3,JBTCX##(J) ;WHO WE WANT SKIPLE T3 ;HUH? HRRE T3,JBTCX##(T3) ;OWNER POPJ P, ;HERE TO GRANT CX TO A JOB AT SCHEDULAR LEVEL SCDCX:: HLRE T3,JBTCX##(J) ;GET THE CX WE WANT JUMPLE T3,CPOPJ1## ;HUH? SYSPIF ;GUARD RACES HRL T3,JBTCX##(T3) ;MAKE SURE IT'S STILL FREE TLNE T3,-1 ;SOMEONE SNEAK IN? JRST ONPOPJ## ;YES, LOSE HRRM J,JBTCX##(T3) ;WE OWN HIS AOS (P) JRST ONPOPJ## ;WIN ;SUBROUTINE FOR CLOCK1 TO CALL TO SEE IF JOB IN J OWNS ANY CX RESOURCES ;SKIP RETURN IF OWN SOME CX, NON-SKIP OTHERWISE OWNCX:: PUSH P,T1 ;SAVE T1 HLRZ T1,JBTCX##(J) ;OWN ANYTHING? JUMPN T1,TPOPJ1## JRST TPOPJ## ;ROUTINE TO SEE IF WE OWN THE CX. NON-SKIP IF WE DON'T, SKIP ;IF WE DO. CX DESIRED IN T1 CXOWN:: CAMN T1,.CPCXJ## ;OWNED BY CPU? JRST CPOPJ1## ;YES PUSH P,T2 HRRZ T2,JBTCX##(T1) ;SEE WHO OWNS HIS CX CAMN T2,.CPJOB## ;US? AOS -1(P) ;YES JRST T2POPJ## SUBTTL ROUTINES TO REFERENCE USER CORE ;GETTAC -- RE-LOAD AC T1 FROM USER'S AC ON A CALLI OR ;THE LIKE, IN CASES WHERE T1 HAS BEEN DESTROYED. ;CALL: ; ; MOVE J,JOB NUMBER ; PUSHJ P,GETTAC ; RETURN ; ;ON RETURN THE USER'S AC IS IN T1. USES M, PRESERVES ALL OTHER ACS. ;CALL GETSAC FOR THE SAME RESULTS, EXCEPT GETWSU IS CALLED INSTEAD OF GETWDU GETTAC::LDB T1,PUUOAC## ;GET USER'S AC NUMBER HRR M,T1 ;PROVIDE AS ADDRESS TO READ PJRST GETWDU ;GO READ THE AC GETSAC::LDB T1,PUUOAC## ;GET USER'S AC NUMBER HRR M,T1 PJRST GETWSU ;GETWDU -- READ 1 WORD FROM USER VIRTUAL ADDRESS SPACE ;GETWD1 -- READ NEXT WORD FROM USER VIRTUAL ADDRESS SPACE ;CALL IS: ; ; MOVEI M, ; PUSHJ P,GETWDU ; RETURN ; ;WHERE IS USER VIRTUAL ADDRESS TO BE READ. ; ;DISPATCHES TO PAGE FAULT HANDLER ON A USER PAGE FAULT, OR PRINTS ILL ;ADR IN UUO IF NO SUCH ADDRESS. ; ;ON SUCCESSFUL RETURN THE USER WORD IS IN T1 AND, IF CALL WAS TO ;GETWD1 M IS UPDATED TO NEW USER VIRTUAL ADDRESS +1. J IS SET ;TO THE USER'S JOB NUMBER. ALL OTHER ACS PRESERVED. GETWD1::HRRI M,1(M) ;INCREMENT M BEFORE PICKING UP WORD GTWST2:: GETWDU::MOVE J,.CPJOB## ;MAKE SURE J CORRECT PUSHJ P,GETWRD ;GET THE WORD AND CHECK IF LEGAL JRST @[MCSEC0+UADERR##] ;ADDRESS NOT ACCESSIBLE, PRINT ERROR POPJ P, ;OK RETURN, T1=WORD ;GETWSU -- READ 1 WORD FROM USER VIRTUAL ADDRESS SPACE ;GETWS1 -- READ NEXT WORD FROM USER VIRTUAL ADDRESS SPACE ;SAME CALL AND RETURN AS GETWRD/GETWR1, BUT STOPCODES IF ;THE ADDRESS IS NOT AVAILABLE, AND DOES NOT LOAD J FROM .CPJOB GETWS1::HRRI M,1(M) GETWSU::PUSHJ P,GETWRD CAIA ;SEE IF MUST STOP POPJ P, PUSHJ P,INTLVL## ;AT INTERRUPT LEVEL? JRST @[MCSEC0+UADERR##] ;NO, ADDRESS CHECK STOPCD .,STOP,GNA ;++GETWRD NOT AVAILABLE ;GETXWD -- READ 1 WORD FROM ANYWHERE IN EXTENDED USER VIRTUAL ADDRESS SPACE ;PUTXWD -- WRITE 1 WORD TO ANYWHERE IN EXTENDED USER VIRTUAL ADDRESS SPACE ;CALL IS: ; ; XMOVEI M, -OR- MOVE M,[IFIW ] ; PUSHJ P,GETXWD/PUTXWD ; ERROR ; NORMAL ; ;USED FOR ONE-SHOT READ/WRITE TO RANDOM LOCATIONS IN THE USER'S ADDRESS SPACE ;OTHERWISE LIKE GETEWD/PUTEWD IFN FTXMON,< GETXWD::JUMPL M,GETWRD ;DO IT THE OLD WAY FOR IFIW FORMAT TDNN M,[^-<(IFIW!<1,,0>)>,,^-17] ;AN AC REFERENCE? JRST GETWRA ;YES, GO HANDLE AC REFERENCE PUSHJ P,SGPXWD ;SETUP FOR PXCT OF XBLT XBLTUX P1, ;READ THE WORD FROM THE USER ERJMP GETWRY ;ATTEMPT ERROR RECOVERY JRST CPOPJ1## ;SUCCEED PUTXWD::JUMPL M,PUTWRD ;IFIW CAN BE DONE MORE EASILY TDNN M,[^-<(IFIW!<1,,0>)>,,^-17] ;AN AC REFERENCE? JRST PUTWRD ;YES, HANDLE THAT THE OLD WAY PUSHJ P,SGPXWD ;SETUP FOR PXCT OF XBLT EXCH P2,P3 ;GOING THE OTHER WAY XBLTXU P1, ;WRITE THE WORD FOR THE USER ERJMP PUTWRZ ;ATTEMPT ERROR RECOVERY JRST CPOPJ1## ;SUCCEED SGPXWD: ADJSP P,2 ;MAKE SOME STORAGE ROOM DMOVEM P2,-1(P) ;SAVE THESE ACS EXCH P1,-2(P) ;SAVE P1 & GET RETURN PC MOVEM P1,1(P) ;USUAL CO-RETURN STORAGE PLACE MOVEI P1,1 ;GOING TO XBLT 1 WORD MOVE P2,M ;GLOBAL ADDRESS FROM M XMOVEI P3,T1 ;INTO T1 PUSHJ P,@1(P) ;CALL THE CALLER CAIA ;ERROR AOS -3(P) ;OR SKIP MOVE P1,-2(P) ;RECOVER AN AC DMOVE P2,-1(P) ;AND THE REST ADJSP P,-3 ;BALANCE THE STACK POPJ P, ;PROPAGATE RETURN > ;END OF IFN FTXMON ;GETWRD -- READ 1 WORD FROM USER VIRTUAL ADDRESS SPACE ;GETWR1 -- READ NEXT WORD FROM USER VIRTUAL ADDRESS SPACE ;CALL IS: ; ; MOVX J, ; MOVX M, ; PUSHJ P,GETWRD ; ERROR ; NORMAL ; ;WHERE IS USER JOB NUMBER AND IS USER VIRTUAL ADDRESS. ;CAN BE CALLED AT CLOCK OR UUO LEVEL. ; ;DISPATCHES TO PAGE FAULT HANDLER ON A USER PAGE FAULT, OTHERWISE ;RETURNS CPOPJ0 IF USER ADDRESS IS INACCESSIBLE. ; ;SUCCESSFUL RETURN IS CPOPJ1 WITH USER WORD IN T1 AND, IF CALL WAS ;TO GETWR1, WITH M INCREMENTED TO NEW USER VIRTUAL ADDRESS +1. ;ALL OTHER ACS ARE PRESERVED. IFN FTXMON,< GETEW1::JUMPL M,GETWR1 ;SKIP OVERHEAD FOR IFIW FORMS AOS T1,M ;INCREMENT GLOBAL ADDRESS TRNE T1,-1 ;DID IT CROSS A SECTION BOUNDARY? JRST GETEWD ;NO, DON'T BOTHER WITH THIS PUSHJ P,SXPCS ;YES, BUMP PCS TO KEEP IT CONSISTENT POPJ P, ;PROPAGATE FAILURES GETEWD::JUMPL M,GETWRD ;SKIP OVERHEAD FOR IFIW FORMS TDNN M,[^-<(IFIW!<1,,0>)>,,^-17] ;AN AC REFERENCE? JRST GETWRA ;YES, GO HANDLE AC REFERENCE SE1ENT ;MUST BE IN SECTION 1 FOR EACALC TO WORK UMOVE T1,@M ;NOT AN AC, FETCH FROM USER SPACE ERJMP GETWRY ;HANDLE ERRORS JRST CPOPJ1## ;RETURN GOODNESS GETMWD::LDB T1,[POINT 5,M,17] ;WHAT WE WANT PCS TO BE PUSHJ P,SVPCS## ;SAVE AND SETUP PCS PJRST GETWRD ;GET THE WORD > ;END OF IFN FTXMON IFE FTXMON,< GETEW1::! > GETWR1::HRRI M,1(M) ;INCREMENT M BEFORE PICKING UP WORD IFE FTXMON,< GETXWD::! GETEWD::! GETMWD::! > ;END OF IFE FTXMON GETWRD::TRNN M,777760 ;REFERENCE TO A USER AC? JRST GETWRA ;YES, HANDLE DIFFERENTLY GETWRU: MOVE T1,M IFN FTXMON,< TLZ T1,-1-MXSECN TRNN T1,777760 ;AC REFERENCE? TLZ T1,MXSECN ;YES, CLEAR POSSIBLE SECTION NUMBER > UMOVE T1,(T1) ERJMP GETWRY ;IF FAILED CHECK FOR PAGE FAULT ETC. JRST CPOPJ1## ;TAKE SKIP RETURN GETWRA::MOVE T1,J ;JOB NUMBER OR JCH ANDI T1,JOBMSK## ;JUST JOB NUMBER MOVE T1,JBTSTS##(T1) ;JOB STATUS FOR THIS JOB TRNN T1,JS.ASA ;REAL OR FAKE ACS? JRST GETWRU ;REAL, HANDLE NORMALLY AFTER ALL HRRZ T1,M ;CLEAR LEFT HALF JUNK MOVE T1,.JDAT(T1) ;FAKE, READ FROM SHADOW ACS AREA JRST CPOPJ1## ;SUCCESSFUL RETURN GETWRY: MOVE R,.CPADR## ;SET UP RELOCATION FOR VMSER PUSHJ P,FLTSY## ;CHECK FOR PAGE FAULT POPJ P, ;BAD ADDRESS-ERROR RETURN POPJ P, ;IT'S STILL BAD, FLTSY NOTWITHSTANDING ;STOTAC -- STORE WORD INTO USER AC ;STOTC1 -- STORE WORD INTO USER AC AND SKIP RETURN ;CALL IS: ; ; MOVX T1, ; PUSHJ P,STOTAC ; RETURN (STOTAC) ; RETURN (STOTC1) ; ;WHERE IS THE WORD TO BE WRITTEN INTO THE USER AC. ; ;PRESERVES ALL ACS. STOTC1::AOSA (P) ;SKIP RETURN RTM2:: MOVNI T1,2 ;RETURN -2 TO USER STOTAC::PUSH P,M ;SAVE M MOVS M,.USMUO ;GET MUUO OPCODE,AC IN LH LDB M,PUUOAC## ;GET USER'S AC PUSHJ P,PUTWDU ;STORE T1 IN USER'S AC JRST MPOPJ## ;RESTORE M AND RETURN ;PUTWDU -- WRITE 1 WORD INTO USER VIRTUAL ADDRESS SPACE ;PUTWD1 -- WRITE NEXT WORD INTO USER VIRTUAL ADDRESS SPACE ;CALL IS: ; ; MOVX M, ; MOVX T1, ; PUSHJ P,PUTWDU ; RETURN ; ;WHERE IS THE WORD TO BE WRITTEN INTO USER VIRTUAL ADDRESS ; ;DISPATCHES TO PAGE FAULT HANDLER ON A USER PAGE FAULT, OR PRINTS ILL ;ADR IN UUO IF NO SUCH ADDRESS. ; ;ON SUCCESSFUL RETURN THE USER WORD IS IN T1 AND, IF CALL WAS TO ;PUTWD1 M IS UPDATED TO NEW USER VIRTUAL ADDRESS +1. ;PRESERVES ALL OTHER ACS. IFN FTXMON,< PUTEW1::JUMPL M,PUTWR1 ;DO OLD WAY IF IFIW FORM AOS M ;INCREMENT GLOBAL ADDRESS TRNE M,-1 ;CROSSING A SECTION BOUNDARY? JRST PUTEWD ;NO, SKIP THIS PUSHJ P,SMPCS ;BUMP PCS FOR THIS FETCH POPJ P, ;PROPAGATE FAILURES PUTEWD::JUMPL M,PUTWRD ;DO OLD WAY IF IFIW FORM TDNN M,[^-<(IFIW!<1,,0>)>,,^-17] ;AN AC REFERENCE? JRST PUTWRD ;YES, DO IT THE OLD WAY SE1ENT ;MUST BE IN SECTION 1 FOR EACALC TO WORK UMOVEM T1,@M ;NOT AN AC, STORE TO USER SPACE ERJMP PUTWRZ ;HANDLE ERRORS JRST CPOPJ1## ;RETURN GOODNESS PUTMWD::PUSHJ P,SSPCS## ;PRESERVE PCS PUSH P,T1 ;SAVE WORD TO STORE LDB T1,[POINT 5,M,17] ;WHAT WE WANT PCS TO BE PUSHJ P,STPCS## ;SAVE AND SETUP PCS POP P,T1 ;RESTORE DATA WORD PJRST PUTWRD ;STORE THE WORD > ;END OF IFN FTXMON PUTWD1::HRRI M,1(M) ;INCREMENT M BEFORE STORING WORD PUTWDU::PUSH P,J ;SAVE J MOVE J,.CPJOB## ;SET UP J FOR THIS CPU'S JOB PUSHJ P,PUTWRD ;STORE THE WORD JRST @[MCSEC0+UADERR##] ;A LOSER JRST JPOPJ## ;A WINNER, RESTORE J AND RETURN ;PUTWSU -- WRITE 1 WORD INTO USER VIRTUAL ADDR SPACE ;PUTWS1 -- WRITE NEXT WORD ;CALL AND RETURN SAME AS PUTWDU/PUTWD1, BUT STOPCODES IF THE WORD ISN'T ;ADDRESSABLE AND DOES NOT LOAD J FROM .CPJOB PUTWS1::HRRI M,1(M) PUTWSU::PUSHJ P,PUTWRD CAIA ;SEE IF MUST STOP POPJ P, PUSHJ P,INTLVL## ;AT INTERRUPT LEVEL? JRST @[MCSEC0+UADERR##] ;NO, ADDRESS CHECK STOPCD .,STOP,PNA ;++PUTWRD NOT AVAILABLE ;PUTWRD -- WRITE 1 WORD INTO USER VIRTUAL ADDRESS SPACE ;PUTWR1 -- WRITE NEXT WORD INTO USER VIRTUAL ADDRESS SPACE ;CALL IS: ; ; MOVX J, ; MOVX M, ; MOVX T1, ; PUSHJ P,GETWRD ; ERROR ; NORMAL ; ;WHERE IS USER JOB NUMBER; IS USER VIRTUAL ADDRESS; ;AND IS THE WORD TO BE WRITTEN INTO THE USER ADDRESS . ;CAN BE CALLED AT CLOCK OR UUO LEVEL. ; ;DISPATCHES TO PAGE FAULT HANDLER ON A USER PAGE FAULT, OTHERWISE ;RETURNS CPOPJ0 IF USER ADDRESS IS UNWRITEABLE. ; ;SUCCESSFUL RETURN IS CPOPJ1 WITH USER WORD IN T1 AND, IF CALL WAS ;TO PUTWR1, WITH M INCREMENTED TO NEW USER VIRTUAL ADDRESS +1. ;ALL OTHER ACS PRESERVED. IFE FTXMON,< PUTEW1::! > PUTWR1::HRRI M,1(M) ;INCREMENT BEFORE STORING WORD IFE FTXMON,< PUTEWD::! PUTMWD::! > PUTWRD::PUSH P,T1 ;NEED A SCRATCH AC MOMENTARILY TRNN M,777760 ;REFERENCE TO USER AC? JRST PUTWRA ;YES, HANDLE DIFFERENTLY HRRZ T1,M ;GET USER VIRTUAL ADDRESS CAIG T1,JOBPFI## ;IN PROTECTED JOB DATA AREA? JRST TPOPJ## ;YES, TAKE FAILURE RETURN PUTWRU: POP P,T1 ;RESTORE VALUE TO BE DEPOSITED IFN FTXMON,< PUSH P,M TLZ M,-1-MXSECN TRNN M,777760 ;AN AC REFERENCE? TLZ M,MXSECN ;YES, CLEAR POSSIBLE SECTION NUMBER > UMOVEM T1,(M) ;STORE WORD IN USER ADDRESS SPACE ERJMP PUTWRY ;CHECK ON FAILURE IFN FTXMON,< POP P,M > JRST CPOPJ1## ;TAKE SUCCESSFUL RETURN PUTWRA: MOVE T1,J ;JOB NUMBER OR JCH ANDI T1,JOBMSK## ;JUST JOB NUMBER MOVE T1,JBTSTS##(T1) ;JOB STATUS FOR THIS JOB TRNN T1,JS.ASA ;REAL OR FAKE ACS? JRST PUTWRU ;REAL, TREAT NORMALLY AFTER ALL POP P,T1 ;FAKE ACS, RESTORE T1 PUSH P,M TLZ M,-1-MXSECN ;CLEAR POSSIBLE JUNK MOVEM T1,.JDAT(M) ;AND WRITE INTO SHADOW ACS POP P,M JRST CPOPJ1## ;ALWAYS SUCCEEDS PUTWRY: IFN FTXMON,< POP P,M ;RESTORE ORIGINAL CONTENTS > PUTWRZ: PUSH P,.USPFW ;SAVE PAGE FAIL WORD PUSHJ P,FLTSY## ;CHECK FOR PAGE FAULT JRST [POP P,(P) ;FIX STACK POPJ P, ] ;BAD ADDRESS EXCH T1,(P) ;SAVE T1, GET ADDRESS PUSH P,T2 ;SAVE T2 PUSH P,S ;PROTECT AGAINST PUSH P,P2 ; HGHDEP MOVE S,-3(P) ;HGHDEP WANTS WORD IN S MOVE T2,T1 ;AND ADDRESS IN T2 PUSH P,M ;MORE AC PROTECTION SNCALL (HGHDEP##,MCSEC0) ;TRY STUFFING INTO HIGH SEGMENT SOS -5(P) ;NOPE POP P,M ;RESTORE M POP P,P2 ;RESTORE POP P,S ; ACS POP P,T2 ; FROM JRST TPOPJ1## ; HGHDEP ;WARNING: ANY CHANGES MADE TO TSTREL SHOULD ALSO BE REFLECTED IN GETWRD & PUTWRD TSTREL::MOVEI T1,JS.ASA ;WHAT DOES REFERENCE TO USER 0-17 REALLY MEAN BIT TRNN M,777760 ;IS THIS REFERENCE TO USER 0-17? TDNN T1,JBTSTS##(J) ;YES, IS IT TO USER'S ACS OR THE SHADOW ACS? AOS (P) ;USER'S ACS POPJ P, ;GIVE SHADOW ACS OR USER AC SET RETURN SUBTTL USER ARGUMENT SECTION ROUTINE ;ROUTINE TO SETUP FOR FETCHING USER ARGUMENTS FROM ARBITRARY SECTIONS ;RESPECTS BOTH 30-BIT ADDRESS (REALLY ONLY 23-BIT) AND IFIW FORMS, ;BUT WITH NEITHER INDEXING NOR INDIRECTION. ;CALLING SEQUENCE: ; MOVE T1,[USER ADDRESS ARGUMENT, EITHER 30-BIT OR IFIW] ; PUSHJ P,SXPCS ; RETURN NON-SKIP ON ANY SORT OF ADDRESSING ERROR ; SKIP RETURN WITH PCS SETUP APPROPRIATELY IF EVERYTHING IS OK ;RESPECTS ALL ACS SMPCS:: EXCH T1,M ;SAME CALL, WITH ADDRESS IN M PUSHJ P,SXPCS ;DO THE DIRTY WORK CAIA ;NON-SKIP AOS (P) ;OR SKIP EXCH T1,M ;RESTORE ACS POPJ P, ;PROPAGATE RETURN SXPCS:: SKIPGE T1 ;IF AN IFIW, TLNN T1,^-<(IFIW)> ;CHECK IF TLNE T1,^-<(IFIW!)> ;ANY ATTEMPT AT INDEXING OR INDIRECTION? POPJ P, ;YES, RETURN FAILURE IFN FTXMON,< JUMPL T1,CPOPJ1## ;IF IFIW, PCS IS ALREADY CORRECT PUSH P,T1 ;SAVE T1 FOR CALLER HLRZS T1 ;ISOLATE SECTION NUMBER IN RH PUSHJ P,STPCS## ;SETUP PCS AS DESIRED JRST TPOPJ1## ;RETURN AS ADVERTISED > IFE FTXMON, ;RETURN GOODNESS IF NO XMON ;SUBROUTINE TO CHECK IF SEGMENT # IN J IS A LEGAL SEG # ;ARGS J=SEG# ;SKIP RETURN IF LEGAL SEGMENT #, NON-SKIP IF NOT LGJSEG::HRRZ T1,J LGLSEG::CAILE T1,JOBMAX## ;SKIP IF BELOW 1ST LEGAL SEG # CAIL T1,JBTMAX## ;NO, SKIP IF LEGAL SEG # POPJ P, JRST CPOPJ1## LGJPRC::SKIPA T1,J ;FROM J, EXCLUDE ZERO LGJPR1::SKIPA T1,J ;FROM J, ALLOW ZERO LGLPRC::JUMPLE T1,CPOPJ## ;JUMP IF LE 0 LGLPR1::CAIG T1,JOBMAX## JUMPGE T1,CPOPJ1## ;0 WAS ALREADY CHECKED POPJ P, ;-N ALWAYS ILLEGAL ;SUBROUTINE TO CREATE A PDB ;ARG J=JOB NUMBER $HIGH CREPDB::HRRZ W,JBTPDB##(J) ;SEE IF ALREADY ONE THERE JUMPE W,CREPD1 ;NONE PUSHJ P,SAVE4## ;SAVE COMCON FROM CTXSER'S DESTRUCTIVENESS PUSHJ P,CTXKIL## ;KILL OFF CONTEXT BLOCKS JRST CREPD2 ;ZERO OUT THE PDB CREPD1: MOVEI T2,.PDLEN## ;NUMBER OF WORDS NEEDED FOR A PDB PUSHJ P,GETWDS## ;GET CORE FOR PDB POPJ P, ;CAN'T GET THRU HRRZ W,T1 ;COPY ADDRESS TO STANDARD AC HRRM W,JBTPDB##(J) ;SAVE PDB ADDRESS CREPD2: SETZM (W) ;CLEAR ALL PDB MOVSI T1,(W) ;MAKE BLT PTR HRRI T1,1(W) BLT T1,.PDLEN##-1(W) MOVE T1,STNPRT## ;INITIALIZE DEAFULT MOVEM T1,.PDDFL##(W) ;TO STANDARD FILE PROTECTION MOVSI T1,(PD.LGN) ;GET THE LOGIN BIT IORM T1,.PDDFL##(W) ;SET IT IN THE WORD PUSHJ P,CTXBLK## ;CREATE AN INITIAL CONTEXT BLOCK JRST KILPDB ;NOT ENOUGH CORE PUSHJ P,ENQJBI## ;INIT QUEUE LIST HEADER JRST CPOPJ1## ;RETURN ;SUBROUTINE TO DEALLOCATE A PDB ;ARGS J=JOB NUMBER KILPDB::JUMPE J,CPOPJ## ;NEVER DELETE THE NULL JOB'S PDB IFN FTMP,< PUSHJ P,INTLVL## ;INTERRUPT LEVEL? JRST [EXCH T1,J ;UPCX WANTS ARG IN T1 PUSHJ P,UPCX ;NO, WAIT UUO LEVEL STYLE EXCH T1,J JRST KILPD1 ] PUSHJ P,GETCX JRST .-1 ;INTERRUPT LEVEL STYLE KILPD1: > ;END IFN FTMP HRRZ W,JBTPDB##(J) ;GET PDB ADDRESS JUMPE W,KILPD2 ;MUST HAVE ONE TO DELETE IT PUSHJ P,CTXKIL## ;GO CLEAN UP OLD CONTEXT BLOCKS MOVEI T1,.PDLEN## ;NUMBER OF WORDS FOR A PDB HRRZ T2,JBTPDB##(J) ;ADDR OF PDB PUSHJ P,GIVWDS## ;DEALLOCATE PDB KILPD2: HLLZS W,JBTPDB##(J) ;CLEAR ADDR OF PDB IFN FTMP,< PUSHJ P,INTLVL## ;INTERRUPT LEVEL? PJRST DWNCX ;GIVE IT UP UUO LEVEL STYLE PJRST GIVCX ;RETURN CX RESOURCE > ;END IFN FTMP IFE FTMP, ;RETURN $CSUB SUBTTL UUO ARGUMENT BLOCK CHECKING ROUTINES -- ARNGE - ADDRESS CHECKING ; ROUTINE TO PERFORM ADDRESS CHECKING ON UUO ARGUMENT BLOCKS. ; THIS HANDLES ALL CASES OF 30-BIT ADDRESSES AND IFIW WORDS. ; IT MAY ONLY BE CALLED AT UUO LEVEL. ; ; IF THE RANGE OF ADDRESSES CROSSES A SECTION BOUNDRY AND THE ; TARGET GIVEN WAS AN IFIW, THEN ADDRESS CHECK ERROR WILL BE ; RETURNED. OTHERWISE, A GLOBAL RANGE OF ADDRESSES WHICH CROSSES ; SECTION BOUNDRIES WILL BE CONSIDERED LEGAL. ; ; THE RANGE OF ADDRESSES IS CONSIDERED ILLEGAL FOR I/O IF ANY ; PAGE IN THE RANGE IS NOT MARKED AS WRITEABLE IN A PAGE MAP. ; ALSO, IF ANY PAGE IN THE RANGE IS MAPPED TO SECTION ZERO ; PAGE ZERO AND ANY ADDRESS RELATIVE TO THAT PAGE IS LESS THAN ; JOBPFI, THE RANGE WILL BE CONSIDERED ILLEGAL FOR I/O. ; ; CALL: MOVE T1, STARTING ADDRESS ; MOVE T2, LENGTH OF BLOCK ; PUSHJ P,ARNGE ; ;ADDRESS CHECK ; ;ADDRESS OK BUT ILLEGAL FOR I/O ; ;ADDRESS OK ; ; PCS AND ALL ACS ARE PRESERVED ARNGE:: PUSH P,T1 ;SAVE T1 PUSH P,T2 ;SAVE T2 PUSH P,T3 ;SAVE T3 PUSH P,T4 ;SAVE T4 PUSHJ P,ARNGE1 ;DO SOME WORK JRST ARNGEX ;ADDRESS CHECK ERROR AOS -4(P) ;ALL PAGES CHECKED OUT OK SKIPN T1 ;ANY PAGES ILLEGAL FOR I/O? AOS -4(P) ;YES ARNGEX: POP P,T4 ;RESTORE T4 POP P,T3 ;RESTORE T3 POP P,T2 ;RESTORE T2 POP P,T1 ;RESTORE T1 POPJ P, ;RETURN ARNGE1: SE1ENT ;ENTER SECTION 1 IFN FTXMON, ;SAVE PCS PUSHJ P,SXPCS ;SET NEW PCS POPJ P, ;BAD ARGUMENTS--ADDRESS CHECK ERROR PUSH P,T1 ;SAVE ADDRESS (WITH POSSIBLE IFIW) XSFM T3 ;GET PCS ANDI T3,MXSECN ;STRIP OFF JUNK HRL T1,T3 ;REPLACE POSSIBLE IFIW WITH REAL SECTION NUMBER ADD T2,T1 ;COMPUTE END ADDRESS +1 SUBI T2,1 ;LAST ADDRESS TO CHECK HLRZ T3,T1 ;GET STARTING SECTION NUMBER HLRZ T4,T2 ;AND ENDING SECTION NUMBER EXCH T1,(P) ;GET POSSIBLE IFIW BACK CAIE T3,(T4) ;CROSS SECTION ? JUMPE T3,TPOPJ## ;ILLEGAL FROM SECTION 0 CAIE T3,(T4) ;CROSS SECTION BOUNDRY? JUMPL T1,TPOPJ## ;YES--ADDRESS CHECK ERROR IF AN IFIW GIVEN MOVEI T1,0 ;CLEAR ILLEGAL I/O FLAG EXCH T1,(P) ;SAVE AND RETRIEVE FULL 30-BIT ADDRESS PUSHJ P,INTLVL## ;ARE WE AT UUO LEVEL? TDNE T2,[^-1,,^-17] ;AND IS ENDING ADDRESS AN AC? JRST ARNGE2 ;NO, SKIP THE SPECIAL CASE CAMGE T2,T1 ;DO ADDRESSES GO BACKWARDS? JRST TPOPJ## ;YES, FATAL CAIN T3,(T4) ;IS ENTIRE RANGE IN THE ACS IN ONE SECTION? JRST TPOPJ1## ;YES, THIS IS ALWAYS LEGAL EVEN FOR I/O MOVEI T2,-1 ;NO, ONLY CHECK TO END OF S0 WHEN CROSSING ARNGE2: HLRZ T3,T1 ;GET SECTION NUMBER CAIG T3,MXSECN ;HAVE A REASONABLE SECTION NUMBER? SKIPN .UPMP+SECTAB(T3);AND DOES THE SECTION EXIST? JRST TPOPJ## ;NO--ADDRESS CHECK ERROR MOVE T3,T1 ;COPY TARGET ADDRESS LSH T3,W2PLSH ;CONVERT TO A PAGE NUMBER HRRZ T4,T1 ;GET RELATIVE ADDRESS WITHIN SECTION CAILE T4,JOBPFI## ;IN PROTECTED JOBDAT? JRST ARNGE3 ;NO MOVE T4,@[IW MS.MAP,UMAPS(T3)] ;POINTER FOR PAGE 0 OF PCS SECTION CAMN T4,@[IW MS.MAP,UMAPS] ;SAME AS POINTER FOR PAGE 0 OF SECTION 0? AOS (P) ;ADDRESS ILLEGAL FOR I/O ARNGE3: SKIPN T4,@[IW MS.MAP,UMAPS(T3)] ;GET POINTER FOR THIS PAGE JRST TPOPJ## ;NON-EXISTANT--ADDRESS CHECK ERROR ARNGE4: TLNE T4,(PM.NIA!PM.SPY) ;I/O LEGAL? AOS (P) ;NO--SAY ILLEGAL FOR I/O LDB T3,[POINT 3,T4,2] ;GET POINTER TYPE JUMPE T3,ARNGE6 ;PAGED OUT, AA OFF, OR ABZ--PAGE FAULT CAIN T3,PM.DCD ;ELSE IS IT A DIRECT POINTER? JRST ARNGE5 ;YES CAIE T3,PM.ICD ;INDIRECT POINTER? JRST [HRRZS T4 ;NO, SHARED, GET SPT INDEX SKIPN T4,SPTTAB##(T4) ;GET POINTER JRST TPOPJ## ;ADDRESS CHECK ERROR IF NONE JRST ARNGE4] ;LOOP OVER POINTERS LDB T3,[POINT 9,T4,17] ;GET INDEX INTO SECONDARY PAGE MAP HRRZS T4 ;GET SPT INDEX HRRZ T4,SPTTAB##(T4) ;GET POINTER TO USE FROM SPT JUMPE T4,TPOPJ## ;FAIL IF SPT SLOT NOT SETUP TLO T4,(B2) ;MAKE VALID MAPPING ENTRY PUSH P,.UPMP+.UMTMP ;SAVE TEMPORARY MAPPING SLOT MOVEM T4,.UPMP+.UMTMP ;STORE MAP POINTER TRO T3,.TEMP ;MAKE FULL ADDRESS FOR FETCH CLRPT .TEMP ;CLEAR PAGING MEMORY SO NEW MAPPING IS USED MOVE T4,@T3 ;GET MAP ENTRY POP P,.UPMP+.UMTMP ;RESTORE TEMPORARY MAPPING SLOT CLRPT .TEMP ;CLEAR PAGING MEMORY SO OLD MAPPING IS USED JUMPN T4,ARNGE4 ;CHASE DOWN MAP POINTER JRST TPOPJ## ;FAIL IF NEXT SLOT IN CHAIN IS ZERO ARNGE6: PUSHJ P,INTLVL## ;AT INTERRUPT LEVEL? JRST @[MCSEC0+UUOFLT##] ;NO, LET PFH HAVE IT AOS (P) ;YES, CONSIDER IT ILLEGAL FOR I/O ; JRST ARNGE5 ;KEEP ON TRUCKING AT INTERRUPT LEVEL ARNGE5: TRO T1,PG.BDY ;ROUND UP TO TOP OF PAGE CAML T1,T2 ;PAST THE END OF THE BLOCK JRST TPOPJ1## ;YES--ALL ADDRESSES CHECK OUT OK ADDI T1,PAGSIZ ;ON TO THE NEXT PAGE JRST ARNGE2 ;LOOP BACK SUBTTL UUO ARGUMENT BLOCK CHECKING ROUTINES -- PRNGE - BYTE POINTER ; CHECK A RANGE OF ADDRESSES GIVEN A BYTE POINTER ; CALL: MOVE T1, BYTE POINTER ; MOVE T2, BYTE COUNT ; PUSHJ P,PRNGE ; ;ADDRESS CHECK ; ;ADDRESS OK BUT ILLEGAL FOR I/O ; ;ADDRESS OK ; ; PCS AND ALL ACS EXCEPT T1-T3 ARE PRESERVED PRNGE:: IBP T1 ;POINT TO FIRST REAL BYTE SOJ T2, ;OFFSET FOR IBP ABOVE ADJBP T2,T1 ;POINT AT END LDB T3,[POINT 6,T1,5] ;GET BYTE POSITION CAILE T3,^D36 ;OWGBP? TLZA T1,(77B5) ;YES HRLI T1,(IFIW) ;OR NO CAILE T3,^D36 ;AGAIN? TLZA T2,(77B5) ;GLOBAL HRLI T2,(IFIW) ;OR LOCAL ADDRESS SUB T2,T1 ;FINALLY, MAKE A COUNT FOR ARNGE AOJA T2,ARNGE ;GO RANGE CHECK THE BLOCK SUBTTL UUO ARGUMENT BLOCK CHECKING ROUTINES -- QRNGE - BYTE POINTER ; CHECK A RANGE OF ADDRESSES GIVEN A BYTE POINTER ; CALL: MOVE T1, BYTE POINTER WORD 1 ; MOVE T2, BYTE POINTER WORD 2 ; MOVE T3, BYTE COUNT ; MOVE M, ADDRESS OF SCRATCH LOCATION FOR PUTEWD ; PUSHJ P,QRNGE ; ;ADDRESS CHECK ; ;ADDRESS OK BUT ILLEGAL FOR I/O ; ;ADDRESS OK ; ; PCS AND ALL ACS EXCEPT T1-T4 ARE PRESERVED ; T1 & T2 HAVE A RESOLVED BYTE POINTER IN THEM ON RETURNS 2 & 3 ; ;NOTE THAT THE SCRATCH LOCATION REQUIRED IS USUALLY THE ADDRESS FROM WHICH ;THE SECOND WORD OF THE BYTE POINTER WAS FETCHED. ; ;NOTE ALSO THAT THE RESOLVED BYTE POINTER RETURNED WILL HAVE CONVERTED A ;OWGBP INTO A TWO-WORD GLOBAL, EVEN IF PCS IS ZERO. IF YOU WANT TO USE ;THE BYTE POINTER DIRECTLY IN A PXCT, CALL ORNGE INSTEAD. ; ;ORNGE REQUIRES THAT RETURNS 2 & 3 LEAVE T3 NON-NEGATIVE. QRNGE:: LDB T4,[POINT 6,T1,5] ;PICK UP P OR P&S FIELD IFE FTXMON,< CAIG T4,44 ;IS THIS A OWGBP? JRST QRNGE2 ;NO, MUST BE LOCAL-SECTION > IFN FTXMON,< CAILE T4,44 ;IS THIS A OWGBP? JRST QRNGE1 ;YEP--GO BREAK IT DOWN XSFM T4 ;GET PCS SKIPN T4 ;IF FROM SECTION ZERO, TLZA T1,(1B12) ;CAN'T BE TWO-WORD FORMAT TLNN T1,(1B12) ;IS IT IN TWO-WORD FORMAT? JRST QRNGE2 ;NO--MUST CONVERT TLNE T1,37 ;IS THE RESERVED FIELD IN USE? POPJ P, ;YES--THIS IS ILLEGAL JRST QRNGE3 ;GO EVALUATE ADDRESS > ;END OF IFN FTXMON QRNGE1: CAIL T4,77 ;IS IT LEGAL EVEN FOR A OWGBP? POPJ P, ;NO--CRY FOUL MOVE T2,T1 ;COPY BYTE POINTER (FOR ADDRESS) MOVE T1,OWGBPT-45(T4);GET LH OF EQUIVALENT BYTE POINTER TLZ T2,(77B5) ;ISOLATE ADDRESS JRST QRNGE4 ;GO CHECK OUT ADDRESS QRNGE2: MOVE T2,T1 ;COPY BYTE POINTER (FOR ADDRESS) TLZ T2,^-37 ;GET RID OF P & S FIELDS TLO T2,(IFIW) ;MAKE SECTION LOCAL TLZ T1,77 ;KEEP ONLY P & S FIELDS IN FIRST WORD QRNGE3: EXCH T1,T2 ;SWAP WORDS FOR A BIT PUSHJ P,PUTEWD ;STUFF ADDRESS WORD JRST [EXCH T1,T2 ;SWAP BACK POPJ P,] ;GIVE ERROR RETURN HRRZ T1,M ;GET ADDRESS POINER FOR EACALC PUSHJ P,EACALC ;GET EFFECTIVE ADDRESS FROM BYTE POINTER VALUE JRST [EXCH T1,T2 ;SWAP BACK POPJ P,] ;PROPAGATE ERROR EXCH T1,T2 ;SWAP B.P. VALUES BACK AGAIN HLLZS T1 ;CLEAR POSSIBLE JUNK QRNGE4: TLNN T1,(1B12) ;IS THIS A TWO-WORD POINTER? HRR T1,T2 ;NO, KEEP A VALID ONE-WORD FORM FOR DECNET PUSH P,T1 ;SAVE THE BYTE POINTER PUSH P,T2 ;AS A DOUBLE-WORD LDB T4,[POINT 6,T1,11] ;GET S FIELD CAILE T4,44 ;IS IT REASONABLE? JRST TTPOPJ## ;NO--AVOID IME JUMPE T4,TTPOPJ## ;DISALLOW ZERO-SIZED BYTES MOVEI T1,^D36 ;YES, GET WORD SIZE IDIVI T1,(T4) ;SEE HOW MANY BYTES FIT IN A WORD LDB T2,[POINT 6,-1(P),5] ;GET P FIELD EXCH T2,T3 ;MOVE FOR SAFETY IDIVI T3,(T4) ;SEE HOW MANY BYTES IN FIRST WORD SUB T2,T3 ;COUNT OF BYTES BEYOND FIRST WORD MOVE T4,T3 ;SAVE FIRST WORD COUNT IDIVI T2,(T1) ;COUNT OF ADDITIONAL WORDS REFERENCED SKIPE T3 ;IF ANY REMAINDER, AOS T2 ;REFERENCE ANOTHER WORD SKIPE T4 ;IF ANY IN FIRST WORD, AOS T2 ;REFERENCE IT TOO SKIPE T4 ;IF ANY IN FIRST WORD, TDZA T1,T1 ;THEN START THERE MOVEI T1,1 ;ELSE START ONE AFTER IT ADD T1,(P) ;FORM BEGINNING ADDRESS TO CHECK PUSHJ P,ARNGE ;CHECK THE WORDS JRST TTPOPJ## ;ILLEGAL ADDRESS IN RANGE TRNA ;READ ONLY AOS -2(P) ;PROPAGATE SKIPNESS AOS -2(P) ;SINGLE OR DOUBLE JRST TTPOPJ## ;AND RETURN MUNGED BYTE POINTER WORDS OWGBPT: DEFINE X(SIZ),< IRP SIZ,< .ZZ==-1 REPEAT ^D<36/>+1,< ,,.ZZ>!IFN FTXMON,<1B12> .ZZ==.ZZ+^D > > > X<6,8,7,9,18> OWGTLN==.-OWGBPT ;LENGTH OF THIS TABLE IF2, SUBTTL UUO ARGUMENT BLOCK CHECKING ROUTINES -- ORNGE - BYTE POINTER ; CHECK A RANGE OF ADDRESSES GIVEN A BYTE POINTER ; CALLING SEQUENCE IS IDENTIAL TO THAT OF QRNGE, WHICH IS CALLED. ; ; ON RETURNS 2 & 3, A RESOLVED BYTE POINTER WILL BE RETURNED. THIS BYTE ; POINTER WILL BE IN ONE-WORD FORMAT IF POSSIBLE. IT WILL BE A ONE-WORD ; GLOBAL IFF T3 IS NEGATIVE. ORNGE:: PUSHJ P,QRNGE ;RESOLVE THE BYTE POINTER POPJ P, ;PROPAGATE FAILURE TRNA ;ILLEGAL FOR I/O RETURN AOS (P) ;PROPAGATE SKIPNESS AOS (P) ;SINGLE OR DOUBLE IFN FTXMON,< TLNN T1,(1B12) ;TWO-WORD FORMAT? JRST ORNGE3 ;NO, RETURN ONE-WORD LOCAL JUMPL T2,ORNGE2 ;CONVERT TWO-WORD LOCAL TO ONE-WORD LOCAL XSFM T3 ;GET PCS (AMONG OTHER THINGS) TSC T3,T2 ;XOR SWAPPED TRNN T3,MXSECN ;GLOBAL ADDRESS IN CURRENT SECTION? JRST ORNGE2 ;YES, CONVERT TO ONE-WORD LOCAL MOVSI T3,-OWGTLN ;GET AOBJN POINTER TO OWGBPT CONVERSION TABLE ORNGE1: CAME T1,OWGBPT(T3) ;IS THIS A MATCH? AOBJN T3,ORNGE1 ;NO, KEEP LOOKING JUMPGE T3,CPOPJ## ;OH, WELL, WE'RE STUCK WITH A TWO-WORD GLOBAL HRRZI T1,45(T3) ;GOT A MATCH, CONVERT TO P&S BYTE LSH T1,^D30 ;POSITION IT IOR T1,T2 ;GET ONE-WORD FORM POPJ P, ;RETURN ORNGE2: TLZ T1,(1B12) ;NOT REALLY GLOBAL AFTER ALL > ;END OF IFN FTXMON ORNGE3: HRR T1,T2 ;MAKE ONE-WORD LOCAL POPJ P, ;RETURN SUBTTL UUO ARGUMENT CHECKING - DECNET-STYLE STRING BLOCK ; ; CHKSTB - CHECK A STRING BLOCK FOR ADDRESSABILITY ; ;CALL: M/ ADDRESS OF STRING BLOCK ; ;RETURN: +1 NOT WRITEABLE OR READABLE ; +2 SUCCESS. MAX BYTE COUNT IN T4 ; ;SIDE-EFFECTS: ; THE BYTE-COUNT IN THE STRING BLOCK IS ZEROED, FOR CONVENIENCE ; IN DEALING WITH ERRORS. IFN FTNET,< CHKSTB::MOVE T1,M ;GET ADDRESS OF BLOCK IFN FTXMON, ;PRESERVE PCS FOR CALLER PUSHJ P,SXPCS ;VALIDATE POINTER TO STRING BLOCK POPJ P, ;NO GO PUSHJ P,GETEWD ;GET FIRST WORD OF STRING BLOCK POPJ P, ;NOT THERE HRRZ T2,T1 ;SAVE LENGTH (IN WORDS) MOVE T1,M ;GET ADDRESS OF BLOCK PUSHJ P,ARNGE ;CHECK IT POPJ P, ;NOT ADDRESSABLE POPJ P, ;NOT WRITEABLE MOVE T1,T2 ;GET LENGTH IN RIGHT AC PUSHJ P,PUTEWD ;AND STUFF IT BACK WITH A 0 LH POPJ P, ;NOT WRITABLE? SOS T4,T1 ;ONE LESS THAN THIS AVAILABLE FOR BYTES LSH T4,2 ;4 BYTES PER WORD JRST CPOPJ1## ;OK > ;END IF IFN FTNET SUBTTL UUO ARGUMENT BLOCK CHECKING ROUTINES -- EACALC - EFFECTIVE ADDR CALC ; ROUTINE TO DO EFFECTIVE ADDRESS CALCULATION ON A UUO ARGUMENT. ; CALL: MOVE T1, SECTION RELATIVE UVA CONTAINING WORD FOR EACALC ; PUSHJ P,EACALC ; ;ILLEGAL ADDRESS REFERENCED ; ;T1 HAS RESOLVED ADDRESS ; ; THE WORD MAY BE EFIW OR IFIW AND OPTIONALLY CONTAIN LOCAL OR ; GLOBAL INDEXING AND INDIRECTION. ON RETURN, T1 WILL CONTAIN ; THE RESOLVED USER VIRTUAL ADDRESS. NO LEGALITY CHECKS ARE MADE ; ON THE ADDRESS. PRESEUMABLY, SOME FLAVOR OF GETWRD/PUTWRD WILL ; TAKE CARE OF ADDRESS CHECKING. ALL ACS ARE PRESERVED. EACACC::MOVE T1,JBTSTS##(J) ;GET JOB STATUS SNCALL (USCHD1##,MCSEC0) ;LET USER CONTROL-C OUT SKIPA T1,(P) ;GET UVA BACK EACALC::PUSH P,T1 ;SAVE UVA HRLI T1,(XMOVEI T1,@);FORM INSTRUCTION ; HERE TO DO ACTUAL EFFECTIVE ADDRESS CALCULATION. KAF STOPCODES ARE ; AVOIDED BY HAVING CLOCK1 (CLKINT) CHECK THE INTERRUPTING PC. IF IT ; IS EACAPC, THEN THE SCHEDULER WILL RUN. INFINITE LOOPS IN EXEC MODE ; WHERE THE USER CAN'T CONTROL-C OUT ARE AVOIDED BY CHECKING CNTRLC IN ; JBTSTS AND ALTERING THE INTERRUPTING PC TO BE EACACC, THUS ALLOWING ; THE USER TO REACH MONITOR LEVEL THE NEXT TIME THE JOB IS SCHEDULED. EACAPC::PXCT PX.EAC,T1 ;LET HARDWARE DO EFFECTIVE ADDRESS CALCULATION ERJMP .+2 ;NON-SKIP FOR ILLEGAL ADDRESS REFERENCE AOS -1(P) ;ADDRESS OK POP P,(P) ;PRUNE STACK POPJ P, ;AND RETURN SUBTTL SUBROUTINES TO REFERENCE PHYSICAL MEMORY ;ROUTINE TO FETCH THE CONTENTS OF A GIVEN PHYSICAL ADDRESS. ;CALL: ; T2/ PHYSICAL ADDRESS ; PUSHJ P,PHMOV ;RETURN: ; CPOPJ ALWAYS WITH: ; T2/ CONTENTS ;MUST PRESERVE T1 AND T3. $CSENT (PHMOV::) SKIPE .CPPMV## ;INSTRUCTION IMPLEMENTED? JRST [PMOVE T2,T2 ;YES, FETCH THE CONTENTS POPJ P,] ;RETURN PUSHJ P,SAVE3## ;SAVE P1-P3 DMOVE P1,T1 ;COPY T1 AND T2 MOVE P3,T3 ;AND T3 PUSHJ P,MAPLOC## ;GET A MAP SLOT TO USE DPB P2,[POINT 9,T3,35] ;SET LINE IN PAGE LSH P2,W2PLSH ;CONVERT TO PAGE NUMBER HRLI P2,(B2) ;MAKE IT ACCESSIBLE DPB P2,T1 ;STORE MAPPING IN EXEC PAGE MAP CLRPT .ERPIL ;MAKE THE NEW MAPPING VISIBLE MOVE T2,0(T3) ;FETCH THE CONTENTS PUSHJ P,UNMAP## ;GIVE UP THE MAP SLOT MOVE T1,P1 ;RESTORE T1 MOVE T3,P3 ;AND T3 POPJ P, ;RETURN ;ROUTINE TO STORE DATA INTO A GIVEN PHYSICAL ADDRESS. ;CALL: ; T2/ PHYSICAL ADDRESS ; T3/ DATA TO STORE ; PUSHJ P,PHMOVM ;RETURN: ; CPOPJ ALWAYS ;MUST PRESERVE T1 AND T3. $CSENT (PHMOVM::) SKIPE .CPPMV## ;INSTRUCTION IMPLEMENTED? JRST [PMOVEM T3,T2 ;YES, STORE THE CONTENTS POPJ P,] ;RETURN PUSHJ P,SAVE3## ;SAVE P1 - P3 DMOVE P1,T1 ;COPY T1 AND T2 MOVE P3,T3 ;COPY DATA TO STORE PUSHJ P,MAPLOC## ;GET A MAP SLOT TO USE DPB P2,[POINT 9,T3,35] ;SET LINE IN PAGE LSH P2,W2PLSH ;CONVERT TO PAGE NUMBER HRLI P2,(B2!PM.WRT) ;MAKE IT ACCESSIBLE AND WRITABLE DPB P2,T1 ;STORE MAPPING IN EXEC PAGE MAP CLRPT .ERPIL ;MAKE THE NEW MAPPING VISIBLE MOVEM P3,0(T3) ;STORE THE DATA PUSHJ P,UNMAP## ;GIVE UP THE MAP SLOT MOVE T1,P1 ;RESTORE T1 MOVE T3,P3 ;AND T3 POPJ P, ;RETURN $LIT DATEND: END