VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 17 months ago

Copyright year updates by scm.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use