Project

General

Profile

Statistics
| Revision:

root / lab4 / .minix-src / include / i386 / vm86.h @ 14

History | View | Annotate | Download (5.04 KB)

1
/*        $NetBSD: vm86.h,v 1.19 2009/11/21 03:11:01 rmind Exp $        */
2

    
3
#undef        VM86_USE_VIF
4

    
5
/*-
6
 * Copyright (c) 1996 The NetBSD Foundation, Inc.
7
 * All rights reserved.
8
 *
9
 * This code is derived from software contributed to The NetBSD Foundation
10
 * by John T. Kohl and Charles M. Hannum.
11
 *
12
 * Redistribution and use in source and binary forms, with or without
13
 * modification, are permitted provided that the following conditions
14
 * are met:
15
 * 1. Redistributions of source code must retain the above copyright
16
 *    notice, this list of conditions and the following disclaimer.
17
 * 2. Redistributions in binary form must reproduce the above copyright
18
 *    notice, this list of conditions and the following disclaimer in the
19
 *    documentation and/or other materials provided with the distribution.
20
 *
21
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31
 * POSSIBILITY OF SUCH DAMAGE.
32
 */
33

    
34
#define SETFLAGS(targ, new, newmask) (targ) = ((targ) & ~(newmask)) | ((new) & (newmask))
35

    
36
#define VM86_TYPE(x)        ((x) & 0xff)
37
#define VM86_ARG(x)        (((x) & 0xff00) >> 8)
38
#define        VM86_MAKEVAL(type,arg) ((type) | (((arg) & 0xff) << 8))
39
#define                VM86_STI        0
40
#define                VM86_INTx        1
41
#define                VM86_SIGNAL        2
42
#define                VM86_UNKNOWN        3
43

    
44
#define        VM86_REALFLAGS        (~PSL_USERSTATIC)
45
#define        VM86_VIRTFLAGS        (PSL_USERSTATIC & ~(PSL_MBO | PSL_MBZ))
46

    
47
struct vm86_kern {                        /* kernel uses this stuff */
48
        __gregset_t regs;
49
        unsigned long ss_cpu_type;
50
};
51
#define cpu_type substr.ss_cpu_type
52

    
53
/*
54
 * Kernel keeps copy of user-mode address of this, but doesn't copy it in.
55
 */
56
struct vm86_struct {
57
        struct vm86_kern substr;
58
        unsigned long screen_bitmap;        /* not used/supported (yet) */
59
        unsigned long flags;                /* not used/supported (yet) */
60
        unsigned char int_byuser[32];        /* 256 bits each: pass control to user */
61
        unsigned char int21_byuser[32];        /* otherwise, handle directly */
62
};
63

    
64
#define VCPU_086                0
65
#define VCPU_186                1
66
#define VCPU_286                2
67
#define VCPU_386                3
68
#define VCPU_486                4
69
#define VCPU_586                5
70

    
71
#ifdef _KERNEL
72
int x86_vm86(struct lwp *, char *, register_t *);
73
int compat_16_x86_vm86(struct lwp *, char *, register_t *);
74
void vm86_gpfault(struct lwp *, int);
75
void vm86_return(struct lwp *, int);
76
static __inline void clr_vif(struct lwp *);
77
static __inline void set_vif(struct lwp *);
78
static __inline void set_vflags(struct lwp *, int);
79
static __inline int get_vflags(struct lwp *);
80
static __inline void set_vflags_short(struct lwp *, int);
81
static __inline int get_vflags_short(struct lwp *);
82

    
83
static __inline void
84
clr_vif(struct lwp *l)
85
{
86
        struct pcb *pcb = lwp_getpcb(l);
87

    
88
#ifndef VM86_USE_VIF
89
        pcb->vm86_eflags &= ~PSL_I;
90
#else
91
        pcb->vm86_eflags &= ~PSL_VIF;
92
#endif
93
}
94

    
95
static __inline void
96
set_vif(struct lwp *l)
97
{
98
        struct pcb *pcb = lwp_getpcb(l);
99

    
100
#ifndef VM86_USE_VIF
101
        pcb->vm86_eflags |= PSL_I;
102
        if ((pcb->vm86_eflags & (PSL_I|PSL_VIP)) == (PSL_I|PSL_VIP))
103
#else
104
        pcb->vm86_eflags |= PSL_VIF;
105
        if ((pcb->vm86_eflags & (PSL_VIF|PSL_VIP)) == (PSL_VIF|PSL_VIP))
106
#endif
107
                vm86_return(l, VM86_STI);
108
}
109

    
110
static __inline void
111
set_vflags(struct lwp *l, int flags)
112
{
113
        struct trapframe *tf = l->l_md.md_regs;
114
        struct pcb *pcb = lwp_getpcb(l);
115

    
116
        flags &= ~pcb->vm86_flagmask;
117
        SETFLAGS(pcb->vm86_eflags, flags, VM86_VIRTFLAGS);
118
        SETFLAGS(tf->tf_eflags, flags, VM86_REALFLAGS);
119
#ifndef VM86_USE_VIF
120
        if ((pcb->vm86_eflags & (PSL_I|PSL_VIP)) == (PSL_I|PSL_VIP))
121
#else
122
        if ((pcb->vm86_eflags & (PSL_VIF|PSL_VIP)) == (PSL_VIF|PSL_VIP))
123
#endif
124
                vm86_return(l, VM86_STI);
125
}
126

    
127
static __inline int
128
get_vflags(struct lwp *l)
129
{
130
        struct trapframe *tf = l->l_md.md_regs;
131
        struct pcb *pcb = lwp_getpcb(l);
132
        int flags = PSL_MBO;
133

    
134
        SETFLAGS(flags, pcb->vm86_eflags, VM86_VIRTFLAGS);
135
        SETFLAGS(flags, tf->tf_eflags, VM86_REALFLAGS);
136
        return (flags);
137
}
138

    
139
static __inline void
140
set_vflags_short(struct lwp *l, int flags)
141
{
142
        struct trapframe *tf = l->l_md.md_regs;
143
        struct pcb *pcb = lwp_getpcb(l);
144

    
145
        flags &= ~pcb->vm86_flagmask;
146
        SETFLAGS(pcb->vm86_eflags, flags, VM86_VIRTFLAGS & 0xffff);
147
        SETFLAGS(tf->tf_eflags, flags, VM86_REALFLAGS & 0xffff);
148
#ifndef VM86_USE_VIF
149
        if ((pcb->vm86_eflags & (PSL_I|PSL_VIP)) == (PSL_I|PSL_VIP))
150
                vm86_return(l, VM86_STI);
151
#endif
152
}
153

    
154
static __inline int
155
get_vflags_short(struct lwp *l)
156
{
157
        struct trapframe *tf = l->l_md.md_regs;
158
        struct pcb *pcb = lwp_getpcb(l);
159
        int flags = PSL_MBO;
160

    
161
        SETFLAGS(flags, pcb->vm86_eflags, VM86_VIRTFLAGS & 0xffff);
162
        SETFLAGS(flags, tf->tf_eflags, VM86_REALFLAGS & 0xffff);
163
        return (flags);
164
}
165
#else
166
int i386_vm86(struct vm86_struct *vmcp);
167
#endif