1 ;; -----------------------------------------------------------------------
3 ;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved
4 ;; Copyright 2009 Intel Corporation; author: H. Peter Anvin
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.
12 ;; -----------------------------------------------------------------------
17 ;; Common code for running a COM32 image
21 ; Load a COM32 image. A COM32 image is the 32-bit analogue to a DOS
22 ; .com file. A COM32 image is loaded at address 0x101000, with %esp
23 ; set to the high end of usable memory.
25 ; A COM32 image should begin with the magic bytes:
26 ; B8 FF 4C CD 21, which is "mov eax,0x21cd4cff" in 32-bit mode and
27 ; "mov ax,0x4cff; int 0x21" in 16-bit mode. This will abort the
28 ; program with an error if run in 16-bit mode.
35 push si ; Save file handle
36 push eax ; Save file length
38 call make_plain_cmdline
39 ; Copy the command line into the low cmdline buffer
45 inc cx ; Include final null
49 call comboot_setup_api ; Set up the COMBOOT-style API
51 mov edi,pm_entry ; Load address
54 xor dx,dx ; No padding
55 mov bx,abort_check ; Don't print dots, but allow abort
60 ; Point the stack to the end of (permitted) high memory
63 xor ax,ax ; Align to a 64K boundary
65 mov bx,.pm ; Where to go in PM
69 ; This is invoked right before the actually starting the COM32
70 ; progam, in 32-bit mode...
74 ; Set up the calling stack frame
76 push dword [HighMemSize] ; Memory managed by Syslinux
77 push dword core_cfarcall ; Cfarcall entry point
78 push dword core_farcall ; Farcall entry point
79 push dword (1 << 16) ; 64K bounce buffer
80 push dword (xfer_buf_seg << 4) ; Bounce buffer address
81 push dword core_intcall ; Intcall entry point
82 push dword command_line ; Command line pointer
83 push dword 7 ; Argument count
84 sti ; Interrupts OK now
85 call pm_entry ; Run the program...
86 ; ... on return, fall through to com32_exit ...
94 mov dword [PMESP],__stack_end ; Stop use of COM32 stack
99 ; 16-bit intcall/farcall handling code
110 mov [cs:Com32SysSP],sp
111 retf ; Invoke routine
113 ; We clean up SP here because we don't know if the
114 ; routine returned with RET, RETF or IRET
115 mov sp,[cs:Com32SysSP]
122 mov bx,com32_syscall.resume
126 ; 16-bit cfarcall handing code
131 mov sp,[cs:Com32SysSP]
133 mov bx,core_cfarcall.resume
137 ; 32-bit support code
142 ; Intcall/farcall invocation. We manifest a structure on the real-mode stack,
143 ; containing the com32sys_t structure from <com32.h> as well as
144 ; the following entries (from low to high address):
148 ; - Return segment (== real mode cs == 0)
153 mov eax,[esp+1*4] ; CS:IP
158 movzx eax,byte [esp+1*4] ; INT number
159 mov eax,[eax*4] ; Get CS:IP from low memory
162 pushfd ; Save IF among other things...
167 push dword [Com32SysSP]
171 movzx edi,word [word RealModeSSSP]
172 movzx ebx,word [word RealModeSSSP+2]
173 sub edi,54 ; Allocate 54 bytes
174 mov [word RealModeSSSP],di
176 add edi,ebx ; Create linear address
178 mov esi,[esp+8*4] ; Source regs
180 mov cl,11 ; 44 bytes to copy
183 ; EAX is already set up to be CS:IP
184 stosd ; Save in stack frame
185 mov eax,com32_sys_rm.return ; Return seg:offs
186 stosd ; Save in stack frame
187 mov eax,[edi-12] ; Return flags
188 and eax,0x200cd7 ; Mask (potentially) unsafe flags
189 mov [edi-12],eax ; Primary flags entry
193 jmp enter_rm ; Go to real mode
195 ; On return, the 44-byte return structure is on the
196 ; real-mode stack, plus the 10 additional bytes used
197 ; by the target address (see above.)
199 movzx esi,word [word RealModeSSSP]
200 movzx eax,word [word RealModeSSSP+2]
201 mov edi,[esp+9*4] ; Dest regs
203 add esi,eax ; Create linear address
204 and edi,edi ; NULL pointer?
206 .no_copy: mov edi,esi ; Do a dummy copy-to-self
207 .do_copy: xor ecx,ecx
209 rep movsd ; Copy register block
211 add dword [word RealModeSSSP],54
214 pop dword [Com32SysSP]
220 ret ; Return to 32-bit program
223 ; Cfarcall invocation. We copy the stack frame to the real-mode stack,
224 ; followed by the return CS:IP and the CS:IP of the target function.
228 pushfd ; Save IF among other things...
233 push dword [Com32SysSP]
236 mov ecx,[esp+9*4] ; Size of stack frame
238 movzx edi,word [word RealModeSSSP]
239 movzx ebx,word [word RealModeSSSP+2]
240 mov [word Com32SysSP],di
241 sub edi,ecx ; Allocate space for stack frame
243 sub edi,4*2 ; Return pointer, return value
244 mov [word RealModeSSSP],di
246 add edi,ebx ; Create linear address
248 mov eax,[esp+7*4] ; CS:IP
249 stosd ; Save to stack frame
250 mov eax,com32_cfar_rm.return ; Return seg:off
252 mov esi,[esp+8*4] ; Stack frame
253 mov eax,ecx ; Copy the stack frame
265 ; EDX already set up to be the RM return value
266 pop dword [Com32SysSP]
278 Com32SysSP resd 1 ; SP saved during COM32 syscall