* Copyright (c) 1982, 1986 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
* @(#)trap.c 7.5 (Berkeley) %G%
#include "../kern/syscalls.c"
#define USER 040 /* user-mode flag added to type */
"Reserved addressing mode",
"Privileged instruction",
"Compatibility mode trap",
int TRAP_TYPES
= (sizeof trap_type
/ sizeof trap_type
[0]);
* Called from the trap handler when a processor trap occurs.
trap(sp
, type
, code
, pc
, psl
)
register int *locr0
= ((int *)&psl
)-PS
;
if (USERMODE(locr0
[PS
])) {
printf("trap type %d, code = %x, pc = %x\n", type
, code
, pc
);
if ((unsigned)type
< TRAP_TYPES
)
case T_PROTFLT
+USER
: /* protection fault */
case T_PRIVINFLT
+USER
: /* privileged instruction fault */
case T_RESADFLT
+USER
: /* reserved addressing fault */
case T_RESOPFLT
+USER
: /* reserved operand fault */
if ((u
.u_procp
->p_flag
& SOWEUPC
) && u
.u_prof
.pr_scale
) {
addupc(pc
, &u
.u_prof
, 1);
u
.u_procp
->p_flag
&= ~SOWEUPC
;
* If the user SP is above the stack segment,
* grow the stack automatically.
if (grow((unsigned)locr0
[SP
]) || grow(code
))
case T_TABLEFLT
: /* allow page table faults in kernel mode */
case T_TABLEFLT
+USER
: /* page table fault */
case T_PAGEFLT
: /* allow page faults in kernel mode */
case T_PAGEFLT
+USER
: /* page fault */
case T_BPTFLT
+USER
: /* bpt instruction fault */
case T_TRCTRAP
+USER
: /* trace trap */
case T_XFCFLT
+USER
: /* xfc instruction fault */
case T_COMPATFLT
+USER
: /* compatibility mode fault */
if (p
->p_cursig
|| ISSIG(p
))
* Since we are u.u_procp, clock will normally just change
* our priority without moving us from one queue to another
* (since the running process is not on a queue.)
* If that happened after we setrq ourselves but before we
* swtch()'ed, we might not be on the queue indicated by
struct timeval
*tv
= &u
.u_ru
.ru_stime
;
ticks
= ((tv
->tv_sec
- syst
.tv_sec
) * 1000 +
(tv
->tv_usec
- syst
.tv_usec
) / 1000) / (tick
/ 1000);
addupc(locr0
[PC
], &u
.u_prof
, ticks
);
* Called from the trap handler when a system call occurs
syscall(sp
, type
, code
, pc
, psl
)
register int *locr0
= ((int *)&psl
)-PS
;
register caddr_t params
; /* known to be r10 below */
register int i
; /* known to be r9 below */
register struct sysent
*callp
;
if (!USERMODE(locr0
[PS
]))
params
= (caddr_t
)locr0
[AP
] + NBPW
;
callp
= &sysent
[0]; /* indir (illegal) */
if (callp
== sysent
) { /* indir */
if ((unsigned)i
>= nsysent
)
if ((i
= callp
->sy_narg
* sizeof (int)) &&
(u
.u_error
= copyin(params
, (caddr_t
)u
.u_arg
, (u_int
)i
)) != 0) {
locr0
[PS
] |= PSL_C
; /* carry bit */
u
.u_r
.r_val2
= locr0
[R1
];
if (setjmp(&u
.u_qsave
)) {
if (u
.u_error
== 0 && u
.u_eosys
!= RESTARTSYS
)
u
.u_eosys
= NORMALRETURN
;
printf("%s", syscallnames
[code
]);
for (i
= 0; i
< callp
->sy_narg
; i
++) {
printf("%s%x", cp
, u
.u_arg
[i
]);
if (u
.u_eosys
== NORMALRETURN
) {
locr0
[PS
] |= PSL_C
; /* carry bit */
locr0
[R0
] = u
.u_r
.r_val1
;
locr0
[R1
] = u
.u_r
.r_val2
;
} else if (u
.u_eosys
== RESTARTSYS
)
/* else if (u.u_eosys == JUSTRETURN) */
if (p
->p_cursig
|| ISSIG(p
))
* Since we are u.u_procp, clock will normally just change
* our priority without moving us from one queue to another
* (since the running process is not on a queue.)
* If that happened after we setrq ourselves but before we
* swtch()'ed, we might not be on the queue indicated by
struct timeval
*tv
= &u
.u_ru
.ru_stime
;
ticks
= ((tv
->tv_sec
- syst
.tv_sec
) * 1000 +
(tv
->tv_usec
- syst
.tv_usec
) / 1000) / (tick
/ 1000);
addupc(locr0
[PC
], &u
.u_prof
, ticks
);