18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _ASM_X86_VM86_H
38c2ecf20Sopenharmony_ci#define _ASM_X86_VM86_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <asm/ptrace.h>
68c2ecf20Sopenharmony_ci#include <uapi/asm/vm86.h>
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci/*
98c2ecf20Sopenharmony_ci * This is the (kernel) stack-layout when we have done a "SAVE_ALL" from vm86
108c2ecf20Sopenharmony_ci * mode - the main change is that the old segment descriptors aren't
118c2ecf20Sopenharmony_ci * useful any more and are forced to be zero by the kernel (and the
128c2ecf20Sopenharmony_ci * hardware when a trap occurs), and the real segment descriptors are
138c2ecf20Sopenharmony_ci * at the end of the structure. Look at ptrace.h to see the "normal"
148c2ecf20Sopenharmony_ci * setup. For user space layout see 'struct vm86_regs' above.
158c2ecf20Sopenharmony_ci */
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_cistruct kernel_vm86_regs {
188c2ecf20Sopenharmony_ci/*
198c2ecf20Sopenharmony_ci * normal regs, with special meaning for the segment descriptors..
208c2ecf20Sopenharmony_ci */
218c2ecf20Sopenharmony_ci	struct pt_regs pt;
228c2ecf20Sopenharmony_ci/*
238c2ecf20Sopenharmony_ci * these are specific to v86 mode:
248c2ecf20Sopenharmony_ci */
258c2ecf20Sopenharmony_ci	unsigned short es, __esh;
268c2ecf20Sopenharmony_ci	unsigned short ds, __dsh;
278c2ecf20Sopenharmony_ci	unsigned short fs, __fsh;
288c2ecf20Sopenharmony_ci	unsigned short gs, __gsh;
298c2ecf20Sopenharmony_ci};
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistruct vm86 {
328c2ecf20Sopenharmony_ci	struct vm86plus_struct __user *user_vm86;
338c2ecf20Sopenharmony_ci	struct pt_regs regs32;
348c2ecf20Sopenharmony_ci	unsigned long veflags;
358c2ecf20Sopenharmony_ci	unsigned long veflags_mask;
368c2ecf20Sopenharmony_ci	unsigned long saved_sp0;
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci	unsigned long flags;
398c2ecf20Sopenharmony_ci	unsigned long screen_bitmap;
408c2ecf20Sopenharmony_ci	unsigned long cpu_type;
418c2ecf20Sopenharmony_ci	struct revectored_struct int_revectored;
428c2ecf20Sopenharmony_ci	struct revectored_struct int21_revectored;
438c2ecf20Sopenharmony_ci	struct vm86plus_info_struct vm86plus;
448c2ecf20Sopenharmony_ci};
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci#ifdef CONFIG_VM86
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_civoid handle_vm86_fault(struct kernel_vm86_regs *, long);
498c2ecf20Sopenharmony_ciint handle_vm86_trap(struct kernel_vm86_regs *, long, int);
508c2ecf20Sopenharmony_civoid save_v86_state(struct kernel_vm86_regs *, int);
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_cistruct task_struct;
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci#define free_vm86(t) do {				\
558c2ecf20Sopenharmony_ci	struct thread_struct *__t = (t);		\
568c2ecf20Sopenharmony_ci	if (__t->vm86 != NULL) {			\
578c2ecf20Sopenharmony_ci		kfree(__t->vm86);			\
588c2ecf20Sopenharmony_ci		__t->vm86 = NULL;			\
598c2ecf20Sopenharmony_ci	}						\
608c2ecf20Sopenharmony_ci} while (0)
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci/*
638c2ecf20Sopenharmony_ci * Support for VM86 programs to request interrupts for
648c2ecf20Sopenharmony_ci * real mode hardware drivers:
658c2ecf20Sopenharmony_ci */
668c2ecf20Sopenharmony_ci#define FIRST_VM86_IRQ		 3
678c2ecf20Sopenharmony_ci#define LAST_VM86_IRQ		15
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_cistatic inline int invalid_vm86_irq(int irq)
708c2ecf20Sopenharmony_ci{
718c2ecf20Sopenharmony_ci	return irq < FIRST_VM86_IRQ || irq > LAST_VM86_IRQ;
728c2ecf20Sopenharmony_ci}
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_civoid release_vm86_irqs(struct task_struct *);
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci#else
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci#define handle_vm86_fault(a, b)
798c2ecf20Sopenharmony_ci#define release_vm86_irqs(a)
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_cistatic inline int handle_vm86_trap(struct kernel_vm86_regs *a, long b, int c)
828c2ecf20Sopenharmony_ci{
838c2ecf20Sopenharmony_ci	return 0;
848c2ecf20Sopenharmony_ci}
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_cistatic inline void save_v86_state(struct kernel_vm86_regs *a, int b) { }
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_ci#define free_vm86(t) do { } while(0)
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci#endif /* CONFIG_VM86 */
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ci#endif /* _ASM_X86_VM86_H */
93