xref: /reactos/boot/freeldr/freeldr/arch/i386/int386.S (revision 25720d75)
1/*
2 *  FreeLoader
3 *  Copyright (C) 1998-2002  Brian Palmer  <brianp@sginet.com>
4 *
5 *  This program is free software; you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation; either version 2 of the License, or
8 *  (at your option) any later version.
9 *
10 *  This program is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License along
16 *  with this program; if not, write to the Free Software Foundation, Inc.,
17 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20	.text
21	.code16
22
23#define ASM
24#include <arch.h>
25
26/* Only these flags are propagated into Int386() */
27#define FLAGS_PROP	(I386FLAG_CF | \
28                     I386FLAG_ZF | \
29                     I386FLAG_SF)
30
31Int386_REGS:
32
33Int386_eax:
34	.long 0
35Int386_ebx:
36	.long 0
37Int386_ecx:
38	.long 0
39Int386_edx:
40	.long 0
41
42Int386_esi:
43	.long 0
44Int386_edi:
45	.long 0
46
47Int386_ds:
48	.word 0
49Int386_es:
50	.word 0
51Int386_fs:
52	.word 0
53Int386_gs:
54	.word 0
55
56Int386_eflags:
57	.long 0
58
59Int386_vector:
60	.long 0
61Int386_regsin:
62	.long 0
63Int386_regsout:
64	.long 0
65
66/*
67 * int Int386(int ivec, REGS* in, REGS* out);
68 */
69EXTERN(_Int386)
70	.code32
71
72	/* Get the function parameters */
73	movl	0x04(%esp),%eax
74	movl	%eax,Int386_vector
75	movb	%al,Int386_vector_opcode
76	movl	0x08(%esp),%eax
77	movl	%eax,Int386_regsin
78	movl	0x0c(%esp),%eax
79	movl	%eax,Int386_regsout
80
81	/* Save all registers + segment registers */
82	pushw	%ds
83	pushw	%es
84	pushw	%fs
85	pushw	%gs
86	pushal
87
88	/* Copy the input regs to our variables */
89	movl	$Int386_REGS,%edi
90	movl	Int386_regsin,%esi
91	movl	$0x24,%ecx
92	cld
93	rep
94	movsb
95
96	call	switch_to_real
97	.code16
98
99	/* Setup the registers */
100	movw	%cs:Int386_ds,%ax
101	movw	%ax,%ds					/* DS register */
102	movw	%cs:Int386_es,%ax
103	movw	%ax,%es					/* ES register */
104	movw	%cs:Int386_fs,%ax
105	movw	%ax,%fs					/* FS register */
106	movw	%cs:Int386_gs,%ax
107	movw	%ax,%gs					/* GS register */
108
109	/* Prepare EFLAGS for recover */
110	pushf
111	movw	%cs:Int386_eflags, %ax
112	popw	%cx
113	andw	$FLAGS_PROP, %ax
114	andw	$~FLAGS_PROP, %cx
115	orw		%cx, %ax
116	pushw	%ax
117
118	/* Recover general purpose registers */
119	movl	%cs:Int386_eax,%eax		/* EAX register */
120	movl	%cs:Int386_ebx,%ebx		/* EBX register */
121	movl	%cs:Int386_ecx,%ecx		/* ECX register */
122	movl	%cs:Int386_edx,%edx		/* EDX register */
123
124	movl	%cs:Int386_esi,%esi		/* ESI register */
125	movl	%cs:Int386_edi,%edi		/* EDI register */
126
127	/* Recover previously prepared flags */
128	popf
129
130	/* Do not set the flags register */
131	/* only return its value in regsout */
132	//pushl	Int386_eflags
133	//popfl							/* EFLAGS register */
134
135	/* Call the interrupt vector */
136	/*int		Int386_vector*/
137Int386_int_opcode:
138	.byte	0xcd
139Int386_vector_opcode:
140	.byte	0x00
141
142	/* Save the registers */
143	movl	%eax,%cs:Int386_eax		/* EAX register */
144	movl	%ebx,%cs:Int386_ebx		/* EBX register */
145	movl	%ecx,%cs:Int386_ecx		/* ECX register */
146	movl	%edx,%cs:Int386_edx		/* EDX register */
147
148	movl	%esi,%cs:Int386_esi		/* ESI register */
149	movl	%edi,%cs:Int386_edi		/* EDI register */
150
151	movw	%ds,%ax					/* DS register */
152	movw	%ax,%cs:Int386_ds
153	movw	%es,%ax					/* ES register */
154	movw	%ax,%cs:Int386_es
155	movw	%fs,%ax					/* FS register */
156	movw	%ax,%cs:Int386_fs
157	movw	%gs,%ax					/* GS register */
158	movw	%ax,%cs:Int386_gs
159
160	pushf
161	popw	%cs:Int386_eflags		/* EFLAGS register */
162
163	call	switch_to_prot
164	.code32
165
166	/* Copy the variables to the output regs */
167	movl	$Int386_REGS,%esi
168	movl	Int386_regsout,%edi
169	movl	$0x24,%ecx
170	cld
171	rep
172	movsb
173
174	/* Restore segment and all other registers */
175
176
177	popal
178	popw	%gs
179	popw	%fs
180	popw	%es
181	popw	%ds
182
183	/* Get return value */
184	movl	Int386_eax,%eax
185
186	ret
187