VirtualBox

source: vbox/trunk/src/VBox/ValidationKit/bootsectors/bootsector2-cpu-pf-1-template.mac@ 82968

Last change on this file since 82968 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 Author Date Id Revision
File size: 27.1 KB
Line 
1; $Id: bootsector2-cpu-pf-1-template.mac 82968 2020-02-04 10:35:17Z vboxsync $
2;; @file
3; Bootsector test for various types of #PFs - multi mode template.
4;
5
6;
7; Copyright (C) 2007-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; The contents of this file may alternatively be used under the terms
18; of the Common Development and Distribution License Version 1.0
19; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20; VirtualBox OSE distribution, in which case the provisions of the
21; CDDL are applicable instead of those of the GPL.
22;
23; You may elect to license modified versions of this file under the
24; terms and conditions of either the GPL or the CDDL or both.
25;
26
27
28%include "bootsector2-template-header.mac"
29
30
31;*******************************************************************************
32;* Defined Constants And Macros *
33;*******************************************************************************
34%undef BIG_PAGE_SIZE
35%undef PXE_SIZE
36%ifdef TMPL_CMN_PP
37 %define BIG_PAGE_SIZE _4M
38 %define PXE_SIZE 4
39%else
40 %define BIG_PAGE_SIZE _2M
41 %define PXE_SIZE 8
42%endif
43
44
45;;
46; Do the tests for this mode.
47;
48; @uses nothing
49;
50BEGINCODELOW
51BITS 16
52BEGINPROC TMPL_NM(DoTestsForMode_rm)
53 push bp
54 mov bp, sp
55 push ax
56
57 ;
58 ; Check if the mode and NX is supported, do the switch.
59 ;
60 call TMPL_NM(Bs2IsModeSupported_rm)
61 jz .done
62 mov ax, [bp - 2]
63 test al, al
64 jz .nx_disabled
65 call Bs2IsNXSupported_r86
66 jz .done
67 call Bs2EnableNX_r86
68.nx_disabled:
69 call TMPL_NM(Bs2EnterMode_rm)
70BITS TMPL_BITS
71
72 ;
73 ; Do the tests.
74 ;
75 call TMPL_NM(TestNotPresent)
76 ;; @todo call TMPL_NM(TestReadOnly)
77 ;; @todo call TMPL_NM(TestSupervisor)
78 ;; @todo call TMPL_NM(TestReservedBits)
79
80 ;
81 ; Back to real mode.
82 ;
83 call TMPL_NM(Bs2ExitMode)
84BITS 16
85 call Bs2DisableNX_r86
86
87.done:
88 pop ax
89 leave
90 ret
91ENDPROC TMPL_NM(DoTestsForMode_rm)
92TMPL_BEGINCODE
93BITS TMPL_BITS
94
95
96;;
97; Do the tests for this mode.
98;
99; @uses nothing
100;
101BEGINCODELOW
102BITS 16
103BEGINPROC TMPL_NM(DoBenchmarksForMode_rm)
104 push bp
105 mov bp, sp
106 push ax
107
108 ;
109 ; Check if the mode and NX is supported, do the switch.
110 ;
111 call TMPL_NM(Bs2IsModeSupported_rm)
112 jz .done
113 call TMPL_NM(Bs2EnterMode_rm)
114BITS TMPL_BITS
115
116 ;
117 ; Do the tests.
118 ;
119 call TMPL_NM(BenchmarkNotPresent)
120
121 ;
122 ; Back to real mode.
123 ;
124 call TMPL_NM(Bs2ExitMode)
125BITS 16
126.done:
127 pop ax
128 leave
129 ret
130ENDPROC TMPL_NM(DoBenchmarksForMode_rm)
131TMPL_BEGINCODE
132BITS TMPL_BITS
133
134
135;;
136; Does the page-not-present tests.
137;
138; @param al Set if NXE=1, clear if NXE=0.
139;
140; @uses nothing
141;
142BEGINPROC TMPL_NM(TestNotPresent)
143 push xBP
144 mov xBP, xSP
145 push sAX
146 push xBX
147 push xCX
148 push xDX
149 push xDI
150 push xSI
151
152 ;
153 ; Setup sCX for all the following tests.
154 ;
155 xor sCX, sCX
156 test al, al
157 jz .no_nxe
158 mov sCX, X86_TRAP_PF_ID
159.no_nxe:
160
161 ;
162 ; First test, big page not present.
163 ;
164 mov xAX, .s_szBigPageNotPresent
165 test sCX, sCX
166 jz .test1_nxe
167 mov xAX, .s_szBigPageNotPresentNX
168.test1_nxe:
169 call TMPL_NM_CMN(TestSub)
170 call TMPL_NM(TestFillTestAreaWithRet)
171
172 mov sAX, TST_SCRATCH_PD_BASE
173 call TMPL_NM(TestGetPdeAddr)
174 and byte [sAX], ~X86_PTE_P
175 mov sAX, cr3
176 mov cr3, sAX
177
178 mov sAX, TST_SCRATCH_PD_BASE
179 mov sDX, 0 ; err code
180 call TMPL_NM(TestHammerPage)
181 jz .test1_cleanup
182
183 mov sAX, TST_SCRATCH_PD_BASE + (BIG_PAGE_SIZE / 2 - _4K)
184 call TMPL_NM(TestHammerPage)
185 jz .test1_cleanup
186
187 mov sAX, TST_SCRATCH_PD_BASE + (BIG_PAGE_SIZE - _4K)
188 call TMPL_NM(TestHammerPage)
189 jz .test1_cleanup
190
191.test1_cleanup:
192 mov sAX, TST_SCRATCH_PD_BASE
193 call TMPL_NM(TestGetPdeAddr)
194 or byte [sAX], X86_PTE_P
195 mov sAX, cr3
196 mov cr3, sAX
197
198 ;
199 ; The second test, normal page not present.
200 ;
201 mov xAX, .s_szPageNotPresent
202 test sCX, sCX
203 jz .test2_nxe
204 mov xAX, .s_szPageNotPresentNX
205.test2_nxe:
206 call TMPL_NM_CMN(TestSub)
207
208 mov sAX, TST_SCRATCH_PD_BASE
209 call TMPL_NM(TstPutPageTableAt)
210
211 ; Make the first and last page not-present.
212 and byte [BS2_USER_PX_0_ADDR], ~X86_PTE_P
213 and byte [BS2_USER_PX_0_ADDR + 01000h - PXE_SIZE], ~X86_PTE_P
214 mov sAX, cr3
215 mov cr3, sAX
216
217 ; Do the tests.
218 mov sAX, TST_SCRATCH_PD_BASE
219 mov sDX, 0 ; err code
220 call TMPL_NM(TestHammerPage)
221 jz .test2_cleanup
222
223 mov sAX, TST_SCRATCH_PD_BASE + (BIG_PAGE_SIZE - _4K)
224 call TMPL_NM(TestHammerPage)
225 jz .test2_cleanup
226
227.test2_cleanup:
228 mov sAX, TST_SCRATCH_PD_BASE
229 call TMPL_NM(TstRestoreBigPageAt)
230
231
232%if PXE_SIZE == 8 ; PAE or LM
233 ;
234 ; The third test, mark a page directory pointer entry not present.
235 ;
236 mov xAX, .s_szPdpeNotPresent
237 test sCX, sCX
238 jz .test3_nxe
239 mov xAX, .s_szPdpeNotPresentNX
240.test3_nxe:
241 call TMPL_NM_CMN(TestSub)
242 call TMPL_NM(TestFillTestAreaWithRet)
243
244 mov sAX, TST_SCRATCH_PDPT_BASE
245 call TMPL_NM(TestGetPdpeAddr)
246 and byte [sAX], ~X86_PTE_P
247 mov sAX, cr3
248 mov cr3, sAX
249
250 mov sAX, TST_SCRATCH_PDPT_BASE
251 mov sDX, 0 ; err code
252 call TMPL_NM(TestHammerPage)
253 jz .test3_cleanup
254
255 mov sAX, TST_SCRATCH_PDPT_BASE + (BIG_PAGE_SIZE / 2 - _4K)
256 call TMPL_NM(TestHammerPage)
257 jz .test3_cleanup
258
259 mov sAX, TST_SCRATCH_PDPT_BASE + (BIG_PAGE_SIZE - _4K)
260 call TMPL_NM(TestHammerPage)
261 jz .test3_cleanup
262
263.test3_cleanup:
264 mov sAX, TST_SCRATCH_PDPT_BASE
265 call TMPL_NM(TestGetPdpeAddr)
266 or byte [sAX], X86_PTE_P
267 mov sAX, cr3
268 mov cr3, sAX
269%endif ; PAE || LM
270
271
272%ifdef TMPL_LM64
273 ;
274 ; The fourth test, mark a page map level 4 entry not present.
275 ;
276 mov xAX, .s_szPml4eNotPresent
277 test sCX, sCX
278 jz .test4_nxe
279 mov xAX, .s_szPml4eNotPresentNX
280.test4_nxe:
281 call TMPL_NM_CMN(TestSub)
282 call TMPL_NM(TestFillTestAreaWithRet)
283
284 mov sAX, TST_SCRATCH_PML4_BASE
285 call TMPL_NM(TestGetPml4eAddr)
286 and byte [sAX], ~X86_PTE_P
287 mov sAX, cr3
288 mov cr3, sAX
289
290 mov sAX, TST_SCRATCH_PML4_BASE
291 mov sDX, 0 ; err code
292 call TMPL_NM(TestHammerPage)
293 jz .test4_cleanup
294
295 mov sAX, TST_SCRATCH_PML4_BASE + (BIG_PAGE_SIZE / 2 - _4K)
296 call TMPL_NM(TestHammerPage)
297 jz .test4_cleanup
298
299 mov sAX, TST_SCRATCH_PML4_BASE + (BIG_PAGE_SIZE - _4K)
300 call TMPL_NM(TestHammerPage)
301 jz .test4_cleanup
302
303.test4_cleanup:
304 mov sAX, TST_SCRATCH_PML4_BASE
305 call TMPL_NM(TestGetPml4eAddr)
306 or byte [sAX], X86_PTE_P
307 mov sAX, cr3
308 mov cr3, sAX
309%endif
310
311 ;
312 ; Done.
313 ;
314 call TMPL_NM_CMN(TestSubDone)
315
316 pop xSI
317 pop xDI
318 pop xDX
319 pop xCX
320 pop xBX
321 pop sAX
322 leave
323 ret
324
325.s_szBigPageNotPresent:
326 db TMPL_MODE_STR, ', !NX, big page NP', 0
327.s_szBigPageNotPresentNX:
328 db TMPL_MODE_STR, ', NX, big page NP', 0
329.s_szPageNotPresent:
330 db TMPL_MODE_STR, ', !NX, page NP', 0
331.s_szPageNotPresentNX:
332 db TMPL_MODE_STR, ', NX, page NP', 0
333%if PXE_SIZE == 8 ; PAE or LM
334.s_szPdpeNotPresent:
335 db TMPL_MODE_STR, ', !NX, PDPE NP', 0
336.s_szPdpeNotPresentNX:
337 db TMPL_MODE_STR, ', NX, PDPE NP', 0
338%endif
339%ifdef TMPL_LM64
340.s_szPml4eNotPresent:
341 db TMPL_MODE_STR, ', !NX, PML4E NP', 0
342.s_szPml4eNotPresentNX:
343 db TMPL_MODE_STR, ', NX, PML4E NP', 0
344%endif
345ENDPROC TMPL_NM(TestNotPresent)
346
347
348
349;;
350; Does the page-not-present benchmark.
351;
352; @uses nothing
353;
354BEGINPROC TMPL_NM(BenchmarkNotPresent)
355 push xBP
356 mov xBP, xSP
357 push sAX
358 push xBX
359 push sCX
360 push sDX
361 push xDI
362 push xSI
363 sub xSP, 20h
364
365 call TMPL_NM(TestFillTestAreaWithRet)
366
367 ;
368 ; The First benchmark: Big page not present.
369 ;
370
371 ; Mark the big test page not present.
372 mov sAX, TST_SCRATCH_PD_BASE
373 call TMPL_NM(TestGetPdeAddr)
374 and byte [sAX], ~X86_PTE_P
375 mov sAX, cr3
376 mov cr3, sAX
377
378 ; Benchmark.
379 mov sAX, TST_SCRATCH_PD_BASE
380 mov xDX, .s_szBigPageNotPresent
381 mov xCX, .s_szBigPageNotPresentFailed
382 call TMPL_NM(TstBenchmark32BitReads)
383
384 ; Cleanup.
385 mov sAX, TST_SCRATCH_PD_BASE
386 call TMPL_NM(TestGetPdeAddr)
387 or byte [sAX], X86_PTE_P
388 mov sAX, cr3
389 mov cr3, sAX
390
391 ;
392 ; The second benchmark: Normal page not present.
393 ;
394
395 ; Replace the big page with a page table and make the first and last
396 ; pages not-present.
397 mov sAX, TST_SCRATCH_PD_BASE
398 call TMPL_NM(TstPutPageTableAt)
399
400 and byte [BS2_USER_PX_0_ADDR], ~X86_PTE_P
401 and byte [BS2_USER_PX_0_ADDR + 01000h - PXE_SIZE], ~X86_PTE_P
402 mov sAX, cr3
403 mov cr3, sAX
404
405 ; Benchmark.
406 mov sAX, TST_SCRATCH_PD_BASE
407 mov xDX, .s_szPageNotPresent
408 mov xCX, .s_szPageNotPresentFailed
409 call TMPL_NM(TstBenchmark32BitReads)
410
411 ; Cleanup
412 mov sAX, TST_SCRATCH_PD_BASE
413 call TMPL_NM(TstRestoreBigPageAt)
414
415
416 ;
417 ; Done.
418 ;
419 add xSP, 20h
420 pop xSI
421 pop xDI
422 pop sDX
423 pop sCX
424 pop xBX
425 pop sAX
426 leave
427 ret
428
429.s_szBigPageNotPresent:
430 db TMPL_MODE_STR, ', read NP big page', 0
431.s_szBigPageNotPresentFailed:
432 db TMPL_MODE_STR, ', reading NP big page failed', 13, 10, 0
433.s_szPageNotPresent:
434 db TMPL_MODE_STR, ', read NP page', 0
435.s_szPageNotPresentFailed:
436 db TMPL_MODE_STR, ', reading NP page failed', 13, 10, 0
437ENDPROC TMPL_NM(BenchmarkNotPresent)
438
439
440;;
441; Benchmark 32-bit reads at a give location.
442;
443; Will report the result under the name given via xDX. Will report any test
444; failure giving the string pointed to by xCX as explanation.
445;
446; @param sAX The location to do the reads.
447; @param xDX The test value name.
448; @param xCX The failure string
449; @uses nothing
450;
451BEGINPROC TMPL_NM(TstBenchmark32BitReads)
452 push xBP
453 mov xBP, xSP
454%define a_pu32Test [xBP - sCB]
455 push sAX
456%define a_pszValue [xBP - sCB*2]
457 push sDX
458%define a_pszFailure [xBP - sCB*3]
459 push sCX
460 push sSI
461 push sDI
462%define u64NanoTS [xBP - sCB*5 - 8h]
463 sub xSP, 8h
464
465 ;
466 ; Calibrate the test so it doesn't take forever.
467 ;
468 mov xAX, .calibrate_resume
469 mov dl, 0eh
470 call TMPL_NM_CMN(Bs2TrapPrepare)
471 mov ecx, TST_CALIBRATE_LOOP_COUNT
472
473 lea xAX, u64NanoTS
474 call TMPL_NM_CMN(GetNanoTS)
475
476.calibrate_loop:
477 mov sAX, a_pu32Test
478 mov esi, [sAX]
479.calibrate_resume:
480 test sAX, sAX
481 jnz .failure
482 dec ecx
483 jnz .calibrate_loop
484
485 lea xAX, u64NanoTS
486 call TMPL_NM_CMN(GetElapsedNanoTS)
487 call TMPL_NM_CMN(Bs2TrapReset)
488
489 ; Figure out how many iterations is required for the full benchmark.
490 mov ecx, TST_BENCHMARK_PERIOD_IN_SECS
491 mov edx, TST_CALIBRATE_LOOP_COUNT
492 mov xAX, xSP
493 call TMPL_NM_CMN(CalcBenchmarkIterations)
494 mov ecx, eax ; iteration count.
495
496 ;
497 ; Do the full benchmark run.
498 ;
499 mov xAX, .bench_resume
500 mov dl, 0eh
501 call TMPL_NM_CMN(Bs2TrapPrepare)
502 mov edx, ecx ; save test count for ReportResult.
503
504 lea xAX, u64NanoTS
505 call TMPL_NM_CMN(GetNanoTS)
506.bench_loop:
507 mov xAX, a_pu32Test
508 mov esi, [eax]
509.bench_resume:
510 test eax, eax
511 jnz .failure
512 dec ecx
513 jnz .bench_loop
514
515 lea xAX, u64NanoTS
516 call TMPL_NM_CMN(GetElapsedNanoTS)
517 call TMPL_NM_CMN(Bs2TrapReset)
518
519 mov xCX, a_pszValue
520 lea xAX, u64NanoTS
521 call TMPL_NM_CMN(ReportResult)
522
523.return:
524 pop sDI
525 pop sSI
526 pop sCX
527 pop sDX
528 pop sAX
529 leave
530 ret
531
532.failure:
533 call TMPL_NM_CMN(Bs2TrapReset)
534 mov xAX, a_pszFailure
535 call TMPL_NM_CMN(TestFailed)
536 jmp .return
537
538%undef a_pszFailure
539%undef a_pu32Test
540%undef a_pszValue
541%undef a_pszFailure
542%undef u64NanoTS
543ENDPROC TMPL_NM(TstBenchmark32BitReads)
544
545
546;;
547; Fills the test area with return instructions.
548;
549; @uses nothing.
550;
551BEGINPROC TMPL_NM(TestFillTestAreaWithRet)
552 push xBP
553 mov xBP, xSP
554 push xDI
555 push xCX
556 push xAX
557
558 mov xDI, TST_SCRATCH_PD_BASE
559 mov xCX, (_4M + _4M) / 4
560 mov eax, 0c3c3c3c3h
561 rep stosd
562
563 mov xDI, TST_SCRATCH_PDPT_BASE
564 mov xCX, (_4M + _4M) / 4
565 mov eax, 0c3c3c3c3h
566 rep stosd
567
568%ifdef TMPL_LM64
569 mov xDI, TST_SCRATCH_PML4_BASE
570 mov xCX, (_4M + _4M) / 8
571 mov rax, 0c3c3c3c3c3c3c3c3h
572 rep stosq
573%endif
574
575 pop xAX
576 pop xCX
577 pop xDI
578 leave
579 ret
580ENDPROC TMPL_NM(TestFillTestAreaWithRet)
581
582
583;;
584; Gets the page directory address.
585;
586; ASSUMES identity mapped page translation tables.
587;
588; @returns ds:xAX The page directory address.
589; @param sAX The virtual address in question.
590; @uses nothing
591;
592BEGINPROC TMPL_NM(TestGetPdeAddr)
593 push xBP
594 mov xBP, xSP
595 push sBX
596 push sCX
597
598%ifdef TMPL_CMN_PP
599 ; PDPE
600 shr sAX, X86_PD_SHIFT
601 and sAX, X86_PD_MASK
602 shl sAX, 2
603 mov sBX, cr3
604 and sBX, X86_CR3_PAGE_MASK
605 add sAX, sBX
606
607%else
608 %ifdef TMPL_CMN_LM
609 ; PML4E
610 mov sCX, sAX
611 shr sCX, X86_PML4_SHIFT
612 and sCX, X86_PML4_MASK
613 shl sCX, 3
614 mov sBX, cr3
615 and sBX, X86_CR3_AMD64_PAGE_MASK & 0ffffffffh
616 add sBX, sCX
617 mov sBX, [sBX]
618 and sBX, X86_PDPE_PG_MASK & 0ffffffffh
619 %else
620 mov sBX, cr3
621 and sBX, X86_CR3_PAE_PAGE_MASK
622 %endif
623
624 ; PDPE
625 mov sCX, sAX
626 shr sCX, X86_PDPT_SHIFT
627 %ifdef TMPL_CMN_LM
628 and sCX, X86_PDPT_MASK_AMD64
629 %else
630 and sCX, X86_PDPT_MASK_PAE
631 %endif
632 shl sCX, 3
633 add sBX, xCX
634 mov sBX, [sBX]
635 and sBX, X86_PDPE_PG_MASK & 0ffffffffh
636
637 ; PDE
638 shr sAX, X86_PD_PAE_SHIFT
639 and sAX, X86_PD_PAE_MASK
640 shl sAX, 3
641 add sAX, sBX
642%endif
643
644 pop sCX
645 pop sBX
646 leave
647 ret
648ENDPROC TMPL_NM(TestGetPdeAddr)
649
650
651%if PXE_SIZE == 8 ; PAE or LM
652;;
653; Gets the page directory pointer entry for an address.
654;
655; ASSUMES identity mapped page translation tables.
656;
657; @returns ds:xAX The pointer to the PDPE.
658; @param sAX The virtual address in question.
659; @uses nothing
660;
661BEGINPROC TMPL_NM(TestGetPdpeAddr)
662 push xBP
663 mov xBP, xSP
664 push sBX
665 push sCX
666
667%ifdef TMPL_CMN_PP
668 %error "misconfig"
669%endif
670
671%ifdef TMPL_CMN_LM
672 ; PML4E
673 mov sCX, sAX
674 shr sCX, X86_PML4_SHIFT
675 and sCX, X86_PML4_MASK
676 shl sCX, 3
677 mov sBX, cr3
678 and sBX, X86_CR3_AMD64_PAGE_MASK & 0ffffffffh
679 add sBX, sCX
680 mov sBX, [sBX]
681 and sBX, X86_PDPE_PG_MASK & 0ffffffffh
682%else
683 mov sBX, cr3
684 and sBX, X86_CR3_PAE_PAGE_MASK
685%endif
686
687 ; PDPE
688 shr sAX, X86_PDPT_SHIFT
689%ifdef TMPL_CMN_LM
690 and sAX, X86_PDPT_MASK_AMD64
691%else
692 and sAX, X86_PDPT_MASK_PAE
693%endif
694 shl sAX, 3
695 add sAX, sBX
696
697 pop sCX
698 pop sBX
699 leave
700 ret
701ENDPROC TMPL_NM(TestGetPdpeAddr)
702%endif ; PAE or LM
703
704
705%ifdef TMPL_CMN_LM
706;;
707; Gets the page map level 4 entry for an address.
708;
709; ASSUMES identity mapped page translation tables.
710;
711; @returns rax The pointer to the PML4E.
712; @param rax The virtual address in question.
713; @uses nothing
714;
715BEGINPROC TMPL_NM(TestGetPml4eAddr)
716 push xBP
717 mov xBP, xSP
718 push rbx
719
720 ; PML4E
721 shr rax, X86_PML4_SHIFT
722 and rax, X86_PML4_MASK
723 shl rax, 3
724 mov rbx, cr3
725 and rbx, X86_CR3_AMD64_PAGE_MASK & 0ffffffffh
726 add rax, rbx
727
728 pop rbx
729 leave
730 ret
731ENDPROC TMPL_NM(TestGetPml4eAddr)
732%endif ; TMPL_CMN_LM
733
734
735;;
736; Initialize page table #0 and hooks it up at the specified address.
737;
738; The page table will have identity mapped pages. The TLBs are flushed
739; wholesale. The caller will have to reconstruct the PDE when finished.
740;
741; @param sAX The virtual address (big page -> page table).
742; @uses nothing
743;
744BEGINPROC TMPL_NM(TstPutPageTableAt)
745 push xBP
746 mov xBP, xSP
747 push sAX
748 push sCX
749 push sDI
750 push sSI
751
752 ; initialize a page table.
753 mov sDI, BS2_USER_PX_0_ADDR
754 mov sSI, sAX
755.init_loop:
756%if PXE_SIZE == 8
757 mov [sDI + 4], dword 0
758 mov [sDI], sSI
759%else
760 mov [sDI], esi
761%endif
762 or byte [sDI], X86_PTE_P | X86_PTE_RW
763 add sSI, _4K
764 add sDI, PXE_SIZE
765 test sDI, 0fffh
766 jnz .init_loop
767
768 ; hook it up instead of the big page.
769 and sAX, ~(BIG_PAGE_SIZE - 1)
770 mov sDI, sAX
771 call TMPL_NM(TestGetPdeAddr)
772 mov dword [sAX], BS2_USER_PX_0_ADDR | X86_PDE_P | X86_PDE_RW | X86_PDE_RW
773%if PXE_SIZE == 8
774 mov dword [sAX + 4], 0
775%endif
776 mov sAX, cr3
777 mov cr3, sAX
778
779 ; Make sure it works.
780 mov eax, 0c3c3c3c3h
781 mov ecx, BIG_PAGE_SIZE / 4
782 rep stosd
783
784 pop sSI
785 pop sDI
786 pop sCX
787 pop sAX
788 leave
789 ret
790ENDPROC TMPL_NM(TstPutPageTableAt)
791
792
793;;
794; Restores the big page for a virtual address, undoing harm done by a
795; previous TstPutPageTableAt call.
796;
797; @param sAX The virtual address to restore to a big page.
798; @uses nothing
799;
800BEGINPROC TMPL_NM(TstRestoreBigPageAt)
801 push xBP
802 mov xBP, xSP
803 push sAX
804 push sCX
805 push sDI
806
807 ; Set it up, inheriting bits from the previous PDE.
808 and sAX, ~(BIG_PAGE_SIZE - 1)
809 mov sDI, sAX ; save it for later.
810 call TMPL_NM(TestGetPdeAddr)
811 mov sCX, [sAX - PXE_SIZE]
812 and sCX, X86_PDE4M_US | X86_PDE4M_RW | X86_PDE4M_G | X86_PDE4M_PAT | X86_PDE4M_AVL | X86_PDE4M_PCD | X86_PDE4M_PWT
813 or sCX, X86_PDE4M_P | X86_PDE4M_PS
814 or sCX, sDI
815%if PXE_SIZE == 8
816 mov dword [sAX + 4], 0
817 mov [sAX], sCX
818%else
819 mov [sAX], ecx
820%endif
821 mov sAX, cr3
822 mov cr3, sAX
823
824 ; Make sure it works.
825 mov eax, 0c3c3c3c3h
826 mov ecx, BIG_PAGE_SIZE / 4
827 rep stosd
828
829 pop sDI
830 pop sCX
831 pop sAX
832 leave
833 ret
834ENDPROC TMPL_NM(TstRestoreBigPageAt)
835
836
837
838;;
839; Hammers a page.
840;
841; Accesses a page in a few different ways, expecting all of the accesses to
842; cause some kind of page fault. The caller just makes sure the page causes
843; a fault and points us to it.
844;
845; @returns al=1, ZF=0 on success.
846; @returns al=0, ZF=1 on failure.
847; @param sAX The page.
848; @param sDX The base error code to expect.
849; @param xCX X86_TRAP_PF_ID if NXE, otherwise 0.
850; @uses al
851;
852BEGINPROC TMPL_NM(TestHammerPage)
853 push xBP
854 mov xBP, xSP
855 push sBX
856%define a_uErrorExec sPRE [xBP - sCB*2]
857 push sCX
858%define a_uErrorFixed sPRE [xBP - sCB*3]
859 push sDX
860 push sDI
861 push sSI
862%define a_pPage sPRE [xBP - sCB*6]
863 push sAX
864
865 ;
866 ; First reads of different sizes.
867 ;
868 mov sDI, a_pPage
869.read_byte_loop:
870 mov dl, 0ffh
871 mov xAX, .read_byte_resume
872 call TMPL_NM_CMN(Bs2TrapPrepare)
873.read_byte:
874 mov cl, byte [sDI]
875.read_byte_resume:
876 mov eax, 0eh ; trap #
877 mov sDX, a_uErrorFixed ; err
878 mov sCX, .read_byte ; fault eip
879 mov sBX, sDI ; fault address.
880 call TMPL_NM_CMN(TestCheckTrap)
881 jz .failed
882 inc sDI
883 test sDI, 0fffh
884 jnz .read_byte_loop
885
886 mov sDI, a_pPage
887.read_word_loop:
888 mov dl, 0ffh
889 mov xAX, .read_word_resume
890 call TMPL_NM_CMN(Bs2TrapPrepare)
891.read_word:
892 mov cx, word [sDI]
893.read_word_resume:
894 mov eax, 0eh ; trap #
895 mov sDX, a_uErrorFixed ; err
896 mov sCX, .read_word ; fault eip
897 mov sBX, sDI ; fault address.
898 call TMPL_NM_CMN(TestCheckTrap)
899 jz .failed
900 inc sDI
901 test sDI, 0fffh
902 jnz .read_word_loop
903
904 mov sDI, a_pPage
905.read_dword_loop:
906 mov dl, 0ffh
907 mov xAX, .read_dword_resume
908 call TMPL_NM_CMN(Bs2TrapPrepare)
909.read_dword:
910 mov ecx, dword [sDI]
911.read_dword_resume:
912 mov eax, 0eh ; trap #
913 mov sDX, a_uErrorFixed ; err
914 mov sCX, .read_dword ; fault eip
915 mov sBX, sDI ; fault address.
916 call TMPL_NM_CMN(TestCheckTrap)
917 jz .failed
918 inc sDI
919 test sDI, 0fffh
920 jnz .read_dword_loop
921
922 ;
923 ; Then writes of different sizes.
924 ;
925 mov sDI, a_pPage
926.write_byte_loop:
927 mov dl, 0ffh
928 mov xAX, .write_byte_resume
929 call TMPL_NM_CMN(Bs2TrapPrepare)
930.write_byte:
931 mov byte [sDI], 0c3h ; (ret instruction)
932.write_byte_resume:
933 mov eax, 0eh ; trap #
934 mov sDX, a_uErrorFixed ; err
935 or sDX, X86_TRAP_PF_RW
936 mov sCX, .write_byte ; fault eip
937 mov sBX, sDI ; fault address.
938 call TMPL_NM_CMN(TestCheckTrap)
939 jz .failed
940 inc sDI
941 test sDI, 0fffh
942 jnz .write_byte_loop
943
944 mov sDI, a_pPage
945.write_word_loop:
946 mov dl, 0ffh
947 mov xAX, .write_word_resume
948 call TMPL_NM_CMN(Bs2TrapPrepare)
949.write_word:
950 mov word [sDI], 0c3c3h ; (2 ret instructions)
951.write_word_resume:
952 mov eax, 0eh ; trap #
953 mov sDX, a_uErrorFixed ; err
954 or sDX, X86_TRAP_PF_RW
955 mov sCX, .write_word ; fault eip
956 mov sBX, sDI ; fault address.
957 call TMPL_NM_CMN(TestCheckTrap)
958 jz .failed
959 inc sDI
960 test sDI, 0fffh
961 jnz .write_word_loop
962
963 mov sDI, a_pPage
964.write_dword_loop:
965 mov dl, 0ffh
966 mov xAX, .write_dword_resume
967 call TMPL_NM_CMN(Bs2TrapPrepare)
968.write_dword:
969 mov dword [sDI], 0c3c3c3c3h ; (4 ret instructions)
970.write_dword_resume:
971 mov eax, 0eh ; trap #
972 mov sDX, a_uErrorFixed ; err
973 or sDX, X86_TRAP_PF_RW
974 mov sCX, .write_dword ; fault eip
975 mov sBX, sDI ; fault address.
976 call TMPL_NM_CMN(TestCheckTrap)
977 jz .failed
978 inc sDI
979 test sDI, 0fffh
980 jnz .write_dword_loop
981
982 ;
983 ; Execute access.
984 ;
985 mov sDI, a_pPage
986 mov xSI, xSP
987.call_loop:
988 mov dl, 0ffh
989 mov xAX, .call_resume
990 call TMPL_NM_CMN(Bs2TrapPrepare)
991 call sDI
992.call_resume:
993 mov xSP, xSI ; restore xSP since the call will change it before #PF'ing.
994 mov eax, 0eh ; trap #
995 mov sDX, a_uErrorFixed ; err
996 or sDX, a_uErrorExec
997 mov sCX, sDI ; fault eip
998 mov sBX, sDI ; fault address.
999 call TMPL_NM_CMN(TestCheckTrap)
1000 jz .failed
1001 inc sDI
1002 test sDI, 0fffh
1003 jnz .call_loop
1004
1005
1006 mov sDI, a_pPage
1007 mov xSI, xSP
1008.jmp_loop:
1009 mov dl, 0ffh
1010 mov xAX, .jmp_resume
1011 call TMPL_NM_CMN(Bs2TrapPrepare)
1012 push .jmp_resume ; push a return address in case of failure.
1013 jmp sDI
1014.jmp_resume:
1015 mov xSP, xSI ; restore xSP in case the jmp didn't trap.
1016 mov eax, 0eh ; trap #
1017 mov sDX, a_uErrorFixed ; err
1018 or sDX, a_uErrorExec
1019 mov sCX, sDI ; fault eip
1020 mov sBX, sDI ; fault address.
1021 call TMPL_NM_CMN(TestCheckTrap)
1022 jz .failed
1023 inc sDI
1024 test sDI, 0fffh
1025 jnz .jmp_loop
1026
1027 ; successfull return.
1028 pop sAX
1029 xor al, al
1030 inc al
1031.return:
1032 pop sSI
1033 pop sDI
1034 pop sDX
1035 pop sCX
1036 pop sBX
1037 leave
1038 ret
1039
1040.failed:
1041 pop sAX
1042 xor al, al
1043 jmp .return
1044%undef a_uErrorFixed
1045%undef a_uErrorExec
1046%undef a_pPage
1047ENDPROC TMPL_NM(TestHammerPage)
1048
1049
1050%include "bootsector2-template-footer.mac"
1051
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