xref: /rk3399_rockchip-uboot/drivers/bios_emulator/biosemu.c (revision 409ecdc0bb47dd28b0af6c25ffd658d22cc36b37)
1ece92f85SJason Jin /****************************************************************************
2ece92f85SJason Jin *
3ece92f85SJason Jin *			 BIOS emulator and interface
4ece92f85SJason Jin *		       to Realmode X86 Emulator Library
5ece92f85SJason Jin *
6ece92f85SJason Jin *  Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved.
7ece92f85SJason Jin *  Jason Jin <Jason.jin@freescale.com>
8ece92f85SJason Jin *
9ece92f85SJason Jin *		Copyright (C) 1996-1999 SciTech Software, Inc.
10ece92f85SJason Jin *
11ece92f85SJason Jin *  ========================================================================
12ece92f85SJason Jin *
13ece92f85SJason Jin *  Permission to use, copy, modify, distribute, and sell this software and
14ece92f85SJason Jin *  its documentation for any purpose is hereby granted without fee,
15ece92f85SJason Jin *  provided that the above copyright notice appear in all copies and that
16ece92f85SJason Jin *  both that copyright notice and this permission notice appear in
17ece92f85SJason Jin *  supporting documentation, and that the name of the authors not be used
18ece92f85SJason Jin *  in advertising or publicity pertaining to distribution of the software
19ece92f85SJason Jin *  without specific, written prior permission.	The authors makes no
20ece92f85SJason Jin *  representations about the suitability of this software for any purpose.
21ece92f85SJason Jin *  It is provided "as is" without express or implied warranty.
22ece92f85SJason Jin *
23ece92f85SJason Jin *  THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
24ece92f85SJason Jin *  INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
25ece92f85SJason Jin *  EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
26ece92f85SJason Jin *  CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
27ece92f85SJason Jin *  USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
28ece92f85SJason Jin *  OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
29ece92f85SJason Jin *  PERFORMANCE OF THIS SOFTWARE.
30ece92f85SJason Jin *
31ece92f85SJason Jin *  ========================================================================
32ece92f85SJason Jin *
33ece92f85SJason Jin * Language:	ANSI C
34ece92f85SJason Jin * Environment:	Any
35ece92f85SJason Jin * Developer:	Kendall Bennett
36ece92f85SJason Jin *
37ece92f85SJason Jin * Description:	Module implementing the system specific functions. This
38ece92f85SJason Jin *		module is always compiled and linked in the OS depedent
39ece92f85SJason Jin *		libraries, and never in a binary portable driver.
40ece92f85SJason Jin *
41ece92f85SJason Jin *		Jason ported this file to u-boot to run the ATI video card BIOS
42ece92f85SJason Jin *		in u-boot. Made all the video memory be emulated during the
43ece92f85SJason Jin *		BIOS runing process which may affect the VGA function but the
44ece92f85SJason Jin *		frambuffer function can work after run the BIOS.
45ece92f85SJason Jin *
46ece92f85SJason Jin ****************************************************************************/
47ece92f85SJason Jin 
48ece92f85SJason Jin #include <malloc.h>
4978cff50eSMichal Simek #include <common.h>
50ece92f85SJason Jin 
51ce981dc8SJason Jin #if defined(CONFIG_BIOSEMU)
52ce981dc8SJason Jin 
535b4de930SMichal Simek #include "biosemui.h"
545b4de930SMichal Simek 
55ece92f85SJason Jin BE_sysEnv _BE_env = {{0}};
56ece92f85SJason Jin static X86EMU_memFuncs _BE_mem __attribute__((section(".got2"))) = {
57ece92f85SJason Jin 	BE_rdb,
58ece92f85SJason Jin 	BE_rdw,
59ece92f85SJason Jin 	BE_rdl,
60ece92f85SJason Jin 	BE_wrb,
61ece92f85SJason Jin 	BE_wrw,
62ece92f85SJason Jin 	BE_wrl,
63ece92f85SJason Jin 	};
64ece92f85SJason Jin 
65ece92f85SJason Jin static X86EMU_pioFuncs _BE_pio __attribute__((section(".got2"))) = {
66ece92f85SJason Jin 	BE_inb,
67ece92f85SJason Jin 	BE_inw,
68ece92f85SJason Jin 	BE_inl,
69ece92f85SJason Jin 	BE_outb,
70ece92f85SJason Jin 	BE_outw,
71ece92f85SJason Jin 	BE_outl,
72ece92f85SJason Jin 	};
73ece92f85SJason Jin 
74ece92f85SJason Jin #define OFF(addr)	(u16)(((addr) >> 0) & 0xffff)
75ece92f85SJason Jin #define SEG(addr)	(u16)(((addr) >> 4) & 0xf000)
76ece92f85SJason Jin 
77ece92f85SJason Jin /****************************************************************************
78ece92f85SJason Jin PARAMETERS:
79ece92f85SJason Jin debugFlags  - Flags to enable debugging options (debug builds only)
80ece92f85SJason Jin memSize	    - Amount of memory to allocate for real mode machine
81ece92f85SJason Jin info	    - Pointer to default VGA device information
82ece92f85SJason Jin 
83ece92f85SJason Jin REMARKS:
84ece92f85SJason Jin This functions initialises the BElib, and uses the passed in
85ece92f85SJason Jin BIOS image as the BIOS that is used and emulated at 0xC0000.
86ece92f85SJason Jin ****************************************************************************/
87ece92f85SJason Jin int X86API BE_init(u32 debugFlags, int memSize, BE_VGAInfo * info, int shared)
88ece92f85SJason Jin {
89ece92f85SJason Jin #if !defined(__DRIVER__)  && !defined(__KERNEL__)
90ece92f85SJason Jin 
91ece92f85SJason Jin 	PM_init();
92ece92f85SJason Jin #endif
93ece92f85SJason Jin 	memset(&M, 0, sizeof(M));
94ece92f85SJason Jin 	if (memSize < 20480){
95ece92f85SJason Jin 		printf("Emulator requires at least 20Kb of memory!\n");
96ece92f85SJason Jin 		return 0;
97ece92f85SJason Jin 	}
98ece92f85SJason Jin 
99*409ecdc0SWolfgang Denk 	M.mem_base = malloc(memSize);
100ece92f85SJason Jin 
101ece92f85SJason Jin 	if (M.mem_base == NULL){
102ece92f85SJason Jin 		printf("Biosemu:Out of memory!");
103ece92f85SJason Jin 		return 0;
104ece92f85SJason Jin 	}
105ece92f85SJason Jin 	M.mem_size = memSize;
106ece92f85SJason Jin 
107ece92f85SJason Jin 	_BE_env.emulateVGA = 0;
108ece92f85SJason Jin 	_BE_env.busmem_base = (unsigned long)malloc(128 * 1024);
109*409ecdc0SWolfgang Denk 	if ((void *)_BE_env.busmem_base == NULL){
110ece92f85SJason Jin 		printf("Biosemu:Out of memory!");
111ece92f85SJason Jin 		return 0;
112ece92f85SJason Jin 	}
113ece92f85SJason Jin 	M.x86.debug = debugFlags;
114ece92f85SJason Jin 	_BE_bios_init((u32*)info->LowMem);
115ece92f85SJason Jin 	X86EMU_setupMemFuncs(&_BE_mem);
116ece92f85SJason Jin 	X86EMU_setupPioFuncs(&_BE_pio);
117ece92f85SJason Jin 	BE_setVGA(info);
118ece92f85SJason Jin 	return 1;
119ece92f85SJason Jin }
120ece92f85SJason Jin 
121ece92f85SJason Jin /****************************************************************************
122ece92f85SJason Jin PARAMETERS:
123ece92f85SJason Jin info	    - Pointer to VGA device information to make current
124ece92f85SJason Jin 
125ece92f85SJason Jin REMARKS:
126ece92f85SJason Jin This function sets the VGA BIOS functions in the emulator to point to the
127ece92f85SJason Jin specific VGA BIOS in use. This includes swapping the BIOS interrupt
128ece92f85SJason Jin vectors, BIOS image and BIOS data area to the new BIOS. This allows the
129ece92f85SJason Jin real mode BIOS to be swapped without resetting the entire emulator.
130ece92f85SJason Jin ****************************************************************************/
131ece92f85SJason Jin void X86API BE_setVGA(BE_VGAInfo * info)
132ece92f85SJason Jin {
133ece92f85SJason Jin 
134ece92f85SJason Jin #ifdef __KERNEL__
135ece92f85SJason Jin 	_BE_env.vgaInfo.function = info->function;
136ece92f85SJason Jin 	_BE_env.vgaInfo.device = info->device;
137ece92f85SJason Jin 	_BE_env.vgaInfo.bus = info->bus;
138ece92f85SJason Jin 	_BE_env.vgaInfo.pcidev = info->pcidev;
139ece92f85SJason Jin #else
140ece92f85SJason Jin 	_BE_env.vgaInfo.pciInfo = info->pciInfo;
141ece92f85SJason Jin #endif
142ece92f85SJason Jin 	_BE_env.vgaInfo.BIOSImage = info->BIOSImage;
143ece92f85SJason Jin 	if (info->BIOSImage) {
144ece92f85SJason Jin 		_BE_env.biosmem_base = (ulong) info->BIOSImage;
145ece92f85SJason Jin 		_BE_env.biosmem_limit = 0xC0000 + info->BIOSImageLen - 1;
146ece92f85SJason Jin 	} else {
147ece92f85SJason Jin 		_BE_env.biosmem_base = _BE_env.busmem_base + 0x20000;
148ece92f85SJason Jin 		_BE_env.biosmem_limit = 0xC7FFF;
149ece92f85SJason Jin 	}
150ece92f85SJason Jin 	if (*((u32 *) info->LowMem) == 0)
151ece92f85SJason Jin 		_BE_bios_init((u32 *) info->LowMem);
152ece92f85SJason Jin 	memcpy((u8 *) M.mem_base, info->LowMem, sizeof(info->LowMem));
153ece92f85SJason Jin }
154ece92f85SJason Jin 
155ece92f85SJason Jin /****************************************************************************
156ece92f85SJason Jin PARAMETERS:
157ece92f85SJason Jin info	    - Pointer to VGA device information to retrieve current
158ece92f85SJason Jin 
159ece92f85SJason Jin REMARKS:
160ece92f85SJason Jin This function returns the VGA BIOS functions currently active in the
161ece92f85SJason Jin emulator, so they can be restored at a later date.
162ece92f85SJason Jin ****************************************************************************/
163ece92f85SJason Jin void X86API BE_getVGA(BE_VGAInfo * info)
164ece92f85SJason Jin {
165ece92f85SJason Jin #ifdef __KERNEL__
166ece92f85SJason Jin 	info->function = _BE_env.vgaInfo.function;
167ece92f85SJason Jin 	info->device = _BE_env.vgaInfo.device;
168ece92f85SJason Jin 	info->bus = _BE_env.vgaInfo.bus;
169ece92f85SJason Jin 	info->pcidev = _BE_env.vgaInfo.pcidev;
170ece92f85SJason Jin #else
171ece92f85SJason Jin 	info->pciInfo = _BE_env.vgaInfo.pciInfo;
172ece92f85SJason Jin #endif
173ece92f85SJason Jin 	info->BIOSImage = _BE_env.vgaInfo.BIOSImage;
174ece92f85SJason Jin 	memcpy(info->LowMem, (u8 *) M.mem_base, sizeof(info->LowMem));
175ece92f85SJason Jin }
176ece92f85SJason Jin 
177ece92f85SJason Jin /****************************************************************************
178ece92f85SJason Jin PARAMETERS:
179ece92f85SJason Jin r_seg	- Segment for pointer to convert
180ece92f85SJason Jin r_off	- Offset for pointer to convert
181ece92f85SJason Jin 
182ece92f85SJason Jin REMARKS:
183ece92f85SJason Jin This function maps a real mode pointer in the emulator memory to a protected
184ece92f85SJason Jin mode pointer that can be used to directly access the memory.
185ece92f85SJason Jin 
186ece92f85SJason Jin NOTE:	The memory is *always* in little endian format, son on non-x86
187ece92f85SJason Jin 	systems you will need to do endian translations to access this
188ece92f85SJason Jin 	memory.
189ece92f85SJason Jin ****************************************************************************/
190ece92f85SJason Jin void *X86API BE_mapRealPointer(uint r_seg, uint r_off)
191ece92f85SJason Jin {
192ece92f85SJason Jin 	u32 addr = ((u32) r_seg << 4) + r_off;
193ece92f85SJason Jin 
194ece92f85SJason Jin 	if (addr >= 0xC0000 && addr <= _BE_env.biosmem_limit) {
195ece92f85SJason Jin 		return (void *)(_BE_env.biosmem_base + addr - 0xC0000);
196ece92f85SJason Jin 	} else if (addr >= 0xA0000 && addr <= 0xFFFFF) {
197ece92f85SJason Jin 		return (void *)(_BE_env.busmem_base + addr - 0xA0000);
198ece92f85SJason Jin 	}
199ece92f85SJason Jin 	return (void *)(M.mem_base + addr);
200ece92f85SJason Jin }
201ece92f85SJason Jin 
202ece92f85SJason Jin /****************************************************************************
203ece92f85SJason Jin PARAMETERS:
204ece92f85SJason Jin len	- Return the length of the VESA buffer
205ece92f85SJason Jin rseg	- Place to store VESA buffer segment
206ece92f85SJason Jin roff	- Place to store VESA buffer offset
207ece92f85SJason Jin 
208ece92f85SJason Jin REMARKS:
209ece92f85SJason Jin This function returns the address of the VESA transfer buffer in real
210ece92f85SJason Jin _BE_piomode emulator memory. The VESA transfer buffer is always 1024 bytes long,
211ece92f85SJason Jin and located at 15Kb into the start of the real mode memory (16Kb is where
212ece92f85SJason Jin we put the real mode code we execute for issuing interrupts).
213ece92f85SJason Jin 
214ece92f85SJason Jin NOTE:	The memory is *always* in little endian format, son on non-x86
215ece92f85SJason Jin 	systems you will need to do endian translations to access this
216ece92f85SJason Jin 	memory.
217ece92f85SJason Jin ****************************************************************************/
218ece92f85SJason Jin void *X86API BE_getVESABuf(uint * len, uint * rseg, uint * roff)
219ece92f85SJason Jin {
220ece92f85SJason Jin 	*len = 1024;
221ece92f85SJason Jin 	*rseg = SEG(0x03C00);
222ece92f85SJason Jin 	*roff = OFF(0x03C00);
223ece92f85SJason Jin 	return (void *)(M.mem_base + ((u32) * rseg << 4) + *roff);
224ece92f85SJason Jin }
225ece92f85SJason Jin 
226ece92f85SJason Jin /****************************************************************************
227ece92f85SJason Jin REMARKS:
228ece92f85SJason Jin Cleans up and exits the emulator.
229ece92f85SJason Jin ****************************************************************************/
230ece92f85SJason Jin void X86API BE_exit(void)
231ece92f85SJason Jin {
232ece92f85SJason Jin 	free(M.mem_base);
233*409ecdc0SWolfgang Denk 	free((void *)_BE_env.busmem_base);
234ece92f85SJason Jin }
235ece92f85SJason Jin 
236ece92f85SJason Jin /****************************************************************************
237ece92f85SJason Jin PARAMETERS:
238ece92f85SJason Jin seg	- Segment of code to call
239ece92f85SJason Jin off	- Offset of code to call
240ece92f85SJason Jin regs	- Real mode registers to load
241ece92f85SJason Jin sregs	- Real mode segment registers to load
242ece92f85SJason Jin 
243ece92f85SJason Jin REMARKS:
244ece92f85SJason Jin This functions calls a real mode far function at the specified address,
245ece92f85SJason Jin and loads all the x86 registers from the passed in registers structure.
246ece92f85SJason Jin On exit the registers returned from the call are returned in the same
247ece92f85SJason Jin structures.
248ece92f85SJason Jin ****************************************************************************/
249ece92f85SJason Jin void X86API BE_callRealMode(uint seg, uint off, RMREGS * regs, RMSREGS * sregs)
250ece92f85SJason Jin {
251ece92f85SJason Jin 	M.x86.R_EAX = regs->e.eax;
252ece92f85SJason Jin 	M.x86.R_EBX = regs->e.ebx;
253ece92f85SJason Jin 	M.x86.R_ECX = regs->e.ecx;
254ece92f85SJason Jin 	M.x86.R_EDX = regs->e.edx;
255ece92f85SJason Jin 	M.x86.R_ESI = regs->e.esi;
256ece92f85SJason Jin 	M.x86.R_EDI = regs->e.edi;
257ece92f85SJason Jin 	M.x86.R_DS = sregs->ds;
258ece92f85SJason Jin 	M.x86.R_ES = sregs->es;
259ece92f85SJason Jin 	M.x86.R_FS = sregs->fs;
260ece92f85SJason Jin 	M.x86.R_GS = sregs->gs;
261ece92f85SJason Jin 
262ece92f85SJason Jin 	((u8 *) M.mem_base)[0x4000] = 0x9A;
263ece92f85SJason Jin 	((u8 *) M.mem_base)[0x4001] = (u8) off;
264ece92f85SJason Jin 	((u8 *) M.mem_base)[0x4002] = (u8) (off >> 8);
265ece92f85SJason Jin 	((u8 *) M.mem_base)[0x4003] = (u8) seg;
266ece92f85SJason Jin 	((u8 *) M.mem_base)[0x4004] = (u8) (seg >> 8);
267ece92f85SJason Jin 	((u8 *) M.mem_base)[0x4005] = 0xF1;	/* Illegal op-code */
268ece92f85SJason Jin 	M.x86.R_CS = SEG(0x04000);
269ece92f85SJason Jin 	M.x86.R_IP = OFF(0x04000);
270ece92f85SJason Jin 
271ece92f85SJason Jin 	M.x86.R_SS = SEG(M.mem_size - 2);
272ece92f85SJason Jin 	M.x86.R_SP = OFF(M.mem_size - 2) + 2;
273ece92f85SJason Jin 
274ece92f85SJason Jin 	X86EMU_exec();
275ece92f85SJason Jin 
276ece92f85SJason Jin 	regs->e.cflag = M.x86.R_EFLG & F_CF;
277ece92f85SJason Jin 	regs->e.eax = M.x86.R_EAX;
278ece92f85SJason Jin 	regs->e.ebx = M.x86.R_EBX;
279ece92f85SJason Jin 	regs->e.ecx = M.x86.R_ECX;
280ece92f85SJason Jin 	regs->e.edx = M.x86.R_EDX;
281ece92f85SJason Jin 	regs->e.esi = M.x86.R_ESI;
282ece92f85SJason Jin 	regs->e.edi = M.x86.R_EDI;
283ece92f85SJason Jin 	sregs->ds = M.x86.R_DS;
284ece92f85SJason Jin 	sregs->es = M.x86.R_ES;
285ece92f85SJason Jin 	sregs->fs = M.x86.R_FS;
286ece92f85SJason Jin 	sregs->gs = M.x86.R_GS;
287ece92f85SJason Jin }
288ece92f85SJason Jin 
289ece92f85SJason Jin /****************************************************************************
290ece92f85SJason Jin PARAMETERS:
291ece92f85SJason Jin intno	- Interrupt number to execute
292ece92f85SJason Jin in	- Real mode registers to load
293ece92f85SJason Jin out	- Place to store resulting real mode registers
294ece92f85SJason Jin 
295ece92f85SJason Jin REMARKS:
296ece92f85SJason Jin This functions calls a real mode interrupt function at the specified address,
297ece92f85SJason Jin and loads all the x86 registers from the passed in registers structure.
298ece92f85SJason Jin On exit the registers returned from the call are returned in out stucture.
299ece92f85SJason Jin ****************************************************************************/
300ece92f85SJason Jin int X86API BE_int86(int intno, RMREGS * in, RMREGS * out)
301ece92f85SJason Jin {
302ece92f85SJason Jin 	M.x86.R_EAX = in->e.eax;
303ece92f85SJason Jin 	M.x86.R_EBX = in->e.ebx;
304ece92f85SJason Jin 	M.x86.R_ECX = in->e.ecx;
305ece92f85SJason Jin 	M.x86.R_EDX = in->e.edx;
306ece92f85SJason Jin 	M.x86.R_ESI = in->e.esi;
307ece92f85SJason Jin 	M.x86.R_EDI = in->e.edi;
308ece92f85SJason Jin 	((u8 *) M.mem_base)[0x4000] = 0xCD;
309ece92f85SJason Jin 	((u8 *) M.mem_base)[0x4001] = (u8) intno;
310ece92f85SJason Jin 	((u8 *) M.mem_base)[0x4002] = 0xF1;
311ece92f85SJason Jin 	M.x86.R_CS = SEG(0x04000);
312ece92f85SJason Jin 	M.x86.R_IP = OFF(0x04000);
313ece92f85SJason Jin 
314ece92f85SJason Jin 	M.x86.R_SS = SEG(M.mem_size - 1);
315ece92f85SJason Jin 	M.x86.R_SP = OFF(M.mem_size - 1) - 1;
316ece92f85SJason Jin 
317ece92f85SJason Jin 	X86EMU_exec();
318ece92f85SJason Jin 	out->e.cflag = M.x86.R_EFLG & F_CF;
319ece92f85SJason Jin 	out->e.eax = M.x86.R_EAX;
320ece92f85SJason Jin 	out->e.ebx = M.x86.R_EBX;
321ece92f85SJason Jin 	out->e.ecx = M.x86.R_ECX;
322ece92f85SJason Jin 	out->e.edx = M.x86.R_EDX;
323ece92f85SJason Jin 	out->e.esi = M.x86.R_ESI;
324ece92f85SJason Jin 	out->e.edi = M.x86.R_EDI;
325ece92f85SJason Jin 	return out->x.ax;
326ece92f85SJason Jin }
327ece92f85SJason Jin 
328ece92f85SJason Jin /****************************************************************************
329ece92f85SJason Jin PARAMETERS:
330ece92f85SJason Jin intno	- Interrupt number to execute
331ece92f85SJason Jin in	- Real mode registers to load
332ece92f85SJason Jin out	- Place to store resulting real mode registers
333ece92f85SJason Jin sregs	- Real mode segment registers to load
334ece92f85SJason Jin 
335ece92f85SJason Jin REMARKS:
336ece92f85SJason Jin This functions calls a real mode interrupt function at the specified address,
337ece92f85SJason Jin and loads all the x86 registers from the passed in registers structure.
338ece92f85SJason Jin On exit the registers returned from the call are returned in out stucture.
339ece92f85SJason Jin ****************************************************************************/
340ece92f85SJason Jin int X86API BE_int86x(int intno, RMREGS * in, RMREGS * out, RMSREGS * sregs)
341ece92f85SJason Jin {
342ece92f85SJason Jin 	M.x86.R_EAX = in->e.eax;
343ece92f85SJason Jin 	M.x86.R_EBX = in->e.ebx;
344ece92f85SJason Jin 	M.x86.R_ECX = in->e.ecx;
345ece92f85SJason Jin 	M.x86.R_EDX = in->e.edx;
346ece92f85SJason Jin 	M.x86.R_ESI = in->e.esi;
347ece92f85SJason Jin 	M.x86.R_EDI = in->e.edi;
348ece92f85SJason Jin 	M.x86.R_DS = sregs->ds;
349ece92f85SJason Jin 	M.x86.R_ES = sregs->es;
350ece92f85SJason Jin 	M.x86.R_FS = sregs->fs;
351ece92f85SJason Jin 	M.x86.R_GS = sregs->gs;
352ece92f85SJason Jin 	((u8 *) M.mem_base)[0x4000] = 0xCD;
353ece92f85SJason Jin 	((u8 *) M.mem_base)[0x4001] = (u8) intno;
354ece92f85SJason Jin 	((u8 *) M.mem_base)[0x4002] = 0xF1;
355ece92f85SJason Jin 	M.x86.R_CS = SEG(0x04000);
356ece92f85SJason Jin 	M.x86.R_IP = OFF(0x04000);
357ece92f85SJason Jin 
358ece92f85SJason Jin 	M.x86.R_SS = SEG(M.mem_size - 1);
359ece92f85SJason Jin 	M.x86.R_SP = OFF(M.mem_size - 1) - 1;
360ece92f85SJason Jin 
361ece92f85SJason Jin 	X86EMU_exec();
362ece92f85SJason Jin 	out->e.cflag = M.x86.R_EFLG & F_CF;
363ece92f85SJason Jin 	out->e.eax = M.x86.R_EAX;
364ece92f85SJason Jin 	out->e.ebx = M.x86.R_EBX;
365ece92f85SJason Jin 	out->e.ecx = M.x86.R_ECX;
366ece92f85SJason Jin 	out->e.edx = M.x86.R_EDX;
367ece92f85SJason Jin 	out->e.esi = M.x86.R_ESI;
368ece92f85SJason Jin 	out->e.edi = M.x86.R_EDI;
369ece92f85SJason Jin 	sregs->ds = M.x86.R_DS;
370ece92f85SJason Jin 	sregs->es = M.x86.R_ES;
371ece92f85SJason Jin 	sregs->fs = M.x86.R_FS;
372ece92f85SJason Jin 	sregs->gs = M.x86.R_GS;
373ece92f85SJason Jin 	return out->x.ax;
374ece92f85SJason Jin }
375ce981dc8SJason Jin #endif
376