#define EBIT 1 /* user error bit in PS: C-bit */
#define UMODE 0170000 /* user-mode bits in PS word */
#define SETD 0170011 /* SETD instruction */
#define SYS 0104400 /* sys (trap) instruction */
#define USER 020 /* user-mode flag added to dev */
* structure of the system entry table (sysent.c)
int count
; /* argument count */
int (*call
)(); /* name of handler */
* Offsets of the user's registers relative to
* the saved r0. See reg.h
R0
, R1
, R2
, R3
, R4
, R5
, R6
, R7
, RPS
* Called from l40.s or l45.s when a processor trap occurs.
* The arguments are the words saved on the system stack
* by the hardware and software during the trap processing.
* Their order is dictated by the hardware and the details
* of C's calling sequence. They are peculiar in that
* this call is not 'by value' and changed user registers
* get copied back on return.
* dev is the kind of trap that occurred.
trap(dev
, sp
, r1
, nps
, r0
, pc
, ps
)
register struct sysent
*callp
;
* Usually a kernel mode bus error.
* The numbers printed are used to
* find the hardware PS/PC as follows.
* (all numbers in octal 18 bits)
* (ka6*0100) + aps - 0140000;
* address_of_saved_ps - 2;
printf("ka6 = %o\n", *ka6
);
printf("aps = %o\n", &ps
);
printf("trap type %o\n", dev
);
case 0+USER
: /* bus error */
* If illegal instructions are not
* being caught and the offending instruction
* is a SETD, the trap is ignored.
* This is because C produces a SETD at
* the beginning of every program which
* will trap on CPUs without 11/45 FPU.
case 1+USER
: /* illegal instruction */
if(fuiword(pc
-2) == SETD
&& u
.u_signal
[SIGINS
] == 0)
case 2+USER
: /* bpt or trace */
case 6+USER
: /* sys call */
callp
= &sysent
[fuiword(pc
-2)&077];
if (callp
== sysent
) { /* indirect */
for(i
=0; i
<callp
->count
; i
++)
u
.u_arg
[i
] = fuword(a
=+ 2);
for(i
=0; i
<callp
->count
; i
++) {
u
.u_arg
[i
] = fuiword(pc
);
* Since the floating exception is an
* imprecise trap, a user generated
* trap may actually come from kernel
* mode. In this case, a signal is sent
* to the current process to be picked
case 8: /* floating exception */
psignal(u
.u_procp
, SIGFPT
);
* If the user SP is below the stack segment,
* grow the stack automatically.
* This relies on the ability of the hardware
* to restart a half executed instruction.
* On the 11/40 this is not the case and
* the routine backup/l40.s may fail.
* The classic example is on the instruction
case 9+USER
: /* segmentation exception */
* Call the system-entry routine f (out of the
* sysent table). This is a subroutine for trap, and
* not in-line, because if a signal occurs
* during processing, an (abnormal) return is simulated from
* the last caller to savu(qsav); if this took place
* inside of trap, it wouldn't have a chance to clean up.
* If this occurs, the return takes place without
* clearing u_intflg; if it's still set, trap
* marks an error which means that a system
* call (like read on a typewriter) got interrupted
* nonexistent system call-- set fatal error code.