VirtualBox

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

Last change on this file since 1224 was 19, checked in by vboxsync, 18 years ago

nasm.mac -> asmdefs.mac + header adjustments.

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