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:function hidden 41 core_farcall: 42 mov eax,[esp+1*4] ; CS:IP 43 jmp core_syscall 44 45 global core_intcall:function hidden 46 core_intcall: 47 movzx eax,byte [esp+1*4] ; INT number 48 mov eax,[eax*4] ; Get CS:IP from low memory 49 50 core_syscall: 51 pushfd ; Save IF among other things... 52 inc dword [CallbackCtr] 53 push ebx 54 push ebp 55 push esi 56 push edi 57 push dword [CallbackSP] 58 59 cld 60 61 movzx edi,word [word RealModeSSSP] 62 movzx ebx,word [word RealModeSSSP+2] 63 sub edi,54 ; Allocate 54 bytes 64 mov [word RealModeSSSP],di 65 shl ebx,4 66 add edi,ebx ; Create linear address 67 68 mov esi,[esp+8*4] ; Source regs 69 xor ecx,ecx 70 mov cl,11 ; 44 bytes to copy 71 rep movsd 72 73 ; EAX is already set up to be CS:IP 74 stosd ; Save in stack frame 75 mov eax,.rm_return ; Return seg:offs 76 stosd ; Save in stack frame 77 mov eax,[edi-12] ; Return flags 78 and eax,0x200ed7 ; Mask (potentially) unsafe flags 79 mov [edi-12],eax ; Primary flags entry 80 stosw ; Return flags 81 82 mov bx,.rm 83 jmp enter_rm ; Go to real mode 84 85 bits 16 86 section .text16 87 .rm: 88 mov ax,sp 89 add ax,9*4+4*2 90 mov [CallbackSP],ax 91 pop gs 92 pop fs 93 pop es 94 pop ds 95 popad 96 popfd 97 retf ; Invoke routine 98 99 .rm_return: 100 ; We clean up SP here because we don't know if the 101 ; routine returned with RET, RETF or IRET 102 mov sp,[cs:CallbackSP] 103 pushfd 104 pushad 105 push ds 106 push es 107 push fs 108 push gs 109 mov ebx,.pm_return 110 jmp enter_pm 111 112 ; On return, the 44-byte return structure is on the 113 ; real-mode stack, plus the 10 additional bytes used 114 ; by the target address (see above.) 115 bits 32 116 section .text 117 .pm_return: 118 movzx esi,word [word RealModeSSSP] 119 movzx eax,word [word RealModeSSSP+2] 120 mov edi,[esp+9*4] ; Dest regs 121 shl eax,4 122 add esi,eax ; Create linear address 123 and edi,edi ; NULL pointer? 124 jnz .do_copy 125 .no_copy: mov edi,esi ; Do a dummy copy-to-self 126 .do_copy: xor ecx,ecx 127 mov cl,11 ; 44 bytes 128 rep movsd ; Copy register block 129 130 add dword [word RealModeSSSP],54 131 ; Remove from stack 132 133 pop dword [CallbackSP] 134 dec dword [CallbackCtr] 135 jnz .skip 136 call [core_pm_hook] 137 .skip: 138 pop edi 139 pop esi 140 pop ebp 141 pop ebx 142 popfd 143 ret ; Return to 32-bit program 144 145 ; 146 ; Cfarcall invocation. We copy the stack frame to the real-mode stack, 147 ; followed by the return CS:IP and the CS:IP of the target function. 148 ; The value of IF is copied from the calling routine. 149 ; 150 global core_cfarcall:function hidden 151 core_cfarcall: 152 pushfd ; Save IF among other things... 153 inc dword [CallbackCtr] 154 push ebx 155 push ebp 156 push esi 157 push edi 158 push dword [CallbackSP] 159 160 cld 161 mov ecx,[esp+9*4] ; Size of stack frame 162 163 movzx edi,word [word RealModeSSSP] 164 movzx ebx,word [word RealModeSSSP+2] 165 mov [word CallbackSP],di 166 sub edi,ecx ; Allocate space for stack frame 167 and edi,~3 ; Round 168 sub edi,4*3 ; Return pointer, return value, EFLAGS 169 mov [word RealModeSSSP],di 170 shl ebx,4 171 add edi,ebx ; Create linear address 172 173 mov eax,[esp+5*4] ; EFLAGS from entry 174 and eax,0x202 ; IF only 175 stosd 176 mov eax,[esp+7*4] ; CS:IP 177 stosd ; Save to stack frame 178 mov eax,.rm_return ; Return seg:off 179 stosd 180 mov esi,[esp+8*4] ; Stack frame 181 mov eax,ecx ; Copy the stack frame 182 shr ecx,2 183 rep movsd 184 mov ecx,eax 185 and ecx,3 186 rep movsb 187 188 mov bx,.rm 189 jmp enter_rm 190 191 bits 16 192 section .text16 193 .rm: 194 popfd 195 retf 196 .rm_return: 197 mov sp,[cs:CallbackSP] 198 mov esi,eax 199 mov ebx,.pm_return 200 jmp enter_pm 201 202 bits 32 203 section .text 204 .pm_return: 205 mov eax,esi 206 ; EDX already set up to be the RM return value 207 pop dword [CallbackSP] 208 dec dword [CallbackCtr] 209 jnz .skip 210 call [core_pm_hook] 211 .skip: 212 pop ebx 213 pop ebp 214 pop esi 215 pop edi 216 popfd 217 ret 218 219 section .bss16 220 alignb 4 221 global core_pm_hook 222 CallbackSP resd 1 ; SP saved during callback 223 CallbackCtr resd 1 224 225 bits 16 226 section .text16 227