Google
 

Trailing-Edge - PDP-10 Archives - SRI_NIC_PERM_FS_1_19910112 - c/old/lib/signal.c
There are 8 other files named signal.c in the archive. Click here to see a list.
/*	title	sigsys - catch or ignore signals
	subttl	David Eppstein / Stanford University / 13-Aug-84
*/
#include "c-env.h"
#if SYS_T20+SYS_10X
	entry	signal,sigsys,kill;

#asm
	SEARCH	MONSYM

ilev==1		; Basic interrupt level
ilevx==1B5	; Ilev in right place for int vectoring.

; make initialization routine to set up pseudo-interrupt system

iint:	block	1		;space for linkage
	pushj	17,chnini	; Initialize channel table
	xmovei	1,lev1pc	;get pc storage
	movem	1,levtab+ilev-1	;for pc save on one level (the only one we use)
	tlne	1,-1
	 jrst iint2

	; Running extended, must use XSIR%
	movei	1,.fhslf	;on ourself
	movei	2,3		;arg block in acs
	movei	3,3		;three words in arg block
	xmovei	4,levtab	;level table
	xmovei	5,chntab	;and channel table
	xsir%			;set up interrupt system
	jrst iint3

	; Non-extended, use old RIR%
iint2:	movei	1,.fhslf	;on ourself
	move	2,[levtab,,chntab]
	rir%

iint3:	movei	1,.fhslf	;on ourself
	eir%			;enable interrupts
	movsi	1,.ticrf	;channel 0 is hang up
	ati%			;assign terminal interrupt
#if SYS_10X
	movei	1,.fhslf
	move	2,[1B<.ICILI>+1B<.ICEOF>+1B<.ICDAE>]
	aic%			; Always keep these on for 10X
#endif
	skipe	16,iint		;more inits?
	 jrst	1(16)		;yes
	popj	17,		;no

define chnset(x)
<	xmovei 1,x	; Get addr of int handler
	tlne 2,-1
	 tlo 1,(ilevx)	; If extended, we use "general" format
	tlnn 2,-1
	 hrli 1,ilev	; Else use "old" non-extended format
	movem 1,(2)
	addi 2,1
>

	; Initialize channel table.  Needed because we dont know which format
	; we will be using until runtime.
chnini:	xmovei 2,chntab

	chnset(hup)		;0 assigned to terminal hang up
	repeat 5,<chnset(unk)>	;1-5 assignable
	chnset(aov)		;6 .ICAOV arithmetic overflow
	chnset(fov)		;7 .ICFOV floating overflow
	chnset(unk)		;8 reserved for DEC
	chnset(pov)		;9 .ICPOV pushdown overflow
	chnset(eof)		;10 .ICEOF end of file condition
	chnset(dae)		;11 .ICDAE data error file condition
	repeat 3,<chnset(unk)>	;12-14 reserved for DEC
	chnset(ili)		;15 .ICILI illegal instruction
	chnset(ird)		;16 .ICIRD illegal memory read
	chnset(iwr)		;17 .ICIWR illegal memory write
	chnset(unk)		;18 reserved for DEC
	chnset(ift)		;19 .ICIFT inferior process termination
	chnset(mse)		;20 .ICMSE system resources exhausted
	chnset(unk)		;21 reserved for DEC
	chnset(nxp)		;22 .ICNXP nonexistent page reference
	repeat 13,<chnset(unk)>	;23-35 assignable
	popj 17,

	$$DATA
chntab:	block 44		; 36. words for channel table

levtab:	block	3		;three words in level table of return PC locs
lev1pc:	block	2		;the return pc from the interrupt
				; (1 word if single section, 2 if extended)
	$$CODE			;back to pure
; table of signal handlers

sigdfl==0			;default
sigign==1			;ignore
sigcat==2			;held signal caught
sighld==3			;hold signal

sigtbl:	repeat 25,<sigdfl>	;nothing there yet

intchn:	1B0			;SIGHUP, channel 0
	0			;SIGINT?
	0			;SIGQUIT?
	1B<.ICILI>		;SIGILL, illegal instruction
	0			;SIGTRAP?
	0			;SIGIOT?
	0			;SIGEMT?
	1B<.ICFOV>		;SIGFPE, floating point exception
	0			;SIGKILL, simulated with HALTF%/HFORK%
	0			;SIGBUS?
	1B<.ICNXP>		;SIGSEGV, segmentation violation
	0			;SIGSYS?
	0			;SIGPIPE?
	0			;SIGALRM?
	0			;SIGTERM?
	0			;16 unassigned
	0			;SIGSTOP?
	0			;SIGTSTP?
	0			;SIGCONT?
	1B<.ICIFT>		;SIGCHLD, child status has changed
	0			;SIGTTIN?
	0			;SIGTTOU?
	0			;SIGTINT?
	0			;SIGXCPU?
	0			;SIGXFSZ?
; entry routines

signal:
sigsys:	move	5,-1(17)	;get signal
	skipl	6,-2(17)	;and function
	 caile	6,^d25		;in range?
	  jrst	badsig		;no
	jumpe	6,drpsig	;SIG_DFL, deassigning
	exch	6,sigtbl-1(5)	;put new sig, get old
	movei	1,.fhslf	;get self
	move	2,intchn-1(5)	;and interrupt channel
	cain	6,sigcat	;was it an old caught one?
	 iic%			;yes, re-initiate
	cain	6,sigdfl	;not there at all before?
	 aic%			;yes, activate interrupt channel
	move	1,6		;return the old value
	popj	17,

badsig:	seto	1,		;unknown signal, return -1
	popj	17,

drpsig:	move	1,.fhslf	;dropping signal, on self
	move	2,intchn-1(5)	;with signal mask for channel
#if SYS_10X
	ANDCM 2,[1B<.ICILI>+1B<.ICEOF>+1B<.ICDAE>]
#endif
				; Never deactivate these on 10X.
	dic%			;deactivate interrupt channel
	setz	6,		;get nothing
	exch	6,sigtbl-1(5)	;exchange with what was there
	cain	6,sigcat	;caught?
	 iic%			;yes, unhold
	setz	1,		;return SIG_DFL as old value
	popj	17,

kill:	move	1,-1(17)	;get fork
	move	2,-2(17)	;signal
	cain	2,^d9		;SIGKILL?
	 jrst	kill0		;yes
	move	2,intchn-1(2)	;channel mask for it
	iic%			;initiate interrupt condition
	popj	17,		;done

kill0:	caie	1,.fhslf	;on self?
	 jrst	kill1		;no
	haltf%			;yes, just stop self
	popj	17,		;done

kill1:	hfork%			;stop inferior
	popj	17,		;done
; individual interrupt handlers

	$$DATA			;data section
acsave:	block	20		;place to save accumulators
	$$CODE			;code again

define	inthan(s) <
	movem	0,acsave	;;first save register zero
	move	0,[1,,acsave+1]	;;get BLT pointer
	blt	0,acsave+17	;;save rest of registers
	movei	5,^d<s>		;;get signal channel to use
	jrst	runint		;go run interrupt
>

unk:
aov:
pov:
ird:
iwr:
mse:
#if SYS_T20
eof:
dae:
#endif
	debrk%			;unknwn interrupt, merely return from it

hup:	inthan(1)		;SIGHUP
fov:	inthan(8)		;SIGFPE
nxp:	inthan(11)		;SIGSEGV
ift:	inthan(20)		;SIGCHLD
#if SYS_T20
ili: inthan(4)		; SIGILL
#endif

#if SYS_10X
	; On TENEX these can result from a failing JSYS.
eof:
dae:
ili:
	movem	0,acsave	;;first save register zero
	move	0,[1,,acsave+1]	;;get BLT pointer
	blt	0,acsave+17	;;save rest of registers
	jrst	int.il
#endif
#if SYS_10X
; This code lifted from MIDAS --KLH
A=1
B=2
INTPC1==LEV1PC

; Handle Illegal Instruction (normally a failing JSYS, bletch!)
; 10X ERJMP-handling interrupt routine.
;ERJMPA==:<JUMPA 16,>	; For use instead of ERJMP where JSYS normally skips.
;IFNDEF ERJMP,ERJMP==:<JUMP 16,>
;IFNDEF ERCAL,ERCAL==:<JUMP 17,>

ERXJMP==:<ERJMP_-27>	; For easier code writing
ERXCAL==:<ERCAL_-27>
ERXJPA==:<ERJMPA_-27>

INT.IL:	PUSH 17,A
	PUSH 17,B
	MOVE A,INTPC1		; Get PC we got interrupted from
	LDB B,[271500,,(A)]	; Get op-code and AC field of instr
	CAIN B,ERXJPA
	 JRST ERJFAK
	CAIE B,ERXJMP		; Is it a magic cookie?
	 CAIN B,ERXCAL
	  JRST ERJFAK
	AOJ A,
	LDB B,[271500,,(A)]	; Try next instr
	CAIE B,ERXJMP		; Any better luck?
	 CAIN B,ERXCAL
	  JRST ERJFAK
;	ETF [ASCIZ "Fatal interrupt encountered"]
	pop 17,b
	pop 17,a
	movei 5,4		; No ERJMPA/ERJMP/ERCAL so take real interrupt
	jrst runint

ERJFAK:	CAIN B,ERXCAL		; See which action to hack
	 JRST ERJFK2		; Go handle ERCAL, messy.
	MOVEI A,@(A)		; ERJMP, get the jump address desired
	MOVEM A,INTPC1		; Make it the new PC
	POP 17,B
	POP 17,A
	DEBRK%
ERJFK2:	MOVEI B,@(A)		; Get jump address
	MOVEM B,INTPC1		; Make it the new PC
	POP P,B
	AOJ A,			; old PC needs to be bumped for return
	EXCH A,(17)		; Restore old A, and save PC+1 on stack
	DEBRK%

; (Actually, since ERCAL is not special except after a JSYS, it would
; still work if the ERCAL-simulation didnt bump the PC; control would
; just drop through to the next instruction on return.  Might confuse
; people looking through the stack frames, though.)
#endif /* 10X */

; handler routine for interrupt
; call with 5/signal number
; returns with DEBRK% after restoring ACs

runint:	move	6,sigtbl-1(5)	;get handler
	cain	6,sighld	;holding?
	 jrst	hldsig		;yes
	caig	6,sighld	;real routine?
	 jrst	intret		;no
	movei	7,sigdfl	;assume default
	tlze	6,200000	;deferred?
	 movei	7,sighld	;yes
	push	17,[0]		;psl
	xmovei	1,. 	    	;get where we are
	tlnn	1,-1	    	;section zero?
	 push	17,lev1pc	;pc (non-extended)
	tlne	1,-1	    	;otherwise...
	 push	17,lev1pc+1	;pc (extended)
	push	17,[0]		;xx
	push	17,[0]		;param
	push	17,5		;signo
	pushj	17,(6)		;call the routine
	adjsp	17,-3		;drop some stuff
	xmovei	1,.
	tlnn	1,-1
	 pop	17,lev1pc	;fix return pc (non-extended)
	tlne	1,-1
	 pop	17,lev1pc+1	;fix return pc (extended)
	movem	7,0(17)		;new function
	push	17,5		;this signal
	pushj	17,sigsys	;reset it
	adjsp	17,-2		;fix stack
intret:	move	0,[acsave+1,,1]	;restoring reegistrs
	blt	0,17		;do it
	move	0,acsave	;get this reg back too
	debrk%			;return from interrupt

hldsig:	movei	6,sigcat	;caught signal
	movem	6,sigtbl-1(5)	;put in place
	jrst	intret		;return from interrupt

#endasm
#endif /* T20+10X */