aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKATO Takenori <kato@FreeBSD.org>1997-08-09 01:57:04 +0000
committerKATO Takenori <kato@FreeBSD.org>1997-08-09 01:57:04 +0000
commitb47d57b7843cd6df1b4ffafb4b57844091a036e4 (patch)
tree67ea8dd5285f4ace66b4717b4f8d493b6450f520
parentf6601c421b9871c987bc95f9c406405d5ed3ab1d (diff)
Notes
-rw-r--r--sys/pc98/i386/trap.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/sys/pc98/i386/trap.c b/sys/pc98/i386/trap.c
index cb46fd4006ed..c7c69ee8f434 100644
--- a/sys/pc98/i386/trap.c
+++ b/sys/pc98/i386/trap.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91
- * $Id: trap.c,v 1.25 1997/06/23 09:35:38 kato Exp $
+ * $Id: trap.c,v 1.26 1997/07/21 13:04:54 kato Exp $
*/
/*
@@ -85,6 +85,7 @@
extern struct i386tss common_tss;
+int (*vm86_emulate) __P((struct vm86frame *));
int (*pmath_emulate) __P((struct trapframe *));
extern void trap __P((struct trapframe frame));
@@ -212,7 +213,7 @@ trap(frame)
asm("sti");
#endif /* CPU_BUGGY_CYRIX */
- if (ISPL(frame.tf_cs) == SEL_UPL) {
+ if ((ISPL(frame.tf_cs) == SEL_UPL) || (frame.tf_eflags & PSL_VM)) {
/* user trap */
sticks = p->p_sticks;
@@ -245,9 +246,22 @@ trap(frame)
}
goto out;
+ /*
+ * The following two traps can happen in
+ * vm86 mode, and, if so, we want to handle
+ * them specially.
+ */
case T_PROTFLT: /* general protection fault */
- case T_SEGNPFLT: /* segment not present fault */
case T_STKFLT: /* stack fault */
+ if (vm86_emulate && (frame.tf_eflags & PSL_VM)) {
+ i = (*vm86_emulate)((struct vm86frame *)&frame);
+ if (i == 0)
+ goto out;
+ break;
+ }
+ /* FALL THROUGH */
+
+ case T_SEGNPFLT: /* segment not present fault */
case T_TSSFLT: /* invalid TSS fault */
case T_DOUBLEFLT: /* double fault */
default:
@@ -744,6 +758,7 @@ trap_fatal(frame)
if (type <= MAX_TRAP_MSG)
printf("\n\nFatal trap %d: %s while in %s mode\n",
type, trap_msg[type],
+ frame->tf_eflags & PSL_VM ? "vm86" :
ISPL(frame->tf_cs) == SEL_UPL ? "user" : "kernel");
#ifdef SMP
printf("cpuid = %d\n", cpuid);
@@ -757,7 +772,7 @@ trap_fatal(frame)
}
printf("instruction pointer = 0x%x:0x%x\n",
frame->tf_cs & 0xffff, frame->tf_eip);
- if (ISPL(frame->tf_cs) == SEL_UPL) {
+ if ((ISPL(frame->tf_cs) == SEL_UPL) || (frame->tf_eflags & PSL_VM)) {
ss = frame->tf_ss & 0xffff;
esp = frame->tf_esp;
} else {
@@ -996,7 +1011,7 @@ bad:
break;
}
- if (frame.tf_eflags & PSL_T) {
+ if ((frame.tf_eflags & PSL_T) && !(frame.tf_eflags & PSL_VM)) {
/* Traced syscall. */
frame.tf_eflags &= ~PSL_T;
trapsignal(p, SIGTRAP, 0);