Home | History | Annotate | Download | only in asm-x86
      1 #ifndef _LINUX_VM86_H
      2 #define _LINUX_VM86_H
      3 
      4 /*
      5  * I'm guessing at the VIF/VIP flag usage, but hope that this is how
      6  * the Pentium uses them. Linux will return from vm86 mode when both
      7  * VIF and VIP is set.
      8  *
      9  * On a Pentium, we could probably optimize the virtual flags directly
     10  * in the eflags register instead of doing it "by hand" in vflags...
     11  *
     12  * Linus
     13  */
     14 
     15 #define TF_MASK		0x00000100
     16 #define IF_MASK		0x00000200
     17 #define IOPL_MASK	0x00003000
     18 #define NT_MASK		0x00004000
     19 #ifdef CONFIG_VM86
     20 #define VM_MASK		0x00020000
     21 #else
     22 #define VM_MASK		0 /* ignored */
     23 #endif
     24 #define AC_MASK		0x00040000
     25 #define VIF_MASK	0x00080000	/* virtual interrupt flag */
     26 #define VIP_MASK	0x00100000	/* virtual interrupt pending */
     27 #define ID_MASK		0x00200000
     28 
     29 #define BIOSSEG		0x0f000
     30 
     31 #define CPU_086		0
     32 #define CPU_186		1
     33 #define CPU_286		2
     34 #define CPU_386		3
     35 #define CPU_486		4
     36 #define CPU_586		5
     37 
     38 /*
     39  * Return values for the 'vm86()' system call
     40  */
     41 #define VM86_TYPE(retval)	((retval) & 0xff)
     42 #define VM86_ARG(retval)	((retval) >> 8)
     43 
     44 #define VM86_SIGNAL	0	/* return due to signal */
     45 #define VM86_UNKNOWN	1	/* unhandled GP fault - IO-instruction or similar */
     46 #define VM86_INTx	2	/* int3/int x instruction (ARG = x) */
     47 #define VM86_STI	3	/* sti/popf/iret instruction enabled virtual interrupts */
     48 
     49 /*
     50  * Additional return values when invoking new vm86()
     51  */
     52 #define VM86_PICRETURN	4	/* return due to pending PIC request */
     53 #define VM86_TRAP	6	/* return due to DOS-debugger request */
     54 
     55 /*
     56  * function codes when invoking new vm86()
     57  */
     58 #define VM86_PLUS_INSTALL_CHECK	0
     59 #define VM86_ENTER		1
     60 #define VM86_ENTER_NO_BYPASS	2
     61 #define	VM86_REQUEST_IRQ	3
     62 #define VM86_FREE_IRQ		4
     63 #define VM86_GET_IRQ_BITS	5
     64 #define VM86_GET_AND_RESET_IRQ	6
     65 
     66 /*
     67  * This is the stack-layout seen by the user space program when we have
     68  * done a translation of "SAVE_ALL" from vm86 mode. The real kernel layout
     69  * is 'kernel_vm86_regs' (see below).
     70  */
     71 
     72 struct vm86_regs {
     73 /*
     74  * normal regs, with special meaning for the segment descriptors..
     75  */
     76 	long ebx;
     77 	long ecx;
     78 	long edx;
     79 	long esi;
     80 	long edi;
     81 	long ebp;
     82 	long eax;
     83 	long __null_ds;
     84 	long __null_es;
     85 	long __null_fs;
     86 	long __null_gs;
     87 	long orig_eax;
     88 	long eip;
     89 	unsigned short cs, __csh;
     90 	long eflags;
     91 	long esp;
     92 	unsigned short ss, __ssh;
     93 /*
     94  * these are specific to v86 mode:
     95  */
     96 	unsigned short es, __esh;
     97 	unsigned short ds, __dsh;
     98 	unsigned short fs, __fsh;
     99 	unsigned short gs, __gsh;
    100 };
    101 
    102 struct revectored_struct {
    103 	unsigned long __map[8];			/* 256 bits */
    104 };
    105 
    106 struct vm86_struct {
    107 	struct vm86_regs regs;
    108 	unsigned long flags;
    109 	unsigned long screen_bitmap;
    110 	unsigned long cpu_type;
    111 	struct revectored_struct int_revectored;
    112 	struct revectored_struct int21_revectored;
    113 };
    114 
    115 /*
    116  * flags masks
    117  */
    118 #define VM86_SCREEN_BITMAP	0x0001
    119 
    120 struct vm86plus_info_struct {
    121 	unsigned long force_return_for_pic:1;
    122 	unsigned long vm86dbg_active:1;       /* for debugger */
    123 	unsigned long vm86dbg_TFpendig:1;     /* for debugger */
    124 	unsigned long unused:28;
    125 	unsigned long is_vm86pus:1;	      /* for vm86 internal use */
    126 	unsigned char vm86dbg_intxxtab[32];   /* for debugger */
    127 };
    128 
    129 struct vm86plus_struct {
    130 	struct vm86_regs regs;
    131 	unsigned long flags;
    132 	unsigned long screen_bitmap;
    133 	unsigned long cpu_type;
    134 	struct revectored_struct int_revectored;
    135 	struct revectored_struct int21_revectored;
    136 	struct vm86plus_info_struct vm86plus;
    137 };
    138 
    139 #ifdef __KERNEL__
    140 /*
    141  * This is the (kernel) stack-layout when we have done a "SAVE_ALL" from vm86
    142  * mode - the main change is that the old segment descriptors aren't
    143  * useful any more and are forced to be zero by the kernel (and the
    144  * hardware when a trap occurs), and the real segment descriptors are
    145  * at the end of the structure. Look at ptrace.h to see the "normal"
    146  * setup. For user space layout see 'struct vm86_regs' above.
    147  */
    148 #include <asm/ptrace.h>
    149 
    150 struct kernel_vm86_regs {
    151 /*
    152  * normal regs, with special meaning for the segment descriptors..
    153  */
    154 	struct pt_regs pt;
    155 /*
    156  * these are specific to v86 mode:
    157  */
    158 	unsigned short es, __esh;
    159 	unsigned short ds, __dsh;
    160 	unsigned short fs, __fsh;
    161 	unsigned short gs, __gsh;
    162 };
    163 
    164 struct kernel_vm86_struct {
    165 	struct kernel_vm86_regs regs;
    166 /*
    167  * the below part remains on the kernel stack while we are in VM86 mode.
    168  * 'tss.esp0' then contains the address of VM86_TSS_ESP0 below, and when we
    169  * get forced back from VM86, the CPU and "SAVE_ALL" will restore the above
    170  * 'struct kernel_vm86_regs' with the then actual values.
    171  * Therefore, pt_regs in fact points to a complete 'kernel_vm86_struct'
    172  * in kernelspace, hence we need not reget the data from userspace.
    173  */
    174 #define VM86_TSS_ESP0 flags
    175 	unsigned long flags;
    176 	unsigned long screen_bitmap;
    177 	unsigned long cpu_type;
    178 	struct revectored_struct int_revectored;
    179 	struct revectored_struct int21_revectored;
    180 	struct vm86plus_info_struct vm86plus;
    181 	struct pt_regs *regs32;   /* here we save the pointer to the old regs */
    182 /*
    183  * The below is not part of the structure, but the stack layout continues
    184  * this way. In front of 'return-eip' may be some data, depending on
    185  * compilation, so we don't rely on this and save the pointer to 'oldregs'
    186  * in 'regs32' above.
    187  * However, with GCC-2.7.2 and the current CFLAGS you see exactly this:
    188 
    189 	long return-eip;        from call to vm86()
    190 	struct pt_regs oldregs;  user space registers as saved by syscall
    191  */
    192 };
    193 
    194 #ifdef CONFIG_VM86
    195 
    196 void handle_vm86_fault(struct kernel_vm86_regs *, long);
    197 int handle_vm86_trap(struct kernel_vm86_regs *, long, int);
    198 
    199 struct task_struct;
    200 void release_vm86_irqs(struct task_struct *);
    201 
    202 #else
    203 
    204 #define handle_vm86_fault(a, b)
    205 #define release_vm86_irqs(a)
    206 
    207 static inline int handle_vm86_trap(struct kernel_vm86_regs *a, long b, int c) {
    208 	return 0;
    209 }
    210 
    211 #endif /* CONFIG_VM86 */
    212 
    213 #endif /* __KERNEL__ */
    214 
    215 #endif
    216