]> git.ipfire.org Git - people/ms/u-boot.git/blame - arch/x86/lib/realmode_switch.S
Convert ISO-8859 files to UTF-8
[people/ms/u-boot.git] / arch / x86 / lib / realmode_switch.S
CommitLineData
2262cfee
WD
1/*
2 * (C) Copyright 2002
fa82f871 3 * Daniel Engström, Omicron Ceti AB, daniel@omicron.se
8bde7f77 4 *
2262cfee
WD
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
2262cfee
WD
24/* 32bit -> 16bit -> 32bit mode switch code */
25
26/*
27 * Stack frame at 0xe00
53677ef1 28 * e00 ebx;
2262cfee
WD
29 * e04 ecx;
30 * e08 edx;
31 * e0c esi;
32 * e10 edi;
8bde7f77 33 * e14 ebp;
2262cfee 34 * e18 eax;
8bde7f77 35 * e1c ds;
2262cfee 36 * e20 es;
8bde7f77 37 * e24 fs;
2262cfee
WD
38 * e28 gs;
39 * e2c orig_eax;
40 * e30 eip;
41 * e34 cs;
42 * e38 eflags;
43 * e3c esp;
44 * e40 ss;
45 */
46
47#define a32 .byte 0x67; /* address size prefix 32 */
8bde7f77 48#define o32 .byte 0x66; /* operand size prefix 32 */
2262cfee
WD
49
50.section .realmode, "ax"
51.code16
2262cfee
WD
52 /* 16bit protected mode code here */
53.globl realmode_enter
54realmode_enter:
55o32 pusha
56o32 pushf
57 cli
53677ef1
WD
58 sidt saved_idt
59 sgdt saved_gdt
60 movl %esp, %eax
61 movl %eax, saved_protected_mode_esp
8bde7f77 62
2262cfee 63 movl $0x10, %eax
53677ef1 64 movl %eax, %esp
2262cfee
WD
65 movw $0x28, %ax
66 movw %ax, %ds
67 movw %ax, %es
68 movw %ax, %fs
69 movw %ax, %gs
70
71 lidt realmode_idt_ptr
53677ef1
WD
72 movl %cr0, %eax /* Go back into real mode by */
73 andl $0x7ffffffe, %eax /* clearing PE to 0 */
2262cfee 74 movl %eax, %cr0
53677ef1 75 ljmp $0x0,$do_realmode /* switch to real mode */
8bde7f77
WD
76
77do_realmode: /* realmode code from here */
2262cfee
WD
78 movw %cs,%ax
79 movw %ax,%ds
80 movw %ax,%es
81 movw %ax,%fs
82 movw %ax,%gs
8bde7f77 83
2262cfee 84 /* create a temporary stack */
8bde7f77
WD
85
86 movw $0xc0, %ax
87 movw %ax, %ss
88 movw $0x200, %ax
89 movw %ax, %sp
90
2262cfee
WD
91 popl %ebx
92 popl %ecx
93 popl %edx
94 popl %esi
95 popl %edi
96 popl %ebp
97 popl %eax
98 movl %eax, temp_eax
99 popl %eax
100 movw %ax, %ds
101 popl %eax
102 movw %ax, %es
103 popl %eax
104 movw %ax, %fs
105 popl %eax
106 movw %ax, %gs
107 popl %eax /* orig_eax */
108 popl %eax
109cs movw %ax, temp_ip
110 popl %eax
111cs movw %ax, temp_cs
112o32 popf
113 popl %eax
114 popw %ss
115 movl %eax, %esp
116cs movl temp_eax, %eax
53677ef1 117 wbinvd /* self-modifying code,
2262cfee 118 * better flush the cache */
8bde7f77 119
2262cfee
WD
120 .byte 0x9a /* lcall */
121temp_ip:
53677ef1 122 .word 0 /* new ip */
8bde7f77 123temp_cs:
53677ef1 124 .word 0 /* new cs */
2262cfee
WD
125realmode_ret:
126 /* save eax, esp and ss */
127cs movl %eax, saved_eax
128 movl %esp, %eax
129cs movl %eax, saved_esp
53677ef1 130 movw %ss, %ax
2262cfee 131cs movw %ax, saved_ss
8bde7f77 132
2262cfee
WD
133 /* restore the stack, note that we set sp to 0x244;
134 * pt_regs is 0x44 bytes long and we push the structure
135 * backwards on to the stack, bottom first */
8bde7f77
WD
136
137 movw $0xc0, %ax
138 movw %ax, %ss
139 movw $0x244, %ax
140 movw %ax, %sp
141
2262cfee
WD
142 xorl %eax,%eax
143cs movw saved_ss, %ax
144 pushl %eax
145cs movl saved_esp, %eax
146 pushl %eax
147o32 pushf
148 xorl %eax,%eax
149cs movw temp_cs, %ax
150 pushl %eax
151cs movw temp_ip, %ax
152 pushl %eax
153 pushl $0
154 movw %gs, %ax
155 pushl %eax
156 movw %fs, %ax
157 pushl %eax
158 movw %es, %ax
159 pushl %eax
160 movw %ds, %ax
161 pushl %eax
162 movl saved_eax, %eax
163 pushl %eax
164 pushl %ebp
165 pushl %edi
166 pushl %esi
167 pushl %edx
168 pushl %ecx
169 pushl %ebx
170
171o32 cs lidt saved_idt
53677ef1 172o32 cs lgdt saved_gdt /* Set GDTR */
2262cfee 173
53677ef1
WD
174 movl %cr0, %eax /* Go back into protected mode */
175 orl $1,%eax /* reset PE to 1 */
176 movl %eax, %cr0
177 jmp next_line /* flush prefetch queue */
8bde7f77
WD
178next_line:
179 movw $return_ptr, %ax
53677ef1 180 movw %ax,%bp
2262cfee
WD
181o32 cs ljmp *(%bp)
182
183.code32
184protected_mode:
53677ef1
WD
185 movl $0x18,%eax /* reload GDT[3] */
186 movw %ax,%fs /* reset FS */
187 movw %ax,%ds /* reset DS */
188 movw %ax,%gs /* reset GS */
189 movw %ax,%es /* reset ES */
190 movw %ax,%ss /* reset SS */
191 movl saved_protected_mode_esp, %eax
2262cfee
WD
192 movl %eax, %esp
193 popf
194 popa
8bde7f77 195 ret
2262cfee
WD
196
197temp_eax:
198 .long 0
199
200saved_ss:
53677ef1 201 .word 0
2262cfee
WD
202saved_esp:
203 .long 0
204saved_eax:
205 .long 0
8bde7f77 206
2262cfee 207realmode_idt_ptr:
8bde7f77
WD
208 .word 0x400
209 .word 0x0, 0x0
210
211saved_gdt:
53677ef1 212 .word 0, 0, 0, 0
2262cfee 213saved_idt:
53677ef1 214 .word 0, 0, 0, 0
2262cfee
WD
215
216saved_protected_mode_esp:
53677ef1 217 .long 0
8bde7f77 218
2262cfee
WD
219return_ptr:
220 .long protected_mode
221 .word 0x10