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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
|
title "Fast Protected Mode services"
;++
;
; Copyright (c) 1989 Microsoft Corporation
;
; Module Name:
;
; fastpm.asm
;
; Abstract:
;
; This module implements a fast entry to and exit from protected mode
;
; Author:
;
; Dave Hastings (daveh) 26-Jul-91
;
;--
.386p
include ks386.inc
include callconv.inc
include bop.inc
include vint.inc
include vdmtb.inc
_TEXT SEGMENT PARA PUBLIC 'CODE'
ASSUME DS:NOTHING, ES:NOTHING, SS:FLAT, FS:NOTHING, GS:NOTHING
_TEXT ENDS
_DATA SEGMENT DWORD PUBLIC 'DATA'
extrn _VdmTib:Dword
public _NTVDMpLockPrefixTable
_NTVDMpLockPrefixTable label dword
dd offset FLAT:_ntvdmlock1
dd offset FLAT:_ntvdmlock2
dd 0
_DATA ENDS
_TEXT SEGMENT
; Interrupt type definitions
CPU_YODA_INT equ 4
BIT_CPU_YODA_INT equ 0
CPU_HW_RESET equ 0
BIT_CPU_HW_RESET equ 1
CPU_TIMER_TICK equ 1
BIT_CPU_TIMER_TICK equ 2
CPU_HW_INT equ 3
BIT_CPU_HW_INT equ 3
page ,132
subttl "FastEnterPm"
;++
;
; Routine Description:
;
; This routine is a faster way to enter 16 bit vdm protected mode.
; Instead of making a system call, we just save the 32 bit state
; into the VdmTib, restore the Vdm state from the VdmTib, and do
; a far return to the application.
;
; Arguments:
;
; ss:sp + 4 = pointer to VdmTib
;
; Returns:
;
; nothing.
;
assume DS:FLAT
cPublicProc _FastEnterPm,0
push ebp
mov ebp,esp ; set up stack frame
push ebx ; free up reg for pointer
lea ebx,_VdmTib
; translate the interrupt flag to the virtual interrupt flag
test [ebx].VtVdmContext.CsEFlags,dword ptr EFLAGS_INTERRUPT_MASK
jz fe10
_ntvdmlock1:
lock or dword ptr ds:FIXED_NTVDMSTATE_LINEAR,dword ptr VDM_VIRTUAL_INTERRUPTS
test dword ptr ds:FIXED_NTVDMSTATE_LINEAR,dword ptr VDM_INTERRUPT_PENDING
jz fe20
; set up event info for an interrupt acknowlege
mov word ptr [ebx].VtEventInfo.EiEvent,VdmIntAck
mov word ptr [ebx].VtEventInfo.EiInstructionSize,0
mov word ptr [ebx].VtEventInfo.EiIntAckInfo,0
pop ebx
mov esp,ebp
pop ebp
stdRET _FastEnterPm
fe10:
_ntvdmlock2:
lock and dword ptr ds:FIXED_NTVDMSTATE_LINEAR, NOT VDM_VIRTUAL_INTERRUPTS
fe20:
mov [ebx].VtMonitorContext.CsEax,eax
mov eax,[ebp - 4]
mov [ebx].VtMonitorContext.CsEbx,eax
mov [ebx].VtMonitorContext.CsEcx,ecx
mov [ebx].VtMonitorContext.CsEdx,edx
mov [ebx].VtMonitorContext.CsEsi,esi
mov [ebx].VtMonitorContext.CsEdi,edi
mov eax,[ebp]
mov [ebx].VtMonitorContext.CsEbp,eax
mov eax,ebp
add eax,8 ; pop ebp and ret addr
mov [ebx].VtMonitorContext.CsEsp,eax
mov eax,[ebp + 4]
mov [ebx].VtMonitorContext.CsEip,eax
mov eax,cs
mov [ebx].VtMonitorContext.CsSegCs,eax
mov eax,ss
mov [ebx].VtMonitorContext.CsSegSs,eax
mov eax,ds
mov [ebx].VtMonitorContext.CsSegDs,eax
mov eax,es
mov [ebx].VtMonitorContext.CsSegEs,eax
mov eax,fs
mov [ebx].VtMonitorContext.CsSegFs,eax
mov eax,gs
mov [ebx].VtMonitorContext.CsSegGs,eax
pushfd
pop eax
mov [ebx].VtMonitorContext.CsEflags,eax
mov eax,[ebx].VtVdmContext.CsSegSs
mov es,eax
mov edi,[ebx].VtVdmContext.CsEsp ; es:edi -> stack
lar eax,eax
test eax,400000h ; big?
jnz fe30
movzx edi,di
fe30: mov eax,[ebx].VtVdmContext.CsEflags
sub edi,4
mov es:[edi],eax ; push Eflags
mov eax,[ebx].VtVdmContext.CsSegCs
sub edi,4
mov es:[edi],eax ; push cs
mov eax,[ebx].VtVdmContext.CsEip
sub edi,4
mov es:[edi],eax ; push ip
sub edi,4
mov eax,[ebx].VtVdmContext.CsEbp ; push ebp
mov es:[edi],eax
fe40: push es
push edi ; push ss:esp for lss esp
mov eax,esp ; save sp for pushad
; simulate pushad
push dword ptr [ebx].VtVdmContext.CsEax
push dword ptr [ebx].VtVdmContext.CsEcx
push dword ptr [ebx].VtVdmContext.CsEdx
push dword ptr [ebx].VtVdmContext.CsEbx
push eax
push ebp ; save pointer to stack frame
push dword ptr [ebx].VtVdmContext.CsEsi
push dword ptr [ebx].VtVdmContext.CsEdi
; push seg regs
push dword ptr [ebx].VtVdmContext.CsSegFs
push dword ptr [ebx].VtVdmContext.CsSegGs
push dword ptr [ebx].VtVdmContext.CsSegDs
push dword ptr [ebx].VtVdmContext.CsSegEs
; set up VDM seg regs
pop es
pop ds
pop gs ; pop fs,gs of invalid selectors are trapped in ntoskrnl,
pop fs ; and handled by setting to zero
; set up VDM general regs
popad
; set up vdm stack
lss esp,[ebp - 12]
; restore ebp
pop ebp
; return to VDM
iretd
stdENDP _FastEnterPm
page ,132
subttl "GetFastBopEntry"
;++
;
; Routine Description:
;
; This routine supplies the address of the routine that segmented
; protected mode code should call to switch to flat mode.
;
; Arguments:
;
; esp + 4 = pointer to VdmTib->VdmContext
;
; Returns:
;
; nothing.
;
assume DS:FLAT
cPublicProc _GetFastBopEntryAddress,1
push ebp
mov ebp,esp
push ebx
push eax
mov ebx,[ebp + 8]
mov [ebx].CsSegEs,cs
mov eax,offset FLAT:_FastLeavePm
mov word ptr [ebx].CsEbx,ax
shr eax,16
mov word ptr [ebx].CsEdx,ax
pop eax
pop ebx
mov esp,ebp
pop ebp
stdRET _GetFastBopEntryAddress
stdENDP _GetFastBopEntryAddress
page ,132
subttl "FastLeavePm"
;++
;
; Routine Description:
;
; This routine switches from the VDM context to the monitor context.
;
; Arguments:
;
; none
;
; Returns:
;
; executing with monitor context
;
assume DS:Nothing,ES:Nothing,SS:Nothing
ALIGN 16
cPublicProc _FastLeavePm,0
push ebx
mov bx,ds
push bx ; so push and pop size same
mov bx,KGDT_R3_DATA OR RPL_MASK
mov ds,bx
assume ds:FLAT
lea ebx,_VdmTib ; get pointer to contexts
pushfd
mov dword ptr [ebx].VtVdmContext.CsEax,eax
pop eax
mov dword ptr [ebx].VtVdmContext.CsEFlags,eax
pop ax
mov word ptr [ebx].VtVdmContext.CsSegDs,ax
pop eax
mov dword ptr [ebx].VtVdmContext.CsEbx,eax
mov dword ptr [ebx].VtVdmContext.CsEcx,ecx
mov dword ptr [ebx].VtVdmContext.CsEdx,edx
mov dword ptr [ebx].VtVdmContext.CsEsi,esi
mov dword ptr [ebx].VtVdmContext.CsEdi,edi
mov dword ptr [ebx].VtVdmContext.CsEbp,ebp
mov word ptr [ebx].VtVdmContext.CsSegEs,es
mov word ptr [ebx].VtVdmContext.CsSegFs,fs
mov word ptr [ebx].VtVdmContext.CsSegGs,gs
pop eax
mov dword ptr [ebx].VtVdmContext.CsEip,eax
pop eax
mov word ptr [ebx].VtVdmContext.CsSegCs,ax
mov dword ptr [ebx].VtVdmContext.CsEsp,esp
mov word ptr [ebx].VtVdmContext.CsSegSs,ss
; switch Stacks
.errnz (CsEsp + 4 - CsSegSS)
lss esp, [ebx].VtMonitorContext.CsEsp
; Now running on Monitor stack
; set up event info
mov word ptr [ebx].VtEventInfo.EiEvent,VdmBop
mov dword ptr [ebx].VtEventInfo.EiInstructionSize,BOP_SIZE
mov ax,[ebx].VtVdmContext.CsSegCs
mov es,ax
; BUGBUG 16 or 32 bit !!!!!
mov di,[ebx].VtVdmContext.CsEip
mov al,byte ptr es:[di]
movzx eax,al
mov [ebx].VtEventInfo.EiBopNumber,eax
sub di,2
mov word ptr [ebx].VtVdmContext.CsEip,di ; set up bop bias
; set up for IRET
push dword ptr [ebx].VtMonitorContext.CsEFlags
push dword ptr [ebx].VtMonitorContext.CsSegCs
push dword ptr [ebx].VtMonitorContext.CsEip
; simulate pushad
mov eax,esp
push dword ptr [ebx].VtMonitorContext.CsEax
push dword ptr [ebx].VtMonitorContext.CsEcx
push dword ptr [ebx].VtMonitorContext.CsEdx
push dword ptr [ebx].VtMonitorContext.CsEbx
push eax
push dword ptr [ebx].VtMonitorContext.CsEbp
push dword ptr [ebx].VtMonitorContext.CsEsi
push dword ptr [ebx].VtMonitorContext.CsEdi
; push seg regs
push dword ptr [ebx].VtMonitorContext.CsSegFs
push dword ptr [ebx].VtMonitorContext.CsSegGs
push dword ptr [ebx].VtMonitorContext.CsSegDs
push dword ptr [ebx].VtMonitorContext.CsSegEs
test ds:FIXED_NTVDMSTATE_LINEAR,dword ptr VDM_VIRTUAL_INTERRUPTS
jz fl10
or [ebx].VtVdmContext.CsEFlags,dword ptr EFLAGS_INTERRUPT_MASK
jmp fl20
fl10: and dword ptr [ebx].VtVdmContext.CsEFlags, NOT EFLAGS_INTERRUPT_MASK
fl20:
; set up Monitor seg regs
pop es
pop ds
pop gs
pop fs
; set up Monitor general regs
popad
xor eax,eax ; indicate success
; return
iretd
stdENDP _FastLeavePm
_TEXT ends
end
|