1/* -----------------------------------------------------------------------
2 *
3 *   Copyright 2009 Intel Corporation; author H. Peter Anvin
4 *
5 *   This file is part of the Linux kernel, and is made available under
6 *   the terms of the GNU General Public License version 2 or (at your
7 *   option) any later version; incorporated herein by reference.
8 *
9 * ----------------------------------------------------------------------- */
10
11/*
12 * "Glove box" for BIOS calls.  Avoids the constant problems with BIOSes
13 * touching registers they shouldn't be.
14 */
15
16	.code16gcc
17	.text
18	.globl	intcall
19	.type	intcall, @function
20intcall:
21	/* Self-modify the INT instruction.  Ugly, but works. */
22	cmpb	%al, 3f
23	je	1f
24	movb	%al, 3f
25	jmp	1f		/* Synchronize pipeline */
261:
27	/* Save state */
28	pushfl
29	pushw	%fs
30	pushw	%gs
31	pushal
32
33	/* Copy input state to stack frame */
34	subw	$44, %sp
35	movw	%dx, %si
36	movw	%sp, %di
37	movw	$11, %cx
38	rep; movsd
39
40	/* Pop full state from the stack */
41	popal
42	popw	%gs
43	popw	%fs
44	popw	%es
45	popw	%ds
46	popfl
47
48	/* Actual INT */
49	.byte	0xcd		/* INT opcode */
503:	.byte	0
51
52	/* Push full state to the stack */
53	pushfl
54	pushw	%ds
55	pushw	%es
56	pushw	%fs
57	pushw	%gs
58	pushal
59
60	/* Re-establish C environment invariants */
61	cld
62	movzwl	%sp, %esp
63	movw	%cs, %ax
64	movw	%ax, %ds
65	movw	%ax, %es
66
67	/* Copy output state from stack frame */
68	movw	68(%esp), %di	/* Original %cx == 3rd argument */
69	andw	%di, %di
70	jz	4f
71	movw	%sp, %si
72	movw	$11, %cx
73	rep; movsd
744:	addw	$44, %sp
75
76	/* Restore state and return */
77	popal
78	popw	%gs
79	popw	%fs
80	popfl
81	retl
82	.size	intcall, .-intcall
83