xref: /minix3/sys/arch/i386/include/vm86.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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