blob: 9f212c2e8e15a8446c8f5d5ef4bd5ca03105da69 [file] [log] [blame]
wdenk591dda52002-11-18 00:14:45 +00001/*
2 * (C) Copyright 2002
3 * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24
25/* 32bit -> 16bit -> 32bit mode switch code */
26
27/*
28 * Stack frame at 0xe00
29 * e00 ebx;
30 * e04 ecx;
31 * e08 edx;
32 * e0c esi;
33 * e10 edi;
34 * e14 ebp;
35 * e18 eax;
36 * e1c ds;
37 * e20 es;
38 * e24 fs;
39 * e28 gs;
40 * e2c orig_eax;
41 * e30 eip;
42 * e34 cs;
43 * e38 eflags;
44 * e3c esp;
45 * e40 ss;
46 */
47
48#define a32 .byte 0x67; /* address size prefix 32 */
49#define o32 .byte 0x66; /* operand size prefix 32 */
50
51.section .realmode, "ax"
52.code16
53
54 /* 16bit protected mode code here */
55.globl realmode_enter
56realmode_enter:
57o32 pusha
58o32 pushf
59 cli
60 sidt saved_idt
61 sgdt saved_gdt
62 movl %esp, %eax
63 movl %eax, saved_protected_mode_esp
64
65 movl $0x10, %eax
66 movl %eax, %esp
67 movw $0x28, %ax
68 movw %ax, %ds
69 movw %ax, %es
70 movw %ax, %fs
71 movw %ax, %gs
72
73 lidt realmode_idt_ptr
74 movl %cr0, %eax /* Go back into real mode by */
75 andl $0x7ffffffe, %eax /* clearing PE to 0 */
76 movl %eax, %cr0
77 ljmp $0x0,$do_realmode /* switch to real mode */
78
79do_realmode: /* realmode code from here */
80 movw %cs,%ax
81 movw %ax,%ds
82 movw %ax,%es
83 movw %ax,%fs
84 movw %ax,%gs
85
86 /* create a temporary stack */
87
88 movw $0xc0, %ax
89 movw %ax, %ss
90 movw $0x200, %ax
91 movw %ax, %sp
92
93 popl %ebx
94 popl %ecx
95 popl %edx
96 popl %esi
97 popl %edi
98 popl %ebp
99 popl %eax
100 movl %eax, temp_eax
101 popl %eax
102 movw %ax, %ds
103 popl %eax
104 movw %ax, %es
105 popl %eax
106 movw %ax, %fs
107 popl %eax
108 movw %ax, %gs
109 popl %eax /* orig_eax */
110 popl %eax
111cs movw %ax, temp_ip
112 popl %eax
113cs movw %ax, temp_cs
114o32 popf
115 popl %eax
116 popw %ss
117 movl %eax, %esp
118cs movl temp_eax, %eax
119 wbinvd /* self-modifying code,
120 * better flush the cache */
121
122 .byte 0x9a /* lcall */
123temp_ip:
124 .word 0 /* new ip */
125temp_cs:
126 .word 0 /* new cs */
127realmode_ret:
128 /* save eax, esp and ss */
129cs movl %eax, saved_eax
130 movl %esp, %eax
131cs movl %eax, saved_esp
132 movw %ss, %ax
133cs movw %ax, saved_ss
134
135 /* restore the stack, note that we set sp to 0x244;
136 * pt_regs is 0x44 bytes long and we push the structure
137 * backwards on to the stack, bottom first */
138
139 movw $0xc0, %ax
140 movw %ax, %ss
141 movw $0x244, %ax
142 movw %ax, %sp
143
144 xorl %eax,%eax
145cs movw saved_ss, %ax
146 pushl %eax
147cs movl saved_esp, %eax
148 pushl %eax
149o32 pushf
150 xorl %eax,%eax
151cs movw temp_cs, %ax
152 pushl %eax
153cs movw temp_ip, %ax
154 pushl %eax
155 pushl $0
156 movw %gs, %ax
157 pushl %eax
158 movw %fs, %ax
159 pushl %eax
160 movw %es, %ax
161 pushl %eax
162 movw %ds, %ax
163 pushl %eax
164 movl saved_eax, %eax
165 pushl %eax
166 pushl %ebp
167 pushl %edi
168 pushl %esi
169 pushl %edx
170 pushl %ecx
171 pushl %ebx
172
173o32 cs lidt saved_idt
174o32 cs lgdt saved_gdt /* Set GDTR */
175
176 movl %cr0, %eax /* Go back into protected mode */
177 orl $1,%eax /* reset PE to 1 */
178 movl %eax, %cr0
179 jmp next_line /* flush prefetch queue */
180next_line:
181 movw $return_ptr, %ax
182 movw %ax,%bp
183o32 cs ljmp *(%bp)
184
185.code32
186protected_mode:
187 movl $0x18,%eax /* reload GDT[3] */
188 movw %ax,%fs /* reset FS */
189 movw %ax,%ds /* reset DS */
190 movw %ax,%gs /* reset GS */
191 movw %ax,%es /* reset ES */
192 movw %ax,%ss /* reset SS */
193 movl saved_protected_mode_esp, %eax
194 movl %eax, %esp
195 popf
196 popa
197 ret
198
199temp_eax:
200 .long 0
201
202saved_ss:
203 .word 0
204saved_esp:
205 .long 0
206saved_eax:
207 .long 0
208
209realmode_idt_ptr:
210 .word 0x400
211 .word 0x0, 0x0
212
213saved_gdt:
214 .word 0, 0, 0, 0
215saved_idt:
216 .word 0, 0, 0, 0
217
218saved_protected_mode_esp:
219 .long 0
220
221return_ptr:
222 .long protected_mode
223 .word 0x10