1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
; $Id: bs3-cmn-SwitchTo32Bit.asm $
;; @file
; BS3Kit - Bs3SwitchTo32Bit
;
;
; Copyright (C) 2007-2023 Oracle and/or its affiliates.
;
; This file is part of VirtualBox base platform packages, as
; available from https://www.virtualbox.org.
;
; This program is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation, in version 3 of the
; License.
;
; This program is distributed in the hope that it will be useful, but
; WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
; General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with this program; if not, see <https://www.gnu.org/licenses>.
;
; The contents of this file may alternatively be used under the terms
; of the Common Development and Distribution License Version 1.0
; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
; in the VirtualBox distribution, in which case the provisions of the
; CDDL are applicable instead of those of the GPL.
;
; You may elect to license modified versions of this file under the
; terms and conditions of either the GPL or the CDDL or both.
;
; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
;
%include "bs3kit-template-header.mac"
%if TMPL_BITS == 16
BS3_EXTERN_CMN Bs3SelProtFar32ToFlat32
BS3_EXTERN_CMN Bs3Syscall
%endif
%if TMPL_BITS != 32
BS3_EXTERN_DATA16 g_bBs3CurrentMode
TMPL_BEGIN_TEXT
%endif
;;
; @cproto BS3_DECL(void) Bs3SwitchTo32Bit(void);
;
; @remarks Does not require 20h of parameter scratch space in 64-bit mode.
;
BS3_PROC_BEGIN_CMN Bs3SwitchTo32Bit, BS3_PBC_NEAR
%if TMPL_BITS == 32
ret
%else
%if TMPL_BITS == 16
push ax ; Reserve space for larger return value (adjusted in 32-bit code).
push eax
pushfd
push edx
%else
pushfq
mov [rsp + 4], eax
%endif
cli
%if TMPL_BITS == 16
; Check for v8086 mode, we need to exit it to enter 32-bit mode.
mov ax, seg g_bBs3CurrentMode
mov ds, ax
mov al, [BS3_DATA16_WRT(g_bBs3CurrentMode)]
test al, BS3_MODE_CODE_V86
jz .not_v8086
; Calc flat stack into edx.
mov dx, ss
movzx edx, dx
shl edx, 4
add dx, sp
adc edx, 0 ; edx = flat stack address corresponding to ss:sp
; Switch to 16-bit ring0 and go on to do the far jump to 32-bit code.
mov ax, BS3_SYSCALL_TO_RING0
call Bs3Syscall
mov xAX, BS3_SEL_R0_CS32
jmp .do_far_jump
%endif
.not_v8086:
%if TMPL_BITS == 16
; Calc flat stack into edx.
movzx eax, sp
push ecx
push ebx
push ss
push eax
call Bs3SelProtFar32ToFlat32
add sp, 6
shl edx, 16
mov dx, ax ; edx = flat stack address corresponding to ss:sp
pop ebx
pop ecx
%endif
; Calc ring addend.
mov ax, cs
and xAX, 3
shl xAX, BS3_SEL_RING_SHIFT
add xAX, BS3_SEL_R0_CS32
; Create far return for switching to 32-bit mode.
.do_far_jump:
push sAX
%if TMPL_BITS == 16
push dword .thirty_two_bit wrt FLAT
o32 retf
%else
push .thirty_two_bit
o64 retf
%endif
BS3_SET_BITS 32
.thirty_two_bit:
; Load 32-bit segment registers.
add eax, BS3_SEL_R0_SS32 - BS3_SEL_R0_CS32
mov ss, ax
%if TMPL_BITS == 16
mov esp, edx ; Load flat stack address.
%endif
add eax, BS3_SEL_R0_DS32 - BS3_SEL_R0_SS32
mov ds, ax
mov es, ax
; Update globals.
and byte [BS3_DATA16_WRT(g_bBs3CurrentMode)], ~BS3_MODE_CODE_MASK
or byte [BS3_DATA16_WRT(g_bBs3CurrentMode)], BS3_MODE_CODE_32
%if TMPL_BITS == 16
; Adjust the return address.
movzx eax, word [esp + 4*3 + 2]
add eax, BS3_ADDR_BS3TEXT16
mov [esp + 4*3], eax
%endif
; Restore and return.
%if TMPL_BITS == 16
pop edx
%endif
popfd
pop eax
TONLY64 ret 4
TNOT64 ret
%endif
BS3_PROC_END_CMN Bs3SwitchTo32Bit
;; @todo far 16-bit variant.
|