VirtualBox

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

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

bs3kit: Fixes and updates.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.3 KB
Line 
1; $Id: bs3-mode-TrapSystemCallHandler.asm 60019 2016-03-14 11:33:59Z vboxsync $
2;; @file
3; BS3Kit - System call trap handler.
4;
5
6;
7; Copyright (C) 2007-2016 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;*********************************************************************************************************************************
28;* Header Files *
29;*********************************************************************************************************************************
30%include "bs3kit-template-header.mac"
31
32
33;*********************************************************************************************************************************
34;* External Symbols *
35;*********************************************************************************************************************************
36BS3_EXTERN_DATA16 g_bBs3CurrentMode
37BS3_EXTERN_DATA16 g_uBs3CpuDetected
38%if TMPL_BITS == 16
39BS3_EXTERN_DATA16 g_uBs3TrapEipHint
40%endif
41TMPL_BEGIN_TEXT
42
43%if TMPL_BITS == 32
44BS3_EXTERN_CMN Bs3SelProtFar32ToFlat32
45%endif
46BS3_EXTERN_CMN Bs3RegCtxConvertToRingX
47BS3_EXTERN_CMN Bs3RegCtxRestore
48BS3_EXTERN_CMN Bs3Panic
49TMPL_BEGIN_TEXT
50
51
52;;
53; System call handler.
54;
55; This is an assembly trap handler that is called in response to a system call
56; request from 'user' code. The only fixed parameter is [ER]AX which contains
57; the system call number. Other registers are assigned on a per system call
58; basis, ditto for which registers are preserved and which are used to return
59; stuff. Generally, though, we preserve all registers not used as return
60; values or otherwise implicitly transformed by the call.
61;
62; Note! The 16-bit versions of this code must be careful with using extended
63; registers as we wish this code to work on real 80286 (maybe even 8086)
64; CPUs too!
65;
66BS3_PROC_BEGIN_MODE Bs3TrapSystemCallHandler
67 ;
68 ; This prologue is kind of complicated because of 80286 and older CPUs
69 ; as well as different requirements for 64-bit and the other modes.
70 ;
71%define VAR_CALLER_BP [xBP]
72%if TMPL_BITS != 64
73 %define VAR_CALLER_DS [xBP - xCB]
74%endif
75%define VAR_CALLER_BX [xBP - sCB*1 - xCB]
76%define VAR_CALLER_AX [xBP - sCB*2 - xCB]
77%define VAR_CALLER_CX [xBP - sCB*3 - xCB]
78%define VAR_CALLER_DX [xBP - sCB*4 - xCB]
79%define VAR_CALLER_SI [xBP - sCB*5 - xCB]
80%define VAR_CALLER_DI [xBP - sCB*6 - xCB]
81%if TMPL_BITS == 16
82 %define VAR_CALLER_ESP [xBP - sCB*7 - xCB]
83 %define VAR_CALLER_EBP [xBP - sCB*8 - xCB]
84 %define VAR_CALLER_EFLAGS [xBP - sCB*9 - xCB]
85 %define VAR_CALLER_MODE [xBP - sCB*9 - xCB*2]
86%else
87 %define VAR_CALLER_MODE [xBP - sCB*6 - xCB*2]
88%endif
89 push xBP
90 mov xBP, xSP
91%if TMPL_BITS == 64
92 push 0 ; dummy DS entry
93%else
94 push ds
95 %ifdef TMPL_CMN_R86
96 push BS3DATA16
97 %else
98 push RT_CONCAT(BS3_SEL_R0_DS,TMPL_BITS)
99 %endif
100 pop ds ; DS = BS3DATA16_GROUP or FLAT and we can safely access data
101 %if TMPL_BITS == 16 && (TMPL_MODE == BS3_MODE_SYS_RM || TMPL_MODE == BS3_MODE_SYS_PE16)
102 cmp byte [BS3_DATA16_WRT(g_uBs3CpuDetected)], BS3CPU_80286
103 jbe .prologue_pre_80386
104 %endif
105%endif
106 push sBX
107 push sAX
108 push sCX
109 push sDX
110 push sSI
111 push sDI
112%if TMPL_BITS == 16
113 push ebp
114 push esp
115 pushfd
116 %if TMPL_MODE == BS3_MODE_SYS_RM || TMPL_MODE == BS3_MODE_SYS_PE16
117 jmp .prologue_end
118
119.prologue_pre_80386:
120 push bx ; dummy
121 push bx
122 push ax ; dummy
123 push ax
124 push cx ; dummy
125 push cx
126 push dx ; dummy
127 push dx
128 push si ; dummy
129 push si
130 push di ; dummy
131 push di
132 sub sp, 0ch ; dummy
133 %endif
134%endif
135.prologue_end:
136
137 ;
138 ; VAR_CALLER_MODE: Save the current mode (important for v8086 with 16-bit kernel).
139 ;
140 xor xBX, xBX
141 mov bl, [BS3_DATA16_WRT(g_bBs3CurrentMode)]
142 push xBX
143
144 ;
145 ; Dispatch the system call.
146 ;
147 cmp ax, BS3_SYSCALL_LAST
148 ja .invalid_syscall
149%ifdef TMPL_16BIT
150 mov bx, ax
151 shl bx, 1
152 jmp word [cs:.aoffSyscallHandlers + bx]
153%else
154 movzx ebx, ax
155 mov ebx, [.aoffSyscallHandlers + ebx * 4]
156 jmp xBX
157%endif
158.aoffSyscallHandlers:
159%ifdef TMPL_16BIT
160 dw .invalid_syscall wrt BS3TEXT16
161 dw .print_chr wrt BS3TEXT16
162 dw .print_str wrt BS3TEXT16
163 dw .to_ringX wrt BS3TEXT16
164 dw .to_ringX wrt BS3TEXT16
165 dw .to_ringX wrt BS3TEXT16
166 dw .to_ringX wrt BS3TEXT16
167%else
168 dd .invalid_syscall wrt FLAT
169 dd .print_chr wrt FLAT
170 dd .print_str wrt FLAT
171 dd .to_ringX wrt FLAT
172 dd .to_ringX wrt FLAT
173 dd .to_ringX wrt FLAT
174 dd .to_ringX wrt FLAT
175%endif
176
177 ;
178 ; Invalid system call.
179 ;
180.invalid_syscall:
181 int3
182 jmp .return
183
184 ;
185 ; Print char in the CL register.
186 ;
187 ; We use the vga bios teletype interrupt to do the writing, so we must
188 ; be in some kind of real mode for this to work. 16-bit code segment
189 ; requried for the mode switching code.
190 ;
191BS3_BEGIN_TEXT16
192 BS3_SET_BITS TMPL_BITS
193.print_chr:
194%if TMPL_BITS != 64
195 push es
196 mov di, ss ; Must save and restore SS for supporting 16/32 and 32/16 caller/kernel ring-0 combinations.
197%endif
198%ifndef TMPL_CMN_R86
199 ; Switch to real mode (20h param scratch area not required).
200 extern TMPL_NM(Bs3SwitchToRM)
201 call TMPL_NM(Bs3SwitchToRM)
202 BS3_SET_BITS 16
203%endif
204
205 ; Print the character, turning '\n' into '\r\n'.
206 cmp cl, 0ah ; \n
207 je .print_chr_newline
208 mov ah, 0eh
209 mov al, cl
210 mov bx, 0ff00h
211 int 10h
212 jmp .print_chr_done
213
214.print_chr_newline:
215 mov ax, 0e0dh ; cmd + \r
216 mov bx, 0ff00h
217 int 10h
218 mov ax, 0e0ah ; cmd + \n
219 mov bx, 0ff00h
220 int 10h
221
222.print_chr_done:
223%ifndef TMPL_CMN_R86
224 ; Switch back (20h param scratch area not required).
225 extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_rm)
226 call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_rm)
227 BS3_SET_BITS TMPL_BITS
228%endif
229%if TMPL_BITS != 64
230 mov ss, di
231 pop es
232%endif
233 jmp .return
234TMPL_BEGIN_TEXT
235
236
237 ;
238 ; Print CX chars from string pointed to by DX:SI in 16-bit and v8086 mode,
239 ; and ESI/RSI in 64-bit and 32-bit mode (flat).
240 ;
241 ; We use the vga bios teletype interrupt to do the writing, so we must
242 ; be in some kind of real mode for this to work. 16-bit code segment
243 ; requried for the mode switching code.
244 ;
245.print_str:
246;;%if TMPL_BITS != 64
247;; mov bl, byte VAR_CALLER_MODE
248;; and bl, BS3_MODE_CODE_MASK
249;; cmp bl, BS3_MODE_CODE_V86
250;; jne .print_str_not_v8086
251;; ;; @todo this gets complicated _fast_. Later.
252;;.print_str_not_v8086:
253;;%endif
254 int3
255 jmp .return
256
257
258 ;
259 ; Switch the caller to ring-0, ring-1, ring-2 or ring-3.
260 ;
261 ; This implement this by saving the entire register context, calling
262 ; a transformation function (C) and restoring the modified register
263 ; context using a generic worker.
264 ;
265.to_ringX:
266 sub xSP, BS3REGCTX_size
267 mov xBX, xSP ; xBP = BS3REGCTX pointer.
268 call .save_context
269
270
271%if TMPL_BITS == 32
272 ; Convert xBP to flat pointer in 32-bit
273 push ss
274 push xBX
275 call Bs3SelProtFar32ToFlat32
276 add sSP, 8
277 mov xBX, xAX
278%endif
279 push xBX ; Save pointer for the final restore call.
280
281 ; Convert the register context from whatever it is to ring-0.
282 BS3_ONLY_64BIT_STMT sub rsp, 10h
283 BS3_ONLY_16BIT_STMT push ss
284 push xBX
285 mov ax, VAR_CALLER_AX
286 sub ax, BS3_SYSCALL_TO_RING0
287 push xAX
288 BS3_CALL Bs3RegCtxConvertToRingX, 2
289 add xSP, sCB BS3_ONLY_64BIT(+ 10h)
290
291 ; Restore the register context (does not return).
292 pop xBX ; restore saved pointer.
293 BS3_ONLY_64BIT_STMT sub rsp, 18h
294 BS3_ONLY_16BIT_STMT push ss
295 push xBX
296 BS3_CALL Bs3RegCtxRestore, 1
297 jmp Bs3Panic
298
299
300 ;
301 ; Return.
302 ;
303.return:
304 pop xBX ; saved mode
305 mov [BS3_DATA16_WRT(g_bBs3CurrentMode)], bl
306%if TMPL_BITS == 16
307 and bl, BS3_MODE_CODE_MASK
308 cmp bl, BS3_MODE_CODE_V86
309 je .return_to_v8086_from_16bit_krnl
310 cmp bl, BS3_MODE_CODE_32
311 je .return_to_32bit_from_16bit_krnl
312 %if TMPL_MODE == BS3_MODE_SYS_RM || TMPL_MODE == BS3_MODE_SYS_PE16
313 cmp byte [BS3_DATA16_WRT(g_uBs3CpuDetected)], BS3CPU_80286
314 jbe .return_pre_80386
315 %endif
316
317 popfd
318 pop esp
319 pop ebp
320%endif
321 pop sDI
322 pop sSI
323 pop sDX
324 pop sCX
325 pop sAX
326 pop sBX
327%if TMPL_BITS != 64
328 pop ds
329 leave
330 iret
331%else
332 leave ; skips fake ds
333 iretq
334%endif
335
336%if TMPL_BITS == 16
337 %if TMPL_MODE == BS3_MODE_SYS_RM || TMPL_MODE == BS3_MODE_SYS_PE16
338 ; Variant of the above for 80286 and older.
339.return_pre_80386:
340 add sp, 0ch
341 pop di
342 pop di
343 pop si
344 pop si
345 pop dx
346 pop dx
347 pop cx
348 pop cx
349 pop ax
350 pop ax
351 pop bx
352 pop bx
353 pop ds
354 pop bp
355 iret
356 %endif
357
358.return_to_v8086_from_16bit_krnl:
359 int3
360 jmp .return_to_v8086_from_16bit_krnl
361
362 ;
363 ; Returning to 32-bit code may require us to expand and seed the eip
364 ; and esp addresses in the iret frame since these are truncated when
365 ; using a 16-bit interrupt handler.
366 ;
367 ; Incoming stack: New stack diff cpl:
368 ; bp + 0ah: [ss]
369 ; bp + 08h: [sp] bx + 38h: [ss] New stack same cpl:
370 ; bp + 06h: flags
371 ; bp + 04h: cs bx + 34h: [esp] bx + 30h: eflags
372 ; bp + 02h: ip
373 ; -------------- bx + 30h: eflags bx + 2ch: cs
374 ; bp + 00h: bp
375 ; bp - 02h: ds bx + 2ch: cs bx + 28h: eip
376 ; -------------
377 ; bp - 06h: ebx bx + 28h: eip bx + 26h: bp
378 ; -------------- bx + 24h: ds
379 ; bp - 0ah: eax bx + 26h: bp
380 ; bx + 24h: ds bx + 20h: ebx
381 ; bp - 0eh: ecx
382 ; bx + 20h: ebx bx + 1ch: eax
383 ; bp - 12h: edx
384 ; bx + 1ch: eax bx + 18h: ecx
385 ; bp - 16h: esi
386 ; bx + 18h: ecx bx + 14h: edx
387 ; bp - 1ah: edi
388 ; bx + 14h: edx bx + 10h: esi
389 ; bp - 1eh: esp
390 ; bx + 10h: esi bx + 0ch: edi
391 ; bp - 22h: ebp
392 ; bx + 0ch: edi bx + 08h: esp
393 ; bp - 26h: eflags
394 ; bx + 08h: esp bx + 04h: ebp
395 ;
396 ; bx + 04h: ebp bx + 00h: eflags
397 ;
398 ; bx + 00h: eflags
399 ;
400 ;
401 ; If we're returning to the same CPL, we're still using the stack of
402 ; the 32-bit caller. The high ESP word does not need restoring.
403 ;
404 ; If we're returning to a lower CPL, there on a 16-bit ring-0 stack,
405 ; however, the high ESP word is still that of the caller.
406 ;
407.return_to_32bit_from_16bit_krnl:
408 mov ax, cs
409 and al, 3
410 mov ah, 3
411 and ah, [xBP + xCB*2]
412 ; The iret frame doubles in size, so allocate more stack.
413 cmp al, ah
414 je .return_to_32bit_from_16bit_krnl_same_cpl_sub_sp
415 sub sp, 2*2
416.return_to_32bit_from_16bit_krnl_same_cpl_sub_sp:
417 sub sp, 3*2
418 mov bx, sp
419 ; Copy the saved registers.
420 xor di, di
421.return_to_32bit_from_16bit_krnl_copy_loop:
422 mov ecx, [bp + di - 26h]
423 mov [ss:bx + di], ecx
424 add di, 4
425 cmp di, 28h
426 jb .return_to_32bit_from_16bit_krnl_copy_loop
427 ; Convert the 16-bit iret frame to a 32-bit iret frame.
428 mov ecx, [BS3_DATA16_WRT(g_uBs3TrapEipHint)]
429 mov cx, [bp + 02h] ; ip
430 mov [ss:bx + 28h], ecx
431 mov ecx, 0f00d0000h
432 mov cx, [bp + 04h] ; cs
433 mov [ss:bx + 2ch], ecx
434 mov ecx, [ss:bx] ; caller eflags
435 mov cx, [bp + 06h] ; flags
436 mov [ss:bx + 30h], ecx
437 cmp al, ah
438 jz .return_to_32bit_from_16bit_krnl_do_return
439 mov ecx, [ss:bx + 08h] ; caller esp
440 mov cx, [bp + 08h] ; sp
441 mov [ss:bx + 34h], ecx
442 mov ecx, 0f00d0000h
443 mov cx, [bp + 0ah] ; ss
444 mov [ss:bx + 38h], ecx
445.return_to_32bit_from_16bit_krnl_do_return:
446 popfd
447 pop ecx ; esp - only the high bits!
448 mov cx, sp
449 mov esp, ecx
450 pop ebp
451 lea bp, [bx + 26h]
452 pop edi
453 pop esi
454 pop edx
455 pop ecx
456 pop eax
457 pop ebx
458 pop ds
459 leave
460 iretd
461
462%endif ; 16-bit
463
464
465 ;
466 ; Internal function. ss:xBX = Pointer to register frame (BS3REGCTX).
467 ; @uses xAX
468 ;
469.save_context:
470%if TMPL_BITS == 16
471 cmp byte [BS3_DATA16_WRT(g_uBs3CpuDetected)], BS3CPU_80386
472 jae .save_context_full
473
474 ;
475 ; 80286 or earlier.
476 ;
477
478 ; Clear the state area first.
479 push di
480 xor di, di
481.save_context_16_clear_loop:
482 mov word [ss:bx + di], 0
483 mov word [ss:bx + di + 2], 0
484 mov word [ss:bx + di + 4], 0
485 mov word [ss:bx + di + 6], 0
486 add di, 8
487 cmp di, BS3REGCTX_size
488 jb .save_context_16_clear_loop
489 pop di
490
491 ; Do the 8086/80186/80286 state saving.
492 mov ax, VAR_CALLER_AX
493 mov [ss:bx + BS3REGCTX.rax], ax
494 mov cx, VAR_CALLER_CX
495 mov [ss:bx + BS3REGCTX.rcx], ax
496 mov ax, VAR_CALLER_DX
497 mov [ss:bx + BS3REGCTX.rdx], ax
498 mov ax, VAR_CALLER_BX
499 mov [ss:bx + BS3REGCTX.rbx], ax
500 mov [ss:bx + BS3REGCTX.rsi], si
501 mov [ss:bx + BS3REGCTX.rdi], di
502 mov ax, VAR_CALLER_BP
503 mov [ss:bx + BS3REGCTX.rbp], ax
504 mov [ss:bx + BS3REGCTX.es], es
505 mov ax, [xBP + xCB]
506 mov [ss:bx + BS3REGCTX.rip], ax
507 mov ax, [xBP + xCB*2]
508 mov [ss:bx + BS3REGCTX.cs], ax
509 and al, X86_SEL_RPL
510 mov [ss:bx + BS3REGCTX.bCpl], al
511 cmp al, 0
512 je .save_context_16_same
513 mov ax, [xBP + xCB*4]
514 mov [ss:bx + BS3REGCTX.rsp], ax
515 mov ax, [xBP + xCB*5]
516 mov [ss:bx + BS3REGCTX.ss], ax
517 jmp .save_context_16_done_stack
518.save_context_16_same:
519 mov ax, bp
520 add ax, xCB * (1 + 3)
521 mov [ss:bx + BS3REGCTX.rsp], ax
522 mov ax, ss
523 mov [ss:bx + BS3REGCTX.ss], ax
524.save_context_16_done_stack:
525 mov ax, [xBP + xCB*3]
526 mov [ss:bx + BS3REGCTX.rflags], ax
527 mov al, VAR_CALLER_MODE
528 mov [ss:bx + BS3REGCTX.bMode], al
529 cmp byte [BS3_DATA16_WRT(g_uBs3CpuDetected)], BS3CPU_80286
530 jne .save_context_16_return
531 smsw [ss:bx + BS3REGCTX.cr0]
532 str [ss:bx + BS3REGCTX.tr]
533 sldt [ss:bx + BS3REGCTX.ldtr]
534.save_context_16_return:
535 ret
536%endif ; TMPL_BITS == 16
537
538 ;
539 ; 80386 or later.
540 ;
541.save_context_full:
542
543 ; Clear the state area first unless 64-bit mode.
544%if TMPL_BITS != 64
545 push xDI
546 xor xDI, xDI
547.save_context_32_clear_loop:
548 mov dword [ss:xBX + xDI], 0
549 mov dword [ss:xBX + xDI + 4], 0
550 add xDI, 8
551 cmp xDI, BS3REGCTX_size
552 jb .save_context_32_clear_loop
553 pop xDI
554%endif
555
556 ; Do the 386+ state saving.
557%if TMPL_BITS == 16 ; save the high word of registered pushed on the stack.
558 mov ecx, VAR_CALLER_AX
559 mov [ss:bx + BS3REGCTX.rax], ecx
560 mov ecx, VAR_CALLER_CX
561 mov [ss:bx + BS3REGCTX.rcx], ecx
562 mov ecx, VAR_CALLER_DX
563 mov [ss:bx + BS3REGCTX.rdx], ecx
564 mov ecx, VAR_CALLER_BX
565 mov [ss:bx + BS3REGCTX.rbx], ecx
566 mov ecx, VAR_CALLER_EBP
567 mov [ss:bx + BS3REGCTX.rbp], ecx
568 mov ecx, VAR_CALLER_ESP
569 mov [ss:bx + BS3REGCTX.rsp], ecx
570 mov ecx, VAR_CALLER_SI
571 mov [ss:bx + BS3REGCTX.rsi], ecx
572 mov ecx, VAR_CALLER_DI
573 mov [ss:bx + BS3REGCTX.rdi], ecx
574 mov ecx, VAR_CALLER_EFLAGS
575 mov [ss:bx + BS3REGCTX.rflags], ecx
576 %if TMPL_BITS == 16
577 ; Seed high EIP word if 32-bit CS.
578 lar ecx, [bp + 4]
579 jnz .save_context_full_done_16bit_high_word
580 test ecx, X86LAR_F_D
581 jz .save_context_full_done_16bit_high_word
582 mov ecx, [BS3_DATA16_WRT(g_uBs3TrapEipHint)]
583 mov [ss:bx + BS3REGCTX.rip], ecx
584 %endif ; 16-bit
585.save_context_full_done_16bit_high_word:
586%endif
587 mov xAX, VAR_CALLER_AX
588 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.rax], xAX
589 mov xCX, VAR_CALLER_CX
590 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.rcx], xCX
591 mov xAX, VAR_CALLER_DX
592 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.rdx], xAX
593 mov xAX, VAR_CALLER_BX
594 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.rbx], xAX
595 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.rsi], sSI
596 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.rdi], sDI
597 mov xAX, VAR_CALLER_BP
598 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.rbp], xAX
599 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.es], es
600 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.fs], fs
601 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.gs], gs
602 mov xAX, [xBP + xCB]
603 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.rip], xAX
604 mov ax, [xBP + xCB*2]
605 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.cs], ax
606%if TMPL_MODE != BS3_MODE_RM
607 and al, X86_SEL_RPL
608 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.bCpl], al
609 cmp al, 0
610 je .save_context_full_same
611 mov xAX, [xBP + xCB*4]
612 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.rsp], xAX
613 mov ax, [xBP + xCB*5]
614 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.ss], ax
615 jmp .save_context_full_done_stack
616%else
617 mov byte [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.bCpl], 0
618%endif
619.save_context_full_same:
620 mov xAX, xBP
621 add xAX, xCB * (1 + 3)
622 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.rsp], xAX
623 mov ax, ss
624 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.ss], ax
625.save_context_full_done_stack:
626 mov xAX, [xBP + xCB*3]
627 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.rflags], sAX
628
629 mov al, VAR_CALLER_MODE
630 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.bMode], al
631%if TMPL_BITS == 64
632 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.r8], r8
633 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.r9], r9
634 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.r10], r10
635 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.r11], r11
636 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.r12], r12
637 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.r13], r13
638 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.r14], r14
639 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.r15], r15
640%endif
641 str [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.tr]
642 sldt [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.ldtr]
643 mov sAX, cr0
644 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.cr0], sAX
645 mov sAX, cr2
646 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.cr2], sAX
647 mov sAX, cr3
648 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.cr3], sAX
649 mov sAX, cr4
650 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.cr4], sAX
651
652%if TMPL_BITS != 64
653 ; Deal with extended v8086 frame.
654 %if TMPL_BITS == 32
655 test dword [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.rflags], X86_EFL_VM
656 jz .save_context_full_return
657 %else
658 mov al, VAR_CALLER_MODE
659 and al, BS3_MODE_CODE_MASK
660 cmp al, BS3_MODE_CODE_V86
661 jne .save_context_full_return
662 mov dword [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.rflags], X86_EFL_VM
663 %endif
664 mov xAX, [xBP + xCB*4]
665 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.rsp], xAX
666 mov ax, [xBP + xCB*5]
667 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.ss], ax
668 mov ax, [xBP + xCB*6]
669 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.es], ax
670 mov ax, [xBP + xCB*7]
671 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.ds], ax
672 mov ax, [xBP + xCB*8]
673 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.fs], ax
674 mov ax, [xBP + xCB*9]
675 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.gs], ax
676 mov byte [BS3_NOT_64BIT(ss:) xBX + BS3REGCTX.bCpl], 3
677 jmp .save_context_full_return
678
679%endif ; !64-bit
680
681.save_context_full_return:
682 ret
683
684
685BS3_PROC_END_MODE Bs3TrapSystemCallHandler
686
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