176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;; -----------------------------------------------------------------------
276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;;
376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;;   Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;;   Copyright 2009 Intel Corporation; author: H. Peter Anvin
576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;;
676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;;   This program is free software; you can redistribute it and/or modify
776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;;   it under the terms of the GNU General Public License as published by
876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;;   Boston MA 02111-1307, USA; either version 2 of the License, or
1076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;;   (at your option) any later version; incorporated herein by reference.
1176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;;
1276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;; -----------------------------------------------------------------------
1376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
1476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;;
1576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;; callback.inc
1676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;;
1776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;; Callbacks from 32-bit mode to 16-bit mode
1876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;;
1976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;
2176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman; 16-bit intcall/farcall handling code
2276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;
2376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
2476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;
2576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman; 32-bit support code
2676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;
2776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		bits 32
2876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		section .text
2976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
3076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;
3176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman; Intcall/farcall invocation.  We manifest a structure on the real-mode stack,
3276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman; containing the com32sys_t structure from <com32.h> as well as
3376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman; the following entries (from low to high address):
3476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman; - Target offset
3576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman; - Target segment
3676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman; - Return offset
3776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman; - Return segment (== real mode cs == 0)
3876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman; - Return flags
3976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;
4076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		global core_farcall:function hidden
4176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmancore_farcall:
4276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov eax,[esp+1*4]		; CS:IP
4376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		jmp core_syscall
4476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
4576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		global core_intcall:function hidden
4676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmancore_intcall:
4776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		movzx eax,byte [esp+1*4]	; INT number
4876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov eax,[eax*4]			; Get CS:IP from low memory
4976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmancore_syscall:
5176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pushfd				; Save IF among other things...
5276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		inc dword [CallbackCtr]
5376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		push ebx
5476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		push ebp
5576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		push esi
5676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		push edi
5776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		push dword [CallbackSP]
5876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
5976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		cld
6076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		movzx edi,word [word RealModeSSSP]
6276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		movzx ebx,word [word RealModeSSSP+2]
6376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		sub edi,54		; Allocate 54 bytes
6476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov [word RealModeSSSP],di
6576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		shl ebx,4
6676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		add edi,ebx		; Create linear address
6776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
6876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov esi,[esp+8*4]	; Source regs
6976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		xor ecx,ecx
7076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov cl,11		; 44 bytes to copy
7176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		rep movsd
7276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
7376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		; EAX is already set up to be CS:IP
7476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		stosd			; Save in stack frame
7576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov eax,.rm_return	; Return seg:offs
7676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		stosd			; Save in stack frame
7776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov eax,[edi-12]	; Return flags
7876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		and eax,0x200ed7	; Mask (potentially) unsafe flags
7976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov [edi-12],eax	; Primary flags entry
8076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		stosw			; Return flags
8176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov bx,.rm
8376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		jmp enter_rm	; Go to real mode
8476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
8576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		bits 16
8676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		section .text16
8776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman.rm:
8876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov ax,sp
8976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		add ax,9*4+4*2
9076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov [CallbackSP],ax
9176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pop gs
9276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pop fs
9376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pop es
9476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pop ds
9576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		popad
9676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		popfd
9776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		retf				; Invoke routine
9876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
9976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman.rm_return:
10076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		; We clean up SP here because we don't know if the
10176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		; routine returned with RET, RETF or IRET
10276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov sp,[cs:CallbackSP]
10376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pushfd
10476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pushad
10576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		push ds
10676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		push es
10776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		push fs
10876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		push gs
10976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov ebx,.pm_return
11076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		jmp enter_pm
11176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
11276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		; On return, the 44-byte return structure is on the
11376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		; real-mode stack, plus the 10 additional bytes used
11476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		; by the target address (see above.)
11576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		bits 32
11676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		section .text
11776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman.pm_return:
11876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		movzx esi,word [word RealModeSSSP]
11976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		movzx eax,word [word RealModeSSSP+2]
12076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov edi,[esp+9*4]	; Dest regs
12176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		shl eax,4
12276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		add esi,eax		; Create linear address
12376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		and edi,edi		; NULL pointer?
12476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		jnz .do_copy
12576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman.no_copy:	mov edi,esi		; Do a dummy copy-to-self
12676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman.do_copy:	xor ecx,ecx
12776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov cl,11		; 44 bytes
12876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		rep movsd		; Copy register block
12976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		add dword [word RealModeSSSP],54
13176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman					; Remove from stack
13276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
13376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pop dword [CallbackSP]
13476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		dec dword [CallbackCtr]
13576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		jnz .skip
13676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		call [core_pm_hook]
13776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman.skip:
13876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pop edi
13976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pop esi
14076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pop ebp
14176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pop ebx
14276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		popfd
14376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ret			; Return to 32-bit program
14476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
14576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;
14676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman; Cfarcall invocation.  We copy the stack frame to the real-mode stack,
14776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman; followed by the return CS:IP and the CS:IP of the target function.
14876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman; The value of IF is copied from the calling routine.
14976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman;
15076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		global core_cfarcall:function hidden
15176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartmancore_cfarcall:
15276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pushfd				; Save IF among other things...
15376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		inc dword [CallbackCtr]
15476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		push ebx
15576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		push ebp
15676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		push esi
15776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		push edi
15876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		push dword [CallbackSP]
15976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
16076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		cld
16176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov ecx,[esp+9*4]		; Size of stack frame
16276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
16376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		movzx edi,word [word RealModeSSSP]
16476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		movzx ebx,word [word RealModeSSSP+2]
16576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov [word CallbackSP],di
16676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		sub edi,ecx		; Allocate space for stack frame
16776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		and edi,~3		; Round
16876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		sub edi,4*3		; Return pointer, return value, EFLAGS
16976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov [word RealModeSSSP],di
17076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		shl ebx,4
17176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		add edi,ebx		; Create linear address
17276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
17376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov eax,[esp+5*4]	; EFLAGS from entry
17476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		and eax,0x202		; IF only
17576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		stosd
17676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov eax,[esp+7*4]	; CS:IP
17776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		stosd			; Save to stack frame
17876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov eax,.rm_return	; Return seg:off
17976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		stosd
18076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov esi,[esp+8*4]	; Stack frame
18176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov eax,ecx		; Copy the stack frame
18276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		shr ecx,2
18376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		rep movsd
18476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov ecx,eax
18576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		and ecx,3
18676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		rep movsb
18776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
18876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov bx,.rm
18976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		jmp enter_rm
19076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
19176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		bits 16
19276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		section .text16
19376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman.rm:
19476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		popfd
19576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		retf
19676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman.rm_return:
19776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov sp,[cs:CallbackSP]
19876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov esi,eax
19976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov ebx,.pm_return
20076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		jmp enter_pm
20176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
20276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		bits 32
20376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		section .text
20476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman.pm_return:
20576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		mov eax,esi
20676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		; EDX already set up to be the RM return value
20776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pop dword [CallbackSP]
20876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		dec dword [CallbackCtr]
20976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		jnz .skip
21076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		call [core_pm_hook]
21176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman.skip:
21276d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pop ebx
21376d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pop ebp
21476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pop esi
21576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		pop edi
21676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		popfd
21776d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		ret
21876d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
21976d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		section .bss16
22076d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		alignb 4
22176d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		global core_pm_hook
22276d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanCallbackSP	resd 1			; SP saved during callback
22376d05dc695b06c4e987bb8078f78032441e1430cGreg HartmanCallbackCtr	resd 1
22476d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman
22576d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		bits 16
22676d05dc695b06c4e987bb8078f78032441e1430cGreg Hartman		section .text16
227