VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-mode-SwitchToRM.asm@ 60439

Last change on this file since 60439 was 60439, checked in by vboxsync, 9 years ago

bs3kit: updates :-)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1; $Id: bs3-mode-SwitchToRM.asm 60439 2016-04-11 19:08:38Z vboxsync $
2;; @file
3; BS3Kit - Bs3SwitchToRM
4;
5
6;
7; Copyright (C) 2007-2015 Oracle Corporation
8;
9; This file is part of VirtualBox Open Source Edition (OSE), as
10; available from http://www.virtualbox.org. This file is free software;
11; you can redistribute it and/or modify it under the terms of the GNU
12; General Public License (GPL) as published by the Free Software
13; Foundation, in version 2 as it comes in the "COPYING" file of the
14; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16;
17; The contents of this file may alternatively be used under the terms
18; of the Common Development and Distribution License Version 1.0
19; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20; VirtualBox OSE distribution, in which case the provisions of the
21; CDDL are applicable instead of those of the GPL.
22;
23; You may elect to license modified versions of this file under the
24; terms and conditions of either the GPL or the CDDL or both.
25;
26
27%include "bs3kit-template-header.mac"
28
29BS3_EXTERN_SYSTEM16 Bs3Gdt
30%if TMPL_MODE == BS3_MODE_PE16
31BS3_EXTERN_DATA16 g_uBs3CpuDetected
32BS3_EXTERN_CMN Bs3KbdWrite
33BS3_EXTERN_CMN Bs3KbdWait
34%endif
35
36
37;*********************************************************************************************************************************
38;* Global Variables *
39;*********************************************************************************************************************************
40%if TMPL_MODE == BS3_MODE_PE16
41BS3_BEGIN_DATA16
42;; Where to start restoring stack.
43g_ResumeSp: dw 0xfeed
44;; Where to start restoring stack.
45g_ResumeSs: dw 0xface
46%endif
47
48TMPL_BEGIN_TEXT
49
50
51;;
52; Switch to real mode from any other mode.
53;
54; @cproto BS3_DECL(void) Bs3SwitchToRM(void);
55;
56; @uses GPRs and EFLAGS are unchanged (except high 32-bit register (AMD64) parts).
57; CS is loaded with BS3TEXT16.
58; SS:[RE]SP is converted to real mode address.
59; DS and ES are loaded with BS3DATA16_GROUP.
60; FS and GS are loaded with zero if present.
61;
62; @remarks Obviously returns to 16-bit mode, even if the caller was
63; in 32-bit or 64-bit mode.
64;
65; @remarks Does not require 20h of parameter scratch space in 64-bit mode.
66;
67BS3_PROC_BEGIN_MODE Bs3SwitchToRM
68%ifdef TMPL_RM
69 push ax
70 mov ax, BS3_SEL_DATA16
71 mov ds, ax
72 mov es, ax
73 pop ax
74 ret
75
76%elif BS3_MODE_IS_V86(TMPL_MODE)
77 ;
78 ; V8086 - Switch to 16-bit ring-0 and call worker for that mode.
79 ;
80 extern BS3_CMN_NM(Bs3SwitchToRing0)
81 call BS3_CMN_NM(Bs3SwitchToRing0)
82 extern %[BS3_MODE_R0_NM_ %+ TMPL_MODE](Bs3SwitchToRM)
83 jmp %[BS3_MODE_R0_NM_ %+ TMPL_MODE](Bs3SwitchToRM)
84
85%else
86 ;
87 ; Protected mode.
88 ; 80286 requirements for PE16 clutters the code a little.
89 ;
90 %if TMPL_MODE == BS3_MODE_PE16
91 cmp byte [BS3_DATA16_WRT(g_uBs3CpuDetected)], BS3CPU_80286
92 ja .do_386_prologue
93 push ax
94 push bx
95 pushf
96 push word 1
97 jmp .done_prologue
98 %endif
99.do_386_prologue:
100 push sAX
101 push sBX
102 sPUSHF
103 %if TMPL_MODE == BS3_MODE_PE16
104 push word 0
105 %elif BS3_MODE_IS_64BIT_SYS(TMPL_MODE)
106 push sDX
107 push sCX
108 %endif
109.done_prologue:
110
111 ;
112 ; Get to 16-bit ring-0 and disable interrupts.
113 ;
114 extern BS3_CMN_NM(Bs3SwitchToRing0)
115 call BS3_CMN_NM(Bs3SwitchToRing0)
116
117 cli
118
119 %if TMPL_MODE == BS3_MODE_PE16
120 ;
121 ; On 80286 we must reset the CPU to get back to real mode.
122 ;
123 CPU 286
124 pop ax
125 push ax
126 test ax, ax
127 jz .is_386_or_better
128
129 ; Save registers and flags, storing SS:SP in at a known global address.
130%ifdef BS3_STRICT
131 mov ax, 0feedh
132 mov bx, 0faceh
133%endif
134 push di
135 push si
136 push bp
137 push bx
138 push dx
139 push cx
140 push ax
141 pushf
142
143 ; Convert ss:sp to real mode address.
144 BS3_EXTERN_CMN Bs3SelProtFar32ToFlat32
145 mov ax, sp
146 push ss
147 push 0
148 push ax
149 call Bs3SelProtFar32ToFlat32
150 add sp, 6
151
152 mov [g_ResumeSp], ax
153 shl dx, 12
154 mov [g_ResumeSs], dx
155
156 ; Setup resume vector.
157 mov bx, BS3_SEL_R0_SS16
158 mov es, bx
159 mov word [es:467h], .resume
160 mov word [es:467h+2], BS3_SEL_TEXT16
161
162 mov al, 0fh | 80h
163 out 70h, al ; set register index
164 in al, 80h
165 mov al, 0ah ; shutdown action command - no EOI, no 287 reset.
166 out 71h, al ; set cmos[f] = al - invoke testResume as early as possible.
167 in al, 71h ; flush
168
169 %if 0 ; for testing in VM
170 CPU 386
171 mov ax, BS3_SEL_R0_DS16
172 mov ds, ax
173 mov es, ax
174 mov fs, ax
175 mov gs, ax
176
177 mov eax, cr0
178 and ax, ~X86_CR0_PE
179 mov cr0, eax
180hlt
181 jmp BS3_SEL_TEXT16:.resume
182 %endif
183
184 ; Port A reset. (FYI: tripple fault does not do the trick)
185 in al, 92h
186 or al, 1
187 out 92h, al
188 in al, 80h ; flush
189 mov cx, 0ffffh
190.reset_delay:
191 loop .reset_delay
192
193 ; Keyboard controller reset.
194 call Bs3KbdWait
195 push 0 ; zero data (whatever.
196 push 0fh ; KBD_CCMD_RESET
197 call Bs3KbdWrite
198.forever:
199 jmp .forever
200
201 ; This is the resume point. We should be in real mode now, at least in theory.
202.resume:
203 mov ax, BS3_SEL_DATA16
204 mov ds, ax
205 mov es, ax
206 mov ax, [g_ResumeSp]
207 mov ss, [g_ResumeSs]
208 mov sp, ax
209
210 popf
211 pop ax
212 pop cx
213 pop dx
214 pop bx
215 pop bp
216 pop si
217 pop di
218 %ifdef BS3_STRICT
219 cmp ax, 0feedh
220 jne .bad_286_rm_switch
221 cmp bx, 0faceh
222 jne .bad_286_rm_switch
223 %endif
224 jmp .enter_mode
225
226 %ifdef BS3_STRICT
227.bad_286_rm_switch:
228 mov ax, 0e00h + 'Q'
229 mov bx, 0ff00h
230 int 10h
231 jmp .bad_286_rm_switch
232 %endif
233
234 CPU 386
235 %elif TMPL_BITS != 16
236 ;
237 ; Must be in 16-bit segment when calling Bs3SwitchTo16Bit.
238 ;
239 jmp .sixteen_bit_segment wrt FLAT
240BS3_BEGIN_TEXT16
241 BS3_SET_BITS TMPL_BITS
242.sixteen_bit_segment:
243
244 extern BS3_CMN_NM(Bs3SwitchTo16Bit)
245 call BS3_CMN_NM(Bs3SwitchTo16Bit)
246 BS3_SET_BITS 16
247 %endif
248 ;
249 ; Before exiting to real mode we must load sensible selectors into the
250 ; segment registers so the hidden parts (which doesn't get reloaded in
251 ; real mode) are real mode compatible.
252 ;
253.is_386_or_better:
254;; @todo Testcase: Experiment leaving weird stuff in the hidden segment registers.
255 mov ax, BS3_SEL_R0_DS16
256 mov ds, ax
257 mov es, ax
258 mov fs, ax
259 mov gs, ax
260
261 ;
262 ; Exit to real mode.
263 ;
264 mov eax, cr0
265 and eax, X86_CR0_NO_PE_NO_PG
266 mov cr0, eax
267 jmp BS3TEXT16:.reload_cs
268.reload_cs:
269
270 ;
271 ; Convert the stack (now 16-bit prot) to real mode.
272 ;
273 mov ax, BS3_SEL_SYSTEM16
274 mov ds, ax
275 mov bx, ss
276 and bx, X86_SEL_MASK ; ASSUMES GDT stack selector
277 mov al, [bx + 4 + Bs3Gdt]
278 mov ah, [bx + 7 + Bs3Gdt]
279 add sp, [bx + 2 + Bs3Gdt] ; ASSUMES not expand down segment.
280 adc ax, 0
281 %ifdef BS3_STRICT
282 test ax, 0fff0h
283 jz .stack_conv_ok
284 int3
285.stack_conv_ok:
286 %endif
287 shl ax, 12
288 mov ss, ax
289 %if TMPL_BITS != 16
290 and esp, 0ffffh
291 %endif
292
293 %if BS3_MODE_IS_64BIT_SYS(TMPL_MODE)
294 ;
295 ; Clear the long mode enable bit.
296 ;
297 mov ecx, MSR_K6_EFER
298 rdmsr
299 and eax, ~MSR_K6_EFER_LME
300 wrmsr
301 %endif
302
303 ;
304 ; Call routine for doing mode specific setups.
305 ;
306.enter_mode:
307 extern NAME(Bs3EnteredMode_rm)
308 call NAME(Bs3EnteredMode_rm)
309
310 %if TMPL_MODE == BS3_MODE_PE16
311 pop ax
312 test ax, ax
313 jz .do_386_epilogue
314 popf
315 pop bx
316 pop ax
317 ret
318 %endif
319.do_386_epilogue:
320 %if BS3_MODE_IS_64BIT_SYS(TMPL_MODE)
321 pop ecx
322 TMPL_ONLY_64BIT_STMT pop eax
323 pop edx
324 TMPL_ONLY_64BIT_STMT pop eax
325 %endif
326 popfd
327 TMPL_ONLY_64BIT_STMT pop eax
328 pop ebx
329 TMPL_ONLY_64BIT_STMT pop eax
330 pop eax
331 TMPL_ONLY_64BIT_STMT add sp, 4
332 retn (TMPL_BITS - 16) / 8
333
334 %if TMPL_BITS != 16
335TMPL_BEGIN_TEXT
336 %endif
337%endif
338BS3_PROC_END_MODE Bs3SwitchToRM
339
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette