root/core/callback.inc

Revision 8659757a388ad9071156f2e3d6b04813960dcfed, 4.6 KB (checked in by H. Peter Anvin <hpa@…>, 2 years ago)

core: Make cfarcall IF-preserving

cfarcall does not take a register image on input, so we need to
explicitly preserve IF in the code flow.

Signed-off-by: H. Peter Anvin <hpa@…>

  • Property mode set to 100644
Line 
1;; -----------------------------------------------------------------------
2;;
3;;   Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
4;;   Copyright 2009 Intel Corporation; author: H. Peter Anvin
5;;
6;;   This program is free software; you can redistribute it and/or modify
7;;   it under the terms of the GNU General Public License as published by
8;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
9;;   Boston MA 02111-1307, USA; either version 2 of the License, or
10;;   (at your option) any later version; incorporated herein by reference.
11;;
12;; -----------------------------------------------------------------------
13
14;;
15;; callback.inc
16;;
17;; Callbacks from 32-bit mode to 16-bit mode
18;;
19
20;
21; 16-bit intcall/farcall handling code
22;
23
24;
25; 32-bit support code
26;
27                bits 32
28                section .text
29
30;
31; Intcall/farcall invocation.  We manifest a structure on the real-mode stack,
32; containing the com32sys_t structure from <com32.h> as well as
33; the following entries (from low to high address):
34; - Target offset
35; - Target segment
36; - Return offset
37; - Return segment (== real mode cs == 0)
38; - Return flags
39;
40                global core_farcall
41core_farcall:
42                mov eax,[esp+1*4]               ; CS:IP
43                jmp core_syscall
44
45                global core_intcall
46core_intcall:
47                movzx eax,byte [esp+1*4]        ; INT number
48                mov eax,[eax*4]                 ; Get CS:IP from low memory
49
50core_syscall:
51                pushfd                          ; Save IF among other things...
52                push ebx
53                push ebp
54                push esi
55                push edi
56                push dword [CallbackSP]
57
58                cld
59
60                movzx edi,word [word RealModeSSSP]
61                movzx ebx,word [word RealModeSSSP+2]
62                sub edi,54              ; Allocate 54 bytes
63                mov [word RealModeSSSP],di
64                shl ebx,4
65                add edi,ebx             ; Create linear address
66
67                mov esi,[esp+8*4]       ; Source regs
68                xor ecx,ecx
69                mov cl,11               ; 44 bytes to copy
70                rep movsd
71
72                ; EAX is already set up to be CS:IP
73                stosd                   ; Save in stack frame
74                mov eax,.rm_return      ; Return seg:offs
75                stosd                   ; Save in stack frame
76                mov eax,[edi-12]        ; Return flags
77                and eax,0x200ed7        ; Mask (potentially) unsafe flags
78                mov [edi-12],eax        ; Primary flags entry
79                stosw                   ; Return flags
80
81                mov bx,.rm
82                jmp enter_rm    ; Go to real mode
83
84                bits 16
85                section .text16
86.rm:
87                mov ax,sp
88                add ax,9*4+4*2
89                mov [CallbackSP],ax
90                pop gs
91                pop fs
92                pop es
93                pop ds
94                popad
95                popfd
96                retf                            ; Invoke routine
97
98.rm_return:
99                ; We clean up SP here because we don't know if the
100                ; routine returned with RET, RETF or IRET
101                mov sp,[cs:CallbackSP]
102                pushfd
103                pushad
104                push ds
105                push es
106                push fs
107                push gs
108                mov ebx,.pm_return
109                jmp enter_pm
110
111                ; On return, the 44-byte return structure is on the
112                ; real-mode stack, plus the 10 additional bytes used
113                ; by the target address (see above.)
114                bits 32
115                section .text
116.pm_return:
117                movzx esi,word [word RealModeSSSP]
118                movzx eax,word [word RealModeSSSP+2]
119                mov edi,[esp+9*4]       ; Dest regs
120                shl eax,4
121                add esi,eax             ; Create linear address
122                and edi,edi             ; NULL pointer?
123                jnz .do_copy
124.no_copy:       mov edi,esi             ; Do a dummy copy-to-self
125.do_copy:       xor ecx,ecx
126                mov cl,11               ; 44 bytes
127                rep movsd               ; Copy register block
128
129                add dword [word RealModeSSSP],54
130                                        ; Remove from stack
131
132                pop dword [CallbackSP]
133                pop edi
134                pop esi
135                pop ebp
136                pop ebx
137                popfd
138                ret                     ; Return to 32-bit program
139
140;
141; Cfarcall invocation.  We copy the stack frame to the real-mode stack,
142; followed by the return CS:IP and the CS:IP of the target function.
143; The value of IF is copied from the calling routine.
144;
145                global core_cfarcall
146core_cfarcall:
147                pushfd                          ; Save IF among other things...
148                push ebx
149                push ebp
150                push esi
151                push edi
152                push dword [CallbackSP]
153
154                cld
155                mov ecx,[esp+9*4]               ; Size of stack frame
156
157                movzx edi,word [word RealModeSSSP]
158                movzx ebx,word [word RealModeSSSP+2]
159                mov [word CallbackSP],di
160                sub edi,ecx             ; Allocate space for stack frame
161                and edi,~3              ; Round
162                sub edi,4*3             ; Return pointer, return value, EFLAGS
163                mov [word RealModeSSSP],di
164                shl ebx,4
165                add edi,ebx             ; Create linear address
166
167                mov eax,[esp+5*4]       ; EFLAGS from entry
168                and eax,0x202           ; IF only
169                stosd
170                mov eax,[esp+7*4]       ; CS:IP
171                stosd                   ; Save to stack frame
172                mov eax,.rm_return      ; Return seg:off
173                stosd
174                mov esi,[esp+8*4]       ; Stack frame
175                mov eax,ecx             ; Copy the stack frame
176                shr ecx,2
177                rep movsd
178                mov ecx,eax
179                and ecx,3
180                rep movsb
181
182                mov bx,.rm
183                jmp enter_rm
184
185                bits 16
186                section .text16
187.rm:
188                popfd
189                retf
190.rm_return:
191                mov sp,[cs:CallbackSP]
192                mov esi,eax
193                mov ebx,.pm_return
194                jmp enter_pm
195
196                bits 32
197                section .text
198.pm_return:
199                mov eax,esi
200                ; EDX already set up to be the RM return value
201                pop dword [CallbackSP]
202                pop ebx
203                pop ebp
204                pop esi
205                pop edi
206                popfd
207                ret
208
209                bits 16
210                section .bss16
211                alignb 4
212CallbackSP      resd 1                  ; SP saved during callback
213
214                bits 16
215                section .text16
Note: See TracBrowser for help on using the browser.