summaryrefslogtreecommitdiffstats
path: root/sys/amd64/amd64/trap.c
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1997-08-09 00:04:06 +0000
committerdyson <dyson@FreeBSD.org>1997-08-09 00:04:06 +0000
commitad0649e2b977efaa77b68c699a1f44b12e7429d1 (patch)
tree925573ddb83b4a0cf21a7d136de8f44817243b6c /sys/amd64/amd64/trap.c
parent56b351207af0157d77bdd770e72c7ff038d57164 (diff)
downloadFreeBSD-src-ad0649e2b977efaa77b68c699a1f44b12e7429d1.zip
FreeBSD-src-ad0649e2b977efaa77b68c699a1f44b12e7429d1.tar.gz
VM86 kernel support.
Work done by BSDI, Jonathan Lemon <jlemon@americantv.com>, Mike Smith <msmith@gsoft.com.au>, Sean Eric Fagan <sef@kithrup.com>, and probably alot of others. Submitted by: Jnathan Lemon <jlemon@americantv.com>
Diffstat (limited to 'sys/amd64/amd64/trap.c')
-rw-r--r--sys/amd64/amd64/trap.c25
1 files changed, 20 insertions, 5 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c
index 6e8c0c3..7110933 100644
--- a/sys/amd64/amd64/trap.c
+++ b/sys/amd64/amd64/trap.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)trap.c 7.4 (Berkeley) 5/13/91
- * $Id: trap.c,v 1.100 1997/06/22 16:03:37 peter Exp $
+ * $Id: trap.c,v 1.101 1997/07/20 08:37:23 bde 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));
@@ -192,7 +193,7 @@ trap(frame)
type = frame.tf_trapno;
code = frame.tf_err;
- 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;
@@ -225,9 +226,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:
@@ -694,6 +708,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);
@@ -707,7 +722,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 {
@@ -946,7 +961,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);
OpenPOWER on IntegriCloud