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