cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Bootsector test for various types of #PFs - multi mode template.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Copyright (C) 2007-2014 Oracle Corporation
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; This file is part of VirtualBox Open Source Edition (OSE), as
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; available from http://www.virtualbox.org. This file is free software;
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; you can redistribute it and/or modify it under the terms of the GNU
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; General Public License (GPL) as published by the Free Software
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Foundation, in version 2 as it comes in the "COPYING" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; The contents of this file may alternatively be used under the terms
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; of the Common Development and Distribution License Version 1.0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; (CDDL) only, as it comes in the "COPYING.CDDL" file of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; VirtualBox OSE distribution, in which case the provisions of the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; CDDL are applicable instead of those of the GPL.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; You may elect to license modified versions of this file under the
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; terms and conditions of either the GPL or the CDDL or both.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;*******************************************************************************
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;* Defined Constants And Macros *
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync;*******************************************************************************
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%undef BIG_PAGE_SIZE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%undef PXE_SIZE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef TMPL_CMN_PP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BIG_PAGE_SIZE _4M
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define PXE_SIZE 4
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define BIG_PAGE_SIZE _2M
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %define PXE_SIZE 8
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Do the tests for this mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC TMPL_NM(DoTestsForMode_rm)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Check if the mode and NX is supported, do the switch.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(Bs2IsModeSupported_rm)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ax, [bp - 2]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test al, al
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .nx_disabled
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call Bs2IsNXSupported_r86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call Bs2EnableNX_r86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.nx_disabled:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(Bs2EnterMode_rm)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBITS TMPL_BITS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Do the tests.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestNotPresent)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ;; @todo call TMPL_NM(TestReadOnly)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ;; @todo call TMPL_NM(TestSupervisor)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ;; @todo call TMPL_NM(TestReservedBits)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Back to real mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(Bs2ExitMode)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call Bs2DisableNX_r86
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC TMPL_NM(DoTestsForMode_rm)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncTMPL_BEGINCODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBITS TMPL_BITS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Do the tests for this mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINCODELOW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC TMPL_NM(DoBenchmarksForMode_rm)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Check if the mode and NX is supported, do the switch.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(Bs2IsModeSupported_rm)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(Bs2EnterMode_rm)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBITS TMPL_BITS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Do the tests.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(BenchmarkNotPresent)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Back to real mode.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(Bs2ExitMode)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC TMPL_NM(DoBenchmarksForMode_rm)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncTMPL_BEGINCODE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBITS TMPL_BITS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Does the page-not-present tests.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @param al Set if NXE=1, clear if NXE=0.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC TMPL_NM(TestNotPresent)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xBP, xSP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Setup sCX for all the following tests.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync xor sCX, sCX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test al, al
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sCX, X86_TRAP_PF_ID
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; First test, big page not present.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .s_szBigPageNotPresent
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test sCX, sCX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .test1_nxe
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .s_szBigPageNotPresentNX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(TestSub)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestFillTestAreaWithRet)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PD_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestGetPdeAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [sAX], ~X86_PTE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PD_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDX, 0 ; err code
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestHammerPage)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .test1_cleanup
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PD_BASE + (BIG_PAGE_SIZE / 2 - _4K)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestHammerPage)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .test1_cleanup
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PD_BASE + (BIG_PAGE_SIZE - _4K)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestHammerPage)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .test1_cleanup
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.test1_cleanup:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PD_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestGetPdeAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or byte [sAX], X86_PTE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; The second test, normal page not present.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .s_szPageNotPresent
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test sCX, sCX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .test2_nxe
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .s_szPageNotPresentNX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(TestSub)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PD_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TstPutPageTableAt)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Make the first and last page not-present.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [BS2_USER_PX_0_ADDR], ~X86_PTE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [BS2_USER_PX_0_ADDR + 01000h - PXE_SIZE], ~X86_PTE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Do the tests.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PD_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDX, 0 ; err code
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestHammerPage)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .test2_cleanup
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PD_BASE + (BIG_PAGE_SIZE - _4K)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestHammerPage)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .test2_cleanup
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.test2_cleanup:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PD_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TstRestoreBigPageAt)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%if PXE_SIZE == 8 ; PAE or LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; The third test, mark a page directory pointer entry not present.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .s_szPdpeNotPresent
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test sCX, sCX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .test3_nxe
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .s_szPdpeNotPresentNX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(TestSub)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestFillTestAreaWithRet)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PDPT_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestGetPdpeAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [sAX], ~X86_PTE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PDPT_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDX, 0 ; err code
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestHammerPage)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .test3_cleanup
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PDPT_BASE + (BIG_PAGE_SIZE / 2 - _4K)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestHammerPage)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .test3_cleanup
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PDPT_BASE + (BIG_PAGE_SIZE - _4K)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestHammerPage)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .test3_cleanup
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.test3_cleanup:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PDPT_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestGetPdpeAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or byte [sAX], X86_PTE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; PAE || LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef TMPL_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; The fourth test, mark a page map level 4 entry not present.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .s_szPml4eNotPresent
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test sCX, sCX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .test4_nxe
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .s_szPml4eNotPresentNX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(TestSub)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestFillTestAreaWithRet)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PML4_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestGetPml4eAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [sAX], ~X86_PTE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PML4_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDX, 0 ; err code
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestHammerPage)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .test4_cleanup
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PML4_BASE + (BIG_PAGE_SIZE / 2 - _4K)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestHammerPage)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .test4_cleanup
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PML4_BASE + (BIG_PAGE_SIZE - _4K)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestHammerPage)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jz .test4_cleanup
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.test4_cleanup:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PML4_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestGetPml4eAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or byte [sAX], X86_PTE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(TestSubDone)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.s_szBigPageNotPresent:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db TMPL_MODE_STR, ', !NX, big page NP', 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.s_szBigPageNotPresentNX:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db TMPL_MODE_STR, ', NX, big page NP', 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.s_szPageNotPresent:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db TMPL_MODE_STR, ', !NX, page NP', 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.s_szPageNotPresentNX:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db TMPL_MODE_STR, ', NX, page NP', 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%if PXE_SIZE == 8 ; PAE or LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.s_szPdpeNotPresent:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db TMPL_MODE_STR, ', !NX, PDPE NP', 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.s_szPdpeNotPresentNX:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db TMPL_MODE_STR, ', NX, PDPE NP', 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef TMPL_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.s_szPml4eNotPresent:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db TMPL_MODE_STR, ', !NX, PML4E NP', 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.s_szPml4eNotPresentNX:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db TMPL_MODE_STR, ', NX, PML4E NP', 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC TMPL_NM(TestNotPresent)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Does the page-not-present benchmark.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC TMPL_NM(BenchmarkNotPresent)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xBP, xSP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sub xSP, 20h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestFillTestAreaWithRet)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; The First benchmark: Big page not present.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Mark the big test page not present.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PD_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestGetPdeAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [sAX], ~X86_PTE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Benchmark.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PD_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xDX, .s_szBigPageNotPresent
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xCX, .s_szBigPageNotPresentFailed
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TstBenchmark32BitReads)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PD_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestGetPdeAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or byte [sAX], X86_PTE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; The second benchmark: Normal page not present.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Replace the big page with a page table and make the first and last
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; pages not-present.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PD_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TstPutPageTableAt)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [BS2_USER_PX_0_ADDR], ~X86_PTE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and byte [BS2_USER_PX_0_ADDR + 01000h - PXE_SIZE], ~X86_PTE_P
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Benchmark.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PD_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xDX, .s_szPageNotPresent
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xCX, .s_szPageNotPresentFailed
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TstBenchmark32BitReads)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, TST_SCRATCH_PD_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TstRestoreBigPageAt)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add xSP, 20h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.s_szBigPageNotPresent:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db TMPL_MODE_STR, ', read NP big page', 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.s_szBigPageNotPresentFailed:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db TMPL_MODE_STR, ', reading NP big page failed', 13, 10, 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.s_szPageNotPresent:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db TMPL_MODE_STR, ', read NP page', 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.s_szPageNotPresentFailed:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync db TMPL_MODE_STR, ', reading NP page failed', 13, 10, 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC TMPL_NM(BenchmarkNotPresent)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Benchmark 32-bit reads at a give location.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Will report the result under the name given via xDX. Will report any test
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; failure giving the string pointed to by xCX as explanation.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @param sAX The location to do the reads.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @param xDX The test value name.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @param xCX The failure string
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC TMPL_NM(TstBenchmark32BitReads)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xBP, xSP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define a_pu32Test [xBP - sCB]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define a_pszValue [xBP - sCB*2]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define a_pszFailure [xBP - sCB*3]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define u64NanoTS [xBP - sCB*5 - 8h]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync sub xSP, 8h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Calibrate the test so it doesn't take forever.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .calibrate_resume
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dl, 0eh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(Bs2TrapPrepare)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ecx, TST_CALIBRATE_LOOP_COUNT
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lea xAX, u64NanoTS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(GetNanoTS)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.calibrate_loop:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, a_pu32Test
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov esi, [sAX]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.calibrate_resume:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test sAX, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .failure
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .calibrate_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lea xAX, u64NanoTS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(GetElapsedNanoTS)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(Bs2TrapReset)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Figure out how many iterations is required for the full benchmark.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ecx, TST_BENCHMARK_PERIOD_IN_SECS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov edx, TST_CALIBRATE_LOOP_COUNT
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, xSP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(CalcBenchmarkIterations)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ecx, eax ; iteration count.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Do the full benchmark run.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .bench_resume
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dl, 0eh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(Bs2TrapPrepare)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov edx, ecx ; save test count for ReportResult.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lea xAX, u64NanoTS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(GetNanoTS)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.bench_loop:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, a_pu32Test
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov esi, [eax]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.bench_resume:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test eax, eax
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .failure
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .bench_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lea xAX, u64NanoTS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(GetElapsedNanoTS)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(Bs2TrapReset)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xCX, a_pszValue
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync lea xAX, u64NanoTS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(ReportResult)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(Bs2TrapReset)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, a_pszFailure
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(TestFailed)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp .return
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%undef a_pszFailure
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%undef a_pu32Test
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%undef a_pszValue
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%undef a_pszFailure
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%undef u64NanoTS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC TMPL_NM(TstBenchmark32BitReads)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Fills the test area with return instructions.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC TMPL_NM(TestFillTestAreaWithRet)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xBP, xSP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xDI, TST_SCRATCH_PD_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xCX, (_4M + _4M) / 4
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, 0c3c3c3c3h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xDI, TST_SCRATCH_PDPT_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xCX, (_4M + _4M) / 4
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, 0c3c3c3c3h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef TMPL_LM64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xDI, TST_SCRATCH_PML4_BASE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xCX, (_4M + _4M) / 8
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov rax, 0c3c3c3c3c3c3c3c3h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC TMPL_NM(TestFillTestAreaWithRet)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Gets the page directory address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; ASSUMES identity mapped page translation tables.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns ds:xAX The page directory address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @param sAX The virtual address in question.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC TMPL_NM(TestGetPdeAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xBP, xSP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef TMPL_CMN_PP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync shr sAX, X86_PD_SHIFT
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sAX, X86_PD_MASK
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sBX, X86_CR3_PAGE_MASK
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add sAX, sBX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %ifdef TMPL_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sCX, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync shr sCX, X86_PML4_SHIFT
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sCX, X86_PML4_MASK
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sBX, X86_CR3_AMD64_PAGE_MASK & 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add sBX, sCX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, [sBX]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sBX, X86_PDPE_PG_MASK & 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sBX, X86_CR3_PAE_PAGE_MASK
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sCX, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync shr sCX, X86_PDPT_SHIFT
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %ifdef TMPL_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sCX, X86_PDPT_MASK_AMD64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sCX, X86_PDPT_MASK_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add sBX, xCX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, [sBX]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sBX, X86_PDPE_PG_MASK & 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync shr sAX, X86_PD_PAE_SHIFT
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sAX, X86_PD_PAE_MASK
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add sAX, sBX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC TMPL_NM(TestGetPdeAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%if PXE_SIZE == 8 ; PAE or LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Gets the page directory pointer entry for an address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; ASSUMES identity mapped page translation tables.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns ds:xAX The pointer to the PDPE.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @param sAX The virtual address in question.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC TMPL_NM(TestGetPdpeAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xBP, xSP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef TMPL_CMN_PP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync %error "misconfig"
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef TMPL_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sCX, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync shr sCX, X86_PML4_SHIFT
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sCX, X86_PML4_MASK
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sBX, X86_CR3_AMD64_PAGE_MASK & 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add sBX, sCX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, [sBX]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sBX, X86_PDPE_PG_MASK & 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sBX, X86_CR3_PAE_PAGE_MASK
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync shr sAX, X86_PDPT_SHIFT
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef TMPL_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sAX, X86_PDPT_MASK_AMD64
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sAX, X86_PDPT_MASK_PAE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add sAX, sBX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC TMPL_NM(TestGetPdpeAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; PAE or LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%ifdef TMPL_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Gets the page map level 4 entry for an address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; ASSUMES identity mapped page translation tables.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns rax The pointer to the PML4E.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @param rax The virtual address in question.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC TMPL_NM(TestGetPml4eAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xBP, xSP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync shr rax, X86_PML4_SHIFT
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and rax, X86_PML4_MASK
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov rbx, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and rbx, X86_CR3_AMD64_PAGE_MASK & 0ffffffffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add rax, rbx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC TMPL_NM(TestGetPml4eAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%endif ; TMPL_CMN_LM
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Initialize page table #0 and hooks it up at the specified address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; The page table will have identity mapped pages. The TLBs are flushed
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; wholesale. The caller will have to reconstruct the PDE when finished.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @param sAX The virtual address (big page -> page table).
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC TMPL_NM(TstPutPageTableAt)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xBP, xSP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; initialize a page table.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDI, BS2_USER_PX_0_ADDR
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sSI, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%if PXE_SIZE == 8
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [sDI + 4], dword 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [sDI], sSI
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [sDI], esi
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or byte [sDI], X86_PTE_P | X86_PTE_RW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add sSI, _4K
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync add sDI, PXE_SIZE
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test sDI, 0fffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .init_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; hook it up instead of the big page.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sAX, ~(BIG_PAGE_SIZE - 1)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDI, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestGetPdeAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [sAX], BS2_USER_PX_0_ADDR | X86_PDE_P | X86_PDE_RW | X86_PDE_RW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%if PXE_SIZE == 8
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [sAX + 4], 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Make sure it works.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, 0c3c3c3c3h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ecx, BIG_PAGE_SIZE / 4
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC TMPL_NM(TstPutPageTableAt)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Restores the big page for a virtual address, undoing harm done by a
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; previous TstPutPageTableAt call.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @param sAX The virtual address to restore to a big page.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @uses nothing
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC TMPL_NM(TstRestoreBigPageAt)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xBP, xSP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Set it up, inheriting bits from the previous PDE.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sAX, ~(BIG_PAGE_SIZE - 1)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDI, sAX ; save it for later.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM(TestGetPdeAddr)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sCX, [sAX - PXE_SIZE]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync and sCX, X86_PDE4M_US | X86_PDE4M_RW | X86_PDE4M_G | X86_PDE4M_PAT | X86_PDE4M_AVL | X86_PDE4M_PCD | X86_PDE4M_PWT
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or sCX, X86_PDE4M_P | X86_PDE4M_PS
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or sCX, sDI
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%if PXE_SIZE == 8
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [sAX + 4], 0
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [sAX], sCX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov [sAX], ecx
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sAX, cr3
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cr3, sAX
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Make sure it works.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, 0c3c3c3c3h
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ecx, BIG_PAGE_SIZE / 4
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC TMPL_NM(TstRestoreBigPageAt)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Hammers a page.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; Accesses a page in a few different ways, expecting all of the accesses to
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; cause some kind of page fault. The caller just makes sure the page causes
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; a fault and points us to it.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns al=1, ZF=0 on success.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @returns al=0, ZF=1 on failure.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @param sAX The page.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @param sDX The base error code to expect.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync; @param xCX X86_TRAP_PF_ID if NXE, otherwise 0.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncBEGINPROC TMPL_NM(TestHammerPage)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xBP, xSP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define a_uErrorExec sPRE [xBP - sCB*2]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define a_uErrorFixed sPRE [xBP - sCB*3]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%define a_pPage sPRE [xBP - sCB*6]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; First reads of different sizes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDI, a_pPage
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.read_byte_loop:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dl, 0ffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .read_byte_resume
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(Bs2TrapPrepare)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cl, byte [sDI]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.read_byte_resume:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, 0eh ; trap #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDX, a_uErrorFixed ; err
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sCX, .read_byte ; fault eip
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, sDI ; fault address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(TestCheckTrap)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test sDI, 0fffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .read_byte_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDI, a_pPage
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.read_word_loop:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dl, 0ffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .read_word_resume
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(Bs2TrapPrepare)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov cx, word [sDI]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.read_word_resume:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, 0eh ; trap #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDX, a_uErrorFixed ; err
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sCX, .read_word ; fault eip
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, sDI ; fault address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(TestCheckTrap)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test sDI, 0fffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .read_word_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDI, a_pPage
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.read_dword_loop:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dl, 0ffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .read_dword_resume
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(Bs2TrapPrepare)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.read_dword:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov ecx, dword [sDI]
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.read_dword_resume:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, 0eh ; trap #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDX, a_uErrorFixed ; err
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sCX, .read_dword ; fault eip
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, sDI ; fault address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(TestCheckTrap)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test sDI, 0fffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .read_dword_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Then writes of different sizes.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDI, a_pPage
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.write_byte_loop:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dl, 0ffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .write_byte_resume
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(Bs2TrapPrepare)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.write_byte:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov byte [sDI], 0c3h ; (ret instruction)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.write_byte_resume:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, 0eh ; trap #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDX, a_uErrorFixed ; err
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or sDX, X86_TRAP_PF_RW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sCX, .write_byte ; fault eip
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, sDI ; fault address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(TestCheckTrap)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test sDI, 0fffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .write_byte_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDI, a_pPage
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.write_word_loop:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dl, 0ffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .write_word_resume
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(Bs2TrapPrepare)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.write_word:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov word [sDI], 0c3c3h ; (2 ret instructions)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.write_word_resume:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, 0eh ; trap #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDX, a_uErrorFixed ; err
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or sDX, X86_TRAP_PF_RW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sCX, .write_word ; fault eip
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, sDI ; fault address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(TestCheckTrap)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test sDI, 0fffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .write_word_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDI, a_pPage
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.write_dword_loop:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dl, 0ffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .write_dword_resume
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(Bs2TrapPrepare)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.write_dword:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dword [sDI], 0c3c3c3c3h ; (4 ret instructions)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.write_dword_resume:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, 0eh ; trap #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDX, a_uErrorFixed ; err
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or sDX, X86_TRAP_PF_RW
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sCX, .write_dword ; fault eip
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, sDI ; fault address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(TestCheckTrap)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test sDI, 0fffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .write_dword_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; Execute access.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDI, a_pPage
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xSI, xSP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dl, 0ffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .call_resume
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(Bs2TrapPrepare)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.call_resume:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xSP, xSI ; restore xSP since the call will change it before #PF'ing.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, 0eh ; trap #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDX, a_uErrorFixed ; err
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or sDX, a_uErrorExec
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sCX, sDI ; fault eip
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, sDI ; fault address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(TestCheckTrap)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test sDI, 0fffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .call_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDI, a_pPage
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xSI, xSP
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov dl, 0ffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xAX, .jmp_resume
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(Bs2TrapPrepare)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync push .jmp_resume ; push a return address in case of failure.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync.jmp_resume:
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov xSP, xSI ; restore xSP in case the jmp didn't trap.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov eax, 0eh ; trap #
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sDX, a_uErrorFixed ; err
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync or sDX, a_uErrorExec
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sCX, sDI ; fault eip
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync mov sBX, sDI ; fault address.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync call TMPL_NM_CMN(TestCheckTrap)
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync test sDI, 0fffh
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jnz .jmp_loop
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync ; successfull return.
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync jmp .return
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%undef a_uErrorFixed
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%undef a_uErrorExec
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsync%undef a_pPage
cf22150eaeeb72431bf1cf65c309a431454fb22bvboxsyncENDPROC TMPL_NM(TestHammerPage)