1/* $NetBSD: vm86.h,v 1.18 2009/03/16 09:38:18 cegger 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 47struct 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 */ 56struct 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 72int x86_vm86(struct lwp *, char *, register_t *); 73int compat_16_x86_vm86(struct lwp *, char *, register_t *); 74void vm86_gpfault(struct lwp *, int); 75void vm86_return(struct lwp *, int); 76static __inline void clr_vif(struct lwp *); 77static __inline void set_vif(struct lwp *); 78static __inline void set_vflags(struct lwp *, int); 79static __inline int get_vflags(struct lwp *); 80static __inline void set_vflags_short(struct lwp *, int); 81static __inline int get_vflags_short(struct lwp *); 82 83static __inline void 84clr_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 95static __inline void 96set_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 110static __inline void 111set_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 127static __inline int 128get_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 139static __inline void 140set_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 154static __inline int 155get_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 166int i386_vm86(struct vm86_struct *vmcp); 167#endif 168