VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstMicroGCA.asm@ 4953

Last change on this file since 4953 was 4071, checked in by vboxsync, 17 years ago

Biggest check-in ever. New source code headers for all (C) innotek files.

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