VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bs3kit/bs3-c32-Trap32Generic.asm@ 106061

Last change on this file since 106061 was 106061, checked in by vboxsync, 5 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.4 KB
Line 
1; $Id: bs3-c32-Trap32Generic.asm 106061 2024-09-16 14:03:52Z vboxsync $
2;; @file
3; BS3Kit - Trap, 32-bit assembly handlers.
4;
5
6;
7; Copyright (C) 2007-2024 Oracle and/or its affiliates.
8;
9; This file is part of VirtualBox base platform packages, as
10; available from https://www.virtualbox.org.
11;
12; This program is free software; you can redistribute it and/or
13; modify it under the terms of the GNU General Public License
14; as published by the Free Software Foundation, in version 3 of the
15; License.
16;
17; This program is distributed in the hope that it will be useful, but
18; WITHOUT ANY WARRANTY; without even the implied warranty of
19; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20; General Public License for more details.
21;
22; You should have received a copy of the GNU General Public License
23; along with this program; if not, see <https://www.gnu.org/licenses>.
24;
25; The contents of this file may alternatively be used under the terms
26; of the Common Development and Distribution License Version 1.0
27; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28; in the VirtualBox distribution, in which case the provisions of the
29; CDDL are applicable instead of those of the GPL.
30;
31; You may elect to license modified versions of this file under the
32; terms and conditions of either the GPL or the CDDL or both.
33;
34; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35;
36
37;*********************************************************************************************************************************
38;* Header Files *
39;*********************************************************************************************************************************
40%include "bs3kit-template-header.mac"
41
42%ifndef TMPL_32BIT
43 %error "32-bit only template"
44%endif
45
46
47;*********************************************************************************************************************************
48;* External Symbols *
49;*********************************************************************************************************************************
50BS3_EXTERN_DATA16 g_bBs3CurrentMode
51BS3_EXTERN_DATA16 g_uBs3CpuDetected
52BS3_EXTERN_DATA16 g_apfnBs3TrapHandlers_c32
53BS3_EXTERN_SYSTEM16 Bs3Gdt
54TMPL_BEGIN_TEXT
55BS3_EXTERN_CMN Bs3TrapDefaultHandler
56BS3_EXTERN_CMN Bs3RegCtxRestore
57TMPL_BEGIN_TEXT
58
59
60;*********************************************************************************************************************************
61;* Global Variables *
62;*********************************************************************************************************************************
63BS3_BEGIN_DATA16
64;; Easy to access flat address of Bs3Trap32GenericEntries.
65BS3_GLOBAL_DATA g_Bs3Trap32GenericEntriesFlatAddr, 4
66 dd Bs3Trap32GenericEntries wrt FLAT
67;; Easy to access flat address of Bs3Trap32DoubleFaultHandler.
68BS3_GLOBAL_DATA g_Bs3Trap32DoubleFaultHandlerFlatAddr, 4
69 dd Bs3Trap32DoubleFaultHandler wrt FLAT
70
71
72TMPL_BEGIN_TEXT
73
74;;
75; Generic entry points for IDT handlers, 8 byte spacing.
76;
77BS3_PROC_BEGIN Bs3Trap32GenericEntries
78%macro Bs3Trap32GenericEntryNoErr 1
79 push byte 0 ; 2 byte: fake error code.
80 db 06ah, i ; 2 byte: push imm8 - note that this is a signextended value.
81 jmp near %1 ; 5 byte
82 ALIGNCODE(2)
83%assign i i+1
84%endmacro
85
86%macro Bs3Trap32GenericEntryErrCd 1
87 db 06ah, i ; 2 byte: push imm8 - note that this is a signextended value.
88 jmp near %1 ; 5 byte
89 db 0cch, 0cch ; 2 byte: padding.
90 ALIGNCODE(2)
91%assign i i+1
92%endmacro
93
94%assign i 0 ; start counter.
95 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 0
96 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 1
97 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 2
98 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 3
99 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 4
100 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 5
101 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 6
102 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 7
103 Bs3Trap32GenericEntryErrCd bs3Trap32GenericTrapOrInt ; 8
104 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 9
105 Bs3Trap32GenericEntryErrCd bs3Trap32GenericTrapOrInt ; a
106 Bs3Trap32GenericEntryErrCd bs3Trap32GenericTrapOrInt ; b
107 Bs3Trap32GenericEntryErrCd bs3Trap32GenericTrapOrInt ; c
108 Bs3Trap32GenericEntryErrCd bs3Trap32GenericTrapOrInt ; d
109 Bs3Trap32GenericEntryErrCd bs3Trap32GenericTrapOrInt ; e
110 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; f (reserved)
111 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 10
112 Bs3Trap32GenericEntryErrCd bs3Trap32GenericTrapOrInt ; 11
113 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 12
114 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 13
115 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 14
116 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 15 (reserved)
117 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 16 (reserved)
118 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 17 (reserved)
119 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 18 (reserved)
120 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 19 (reserved)
121 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 1a (reserved)
122 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 1b (reserved)
123 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 1c (reserved)
124 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 1d (reserved)
125 Bs3Trap32GenericEntryErrCd bs3Trap32GenericTrapOrInt ; 1e
126 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt ; 1f (reserved)
127%rep 224
128 Bs3Trap32GenericEntryNoErr bs3Trap32GenericTrapOrInt
129%endrep
130BS3_PROC_END Bs3Trap32GenericEntries
131AssertCompile(Bs3Trap32GenericEntries_EndProc - Bs3Trap32GenericEntries == 10*256)
132
133
134;;
135; Trap or interrupt with error code, faked if necessary.
136;
137BS3_PROC_BEGIN bs3Trap32GenericTrapOrInt
138 push ebp ; 0
139 mov ebp, esp
140 pushfd ; -04h
141 cld
142 push eax ; -08h
143 push edi ; -0ch
144 lea eax, [esp + (4+1+1)*4] ; 4 pushes above, 1 exception number push, 1 error code.
145 push eax ; -10h = handler ESP
146 add eax, 3*4 ; 3 dword iret frame
147 push eax ; -14h = caller ESP if same CPL
148 push ss ; -18h
149 push ds ; -1ch
150
151 ; Make sure we've got a flat DS. It makes everything so much simpler.
152 mov ax, ss
153 and al, 3
154 AssertCompile(BS3_SEL_RING_SHIFT == 8)
155 mov ah, al
156 add ax, BS3_SEL_R0_DS32
157 mov ds, ax
158
159 ;
160 ; We may be comming from 16-bit code with a 16-bit SS. Thunk it as
161 ; the C code may assume flat SS and we'll mess up by using EBP/ESP/EDI
162 ; instead of BP/SP/SS:DI. ASSUMES standard GDT selector.
163 ;
164 mov ax, ss
165 lar eax, ax
166 test eax, X86LAR_F_D
167 jz .stack_thunk
168 mov ax, ss
169 and al, 3
170 AssertCompile(BS3_SEL_RING_SHIFT == 8)
171 mov ah, al
172 add ax, BS3_SEL_R0_SS32
173 mov ss, ax
174 jmp .stack_flat
175.stack_thunk:
176 mov di, ss
177 and edi, X86_SEL_MASK_OFF_RPL
178 mov al, [X86DESCGENERIC_BIT_OFF_BASE_HIGH1 / 8 + edi + Bs3Gdt wrt FLAT]
179 mov ah, [X86DESCGENERIC_BIT_OFF_BASE_HIGH2 / 8 + edi + Bs3Gdt wrt FLAT]
180 shl eax, 16
181 mov ax, [X86DESCGENERIC_BIT_OFF_BASE_LOW / 8 + edi + Bs3Gdt wrt FLAT] ; eax = SS.base
182 movzx ebp, bp ; SS:BP -> flat EBP.
183 add ebp, eax
184 movzx edi, sp ; SS:SP -> flat ESP in EAX.
185 add edi, eax
186 mov ax, ss
187 and al, 3
188 AssertCompile(BS3_SEL_RING_SHIFT == 8)
189 mov ah, al
190 add ax, BS3_SEL_R0_SS32
191 mov ss, ax
192 mov esp, edi
193 sub dword [ebp - 10h], (4+1)*4 ; Recalc handler ESP in case of wraparound.
194 add word [ebp - 10h], (4+1)*4
195 sub dword [ebp - 10h], (4+1+3)*4 ; Recalc caller ESP in case of wraparound.
196 add word [ebp - 10h], (4+1+3)*4
197.stack_flat:
198
199 ; Reserve space for the register and trap frame.
200 mov eax, (BS3TRAPFRAME_size + 7) / 8
201AssertCompileSizeAlignment(BS3TRAPFRAME, 8)
202.more_zeroed_space:
203 push dword 0
204 push dword 0
205 dec eax
206 jnz .more_zeroed_space
207 mov edi, esp ; edi points to trapframe structure.
208
209 ; Copy stuff from the stack over.
210 mov eax, [ebp + 8]
211;; @todo Do voodoo checks for 'int xx' or misguided hardware interrupts.
212 mov [edi + BS3TRAPFRAME.uErrCd], eax
213 mov al, [ebp + 4]
214 mov [edi + BS3TRAPFRAME.bXcpt], al
215 mov eax, [ebp]
216 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp], eax
217 mov eax, [ebp - 04h]
218 mov [edi + BS3TRAPFRAME.fHandlerRfl], eax
219 mov eax, [ebp - 08h]
220 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rax], eax
221 mov eax, [ebp - 0ch]
222 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rdi], eax
223 mov eax, [ebp - 10h]
224 mov [edi + BS3TRAPFRAME.uHandlerRsp], eax
225 mov eax, [ebp - 14h]
226 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], eax
227 mov ax, [ebp - 18h]
228 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.ss], ax
229 mov [edi + BS3TRAPFRAME.uHandlerSs], ax
230 mov ax, [ebp - 1ch]
231 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.ds], ax
232
233 lea ebp, [ebp + 8] ; iret - 4 (i.e. ebp frame chain location)
234 jmp bs3Trap32GenericCommon
235BS3_PROC_END bs3Trap32GenericTrapErrCode
236
237
238;;
239; Common context saving code and dispatching.
240;
241; @param edi Pointer to the trap frame. The following members have been
242; filled in by the previous code:
243; - bXcpt
244; - uErrCd
245; - fHandlerRfl
246; - uHandlerRsp
247; - uHandlerSs
248; - Ctx.rax
249; - Ctx.rbp
250; - Ctx.rdi
251; - Ctx.rsp - assuming same CPL
252; - Ctx.ds
253; - Ctx.ss
254;
255; @param ebp Pointer to the dword before the iret frame, i.e. where ebp
256; would be saved if this was a normal call.
257;
258; @remarks This is a separate function for hysterical raisins.
259;
260BS3_PROC_BEGIN bs3Trap32GenericCommon
261 ;
262 ; Fake EBP frame.
263 ;
264 mov eax, [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp]
265 mov [ebp], eax
266
267 ;
268 ; Save the remaining GPRs and segment registers.
269 ;
270 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rcx], ecx
271 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rdx], edx
272 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rbx], ebx
273 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rsi], esi
274 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.es], es
275 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.fs], fs
276 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.gs], gs
277
278 ;
279 ; Load 32-bit data selector for the DPL we're executing at into DS and ES.
280 ; Save the handler CS value first.
281 ;
282 mov ax, cs
283 mov [edi + BS3TRAPFRAME.uHandlerCs], ax
284 and al, 3
285 AssertCompile(BS3_SEL_RING_SHIFT == 8)
286 mov ah, al
287 add ax, BS3_SEL_R0_DS32
288 mov ds, ax
289 mov es, ax
290
291 ;
292 ; Copy and update the mode now that we've got a flat DS.
293 ;
294 mov al, [BS3_DATA16_WRT(g_bBs3CurrentMode)]
295 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.bMode], al
296 and al, ~BS3_MODE_CODE_MASK
297 or al, BS3_MODE_CODE_32
298 mov [BS3_DATA16_WRT(g_bBs3CurrentMode)], al
299
300 ;
301 ; Copy iret info.
302 ;
303 mov ecx, [ebp + 4]
304 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rip], ecx
305 mov ecx, [ebp + 12]
306 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rflags], ecx
307 mov cx, [ebp + 8]
308 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.cs], cx
309 test dword [ebp + 12], X86_EFL_VM
310 jnz .iret_frame_v8086
311 mov ax, ss
312 and al, 3
313 and cl, 3
314 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.bCpl], cl
315 cmp cl, al
316 je .iret_frame_same_cpl
317
318.iret_frame_different_cpl:
319 mov ecx, [ebp + 16]
320 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], ecx
321 mov cx, [ebp + 20]
322 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.ss], cx
323 mov byte [edi + BS3TRAPFRAME.cbIretFrame], 5*4
324 jmp .iret_frame_done
325
326.iret_frame_v8086:
327 mov byte [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.bCpl], 3
328 or byte [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.bMode], BS3_MODE_CODE_V86 ; paranoia ^ 2
329 mov ecx, [ebp + 16]
330 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], ecx
331 mov cx, [ebp + 20]
332 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.ss], cx
333 mov cx, [ebp + 24]
334 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.es], cx
335 mov cx, [ebp + 28]
336 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.ds], cx
337 mov cx, [ebp + 32]
338 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.fs], cx
339 mov cx, [ebp + 36]
340 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.gs], cx
341 mov byte [edi + BS3TRAPFRAME.cbIretFrame], 9*4
342 jmp .iret_frame_done
343
344.iret_frame_same_cpl: ; (caller already set SS:RSP and uHandlerRsp for same CPL iret frames)
345 mov byte [edi + BS3TRAPFRAME.cbIretFrame], 3*4
346
347.iret_frame_done:
348 ;
349 ; Control registers.
350 ;
351 str ax
352 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.tr], ax
353 sldt ax
354 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.ldtr], ax
355
356 mov ax, ss
357 test al, 3
358 jnz .skip_crX_because_cpl_not_0
359
360 mov eax, cr3
361 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.cr3], eax
362.save_cr0_cr2_cr4: ; The double fault code joins us here.
363 mov eax, cr0
364 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.cr0], eax
365 mov eax, cr2
366 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.cr2], eax
367
368 test byte [1 + BS3_DATA16_WRT(g_uBs3CpuDetected)], (BS3CPU_F_CPUID >> 8) ; CR4 first appeared in later 486es.
369 jz .skip_cr4_because_not_there
370 mov eax, cr4
371 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.cr4], eax
372 jmp .set_flags
373
374.skip_cr4_because_not_there:
375 mov byte [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_CR4
376 jmp .set_flags
377
378.skip_crX_because_cpl_not_0:
379 or byte [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.fbFlags], \
380 BS3REG_CTX_F_NO_CR0_IS_MSW | BS3REG_CTX_F_NO_CR2_CR3 | BS3REG_CTX_F_NO_CR4
381 smsw [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.cr0]
382.set_flags:
383 or byte [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.fbFlags], BS3REG_CTX_F_NO_AMD64
384
385 ;
386 ; Dispatch it to C code.
387 ;
388.dispatch_to_handler:
389 movzx ebx, byte [edi + BS3TRAPFRAME.bXcpt]
390 mov eax, [ebx * 4 + BS3_DATA16_WRT(_g_apfnBs3TrapHandlers_c32)]
391 or eax, eax
392 jnz .call_handler
393 mov eax, Bs3TrapDefaultHandler
394.call_handler:
395 push edi
396 call eax
397
398 ;
399 ; Resume execution using trap frame.
400 ;
401 push 0
402 add edi, BS3TRAPFRAME.Ctx
403 push edi
404 call Bs3RegCtxRestore
405.panic:
406 hlt
407 jmp .panic
408BS3_PROC_END bs3Trap32GenericCommon
409
410
411;;
412; Helper.
413;
414; @retruns Flat address in eax.
415; @param ax
416; @uses eax
417;
418bs3Trap32TssInAxToFlatInEax:
419 ; Get the GDT base address and find the descriptor address (EAX)
420 sub esp, 8+2
421 sgdt [esp]
422 and eax, 0fff8h
423 add eax, [esp + 2] ; GDT base address.
424 add esp, 8+2
425
426 ; Get the flat TSS address from the descriptor.
427 mov al, [eax + (X86DESCGENERIC_BIT_OFF_BASE_HIGH1 / 8)]
428 mov ah, [eax + (X86DESCGENERIC_BIT_OFF_BASE_HIGH2 / 8)]
429 shl eax, 16
430 mov ax, [eax + (X86DESCGENERIC_BIT_OFF_BASE_LOW / 8)]
431 ret
432
433;;
434; Double fault handler.
435;
436; We don't have to load any selectors or clear anything in EFLAGS because the
437; TSS specified sane values which got loaded during the task switch.
438;
439BS3_PROC_BEGIN Bs3Trap32DoubleFaultHandler
440 push 0 ; We'll copy the rip from the other TSS here later to create a more sensible call chain.
441 push ebp
442 mov ebp, esp
443
444 pushfd ; Get handler flags.
445 pop ecx
446
447 xor edx, edx ; NULL register.
448
449 ;
450 ; Allocate a zero filled trap frame.
451 ;
452 mov eax, (BS3TRAPFRAME_size + 7) / 8
453AssertCompileSizeAlignment(BS3TRAPFRAME, 8)
454.more_zeroed_space:
455 push edx
456 push edx
457 dec eax
458 jz .more_zeroed_space
459 mov edi, esp
460
461 ;
462 ; Fill in the non-context trap frame bits.
463 ;
464 mov [edi + BS3TRAPFRAME.fHandlerRfl], ecx
465 mov word [edi + BS3TRAPFRAME.bXcpt], X86_XCPT_DF
466 mov [edi + BS3TRAPFRAME.uHandlerCs], cs
467 mov [edi + BS3TRAPFRAME.uHandlerSs], ss
468 lea ecx, [ebp + 3*4] ; two pushes, one error code.
469 mov [edi + BS3TRAPFRAME.uHandlerRsp], ecx
470 mov ecx, [ebp + 8]
471 mov [edi + BS3TRAPFRAME.uErrCd], ecx
472
473 ;
474 ; Copy the register state from the previous task segment.
475 ;
476
477 ; Find our TSS.
478 str ax
479 call bs3Trap32TssInAxToFlatInEax
480
481 ; Find the previous TSS.
482 mov ax, [eax + X86TSS32.selPrev]
483 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.tr], ax
484 call bs3Trap32TssInAxToFlatInEax
485
486 ; Do the copying.
487 mov ecx, [eax + X86TSS32.eax]
488 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rax], ecx
489 mov ecx, [eax + X86TSS32.ecx]
490 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rcx], ecx
491 mov ecx, [eax + X86TSS32.edx]
492 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rdx], ecx
493 mov ecx, [eax + X86TSS32.ebx]
494 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rbx], ecx
495 mov ecx, [eax + X86TSS32.esp]
496 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rsp], ecx
497 mov ecx, [eax + X86TSS32.ebp]
498 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rbp], ecx
499 mov [ebp], ecx ; For better call stacks.
500 mov ecx, [eax + X86TSS32.esi]
501 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rsi], ecx
502 mov ecx, [eax + X86TSS32.edi]
503 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rdi], ecx
504 mov ecx, [eax + X86TSS32.esi]
505 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rsi], ecx
506 mov ecx, [eax + X86TSS32.eflags]
507 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rflags], ecx
508 mov ecx, [eax + X86TSS32.eip]
509 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.rip], ecx
510 mov [ebp + 4], ecx ; For better call stacks.
511 mov cx, [eax + X86TSS32.cs]
512 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.cs], cx
513 mov cx, [eax + X86TSS32.ds]
514 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.ds], cx
515 mov cx, [eax + X86TSS32.es]
516 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.es], cx
517 mov cx, [eax + X86TSS32.fs]
518 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.fs], cx
519 mov cx, [eax + X86TSS32.gs]
520 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.gs], cx
521 mov cx, [eax + X86TSS32.ss]
522 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.ss], cx
523 mov cx, [eax + X86TSS32.selLdt] ; Note! This isn't necessarily the ldtr at the time of the fault.
524 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.ldtr], cx
525 mov cx, [eax + X86TSS32.cr3] ; Note! This isn't necessarily the cr3 at the time of the fault.
526 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.cr3], ecx
527
528 ;
529 ; Set CPL; copy and update mode.
530 ;
531 mov cl, [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.ss]
532 and cl, 3
533 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.bCpl], cl
534
535 mov cl, [BS3_DATA16_WRT(g_bBs3CurrentMode)]
536 mov [edi + BS3TRAPFRAME.Ctx + BS3REGCTX.bMode], cl
537 and cl, ~BS3_MODE_CODE_MASK
538 or cl, BS3_MODE_CODE_32
539 mov [BS3_DATA16_WRT(g_bBs3CurrentMode)], cl
540
541 ;
542 ; Join code paths with the generic handler code.
543 ;
544 jmp bs3Trap32GenericCommon.save_cr0_cr2_cr4
545BS3_PROC_END Bs3Trap32DoubleFaultHandler
546
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