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