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