1 /*	$OpenBSD: vm86.h,v 1.8 2002/03/14 01:26:33 millert Exp $	*/
2 /*	$NetBSD: vm86.h,v 1.8 1996/05/03 19:26:32 christos Exp $	*/
3 
4 #undef	VM86_USE_VIF
5 
6 /*-
7  * Copyright (c) 1996 The NetBSD Foundation, Inc.
8  * All rights reserved.
9  *
10  * This code is derived from software contributed to The NetBSD Foundation
11  * by John T. Kohl and Charles M. Hannum.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. All advertising materials mentioning features or use of this software
22  *    must display the following acknowledgement:
23  *        This product includes software developed by the NetBSD
24  *        Foundation, Inc. and its contributors.
25  * 4. Neither the name of The NetBSD Foundation nor the names of its
26  *    contributors may be used to endorse or promote products derived
27  *    from this software without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
30  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
31  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
32  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
33  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39  * POSSIBILITY OF SUCH DAMAGE.
40  */
41 
42 #define SETFLAGS(targ, new, newmask) (targ) = ((targ) & ~(newmask)) | ((new) & (newmask))
43 
44 #define VM86_TYPE(x)	((x) & 0xff)
45 #define VM86_ARG(x)	(((x) & 0xff00) >> 8)
46 #define	VM86_MAKEVAL(type,arg) ((type) | (((arg) & 0xff) << 8))
47 #define		VM86_STI	0
48 #define		VM86_INTx	1
49 #define		VM86_SIGNAL	2
50 #define		VM86_UNKNOWN	3
51 
52 #define	VM86_REALFLAGS	(~PSL_USERSTATIC)
53 #define	VM86_VIRTFLAGS	(PSL_USERSTATIC & ~(PSL_MBO | PSL_MBZ))
54 
55 struct vm86_regs {
56 	struct sigcontext vmsc;
57 };
58 
59 struct vm86_kern {			/* kernel uses this stuff */
60 	struct vm86_regs regs;
61 	unsigned long ss_cpu_type;
62 };
63 #define cpu_type substr.ss_cpu_type
64 
65 /*
66  * Kernel keeps copy of user-mode address of this, but doesn't copy it in.
67  */
68 struct vm86_struct {
69 	struct vm86_kern substr;
70 	unsigned long screen_bitmap;	/* not used/supported (yet) */
71 	unsigned long flags;		/* not used/supported (yet) */
72 	unsigned char int_byuser[32];	/* 256 bits each: pass control to user */
73 	unsigned char int21_byuser[32];	/* otherwise, handle directly */
74 };
75 
76 #define VCPU_086		0
77 #define VCPU_186		1
78 #define VCPU_286		2
79 #define VCPU_386		3
80 #define VCPU_486		4
81 #define VCPU_586		5
82 
83 #ifdef _KERNEL
84 int i386_vm86(struct proc *, char *, register_t *);
85 void vm86_gpfault(struct proc *, int);
86 void vm86_return(struct proc *, int);
87 static __inline void clr_vif(struct proc *);
88 static __inline void set_vif(struct proc *);
89 static __inline void set_vflags(struct proc *, int);
90 static __inline int get_vflags(struct proc *);
91 static __inline void set_vflags_short(struct proc *, int);
92 static __inline int get_vflags_short(struct proc *);
93 
94 static __inline void
clr_vif(p)95 clr_vif(p)
96 	struct proc *p;
97 {
98 	struct pcb *pcb = &p->p_addr->u_pcb;
99 
100 #ifndef VM86_USE_VIF
101 	pcb->vm86_eflags &= ~PSL_I;
102 #else
103 	pcb->vm86_eflags &= ~PSL_VIF;
104 #endif
105 }
106 
107 static __inline void
set_vif(p)108 set_vif(p)
109 	struct proc *p;
110 {
111 	struct pcb *pcb = &p->p_addr->u_pcb;
112 
113 #ifndef VM86_USE_VIF
114 	pcb->vm86_eflags |= PSL_I;
115 	if ((pcb->vm86_eflags & (PSL_I|PSL_VIP)) == (PSL_I|PSL_VIP))
116 #else
117 	pcb->vm86_eflags |= PSL_VIF;
118 	if ((pcb->vm86_eflags & (PSL_VIF|PSL_VIP)) == (PSL_VIF|PSL_VIP))
119 #endif
120 		vm86_return(p, VM86_STI);
121 }
122 
123 static __inline void
set_vflags(p,flags)124 set_vflags(p, flags)
125 	struct proc *p;
126 	int flags;
127 {
128 	struct trapframe *tf = p->p_md.md_regs;
129 	struct pcb *pcb = &p->p_addr->u_pcb;
130 
131 	flags &= ~pcb->vm86_flagmask;
132 	SETFLAGS(pcb->vm86_eflags, flags, VM86_VIRTFLAGS);
133 	SETFLAGS(tf->tf_eflags, flags, VM86_REALFLAGS);
134 #ifndef VM86_USE_VIF
135 	if ((pcb->vm86_eflags & (PSL_I|PSL_VIP)) == (PSL_I|PSL_VIP))
136 #else
137 	if ((pcb->vm86_eflags & (PSL_VIF|PSL_VIP)) == (PSL_VIF|PSL_VIP))
138 #endif
139 		vm86_return(p, VM86_STI);
140 }
141 
142 static __inline int
get_vflags(p)143 get_vflags(p)
144 	struct proc *p;
145 {
146 	struct trapframe *tf = p->p_md.md_regs;
147 	struct pcb *pcb = &p->p_addr->u_pcb;
148 	int flags = PSL_MBO;
149 
150 	SETFLAGS(flags, pcb->vm86_eflags, VM86_VIRTFLAGS);
151 	SETFLAGS(flags, tf->tf_eflags, VM86_REALFLAGS);
152 	return (flags);
153 }
154 
155 static __inline void
set_vflags_short(p,flags)156 set_vflags_short(p, flags)
157 	struct proc *p;
158 	int flags;
159 {
160 	struct trapframe *tf = p->p_md.md_regs;
161 	struct pcb *pcb = &p->p_addr->u_pcb;
162 
163 	flags &= ~pcb->vm86_flagmask;
164 	SETFLAGS(pcb->vm86_eflags, flags, VM86_VIRTFLAGS & 0xffff);
165 	SETFLAGS(tf->tf_eflags, flags, VM86_REALFLAGS & 0xffff);
166 #ifndef VM86_USE_VIF
167 	if ((pcb->vm86_eflags & (PSL_I|PSL_VIP)) == (PSL_I|PSL_VIP))
168 		vm86_return(p, VM86_STI);
169 #endif
170 }
171 
172 static __inline int
get_vflags_short(p)173 get_vflags_short(p)
174 	struct proc *p;
175 {
176 	struct trapframe *tf = p->p_md.md_regs;
177 	struct pcb *pcb = &p->p_addr->u_pcb;
178 	int flags = PSL_MBO;
179 
180 	SETFLAGS(flags, pcb->vm86_eflags, VM86_VIRTFLAGS & 0xffff);
181 	SETFLAGS(flags, tf->tf_eflags, VM86_REALFLAGS & 0xffff);
182 	return (flags);
183 }
184 #else
185 int i386_vm86(struct vm86_struct *vmcp);
186 #endif
187