VirtualBox

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

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

bs3kit: To be continued...

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.7 KB
Line 
1; $Id: bs3-mode-TrapSystemCallHandler.asm 59952 2016-03-08 10:56:04Z 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%include "bs3kit-template-header.mac"
28
29
30BS3_EXTERN_DATA16 g_bBs3CurrentMode
31BS3_EXTERN_DATA16 g_uBs3CpuDetected
32TMPL_BEGIN_TEXT
33
34
35;;
36; System call handler.
37;
38; This is an assembly trap handler that is called in response to a system call
39; request from 'user' code. The only fixed parameter is [ER]AX which contains
40; the system call number. Other registers are assigned on a per system call
41; basis, ditto for which registers are preserved and which are used to return
42; stuff. Generally, though, we preserve all registers not used as return
43; values or otherwise implicitly transformed by the call.
44;
45BS3_PROC_BEGIN_MODE Bs3TrapSystemCallHandler
46 push xBP
47 mov xBP, xSP
48%ifndef TMPL_64BIT
49 %define VAR_CALLER_DS [xBP - xCB]
50 push ds
51 %ifdef TMPL_CMN_R86
52 push BS3DATA16
53 %else
54 push RT_CONCAT(BS3_SEL_R0_DS,TMPL_BITS)
55 %endif
56 pop ds
57 %define VAR_CALLER_BP [xBP]
58 %define VAR_CALLER_DS [xBP - - xCB]
59 %define VAR_CALLER_BX [xBP - xCB*1 - xCB]
60 %define VAR_CALLER_AX [xBP - xCB*2 - xCB]
61 %define VAR_CALLER_CX [xBP - xCB*3 - xCB]
62 %define VAR_CALLER_DX [xBP - xCB*4 - xCB]
63 %define VAR_CALLER_MODE [xBP - xCB*5 - xCB]
64%else
65 %define VAR_CALLER_BP [xBP]
66 %define VAR_CALLER_BX [xBP - xCB*1]
67 %define VAR_CALLER_AX [xBP - xCB*2]
68 %define VAR_CALLER_CX [xBP - xCB*3]
69 %define VAR_CALLER_DX [xBP - xCB*4]
70 %define VAR_CALLER_MODE [xBP - xCB*5]
71%endif
72 push xBX
73 push xAX
74 push xCX
75 push xDX
76
77 ; VAR_CALLER_MODE: Save the current mode (important for v8086 with 16-bit kernel).
78 xor xBX, xBX
79 mov bl, [g_bBs3CurrentMode]
80 push xBX
81
82 ;
83 ; Dispatch the system call.
84 ;
85 cmp ax, BS3_SYSCALL_LAST
86 ja .invalid_syscall
87%ifdef TMPL_16BIT
88 mov bx, ax
89 shl bx, 1
90 jmp word [cs:.aoffSyscallHandlers + bx]
91%else
92 movzx ebx, ax
93 mov ebx, [.aoffSyscallHandlers + ebx * 4]
94 jmp xBX
95%endif
96.aoffSyscallHandlers:
97%ifdef TMPL_16BIT
98 dw .invalid_syscall wrt BS3TEXT16
99 dw .print_chr wrt BS3TEXT16
100 dw .print_str wrt BS3TEXT16
101 dw .to_ring0 wrt BS3TEXT16
102 dw .to_ring1 wrt BS3TEXT16
103 dw .to_ring2 wrt BS3TEXT16
104 dw .to_ring3 wrt BS3TEXT16
105%else
106 dd .invalid_syscall wrt FLAT
107 dd .print_chr wrt FLAT
108 dd .print_str wrt FLAT
109 dd .to_ring0 wrt FLAT
110 dd .to_ring1 wrt FLAT
111 dd .to_ring2 wrt FLAT
112 dd .to_ring3 wrt FLAT
113%endif
114
115 ;
116 ; Invalid system call.
117 ;
118.invalid_syscall:
119 int3
120 jmp .return
121
122 ;
123 ; Print char in the CL register.
124 ;
125 ; We use the vga bios teletype interrupt to do the writing, so we must
126 ; be in some kind of real mode for this to work. 16-bit code segment
127 ; requried for the mode switching code.
128 ;
129%ifndef TMPL_16BIT
130BS3_BEGIN_TEXT16
131 BS3_SET_BITS TMPL_BITS
132%endif
133.print_chr:
134%ifndef TMPL_CMN_R86
135 ; Switch to real mode (20h param scratch area not required).
136 extern TMPL_NM(Bs3SwitchToRM)
137 call TMPL_NM(Bs3SwitchToRM)
138 BS3_SET_BITS 16
139%endif
140
141 ; Print the character.
142 mov bx, 0ff00h
143 mov al, cl
144 mov ah, 0eh
145 int 10h
146
147%ifndef TMPL_CMN_R86
148 ; Switch back (20h param scratch area not required).
149 extern RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_rm)
150 call RT_CONCAT3(_Bs3SwitchTo,TMPL_MODE_UNAME,_rm)
151 BS3_SET_BITS TMPL_BITS
152%endif
153 jmp .return
154%ifndef TMPL_16BIT
155TMPL_BEGIN_TEXT
156%endif
157
158 ;
159 ; Print CX chars from string pointed to by DX:SI in 16-bit and v8086 mode,
160 ; and ESI/RSI in 64-bit and 32-bit mode (flat).
161 ;
162 ; We use the vga bios teletype interrupt to do the writing, so we must
163 ; be in some kind of real mode for this to work. 16-bit code segment
164 ; requried for the mode switching code.
165 ;
166.print_str:
167 push xSI ; we setup ds:xSI to point to the thing.
168%if TMPL_BITS != 64
169 mov bl, byte VAR_CALLER_MODE
170 and bl, BS3_MODE_CODE_MASK
171 cmp bl, BS3_MODE_CODE_V86
172 jne .print_str_not_v8086
173 ;; @todo this gets complicated _fast_. Later.
174.print_str_not_v8086:
175%endif
176 int3
177 jmp .return
178
179
180 ;
181 ; Switch the caller to ring-0.
182 ;
183.to_ring0:
184 sub xSP, BS3REGS_size
185 mov xBX, xSP ; xBP = BS3REGS pointer.
186 call .save_context
187
188
189 jmp .return
190
191;; @todo the remainder could be implemented in client code using SwitchToRing0
192.to_ring1:
193 int3
194 jmp .return
195
196.to_ring2:
197 int3
198 jmp .return
199
200.to_ring3:
201 int3
202 jmp .return
203
204
205 ;
206 ; Return.
207 ;
208.return:
209 pop xBX ; saved mode
210%if TMPL_BITS == 16
211 and bl, BS3_MODE_CODE_MASK
212 cmp bl, BS3_MODE_CODE_V86
213 je .return_to_v8086_from_16bit_krnl
214%endif
215 pop xDX
216 pop xCX
217 pop xAX
218 pop xBX
219%ifndef TMPL_64BIT
220 pop ds
221%endif
222 leave
223%ifdef TMPL_64BIT
224 iretq
225%else
226 iret
227%endif
228
229%if TMPL_BITS == 16
230.return_to_v8086_from_16bit_krnl:
231 int3
232 jmp .return_to_v8086_from_16bit_krnl
233%endif
234
235
236
237 ;
238 ; Internal function. ss:xBX = Pointer to register frame (BS3REGS).
239 ; @uses xAX
240 ;
241.save_context:
242%if TMPL_BITS == 16
243 cmp byte [g_uBs3CpuDetected], BS3CPU_80386
244 jae .save_context_full
245
246 ;
247 ; 80286 or earlier.
248 ;
249
250 ; Clear the state area first.
251 push di
252 xor di, di
253.save_context_16_clear_loop:
254 mov word [ss:bx + di], 0
255 mov word [ss:bx + di + 2], 0
256 mov word [ss:bx + di + 4], 0
257 mov word [ss:bx + di + 6], 0
258 add di, 8
259 cmp di, BS3REGS_size
260 jb .save_context_16_clear_loop
261 pop di
262
263 ; Do the 8086/80186/80286 state saving.
264 mov ax, VAR_CALLER_AX
265 mov [ss:bx + BS3REGS.rax], ax
266 mov cx, VAR_CALLER_CX
267 mov [ss:bx + BS3REGS.rcx], ax
268 mov ax, VAR_CALLER_DX
269 mov [ss:bx + BS3REGS.rdx], ax
270 mov ax, VAR_CALLER_BX
271 mov [ss:bx + BS3REGS.rbx], ax
272 mov [ss:bx + BS3REGS.rsi], si
273 mov [ss:bx + BS3REGS.rdi], di
274 mov ax, VAR_CALLER_BP
275 mov [ss:bx + BS3REGS.rbp], ax
276 mov [ss:bx + BS3REGS.es], es
277 mov ax, [xBP + xCB]
278 mov [ss:bx + BS3REGS.rip], ax
279 mov ax, [xBP + xCB*2]
280 mov [ss:bx + BS3REGS.cs], ax
281 and al, X86_SEL_RPL
282 mov [ss:bx + BS3REGS.bCpl], al
283 cmp al, 0
284 je .save_context_16_same
285 mov ax, [xBP + xCB*4]
286 mov [ss:bx + BS3REGS.rsp], ax
287 mov ax, [xBP + xCB*5]
288 mov [ss:bx + BS3REGS.ss], ax
289 jmp .save_context_16_done_stack
290.save_context_16_same:
291 mov ax, bp
292 add ax, xCB * (1 + 3)
293 mov [ss:bx + BS3REGS.rsp], ax
294 mov ax, ss
295 mov [ss:bx + BS3REGS.ss], ax
296.save_context_16_done_stack:
297 mov ax, [xBP + xCB*3]
298 mov [ss:bx + BS3REGS.rflags], ax
299 mov al, VAR_CALLER_MODE
300 mov [ss:bx + BS3REGS.bMode], al
301 cmp byte [g_uBs3CpuDetected], BS3CPU_80286
302 jne .save_context_16_return
303 smsw [ss:bx + BS3REGS.cr0]
304 str [ss:bx + BS3REGS.tr]
305 sldt [ss:bx + BS3REGS.ldtr]
306.save_context_16_return:
307 ret
308%endif ; TMPL_BITS == 16
309
310 ;
311 ; 80386 or later.
312 ;
313.save_context_full:
314
315 ; Clear the state area first unless 64-bit mode.
316%if TMPL_BITS != 64
317 push xDI
318 xor xDI, xDI
319.save_context_32_clear_loop:
320 mov dword [ss:xBX + xDI], 0
321 mov dword [ss:xBX + xDI + 4], 0
322 add xDI, 8
323 cmp xDI, BS3REGS_size
324 jb .save_context_32_clear_loop
325 pop xDI
326%endif
327
328 ; Do the 386+ state saving.
329%if TMPL_BITS == 16 ; save the high word of registered pushed on the stack.
330 mov [ss:bx + BS3REGS.rax], eax
331 mov [ss:bx + BS3REGS.rcx], ecx
332 mov [ss:bx + BS3REGS.rdx], edx
333 mov [ss:bx + BS3REGS.rbx], ebx
334 mov [ss:bx + BS3REGS.rbp], ebp
335 mov [ss:bx + BS3REGS.rsp], esp
336%endif
337 mov xAX, VAR_CALLER_AX
338 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.rax], xAX
339 mov xCX, VAR_CALLER_CX
340 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.rcx], xCX
341 mov xAX, VAR_CALLER_DX
342 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.rdx], xAX
343 mov xAX, VAR_CALLER_BX
344 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.rbx], xAX
345 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.rsi], sSI
346 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.rdi], sDI
347 mov xAX, VAR_CALLER_BP
348 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.rbp], xAX
349 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.es], es
350 mov xAX, [xBP + xCB]
351 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.rip], xAX
352 mov ax, [xBP + xCB*2]
353 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.cs], ax
354%if TMPL_MODE != BS3_MODE_RM
355 and al, X86_SEL_RPL
356 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.bCpl], al
357 cmp al, 0
358 je .save_context_full_same
359 mov xAX, [xBP + xCB*4]
360 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.rsp], xAX
361 mov ax, [xBP + xCB*5]
362 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.ss], ax
363 jmp .save_context_full_done_stack
364%else
365 mov byte [BS3_NOT_64BIT(ss:) xBX + BS3REGS.bCpl], 0
366%endif
367.save_context_full_same:
368 mov xAX, xBP
369 add xAX, xCB * (1 + 3)
370 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.rsp], xAX
371 mov ax, ss
372 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.ss], ax
373.save_context_full_done_stack:
374 mov xAX, [xBP + xCB*3]
375 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.rflags], xAX
376 mov al, VAR_CALLER_MODE
377 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.bMode], al
378%if TMPL_BITS == 64
379 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.r8], r8
380 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.r9], r9
381 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.r10], r10
382 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.r11], r11
383 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.r12], r12
384 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.r13], r13
385 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.r14], r14
386 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.r15], r15
387%endif
388 ; Save state according to detected CPU.
389 str [BS3_NOT_64BIT(ss:) xBX + BS3REGS.tr]
390 sldt [BS3_NOT_64BIT(ss:) xBX + BS3REGS.ldtr]
391 cmp byte [g_uBs3CpuDetected], BS3CPU_80286
392 ja .save_context_full_return
393 smsw [BS3_NOT_64BIT(ss:) xBX + BS3REGS.cr0]
394 jmp .save_context_full_return
395
396.save_context_full_386_plus:
397 mov sAX, cr0
398 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.cr0], sAX
399 mov sAX, cr2
400 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.cr2], sAX
401 mov sAX, cr3
402 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.cr3], sAX
403 mov sAX, cr4
404 mov [BS3_NOT_64BIT(ss:) xBX + BS3REGS.cr4], sAX
405
406.save_context_full_return:
407 ret
408
409
410BS3_PROC_END_MODE Bs3TrapSystemCallHandler
411
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