VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bootsector2-common-init-traps.mac@ 77807

Last change on this file since 77807 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 54.8 KB
Line 
1; $Id: bootsector2-common-init-traps.mac 76553 2019-01-01 01:45:53Z vboxsync $
2;; @file
3; Common bootsector code init, traps.
4;
5; This is included from bootsector2-common-init-code.mac and was split out of
6; that file to keep the size manageable.
7;
8
9;
10; Copyright (C) 2007-2019 Oracle Corporation
11;
12; This file is part of VirtualBox Open Source Edition (OSE), as
13; available from http://www.virtualbox.org. This file is free software;
14; you can redistribute it and/or modify it under the terms of the GNU
15; General Public License (GPL) as published by the Free Software
16; Foundation, in version 2 as it comes in the "COPYING" file of the
17; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
18; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19;
20; The contents of this file may alternatively be used under the terms
21; of the Common Development and Distribution License Version 1.0
22; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
23; VirtualBox OSE distribution, in which case the provisions of the
24; CDDL are applicable instead of those of the GPL.
25;
26; You may elect to license modified versions of this file under the
27; terms and conditions of either the GPL or the CDDL or both.
28;
29
30%ifndef BS2_WITH_TRAPS
31 %error "huh? BS2_WITH_TRAPS is not defined!"
32%endif
33
34
35;*******************************************************************************
36;* Header Files *
37;*******************************************************************************
38%include "bootsector2-structures.mac"
39%include "bootsector2-api.mac"
40
41
42;*******************************************************************************
43;* Global Variables *
44;*******************************************************************************
45BEGINCODELOW
46ALIGNDATA(8)
47;; Where to resume execution after a trap (if g_fTrapPrepared is set).
48; @internal
49g_TrapResumeRIP:
50 dq 0
51;; Set if we've prepared for a trap.
52; @internal
53g_fTrapPrepared:
54 db 0
55;; Benchmark indicator.
56; This is set to the expected trap number when we're benchmarking and 0ffh when
57; we aren't benchmarking.
58; @internal
59g_u8TrapBenchmarkNo:
60 db 0ffh
61 db 0 ; alignment padding.
62;; The last trap number.
63GLOBALNAME g_u8LastTrapNo
64 db 0
65;; The number of traps since last call to Bs2TrapReset.
66GLOBALNAME g_u32cTraps
67 dd 0
68;; The last trap error code.
69GLOBALNAME g_u64LastTrapErr
70 dq 0
71;; The register frame of the last trap (BS2REGS).
72GLOBALNAME g_LastTrapRegs
73 times (BS2REGS_size) db 0
74
75;; The RFLAGS/EFLAGS inside last invoked trap handler.
76GLOBALNAME g_u64LastTrapHandlerRFlags
77 dq 0
78;; The CS inside last invoked trap handler.
79GLOBALNAME g_u16LastTrapHandlerCS
80 dw 0
81;; The SS inside last invoked trap handler.
82GLOBALNAME g_u16LastTrapHandlerSS
83 dw 0
84 dw 0,0 ; alignment
85;; The RSP inside the last invoked trap handler, i.e. when bs2Trap_XX_32bit is
86; entered, so including fake error code and vector number.
87GLOBALNAME g_u64LastTrapHandlerRSP
88 dq 0
89
90;;
91; Pointer to an array of BS2TRAPREC1 records.
92GLOBALNAME g_paTrapRecs
93 dq 0
94;; Number of entries in the array g_paTrapRecs points to.
95GLOBALNAME g_cTrapRecs
96 dd 0
97;; The index of the last BS2TRAPREC1 we hit.
98GLOBALNAME g_iTrapRecLast
99 dd 0
100;; The base address the BS2TRAPREC.offWhere values are relative to.
101GLOBALNAME g_pTrapRecBase
102 dq 0
103
104
105;;
106; Reset all the trap globals to default.
107;
108; This undos the effect of any previous Bs2TrapPrepare call.
109;
110; @uses nothing.
111;
112BEGINCODELOW
113BITS 16
114BEGINPROC Bs2TrapReset_rm16
115 push xBP
116 mov xBP, xSP
117 push ds
118 push word 0
119 pop ds
120
121 mov dword [g_u32cTraps], 0
122 mov byte [g_u8LastTrapNo], 0ffh
123 mov dword [g_u64LastTrapErr], 0
124 mov dword [g_u64LastTrapErr + 4], 0
125 mov dword [g_TrapResumeRIP], 0
126 mov dword [g_TrapResumeRIP + 4], 0
127 mov byte [g_u8TrapBenchmarkNo], 0ffh
128 mov byte [g_fTrapPrepared], 0
129
130 pop ds
131 leave
132 ret
133ENDPROC Bs2TrapReset_rm16
134
135
136;;
137; Reset all the trap globals to default.
138;
139; This undos the effect of any previous Bs2TrapPrepare call.
140;
141; @uses nothing.
142;
143BEGINCODELOW
144BITS 16
145BEGINPROC Bs2TrapReset_p16
146 push ds
147 push BS2_SEL_DS16
148 pop ds
149
150 mov dword [g_u32cTraps], 0
151 mov byte [g_u8LastTrapNo], 0ffh
152 mov dword [g_u64LastTrapErr], 0
153 mov dword [g_u64LastTrapErr + 4], 0
154 mov dword [g_TrapResumeRIP], 0
155 mov dword [g_TrapResumeRIP + 4], 0
156 mov byte [g_u8TrapBenchmarkNo], 0ffh
157 mov byte [g_fTrapPrepared], 0
158
159 pop ds
160 ret
161ENDPROC Bs2TrapReset_p16
162
163
164
165;;
166; Reset all the trap globals to default.
167;
168; This undos the effect of any previous Bs2TrapPrepare call.
169;
170; @uses nothing.
171;
172BEGINCODEHIGH
173BITS 32
174BEGINPROC Bs2TrapReset_p32
175 push ds
176 push BS2_SEL_DS32
177 pop ds
178
179 mov dword [g_u32cTraps], 0
180 mov byte [g_u8LastTrapNo], 0ffh
181 mov dword [g_u64LastTrapErr], 0
182 mov dword [g_u64LastTrapErr + 4], 0
183 mov dword [g_TrapResumeRIP], 0
184 mov dword [g_TrapResumeRIP + 4], 0
185 mov byte [g_u8TrapBenchmarkNo], 0ffh
186 mov byte [g_fTrapPrepared], 0
187
188 pop ds
189 ret
190ENDPROC Bs2TrapReset_p32
191
192
193;;
194; Reset all the trap globals to default.
195;
196; This undos the effect of any previous Bs2TrapPrepare call.
197;
198; @uses nothing.
199;
200BEGINCODEHIGH
201BITS 64
202BEGINPROC Bs2TrapReset_p64
203 mov dword [g_u32cTraps], 0
204 mov byte [g_u8LastTrapNo], 0ffh
205 mov qword [g_u64LastTrapErr], 0
206 mov qword [g_TrapResumeRIP], 0
207 mov byte [g_u8TrapBenchmarkNo], 0ffh
208 mov byte [g_fTrapPrepared], 0
209 ret
210ENDPROC Bs2TrapReset_p64
211
212
213
214;;
215; Prepare for a test that will trap.
216;
217; @param xAX Where to resume after the trap.
218; @param dl Set to 0ffh for tests and the expected trap number when
219; preparing a benchmark.
220; @uses nothing.
221;
222BEGINCODELOW
223BITS 16
224BEGINPROC Bs2TrapPrepare_rm16
225 push xBP
226 mov xBP, xSP
227 push ds
228 push word 0
229 pop ds
230
231 mov dword [g_u32cTraps], 0
232 mov byte [g_u8LastTrapNo], 0ffh
233 mov dword [g_u64LastTrapErr], 0
234 mov dword [g_u64LastTrapErr + 4], 0
235 mov word [g_TrapResumeRIP], ax
236 mov word [g_TrapResumeRIP + 2], 0
237 mov dword [g_TrapResumeRIP + 4], 0
238 mov byte [g_u8TrapBenchmarkNo], dl
239 mov byte [g_fTrapPrepared], 1
240
241 pop ds
242 leave
243 ret
244ENDPROC Bs2TrapPrepare_rm16
245
246
247;;
248; Prepare for a test that will trap.
249;
250; @param ax Where to resume after the trap.
251; @param dl Set to 0ffh for tests and the expected trap number when
252; preparing a benchmark.
253; @uses nothing.
254;
255BEGINCODELOW
256BITS 16
257BEGINPROC Bs2TrapPrepare_p16
258 push ds
259 push BS2_SEL_DS16
260 pop ds
261
262 mov dword [g_u32cTraps], 0
263 mov byte [g_u8LastTrapNo], 0ffh
264 mov dword [g_u64LastTrapErr], 0
265 mov dword [g_u64LastTrapErr + 4], 0
266 mov word [g_TrapResumeRIP], ax
267 mov word [g_TrapResumeRIP + 2], 0
268 mov dword [g_TrapResumeRIP + 4], 0
269 mov byte [g_u8TrapBenchmarkNo], dl
270 mov byte [g_fTrapPrepared], 1
271
272 pop ds
273 ret
274ENDPROC Bs2TrapPrepare_p16
275
276
277;;
278; Prepare for a test that will trap.
279;
280; @param eax Where to resume after the trap.
281; @param dl Set to 0ffh for tests and the expected trap number when
282; preparing a benchmark.
283; @uses nothing.
284;
285BEGINCODEHIGH
286BITS 32
287BEGINPROC Bs2TrapPrepare_p32
288 push ds
289 push BS2_SEL_DS32
290 pop ds
291
292 mov dword [g_u32cTraps], 0
293 mov byte [g_u8LastTrapNo], 0ffh
294 mov dword [g_u64LastTrapErr], 0
295 mov dword [g_u64LastTrapErr + 4], 0
296 mov dword [g_TrapResumeRIP], eax
297 mov dword [g_TrapResumeRIP + 4], 0
298 mov byte [g_u8TrapBenchmarkNo], dl
299 mov byte [g_fTrapPrepared], 1
300
301 pop ds
302 ret
303ENDPROC Bs2TrapPrepare_p32
304
305
306;;
307; Prepare for a test that will trap.
308;
309; @param rax Where to resume after the trap.
310; @param dl Set to 0ffh for tests and the expected trap number when
311; preparing a benchmark.
312; @uses nothing.
313;
314BEGINCODEHIGH
315BITS 64
316BEGINPROC Bs2TrapPrepare_p64
317 mov dword [g_u32cTraps], 0
318 mov byte [g_u8LastTrapNo], 0ffh
319 mov qword [g_u64LastTrapErr], 0
320 mov qword [g_TrapResumeRIP], rax
321 mov byte [g_u8TrapBenchmarkNo], dl
322 mov byte [g_fTrapPrepared], 1
323 ret
324ENDPROC Bs2TrapPrepare_p64
325
326
327BEGINCODELOW ; The TSSes, IDTs and handlers must be 16-bit addressable.
328
329%ifdef BS2_INC_CMN_PM
330;
331; 32-bit TSS (X86TSS32).
332;
333ALIGNDATA(16)
334bs2Tss32Bit:
335 dw 07fffh ; selPrev - Back link to previous task. (static)
336 dw 0h ; padding1;
337 dd BS2_R0_STACK_ADDR ; esp0 - Ring-0 stack pointer. (static)
338 dw BS2_SEL_SS32 ; ss0
339 dw 0 ; padding
340 dd BS2_R1_STACK_ADDR ; esp1 - Ring-1 stack pointer. (static)
341 dw 0 ; ss1
342 dw 0 ; padding
343 dd BS2_R2_STACK_ADDR ; esp2 - Ring-1 stack pointer. (static)
344 dw 0 ; ss2
345 dw 0 ; padding
346 dd 0ffffffffh ; cr3 - Page directory for the task. (static)
347 dd 0 ; eip - EIP before task switch.
348 dd 0 ; eflags - EFLAGS before task switch.
349 dd 0 ; eax - EAX before task switch.
350 dd 0 ; ecx - ECX before task switch.
351 dd 0 ; edx - EDX before task switch.
352 dd 0 ; ebx - EBX before task switch.
353 dd 0 ; esp - ESP before task switch.
354 dd 0 ; ebp - EBP before task switch.
355 dd 0 ; esi - ESI before task switch.
356 dd 0 ; edi - EDI before task switch.
357 dw 0, 0 ; es,pad - ES before task switch.
358 dw 0, 0 ; cs,pad - CS before task switch.
359 dw 0, 0 ; ss,pad - SS before task switch.
360 dw 0, 0 ; ds,pad - DS before task switch.
361 dw 0, 0 ; fs,pad - FS before task switch.
362 dw 0, 0 ; gs,pad - GS before task switch.
363 dw 0, 0 ; ldt,pad - LDTR before task switch.
364 dw 0 ; fDebugTrap - Debug trap flag.
365 dw 7fffh ; offIoBitmap - Offset relative to the TSS of the
366 ; start of the I/O Bitmap and the end of the
367 ; interrupt redirection bitmap.
368 ; IntRedirBitmap - 32 bytes for the virtual interrupt redirection bitmap. (VME)
369bs2Tss32BitEnd:
370times (68h - (bs2Tss32BitEnd - bs2Tss32Bit)) db 0
371times ((bs2Tss32BitEnd - bs2Tss32Bit) - 68h) db 0
372
373
374;
375; 32-bit TSS for #DF (X86TSS32).
376;
377ALIGNDATA(16)
378bs2Tss32BitDf:
379 dw 07fffh ; selPrev - Back link to previous task. (static)
380 dw 0h ; padding1;
381 dd BS2_DF_R0_STACK_ADDR ; esp0 - Ring-0 stack pointer. (static)
382 dw BS2_SEL_SS32 ; ss0
383 dw 0 ; padding
384 dd 0 ; esp1 - Ring-1 stack pointer. (static)
385 dw 0 ; ss1
386 dw 0 ; padding
387 dd 0 ; esp2 - Ring-1 stack pointer. (static)
388 dw 0 ; ss2
389 dw 0 ; padding
390 dd 0ffffffffh ; cr3 - Page directory for the task. (static)
391 dd bs2Trap_08h_32bit ; eip - EIP before task switch. */
392 dd 0 ; eflags - EFLAGS before task switch. */
393 dd 0 ; eax - EAX before task switch. */
394 dd 0 ; ecx - ECX before task switch. */
395 dd 0 ; edx - EDX before task switch. */
396 dd 0 ; ebx - EBX before task switch. */
397 dd BS2_DF_R0_STACK_ADDR ; esp - ESP before task switch. */
398 dd 0 ; ebp - EBP before task switch. */
399 dd 0 ; esi - ESI before task switch. */
400 dd 0 ; edi - EDI before task switch. */
401 dw BS2_SEL_DS32, 0 ; es,pad - ES before task switch. */
402 dw BS2_SEL_CS32, 0 ; cs,pad - CS before task switch. */
403 dw BS2_SEL_SS32, 0 ; ss,pad - SS before task switch. */
404 dw BS2_SEL_DS32, 0 ; ds,pad - DS before task switch. */
405 dw BS2_SEL_DS32, 0 ; fs,pad - FS before task switch. */
406 dw BS2_SEL_DS32, 0 ; gs,pad - GS before task switch. */
407 dw 0, 0 ; ldt,pad- LDTR before task switch. */
408 dw 0 ; fDebugTrap - Debug trap flag.
409 dw 7fffh ; offIoBitmap - Offset relative to the TSS of the
410 ; start of the I/O Bitmap and the end of the
411 ; interrupt redirection bitmap.
412 ; IntRedirBitmap - 32 bytes for the virtual interrupt redirection bitmap. (VME)
413bs2Tss32BitDfEnd:
414times (68h - (bs2Tss32BitDfEnd - bs2Tss32BitDf)) db 0
415times ((bs2Tss32BitDfEnd - bs2Tss32BitDf) - 68h) db 0
416
417
418;
419; 32-bit IDT (X86DESCGATE).
420;
421ALIGNDATA(16)
422bs2Idt32bit:
423 dw bs2Trap_00h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
424 dw bs2Trap_01h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
425 dw bs2Trap_02h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
426bs2Idt32bit_BP:
427 dw bs2Trap_03h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
428 dw bs2Trap_04h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
429 dw bs2Trap_05h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
430 dw bs2Trap_06h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
431 dw bs2Trap_07h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
432 dw 0, BS2_SEL_TSS32_DF, 08500h, 00000h ; p=1 dpl=0 type=taskgate
433 dw bs2Trap_09h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
434 dw bs2Trap_0ah_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
435 dw bs2Trap_0bh_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
436 dw bs2Trap_0ch_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
437 dw bs2Trap_0dh_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
438 dw bs2Trap_0eh_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
439 dw bs2Trap_0fh_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
440 dw bs2Trap_10h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
441 dw bs2Trap_11h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
442 dw bs2Trap_12h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
443 dw bs2Trap_13h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
444 dw bs2Trap_14h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
445 dw bs2Trap_15h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
446 dw bs2Trap_16h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
447 dw bs2Trap_17h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
448 dw bs2Trap_18h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
449 dw bs2Trap_19h_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
450 dw bs2Trap_1ah_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
451 dw bs2Trap_1bh_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
452 dw bs2Trap_1ch_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
453 dw bs2Trap_1dh_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
454 dw bs2Trap_1eh_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
455 dw bs2Trap_1fh_32bit, BS2_SEL_CS32, 08e00h, 00000h ; p=1 dpl=0 type=int32gate
456 dw bs2TrapService32bit,BS2_SEL_CS32,0ee00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=3 type=int32gate
457%define BS2_TRAP_SERVICE_NO 30h
458;; @todo
459bs2Idt32bitEnd
460
461;
462; 32-bit trap handlers.
463;
464BITS 32
465%macro bs2Trap_XX_32bit_macro 1
466bs2Trap_ %+ %1 %+ _32bit:
467 push %1
468 jmp bs2Trap_XX_32bit
469%endmacro
470%macro bs2Trap_XX_32bit_macro_no_err 1
471bs2Trap_ %+ %1 %+ _32bit:
472 push 0
473 push %1
474 jmp bs2Trap_XX_32bit
475%endmacro
476 bs2Trap_XX_32bit_macro_no_err 00h
477 bs2Trap_XX_32bit_macro_no_err 01h
478 bs2Trap_XX_32bit_macro_no_err 02h
479 bs2Trap_XX_32bit_macro_no_err 03h
480 bs2Trap_XX_32bit_macro_no_err 04h
481 bs2Trap_XX_32bit_macro_no_err 05h
482 bs2Trap_XX_32bit_macro_no_err 06h
483 bs2Trap_XX_32bit_macro_no_err 07h
484 bs2Trap_XX_32bit_macro 08h
485 bs2Trap_XX_32bit_macro_no_err 09h
486 bs2Trap_XX_32bit_macro 0ah
487 bs2Trap_XX_32bit_macro 0bh
488 bs2Trap_XX_32bit_macro 0ch
489 bs2Trap_XX_32bit_macro 0dh
490 bs2Trap_XX_32bit_macro 0eh
491 bs2Trap_XX_32bit_macro_no_err 0fh
492 bs2Trap_XX_32bit_macro_no_err 10h
493 bs2Trap_XX_32bit_macro 11h
494 bs2Trap_XX_32bit_macro_no_err 12h
495 bs2Trap_XX_32bit_macro_no_err 13h
496 bs2Trap_XX_32bit_macro_no_err 14h
497 bs2Trap_XX_32bit_macro_no_err 15h
498 bs2Trap_XX_32bit_macro_no_err 16h
499 bs2Trap_XX_32bit_macro_no_err 17h
500 bs2Trap_XX_32bit_macro_no_err 18h
501 bs2Trap_XX_32bit_macro_no_err 19h
502 bs2Trap_XX_32bit_macro_no_err 1ah
503 bs2Trap_XX_32bit_macro_no_err 1bh
504 bs2Trap_XX_32bit_macro_no_err 1ch
505 bs2Trap_XX_32bit_macro_no_err 1dh
506 bs2Trap_XX_32bit_macro_no_err 1eh
507 bs2Trap_XX_32bit_macro_no_err 1fh
508
509;;
510; Common 32-bit trap handler.
511;
512; return GS ebp + 2ch - v86
513; return FS ebp + 28h - v86
514; return DS ebp + 24h - v86
515; return ES ebp + 20h - v86
516; return SS ebp + 1ch - higher privilege
517; return ESP ebp + 18h - higher privilege
518; return EFLAGS ebp + 14h
519; return CS ebp + 10h
520; return EIP ebp + 0ch
521; error code ebp + 08h
522; vector # ebp + 04h
523BITS 32
524BEGINCODEHIGH
525BEGINPROC bs2Trap_XX_32bit
526 push ebp ; ebp + 00h
527 mov ebp, esp
528 pushfd ; ebp - 04h
529 push eax ; ebp - 08h
530 push ebx ; ebp - 0ch
531 push ecx ; ebp - 10h
532 push ds ; ebp - 14h
533
534 mov eax, ss ; load flat DS. Using SS here because of conforming IDTE.CS tests.
535 mov ds, ax
536
537 pushfd ; Clear the AC flag.
538 and dword [esp], ~X86_EFL_AC
539 popfd
540
541 ;
542 ; Benchmark mode? Then resume the action right away!
543 ;
544 mov eax, [ebp + 04h]
545 cmp [g_u8TrapBenchmarkNo], al
546 jne .test_mode
547 cmp byte [g_fTrapPrepared], 0
548 je .test_mode
549 mov eax, [g_TrapResumeRIP]
550 mov [ebp + 0ch], eax
551
552 pop ds
553 pop ecx
554 pop ebx
555 ;pop eax
556 ;popfd
557 leave
558 add esp, 08h ; Skip the vector # and error code.
559 xor eax, eax
560 iret
561
562
563 ;
564 ; Update the globals.
565 ;
566.test_mode:
567 xor ecx, ecx ; zero register
568 inc dword [g_u32cTraps]
569 mov eax, [ebp + 04h]
570 mov [g_u8LastTrapNo], al
571 mov eax, [ebp + 08h]
572 mov [g_u64LastTrapErr], eax
573 mov [g_u64LastTrapErr + 4], ecx
574 mov eax, [ebp - 04h]
575 mov [g_u64LastTrapHandlerRFlags], eax
576 mov dword [g_u64LastTrapHandlerRFlags + 4], ecx
577 mov ax, cs
578 mov [g_u16LastTrapHandlerCS], ax
579 mov ax, ss
580 mov [g_u16LastTrapHandlerSS], ax
581 lea eax, [ebp + 4]
582 mov [g_u64LastTrapHandlerRSP], eax
583 mov [g_u64LastTrapHandlerRSP + 4], ecx
584
585 ;
586 ; Save the registers.
587 ;
588 lea ebx, [g_LastTrapRegs]
589 mov eax, [ebp - 08h]
590 mov [ebx + BS2REGS.rax], eax
591 mov [ebx + BS2REGS.rax + 4], ecx
592 mov eax, [ebp - 0ch]
593 mov [ebx + BS2REGS.rbx], eax
594 mov [ebx + BS2REGS.rbx + 4], ecx
595 mov eax, [ebp - 10h]
596 mov [ebx + BS2REGS.rcx], eax
597 mov [ebx + BS2REGS.rcx + 4], ecx
598 mov [ebx + BS2REGS.rdx], edx
599 mov [ebx + BS2REGS.rdx + 4], ecx
600 mov [ebx + BS2REGS.rdi], edi
601 mov [ebx + BS2REGS.rdi + 4], ecx
602 mov [ebx + BS2REGS.rsi], esi
603 mov [ebx + BS2REGS.rsi + 4], ecx
604 mov eax, [ebp]
605 mov [ebx + BS2REGS.rbp], eax
606 mov [ebx + BS2REGS.rbp + 4], ecx
607 mov eax, [ebp + 0ch]
608 mov [ebx + BS2REGS.rip], eax
609 mov [ebx + BS2REGS.rip + 4], ecx
610 mov [ebx + BS2REGS.r8], ecx
611 mov [ebx + BS2REGS.r8 + 4], ecx
612 mov [ebx + BS2REGS.r9], ecx
613 mov [ebx + BS2REGS.r9 + 4], ecx
614 mov [ebx + BS2REGS.r10], ecx
615 mov [ebx + BS2REGS.r10 + 4], ecx
616 mov [ebx + BS2REGS.r11], ecx
617 mov [ebx + BS2REGS.r11 + 4], ecx
618 mov [ebx + BS2REGS.r12], ecx
619 mov [ebx + BS2REGS.r12 + 4], ecx
620 mov [ebx + BS2REGS.r13], ecx
621 mov [ebx + BS2REGS.r13 + 4], ecx
622 mov [ebx + BS2REGS.r14], ecx
623 mov [ebx + BS2REGS.r14 + 4], ecx
624 mov [ebx + BS2REGS.r15], ecx
625 mov [ebx + BS2REGS.r15 + 4], ecx
626 mov eax, [ebp + 14h]
627 mov [ebx + BS2REGS.rflags], eax
628 mov [ebx + BS2REGS.rflags+4],ecx
629 mov eax, [ebp + 10h]
630 mov [ebx + BS2REGS.cs], ax
631 mov [ebx + BS2REGS.cBits], byte 32
632
633 ; Part of the stack varies depending on the trap context.
634 test dword [ebx + BS2REGS.rflags], X86_EFL_VM
635 jnz .v86
636 test ax, 7h
637 jz .ring0
638
639.ring0:
640 lea eax, [ebp + 18h]
641 mov [ebx + BS2REGS.rsp], eax
642 mov [ebx + BS2REGS.rsp + 4], ecx
643 mov [ebx + BS2REGS.ss], ss
644 mov eax, [ebp - 14h]
645 mov [ebx + BS2REGS.ds], ax
646 mov [ebx + BS2REGS.es], es
647 mov [ebx + BS2REGS.fs], fs
648 mov [ebx + BS2REGS.gs], gs
649 jmp .do_crX
650
651.higher_privilege:
652 mov eax, [ebp + 18h]
653 mov [ebx + BS2REGS.rsp], eax
654 mov [ebx + BS2REGS.rsp + 4], ecx
655 mov eax, [ebp + 20h]
656 mov [ebx + BS2REGS.ss], ax
657 mov eax, [ebp - 14h]
658 mov [ebx + BS2REGS.ds], ax
659 mov [ebx + BS2REGS.es], es
660 mov [ebx + BS2REGS.fs], fs
661 mov [ebx + BS2REGS.gs], gs
662 jmp .do_crX
663
664.v86:
665 mov eax, [ebp + 18h]
666 mov [ebx + BS2REGS.rsp], eax
667 mov [ebx + BS2REGS.rsp + 4], ecx
668 mov eax, [ebp + 1ch]
669 mov [ebx + BS2REGS.ss], ax
670 mov eax, [ebp + 24h]
671 mov [ebx + BS2REGS.ds], ax
672 mov eax, [ebp + 20h]
673 mov [ebx + BS2REGS.es], ax
674 mov eax, [ebp + 28h]
675 mov [ebx + BS2REGS.fs], ax
676 mov eax, [ebp + 2ch]
677 mov [ebx + BS2REGS.gs], ax
678 ;jmp .do_crX
679
680.do_crX:
681 ; The CRx registers are only accessible from ring-0 (CS=conforming, CPL < 0)
682 test byte [ebx + BS2REGS.ss], 3
683 jnz .skip_crX
684 mov eax, cr0
685 mov [ebx + BS2REGS.cr0], eax
686 mov [ebx + BS2REGS.cr0 + 4], ecx
687 mov eax, cr2
688 mov [ebx + BS2REGS.cr2], eax
689 mov [ebx + BS2REGS.cr2 + 4], ecx
690 mov eax, cr3
691 mov [ebx + BS2REGS.cr3], eax
692 mov [ebx + BS2REGS.cr3 + 4], ecx
693 mov eax, cr4
694 mov [ebx + BS2REGS.cr4], eax
695 mov [ebx + BS2REGS.cr4 + 4], ecx
696 mov [ebx + BS2REGS.cr8], ecx
697 mov [ebx + BS2REGS.cr8 + 4], ecx
698.skip_crX:
699
700 ;
701 ; Advance to a prepared resume position or panic.
702 ;
703 cmp byte [g_fTrapPrepared], 0
704 je .no_resume_pos
705 mov byte [g_fTrapPrepared], 0
706 mov eax, [g_TrapResumeRIP]
707 mov [ebp + 0ch], eax
708
709.resume:
710%ifdef BS2_WITH_XCPT_DB_CLEARING_TF
711 cmp byte [ebp + 04h], X86_XCPT_DB ; make sure we won't trap again due to a TF.
712 jne .resume_no_clear_trap_flags
713 and word [ebp + 14h], ~X86_EFL_TF
714.resume_no_clear_trap_flags:
715%endif
716 pop ds
717 pop ecx
718 pop ebx
719 pop eax
720 ;popfd
721 leave
722 add esp, 8h
723 iret
724
725
726.no_resume_pos:
727 ;
728 ; Look for a trap record.
729 ;
730 mov ecx, [g_cTrapRecs] ; the number of records.
731 test ecx, ecx
732 jz .panic
733 mov eax, [g_LastTrapRegs + BS2REGS.rip]
734 sub eax, [g_pTrapRecBase] ; the offWhere we're looking for.
735 jb .panic
736
737 ; Look starting at the previous record first.
738 mov ebx, [g_iTrapRecLast]
739 sub ecx, ebx
740 jbe .traprec_loop2 ; g_iTrapRecLast is out of range.
741 shl ebx, BS2TRAPREC_SIZE_SHIFT
742 add ebx, [g_paTrapRecs] ; ebx points to the record we hit last time.
743.traprec_loop1_next:
744 cmp [ebx + BS2TRAPREC.offWhere], eax
745 je .traprec_found
746 add ebx, BS2TRAPREC_size
747 dec ecx
748 jnz .traprec_loop1_next
749
750 ; Start searching from the start, stopping at the previous record.
751.traprec_loop2:
752 mov ecx, [g_iTrapRecLast]
753 or ecx, ecx
754 jz .panic ; not found.
755 mov ebx, [g_paTrapRecs]
756.traprec_loop2_next:
757 cmp [ebx + BS2TRAPREC.offWhere], eax
758 je .traprec_found
759 add ebx, BS2TRAPREC_size
760 dec ecx
761 jnz .traprec_loop2_next
762 jmp .panic ; not found
763
764.traprec_found:
765 ; Remember the hit for the next trap.
766 mov eax, ebx
767 sub eax, [g_paTrapRecs]
768 shr eax, BS2TRAPREC_SIZE_SHIFT
769 mov [g_iTrapRecLast], eax
770
771 ;
772 ; Fail the test if we got the wrong trap or error code.
773 ;
774 mov al, [g_u8LastTrapNo]
775 cmp al, [ebx + BS2TRAPREC.u8TrapNo]
776 je .traprec_ok_trap
777 push eax
778 movzx eax, byte [ebx + BS2TRAPREC.u8TrapNo]
779 push eax
780 push .s_szWrongTrap
781 call NAME(TestFailedF_p32)
782 add esp, 12
783
784.traprec_ok_trap:
785 mov ax, [g_u64LastTrapErr]
786 cmp ax, [ebx + BS2TRAPREC.u16ErrCd]
787 je .traprec_ok_err_cd
788 push eax
789 movzx eax, word [ebx + BS2TRAPREC.u16ErrCd]
790 push eax
791 push .s_szWrongErrCd
792 call NAME(TestFailedF_p32)
793 add esp, 12
794
795.traprec_ok_err_cd:
796 ;
797 ; Advance the EIP and resume execution.
798 ;
799 movzx eax, byte [ebx + BS2TRAPREC.offResumeAddend]
800 add eax, [g_LastTrapRegs + BS2REGS.rip]
801 mov [ebp + 0ch], eax
802 jmp .resume
803
804
805 ;
806 ; Write panic message and then halt.
807 ;
808.panic:
809 push dword [g_LastTrapRegs + BS2REGS.rflags]
810 push dword [g_LastTrapRegs + BS2REGS.ss]
811 push dword [g_LastTrapRegs + BS2REGS.gs]
812 push dword [g_LastTrapRegs + BS2REGS.fs]
813 push dword [g_LastTrapRegs + BS2REGS.es]
814 push dword [g_LastTrapRegs + BS2REGS.ds]
815 push dword [g_LastTrapRegs + BS2REGS.cs]
816 ; line break
817 push dword [g_LastTrapRegs + BS2REGS.cr4]
818 push dword [g_LastTrapRegs + BS2REGS.cr3]
819 push dword [g_LastTrapRegs + BS2REGS.cr0]
820 push dword [g_LastTrapRegs + BS2REGS.rbp]
821 push dword [g_LastTrapRegs + BS2REGS.rsp]
822 push dword [g_LastTrapRegs + BS2REGS.rip]
823 ; line break
824 push dword [g_LastTrapRegs + BS2REGS.rdi]
825 push dword [g_LastTrapRegs + BS2REGS.rsi]
826 push dword [g_LastTrapRegs + BS2REGS.rdx]
827 push dword [g_LastTrapRegs + BS2REGS.rcx]
828 push dword [g_LastTrapRegs + BS2REGS.rbx]
829 push dword [g_LastTrapRegs + BS2REGS.rax]
830 ; line break
831 mov eax, [ebp + 08h]
832 push eax
833 mov eax, cr2
834 push eax
835 mov eax, [ebp + 0ch]
836 push eax
837 movzx eax, word [ebp + 10h]
838 push eax
839 movzx eax, byte [ebp + 04h]
840 push eax
841 push .s_szPanicMsg
842 call NAME(TestFailedF_p32)
843
844 call Bs2Panic
845 jmp .panic ; paranoia
846
847.s_szPanicMsg:
848 db 'trap #%RX8 at %RX16:%RX32 cr2=%RX32 err=%RX32', 13, 10
849 db 'eax=%RX32 ebx=%RX32 ecx=%RX32 edx=%RX32 esi=%RX32 edi=%RX32', 13, 10
850 db 'eip=%RX32 esp=%RX32 ebp=%RX32 cr0=%RX32 cr3=%RX32 cr4=%RX32', 13, 10
851 db 'cs=%RX16 ds=%RX16 es=%RX16 fs=%RX16 gs=%RX16 ss=%RX16 eflags=%RX32', 13, 10
852 db 0
853.s_szWrongTrap:
854 db 'Expected trap %RX8 got %RX8', 13, 10, 0
855.s_szWrongErrCd:
856 db 'Expected errcd %RX16 got %RX16', 13, 10, 0
857ENDPROC bs2Trap_XX_32bit
858
859;;
860; Service IRQ handler, 32-bit version.
861;
862; Takes requests in eax and later maybe parameters in other registers.
863;
864; return GS ebp + 24h - v86
865; return FS ebp + 20h - v86
866; return DS ebp + 1ch - v86
867; return ES ebp + 18h - v86
868; return SS ebp + 14h - higher privilege
869; return ESP ebp + 10h - higher privilege
870; return EFLAGS ebp + 0ch
871; return CS ebp + 08h
872; return EIP ebp + 04h
873BEGINCODELOW
874BEGINPROC bs2TrapService32bit
875 jmp .highsegment
876BEGINCODEHIGH
877.highsegment:
878 push ebp ; ebp
879 mov ebp, esp
880 push eax ; ebp - 04h
881 push edx ; ebp - 08h
882 push ecx ; ebp - 0ch
883 push ebx ; ebp - 10h
884 push ds ; ebp - 14h
885
886 mov dx, ss
887 mov ds, dx
888
889 ;
890 ; Classify the caller context in cl.
891 ;; @todo What if CS on the stack is conforming?
892 ;
893%define BS2_TRP_SRV_CALLER_SAME_RING 0
894%define BS2_TRP_SRV_CALLER_OTHER_RING 1
895%define BS2_TRP_SRV_CALLER_VM 2
896 test dword [ebp + 0ch], X86_EFL_VM
897 jnz .vm_ctx
898
899 mov cx, ss
900 mov ch, [ebp + 08h] ; cs
901 and cx, 00303h
902 cmp ch, cl
903 jz .same_ctx
904 mov cl, BS2_TRP_SRV_CALLER_OTHER_RING
905 jmp .done_ctx
906.vm_ctx:
907 mov cl, BS2_TRP_SRV_CALLER_VM
908 jmp .done_ctx
909.same_ctx:
910 mov cl, BS2_TRP_SRV_CALLER_SAME_RING
911.done_ctx:
912
913 ;
914 ; Switch (eax).
915 ;
916 cmp eax, BS2_SYSCALL_TO_RING3
917 jbe .to_ringX
918
919 ; Unknown request.
920.failure:
921 mov eax, -1
922.return: ; careful with ebp here!
923 pop ds
924 pop ebx
925 pop ecx
926 pop edx
927 ;pop eax
928 leave
929 iretd
930
931 ;
932 ; Switching to the ring specified by eax.
933 ; Annoying that ss:esp isn't always restored.
934 ;
935.to_ringX:
936 cmp cl, BS2_TRP_SRV_CALLER_VM
937 je .failure
938 sub al, BS2_SYSCALL_TO_RING0
939
940 ; Fake missing stack registers if necessary.
941 cmp cl, BS2_TRP_SRV_CALLER_SAME_RING
942 jnz .have_stack_regs
943
944 sub esp, 8h
945 sub ebp, 8h
946 xor ebx, ebx
947.move_more:
948 mov edx, [esp + 8 + ebx]
949 mov [esp + ebx], edx
950 add ebx, 4
951 cmp ebx, 9*4
952 jb .move_more
953
954 mov dx, ss
955 mov [ebp + 14h], edx
956 lea edx, [ebp + 18h]
957 mov [ebp + 10h], edx
958
959.have_stack_regs:
960 ; Translate the selector registers
961 mov dx, [ebp - 14h]
962 call bs2SRegToRing
963 mov [ebp - 14h], dx
964
965 mov dx, es
966 call bs2SRegToRing
967 mov es, dx
968
969 mov dx, fs
970 call bs2SRegToRing
971 mov fs, dx
972
973 mov dx, gs
974 call bs2SRegToRing
975 mov gs, dx
976
977 mov dx, [ebp + 08h] ; cs
978 call bs2SRegToRing
979 mov [ebp + 08h], dx
980
981 mov dx, [ebp + 14h] ; ss
982 call bs2SRegToRing
983 mov [ebp + 14h], dx
984
985 or dword [ebp + 0ch], X86_EFL_IOPL ; set IOPL=3
986
987 ; If the desired target is ring-0 we cannot use iret.
988 cmp al, 0
989 je .iret_to_ring_with_stack
990
991.done_success:
992 xor eax, eax
993 jmp .return
994
995.iret_to_ring_with_stack:
996 ;
997 ; Move the iret-to-same-ring to the desired return position. By also
998 ; moving the saved ebp we make the leave instruction do stack
999 ; adjusting/switching for us.
1000 ;
1001 cli ; paranoia, it's disable already.
1002 mov eax, [ebp + 10h]
1003 lea edx, [ebp + 18h]
1004 cmp eax, edx
1005 lea ecx, [ebp + 08h] ; same stack, just shifted 8 bytes
1006 je .move_iret_and_ebp
1007 mov ecx, [ebp + 10h] ; different stack.
1008 sub ecx, 10h
1009.move_iret_and_ebp:
1010 mov edx, [ebp + 0ch]
1011 mov eax, [ebp + 08h]
1012 mov [ecx + 0ch], edx
1013 mov [ecx + 08h], eax
1014 mov edx, [ebp + 04h]
1015 mov eax, [ebp + 00h]
1016 mov [ecx + 04h], edx
1017 mov [ecx + 00h], eax
1018 mov ebp, ecx
1019 xor eax, eax
1020 jmp .return
1021
1022ENDPROC bs2TrapService32bit
1023
1024%endif ; BS2_INC_CMN_PM
1025
1026
1027%ifdef BS2_INC_CMN_LM
1028;
1029; 64-bit TSS (X86TSS64).
1030;
1031BEGINCODELOW
1032ALIGNDATA(16)
1033bs2Tss64Bit:
1034 dd 0 ; 00h - u32Reserved - Reserved.
1035 dq BS2_R0_STACK_ADDR ; 04h - rsp0 - Ring-0 stack pointer. (static)
1036 dq BS2_R1_STACK_ADDR ; 1ch - rsp1 - Ring-1 stack pointer. (static)
1037 dq BS2_R2_STACK_ADDR ; 14h - rsp2 - Ring-2 stack pointer. (static)
1038 dq 0 ; 2ch - reserved
1039 dq BS2_DF_R0_STACK_ADDR ; 24h - ist1;
1040 dq BS2_R0_STACK_ADDR ; 3ch - ist2;
1041 dq BS2_R0_STACK_ADDR ; 34h - ist3;
1042 dq BS2_R0_STACK_ADDR ; 4ch - ist4;
1043 dq BS2_R0_STACK_ADDR ; 44h - ist5;
1044 dq BS2_R0_STACK_ADDR ; 5ch - ist6;
1045 dq BS2_R0_STACK_ADDR ; 54h - ist7;
1046 dw 0,0,0,0,0 ; 6ch - reserved
1047 dw 0 ; 76h - offIoBitmap - Offset relative to the TSS of the
1048 ; 00h - start of the I/O Bitmap and the end of the
1049 ; 00h - interrupt redirection bitmap.
1050bs2Tss64BitEnd:
1051times (68h - (bs2Tss64BitEnd - bs2Tss64Bit)) db 0
1052times ((bs2Tss64BitEnd - bs2Tss64Bit) - 68h) db 0
1053
1054;
1055; 64-bit IDT (X86DESC64GATE).
1056;
1057BEGINCODELOW
1058ALIGNDATA(16)
1059bs2Idt64bit:
1060 dw bs2Trap_00h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1061 dw bs2Trap_01h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1062 dw bs2Trap_02h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1063bs2Idt64bit_BP:
1064 dw bs2Trap_03h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1065 dw bs2Trap_04h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1066 dw bs2Trap_05h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1067 dw bs2Trap_06h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1068 dw bs2Trap_07h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1069 dw bs2Trap_08h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1070 dw bs2Trap_09h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1071 dw bs2Trap_0ah_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1072 dw bs2Trap_0bh_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1073 dw bs2Trap_0ch_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1074 dw bs2Trap_0dh_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1075 dw bs2Trap_0eh_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1076 dw bs2Trap_0fh_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1077 dw bs2Trap_10h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1078 dw bs2Trap_11h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1079 dw bs2Trap_12h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1080 dw bs2Trap_13h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1081 dw bs2Trap_14h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1082 dw bs2Trap_15h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1083 dw bs2Trap_16h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1084 dw bs2Trap_17h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1085 dw bs2Trap_18h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1086 dw bs2Trap_19h_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1087 dw bs2Trap_1ah_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1088 dw bs2Trap_1bh_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1089 dw bs2Trap_1ch_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1090 dw bs2Trap_1dh_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1091 dw bs2Trap_1eh_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1092 dw bs2Trap_1fh_64bit, BS2_SEL_CS64, 08e00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=0 type=int64gate
1093 dw bs2TrapService64bit,BS2_SEL_CS64,0ee00h, 00000h, 0, 0, 0, 0 ; p=1 dpl=3 type=int64gate
1094bs2Idt64bitEnd
1095
1096
1097;
1098; 64-bit trap handlers.
1099;
1100BITS 64
1101%macro bs2Trap_XX_64bit_macro 1
1102BEGINCODELOW
1103bs2Trap_ %+ %1 %+ _64bit:
1104 push %1
1105 jmp bs2Trap_XX_64bit
1106%endmacro
1107%macro bs2Trap_XX_64bit_macro_no_err 1
1108bs2Trap_ %+ %1 %+ _64bit:
1109 push 0
1110 push %1
1111 jmp bs2Trap_XX_64bit
1112%endmacro
1113 bs2Trap_XX_64bit_macro_no_err 00h
1114 bs2Trap_XX_64bit_macro_no_err 01h
1115 bs2Trap_XX_64bit_macro_no_err 02h
1116 bs2Trap_XX_64bit_macro_no_err 03h
1117 bs2Trap_XX_64bit_macro_no_err 04h
1118 bs2Trap_XX_64bit_macro_no_err 05h
1119 bs2Trap_XX_64bit_macro_no_err 06h
1120 bs2Trap_XX_64bit_macro_no_err 07h
1121 bs2Trap_XX_64bit_macro 08h
1122 bs2Trap_XX_64bit_macro_no_err 09h
1123 bs2Trap_XX_64bit_macro 0ah
1124 bs2Trap_XX_64bit_macro 0bh
1125 bs2Trap_XX_64bit_macro 0ch
1126 bs2Trap_XX_64bit_macro 0dh
1127 bs2Trap_XX_64bit_macro 0eh
1128 bs2Trap_XX_64bit_macro_no_err 0fh
1129 bs2Trap_XX_64bit_macro_no_err 10h
1130 bs2Trap_XX_64bit_macro 11h
1131 bs2Trap_XX_64bit_macro_no_err 12h
1132 bs2Trap_XX_64bit_macro_no_err 13h
1133 bs2Trap_XX_64bit_macro_no_err 14h
1134 bs2Trap_XX_64bit_macro_no_err 15h
1135 bs2Trap_XX_64bit_macro_no_err 16h
1136 bs2Trap_XX_64bit_macro_no_err 17h
1137 bs2Trap_XX_64bit_macro_no_err 18h
1138 bs2Trap_XX_64bit_macro_no_err 19h
1139 bs2Trap_XX_64bit_macro_no_err 1ah
1140 bs2Trap_XX_64bit_macro_no_err 1bh
1141 bs2Trap_XX_64bit_macro_no_err 1ch
1142 bs2Trap_XX_64bit_macro_no_err 1dh
1143 bs2Trap_XX_64bit_macro_no_err 1eh
1144 bs2Trap_XX_64bit_macro_no_err 1fh
1145
1146;;
1147; Common 64-bit trap handler.
1148;
1149; return SS rbp + 38h
1150; return RSP rbp + 30h
1151; return RFLAGS rbp + 28h
1152; return CS rbp + 20h
1153; return RIP rbp + 18h
1154; error code rbp + 10h
1155; vector # rbp + 08h
1156BEGINCODEHIGH
1157BEGINPROC bs2Trap_XX_64bit
1158 push rbp ; rbp + 00h
1159 mov rbp, rsp
1160 pushfq ; rbp - 08h
1161 push rax ; rbp - 10h
1162 push rbx ; rbp - 18h
1163
1164 ;
1165 ; Benchmark mode? Then resume the action right away!
1166 ;
1167 mov rax, [rbp + 08h]
1168 cmp [g_u8TrapBenchmarkNo], al
1169 jne .test_mode
1170 cmp byte [g_fTrapPrepared], 0
1171 je .test_mode
1172 mov rax, [g_TrapResumeRIP]
1173 mov [rbp + 18h], rax
1174
1175 pop rbx
1176 ;pop rax
1177 ;popfq
1178 leave
1179 add rsp, 10h ; Skip the vector # and error code.
1180 xor rax, rax
1181 iretq
1182
1183 ;
1184 ; Save the trap information
1185 ;
1186.test_mode:
1187 inc dword [g_u32cTraps]
1188 mov rax, [rbp + 08h]
1189 mov [g_u8LastTrapNo], al
1190 mov rax, [rbp + 10h]
1191 mov [g_u64LastTrapErr], rax
1192 mov rax, [rbp - 08h]
1193 mov [g_u64LastTrapHandlerRFlags], rax
1194 mov ax, cs
1195 mov [g_u16LastTrapHandlerCS], ax
1196 mov ax, ss
1197 mov [g_u16LastTrapHandlerSS], ax
1198 lea rax, [rbp + 8]
1199 mov [g_u64LastTrapHandlerRSP], rax
1200
1201 ; Save the registers.
1202 lea rbx, [g_LastTrapRegs]
1203 mov rax, [rbp - 10h]
1204 mov [rbx + BS2REGS.rax], rax
1205 mov rax, [rbp - 18h]
1206 mov [rbx + BS2REGS.rbx], rax
1207 mov [rbx + BS2REGS.rcx], rcx
1208 mov [rbx + BS2REGS.rdx], rdx
1209 mov [rbx + BS2REGS.rdi], rdi
1210 mov [rbx + BS2REGS.rsi], rsi
1211 mov rax, [rbp]
1212 mov [rbx + BS2REGS.rbp], rax
1213 mov rax, [rbp + 30h]
1214 mov [rbx + BS2REGS.rsp], rax
1215 mov rax, [rbp + 18h]
1216 mov [rbx + BS2REGS.rip], rax
1217 mov [rbx + BS2REGS.r8], r8
1218 mov [rbx + BS2REGS.r9], r9
1219 mov [rbx + BS2REGS.r10], r10
1220 mov [rbx + BS2REGS.r11], r11
1221 mov [rbx + BS2REGS.r12], r12
1222 mov [rbx + BS2REGS.r13], r13
1223 mov [rbx + BS2REGS.r14], r14
1224 mov [rbx + BS2REGS.r15], r15
1225 mov rax, [rbp + 28h]
1226 mov [rbx + BS2REGS.rflags], rax
1227 mov rax, [rbp + 20h]
1228 mov [rbx + BS2REGS.cs], ax
1229 mov [rbx + BS2REGS.ds], ds
1230 mov [rbx + BS2REGS.es], es
1231 mov [rbx + BS2REGS.fs], fs
1232 mov [rbx + BS2REGS.gs], gs
1233 mov rax, [rbp + 38h]
1234 mov [rbx + BS2REGS.ss], ax
1235 mov [rbx + BS2REGS.cBits], byte 64
1236
1237 ; The CRx registers are only accessible from ring-0 (CS=conforming, CPL < 0)
1238 test byte [rbx + BS2REGS.ss], 3
1239 jnz .skip_crX
1240 mov rax, cr0
1241 mov [rbx + BS2REGS.cr0], rax
1242 mov rax, cr2
1243 mov [rbx + BS2REGS.cr2], rax
1244 mov rax, cr3
1245 mov [rbx + BS2REGS.cr3], rax
1246 mov rax, cr4
1247 mov [rbx + BS2REGS.cr4], rax
1248 mov rax, cr8
1249 mov [rbx + BS2REGS.cr8], rax
1250.skip_crX:
1251
1252 ;
1253 ; Advance to a prepared resume position or panic.
1254 ;
1255 cmp byte [g_fTrapPrepared], 0
1256 je .no_resume_pos
1257 mov byte [g_fTrapPrepared], 0
1258 mov rax, [g_TrapResumeRIP]
1259 mov [rbp + 18h], rax
1260 jmp .resume
1261
1262.resume:
1263%ifdef BS2_WITH_XCPT_DB_CLEARING_TF
1264 cmp byte [rbp + 08h], X86_XCPT_DB ; make sure we won't trap again due to a TF.
1265 jne .resume_no_clear_trap_flags
1266 and word [rbp + 28h], ~X86_EFL_TF
1267.resume_no_clear_trap_flags:
1268%endif
1269 pop rbx
1270 pop rax
1271 ;popfq
1272 leave
1273 add rsp, 10h
1274 iretq
1275
1276
1277.no_resume_pos:
1278 ;
1279 ; Look for a trap record.
1280 ;
1281 push rcx
1282
1283 mov ecx, [g_cTrapRecs] ; the number of records.
1284 test ecx, ecx
1285 jz .panic
1286 mov rax, [g_LastTrapRegs + BS2REGS.rip]
1287 sub rax, [g_pTrapRecBase] ; the offWhere we're looking for.
1288 jb .panic
1289 mov rbx, _4G
1290 cmp rax, rbx
1291 jae .panic ; out of range.
1292
1293 ; Look starting at the previous record first.
1294 mov ebx, [g_iTrapRecLast]
1295 sub ecx, ebx
1296 jbe .traprec_loop2 ; g_iTrapRecLast is out of range.
1297 shl rbx, BS2TRAPREC_SIZE_SHIFT
1298 add rbx, [g_paTrapRecs] ; ebx points to the record we hit last time.
1299.traprec_loop1_next:
1300 cmp [rbx + BS2TRAPREC.offWhere], eax
1301 je .traprec_found
1302 add rbx, BS2TRAPREC_size
1303 dec ecx
1304 jnz .traprec_loop1_next
1305
1306 ; Start searching from the start, stopping at the previous record.
1307.traprec_loop2:
1308 mov ecx, [g_iTrapRecLast]
1309 or ecx, ecx
1310 jz .panic ; not found.
1311 mov rbx, [g_paTrapRecs]
1312.traprec_loop2_next:
1313 cmp [rbx + BS2TRAPREC.offWhere], eax
1314 je .traprec_found
1315 add rbx, BS2TRAPREC_size
1316 dec ecx
1317 jnz .traprec_loop2_next
1318 jmp .panic ; not found
1319
1320.traprec_found:
1321 ; Remember the hit for the next trap.
1322 mov rax, rbx
1323 sub rax, [g_paTrapRecs]
1324 shr rax, BS2TRAPREC_SIZE_SHIFT
1325 mov [g_iTrapRecLast], eax
1326
1327 ;
1328 ; Fail the test if we got the wrong trap or error code.
1329 ;
1330 mov al, [g_u8LastTrapNo wrt rip]
1331 cmp al, [rbx + BS2TRAPREC.u8TrapNo]
1332 je .traprec_ok_trap
1333 push rax
1334 movzx rax, byte [rbx + BS2TRAPREC.u8TrapNo]
1335 push rax
1336 push .s_szWrongTrap
1337 call NAME(TestFailedF_p64)
1338 add rsp, 24
1339
1340.traprec_ok_trap:
1341 mov ax, [g_u64LastTrapErr wrt rip]
1342 cmp ax, [rbx + BS2TRAPREC.u16ErrCd]
1343 je .traprec_ok_err_cd
1344 push rax
1345 movzx rax, word [rbx + BS2TRAPREC.u16ErrCd]
1346 push rax
1347 push .s_szWrongErrCd
1348 call NAME(TestFailedF_p64)
1349 add rsp, 24
1350
1351.traprec_ok_err_cd:
1352 ;
1353 ; Advance the EIP and resume execution.
1354 ;
1355 movzx rax, byte [rbx + BS2TRAPREC.offResumeAddend]
1356 add rax, [g_LastTrapRegs + BS2REGS.rip]
1357 mov [rbp + 18h], rax
1358
1359 pop rcx
1360 jmp .resume
1361
1362
1363 ;
1364 ; Format a panic message and halt.
1365 ;
1366.panic:
1367 lea rbx, [g_LastTrapRegs]
1368 ; line break
1369 movzx eax, word [rbx + BS2REGS.ss]
1370 push rax
1371 movzx eax, word [rbx + BS2REGS.gs]
1372 push rax
1373 movzx eax, word [rbx + BS2REGS.fs]
1374 push rax
1375 movzx eax, word [rbx + BS2REGS.es]
1376 push rax
1377 movzx eax, word [rbx + BS2REGS.ds]
1378 push rax
1379 movzx eax, word [rbx + BS2REGS.cs]
1380 push rax
1381 ; line break
1382 push qword [rbx + BS2REGS.rbp]
1383 push qword [rbx + BS2REGS.rsp]
1384 push qword [rbx + BS2REGS.rip]
1385 ; line break
1386 push qword [rbx + BS2REGS.rflags]
1387 push qword [rbx + BS2REGS.r15]
1388 push qword [rbx + BS2REGS.r14]
1389 ; line break
1390 push qword [rbx + BS2REGS.r13]
1391 push qword [rbx + BS2REGS.r12]
1392 push qword [rbx + BS2REGS.r11]
1393 ; line break
1394 push qword [rbx + BS2REGS.r10]
1395 push qword [rbx + BS2REGS.r9]
1396 push qword [rbx + BS2REGS.r8]
1397 ; line break
1398 push qword [rbx + BS2REGS.rdi]
1399 push qword [rbx + BS2REGS.rsi]
1400 push qword [rbx + BS2REGS.rdx]
1401 ; line break
1402 push qword [rbx + BS2REGS.rcx]
1403 push qword [rbx + BS2REGS.rbx]
1404 push qword [rbx + BS2REGS.rax]
1405 ; line break
1406 mov eax, [rbx + BS2REGS.cr8]
1407 push rax
1408 mov eax, [rbx + BS2REGS.cr4]
1409 push rax
1410 mov eax, [rbx + BS2REGS.cr3]
1411 push rax
1412 mov eax, [rbx + BS2REGS.cr0]
1413 push rax
1414 ; line break
1415 push qword [rbp + 10h]
1416 push qword [rbx + BS2REGS.cr2]
1417 push qword [rbx + BS2REGS.rip]
1418 movzx eax, word [rbp + BS2REGS.ss]
1419 push rax
1420 movzx eax, byte [rbp + 08h]
1421 push rax
1422 push .s_szPanicMsg
1423 call NAME(TestFailedF_p64)
1424
1425 call Bs2Panic
1426 jmp .panic ; paranoia
1427
1428.s_szPanicMsg:
1429 db 'trap #%RX8 at %RX16:%RX64 cr2=%RX64 err=%RX64', 13, 10
1430 db 'cr0=%RX64 cr3=%RX64 cr4=%RX64 cr8=%RX16', 13, 10
1431 db 'rax=%RX64 rbx=%RX64 rcx=%RX64', 13, 10
1432 db 'rdx=%RX64 rsi=%RX64 rdi=%RX64', 13, 10
1433 db 'r8 =%RX64 r9 =%RX64 r10=%RX64', 13, 10
1434 db 'r11=%RX64 r12=%RX64 r13=%RX64', 13, 10
1435 db 'r14=%RX64 r15=%RX64 rfl=%RX64', 13, 10
1436 db 'rip=%RX64 rsp=%RX64 rbp=%RX64 ', 13, 10
1437 db 'cs=%RX16 ds=%RX16 es=%RX16 fs=%RX16 gs=%RX16 ss=%RX16', 13, 10
1438 db 0
1439.s_szWrongTrap:
1440 db 'Expected trap %RX8 got %RX8', 13, 10, 0
1441.s_szWrongErrCd:
1442 db 'Expected errcd %RX16 got %RX16', 13, 10, 0
1443ENDPROC bs2Trap_XX_64bit
1444
1445
1446;;
1447; Service IRQ handler.
1448;
1449; Takes requests in eax and later maybe parameters in other registers.
1450;
1451; return SS rbp + 28h
1452; return RSP rbp + 20h
1453; return RFLAGS rbp + 18h
1454; return CS rbp + 10h
1455; return RIP rbp + 08h
1456BEGINCODELOW
1457BEGINPROC bs2TrapService64bit
1458 jmp .highsegment
1459BEGINCODEHIGH
1460.highsegment:
1461 push rbp
1462 mov rbp, rsp
1463 push rax
1464 push rdx
1465 push rcx
1466
1467
1468 ;
1469 ; Switch (eax).
1470 ;
1471 cmp eax, BS2_SYSCALL_TO_RING3
1472 jbe .to_ringX
1473
1474 ; Unknown request.
1475 mov rax, -1
1476.return:
1477 pop rcx
1478 pop rdx
1479 ;pop rax
1480 leave
1481 iretq
1482
1483 ;
1484 ; Switching to the ring specified by eax.
1485 ;
1486.to_ringX:
1487 sub eax, BS2_SYSCALL_TO_RING0 ; al = new ring number.
1488
1489 mov dx, ds
1490 call bs2SRegToRing
1491 mov ds, dx
1492
1493 mov dx, es
1494 call bs2SRegToRing
1495 mov es, dx
1496
1497 mov dx, fs
1498 call bs2SRegToRing
1499 mov fs, dx
1500
1501 mov dx, gs
1502 call bs2SRegToRing
1503 mov gs, dx
1504
1505 mov dx, [rbp + 10h] ; cs
1506 call bs2SRegToRing
1507 mov [rbp + 10h], dx
1508
1509 mov dx, [rbp + 28h] ; ss
1510 call bs2SRegToRing
1511 mov [rbp + 28h], dx
1512
1513 or dword [ebp + 18h], X86_EFL_IOPL ; set IOPL=3
1514
1515 jmp .done_success
1516
1517.done_success:
1518 xor eax, eax
1519 jmp .return
1520
1521ENDPROC bs2TrapService64bit
1522
1523%endif ; BS2_INC_CMN_LM
1524
1525
1526;;
1527; Converts a segment value (dx) to the ring specified by al.
1528;
1529; If the selector isn't a known CS, DS or SS selector it will be set to null.
1530;
1531; @returns dx
1532; @param al The desired ring.
1533; @param dx The segment to convert.
1534;
1535; @remarks WARNING! This has to work exactly the same both in 32-bit and 64-bit mode.
1536;
1537BEGINCODEHIGH
1538BITS 32
1539BEGINPROC bs2SRegToRing
1540 ;
1541 ; Classify the incoming selector.
1542 ;
1543 cmp dx, BS2_SEL_R0_BASE
1544 jb .null
1545 cmp dx, BS2_SEL_R0_BASE + BS2_SEL_GRP_SIZE
1546 jb .ring0
1547
1548 cmp dx, BS2_SEL_R1_BASE
1549 jb .miss
1550 cmp dx, BS2_SEL_R1_BASE + BS2_SEL_GRP_SIZE
1551 jb .ring1
1552
1553 cmp dx, BS2_SEL_R2_BASE
1554 jb .miss
1555 cmp dx, BS2_SEL_R2_BASE + BS2_SEL_GRP_SIZE
1556 jb .ring2
1557
1558 cmp dx, BS2_SEL_R3_BASE
1559 jb .miss
1560 cmp dx, BS2_SEL_R3_BASE + BS2_SEL_GRP_SIZE
1561 jb .ring3
1562 jmp .miss
1563
1564 ;
1565 ; Convert the incoming selector to ring-0 and then from ring-0 to the
1566 ; desired one.
1567 ;
1568.ring0:
1569 cmp al, 0
1570 je .done
1571
1572 add dx, BS2_SEL_R1_BASE - BS2_SEL_R0_BASE
1573 cmp al, 1
1574 je .done
1575
1576 add dx, BS2_SEL_R2_BASE - BS2_SEL_R1_BASE
1577 cmp al, 2
1578 je .done
1579
1580 add dx, BS2_SEL_R3_BASE - BS2_SEL_R2_BASE
1581 cmp al, 3
1582 je .done
1583.panic:
1584 hlt
1585 jmp .panic
1586
1587.ring1:
1588 sub dx, BS2_SEL_R1_BASE - BS2_SEL_R0_BASE
1589 jmp .ring0
1590.ring2:
1591 sub dx, BS2_SEL_R2_BASE - BS2_SEL_R0_BASE
1592 jmp .ring0
1593.ring3:
1594 sub dx, BS2_SEL_R3_BASE - BS2_SEL_R0_BASE
1595 jmp .ring0
1596
1597.done:
1598 and dl, ~3h
1599 or dl, al ; set the RPL
1600 ret
1601
1602.miss:
1603.null:
1604 xor dx, dx
1605 ret
1606ENDPROC bs2SRegToRing
1607
1608BEGINCODELOW
1609
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