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 41core_farcall: 42 mov eax,[esp+1*4] ; CS:IP 43 jmp core_syscall 44 45 global core_intcall:function hidden 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 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 151core_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 222CallbackSP resd 1 ; SP saved during callback 223CallbackCtr resd 1 224 225 bits 16 226 section .text16 227