xref: /linux/arch/x86/boot/bioscall.S (revision 6fdcba32711044c35c0e1b094cbd8f3f0b4472c9)
1/* SPDX-License-Identifier: GPL-2.0-or-later */
2/* -----------------------------------------------------------------------
3 *
4 *   Copyright 2009-2014 Intel Corporation; author H. Peter Anvin
5 *
6 * ----------------------------------------------------------------------- */
7
8/*
9 * "Glove box" for BIOS calls.  Avoids the constant problems with BIOSes
10 * touching registers they shouldn't be.
11 */
12
13	.code16
14	.section ".inittext","ax"
15	.globl	intcall
16	.type	intcall, @function
17intcall:
18	/* Self-modify the INT instruction.  Ugly, but works. */
19	cmpb	%al, 3f
20	je	1f
21	movb	%al, 3f
22	jmp	1f		/* Synchronize pipeline */
231:
24	/* Save state */
25	pushfl
26	pushw	%fs
27	pushw	%gs
28	pushal
29
30	/* Copy input state to stack frame */
31	subw	$44, %sp
32	movw	%dx, %si
33	movw	%sp, %di
34	movw	$11, %cx
35	rep; movsd
36
37	/* Pop full state from the stack */
38	popal
39	popw	%gs
40	popw	%fs
41	popw	%es
42	popw	%ds
43	popfl
44
45	/* Actual INT */
46	.byte	0xcd		/* INT opcode */
473:	.byte	0
48
49	/* Push full state to the stack */
50	pushfl
51	pushw	%ds
52	pushw	%es
53	pushw	%fs
54	pushw	%gs
55	pushal
56
57	/* Re-establish C environment invariants */
58	cld
59	movzwl	%sp, %esp
60	movw	%cs, %ax
61	movw	%ax, %ds
62	movw	%ax, %es
63
64	/* Copy output state from stack frame */
65	movw	68(%esp), %di	/* Original %cx == 3rd argument */
66	andw	%di, %di
67	jz	4f
68	movw	%sp, %si
69	movw	$11, %cx
70	rep; movsd
714:	addw	$44, %sp
72
73	/* Restore state and return */
74	popal
75	popw	%gs
76	popw	%fs
77	popfl
78	retl
79	.size	intcall, .-intcall
80