Google
 

Trailing-Edge - PDP-10 Archives - bb-jr93d-bb - 7,6/ap017/mosser.x17
There is 1 other file named mosser.x17 in the archive. Click here to see a list.
TITLE	MOSSER - MODULE TO SUPPORT MOS MEMORY - THGA - V022
SUBTTL	J.M. FLEMMING/JMF  TS   24 SEP 85
	SEARCH	F,S
	$RELOC
	$HIGH



;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
.CPYRT<1973,1986>
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986
;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL RIGHTS RESERVED.
;
;XP VMOSSER,022
		; PUT VERSION NUMBER IN GLOB LISTING AND LOADER STORAGE MAP

	ENTRY	MOSSER		;LOAD MOSSER IF LIBRARY SEARCH
MOSSER::
;SEND AN IPCF MESSAGE TO THGA
;WORRY ABOUT HARD ERRORS
;TURN CLOCKS OFF ON ALL CPU'S
MOSTAB:	-10,,10
	-5,,0

	PHASE	0
MOSERB:!BLOCK	0	;(0) MOS ERROR REPORT BLOCK
MOSEID:!BLOCK	1	;(0) MOS ERROR REPORT IDENTIFICATION WORD
MOSECN:!BLOCK	1	;(1) ENTRY TYPE AND CONTROLLER NUMBER
MOSERA:!BLOCK	1	;(2) ERA AT ERROR
MOSSAE:!BLOCK	1	;(3) SYNDROME AT ERROR
MOSBLN:!BLOCK	1	;(4) BLOCK NUMBER
MOSSBN:!BLOCK	1	;(5) SPARE BIT NUMBER
MOSEAD:!BLOCK	1	;(6) 22 BIT ERROR ADDRESS
MOSCSN:!BLOCK	4	;(7) CONTROLLER SERIAL NUMBERS
MOSAID:!BLOCK	1	;(13) APRID OF CPU ERROR OCCURED ON
MOSLEB==.-MOSERB	;LENGTH OF THE ERROR BLOCK
	DEPHASE




MOSMEM:	DEC	5		;MAX MOS ERRORS/MIN TO REPORT





;HERE FROM CLOCK1 EACH MINUTE
MOSMIN:: SETZM	.CPMET##		;CLEARS ERRORS THIS MINUTE
	 POPJ	P,		

;HERE FROM COMMON ON AN SBUS ERROR

SBERR::	PUSHJ	P,SAVE4##	;SAVE PRESERVED ACS
	PUSHJ	P,SAVT##	;ALSO TEMPS SINCE AT INTERRUPT LEVEL
	MOVEI	P1,2		;NUMBER OF ENTRIES IN MOSTAB
	JRST	SBERR3		;GO PROCESS
SBERR1:	MOVEI	T1,0		;FUNCTION 0
	DPB	P2,[POINT 5,T1,4] ;CONTROLLER NUMBER
	SBDIAG	T1		;READ IT
	MOVE	P4,T2		;SBDIAG FUNCTION 0 RESULTS
	CAME	T2,[-1]		;CONTROLLER EXIST?
	TLNN	T2,770000	;YES, ANY ERRORS?
	JRST	SBERR2		;NO, SKIP ON
	HRRI	T1,1		;CONTROLLER NUMBER,,FUNCTION 1
	SBDIAG	T1		;READ IT
	LDB	T3,[POINT 4,T2,11] ;CONTROLLER TYPE
	CAIN	T3,5		;MOS?
	TRNE	T2,2000		;AND ENABLED?
	JRST	SBERR2		;NO
	JRST	SBERR4		;YES, PROCESS THE ERROR
SBERR2:	AOBJN	P2,SBERR1	;NEXT CONTROLLER
SBERR3:	SOJL	P1,SBERR6	;SCANNED ALL OF MOSTAB?
	MOVE	P2,MOSTAB(P1)	;NO, NEXT ENTRY IN MOSTAB
	JRST	SBERR1		;LOOP OVER ALL OF MOSTAB
SBERR4:	TLNN	P4,200000	;CORRECTABLE ERROR?
	JRST	S..SB0##	;********NO, SHOULDN'T GET HERE ON A DOUBLE BIT ERROR?
	AOS	.CPTME##		;COUNT AN ACTUAL MOS ERROR
	AOS	T1,.CPMET##	;ANOTHER THIS MINUTE
	CAMLE	T1,MOSMEM	;TOO MANY?
	  JRST  SBERR6		;YES DON'T FLOOD THE WORLD
	AOS	.CPMEC##		;NO, ANOTHER TO TGHA
	MOVEI	T2,MOSLEB	;LENGTH OF AN ERROR BLOCK
	PUSHJ	P,GETWDS##	;1 WORD HEADER, 11 WORDS OF ERROR INFO
	  JRST	SBERR6		;CAN'T DO IT
	HRLI	T1,MOSLEB	;PUT LENGTH IN THE LEFT HALF, IPCF WANTS IT THERE
	PUSH	P,T1		;LENGTH,,ADDRESS
	MOVSI	T2,(T1)		;ZERO BLOCK SINCE SOME BITS/BYTES DON'T GET FILLED IN
	HRRI	T2,1(T1)
	SETZM	(T1)		;ZERO FIRST WORD OF THE BLOCK
	BLT	T2,MOSLEB-1(T1)	;ZAP, THE ERROR BLOCK IS ZERO
	MOVE	T2,[MOSLEB,,.IPCME##]
	MOVEM	T2,MOSEID(T1)
	MOVEI	T2,.PMMER	;ENTRY TYPE
	DPB	T2,[POINT 9,MOSECN(T1),8]
	DPB	P2,[POINT 18,MOSECN(T1),35]	;STORE CONTROLLER NUMBER
	RDERA	MOSERA(T1)	;ERA AT ERROR
	TRZ	P4,3		;LEFT MOST 34 BITS OF ERROR ADDRESS
	MOVEI	T3,2		;FUNCTION 2
	DPB	P2,[POINT 5,T3,4] ;CURRENT CONTROLLER
	SBDIAG	T3		;RESULTS OF FUNCTION 2
	LDB	T4,[POINT 2,T4,6] ;LOW TWO BITS OF ADDRESS
	IOR	P4,T4		;FULL WORD ADDRESS OF THE ERROR
	MOVEM	P4,MOSEAD(T1)	;STORE THAT
	HRRI	T3,1B27+6	;FUNCTION 6.1
	SBDIAG	T3		;SYNDROME
	LDB	T4,[POINT 6,T4,12] ;SYNDROME
	MOVEM	T4,MOSSAE(T1)	;SYNDROME AT ERROR
	HRRI	T3,12		;SETUP TO GET BLOCK NUMBER
	LDB	T4,[POINT 8,P4,21] ;GET RAM ADDRESS FROM EFFECTIVE ADDRESS
	DPB	T4,[POINT 8,T3,27] ;WHAT TO READ
	SBDIAG	T3		;READ IT
	LDB	T4,[POINT 4,T4,13] ;GET BLOCK NUMBER
	MOVEM	T4,MOSBLN(T1)	;STORE BLOCK NUMBER
	HRRI	T3,7		;SETUP TO GET SPARE BIT NUMBER
	DPB	T4,[POINT 4,T3,24] ;BLOCK NUMBER
	LDB	T2,[POINT 3,P4,35] ;OFFSET WITHIN INTERLEAVE GROUP
	DPB	T2,[POINT 3,T3,27] ;STORE ADDRESS
	SBDIAG	T3		;READ SPARE BIT NUMBER
	LDB	T2,[POINT 6,T4,12] ;SPARE BIT NUMBER
	MOVEM	T2,MOSSBN(T1)	;STORE IT
	TLNN	T4,(1B13)
	TLC	T4,(7B15)	;COMPLEMENT ICE FIELD (IGNORE CORRECTABLE ERROR)
	IOR	T3,T4		;SUPPRESS CORRECTABLE ERROR REPORTING
	TLNE	P4,200000	;IF NOT A HARD ERROR,
	SBDIAG	T3		;CAUSE FUTURE ERRORS TO BE FIXED AND IGNORED
;HERE TO READ CONTROLLER SERIAL NUMBERS
	MOVEI	T3,2		;HOW TO GET SERIAL NUMBERS
	DPB	P2,[POINT 5,T3,4] ;CONTROLLER
	MOVE	T4,MOSBLN(T1)	;BLOCK NUMBER
	LSH	T4,-2
	DPB	T4,[POINT 2,T3,10] ;SET BLOCK NUMBER DIVIDED BY 4
	MOVE	T2,[POINT 8,MOSCSN(T1),3]
	MOVEI	P3,^D16		;NUMBER OF BYTES OF SERIAL NUMBER
SBERR5:	SBDIAG	T3		;NEXT BYTE OF THE SERIAL NUMBER
	LDB	T4,[POINT 8,T4,14] ;GET THE BYTE
	IDPB	T4,T2		;STORE IT IN THE ERROR BLOCK
	ADD	T3,[1B14]	;NEXT BYTE
	TLNN	T2,770000	;TGHA WANTS THE SERIAL NUMBERS RIGHT JUSTIFIED
	ADD	T2,[POINT 0,1,3];SKIP THE HIGH FOUR BITS
	SOJG	P3,SBERR5	;GET THE NEXT ONE
	APRID	MOSAID(T1)	;APR ID OF CPU ERROR WAS DECTECTED ON
	PUSHJ	P,MAPLOC##	;GET A MAP SLOT TO MAKE THE ERROR LOCATION ADDRESSABLE
	LDB	T4,[POINT 14,P4,26] ;PHYSICAL PAGE NUMBER WHERE THE ERROR OCCURED
	HRLI	T4,(<PM.DCD>B2+PM.WRT+PM.PUB)

	DPB	T4,T1		;STORE MAPPING IN THE EXEC MAP
	CLRPT	(T3)		;MAKE SURE THE NEW MAPPING IS IN EFFECT
	LDB	T1,[POINT 9,P4,35] ;LINE NUMBER WITHIN THE PAGE
	ADDI	T3,(T1)		;VIRTUAL ADDRESS OF WORD CONTAINING THE ERROR
	MOVES	T3,(T3)		;READ, RE-WRITE THE WORD, CORRECTING THE ERROR
	PUSHJ	P,UNMAP##	;RETURN EXEC MAP SLOT
	POP	P,T1		;LENGTH,,ADDRESS OF THE ERROR BLOCK
	PUSHJ	P,SNDTGH	;SEND THE ERROR BLOCK TO TGHA
	  JFCL			;IGNORE FAILURE
	JRST	SBERR2		;PROCESS NEXT ERROR
SBERR6:	PUSHJ	P,CLRSBD##	;CLEAR ALL CONTROLLERS
	POPJ	P,		;AND RETURN

;INTERFACE ROUTINE TO SEND AN IPFC MESSAGE TO THGA
;CALLING SEQUENCE:
;	MOVE	T1,[LENGTH,,ADDRESS OF MESSAGE]
;	PUSHJ	P,SNDTGH
;ALWAYS RETURNS HERE

SNDTGH:	SE1ENT			;ENTER SECTION 1
	PUSH	P,T1		;SNDMDX WANTS THE ARGUMENT ON THE STACK
	MOVEI	T1,%SITGH##	;TGHA'S PID
	PJRST	SNDMDX##	;SEND IT
;HERE TO SETUP TO GIVE THGA CONTROL TO FIDDLE WITH THE MF/G20

DIAGTM::CAIL	P1,4		;MUST BE AT LEAST 4 ARGUMENTS
	CAILE	P1,6		;6 IS ALLOWED FOR THE MG20

	JRST	WRONGN##	;WRONG NUMBER OF ARGUMENTS
	PUSHJ	P,GETWD1##	;FIRST USER PAGE
	MOVE	P2,T1		;SAVE THAT
	PUSHJ	P,GETWD1##	;FIRST PHYSICAL PAGE
	HRL	P2,T1		;AND THAT
	PUSHJ	P,GETWD1##	;NUMBER OF PAGES
	JUMPL	T1,DIABAL##	;NEGATIVE NUMBER OF PAGES IS ILLEGAL
	MOVE	P3,T1		;SAVE COUNT
	HLRZ	T2,P2		;FIRST PHYSICAL PAGE
	ADD	T1,T2		;NUMBER OF PAGES
	LSH	T1,P2WLSH##	;CONVERT TO HIGHEST PHYSICAL ADDRESS
	CAMLE	T1,MEMSIZ##	;MUST BE IN BOUNDS
	JRST	DIABAL##	;NOT, ILLEGAL ARGUMENT LIST
	HRRZ	T1,P2		;FIRST USER PAGE
	HRRZ	T2,P2		;AGAIN
	ADDI	T1,-1(P3)	;HIGHEST USER PAGE
	SE1ENT			;FOR PAGE MAP ACCESS
	CAIGE	P1,6		;TGHA VERSION 4 OR LATER?
	JRST	DIAGT0		;NO, DO IT THE OLD WAY
	CAIL	T1,MXSECN*PAGSIZ##+PG.BDY ;HIGHEST PAGE NUMBER MUST BE IN A LEGAL SECTION
	JRST	DIABAL##	;NOT, ILLEGAL ARGUMENT LIST
	TRZ	T1,PG.BDY##	;HIGHEST PAGE NUMBER ROUNDED DOWN TO A SECTION BOUNDARY
	TRZ	T2,PG.BDY##	;ROUND DOWN
	CAIN	T1,(T2)		;ALL REQUESTED PAGES MUST BE IN THE SAME SECTION
	CAIGE	P2,2000		; AND MUST BE IN A SECTION GREATER THAN 2
	JRST	DIABAL##	;NOT, BAD ARGUMENT LIST
	HRRI	M,2(M)		;POINT AT SIXTH ARGUMENT
	PUSHJ	P,GETWDU##	;GET USER SUPPLIED SCRATCH PAGES ARGUMENT
	
	HLRZ	T3,T1		;GET NUMBER OF PAGES PROVIDED
	CAIGE	T3,3		;MUST BE AT LEAST 3, UPT, MAP, NZS MAP
	JRST	WRONGN##	;WRONG NUMBER
	HRRZS	P4,T1		;FIRST USER SCRATCH PAGE NUMBER
DIAGTA:	PUSHJ	P,GTPME##	;GET CONTENTS OF USER'S MAP
	TLNE	T2,(<PM.ACD>B2)	;MUST EXIST, ACCESS ALLOWED,
	TLNN	T2,(PM.WRT)	; AND BE WRITABLE
	JRST	DIABAL##	;BAD ARGUMENT LIST FOR LACK OF A BETTER RETURN
	AOS	T1		;NEXT PAGE
	SOJG	T3,DIAGTA	;LOOP OVER ALL PAGES SUPPLIED
	LSH	P4,P2WLSH##	;CONVERT TO USER VIRTUAL ADDRESS
	MOVSI	T1,.UPMAP	;COPY THE MAP AND UPT TO USER SCRATCH PAGES
	HRRI	T1,(P4)
	EXCTXU	<BLT T1,2*PAGSIZ##-1(P4)>
	HRRZ	T1,P2		;FIRST USER PAGE
	ANDI	T1,PG.BDY##	;PAGE NUMBER WITHIN SECTION
	ADDI	T1,2*PAGSIZ##(P4) ;STARTING ADDRESS IN SUBSTITUTION SECTION MAP
	HLRZ	T2,P2		;FIRST PHYSICAL PAGE
	HRLI	T2,(<PM.DCD>B2+PM.WRT+PM.PUB) ;PAGE POINTER
	MOVE	T3,P3		;NUMBER OF PAGES
DIAGTB:	EXCTUX	<MOVEM T2,(T1)>	;STORE POINTER IN SCRATCH SECTION MAP
	AOS	T1		;NEXT PAGE IN SECTION
	AOS	T2		;NEXT PHYSICAL PAGE
	SOJG	T3,DIAGTB	;LOOP FOR ALL PAGES
	EXCTUX	<MAP T1,(P4)>	;PHYSICAL ADDRESS OF WHAT WILL BE THE SECTION 0 MAP
	TLZ	T1,777760	;CLEAR EXTRANEOUS BITS
	LSH	T1,W2PLSH##	;CONVERT TO PAGE NUMBER
	HRLI	T1,(<PM.DCD>B2+PM.PUB+PM.WRT)
	EXCTXU	<MOVEM T1,PAGSIZ##+SECTAB+0(P4)> ;SECTION 0 MAP POINTER
	MOVSI	T1,SECTAB+0(<PM.ICD>B2+PM.WRT+PM.PUB)
	EXCTXU	<MOVEM T1,PAGSIZ##+SECTAB+1(P4)> ;SECTION 1 IS @ SECTION 0
	EXCTUX	<MAP T1,2*PAGSIZ##(P4)> ;PHYSICAL ADDRESS OF WHAT WILL BE
				; SUBSTITUTION SECTION MAP
	TLZ	T1,777760	;CLEAR EXTRANEOUS BITS
	LSH	T1,W2PLSH##	;CONVERT TO PAGE NUMBER
	HRLI	T1,(<PM.DCD>B2+PM.WRT+PM.PUB)
	MOVE	T2,P2		;SECTION NUMBER TO MAP
	LSH	T2,W2PLSH##
	ADD	T2,P4
	EXCTXU	<MOVEM T1,PAGSIZ##+SECTAB(T2)> ;MAP POINTER FOR SUBSTITUTION SECTION
	EXCTUX	<MAP T1,PAGSIZ##(P4)> ;PHYSICAL PAGE NUMBER OF WHAT WILL BE UPT
	TLZ	T1,777760	;CLEAR EXTRANEOUS BITS
	LSH	T1,W2PLSH##	;CONVERT TO PAGE NUMBER
	EXCTUX	<HRRM T1,PAGSIZ##+.UMUPT(P4)> ;MAP UPMP PER PROCESS IN THIS UPT
	EXCTUX	<HRRM T1,PAGSIZ##+.UMUUP(P4)> ;DITTO FOR CACHED
	HRLI	T1,(LG.LUB)	;SET TO LOAD THE USER BASE REGISTER
	HRRZ	P2,JBTUPM##(J)	;GET CURRENT UPT
	CONO	PI,PI.OFF	;NO PIS
	HRRM	T1,@.CPSPT##	;SETUP THE SPT
	HRRM	T1,JBTUPM##(J)	;AND JBTUPM
	DATAO	PAG,T1		;AND IF WE DIDN'T MISS ANY IMPORTANT POINTERS,
				; EVERYTHING IS NOW ADDRESSABLE THROUGH THE SCRACH MAPS
	CONO	PI,PI.ON	;PIS ARE NOW OK
	HRRI	M,-2(M)		;POINT M BACK AT 4TH ARGUMNET
	MOVE	P3,P4		;VIRTUAL ADDRESS OF SCRATCH MAPS
	TLO	P3,400000	;TO DISTINGUISH IT FROM NUMBER OF PAGES
	JRST	DIAGTC		;JOIN COMMON CODE FOR OLD TGHA
DIAGT0:
	CAIG	T1,HLGPNO	;WITHIN THE USER'S ADDRESS SPACE
	PUSHJ	P,CKNZP##	;AND ARE ALL THE PAGES SPANNED NOT ALLOCATED?
	  JRST	DIABAL##	;NO, ILLEGAL ARGUMENT LIST
	SOS	T1,T2		;SET FOR IDPB
	PUSHJ	P,GTPME##	;CCOMPUTE A BYTE POINTER TO THE USER'S MAP
	HLRZ	T1,P2		;FIRST PHYSICAL PAGE TO BE MAPPED
	HRLI	T1,(<PM.DCD>B2+PM.PUB+PM.WRT)

	MOVE	T2,P3		;NUMBER OF PAGES TO MAP INTO THE USER'S ADDRESS SPACE
DIAGT1:	MOVEM	T1,(T4)		;MAKE THE PAGE ADDRESSABLE TO THE USER
	AOS	T4		;ADVANCE POINTER
	AOS	T1		;NEXT PAGE
	SOJG	T2,DIAGT1	;LOOP UNTIL ALL PAGES HAVE BEEN MAPPED
	CLRPGT	(0)		;MAKE SURE THE HARDWARE SEES THE CHANGE
DIAGTC:	CAIG	P1,4		;A FIFTH ARGUMENT SUPPLIED?
	TDZA	T1,T1		;NO, REMEMBER
	PUSHJ	P,GETWD1##	;YES, GET THE FIFTH ARGUMENT
	MOVE	P1,T1		;SAVE AR/ARX PARITY ERROR NEW PC
	MOVEI	T2,2		;TWO WORDS OF FREE SPACE
	PUSHJ	P,GETWDS##	;GET IT
	  JRST	DINEFC##	;ERROR, NOT ENOUGH FREE CORE
	MOVEM	T1,.PDDIA##(W)	;SAVE THE ADDRESS OF THE FREE CORE
	DMOVEM	P2,(T1)		;STORE USER PAGE,,PHYSICAL PAGE, NUMBER OF PAGES
	MOVSI	T2,(XC.USR+XC.PUB+XC.UIO) ;TRAP IN USER MODE ON PARITY ERROR
	HRR	T2,P1		;USER TRAP ADDRESS
	SKIPLE	P1		;SKIP IF NONE SUPPLIED OR USE EXEC SPECIFIED
	MOVEM	T2,.USPFN	;STORE PAGE FAIL NEW PC
	MOVEI	T1,[MOVEM J,.CPSTS##-.CPCDB##(P1) ;ROUTINE TO BE EXECUTED
		    POPJ P,]	; OVER ALL CPU'S
	PUSHJ	P,CPUAPP##	;RUN ONLY ME ON ALL CPU'S
;HERE TO CLEAR ALL DTES ON ALL CPUS (REMEMBER STATE?)
	MOVEI	T1,DTESTP	;ROUTINE TO STOP DTES
	PUSHJ	P,CPUAPP##	;APPLY THAT ACROSS ALL CPUS
	MOVE	J,.CPJOB##	;RESTORE THE CURRENT JOB NUMBER
IFN FTMP,<
	PUSHJ	P,ONCPU0##	;MAKE SURE THE REST OF THIS OCCURS ON THE BOOT CPU
	SETOM	MOFLPG##	;CAUSE ALL OTHER CPUS TO STOP
>; END IFN FTMP
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,10		;10 SECONDS
DIAGT2:	PUSHJ	P,SLEEP##	;WAIT FOR ALL RH20S TO STOP
IFN FTMP,<
	MOVEI	T1,0		;1 TIC
	PUSHJ	P,CP1STP##	;WAIT FOR ALL CPUS TO STOP
	  JRST	DIAGT2		;SOME ARE STILL RUNNING, SLEEP A TIC
>
	PUSHJ	P,ACCMOF##	;TURN OFF THE METERS
	CONO	TIM,0		;AND THE INTERVAL TIMER
	CONO	PI,PI.OFF	;STOP THE WORLD
	PUSHJ	P,DTESPP##	;ENTER PROTOCOL PAUSE
	CONSO	PAG,LG.CSL+LG.CSW ;CACHE ON?
	JRST	DIAGT3		;NO, SKIP ON
	MOVEI	T1,LG.CSW	;STRATEGY LOAD
	ANDCAB	T1,.CPEBR##	;CLEAR THAT
	CONO	PAG,@.CPEBR##	;TURN OFF CACHE STRATEGY LOAD
	PUSHJ	P,CSDMP##	;CLEAR THE CACHE
	TRZ	T1,LG.CSL	;CACHE STRATEGY LOOK, CLEAR THAT
	MOVEM	T1,.CPEBR##	;CLEAR LOOK AND LOAD
	CONO	PAG,@.CPEBR##	;LET THE HARDWARE KNOW
DIAGT3:	MOVEI	T1,^D50000	;A FEW MILLISECONDS
	SOJG	T1,.		;JUST TO MAKE SURE ALL ACTIVITY HAS DIED OUT
	JRST	CPOPJ1##	;RETURN TO THE DIAGNOSTIC

;SUBROUTINE TO SHUTDOWN ALL DTES ON A CPU, CALL WITH P1 POINTING AT
; THE CPU UPON WHICH THE DTES ARE TO BE SHUTDOWN
DTESTP:	MOVE	T1,.CPCPN##-.CPCDB##(P1) ;CPU NUMBER
IFN FTMP,<
	PUSHJ	P,ONCPUS##	;GET TO THAT CPU
	  POPJ	P,		;FORGET IT IF THE CPU ISN'T RUNNING
>
	PUSH	P,.CPDTN##	;NUMBER OF DTES ON THIS CPU
DTEST1:	HLRZ	F,.CPSLF##	;ADDRESS OF THE CDB
	HRR	F,(P)		;DTE NUMBER
	PUSHJ	P,GETETD##	;GET THE ADDRESS OF THE DTE CONTROL BLOCK
	  JRST	DTEST2		;NON-EXISTANT DTE, SKIP ON
	PUSHJ	P,DTECLR##	;SHUTDOWN THIS DTE
DTEST2:	SOSL	(P)		;ANYMORE DTES?
	JRST	DTEST1		;YES, GO SHUT THEM DOWN TOO
	JRST	TPOPJ##		;RETURN
;HERE WHEN THGA RELENQUISHES CONTROL AFTER FIDDLING WITH THE MF/G20

DIAGVM::PUSHJ	P,CSDMP##	;SWEEP CACHE
	MOVEI	T1,LG.CSL+LG.CSW;CACHE STRATEGY LOOK AND LOAD
	IORM	T1,.CPEBR##	;TURN THAT ON
	CONO	PAG,@.CPEBR##	;REENABLE THE CACHE
	PUSHJ	P,DTERPP##	;CLEAR PROTOCOL PAUSE
	CONO	PI,PI.ON	;RESTORE THE PI SYSTEM
	CONO	TIM,TO.CTD!TO.CIT!TO.SIT!^D1667 ;TURN THE INTERVAL TIMER BACK ON
	PUSHJ	P,ACCMON##	;AND START UP THE METERS
IFN FTMP,<
	SETZM	MOFLPG##	;WAKEUP THE OTHER CPUS
	MOVEI	T1,2		;GIVE OTHER CPU'S A CHANCE TO COME BACK TO LIFE
	PUSHJ	P,SLEEP##	;SO CAN CALL CPUAPP AND GET THINGS STARTED AGAIN EVERWHERE
>
;HERE TO RESTART DTE'S (BASED ON SAVED STATUS?)
	MOVEI	T1,DTESTR	;ROUTINE TO RESTART DTES
	PUSHJ	P,CPUAPP##	;APPLY THAT OVER ALL CPUS
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
	MOVE	J,.CPJOB##
	PUSHJ	P,FNDPDS##	;FETCH THE PDB POINTER
IFN FTMP,<
	PUSHJ	P,CRESET##	;RESET CPU SPECIFICATION
>
	MOVE	T1,[XC.UIO+SEILM##] ;NORMAL PAGE FAIL NEW PC
	MOVEM	T1,.USPFN	;RESTORE THAT
	MOVE	T1,.PDDIA##(W)	;ADDRESS OF ARGUMENT SAVE BLOCK
	MOVE	T3,1(T1)	;NUMBER OF PAGES MAPPED
	JUMPG	T3,DIAGVA	;JUMP IF OLD VERSION OF TGHA
;	PUSHJ	P,STEUB##	;RESTORE MAPS (CAN'T DO A PUSHJ)
	HRRZ	T1,(T1)		;T1 = THE PAGE NUMBER OF THE USER PROCESS TABLE
	CONO	PI,PI.OFF	;NO INTERRUPTS WHILE CHANGING UBR/SPT
	HRRM	T1,@.CPSPT##	;SETUP NEW SPT
	HRRM	T1,JBTUPM##(J)	;AND JBTUPM
	HRLI	T1,(LG.LUB)	;REQUEST LOADING UBR
	DATAO	PAG,T1		;SETUP THE UBR AND CLEAR PAGING MEMORY
	CONO	PI,PI.ON	;INTERRUPTS ARE OK NOW
	MOVSI	T1,PAGSIZ##(T3)	;WHERE THE PDL IS
	HRRI	T1,JOBPDO	;WHERE IT SHOULD BE
	EXCTUX	<BLT T1,JOBPDO+PDLLEN-1> ;PUT IT BACK
	JRST	DIAGVB		;JOIN COMMON CODE
DIAGVA:	SE1ENT
	HRRZ	T1,(T1)		;FIRST USER PAGE
	SUBI	T1,1		;SET FOR IDPB
	PUSHJ	P,GTPME##	;FORM A BYTE POINTER TO THE MAP
DIAGV1:	AOS	T4		;INCRMENT
	SETZM	(T4)		;ZAP
	SOJG	T3,DIAGV1	;LOOP OVER ALL MAPPED PAGES
DIAGVB:	MOVE	T2,.PDDIA##(W)	;ADDRESS OF ARGUMENT SAVE BLOCK
	SETZM	.PDDIA##(W)	;ZERO DIAG WORD
	MOVEI	T1,2		;2 WORDS TO RETURN
	PUSHJ	P,GIVWDS##	;RETURN THE FUNNY SPACE
	MOVEI	T1,[SETZM .CPSTS##-.CPCDB##(P1) ;ROUTINE TO APPLY
		    POPJ P,]	; ACROSS ALL CPUS
	PUSHJ	P,CPUAPP##	;ALLOW JOBS TO RUN AGAIN ON OTHER CPUS
	JRST	CPOPJ1##	;AND GIVE GOOD RETURN TO THE DIAGNOSTIC
;SUBROUTINE TO START ALL DTES ON A CPU, CALL WITH (P1) = CPU CDB
DTESTR:	MOVE	T1,.CPCPN##-.CPCDB##(P1) ;CPU NUMBER
IFN FTMP,<
	PUSHJ	P,ONCPUS##	;GET ON THAT CPU
	  POPJ	P,		;NOTHING TO DO IF THE CPU ISN'T RUNNING
>
	PUSHJ	P,ENTSPC##	;ENTER SECONDARY PROTOCOL ON THE MASTER DTE
	PUSHJ	P,STAPPC##	;START PRIMARY PROTOCOL ON ALL DTES
	POPJ	P,		;RETURN

MOSEND:	END