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 |
17 | intcall: |
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 */ |
23 | 1: |
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; movsl |
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 */ |
47 | 3: .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; movsl |
71 | 4: 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 | |