Merge branch 'for-2.6.31' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[linux-2.6] / arch / x86 / boot / bioscall.S
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
20 intcall:
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 */
26 1:
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 */
50 3:      .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
74 4:      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