VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstMicroRCA.asm@ 86178

Last change on this file since 86178 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 13.5 KB
Line 
1; $Id: tstMicroRCA.asm 82968 2020-02-04 10:35:17Z vboxsync $
2;; @file
3; tstMicroRCA
4;
5
6;
7; Copyright (C) 2006-2020 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
18;*******************************************************************************
19;* Header Files *
20;*******************************************************************************
21%include "VBox/asmdefs.mac"
22%include "iprt/x86.mac"
23%include "VBox/vmm/cpum.mac"
24%include "VBox/err.mac"
25%include "VBox/vmm/vm.mac"
26%include "tstMicro.mac"
27
28
29;*******************************************************************************
30;* Defined Constants And Macros *
31;*******************************************************************************
32;;
33; Function prolog which saves everything and loads the first parameter into ebx.
34%macro PROLOG 0
35 push ebp
36 mov ebp, esp
37 push ebx
38 push esi
39 push edi
40 mov ebx, [ebp + 8] ; pTst
41%endm
42
43;;
44; Function epilog which saves everything and loads the first parameter into ebx.
45%macro EPILOG 0
46 pop edi
47 pop esi
48 pop ebx
49 leave
50%endm
51
52;;
53; Does an rdtsc (trashing edx:eax) and move the result to edi:esi.
54%macro RDTSC_EDI_ESI 0
55 rdtsc
56 xchg eax, esi
57 xchg edx, edi
58%endm
59
60;;
61; Does an rdtsc (trashing edx:eax) and move the result to ecx:ebp.
62%macro RDTSC_ECX_EBP 0
63 rdtsc
64 xchg eax, ebp
65 xchg edx, ecx
66%endm
67
68;;
69; Saves the result of an instruction profiling operation.
70;
71; Input is in edi:esi (start) and [ebp + 8] points to TSTMICRO.
72; Trashes ebx.
73%macro STORE_INSTR_PRF_RESULT 0
74 mov ebx, [ebp + 8]
75 mov [ebx + TSTMICRO.u64TSCR0Start ], esi
76 mov [ebx + TSTMICRO.u64TSCR0Start + 4], edi
77 mov [ebx + TSTMICRO.u64TSCR0End ], eax
78 mov [ebx + TSTMICRO.u64TSCR0End + 4], edx
79%endm
80
81;;
82; Samples the end time of an instruction profiling operation and
83; Saves the result of an instruction profiling operation.
84;
85; Input is in edi:esi (start) and [ebp + 8] points to TSTMICRO.
86; Trashes ebx.
87%macro RDTSC_STORE_INSTR_PRF_RESULT 0
88 rdtsc
89 STORE_INSTR_PRF_RESULT
90%endm
91
92
93;;
94; copies the stack to gabStackCopy and saves ESP and EBP in gpESP and gpEBP.
95;
96; @param %1 The resume label.
97; @param ebx TSTMICRO pointer.
98; @uses ecx, edi, esi, flags.
99%macro COPY_STACK_ESP_EBP_RESUME 1
100 mov [gpTst], ebx
101 mov [gESPResume], esp
102 mov [gEBPResume], ebp
103 mov dword [gEIPResume], %1
104
105 mov esi, esp
106 and esi, ~0fffh
107 mov edi, gabStackCopy
108 mov ecx, 01000h / 4
109 rep movsd
110
111%endm
112
113
114;*******************************************************************************
115;* Global Variables *
116;*******************************************************************************
117BEGINDATA
118gpTst dd 0
119
120gESPResume dd 0
121gEBPResume dd 0
122gEIPResume dd 0
123
124BEGINBSS
125gabStackCopy resb 4096
126
127extern NAME(idtOnly42)
128extern IMPNAME(g_VM)
129
130BEGINCODE
131EXPORTEDNAME tstMicroRCAsmStart
132
133
134;;
135; Check the overhead of doing rdtsc + two xchg operations.
136;
137BEGINPROC tstOverhead
138 PROLOG
139
140 RDTSC_EDI_ESI
141 RDTSC_STORE_INSTR_PRF_RESULT
142
143 EPILOG
144 ret
145ENDPROC tstOverhead
146
147
148;;
149; Invalidate page 0.
150;
151BEGINPROC tstInvlpg0
152 PROLOG
153
154 RDTSC_EDI_ESI
155 invlpg [0]
156 RDTSC_STORE_INSTR_PRF_RESULT
157
158 EPILOG
159 ret
160ENDPROC tstInvlpg0
161
162;;
163; Invalidate the current code page.
164;
165BEGINPROC tstInvlpgEIP
166 PROLOG
167
168 RDTSC_EDI_ESI
169 invlpg [NAME(tstInvlpgEIP)]
170 RDTSC_STORE_INSTR_PRF_RESULT
171
172 EPILOG
173 ret
174ENDPROC tstInvlpgEIP
175
176
177;;
178; Invalidate page 0.
179;
180BEGINPROC tstInvlpgESP
181 PROLOG
182
183 RDTSC_EDI_ESI
184 invlpg [esp]
185 RDTSC_STORE_INSTR_PRF_RESULT
186
187 EPILOG
188 ret
189ENDPROC tstInvlpgESP
190
191
192;;
193; cr3 reload sequence.
194;
195BEGINPROC tstCR3Reload
196 PROLOG
197
198 RDTSC_EDI_ESI
199 mov ebx, cr3
200 mov cr3, ebx
201 RDTSC_STORE_INSTR_PRF_RESULT
202
203 EPILOG
204 ret
205ENDPROC tstCR3Reload
206
207
208;;
209; Enable WP sequence.
210;
211BEGINPROC tstWPEnable
212 PROLOG
213
214 RDTSC_EDI_ESI
215 mov ebx, cr0
216 or ebx, X86_CR0_WRITE_PROTECT
217 mov cr0, ebx
218 rdtsc
219 ; disabled it now or we'll die...
220 and ebx, ~X86_CR0_WRITE_PROTECT
221 mov cr0, ebx
222 STORE_INSTR_PRF_RESULT
223
224 EPILOG
225 ret
226ENDPROC tstWPEnable
227
228
229;;
230; Disable WP sequence.
231;
232BEGINPROC tstWPDisable
233 PROLOG
234
235 ;
236 mov ebx, cr0
237 or ebx, X86_CR0_WRITE_PROTECT
238 mov cr0, ebx
239 ; just wast a bit of space and time to try avoid the enable bit tainting the results of the disable.
240 xor ebx, ebx
241 rdtsc
242 add ebx, eax
243 rdtsc
244 add ebx, edx
245 rdtsc
246 sub ebx, eax
247
248 RDTSC_EDI_ESI
249 mov ebx, cr0
250 and ebx, ~X86_CR0_WRITE_PROTECT
251 mov cr0, ebx
252 RDTSC_STORE_INSTR_PRF_RESULT
253
254 EPILOG
255 ret
256ENDPROC tstWPDisable
257
258
259
260
261;;
262; Generate a #PF accessing page 0 in
263;
264BEGINPROC tstPFR0
265 PROLOG
266
267 COPY_STACK_ESP_EBP_RESUME tstPFR0_Resume
268
269 rdtsc
270 mov [ebx + TSTMICRO.u64TSCR0Start ], eax
271 mov [ebx + TSTMICRO.u64TSCR0Start + 4], edx
272 xor ebx, ebx ; The NULL pointer.
273 xor ecx, ecx
274 xor ebp, ebp ; ebp:ecx - Rx enter time (0:0).
275 RDTSC_EDI_ESI ; edi:esi - Before trap.
276 mov [ebx], ebx ; traps - 2 bytes
277
278 RDTSC_EDI_ESI ; edi:esi - Rx entry time.
279 int 42h ; we're done.
280
281tstPFR0_Resume:
282 EPILOG
283 ret
284ENDPROC tstPFR0
285
286
287
288;;
289; Generate a #PF accessing page 0 in ring-1
290;
291BEGINPROC_EXPORTED tstPFR1
292 PROLOG
293
294 COPY_STACK_ESP_EBP_RESUME tstPFR1_Resume
295
296 ; Setup iret to execute r1 code.
297 mov eax, 02069h ; load ds and es with R1 selectors.
298 mov es, eax
299 mov ds, eax
300 push dword 01069h ; ss
301 push dword [ebx + TSTMICRO.RCPtrStack] ; esp
302 push dword 0000h ; eflags
303 push dword 01061h ; cs
304 push tstPTR1_R1 ; eip
305
306 rdtsc
307 mov [ebx + TSTMICRO.u64TSCR0Start ], eax
308 mov [ebx + TSTMICRO.u64TSCR0Start + 4], edx
309 iret
310
311 ; R1 code
312tstPTR1_R1:
313 RDTSC_ECX_EBP ; ebp:ecx - Rx enter time (0:0).
314 xor ebx, ebx
315 RDTSC_EDI_ESI ; edi:esi - Before trap.
316 mov [ebx], ebx ; traps - 2 bytes
317
318 RDTSC_EDI_ESI ; edi:esi - Rx entry time.
319 int 42h ; we're done.
320
321 ; Resume in R0
322tstPFR1_Resume:
323 EPILOG
324 ret
325ENDPROC tstPFR1
326
327
328;;
329; Generate a #PF accessing page 0 in ring-2
330;
331BEGINPROC_EXPORTED tstPFR2
332 PROLOG
333
334 COPY_STACK_ESP_EBP_RESUME tstPFR2_Resume
335
336 ; Setup iret to execute r2 code.
337 mov eax, 0206ah ; load ds and es with R2 selectors.
338 mov es, eax
339 mov ds, eax
340 push 0206ah ; ss
341 push dword [ebx + TSTMICRO.RCPtrStack] ; esp
342 push dword 0000h ; eflags
343 push 02062h ; cs
344 push tstPTR2_R2 ; eip
345
346 rdtsc
347 mov [ebx + TSTMICRO.u64TSCR0Start ], eax
348 mov [ebx + TSTMICRO.u64TSCR0Start + 4], edx
349 iret
350
351 ; R2 code
352tstPTR2_R2:
353 RDTSC_ECX_EBP ; ebp:ecx - Rx enter time (0:0).
354 xor ebx, ebx
355 RDTSC_EDI_ESI ; edi:esi - Before trap.
356 mov [ebx], ebx ; traps - 2 bytes
357
358 RDTSC_EDI_ESI ; edi:esi - Rx entry time.
359 int 42h ; we're done.
360
361 ; Resume in R0
362tstPFR2_Resume:
363 EPILOG
364 ret
365ENDPROC tstPFR2
366
367
368;;
369; Generate a #PF accessing page 0 in ring-3
370;
371BEGINPROC_EXPORTED tstPFR3
372 PROLOG
373
374 COPY_STACK_ESP_EBP_RESUME tstPFR3_Resume
375
376 ; Setup iret to execute r3 code.
377 mov eax, 0306bh ; load ds and es with R3 selectors.
378 mov es, eax
379 mov ds, eax
380 push 0306bh ; ss
381 push dword [ebx + TSTMICRO.RCPtrStack] ; esp
382 push dword 0000h ; eflags
383 push 03063h ; cs
384 push tstPTR3_R3 ; eip
385
386 rdtsc
387 mov [ebx + TSTMICRO.u64TSCR0Start ], eax
388 mov [ebx + TSTMICRO.u64TSCR0Start + 4], edx
389 iret
390
391 ; R3 code
392tstPTR3_R3:
393 RDTSC_ECX_EBP ; ebp:ecx - Rx enter time (0:0).
394 xor ebx, ebx
395 RDTSC_EDI_ESI ; edi:esi - Before trap.
396 mov [ebx], ebx ; traps - 2 bytes
397
398 RDTSC_EDI_ESI ; edi:esi - Rx entry time.
399 int 42h ; we're done.
400
401 ; Resume in R0
402tstPFR3_Resume:
403 EPILOG
404 ret
405ENDPROC tstPFR3
406
407
408
409;;
410; Trap handler with error code - share code with tstTrapHandler.
411align 8
412BEGINPROC_EXPORTED tstTrapHandlerNoErr
413 rdtsc
414 push 0ffffffffh
415 jmp tstTrapHandler_Common
416
417;;
418; Trap handler with error code.
419; 14 SS (only if ring transition.)
420; 10 ESP (only if ring transition.)
421; c EFLAGS
422; 8 CS
423; 4 EIP
424; 0 Error code. (~0 for vectors which don't take an error code.)
425;; @todo This is a bit of a mess - clean up!
426align 8
427BEGINPROC tstTrapHandler
428 ; get the time
429 rdtsc
430
431tstTrapHandler_Common:
432 xchg ecx, eax
433 mov eax, -1 ; return code
434
435 ; disable WP
436 mov ebx, cr0
437 and ebx, ~X86_CR0_WRITE_PROTECT
438 mov cr0, ebx
439
440 ; first hit, or final hit?
441 mov ebx, [gpTst]
442 inc dword [ebx + TSTMICRO.cHits]
443 cmp dword [ebx + TSTMICRO.cHits], byte 1
444 jne near tstTrapHandler_Fault
445
446 ; save the results - edx:ecx == r0 enter time, edi:esi == before trap, ecx:ebp == Rx enter time.
447
448 mov [ebx + TSTMICRO.u64TSCR0Enter ], ecx
449 mov [ebx + TSTMICRO.u64TSCR0Enter + 4], edx
450
451 ;mov [ebx + TSTMICRO.u64TSCRxStart ], ecx
452 ;mov [ebx + TSTMICRO.u64TSCRxStart + 4], ebp
453
454 mov [ebx + TSTMICRO.u64TSCRxStart ], esi
455 mov [ebx + TSTMICRO.u64TSCRxStart + 4], edi
456
457 mov eax, cr2
458 mov [ebx + TSTMICRO.u32CR2], eax
459 mov eax, [esp + 0]
460 mov [ebx + TSTMICRO.u32ErrCd], eax
461 mov eax, [esp + 4]
462 mov [ebx + TSTMICRO.u32EIP], eax
463
464 ;
465 ; Advance the EIP and resume.
466 ;
467 mov ecx, [ebx + TSTMICRO.offEIPAdd]
468 add [esp + 4], ecx ; return eip + offEIPAdd
469
470 add esp, byte 4 ; skip the err code
471
472 ; take the timestamp before resuming.
473 rdtsc
474 mov [ebx + TSTMICRO.u64TSCR0Exit ], eax
475 mov [ebx + TSTMICRO.u64TSCR0Exit + 4], edx
476 iret
477
478
479tstTrapHandler_Fault:
480 cld
481
482%if 0 ; this has been broken for quite some time
483 ;
484 ; Setup CPUMCTXCORE frame
485 ;
486 push dword [esp + 4h + 0h] ; 3ch - eip
487 push dword [esp + 0ch + 4h] ; 38h - eflags
488 ;;;;push dword [esp + 08h + 8h] ; 34h - cs
489 push cs;want disasm
490 push ds ; c ; 30h
491 push es ;10 ; 2ch
492 push fs ;14 ; 28h
493 push gs ;18 ; 24h
494 push dword [esp + 14h + 1ch] ; 20h - ss
495 push dword [esp + 10h + 20h] ; 1ch - esp
496 push ecx ;24 ; 18h
497 push edx ;28 ; 14h
498 push ebx ;2c ; 10h
499 push eax ;30 ; ch
500 push ebp ;34 ; 8h
501 push esi ;38 ; 4h
502 push edi ;3c ; 0h
503 ;40
504%endif
505
506 test byte [esp + 0ch + 4h], 3h ; check CPL of the cs selector
507 jmp short tstTrapHandler_Fault_Hyper ;; @todo
508 jz short tstTrapHandler_Fault_Hyper
509tstTrapHandler_Fault_Guest:
510 mov ecx, esp
511 mov edx, IMP(g_VM)
512 mov eax, VERR_TRPM_DONT_PANIC
513 call [edx + VM.pfnVMMRCToHostAsm]
514 jmp short tstTrapHandler_Fault_Guest
515
516tstTrapHandler_Fault_Hyper:
517 ; fix ss:esp.
518 lea ebx, [esp + 14h + 040h] ; calc esp at trap
519 mov [esp + CPUMCTXCORE.esp], ebx; update esp in register frame
520 mov [esp + CPUMCTXCORE.ss.Sel], ss ; update ss in register frame
521
522 mov ecx, esp
523 mov edx, IMP(g_VM)
524 mov eax, VERR_TRPM_DONT_PANIC
525 call [edx + VM.pfnVMMRCToHostAsm]
526 jmp short tstTrapHandler_Fault_Hyper
527
528BEGINPROC tstInterrupt42
529 rdtsc
530 push byte 0
531 mov ecx, eax ; low ts
532 xor eax, eax ; return code.
533
534 ; save the results - edx:ecx == r0 end time, edi:esi == Rx end time.
535 mov [ebx + TSTMICRO.u64TSCR0End ], ecx
536 mov [ebx + TSTMICRO.u64TSCR0End + 4], edx
537
538 mov [ebx + TSTMICRO.u64TSCRxEnd ], esi
539 mov [ebx + TSTMICRO.u64TSCRxEnd + 4], edi
540
541 ;
542 ; Restore the IDT and stack, and resume the testcase code.
543 ;
544 lidt [ebx + TSTMICRO.OriginalIDTR]
545
546 mov edi, esp
547 and edi, ~0fffh
548 mov esi, gabStackCopy
549 mov ecx, 01000h / 4
550 mov esp, [gESPResume]
551 mov ebp, [gEBPResume]
552 rep movsd
553
554 jmp [gEIPResume]
555
556ENDPROC tstTrapHandler
557
558EXPORTEDNAME tstMicroRCAsmEnd
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