public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Michael D Kinney" <michael.d.kinney@intel.com>
To: "Gao, Liming" <liming.gao@intel.com>,
	"devel@edk2.groups.io" <devel@edk2.groups.io>,
	"Kinney, Michael D" <michael.d.kinney@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>,
	Bret Barkelew <Bret.Barkelew@microsoft.com>,
	"Yao, Jiewen" <jiewen.yao@intel.com>
Subject: Re: [Patch v2 05/16] MdePkg/Library/BaseLib: Add BaseLib instance for host based unit tests
Date: Thu, 9 Jul 2020 17:05:25 +0000	[thread overview]
Message-ID: <MN2PR11MB44617368CA63B626EF1BFF8AD2640@MN2PR11MB4461.namprd11.prod.outlook.com> (raw)
In-Reply-To: <MWHPR11MB1630120865B7E4E0AA0AE89D80640@MWHPR11MB1630.namprd11.prod.outlook.com>

Hi Liming,

I made the LIBRARY_CLASS BaseLib on purpose.

  LIBRARY_CLASS                  = BaseLib|HOST_APPLICATION

When building a host based test for code under test,
that code under test may have a dependency on the
BaseLib class and that means we need a BaseLib instance
to be resolved.  Notice that this new instance of the
BaseLib class is declared to only be compatible with
modules of type HOST_APPLICATION, so it can not be 
accidently used with a FW module.

Best regards,

Mike

> -----Original Message-----
> From: Gao, Liming <liming.gao@intel.com>
> Sent: Thursday, July 9, 2020 7:13 AM
> To: Kinney, Michael D <michael.d.kinney@intel.com>;
> devel@edk2.groups.io
> Cc: Sean Brogan <sean.brogan@microsoft.com>; Bret
> Barkelew <Bret.Barkelew@microsoft.com>; Yao, Jiewen
> <jiewen.yao@intel.com>
> Subject: RE: [Patch v2 05/16] MdePkg/Library/BaseLib:
> Add BaseLib instance for host based unit tests
> 
> Mike:
>   New library instance library class should be
> UnitTestHostBaseLib instead of BaseLib.
> 
> Thanks
> Liming
> > -----Original Message-----
> > From: Kinney, Michael D <michael.d.kinney@intel.com>
> > Sent: Thursday, July 9, 2020 12:05 PM
> > To: devel@edk2.groups.io
> > Cc: Gao, Liming <liming.gao@intel.com>; Sean Brogan
> <sean.brogan@microsoft.com>; Bret Barkelew
> <Bret.Barkelew@microsoft.com>;
> > Yao, Jiewen <jiewen.yao@intel.com>
> > Subject: [Patch v2 05/16] MdePkg/Library/BaseLib: Add
> BaseLib instance for host based unit tests
> >
> > REF:
> https://bugzilla.tianocore.org/show_bug.cgi?id=2800
> >
> > Add a new version of BaseLib that is safe for use from
> host based
> > unit test applications.  Host based unit test
> applications may need
> > to provide implementations of some BaseLib functions
> that provide
> > simple emulation to exercise the code under test.  The
> structure
> > UNIT_TEST_HOST_BASE_LIB is filled in with services
> that provide
> > default emulation for BaseLib APIs that would normally
> generate
> > exceptions in a host based unit test application.
> This structure
> > allows an individual unit test to replace the default
> emulation of
> > a BaseLib service with an alternate version that is
> required by a
> > specific unit test.
> >
> > Normally cmocka would be used to mock services the
> code under
> > test calls.  However, the BaseLib is used by the Unit
> Test
> > Framework itself, so using a mocked interface is not
> possible.
> > The use of a structure to provide hooks for unit test
> is not
> > expected to be a common feature.  It should only be
> required
> > for libraries that are used by both the Unit Test
> Framework and
> > the code under test where the code under test requires
> a
> > different behavior than the Unit Test Framework.
> >
> > Cc: Liming Gao <liming.gao@intel.com>
> > Cc: Sean Brogan <sean.brogan@microsoft.com>
> > Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
> > Cc: Jiewen Yao <jiewen.yao@intel.com>
> > Signed-off-by: Michael D Kinney
> <michael.d.kinney@intel.com>
> > ---
> >  MdePkg/Library/BaseLib/UnitTestHost.c         |  140
> +
> >  MdePkg/Library/BaseLib/UnitTestHost.h         |   66
> +
> >  .../Library/BaseLib/UnitTestHostBaseLib.inf   |  216
> ++
> >  .../Library/BaseLib/UnitTestHostBaseLib.uni   |   11
> +
> >  MdePkg/Library/BaseLib/X86UnitTestHost.c      | 2977
> +++++++++++++++++
> >  MdePkg/MdePkg.dec                             |    3
> +-
> >  MdePkg/Test/MdePkgHostTest.dsc                |    5
> +
> >  .../Include/HostTest/UnitTestHostBaseLib.h    |  582
> ++++
> >  8 files changed, 3999 insertions(+), 1 deletion(-)
> >  create mode 100644
> MdePkg/Library/BaseLib/UnitTestHost.c
> >  create mode 100644
> MdePkg/Library/BaseLib/UnitTestHost.h
> >  create mode 100644
> MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
> >  create mode 100644
> MdePkg/Library/BaseLib/UnitTestHostBaseLib.uni
> >  create mode 100644
> MdePkg/Library/BaseLib/X86UnitTestHost.c
> >  create mode 100644
> MdePkg/Test/UnitTest/Include/HostTest/UnitTestHostBaseLi
> b.h
> >
> > diff --git a/MdePkg/Library/BaseLib/UnitTestHost.c
> b/MdePkg/Library/BaseLib/UnitTestHost.c
> > new file mode 100644
> > index 0000000000..79eec7caca
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseLib/UnitTestHost.c
> > @@ -0,0 +1,140 @@
> > +/** @file
> > +  Common Unit Test Host functions.
> > +
> > +  Copyright (c) 2020, Intel Corporation. All rights
> reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "UnitTestHost.h"
> > +
> > +///
> > +/// Module global variable for simple system
> emulation of interrupt state
> > +///
> > +STATIC BOOLEAN
> mUnitTestHostBaseLibInterruptState;
> > +
> > +/**
> > +  Enables CPU interrupts.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibEnableInterrupts (
> > +  VOID
> > +  )
> > +{
> > +  mUnitTestHostBaseLibInterruptState = TRUE;
> > +}
> > +
> > +/**
> > +  Disables CPU interrupts.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibDisableInterrupts (
> > +  VOID
> > +  )
> > +{
> > +  mUnitTestHostBaseLibInterruptState = FALSE;
> > +}
> > +
> > +/**
> > +  Enables CPU interrupts for the smallest window
> required to capture any
> > +  pending interrupts.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibEnableDisableInterrupts (
> > +  VOID
> > +  )
> > +{
> > +  mUnitTestHostBaseLibInterruptState = FALSE;
> > +}
> > +
> > +/**
> > +  Set the current CPU interrupt state.
> > +
> > +  Sets the current CPU interrupt state to the state
> specified by
> > +  InterruptState. If InterruptState is TRUE, then
> interrupts are enabled. If
> > +  InterruptState is FALSE, then interrupts are
> disabled. InterruptState is
> > +  returned.
> > +
> > +  @param  InterruptState  TRUE if interrupts should
> enabled. FALSE if
> > +                          interrupts should be
> disabled.
> > +
> > +  @return InterruptState
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +UnitTestHostBaseLibGetInterruptState (
> > +  VOID
> > +  )
> > +{
> > +  return mUnitTestHostBaseLibInterruptState;
> > +}
> > +
> > +/**
> > +  Enables CPU interrupts.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +EnableInterrupts (
> > +  VOID
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.Common->EnableInterrupts ();
> > +}
> > +
> > +/**
> > +  Disables CPU interrupts.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +DisableInterrupts (
> > +  VOID
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.Common->DisableInterrupts ();
> > +}
> > +
> > +/**
> > +  Enables CPU interrupts for the smallest window
> required to capture any
> > +  pending interrupts.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +EnableDisableInterrupts (
> > +  VOID
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.Common-
> >EnableDisableInterrupts ();
> > +}
> > +
> > +/**
> > +  Set the current CPU interrupt state.
> > +
> > +  Sets the current CPU interrupt state to the state
> specified by
> > +  InterruptState. If InterruptState is TRUE, then
> interrupts are enabled. If
> > +  InterruptState is FALSE, then interrupts are
> disabled. InterruptState is
> > +  returned.
> > +
> > +  @param  InterruptState  TRUE if interrupts should
> enabled. FALSE if
> > +                          interrupts should be
> disabled.
> > +
> > +  @return InterruptState
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +GetInterruptState (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.Common-
> >GetInterruptState ();
> > +}
> > diff --git a/MdePkg/Library/BaseLib/UnitTestHost.h
> b/MdePkg/Library/BaseLib/UnitTestHost.h
> > new file mode 100644
> > index 0000000000..6a51fb468c
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseLib/UnitTestHost.h
> > @@ -0,0 +1,66 @@
> > +/** @file
> > +  Unit Test Host functions.
> > +
> > +  Copyright (c) 2020, Intel Corporation. All rights
> reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef __UNIT_TEST_HOST_H__
> > +#define __UNIT_TEST_HOST_H__
> > +
> > +#include "BaseLibInternals.h"
> > +#include <HostTest/UnitTestHostBaseLib.h>
> > +
> > +/**
> > +  Enables CPU interrupts.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibEnableInterrupts (
> > +  VOID
> > +  );
> > +
> > +/**
> > +  Disables CPU interrupts.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibDisableInterrupts (
> > +  VOID
> > +  );
> > +
> > +/**
> > +  Enables CPU interrupts for the smallest window
> required to capture any
> > +  pending interrupts.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibEnableDisableInterrupts (
> > +  VOID
> > +  );
> > +
> > +/**
> > +  Set the current CPU interrupt state.
> > +
> > +  Sets the current CPU interrupt state to the state
> specified by
> > +  InterruptState. If InterruptState is TRUE, then
> interrupts are enabled. If
> > +  InterruptState is FALSE, then interrupts are
> disabled. InterruptState is
> > +  returned.
> > +
> > +  @param  InterruptState  TRUE if interrupts should
> enabled. FALSE if
> > +                          interrupts should be
> disabled.
> > +
> > +  @return InterruptState
> > +
> > +**/
> > +BOOLEAN
> > +EFIAPI
> > +UnitTestHostBaseLibGetInterruptState (
> > +  VOID
> > +  );
> > +
> > +#endif
> > diff --git
> a/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
> b/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
> > new file mode 100644
> > index 0000000000..f95daa5e33
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
> > @@ -0,0 +1,216 @@
> > +## @file
> > +#  Base Library implementation for use with host
> based unit tests.
> > +#
> > +#  Copyright (c) 2007 - 2020, Intel Corporation. All
> rights reserved.<BR>
> > +#  Portions copyright (c) 2008 - 2009, Apple Inc. All
> rights reserved.<BR>
> > +#  Portions copyright (c) 2011 - 2013, ARM Ltd. All
> rights reserved.<BR>
> > +#  Copyright (c) 2020, Hewlett Packard Enterprise
> Development LP. All rights reserved.<BR>
> > +#
> > +#  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +#
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    = 0x00010005
> > +  BASE_NAME                      =
> UnitTestHostBaseLib
> > +  MODULE_UNI_FILE                =
> UnitTestHostBaseLib.uni
> > +  FILE_GUID                      = 9555A0D3-09BA-
> 46C4-A51A-45198E3C765E
> > +  MODULE_TYPE                    = BASE
> > +  VERSION_STRING                 = 1.1
> > +  LIBRARY_CLASS                  =
> BaseLib|HOST_APPLICATION
> > +
> > +#
> > +#  VALID_ARCHITECTURES           = IA32 X64 EBC ARM
> AARCH64 RISCV64
> > +#
> > +
> > +[Sources]
> > +  CheckSum.c
> > +  SwitchStack.c
> > +  SwapBytes64.c
> > +  SwapBytes32.c
> > +  SwapBytes16.c
> > +  LongJump.c
> > +  SetJump.c
> > +  RShiftU64.c
> > +  RRotU64.c
> > +  RRotU32.c
> > +  MultU64x64.c
> > +  MultU64x32.c
> > +  MultS64x64.c
> > +  ModU64x32.c
> > +  LShiftU64.c
> > +  LRotU64.c
> > +  LRotU32.c
> > +  LowBitSet64.c
> > +  LowBitSet32.c
> > +  HighBitSet64.c
> > +  HighBitSet32.c
> > +  GetPowerOfTwo64.c
> > +  GetPowerOfTwo32.c
> > +  DivU64x64Remainder.c
> > +  DivU64x32Remainder.c
> > +  DivU64x32.c
> > +  DivS64x64Remainder.c
> > +  ARShiftU64.c
> > +  BitField.c
> > +  CpuDeadLoop.c
> > +  Cpu.c
> > +  LinkedList.c
> > +  SafeString.c
> > +  String.c
> > +  FilePaths.c
> > +  BaseLibInternals.h
> > +  UnitTestHost.c
> > +  UnitTestHost.h
> > +
> > +[Sources.Ia32]
> > +  Ia32/SwapBytes64.c | MSFT
> > +  Ia32/RRotU64.c | MSFT
> > +  Ia32/RShiftU64.c | MSFT
> > +  Ia32/ReadTsc.c | MSFT
> > +  Ia32/ReadEflags.c | MSFT
> > +  Ia32/ModU64x32.c | MSFT
> > +  Ia32/MultU64x64.c | MSFT
> > +  Ia32/MultU64x32.c | MSFT
> > +  Ia32/LShiftU64.c | MSFT
> > +  Ia32/LRotU64.c | MSFT
> > +  Ia32/FxRestore.c | MSFT
> > +  Ia32/FxSave.c | MSFT
> > +  Ia32/DivU64x32Remainder.c | MSFT
> > +  Ia32/DivU64x32.c | MSFT
> > +  Ia32/CpuPause.c | MSFT
> > +  Ia32/CpuBreakpoint.c | MSFT
> > +  Ia32/ARShiftU64.c | MSFT
> > +  Ia32/GccInline.c | GCC
> > +  Ia32/LongJump.nasm
> > +  Ia32/SetJump.nasm
> > +  Ia32/SwapBytes64.nasm| GCC
> > +  Ia32/DivU64x64Remainder.nasm
> > +  Ia32/DivU64x32Remainder.nasm| GCC
> > +  Ia32/ModU64x32.nasm| GCC
> > +  Ia32/DivU64x32.nasm| GCC
> > +  Ia32/MultU64x64.nasm| GCC
> > +  Ia32/MultU64x32.nasm| GCC
> > +  Ia32/RRotU64.nasm| GCC
> > +  Ia32/LRotU64.nasm| GCC
> > +  Ia32/ARShiftU64.nasm| GCC
> > +  Ia32/RShiftU64.nasm| GCC
> > +  Ia32/LShiftU64.nasm| GCC
> > +  Ia32/RdRand.nasm
> > +  Ia32/DivS64x64Remainder.c
> > +  Ia32/InternalSwitchStack.c | MSFT
> > +  Ia32/InternalSwitchStack.nasm | GCC
> > +  Ia32/Non-existing.c
> > +  Unaligned.c
> > +  X86FxSave.c
> > +  X86FxRestore.c
> > +  X86Msr.c
> > +  X86RdRand.c
> > +  X86SpeculationBarrier.c
> > +  X86UnitTestHost.c
> > +
> > +[Sources.X64]
> > +  X64/LongJump.nasm
> > +  X64/SetJump.nasm
> > +  X64/SwitchStack.nasm
> > +  X64/CpuBreakpoint.c | MSFT
> > +  X64/CpuPause.nasm| MSFT
> > +  X64/ReadTsc.nasm| MSFT
> > +  X64/FxRestore.nasm| MSFT
> > +  X64/FxSave.nasm| MSFT
> > +  X64/ReadEflags.nasm| MSFT
> > +  X64/Non-existing.c
> > +  Math64.c
> > +  Unaligned.c
> > +  X86FxSave.c
> > +  X86FxRestore.c
> > +  X86Msr.c
> > +  X86RdRand.c
> > +  X86SpeculationBarrier.c
> > +  X64/GccInline.c | GCC
> > +  X64/RdRand.nasm
> > +  ChkStkGcc.c  | GCC
> > +  X86UnitTestHost.c
> > +
> > +[Sources.EBC]
> > +  Ebc/CpuBreakpoint.c
> > +  Ebc/SetJumpLongJump.c
> > +  Ebc/SwitchStack.c
> > +  Ebc/SpeculationBarrier.c
> > +  Unaligned.c
> > +  Math64.c
> > +
> > +[Sources.ARM]
> > +  Arm/InternalSwitchStack.c
> > +  Arm/Unaligned.c
> > +  Math64.c                   | RVCT
> > +  Math64.c                   | MSFT
> > +
> > +  Arm/SwitchStack.asm        | RVCT
> > +  Arm/SetJumpLongJump.asm    | RVCT
> > +  Arm/CpuPause.asm           | RVCT
> > +  Arm/CpuBreakpoint.asm      | RVCT
> > +  Arm/MemoryFence.asm        | RVCT
> > +  Arm/SpeculationBarrier.S   | RVCT
> > +
> > +  Arm/SwitchStack.asm        | MSFT
> > +  Arm/SetJumpLongJump.asm    | MSFT
> > +  Arm/CpuPause.asm           | MSFT
> > +  Arm/CpuBreakpoint.asm      | MSFT
> > +  Arm/MemoryFence.asm        | MSFT
> > +  Arm/SpeculationBarrier.asm | MSFT
> > +
> > +  Arm/Math64.S                  | GCC
> > +  Arm/SwitchStack.S             | GCC
> > +  Arm/SetJumpLongJump.S         | GCC
> > +  Arm/CpuBreakpoint.S           | GCC
> > +  Arm/MemoryFence.S             | GCC
> > +  Arm/SpeculationBarrier.S      | GCC
> > +
> > +[Sources.AARCH64]
> > +  Arm/InternalSwitchStack.c
> > +  Arm/Unaligned.c
> > +  Math64.c
> > +
> > +  AArch64/MemoryFence.S             | GCC
> > +  AArch64/SwitchStack.S             | GCC
> > +  AArch64/SetJumpLongJump.S         | GCC
> > +  AArch64/CpuBreakpoint.S           | GCC
> > +  AArch64/SpeculationBarrier.S      | GCC
> > +
> > +  AArch64/MemoryFence.asm           | MSFT
> > +  AArch64/SwitchStack.asm           | MSFT
> > +  AArch64/SetJumpLongJump.asm       | MSFT
> > +  AArch64/CpuBreakpoint.asm         | MSFT
> > +  AArch64/SpeculationBarrier.asm    | MSFT
> > +
> > +[Sources.RISCV64]
> > +  Math64.c
> > +  Unaligned.c
> > +  RiscV64/InternalSwitchStack.c
> > +  RiscV64/CpuBreakpoint.c
> > +  RiscV64/CpuPause.c
> > +  RiscV64/RiscVSetJumpLongJump.S    | GCC
> > +  RiscV64/RiscVCpuBreakpoint.S      | GCC
> > +  RiscV64/RiscVCpuPause.S           | GCC
> > +  RiscV64/RiscVInterrupt.S          | GCC
> > +  RiscV64/FlushCache.S              | GCC
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +
> > +[LibraryClasses]
> > +  PcdLib
> > +  DebugLib
> > +  BaseMemoryLib
> > +
> > +[Pcd]
> > +  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength
> ## SOMETIMES_CONSUMES
> > +
> gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength
> ## SOMETIMES_CONSUMES
> > +
> gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength
> ## SOMETIMES_CONSUMES
> > +
> gEfiMdePkgTokenSpaceGuid.PcdControlFlowEnforcementProper
> tyMask   ## SOMETIMES_CONSUMES
> > +  gEfiMdePkgTokenSpaceGuid.PcdSpeculationBarrierType
> ## SOMETIMES_CONSUMES
> > +
> > +[FeaturePcd]
> > +  gEfiMdePkgTokenSpaceGuid.PcdVerifyNodeInList  ##
> CONSUMES
> > diff --git
> a/MdePkg/Library/BaseLib/UnitTestHostBaseLib.uni
> b/MdePkg/Library/BaseLib/UnitTestHostBaseLib.uni
> > new file mode 100644
> > index 0000000000..e63ecef82c
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseLib/UnitTestHostBaseLib.uni
> > @@ -0,0 +1,11 @@
> > +// /** @file
> > +// Base Library implementation for use with host
> based unit tests.
> > +//
> > +// Copyright (c) 2020, Intel Corporation. All rights
> reserved.<BR>
> > +// SPDX-License-Identifier: BSD-2-Clause-Patent
> > +//
> > +// **/
> > +
> > +#string STR_MODULE_ABSTRACT             #language en-
> US "Base Library implementation for use with host based
> unit tests."
> > +
> > +#string STR_MODULE_DESCRIPTION          #language en-
> US "Base Library implementation for use with host based
> unit tests."
> > diff --git a/MdePkg/Library/BaseLib/X86UnitTestHost.c
> b/MdePkg/Library/BaseLib/X86UnitTestHost.c
> > new file mode 100644
> > index 0000000000..d0e428457e
> > --- /dev/null
> > +++ b/MdePkg/Library/BaseLib/X86UnitTestHost.c
> > @@ -0,0 +1,2977 @@
> > +/** @file
> > +  IA32/X64 specific Unit Test Host functions.
> > +
> > +  Copyright (c) 2020, Intel Corporation. All rights
> reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#include "UnitTestHost.h"
> > +
> > +///
> > +/// Defines for mUnitTestHostBaseLibSegment indexes
> > +///
> > +#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_CS    0
> > +#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_DS    1
> > +#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_ES    2
> > +#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_FS    3
> > +#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_GS    4
> > +#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_SS    5
> > +#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_TR    6
> > +#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_LDTR  7
> > +
> > +///
> > +/// Module global variables for simple system
> emulation of MSRs, CRx, DRx,
> > +/// GDTR, IDTR, and Segment Selectors.
> > +///
> > +STATIC UINT64
> mUnitTestHostBaseLibMsr[2][0x1000];
> > +STATIC UINTN            mUnitTestHostBaseLibCr[5];
> > +STATIC UINTN            mUnitTestHostBaseLibDr[8];
> > +STATIC UINT16
> mUnitTestHostBaseLibSegment[8];
> > +STATIC IA32_DESCRIPTOR  mUnitTestHostBaseLibGdtr;
> > +STATIC IA32_DESCRIPTOR  mUnitTestHostBaseLibIdtr;
> > +
> > +/**
> > +  Retrieves CPUID information.
> > +
> > +  Executes the CPUID instruction with EAX set to the
> value specified by Index.
> > +  This function always returns Index.
> > +  If Eax is not NULL, then the value of EAX after
> CPUID is returned in Eax.
> > +  If Ebx is not NULL, then the value of EBX after
> CPUID is returned in Ebx.
> > +  If Ecx is not NULL, then the value of ECX after
> CPUID is returned in Ecx.
> > +  If Edx is not NULL, then the value of EDX after
> CPUID is returned in Edx.
> > +  This function is only available on IA-32 and x64.
> > +
> > +  @param  Index The 32-bit value to load into EAX
> prior to invoking the CPUID
> > +                instruction.
> > +  @param  Eax   The pointer to the 32-bit EAX value
> returned by the CPUID
> > +                instruction. This is an optional
> parameter that may be NULL.
> > +  @param  Ebx   The pointer to the 32-bit EBX value
> returned by the CPUID
> > +                instruction. This is an optional
> parameter that may be NULL.
> > +  @param  Ecx   The pointer to the 32-bit ECX value
> returned by the CPUID
> > +                instruction. This is an optional
> parameter that may be NULL.
> > +  @param  Edx   The pointer to the 32-bit EDX value
> returned by the CPUID
> > +                instruction. This is an optional
> parameter that may be NULL.
> > +
> > +  @return Index.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +UnitTestHostBaseLibAsmCpuid (
> > +  IN      UINT32                    Index,
> > +  OUT     UINT32                    *Eax,  OPTIONAL
> > +  OUT     UINT32                    *Ebx,  OPTIONAL
> > +  OUT     UINT32                    *Ecx,  OPTIONAL
> > +  OUT     UINT32                    *Edx   OPTIONAL
> > +  )
> > +{
> > +  if (Eax != NULL) {
> > +    *Eax = 0;
> > +  }
> > +  if (Ebx != NULL) {
> > +    *Ebx = 0;
> > +  }
> > +  if (Ecx != NULL) {
> > +    *Ecx = 0;
> > +  }
> > +  if (Edx != NULL) {
> > +    *Edx = 0;
> > +  }
> > +  return Index;
> > +}
> > +
> > +/**
> > +  Retrieves CPUID information using an extended leaf
> identifier.
> > +
> > +  Executes the CPUID instruction with EAX set to the
> value specified by Index
> > +  and ECX set to the value specified by SubIndex.
> This function always returns
> > +  Index. This function is only available on IA-32 and
> x64.
> > +
> > +  If Eax is not NULL, then the value of EAX after
> CPUID is returned in Eax.
> > +  If Ebx is not NULL, then the value of EBX after
> CPUID is returned in Ebx.
> > +  If Ecx is not NULL, then the value of ECX after
> CPUID is returned in Ecx.
> > +  If Edx is not NULL, then the value of EDX after
> CPUID is returned in Edx.
> > +
> > +  @param  Index     The 32-bit value to load into EAX
> prior to invoking the
> > +                    CPUID instruction.
> > +  @param  SubIndex  The 32-bit value to load into ECX
> prior to invoking the
> > +                    CPUID instruction.
> > +  @param  Eax       The pointer to the 32-bit EAX
> value returned by the CPUID
> > +                    instruction. This is an optional
> parameter that may be
> > +                    NULL.
> > +  @param  Ebx       The pointer to the 32-bit EBX
> value returned by the CPUID
> > +                    instruction. This is an optional
> parameter that may be
> > +                    NULL.
> > +  @param  Ecx       The pointer to the 32-bit ECX
> value returned by the CPUID
> > +                    instruction. This is an optional
> parameter that may be
> > +                    NULL.
> > +  @param  Edx       The pointer to the 32-bit EDX
> value returned by the CPUID
> > +                    instruction. This is an optional
> parameter that may be
> > +                    NULL.
> > +
> > +  @return Index.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +UnitTestHostBaseLibAsmCpuidEx (
> > +  IN      UINT32                    Index,
> > +  IN      UINT32                    SubIndex,
> > +  OUT     UINT32                    *Eax,  OPTIONAL
> > +  OUT     UINT32                    *Ebx,  OPTIONAL
> > +  OUT     UINT32                    *Ecx,  OPTIONAL
> > +  OUT     UINT32                    *Edx   OPTIONAL
> > +  )
> > +{
> > +  if (Eax != NULL) {
> > +    *Eax = 0;
> > +  }
> > +  if (Ebx != NULL) {
> > +    *Ebx = 0;
> > +  }
> > +  if (Ecx != NULL) {
> > +    *Ecx = 0;
> > +  }
> > +  if (Edx != NULL) {
> > +    *Edx = 0;
> > +  }
> > +  return Index;
> > +}
> > +
> > +/**
> > +  Set CD bit and clear NW bit of CR0 followed by a
> WBINVD.
> > +
> > +  Disables the caches by setting the CD bit of CR0 to
> 1, clearing the NW bit of CR0 to 0,
> > +  and executing a WBINVD instruction.  This function
> is only available on IA-32 and x64.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmDisableCache (
> > +  VOID
> > +  )
> > +{
> > +}
> > +
> > +/**
> > +  Perform a WBINVD and clear both the CD and NW bits
> of CR0.
> > +
> > +  Enables the caches by executing a WBINVD
> instruction and then clear both the CD and NW
> > +  bits of CR0 to 0.  This function is only available
> on IA-32 and x64.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmEnableCache (
> > +  VOID
> > +  )
> > +{
> > +}
> > +
> > +/**
> > +  Returns a 64-bit Machine Specific Register(MSR).
> > +
> > +  Reads and returns the 64-bit MSR specified by
> Index. No parameter checking is
> > +  performed on Index, and some Index values may cause
> CPU exceptions. The
> > +  caller must either guarantee that Index is valid,
> or the caller must set up
> > +  exception handlers to catch the exceptions. This
> function is only available
> > +  on IA-32 and x64.
> > +
> > +  @param  Index The 32-bit MSR index to read.
> > +
> > +  @return The value of the MSR identified by Index.
> > +
> > +**/
> > +UINT64
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadMsr64 (
> > +  IN      UINT32                    Index
> > +  )
> > +{
> > +  if (Index < 0x1000) {
> > +    return mUnitTestHostBaseLibMsr[0][Index];
> > +  }
> > +  if (Index >= 0xC0000000 && Index < 0xC0001000) {
> > +    return mUnitTestHostBaseLibMsr[1][Index];
> > +  }
> > +  return 0;
> > +}
> > +
> > +/**
> > +  Writes a 64-bit value to a Machine Specific
> Register(MSR), and returns the
> > +  value.
> > +
> > +  Writes the 64-bit value specified by Value to the
> MSR specified by Index. The
> > +  64-bit value written to the MSR is returned. No
> parameter checking is
> > +  performed on Index or Value, and some of these may
> cause CPU exceptions. The
> > +  caller must either guarantee that Index and Value
> are valid, or the caller
> > +  must establish proper exception handlers. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @param  Index The 32-bit MSR index to write.
> > +  @param  Value The 64-bit value to write to the MSR.
> > +
> > +  @return Value
> > +
> > +**/
> > +UINT64
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteMsr64 (
> > +  IN      UINT32                    Index,
> > +  IN      UINT64                    Value
> > +  )
> > +{
> > +  if (Index < 0x1000) {
> > +    mUnitTestHostBaseLibMsr[0][Index] = Value;
> > +  }
> > +  if (Index >= 0xC0000000 && Index < 0xC0001000) {
> > +    mUnitTestHostBaseLibMsr[1][Index - 0xC00000000] =
> Value;
> > +  }
> > +  return Value;
> > +}
> > +
> > +/**
> > +  Reads the current value of the Control Register 0
> (CR0).
> > +
> > +  Reads and returns the current value of CR0. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of the Control Register 0 (CR0).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadCr0 (
> > +  VOID
> > +  )
> > +{
> > +  return mUnitTestHostBaseLibCr[0];
> > +}
> > +
> > +/**
> > +  Reads the current value of the Control Register 2
> (CR2).
> > +
> > +  Reads and returns the current value of CR2. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of the Control Register 2 (CR2).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadCr2 (
> > +  VOID
> > +  )
> > +{
> > +  return mUnitTestHostBaseLibCr[2];
> > +}
> > +
> > +/**
> > +  Reads the current value of the Control Register 3
> (CR3).
> > +
> > +  Reads and returns the current value of CR3. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of the Control Register 3 (CR3).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadCr3 (
> > +  VOID
> > +  )
> > +{
> > +  return mUnitTestHostBaseLibCr[3];
> > +}
> > +
> > +/**
> > +  Reads the current value of the Control Register 4
> (CR4).
> > +
> > +  Reads and returns the current value of CR4. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of the Control Register 4 (CR4).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadCr4 (
> > +  VOID
> > +  )
> > +{
> > +  return mUnitTestHostBaseLibCr[4];
> > +}
> > +
> > +/**
> > +  Writes a value to Control Register 0 (CR0).
> > +
> > +  Writes and returns a new value to CR0. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Cr0 The value to write to CR0.
> > +
> > +  @return The value written to CR0.
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteCr0 (
> > +  UINTN  Cr0
> > +  )
> > +{
> > +  mUnitTestHostBaseLibCr[0] = Cr0;
> > +  return Cr0;
> > +}
> > +
> > +/**
> > +  Writes a value to Control Register 2 (CR2).
> > +
> > +  Writes and returns a new value to CR2. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Cr2 The value to write to CR2.
> > +
> > +  @return The value written to CR2.
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteCr2 (
> > +  UINTN  Cr2
> > +  )
> > +{
> > +  mUnitTestHostBaseLibCr[2] = Cr2;
> > +  return Cr2;
> > +}
> > +
> > +/**
> > +  Writes a value to Control Register 3 (CR3).
> > +
> > +  Writes and returns a new value to CR3. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Cr3 The value to write to CR3.
> > +
> > +  @return The value written to CR3.
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteCr3 (
> > +  UINTN  Cr3
> > +  )
> > +{
> > +  mUnitTestHostBaseLibCr[3] = Cr3;
> > +  return Cr3;
> > +}
> > +
> > +/**
> > +  Writes a value to Control Register 4 (CR4).
> > +
> > +  Writes and returns a new value to CR4. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Cr4 The value to write to CR4.
> > +
> > +  @return The value written to CR4.
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteCr4 (
> > +  UINTN  Cr4
> > +  )
> > +{
> > +  mUnitTestHostBaseLibCr[4] = Cr4;
> > +  return Cr4;
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 0 (DR0).
> > +
> > +  Reads and returns the current value of DR0. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 0 (DR0).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadDr0 (
> > +  VOID
> > +  )
> > +{
> > +  return mUnitTestHostBaseLibDr[0];
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 1 (DR1).
> > +
> > +  Reads and returns the current value of DR1. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 1 (DR1).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadDr1 (
> > +  VOID
> > +  )
> > +{
> > +  return mUnitTestHostBaseLibDr[1];
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 2 (DR2).
> > +
> > +  Reads and returns the current value of DR2. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 2 (DR2).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadDr2 (
> > +  VOID
> > +  )
> > +{
> > +  return mUnitTestHostBaseLibDr[2];
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 3 (DR3).
> > +
> > +  Reads and returns the current value of DR3. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 3 (DR3).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadDr3 (
> > +  VOID
> > +  )
> > +{
> > +  return mUnitTestHostBaseLibDr[3];
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 4 (DR4).
> > +
> > +  Reads and returns the current value of DR4. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 4 (DR4).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadDr4 (
> > +  VOID
> > +  )
> > +{
> > +  return mUnitTestHostBaseLibDr[4];
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 5 (DR5).
> > +
> > +  Reads and returns the current value of DR5. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 5 (DR5).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadDr5 (
> > +  VOID
> > +  )
> > +{
> > +  return mUnitTestHostBaseLibDr[5];
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 6 (DR6).
> > +
> > +  Reads and returns the current value of DR6. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 6 (DR6).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadDr6 (
> > +  VOID
> > +  )
> > +{
> > +  return mUnitTestHostBaseLibDr[6];
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 7 (DR7).
> > +
> > +  Reads and returns the current value of DR7. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 7 (DR7).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadDr7 (
> > +  VOID
> > +  )
> > +{
> > +  return mUnitTestHostBaseLibDr[7];
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 0 (DR0).
> > +
> > +  Writes and returns a new value to DR0. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr0 The value to write to Dr0.
> > +
> > +  @return The value written to Debug Register 0
> (DR0).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteDr0 (
> > +  UINTN  Dr0
> > +  )
> > +{
> > +  mUnitTestHostBaseLibDr[0] = Dr0;
> > +  return Dr0;
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 1 (DR1).
> > +
> > +  Writes and returns a new value to DR1. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr1 The value to write to Dr1.
> > +
> > +  @return The value written to Debug Register 1
> (DR1).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteDr1 (
> > +  UINTN  Dr1
> > +  )
> > +{
> > +  mUnitTestHostBaseLibDr[1] = Dr1;
> > +  return Dr1;
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 2 (DR2).
> > +
> > +  Writes and returns a new value to DR2. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr2 The value to write to Dr2.
> > +
> > +  @return The value written to Debug Register 2
> (DR2).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteDr2 (
> > +  UINTN  Dr2
> > +  )
> > +{
> > +  mUnitTestHostBaseLibDr[2] = Dr2;
> > +  return Dr2;
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 3 (DR3).
> > +
> > +  Writes and returns a new value to DR3. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr3 The value to write to Dr3.
> > +
> > +  @return The value written to Debug Register 3
> (DR3).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteDr3 (
> > +  UINTN  Dr3
> > +  )
> > +{
> > +  mUnitTestHostBaseLibDr[3] = Dr3;
> > +  return Dr3;
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 4 (DR4).
> > +
> > +  Writes and returns a new value to DR4. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr4 The value to write to Dr4.
> > +
> > +  @return The value written to Debug Register 4
> (DR4).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteDr4 (
> > +  UINTN  Dr4
> > +  )
> > +{
> > +  mUnitTestHostBaseLibDr[4] = Dr4;
> > +  return Dr4;
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 5 (DR5).
> > +
> > +  Writes and returns a new value to DR5. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr5 The value to write to Dr5.
> > +
> > +  @return The value written to Debug Register 5
> (DR5).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteDr5 (
> > +  UINTN  Dr5
> > +  )
> > +{
> > +  mUnitTestHostBaseLibDr[5] = Dr5;
> > +  return Dr5;
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 6 (DR6).
> > +
> > +  Writes and returns a new value to DR6. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr6 The value to write to Dr6.
> > +
> > +  @return The value written to Debug Register 6
> (DR6).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteDr6 (
> > +  UINTN  Dr6
> > +  )
> > +{
> > +  mUnitTestHostBaseLibDr[6] = Dr6;
> > +  return Dr6;
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 7 (DR7).
> > +
> > +  Writes and returns a new value to DR7. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr7 The value to write to Dr7.
> > +
> > +  @return The value written to Debug Register 7
> (DR7).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteDr7 (
> > +  UINTN  Dr7
> > +  )
> > +{
> > +  mUnitTestHostBaseLibDr[7] = Dr7;
> > +  return Dr7;
> > +}
> > +
> > +/**
> > +  Reads the current value of Code Segment Register
> (CS).
> > +
> > +  Reads and returns the current value of CS. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @return The current value of CS.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadCs (
> > +  VOID
> > +  )
> > +{
> > +  return
> mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGM
> ENT_CS];
> > +}
> > +
> > +/**
> > +  Reads the current value of Data Segment Register
> (DS).
> > +
> > +  Reads and returns the current value of DS. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @return The current value of DS.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadDs (
> > +  VOID
> > +  )
> > +{
> > +  return
> mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGM
> ENT_DS];
> > +}
> > +
> > +/**
> > +  Reads the current value of Extra Segment Register
> (ES).
> > +
> > +  Reads and returns the current value of ES. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @return The current value of ES.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadEs (
> > +  VOID
> > +  )
> > +{
> > +  return
> mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGM
> ENT_ES];
> > +}
> > +
> > +/**
> > +  Reads the current value of FS Data Segment Register
> (FS).
> > +
> > +  Reads and returns the current value of FS. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @return The current value of FS.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadFs (
> > +  VOID
> > +  )
> > +{
> > +  return
> mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGM
> ENT_FS];
> > +}
> > +
> > +/**
> > +  Reads the current value of GS Data Segment Register
> (GS).
> > +
> > +  Reads and returns the current value of GS. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @return The current value of GS.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadGs (
> > +  VOID
> > +  )
> > +{
> > +  return
> mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGM
> ENT_GS];
> > +}
> > +
> > +/**
> > +  Reads the current value of Stack Segment Register
> (SS).
> > +
> > +  Reads and returns the current value of SS. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @return The current value of SS.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadSs (
> > +  VOID
> > +  )
> > +{
> > +  return
> mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGM
> ENT_SS];
> > +}
> > +
> > +/**
> > +  Reads the current value of Task Register (TR).
> > +
> > +  Reads and returns the current value of TR. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @return The current value of TR.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadTr (
> > +  VOID
> > +  )
> > +{
> > +  return
> mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGM
> ENT_TR];
> > +}
> > +
> > +/**
> > +  Reads the current Global Descriptor Table
> Register(GDTR) descriptor.
> > +
> > +  Reads and returns the current GDTR descriptor and
> returns it in Gdtr. This
> > +  function is only available on IA-32 and x64.
> > +
> > +  If Gdtr is NULL, then ASSERT().
> > +
> > +  @param  Gdtr  The pointer to a GDTR descriptor.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadGdtr (
> > +  OUT     IA32_DESCRIPTOR           *Gdtr
> > +  )
> > +{
> > +  Gdtr = &mUnitTestHostBaseLibGdtr;
> > +}
> > +
> > +/**
> > +  Writes the current Global Descriptor Table Register
> (GDTR) descriptor.
> > +
> > +  Writes and the current GDTR descriptor specified by
> Gdtr. This function is
> > +  only available on IA-32 and x64.
> > +
> > +  If Gdtr is NULL, then ASSERT().
> > +
> > +  @param  Gdtr  The pointer to a GDTR descriptor.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteGdtr (
> > +  IN      CONST IA32_DESCRIPTOR     *Gdtr
> > +  )
> > +{
> > +  CopyMem (&mUnitTestHostBaseLibGdtr, Gdtr, sizeof
> (IA32_DESCRIPTOR));
> > +}
> > +
> > +/**
> > +  Reads the current Interrupt Descriptor Table
> Register(IDTR) descriptor.
> > +
> > +  Reads and returns the current IDTR descriptor and
> returns it in Idtr. This
> > +  function is only available on IA-32 and x64.
> > +
> > +  If Idtr is NULL, then ASSERT().
> > +
> > +  @param  Idtr  The pointer to a IDTR descriptor.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadIdtr (
> > +  OUT     IA32_DESCRIPTOR           *Idtr
> > +  )
> > +{
> > +  Idtr = &mUnitTestHostBaseLibIdtr;
> > +}
> > +
> > +/**
> > +  Writes the current Interrupt Descriptor Table
> Register(IDTR) descriptor.
> > +
> > +  Writes the current IDTR descriptor and returns it
> in Idtr. This function is
> > +  only available on IA-32 and x64.
> > +
> > +  If Idtr is NULL, then ASSERT().
> > +
> > +  @param  Idtr  The pointer to a IDTR descriptor.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteIdtr (
> > +  IN      CONST IA32_DESCRIPTOR     *Idtr
> > +  )
> > +{
> > +  CopyMem (&mUnitTestHostBaseLibIdtr, Idtr, sizeof
> (IA32_DESCRIPTOR));
> > +}
> > +
> > +/**
> > +  Reads the current Local Descriptor Table
> Register(LDTR) selector.
> > +
> > +  Reads and returns the current 16-bit LDTR
> descriptor value. This function is
> > +  only available on IA-32 and x64.
> > +
> > +  @return The current selector of LDT.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadLdtr (
> > +  VOID
> > +  )
> > +{
> > +  return
> mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGM
> ENT_LDTR];
> > +}
> > +
> > +/**
> > +  Writes the current Local Descriptor Table Register
> (LDTR) selector.
> > +
> > +  Writes and the current LDTR descriptor specified by
> Ldtr. This function is
> > +  only available on IA-32 and x64.
> > +
> > +  @param  Ldtr  16-bit LDTR selector value.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteLdtr (
> > +  IN      UINT16                    Ldtr
> > +  )
> > +{
> > +
> mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGM
> ENT_LDTR] = Ldtr;
> > +}
> > +
> > +/**
> > +  Reads the current value of a Performance Counter
> (PMC).
> > +
> > +  Reads and returns the current value of performance
> counter specified by
> > +  Index. This function is only available on IA-32 and
> x64.
> > +
> > +  @param  Index The 32-bit Performance Counter index
> to read.
> > +
> > +  @return The value of the PMC specified by Index.
> > +
> > +**/
> > +UINT64
> > +EFIAPI
> > +UnitTestHostBaseLibAsmReadPmc (
> > +  IN      UINT32                    Index
> > +  )
> > +{
> > +  return 0;
> > +}
> > +
> > +/**
> > +  Sets up a monitor buffer that is used by
> AsmMwait().
> > +
> > +  Executes a MONITOR instruction with the register
> state specified by Eax, Ecx
> > +  and Edx. Returns Eax. This function is only
> available on IA-32 and x64.
> > +
> > +  @param  Eax The value to load into EAX or RAX
> before executing the MONITOR
> > +              instruction.
> > +  @param  Ecx The value to load into ECX or RCX
> before executing the MONITOR
> > +              instruction.
> > +  @param  Edx The value to load into EDX or RDX
> before executing the MONITOR
> > +              instruction.
> > +
> > +  @return Eax
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmMonitor (
> > +  IN      UINTN                     Eax,
> > +  IN      UINTN                     Ecx,
> > +  IN      UINTN                     Edx
> > +  )
> > +{
> > +  return Eax;
> > +}
> > +
> > +/**
> > +  Executes an MWAIT instruction.
> > +
> > +  Executes an MWAIT instruction with the register
> state specified by Eax and
> > +  Ecx. Returns Eax. This function is only available
> on IA-32 and x64.
> > +
> > +  @param  Eax The value to load into EAX or RAX
> before executing the MONITOR
> > +              instruction.
> > +  @param  Ecx The value to load into ECX or RCX
> before executing the MONITOR
> > +              instruction.
> > +
> > +  @return Eax
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +UnitTestHostBaseLibAsmMwait (
> > +  IN      UINTN                     Eax,
> > +  IN      UINTN                     Ecx
> > +  )
> > +{
> > +  return Eax;
> > +}
> > +
> > +/**
> > +  Executes a WBINVD instruction.
> > +
> > +  Executes a WBINVD instruction. This function is
> only available on IA-32 and
> > +  x64.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWbinvd (
> > +  VOID
> > +  )
> > +{
> > +}
> > +
> > +/**
> > +  Executes a INVD instruction.
> > +
> > +  Executes a INVD instruction. This function is only
> available on IA-32 and
> > +  x64.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmInvd (
> > +  VOID
> > +  )
> > +{
> > +}
> > +
> > +/**
> > +  Flushes a cache line from all the instruction and
> data caches within the
> > +  coherency domain of the CPU.
> > +
> > +  Flushed the cache line specified by LinearAddress,
> and returns LinearAddress.
> > +  This function is only available on IA-32 and x64.
> > +
> > +  @param  LinearAddress The address of the cache line
> to flush. If the CPU is
> > +                        in a physical addressing
> mode, then LinearAddress is a
> > +                        physical address. If the CPU
> is in a virtual
> > +                        addressing mode, then
> LinearAddress is a virtual
> > +                        address.
> > +
> > +  @return LinearAddress.
> > +**/
> > +VOID *
> > +EFIAPI
> > +UnitTestHostBaseLibAsmFlushCacheLine (
> > +  IN      VOID                      *LinearAddress
> > +  )
> > +{
> > +  return LinearAddress;
> > +}
> > +
> > +/**
> > +  Enables the 32-bit paging mode on the CPU.
> > +
> > +  Enables the 32-bit paging mode on the CPU. CR0,
> CR3, CR4, and the page tables
> > +  must be properly initialized prior to calling this
> service. This function
> > +  assumes the current execution mode is 32-bit
> protected mode. This function is
> > +  only available on IA-32. After the 32-bit paging
> mode is enabled, control is
> > +  transferred to the function specified by EntryPoint
> using the new stack
> > +  specified by NewStack and passing in the parameters
> specified by Context1 and
> > +  Context2. Context1 and Context2 are optional and
> may be NULL. The function
> > +  EntryPoint must never return.
> > +
> > +  If the current execution mode is not 32-bit
> protected mode, then ASSERT().
> > +  If EntryPoint is NULL, then ASSERT().
> > +  If NewStack is NULL, then ASSERT().
> > +
> > +  There are a number of constraints that must be
> followed before calling this
> > +  function:
> > +  1)  Interrupts must be disabled.
> > +  2)  The caller must be in 32-bit protected mode
> with flat descriptors. This
> > +      means all descriptors must have a base of 0 and
> a limit of 4GB.
> > +  3)  CR0 and CR4 must be compatible with 32-bit
> protected mode with flat
> > +      descriptors.
> > +  4)  CR3 must point to valid page tables that will
> be used once the transition
> > +      is complete, and those page tables must
> guarantee that the pages for this
> > +      function and the stack are identity mapped.
> > +
> > +  @param  EntryPoint  A pointer to function to call
> with the new stack after
> > +                      paging is enabled.
> > +  @param  Context1    A pointer to the context to
> pass into the EntryPoint
> > +                      function as the first parameter
> after paging is enabled.
> > +  @param  Context2    A pointer to the context to
> pass into the EntryPoint
> > +                      function as the second
> parameter after paging is enabled.
> > +  @param  NewStack    A pointer to the new stack to
> use for the EntryPoint
> > +                      function after paging is
> enabled.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmEnablePaging32 (
> > +  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,
> > +  IN      VOID                      *Context1,
> OPTIONAL
> > +  IN      VOID                      *Context2,
> OPTIONAL
> > +  IN      VOID                      *NewStack
> > +  )
> > +{
> > +  EntryPoint (Context1, Context2);
> > +}
> > +
> > +/**
> > +  Disables the 32-bit paging mode on the CPU.
> > +
> > +  Disables the 32-bit paging mode on the CPU and
> returns to 32-bit protected
> > +  mode. This function assumes the current execution
> mode is 32-paged protected
> > +  mode. This function is only available on IA-32.
> After the 32-bit paging mode
> > +  is disabled, control is transferred to the function
> specified by EntryPoint
> > +  using the new stack specified by NewStack and
> passing in the parameters
> > +  specified by Context1 and Context2. Context1 and
> Context2 are optional and
> > +  may be NULL. The function EntryPoint must never
> return.
> > +
> > +  If the current execution mode is not 32-bit paged
> mode, then ASSERT().
> > +  If EntryPoint is NULL, then ASSERT().
> > +  If NewStack is NULL, then ASSERT().
> > +
> > +  There are a number of constraints that must be
> followed before calling this
> > +  function:
> > +  1)  Interrupts must be disabled.
> > +  2)  The caller must be in 32-bit paged mode.
> > +  3)  CR0, CR3, and CR4 must be compatible with 32-
> bit paged mode.
> > +  4)  CR3 must point to valid page tables that
> guarantee that the pages for
> > +      this function and the stack are identity
> mapped.
> > +
> > +  @param  EntryPoint  A pointer to function to call
> with the new stack after
> > +                      paging is disabled.
> > +  @param  Context1    A pointer to the context to
> pass into the EntryPoint
> > +                      function as the first parameter
> after paging is disabled.
> > +  @param  Context2    A pointer to the context to
> pass into the EntryPoint
> > +                      function as the second
> parameter after paging is
> > +                      disabled.
> > +  @param  NewStack    A pointer to the new stack to
> use for the EntryPoint
> > +                      function after paging is
> disabled.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmDisablePaging32 (
> > +  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,
> > +  IN      VOID                      *Context1,
> OPTIONAL
> > +  IN      VOID                      *Context2,
> OPTIONAL
> > +  IN      VOID                      *NewStack
> > +  )
> > +{
> > +  EntryPoint (Context1, Context2);
> > +}
> > +
> > +/**
> > +  Enables the 64-bit paging mode on the CPU.
> > +
> > +  Enables the 64-bit paging mode on the CPU. CR0,
> CR3, CR4, and the page tables
> > +  must be properly initialized prior to calling this
> service. This function
> > +  assumes the current execution mode is 32-bit
> protected mode with flat
> > +  descriptors. This function is only available on IA-
> 32. After the 64-bit
> > +  paging mode is enabled, control is transferred to
> the function specified by
> > +  EntryPoint using the new stack specified by
> NewStack and passing in the
> > +  parameters specified by Context1 and Context2.
> Context1 and Context2 are
> > +  optional and may be 0. The function EntryPoint must
> never return.
> > +
> > +  If the current execution mode is not 32-bit
> protected mode with flat
> > +  descriptors, then ASSERT().
> > +  If EntryPoint is 0, then ASSERT().
> > +  If NewStack is 0, then ASSERT().
> > +
> > +  @param  Cs          The 16-bit selector to load in
> the CS before EntryPoint
> > +                      is called. The descriptor in
> the GDT that this selector
> > +                      references must be setup for
> long mode.
> > +  @param  EntryPoint  The 64-bit virtual address of
> the function to call with
> > +                      the new stack after paging is
> enabled.
> > +  @param  Context1    The 64-bit virtual address of
> the context to pass into
> > +                      the EntryPoint function as the
> first parameter after
> > +                      paging is enabled.
> > +  @param  Context2    The 64-bit virtual address of
> the context to pass into
> > +                      the EntryPoint function as the
> second parameter after
> > +                      paging is enabled.
> > +  @param  NewStack    The 64-bit virtual address of
> the new stack to use for
> > +                      the EntryPoint function after
> paging is enabled.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmEnablePaging64 (
> > +  IN      UINT16                    Cs,
> > +  IN      UINT64                    EntryPoint,
> > +  IN      UINT64                    Context1,
> OPTIONAL
> > +  IN      UINT64                    Context2,
> OPTIONAL
> > +  IN      UINT64                    NewStack
> > +  )
> > +{
> > +  SWITCH_STACK_ENTRY_POINT  NewEntryPoint;
> > +
> > +  NewEntryPoint =
> (SWITCH_STACK_ENTRY_POINT)(UINTN)(EntryPoint);
> > +  NewEntryPoint ((VOID *)(UINTN)Context1, (VOID
> *)(UINTN)Context2);
> > +}
> > +
> > +/**
> > +  Disables the 64-bit paging mode on the CPU.
> > +
> > +  Disables the 64-bit paging mode on the CPU and
> returns to 32-bit protected
> > +  mode. This function assumes the current execution
> mode is 64-paging mode.
> > +  This function is only available on x64. After the
> 64-bit paging mode is
> > +  disabled, control is transferred to the function
> specified by EntryPoint
> > +  using the new stack specified by NewStack and
> passing in the parameters
> > +  specified by Context1 and Context2. Context1 and
> Context2 are optional and
> > +  may be 0. The function EntryPoint must never
> return.
> > +
> > +  If the current execution mode is not 64-bit paged
> mode, then ASSERT().
> > +  If EntryPoint is 0, then ASSERT().
> > +  If NewStack is 0, then ASSERT().
> > +
> > +  @param  Cs          The 16-bit selector to load in
> the CS before EntryPoint
> > +                      is called. The descriptor in
> the GDT that this selector
> > +                      references must be setup for
> 32-bit protected mode.
> > +  @param  EntryPoint  The 64-bit virtual address of
> the function to call with
> > +                      the new stack after paging is
> disabled.
> > +  @param  Context1    The 64-bit virtual address of
> the context to pass into
> > +                      the EntryPoint function as the
> first parameter after
> > +                      paging is disabled.
> > +  @param  Context2    The 64-bit virtual address of
> the context to pass into
> > +                      the EntryPoint function as the
> second parameter after
> > +                      paging is disabled.
> > +  @param  NewStack    The 64-bit virtual address of
> the new stack to use for
> > +                      the EntryPoint function after
> paging is disabled.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmDisablePaging64 (
> > +  IN      UINT16                    Cs,
> > +  IN      UINT32                    EntryPoint,
> > +  IN      UINT32                    Context1,
> OPTIONAL
> > +  IN      UINT32                    Context2,
> OPTIONAL
> > +  IN      UINT32                    NewStack
> > +  )
> > +{
> > +  SWITCH_STACK_ENTRY_POINT  NewEntryPoint;
> > +
> > +  NewEntryPoint =
> (SWITCH_STACK_ENTRY_POINT)(UINTN)(EntryPoint);
> > +  NewEntryPoint ((VOID *)(UINTN)Context1, (VOID
> *)(UINTN)Context2);
> > +}
> > +
> > +/**
> > +  Retrieves the properties for 16-bit thunk
> functions.
> > +
> > +  Computes the size of the buffer and stack below 1MB
> required to use the
> > +  AsmPrepareThunk16(), AsmThunk16() and
> AsmPrepareAndThunk16() functions. This
> > +  buffer size is returned in RealModeBufferSize, and
> the stack size is returned
> > +  in ExtraStackSize. If parameters are passed to the
> 16-bit real mode code,
> > +  then the actual minimum stack size is
> ExtraStackSize plus the maximum number
> > +  of bytes that need to be passed to the 16-bit real
> mode code.
> > +
> > +  If RealModeBufferSize is NULL, then ASSERT().
> > +  If ExtraStackSize is NULL, then ASSERT().
> > +
> > +  @param  RealModeBufferSize  A pointer to the size
> of the buffer below 1MB
> > +                              required to use the 16-
> bit thunk functions.
> > +  @param  ExtraStackSize      A pointer to the extra
> size of stack below 1MB
> > +                              that the 16-bit thunk
> functions require for
> > +                              temporary storage in
> the transition to and from
> > +                              16-bit real mode.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmGetThunk16Properties (
> > +  OUT     UINT32
> *RealModeBufferSize,
> > +  OUT     UINT32                    *ExtraStackSize
> > +  )
> > +{
> > +  *RealModeBufferSize = 0;
> > +  *ExtraStackSize     = 0;
> > +}
> > +
> > +/**
> > +  Prepares all structures a code required to use
> AsmThunk16().
> > +
> > +  Prepares all structures and code required to use
> AsmThunk16().
> > +
> > +  This interface is limited to be used in either
> physical mode or virtual modes with paging enabled where
> the
> > +  virtual to physical mappings for
> ThunkContext.RealModeBuffer is mapped 1:1.
> > +
> > +  If ThunkContext is NULL, then ASSERT().
> > +
> > +  @param  ThunkContext  A pointer to the context
> structure that describes the
> > +                        16-bit real mode code to
> call.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmPrepareThunk16 (
> > +  IN OUT  THUNK_CONTEXT             *ThunkContext
> > +  )
> > +{
> > +}
> > +
> > +/**
> > +  Transfers control to a 16-bit real mode entry point
> and returns the results.
> > +
> > +  Transfers control to a 16-bit real mode entry point
> and returns the results.
> > +  AsmPrepareThunk16() must be called with
> ThunkContext before this function is used.
> > +  This function must be called with interrupts
> disabled.
> > +
> > +  The register state from the RealModeState field of
> ThunkContext is restored just prior
> > +  to calling the 16-bit real mode entry point.  This
> includes the EFLAGS field of RealModeState,
> > +  which is used to set the interrupt state when a 16-
> bit real mode entry point is called.
> > +  Control is transferred to the 16-bit real mode
> entry point specified by the CS and Eip fields of
> RealModeState.
> > +  The stack is initialized to the SS and ESP fields
> of RealModeState.  Any parameters passed to
> > +  the 16-bit real mode code must be populated by the
> caller at SS:ESP prior to calling this function.
> > +  The 16-bit real mode entry point is invoked with a
> 16-bit CALL FAR instruction,
> > +  so when accessing stack contents, the 16-bit real
> mode code must account for the 16-bit segment
> > +  and 16-bit offset of the return address that were
> pushed onto the stack. The 16-bit real mode entry
> > +  point must exit with a RETF instruction. The
> register state is captured into RealModeState
> immediately
> > +  after the RETF instruction is executed.
> > +
> > +  If EFLAGS specifies interrupts enabled, or any of
> the 16-bit real mode code enables interrupts,
> > +  or any of the 16-bit real mode code makes a SW
> interrupt, then the caller is responsible for making
> sure
> > +  the IDT at address 0 is initialized to handle any
> HW or SW interrupts that may occur while in 16-bit real
> mode.
> > +
> > +  If EFLAGS specifies interrupts enabled, or any of
> the 16-bit real mode code enables interrupts,
> > +  then the caller is responsible for making sure the
> 8259 PIC is in a state compatible with 16-bit real mode.
> > +  This includes the base vectors, the interrupt
> masks, and the edge/level trigger mode.
> > +
> > +  If THUNK_ATTRIBUTE_BIG_REAL_MODE is set in the
> ThunkAttributes field of ThunkContext, then the user
> code
> > +  is invoked in big real mode.  Otherwise, the user
> code is invoked in 16-bit real mode with 64KB segment
> limits.
> > +
> > +  If neither THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15
> nor THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL are set in
> > +  ThunkAttributes, then it is assumed that the user
> code did not enable the A20 mask, and no attempt is made
> to
> > +  disable the A20 mask.
> > +
> > +  If THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 is set
> and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL is clear
> in
> > +  ThunkAttributes, then attempt to use the INT 15
> service to disable the A20 mask.  If this INT 15 call
> fails,
> > +  then attempt to disable the A20 mask by directly
> accessing the 8042 keyboard controller I/O ports.
> > +
> > +  If THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 is clear
> and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL is set in
> > +  ThunkAttributes, then attempt to disable the A20
> mask by directly accessing the 8042 keyboard controller
> I/O ports.
> > +
> > +  If ThunkContext is NULL, then ASSERT().
> > +  If AsmPrepareThunk16() was not previously called
> with ThunkContext, then ASSERT().
> > +  If both THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 and
> THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL are set in
> > +  ThunkAttributes, then ASSERT().
> > +
> > +  This interface is limited to be used in either
> physical mode or virtual modes with paging enabled where
> the
> > +  virtual to physical mappings for
> ThunkContext.RealModeBuffer are mapped 1:1.
> > +
> > +  @param  ThunkContext  A pointer to the context
> structure that describes the
> > +                        16-bit real mode code to
> call.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmThunk16 (
> > +  IN OUT  THUNK_CONTEXT             *ThunkContext
> > +  )
> > +{
> > +}
> > +
> > +/**
> > +  Prepares all structures and code for a 16-bit real
> mode thunk, transfers
> > +  control to a 16-bit real mode entry point, and
> returns the results.
> > +
> > +  Prepares all structures and code for a 16-bit real
> mode thunk, transfers
> > +  control to a 16-bit real mode entry point, and
> returns the results. If the
> > +  caller only need to perform a single 16-bit real
> mode thunk, then this
> > +  service should be used. If the caller intends to
> make more than one 16-bit
> > +  real mode thunk, then it is more efficient if
> AsmPrepareThunk16() is called
> > +  once and AsmThunk16() can be called for each 16-bit
> real mode thunk.
> > +
> > +  This interface is limited to be used in either
> physical mode or virtual modes with paging enabled where
> the
> > +  virtual to physical mappings for
> ThunkContext.RealModeBuffer is mapped 1:1.
> > +
> > +  See AsmPrepareThunk16() and AsmThunk16() for the
> detailed description and ASSERT() conditions.
> > +
> > +  @param  ThunkContext  A pointer to the context
> structure that describes the
> > +                        16-bit real mode code to
> call.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmPrepareAndThunk16 (
> > +  IN OUT  THUNK_CONTEXT             *ThunkContext
> > +  )
> > +{
> > +}
> > +
> > +/**
> > +  Load given selector into TR register.
> > +
> > +  @param[in] Selector     Task segment selector
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmWriteTr (
> > +  IN UINT16 Selector
> > +  )
> > +{
> > +
> mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGM
> ENT_TR] = Selector;
> > +}
> > +
> > +/**
> > +  Performs a serializing operation on all load-from-
> memory instructions that
> > +  were issued prior the AsmLfence function.
> > +
> > +  Executes a LFENCE instruction. This function is
> only available on IA-32 and x64.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibAsmLfence (
> > +  VOID
> > +  )
> > +{
> > +}
> > +
> > +/**
> > +  Patch the immediate operand of an IA32 or X64
> instruction such that the byte,
> > +  word, dword or qword operand is encoded at the end
> of the instruction's
> > +  binary representation.
> > +
> > +  This function should be used to update object code
> that was compiled with
> > +  NASM from assembly source code. Example:
> > +
> > +  NASM source code:
> > +
> > +        mov     eax, strict dword 0 ; the imm32 zero
> operand will be patched
> > +    ASM_PFX(gPatchCr3):
> > +        mov     cr3, eax
> > +
> > +  C source code:
> > +
> > +    X86_ASSEMBLY_PATCH_LABEL gPatchCr3;
> > +    PatchInstructionX86 (gPatchCr3, AsmReadCr3 (),
> 4);
> > +
> > +  @param[out] InstructionEnd  Pointer right past the
> instruction to patch. The
> > +                              immediate operand to
> patch is expected to
> > +                              comprise the trailing
> bytes of the instruction.
> > +                              If InstructionEnd is
> closer to address 0 than
> > +                              ValueSize permits, then
> ASSERT().
> > +
> > +  @param[in] PatchValue       The constant to write
> to the immediate operand.
> > +                              The caller is
> responsible for ensuring that
> > +                              PatchValue can be
> represented in the byte, word,
> > +                              dword or qword operand
> (as indicated through
> > +                              ValueSize); otherwise
> ASSERT().
> > +
> > +  @param[in] ValueSize        The size of the operand
> in bytes; must be 1, 2,
> > +                              4, or 8. ASSERT()
> otherwise.
> > +**/
> > +VOID
> > +EFIAPI
> > +UnitTestHostBaseLibPatchInstructionX86 (
> > +  OUT X86_ASSEMBLY_PATCH_LABEL *InstructionEnd,
> > +  IN  UINT64                   PatchValue,
> > +  IN  UINTN                    ValueSize
> > +  )
> > +{
> > +}
> > +
> > +/**
> > +  Retrieves CPUID information.
> > +
> > +  Executes the CPUID instruction with EAX set to the
> value specified by Index.
> > +  This function always returns Index.
> > +  If Eax is not NULL, then the value of EAX after
> CPUID is returned in Eax.
> > +  If Ebx is not NULL, then the value of EBX after
> CPUID is returned in Ebx.
> > +  If Ecx is not NULL, then the value of ECX after
> CPUID is returned in Ecx.
> > +  If Edx is not NULL, then the value of EDX after
> CPUID is returned in Edx.
> > +  This function is only available on IA-32 and x64.
> > +
> > +  @param  Index The 32-bit value to load into EAX
> prior to invoking the CPUID
> > +                instruction.
> > +  @param  Eax   The pointer to the 32-bit EAX value
> returned by the CPUID
> > +                instruction. This is an optional
> parameter that may be NULL.
> > +  @param  Ebx   The pointer to the 32-bit EBX value
> returned by the CPUID
> > +                instruction. This is an optional
> parameter that may be NULL.
> > +  @param  Ecx   The pointer to the 32-bit ECX value
> returned by the CPUID
> > +                instruction. This is an optional
> parameter that may be NULL.
> > +  @param  Edx   The pointer to the 32-bit EDX value
> returned by the CPUID
> > +                instruction. This is an optional
> parameter that may be NULL.
> > +
> > +  @return Index.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +AsmCpuid (
> > +  IN      UINT32                    Index,
> > +  OUT     UINT32                    *Eax,  OPTIONAL
> > +  OUT     UINT32                    *Ebx,  OPTIONAL
> > +  OUT     UINT32                    *Ecx,  OPTIONAL
> > +  OUT     UINT32                    *Edx   OPTIONAL
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmCpuid (Index,
> Eax, Ebx, Ecx, Edx);
> > +}
> > +
> > +/**
> > +  Retrieves CPUID information using an extended leaf
> identifier.
> > +
> > +  Executes the CPUID instruction with EAX set to the
> value specified by Index
> > +  and ECX set to the value specified by SubIndex.
> This function always returns
> > +  Index. This function is only available on IA-32 and
> x64.
> > +
> > +  If Eax is not NULL, then the value of EAX after
> CPUID is returned in Eax.
> > +  If Ebx is not NULL, then the value of EBX after
> CPUID is returned in Ebx.
> > +  If Ecx is not NULL, then the value of ECX after
> CPUID is returned in Ecx.
> > +  If Edx is not NULL, then the value of EDX after
> CPUID is returned in Edx.
> > +
> > +  @param  Index     The 32-bit value to load into EAX
> prior to invoking the
> > +                    CPUID instruction.
> > +  @param  SubIndex  The 32-bit value to load into ECX
> prior to invoking the
> > +                    CPUID instruction.
> > +  @param  Eax       The pointer to the 32-bit EAX
> value returned by the CPUID
> > +                    instruction. This is an optional
> parameter that may be
> > +                    NULL.
> > +  @param  Ebx       The pointer to the 32-bit EBX
> value returned by the CPUID
> > +                    instruction. This is an optional
> parameter that may be
> > +                    NULL.
> > +  @param  Ecx       The pointer to the 32-bit ECX
> value returned by the CPUID
> > +                    instruction. This is an optional
> parameter that may be
> > +                    NULL.
> > +  @param  Edx       The pointer to the 32-bit EDX
> value returned by the CPUID
> > +                    instruction. This is an optional
> parameter that may be
> > +                    NULL.
> > +
> > +  @return Index.
> > +
> > +**/
> > +UINT32
> > +EFIAPI
> > +AsmCpuidEx (
> > +  IN      UINT32                    Index,
> > +  IN      UINT32                    SubIndex,
> > +  OUT     UINT32                    *Eax,  OPTIONAL
> > +  OUT     UINT32                    *Ebx,  OPTIONAL
> > +  OUT     UINT32                    *Ecx,  OPTIONAL
> > +  OUT     UINT32                    *Edx   OPTIONAL
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmCpuidEx (Index,
> SubIndex, Eax, Ebx, Ecx, Edx);
> > +}
> > +
> > +/**
> > +  Set CD bit and clear NW bit of CR0 followed by a
> WBINVD.
> > +
> > +  Disables the caches by setting the CD bit of CR0 to
> 1, clearing the NW bit of CR0 to 0,
> > +  and executing a WBINVD instruction.  This function
> is only available on IA-32 and x64.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmDisableCache (
> > +  VOID
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmDisableCache ();
> > +}
> > +
> > +/**
> > +  Perform a WBINVD and clear both the CD and NW bits
> of CR0.
> > +
> > +  Enables the caches by executing a WBINVD
> instruction and then clear both the CD and NW
> > +  bits of CR0 to 0.  This function is only available
> on IA-32 and x64.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmEnableCache (
> > +  VOID
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmEnableCache ();
> > +}
> > +
> > +/**
> > +  Returns a 64-bit Machine Specific Register(MSR).
> > +
> > +  Reads and returns the 64-bit MSR specified by
> Index. No parameter checking is
> > +  performed on Index, and some Index values may cause
> CPU exceptions. The
> > +  caller must either guarantee that Index is valid,
> or the caller must set up
> > +  exception handlers to catch the exceptions. This
> function is only available
> > +  on IA-32 and x64.
> > +
> > +  @param  Index The 32-bit MSR index to read.
> > +
> > +  @return The value of the MSR identified by Index.
> > +
> > +**/
> > +UINT64
> > +EFIAPI
> > +AsmReadMsr64 (
> > +  IN      UINT32                    Index
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadMsr64
> (Index);
> > +}
> > +
> > +/**
> > +  Writes a 64-bit value to a Machine Specific
> Register(MSR), and returns the
> > +  value.
> > +
> > +  Writes the 64-bit value specified by Value to the
> MSR specified by Index. The
> > +  64-bit value written to the MSR is returned. No
> parameter checking is
> > +  performed on Index or Value, and some of these may
> cause CPU exceptions. The
> > +  caller must either guarantee that Index and Value
> are valid, or the caller
> > +  must establish proper exception handlers. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @param  Index The 32-bit MSR index to write.
> > +  @param  Value The 64-bit value to write to the MSR.
> > +
> > +  @return Value
> > +
> > +**/
> > +UINT64
> > +EFIAPI
> > +AsmWriteMsr64 (
> > +  IN      UINT32                    Index,
> > +  IN      UINT64                    Value
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmWriteMsr64
> (Index, Value);
> > +}
> > +
> > +/**
> > +  Reads the current value of the Control Register 0
> (CR0).
> > +
> > +  Reads and returns the current value of CR0. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of the Control Register 0 (CR0).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmReadCr0 (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadCr0 ();
> > +}
> > +
> > +/**
> > +  Reads the current value of the Control Register 2
> (CR2).
> > +
> > +  Reads and returns the current value of CR2. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of the Control Register 2 (CR2).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmReadCr2 (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadCr2 ();
> > +}
> > +
> > +/**
> > +  Reads the current value of the Control Register 3
> (CR3).
> > +
> > +  Reads and returns the current value of CR3. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of the Control Register 3 (CR3).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmReadCr3 (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadCr3 ();
> > +}
> > +
> > +/**
> > +  Reads the current value of the Control Register 4
> (CR4).
> > +
> > +  Reads and returns the current value of CR4. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of the Control Register 4 (CR4).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmReadCr4 (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadCr4 ();
> > +}
> > +
> > +/**
> > +  Writes a value to Control Register 0 (CR0).
> > +
> > +  Writes and returns a new value to CR0. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Cr0 The value to write to CR0.
> > +
> > +  @return The value written to CR0.
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmWriteCr0 (
> > +  UINTN  Cr0
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmWriteCr0 (Cr0);
> > +}
> > +
> > +/**
> > +  Writes a value to Control Register 2 (CR2).
> > +
> > +  Writes and returns a new value to CR2. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Cr2 The value to write to CR2.
> > +
> > +  @return The value written to CR2.
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmWriteCr2 (
> > +  UINTN  Cr2
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmWriteCr2 (Cr2);
> > +}
> > +
> > +/**
> > +  Writes a value to Control Register 3 (CR3).
> > +
> > +  Writes and returns a new value to CR3. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Cr3 The value to write to CR3.
> > +
> > +  @return The value written to CR3.
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmWriteCr3 (
> > +  UINTN  Cr3
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmWriteCr3 (Cr3);
> > +}
> > +
> > +/**
> > +  Writes a value to Control Register 4 (CR4).
> > +
> > +  Writes and returns a new value to CR4. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Cr4 The value to write to CR4.
> > +
> > +  @return The value written to CR4.
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmWriteCr4 (
> > +  UINTN  Cr4
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmWriteCr4 (Cr4);
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 0 (DR0).
> > +
> > +  Reads and returns the current value of DR0. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 0 (DR0).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmReadDr0 (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadDr0 ();
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 1 (DR1).
> > +
> > +  Reads and returns the current value of DR1. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 1 (DR1).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmReadDr1 (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadDr1 ();
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 2 (DR2).
> > +
> > +  Reads and returns the current value of DR2. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 2 (DR2).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmReadDr2 (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadDr2 ();
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 3 (DR3).
> > +
> > +  Reads and returns the current value of DR3. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 3 (DR3).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmReadDr3 (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadDr3 ();
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 4 (DR4).
> > +
> > +  Reads and returns the current value of DR4. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 4 (DR4).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmReadDr4 (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadDr4 ();
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 5 (DR5).
> > +
> > +  Reads and returns the current value of DR5. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 5 (DR5).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmReadDr5 (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadDr5 ();
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 6 (DR6).
> > +
> > +  Reads and returns the current value of DR6. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 6 (DR6).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmReadDr6 (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadDr6 ();
> > +}
> > +
> > +/**
> > +  Reads the current value of Debug Register 7 (DR7).
> > +
> > +  Reads and returns the current value of DR7. This
> function is only available
> > +  on IA-32 and x64. This returns a 32-bit value on
> IA-32 and a 64-bit value on
> > +  x64.
> > +
> > +  @return The value of Debug Register 7 (DR7).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmReadDr7 (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadDr7 ();
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 0 (DR0).
> > +
> > +  Writes and returns a new value to DR0. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr0 The value to write to Dr0.
> > +
> > +  @return The value written to Debug Register 0
> (DR0).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmWriteDr0 (
> > +  UINTN  Dr0
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmWriteDr0 (Dr0);
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 1 (DR1).
> > +
> > +  Writes and returns a new value to DR1. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr1 The value to write to Dr1.
> > +
> > +  @return The value written to Debug Register 1
> (DR1).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmWriteDr1 (
> > +  UINTN  Dr1
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmWriteDr1 (Dr1);
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 2 (DR2).
> > +
> > +  Writes and returns a new value to DR2. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr2 The value to write to Dr2.
> > +
> > +  @return The value written to Debug Register 2
> (DR2).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmWriteDr2 (
> > +  UINTN  Dr2
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmWriteDr2 (Dr2);
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 3 (DR3).
> > +
> > +  Writes and returns a new value to DR3. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr3 The value to write to Dr3.
> > +
> > +  @return The value written to Debug Register 3
> (DR3).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmWriteDr3 (
> > +  UINTN  Dr3
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmWriteDr3 (Dr3);
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 4 (DR4).
> > +
> > +  Writes and returns a new value to DR4. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr4 The value to write to Dr4.
> > +
> > +  @return The value written to Debug Register 4
> (DR4).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmWriteDr4 (
> > +  UINTN  Dr4
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmWriteDr4 (Dr4);
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 5 (DR5).
> > +
> > +  Writes and returns a new value to DR5. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr5 The value to write to Dr5.
> > +
> > +  @return The value written to Debug Register 5
> (DR5).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmWriteDr5 (
> > +  UINTN  Dr5
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmWriteDr5 (Dr5);
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 6 (DR6).
> > +
> > +  Writes and returns a new value to DR6. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr6 The value to write to Dr6.
> > +
> > +  @return The value written to Debug Register 6
> (DR6).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmWriteDr6 (
> > +  UINTN  Dr6
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmWriteDr6 (Dr6);
> > +}
> > +
> > +/**
> > +  Writes a value to Debug Register 7 (DR7).
> > +
> > +  Writes and returns a new value to DR7. This
> function is only available on
> > +  IA-32 and x64. This writes a 32-bit value on IA-32
> and a 64-bit value on x64.
> > +
> > +  @param  Dr7 The value to write to Dr7.
> > +
> > +  @return The value written to Debug Register 7
> (DR7).
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmWriteDr7 (
> > +  UINTN  Dr7
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmWriteDr7 (Dr7);
> > +}
> > +
> > +/**
> > +  Reads the current value of Code Segment Register
> (CS).
> > +
> > +  Reads and returns the current value of CS. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @return The current value of CS.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +AsmReadCs (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadCs ();
> > +}
> > +
> > +/**
> > +  Reads the current value of Data Segment Register
> (DS).
> > +
> > +  Reads and returns the current value of DS. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @return The current value of DS.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +AsmReadDs (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadDs ();
> > +}
> > +
> > +/**
> > +  Reads the current value of Extra Segment Register
> (ES).
> > +
> > +  Reads and returns the current value of ES. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @return The current value of ES.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +AsmReadEs (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadEs ();
> > +}
> > +
> > +/**
> > +  Reads the current value of FS Data Segment Register
> (FS).
> > +
> > +  Reads and returns the current value of FS. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @return The current value of FS.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +AsmReadFs (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadFs ();
> > +}
> > +
> > +/**
> > +  Reads the current value of GS Data Segment Register
> (GS).
> > +
> > +  Reads and returns the current value of GS. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @return The current value of GS.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +AsmReadGs (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadGs ();
> > +}
> > +
> > +/**
> > +  Reads the current value of Stack Segment Register
> (SS).
> > +
> > +  Reads and returns the current value of SS. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @return The current value of SS.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +AsmReadSs (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadSs ();
> > +}
> > +
> > +/**
> > +  Reads the current value of Task Register (TR).
> > +
> > +  Reads and returns the current value of TR. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @return The current value of TR.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +AsmReadTr (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadTr ();
> > +}
> > +
> > +/**
> > +  Reads the current Global Descriptor Table
> Register(GDTR) descriptor.
> > +
> > +  Reads and returns the current GDTR descriptor and
> returns it in Gdtr. This
> > +  function is only available on IA-32 and x64.
> > +
> > +  If Gdtr is NULL, then ASSERT().
> > +
> > +  @param  Gdtr  The pointer to a GDTR descriptor.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmReadGdtr (
> > +  OUT     IA32_DESCRIPTOR           *Gdtr
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmReadGdtr (Gdtr);
> > +}
> > +
> > +/**
> > +  Writes the current Global Descriptor Table Register
> (GDTR) descriptor.
> > +
> > +  Writes and the current GDTR descriptor specified by
> Gdtr. This function is
> > +  only available on IA-32 and x64.
> > +
> > +  If Gdtr is NULL, then ASSERT().
> > +
> > +  @param  Gdtr  The pointer to a GDTR descriptor.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmWriteGdtr (
> > +  IN      CONST IA32_DESCRIPTOR     *Gdtr
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmWriteGdtr (Gdtr);
> > +}
> > +
> > +/**
> > +  Reads the current Interrupt Descriptor Table
> Register(IDTR) descriptor.
> > +
> > +  Reads and returns the current IDTR descriptor and
> returns it in Idtr. This
> > +  function is only available on IA-32 and x64.
> > +
> > +  If Idtr is NULL, then ASSERT().
> > +
> > +  @param  Idtr  The pointer to a IDTR descriptor.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmReadIdtr (
> > +  OUT     IA32_DESCRIPTOR           *Idtr
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmReadIdtr (Idtr);
> > +}
> > +
> > +/**
> > +  Writes the current Interrupt Descriptor Table
> Register(IDTR) descriptor.
> > +
> > +  Writes the current IDTR descriptor and returns it
> in Idtr. This function is
> > +  only available on IA-32 and x64.
> > +
> > +  If Idtr is NULL, then ASSERT().
> > +
> > +  @param  Idtr  The pointer to a IDTR descriptor.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmWriteIdtr (
> > +  IN      CONST IA32_DESCRIPTOR     *Idtr
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmWriteIdtr (Idtr);
> > +}
> > +
> > +/**
> > +  Reads the current Local Descriptor Table
> Register(LDTR) selector.
> > +
> > +  Reads and returns the current 16-bit LDTR
> descriptor value. This function is
> > +  only available on IA-32 and x64.
> > +
> > +  @return The current selector of LDT.
> > +
> > +**/
> > +UINT16
> > +EFIAPI
> > +AsmReadLdtr (
> > +  VOID
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadLdtr ();
> > +}
> > +
> > +/**
> > +  Writes the current Local Descriptor Table Register
> (LDTR) selector.
> > +
> > +  Writes and the current LDTR descriptor specified by
> Ldtr. This function is
> > +  only available on IA-32 and x64.
> > +
> > +  @param  Ldtr  16-bit LDTR selector value.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmWriteLdtr (
> > +  IN      UINT16                    Ldtr
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmWriteLdtr (Ldtr);
> > +}
> > +
> > +/**
> > +  Reads the current value of a Performance Counter
> (PMC).
> > +
> > +  Reads and returns the current value of performance
> counter specified by
> > +  Index. This function is only available on IA-32 and
> x64.
> > +
> > +  @param  Index The 32-bit Performance Counter index
> to read.
> > +
> > +  @return The value of the PMC specified by Index.
> > +
> > +**/
> > +UINT64
> > +EFIAPI
> > +AsmReadPmc (
> > +  IN      UINT32                    Index
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmReadPmc
> (Index);
> > +}
> > +
> > +/**
> > +  Sets up a monitor buffer that is used by
> AsmMwait().
> > +
> > +  Executes a MONITOR instruction with the register
> state specified by Eax, Ecx
> > +  and Edx. Returns Eax. This function is only
> available on IA-32 and x64.
> > +
> > +  @param  Eax The value to load into EAX or RAX
> before executing the MONITOR
> > +              instruction.
> > +  @param  Ecx The value to load into ECX or RCX
> before executing the MONITOR
> > +              instruction.
> > +  @param  Edx The value to load into EDX or RDX
> before executing the MONITOR
> > +              instruction.
> > +
> > +  @return Eax
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmMonitor (
> > +  IN      UINTN                     Eax,
> > +  IN      UINTN                     Ecx,
> > +  IN      UINTN                     Edx
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmMonitor (Eax,
> Ecx, Edx);
> > +}
> > +
> > +/**
> > +  Executes an MWAIT instruction.
> > +
> > +  Executes an MWAIT instruction with the register
> state specified by Eax and
> > +  Ecx. Returns Eax. This function is only available
> on IA-32 and x64.
> > +
> > +  @param  Eax The value to load into EAX or RAX
> before executing the MONITOR
> > +              instruction.
> > +  @param  Ecx The value to load into ECX or RCX
> before executing the MONITOR
> > +              instruction.
> > +
> > +  @return Eax
> > +
> > +**/
> > +UINTN
> > +EFIAPI
> > +AsmMwait (
> > +  IN      UINTN                     Eax,
> > +  IN      UINTN                     Ecx
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmMwait (Eax,
> Ecx);
> > +}
> > +
> > +/**
> > +  Executes a WBINVD instruction.
> > +
> > +  Executes a WBINVD instruction. This function is
> only available on IA-32 and
> > +  x64.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmWbinvd (
> > +  VOID
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmWbinvd ();
> > +}
> > +
> > +/**
> > +  Executes a INVD instruction.
> > +
> > +  Executes a INVD instruction. This function is only
> available on IA-32 and
> > +  x64.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmInvd (
> > +  VOID
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmInvd ();
> > +}
> > +
> > +/**
> > +  Flushes a cache line from all the instruction and
> data caches within the
> > +  coherency domain of the CPU.
> > +
> > +  Flushed the cache line specified by LinearAddress,
> and returns LinearAddress.
> > +  This function is only available on IA-32 and x64.
> > +
> > +  @param  LinearAddress The address of the cache line
> to flush. If the CPU is
> > +                        in a physical addressing
> mode, then LinearAddress is a
> > +                        physical address. If the CPU
> is in a virtual
> > +                        addressing mode, then
> LinearAddress is a virtual
> > +                        address.
> > +
> > +  @return LinearAddress.
> > +**/
> > +VOID *
> > +EFIAPI
> > +AsmFlushCacheLine (
> > +  IN      VOID                      *LinearAddress
> > +  )
> > +{
> > +  return gUnitTestHostBaseLib.X86->AsmFlushCacheLine
> (LinearAddress);
> > +}
> > +
> > +/**
> > +  Enables the 32-bit paging mode on the CPU.
> > +
> > +  Enables the 32-bit paging mode on the CPU. CR0,
> CR3, CR4, and the page tables
> > +  must be properly initialized prior to calling this
> service. This function
> > +  assumes the current execution mode is 32-bit
> protected mode. This function is
> > +  only available on IA-32. After the 32-bit paging
> mode is enabled, control is
> > +  transferred to the function specified by EntryPoint
> using the new stack
> > +  specified by NewStack and passing in the parameters
> specified by Context1 and
> > +  Context2. Context1 and Context2 are optional and
> may be NULL. The function
> > +  EntryPoint must never return.
> > +
> > +  If the current execution mode is not 32-bit
> protected mode, then ASSERT().
> > +  If EntryPoint is NULL, then ASSERT().
> > +  If NewStack is NULL, then ASSERT().
> > +
> > +  There are a number of constraints that must be
> followed before calling this
> > +  function:
> > +  1)  Interrupts must be disabled.
> > +  2)  The caller must be in 32-bit protected mode
> with flat descriptors. This
> > +      means all descriptors must have a base of 0 and
> a limit of 4GB.
> > +  3)  CR0 and CR4 must be compatible with 32-bit
> protected mode with flat
> > +      descriptors.
> > +  4)  CR3 must point to valid page tables that will
> be used once the transition
> > +      is complete, and those page tables must
> guarantee that the pages for this
> > +      function and the stack are identity mapped.
> > +
> > +  @param  EntryPoint  A pointer to function to call
> with the new stack after
> > +                      paging is enabled.
> > +  @param  Context1    A pointer to the context to
> pass into the EntryPoint
> > +                      function as the first parameter
> after paging is enabled.
> > +  @param  Context2    A pointer to the context to
> pass into the EntryPoint
> > +                      function as the second
> parameter after paging is enabled.
> > +  @param  NewStack    A pointer to the new stack to
> use for the EntryPoint
> > +                      function after paging is
> enabled.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmEnablePaging32 (
> > +  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,
> > +  IN      VOID                      *Context1,
> OPTIONAL
> > +  IN      VOID                      *Context2,
> OPTIONAL
> > +  IN      VOID                      *NewStack
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmEnablePaging32
> (EntryPoint, Context1, Context2, NewStack);
> > +}
> > +
> > +/**
> > +  Disables the 32-bit paging mode on the CPU.
> > +
> > +  Disables the 32-bit paging mode on the CPU and
> returns to 32-bit protected
> > +  mode. This function assumes the current execution
> mode is 32-paged protected
> > +  mode. This function is only available on IA-32.
> After the 32-bit paging mode
> > +  is disabled, control is transferred to the function
> specified by EntryPoint
> > +  using the new stack specified by NewStack and
> passing in the parameters
> > +  specified by Context1 and Context2. Context1 and
> Context2 are optional and
> > +  may be NULL. The function EntryPoint must never
> return.
> > +
> > +  If the current execution mode is not 32-bit paged
> mode, then ASSERT().
> > +  If EntryPoint is NULL, then ASSERT().
> > +  If NewStack is NULL, then ASSERT().
> > +
> > +  There are a number of constraints that must be
> followed before calling this
> > +  function:
> > +  1)  Interrupts must be disabled.
> > +  2)  The caller must be in 32-bit paged mode.
> > +  3)  CR0, CR3, and CR4 must be compatible with 32-
> bit paged mode.
> > +  4)  CR3 must point to valid page tables that
> guarantee that the pages for
> > +      this function and the stack are identity
> mapped.
> > +
> > +  @param  EntryPoint  A pointer to function to call
> with the new stack after
> > +                      paging is disabled.
> > +  @param  Context1    A pointer to the context to
> pass into the EntryPoint
> > +                      function as the first parameter
> after paging is disabled.
> > +  @param  Context2    A pointer to the context to
> pass into the EntryPoint
> > +                      function as the second
> parameter after paging is
> > +                      disabled.
> > +  @param  NewStack    A pointer to the new stack to
> use for the EntryPoint
> > +                      function after paging is
> disabled.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmDisablePaging32 (
> > +  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,
> > +  IN      VOID                      *Context1,
> OPTIONAL
> > +  IN      VOID                      *Context2,
> OPTIONAL
> > +  IN      VOID                      *NewStack
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmDisablePaging32
> (EntryPoint, Context1, Context2, NewStack);
> > +}
> > +
> > +/**
> > +  Enables the 64-bit paging mode on the CPU.
> > +
> > +  Enables the 64-bit paging mode on the CPU. CR0,
> CR3, CR4, and the page tables
> > +  must be properly initialized prior to calling this
> service. This function
> > +  assumes the current execution mode is 32-bit
> protected mode with flat
> > +  descriptors. This function is only available on IA-
> 32. After the 64-bit
> > +  paging mode is enabled, control is transferred to
> the function specified by
> > +  EntryPoint using the new stack specified by
> NewStack and passing in the
> > +  parameters specified by Context1 and Context2.
> Context1 and Context2 are
> > +  optional and may be 0. The function EntryPoint must
> never return.
> > +
> > +  If the current execution mode is not 32-bit
> protected mode with flat
> > +  descriptors, then ASSERT().
> > +  If EntryPoint is 0, then ASSERT().
> > +  If NewStack is 0, then ASSERT().
> > +
> > +  @param  Cs          The 16-bit selector to load in
> the CS before EntryPoint
> > +                      is called. The descriptor in
> the GDT that this selector
> > +                      references must be setup for
> long mode.
> > +  @param  EntryPoint  The 64-bit virtual address of
> the function to call with
> > +                      the new stack after paging is
> enabled.
> > +  @param  Context1    The 64-bit virtual address of
> the context to pass into
> > +                      the EntryPoint function as the
> first parameter after
> > +                      paging is enabled.
> > +  @param  Context2    The 64-bit virtual address of
> the context to pass into
> > +                      the EntryPoint function as the
> second parameter after
> > +                      paging is enabled.
> > +  @param  NewStack    The 64-bit virtual address of
> the new stack to use for
> > +                      the EntryPoint function after
> paging is enabled.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmEnablePaging64 (
> > +  IN      UINT16                    Cs,
> > +  IN      UINT64                    EntryPoint,
> > +  IN      UINT64                    Context1,
> OPTIONAL
> > +  IN      UINT64                    Context2,
> OPTIONAL
> > +  IN      UINT64                    NewStack
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmEnablePaging64 (Cs,
> EntryPoint, Context1, Context2, NewStack);
> > +}
> > +
> > +/**
> > +  Disables the 64-bit paging mode on the CPU.
> > +
> > +  Disables the 64-bit paging mode on the CPU and
> returns to 32-bit protected
> > +  mode. This function assumes the current execution
> mode is 64-paging mode.
> > +  This function is only available on x64. After the
> 64-bit paging mode is
> > +  disabled, control is transferred to the function
> specified by EntryPoint
> > +  using the new stack specified by NewStack and
> passing in the parameters
> > +  specified by Context1 and Context2. Context1 and
> Context2 are optional and
> > +  may be 0. The function EntryPoint must never
> return.
> > +
> > +  If the current execution mode is not 64-bit paged
> mode, then ASSERT().
> > +  If EntryPoint is 0, then ASSERT().
> > +  If NewStack is 0, then ASSERT().
> > +
> > +  @param  Cs          The 16-bit selector to load in
> the CS before EntryPoint
> > +                      is called. The descriptor in
> the GDT that this selector
> > +                      references must be setup for
> 32-bit protected mode.
> > +  @param  EntryPoint  The 64-bit virtual address of
> the function to call with
> > +                      the new stack after paging is
> disabled.
> > +  @param  Context1    The 64-bit virtual address of
> the context to pass into
> > +                      the EntryPoint function as the
> first parameter after
> > +                      paging is disabled.
> > +  @param  Context2    The 64-bit virtual address of
> the context to pass into
> > +                      the EntryPoint function as the
> second parameter after
> > +                      paging is disabled.
> > +  @param  NewStack    The 64-bit virtual address of
> the new stack to use for
> > +                      the EntryPoint function after
> paging is disabled.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmDisablePaging64 (
> > +  IN      UINT16                    Cs,
> > +  IN      UINT32                    EntryPoint,
> > +  IN      UINT32                    Context1,
> OPTIONAL
> > +  IN      UINT32                    Context2,
> OPTIONAL
> > +  IN      UINT32                    NewStack
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmDisablePaging64 (Cs,
> EntryPoint, Context1, Context2, NewStack);
> > +}
> > +
> > +/**
> > +  Retrieves the properties for 16-bit thunk
> functions.
> > +
> > +  Computes the size of the buffer and stack below 1MB
> required to use the
> > +  AsmPrepareThunk16(), AsmThunk16() and
> AsmPrepareAndThunk16() functions. This
> > +  buffer size is returned in RealModeBufferSize, and
> the stack size is returned
> > +  in ExtraStackSize. If parameters are passed to the
> 16-bit real mode code,
> > +  then the actual minimum stack size is
> ExtraStackSize plus the maximum number
> > +  of bytes that need to be passed to the 16-bit real
> mode code.
> > +
> > +  If RealModeBufferSize is NULL, then ASSERT().
> > +  If ExtraStackSize is NULL, then ASSERT().
> > +
> > +  @param  RealModeBufferSize  A pointer to the size
> of the buffer below 1MB
> > +                              required to use the 16-
> bit thunk functions.
> > +  @param  ExtraStackSize      A pointer to the extra
> size of stack below 1MB
> > +                              that the 16-bit thunk
> functions require for
> > +                              temporary storage in
> the transition to and from
> > +                              16-bit real mode.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmGetThunk16Properties (
> > +  OUT     UINT32
> *RealModeBufferSize,
> > +  OUT     UINT32                    *ExtraStackSize
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmGetThunk16Properties
> (RealModeBufferSize, ExtraStackSize);
> > +}
> > +
> > +/**
> > +  Prepares all structures a code required to use
> AsmThunk16().
> > +
> > +  Prepares all structures and code required to use
> AsmThunk16().
> > +
> > +  This interface is limited to be used in either
> physical mode or virtual modes with paging enabled where
> the
> > +  virtual to physical mappings for
> ThunkContext.RealModeBuffer is mapped 1:1.
> > +
> > +  If ThunkContext is NULL, then ASSERT().
> > +
> > +  @param  ThunkContext  A pointer to the context
> structure that describes the
> > +                        16-bit real mode code to
> call.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmPrepareThunk16 (
> > +  IN OUT  THUNK_CONTEXT             *ThunkContext
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmPrepareThunk16
> (ThunkContext);
> > +}
> > +
> > +/**
> > +  Transfers control to a 16-bit real mode entry point
> and returns the results.
> > +
> > +  Transfers control to a 16-bit real mode entry point
> and returns the results.
> > +  AsmPrepareThunk16() must be called with
> ThunkContext before this function is used.
> > +  This function must be called with interrupts
> disabled.
> > +
> > +  The register state from the RealModeState field of
> ThunkContext is restored just prior
> > +  to calling the 16-bit real mode entry point.  This
> includes the EFLAGS field of RealModeState,
> > +  which is used to set the interrupt state when a 16-
> bit real mode entry point is called.
> > +  Control is transferred to the 16-bit real mode
> entry point specified by the CS and Eip fields of
> RealModeState.
> > +  The stack is initialized to the SS and ESP fields
> of RealModeState.  Any parameters passed to
> > +  the 16-bit real mode code must be populated by the
> caller at SS:ESP prior to calling this function.
> > +  The 16-bit real mode entry point is invoked with a
> 16-bit CALL FAR instruction,
> > +  so when accessing stack contents, the 16-bit real
> mode code must account for the 16-bit segment
> > +  and 16-bit offset of the return address that were
> pushed onto the stack. The 16-bit real mode entry
> > +  point must exit with a RETF instruction. The
> register state is captured into RealModeState
> immediately
> > +  after the RETF instruction is executed.
> > +
> > +  If EFLAGS specifies interrupts enabled, or any of
> the 16-bit real mode code enables interrupts,
> > +  or any of the 16-bit real mode code makes a SW
> interrupt, then the caller is responsible for making
> sure
> > +  the IDT at address 0 is initialized to handle any
> HW or SW interrupts that may occur while in 16-bit real
> mode.
> > +
> > +  If EFLAGS specifies interrupts enabled, or any of
> the 16-bit real mode code enables interrupts,
> > +  then the caller is responsible for making sure the
> 8259 PIC is in a state compatible with 16-bit real mode.
> > +  This includes the base vectors, the interrupt
> masks, and the edge/level trigger mode.
> > +
> > +  If THUNK_ATTRIBUTE_BIG_REAL_MODE is set in the
> ThunkAttributes field of ThunkContext, then the user
> code
> > +  is invoked in big real mode.  Otherwise, the user
> code is invoked in 16-bit real mode with 64KB segment
> limits.
> > +
> > +  If neither THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15
> nor THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL are set in
> > +  ThunkAttributes, then it is assumed that the user
> code did not enable the A20 mask, and no attempt is made
> to
> > +  disable the A20 mask.
> > +
> > +  If THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 is set
> and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL is clear
> in
> > +  ThunkAttributes, then attempt to use the INT 15
> service to disable the A20 mask.  If this INT 15 call
> fails,
> > +  then attempt to disable the A20 mask by directly
> accessing the 8042 keyboard controller I/O ports.
> > +
> > +  If THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 is clear
> and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL is set in
> > +  ThunkAttributes, then attempt to disable the A20
> mask by directly accessing the 8042 keyboard controller
> I/O ports.
> > +
> > +  If ThunkContext is NULL, then ASSERT().
> > +  If AsmPrepareThunk16() was not previously called
> with ThunkContext, then ASSERT().
> > +  If both THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 and
> THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL are set in
> > +  ThunkAttributes, then ASSERT().
> > +
> > +  This interface is limited to be used in either
> physical mode or virtual modes with paging enabled where
> the
> > +  virtual to physical mappings for
> ThunkContext.RealModeBuffer are mapped 1:1.
> > +
> > +  @param  ThunkContext  A pointer to the context
> structure that describes the
> > +                        16-bit real mode code to
> call.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmThunk16 (
> > +  IN OUT  THUNK_CONTEXT             *ThunkContext
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmThunk16
> (ThunkContext);
> > +}
> > +
> > +/**
> > +  Prepares all structures and code for a 16-bit real
> mode thunk, transfers
> > +  control to a 16-bit real mode entry point, and
> returns the results.
> > +
> > +  Prepares all structures and code for a 16-bit real
> mode thunk, transfers
> > +  control to a 16-bit real mode entry point, and
> returns the results. If the
> > +  caller only need to perform a single 16-bit real
> mode thunk, then this
> > +  service should be used. If the caller intends to
> make more than one 16-bit
> > +  real mode thunk, then it is more efficient if
> AsmPrepareThunk16() is called
> > +  once and AsmThunk16() can be called for each 16-bit
> real mode thunk.
> > +
> > +  This interface is limited to be used in either
> physical mode or virtual modes with paging enabled where
> the
> > +  virtual to physical mappings for
> ThunkContext.RealModeBuffer is mapped 1:1.
> > +
> > +  See AsmPrepareThunk16() and AsmThunk16() for the
> detailed description and ASSERT() conditions.
> > +
> > +  @param  ThunkContext  A pointer to the context
> structure that describes the
> > +                        16-bit real mode code to
> call.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmPrepareAndThunk16 (
> > +  IN OUT  THUNK_CONTEXT             *ThunkContext
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmPrepareAndThunk16
> (ThunkContext);
> > +}
> > +
> > +/**
> > +  Load given selector into TR register.
> > +
> > +  @param[in] Selector     Task segment selector
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmWriteTr (
> > +  IN UINT16 Selector
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmWriteTr (Selector);
> > +}
> > +
> > +/**
> > +  Performs a serializing operation on all load-from-
> memory instructions that
> > +  were issued prior the AsmLfence function.
> > +
> > +  Executes a LFENCE instruction. This function is
> only available on IA-32 and x64.
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +AsmLfence (
> > +  VOID
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->AsmLfence ();
> > +}
> > +
> > +/**
> > +  Patch the immediate operand of an IA32 or X64
> instruction such that the byte,
> > +  word, dword or qword operand is encoded at the end
> of the instruction's
> > +  binary representation.
> > +
> > +  This function should be used to update object code
> that was compiled with
> > +  NASM from assembly source code. Example:
> > +
> > +  NASM source code:
> > +
> > +        mov     eax, strict dword 0 ; the imm32 zero
> operand will be patched
> > +    ASM_PFX(gPatchCr3):
> > +        mov     cr3, eax
> > +
> > +  C source code:
> > +
> > +    X86_ASSEMBLY_PATCH_LABEL gPatchCr3;
> > +    PatchInstructionX86 (gPatchCr3, AsmReadCr3 (),
> 4);
> > +
> > +  @param[out] InstructionEnd  Pointer right past the
> instruction to patch. The
> > +                              immediate operand to
> patch is expected to
> > +                              comprise the trailing
> bytes of the instruction.
> > +                              If InstructionEnd is
> closer to address 0 than
> > +                              ValueSize permits, then
> ASSERT().
> > +
> > +  @param[in] PatchValue       The constant to write
> to the immediate operand.
> > +                              The caller is
> responsible for ensuring that
> > +                              PatchValue can be
> represented in the byte, word,
> > +                              dword or qword operand
> (as indicated through
> > +                              ValueSize); otherwise
> ASSERT().
> > +
> > +  @param[in] ValueSize        The size of the operand
> in bytes; must be 1, 2,
> > +                              4, or 8. ASSERT()
> otherwise.
> > +**/
> > +VOID
> > +EFIAPI
> > +PatchInstructionX86 (
> > +  OUT X86_ASSEMBLY_PATCH_LABEL *InstructionEnd,
> > +  IN  UINT64                   PatchValue,
> > +  IN  UINTN                    ValueSize
> > +  )
> > +{
> > +  gUnitTestHostBaseLib.X86->PatchInstructionX86
> (InstructionEnd, PatchValue, ValueSize);
> > +}
> > +
> > +///
> > +/// Common services
> > +///
> > +STATIC UNIT_TEST_HOST_BASE_LIB_COMMON
> mUnitTestHostBaseLibCommon = {
> > +  UnitTestHostBaseLibEnableInterrupts,
> > +  UnitTestHostBaseLibDisableInterrupts,
> > +  UnitTestHostBaseLibEnableDisableInterrupts,
> > +  UnitTestHostBaseLibGetInterruptState,
> > +};
> > +
> > +///
> > +/// IA32/X64 services
> > +///
> > +STATIC UNIT_TEST_HOST_BASE_LIB_X86
> mUnitTestHostBaseLibX86 = {
> > +  UnitTestHostBaseLibAsmCpuid,
> > +  UnitTestHostBaseLibAsmCpuidEx,
> > +  UnitTestHostBaseLibAsmDisableCache,
> > +  UnitTestHostBaseLibAsmEnableCache,
> > +  UnitTestHostBaseLibAsmReadMsr64,
> > +  UnitTestHostBaseLibAsmWriteMsr64,
> > +  UnitTestHostBaseLibAsmReadCr0,
> > +  UnitTestHostBaseLibAsmReadCr2,
> > +  UnitTestHostBaseLibAsmReadCr3,
> > +  UnitTestHostBaseLibAsmReadCr4,
> > +  UnitTestHostBaseLibAsmWriteCr0,
> > +  UnitTestHostBaseLibAsmWriteCr2,
> > +  UnitTestHostBaseLibAsmWriteCr3,
> > +  UnitTestHostBaseLibAsmWriteCr4,
> > +  UnitTestHostBaseLibAsmReadDr0,
> > +  UnitTestHostBaseLibAsmReadDr1,
> > +  UnitTestHostBaseLibAsmReadDr2,
> > +  UnitTestHostBaseLibAsmReadDr3,
> > +  UnitTestHostBaseLibAsmReadDr4,
> > +  UnitTestHostBaseLibAsmReadDr5,
> > +  UnitTestHostBaseLibAsmReadDr6,
> > +  UnitTestHostBaseLibAsmReadDr7,
> > +  UnitTestHostBaseLibAsmWriteDr0,
> > +  UnitTestHostBaseLibAsmWriteDr1,
> > +  UnitTestHostBaseLibAsmWriteDr2,
> > +  UnitTestHostBaseLibAsmWriteDr3,
> > +  UnitTestHostBaseLibAsmWriteDr4,
> > +  UnitTestHostBaseLibAsmWriteDr5,
> > +  UnitTestHostBaseLibAsmWriteDr6,
> > +  UnitTestHostBaseLibAsmWriteDr7,
> > +  UnitTestHostBaseLibAsmReadCs,
> > +  UnitTestHostBaseLibAsmReadDs,
> > +  UnitTestHostBaseLibAsmReadEs,
> > +  UnitTestHostBaseLibAsmReadFs,
> > +  UnitTestHostBaseLibAsmReadGs,
> > +  UnitTestHostBaseLibAsmReadSs,
> > +  UnitTestHostBaseLibAsmReadTr,
> > +  UnitTestHostBaseLibAsmReadGdtr,
> > +  UnitTestHostBaseLibAsmWriteGdtr,
> > +  UnitTestHostBaseLibAsmReadIdtr,
> > +  UnitTestHostBaseLibAsmWriteIdtr,
> > +  UnitTestHostBaseLibAsmReadLdtr,
> > +  UnitTestHostBaseLibAsmWriteLdtr,
> > +  UnitTestHostBaseLibAsmReadPmc,
> > +  UnitTestHostBaseLibAsmMonitor,
> > +  UnitTestHostBaseLibAsmMwait,
> > +  UnitTestHostBaseLibAsmWbinvd,
> > +  UnitTestHostBaseLibAsmInvd,
> > +  UnitTestHostBaseLibAsmFlushCacheLine,
> > +  UnitTestHostBaseLibAsmEnablePaging32,
> > +  UnitTestHostBaseLibAsmDisablePaging32,
> > +  UnitTestHostBaseLibAsmEnablePaging64,
> > +  UnitTestHostBaseLibAsmDisablePaging64,
> > +  UnitTestHostBaseLibAsmGetThunk16Properties,
> > +  UnitTestHostBaseLibAsmPrepareThunk16,
> > +  UnitTestHostBaseLibAsmThunk16,
> > +  UnitTestHostBaseLibAsmPrepareAndThunk16,
> > +  UnitTestHostBaseLibAsmWriteTr,
> > +  UnitTestHostBaseLibAsmLfence,
> > +  UnitTestHostBaseLibPatchInstructionX86
> > +};
> > +
> > +///
> > +/// Structure of hook functions for BaseLib functions
> that can not be used from
> > +/// a host application.  A simple emulation of these
> function is provided by
> > +/// default.  A specific unit test can provide its
> own implementation for any
> > +/// of these functions.
> > +///
> > +UNIT_TEST_HOST_BASE_LIB  gUnitTestHostBaseLib = {
> > +  &mUnitTestHostBaseLibCommon,
> > +  &mUnitTestHostBaseLibX86
> > +};
> > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
> > index 682e61cb88..855012172d 100644
> > --- a/MdePkg/MdePkg.dec
> > +++ b/MdePkg/MdePkg.dec
> > @@ -4,7 +4,7 @@
> >  # It also provides the definitions(including
> PPIs/PROTOCOLs/GUIDs) of
> >  # EFI1.10/UEFI2.7/PI1.7 and some Industry Standards.
> >  #
> > -# Copyright (c) 2007 - 2019, Intel Corporation. All
> rights reserved.<BR>
> > +# Copyright (c) 2007 - 2020, Intel Corporation. All
> rights reserved.<BR>
> >  # Portions copyright (c) 2008 - 2009, Apple Inc. All
> rights reserved.<BR>
> >  # (C) Copyright 2016 - 2020 Hewlett Packard
> Enterprise Development LP<BR>
> >  #
> > @@ -23,6 +23,7 @@ [Defines]
> >
> >  [Includes]
> >    Include
> > +  Test/UnitTest/Include
> >
> >  [Includes.IA32]
> >    Include/Ia32
> > diff --git a/MdePkg/Test/MdePkgHostTest.dsc
> b/MdePkg/Test/MdePkgHostTest.dsc
> > index 3d677ee75c..0cac14f0e5 100644
> > --- a/MdePkg/Test/MdePkgHostTest.dsc
> > +++ b/MdePkg/Test/MdePkgHostTest.dsc
> > @@ -28,3 +28,8 @@ [Components]
> >    #
> >
> MdePkg/Test/UnitTest/Library/BaseSafeIntLib/TestBaseSafe
> IntLibHost.inf
> >
> MdePkg/Test/UnitTest/Library/BaseLib/BaseLibUnitTestsHos
> t.inf
> > +
> > +  #
> > +  # Build HOST_APPLICATION Libraries
> > +  #
> > +  MdePkg/Library/BaseLib/UnitTestHostBaseLib.inf
> > diff --git
> a/MdePkg/Test/UnitTest/Include/HostTest/UnitTestHostBase
> Lib.h
> >
> b/MdePkg/Test/UnitTest/Include/HostTest/UnitTestHostBase
> Lib.h
> > new file mode 100644
> > index 0000000000..4ad05a5af1
> > --- /dev/null
> > +++
> b/MdePkg/Test/UnitTest/Include/HostTest/UnitTestHostBase
> Lib.h
> > @@ -0,0 +1,582 @@
> > +/** @file
> > +  Unit Test Host BaseLib hooks.
> > +
> > +  Copyright (c) 2020, Intel Corporation. All rights
> reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +
> > +#ifndef __UNIT_TEST_HOST_BASE_LIB_H__
> > +#define __UNIT_TEST_HOST_BASE_LIB_H__
> > +
> > +/**
> > +  Prototype of service with no parameters and no
> return value.
> > +**/
> > +typedef
> > +VOID
> > +(EFIAPI *UNIT_TEST_HOST_BASE_LIB_VOID)(
> > +  VOID
> > +  );
> > +
> > +/**
> > +  Prototype of service that reads and returns a
> BOOLEAN value.
> > +
> > +  @return The value read.
> > +**/
> > +typedef
> > +BOOLEAN
> > +(EFIAPI *UNIT_TEST_HOST_BASE_LIB_READ_BOOLEAN)(
> > +  VOID
> > +  );
> > +
> > +/**
> > +  Prototype of service that reads and returns a
> UINT16 value.
> > +
> > +  @return The value read.
> > +**/
> > +typedef
> > +UINT16
> > +(EFIAPI *UNIT_TEST_HOST_BASE_LIB_READ_UINT16)(
> > +  VOID
> > +  );
> > +
> > +/**
> > +  Prototype of service that reads and returns a UINTN
> value.
> > +
> > +  @return The value read.
> > +**/
> > +typedef
> > +UINTN
> > +(EFIAPI *UNIT_TEST_HOST_BASE_LIB_READ_UINTN)(
> > +  VOID
> > +  );
> > +
> > +/**
> > +  Prototype of service that writes and returns a
> UINT16 value.
> > +
> > +  @param[in]  Value  The value to write.
> > +
> > +  @return The value written.
> > +**/
> > +typedef
> > +VOID
> > +(EFIAPI *UNIT_TEST_HOST_BASE_LIB_WRITE_UINT16)(
> > +  IN UINT16  Value
> > +  );
> > +
> > +/**
> > +  Prototype of service that writes and returns a
> UINTN value.
> > +
> > +  @param[in]  Value  The value to write.
> > +
> > +  @return The value written.
> > +**/
> > +typedef
> > +UINTN
> > +(EFIAPI *UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN)(
> > +  IN UINTN  Value
> > +  );
> > +
> > +/**
> > +  Prototype of service that reads and returns an
> IA32_DESCRIPTOR.
> > +
> > +  @param[out]  Ia32Descriptor  Pointer to the
> descriptor read.
> > +**/
> > +typedef
> > +VOID
> > +(EFIAPI
> *UNIT_TEST_HOST_BASE_LIB_ASM_READ_IA32_DESCRIPTOR)(
> > +  OUT IA32_DESCRIPTOR           *Ia32Descriptor
> > +  );
> > +
> > +/**
> > +  Prototype of service that writes an
> IA32_DESCRIPTOR.
> > +
> > +  @param[in]  Ia32Descriptor  Pointer to the
> descriptor to write.
> > +**/
> > +typedef
> > +VOID
> > +(EFIAPI
> *UNIT_TEST_HOST_BASE_LIB_ASM_WRITE_IA32_DESCRIPTOR)(
> > +  IN CONST IA32_DESCRIPTOR     *Ia32Descriptor
> > +  );
> > +
> > +/**
> > +  Retrieves CPUID information.
> > +
> > +  Executes the CPUID instruction with EAX set to the
> value specified by Index.
> > +  This function always returns Index.
> > +  If Eax is not NULL, then the value of EAX after
> CPUID is returned in Eax.
> > +  If Ebx is not NULL, then the value of EBX after
> CPUID is returned in Ebx.
> > +  If Ecx is not NULL, then the value of ECX after
> CPUID is returned in Ecx.
> > +  If Edx is not NULL, then the value of EDX after
> CPUID is returned in Edx.
> > +  This function is only available on IA-32 and x64.
> > +
> > +  @param  Index The 32-bit value to load into EAX
> prior to invoking the CPUID
> > +                instruction.
> > +  @param  Eax   The pointer to the 32-bit EAX value
> returned by the CPUID
> > +                instruction. This is an optional
> parameter that may be NULL.
> > +  @param  Ebx   The pointer to the 32-bit EBX value
> returned by the CPUID
> > +                instruction. This is an optional
> parameter that may be NULL.
> > +  @param  Ecx   The pointer to the 32-bit ECX value
> returned by the CPUID
> > +                instruction. This is an optional
> parameter that may be NULL.
> > +  @param  Edx   The pointer to the 32-bit EDX value
> returned by the CPUID
> > +                instruction. This is an optional
> parameter that may be NULL.
> > +
> > +  @return Index.
> > +
> > +**/
> > +typedef
> > +UINT32
> > +(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_CPUID)(
> > +  IN      UINT32                    Index,
> > +  OUT     UINT32                    *Eax,  OPTIONAL
> > +  OUT     UINT32                    *Ebx,  OPTIONAL
> > +  OUT     UINT32                    *Ecx,  OPTIONAL
> > +  OUT     UINT32                    *Edx   OPTIONAL
> > +  );
> > +
> > +/**
> > +  Retrieves CPUID information using an extended leaf
> identifier.
> > +
> > +  Executes the CPUID instruction with EAX set to the
> value specified by Index
> > +  and ECX set to the value specified by SubIndex.
> This function always returns
> > +  Index. This function is only available on IA-32 and
> x64.
> > +
> > +  If Eax is not NULL, then the value of EAX after
> CPUID is returned in Eax.
> > +  If Ebx is not NULL, then the value of EBX after
> CPUID is returned in Ebx.
> > +  If Ecx is not NULL, then the value of ECX after
> CPUID is returned in Ecx.
> > +  If Edx is not NULL, then the value of EDX after
> CPUID is returned in Edx.
> > +
> > +  @param  Index     The 32-bit value to load into EAX
> prior to invoking the
> > +                    CPUID instruction.
> > +  @param  SubIndex  The 32-bit value to load into ECX
> prior to invoking the
> > +                    CPUID instruction.
> > +  @param  Eax       The pointer to the 32-bit EAX
> value returned by the CPUID
> > +                    instruction. This is an optional
> parameter that may be
> > +                    NULL.
> > +  @param  Ebx       The pointer to the 32-bit EBX
> value returned by the CPUID
> > +                    instruction. This is an optional
> parameter that may be
> > +                    NULL.
> > +  @param  Ecx       The pointer to the 32-bit ECX
> value returned by the CPUID
> > +                    instruction. This is an optional
> parameter that may be
> > +                    NULL.
> > +  @param  Edx       The pointer to the 32-bit EDX
> value returned by the CPUID
> > +                    instruction. This is an optional
> parameter that may be
> > +                    NULL.
> > +
> > +  @return Index.
> > +
> > +**/
> > +typedef
> > +UINT32
> > +(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_CPUID_EX)(
> > +  IN      UINT32                    Index,
> > +  IN      UINT32                    SubIndex,
> > +  OUT     UINT32                    *Eax,  OPTIONAL
> > +  OUT     UINT32                    *Ebx,  OPTIONAL
> > +  OUT     UINT32                    *Ecx,  OPTIONAL
> > +  OUT     UINT32                    *Edx   OPTIONAL
> > +  );
> > +
> > +/**
> > +  Returns a 64-bit Machine Specific Register(MSR).
> > +
> > +  Reads and returns the 64-bit MSR specified by
> Index. No parameter checking is
> > +  performed on Index, and some Index values may cause
> CPU exceptions. The
> > +  caller must either guarantee that Index is valid,
> or the caller must set up
> > +  exception handlers to catch the exceptions. This
> function is only available
> > +  on IA-32 and x64.
> > +
> > +  @param  Index The 32-bit MSR index to read.
> > +
> > +  @return The value of the MSR identified by Index.
> > +
> > +**/
> > +typedef
> > +UINT64
> > +(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_READ_MSR_64)(
> > +  IN      UINT32                    Index
> > +  );
> > +
> > +/**
> > +  Writes a 64-bit value to a Machine Specific
> Register(MSR), and returns the
> > +  value.
> > +
> > +  Writes the 64-bit value specified by Value to the
> MSR specified by Index. The
> > +  64-bit value written to the MSR is returned. No
> parameter checking is
> > +  performed on Index or Value, and some of these may
> cause CPU exceptions. The
> > +  caller must either guarantee that Index and Value
> are valid, or the caller
> > +  must establish proper exception handlers. This
> function is only available on
> > +  IA-32 and x64.
> > +
> > +  @param  Index The 32-bit MSR index to write.
> > +  @param  Value The 64-bit value to write to the MSR.
> > +
> > +  @return Value
> > +
> > +**/
> > +typedef
> > +UINT64
> > +(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_WRITE_MSR_64)(
> > +  IN      UINT32                    Index,
> > +  IN      UINT64                    Value
> > +  );
> > +
> > +/**
> > +  Reads the current value of a Performance Counter
> (PMC).
> > +
> > +  Reads and returns the current value of performance
> counter specified by
> > +  Index. This function is only available on IA-32 and
> x64.
> > +
> > +  @param  Index The 32-bit Performance Counter index
> to read.
> > +
> > +  @return The value of the PMC specified by Index.
> > +
> > +**/
> > +typedef
> > +UINT64
> > +(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_READ_PMC)(
> > +  IN      UINT32                    Index
> > +  );
> > +
> > +/**
> > +  Sets up a monitor buffer that is used by
> AsmMwait().
> > +
> > +  Executes a MONITOR instruction with the register
> state specified by Eax, Ecx
> > +  and Edx. Returns Eax. This function is only
> available on IA-32 and x64.
> > +
> > +  @param  Eax The value to load into EAX or RAX
> before executing the MONITOR
> > +              instruction.
> > +  @param  Ecx The value to load into ECX or RCX
> before executing the MONITOR
> > +              instruction.
> > +  @param  Edx The value to load into EDX or RDX
> before executing the MONITOR
> > +              instruction.
> > +
> > +  @return Eax
> > +
> > +**/
> > +typedef
> > +UINTN
> > +(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_MONITOR)(
> > +  IN      UINTN                     Eax,
> > +  IN      UINTN                     Ecx,
> > +  IN      UINTN                     Edx
> > +  );
> > +
> > +/**
> > +  Executes an MWAIT instruction.
> > +
> > +  Executes an MWAIT instruction with the register
> state specified by Eax and
> > +  Ecx. Returns Eax. This function is only available
> on IA-32 and x64.
> > +
> > +  @param  Eax The value to load into EAX or RAX
> before executing the MONITOR
> > +              instruction.
> > +  @param  Ecx The value to load into ECX or RCX
> before executing the MONITOR
> > +              instruction.
> > +
> > +  @return Eax
> > +
> > +**/
> > +typedef
> > +UINTN
> > +(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_MWAIT)(
> > +  IN      UINTN                     Eax,
> > +  IN      UINTN                     Ecx
> > +  );
> > +
> > +/**
> > +  Flushes a cache line from all the instruction and
> data caches within the
> > +  coherency domain of the CPU.
> > +
> > +  Flushed the cache line specified by LinearAddress,
> and returns LinearAddress.
> > +  This function is only available on IA-32 and x64.
> > +
> > +  @param  LinearAddress The address of the cache line
> to flush. If the CPU is
> > +                        in a physical addressing
> mode, then LinearAddress is a
> > +                        physical address. If the CPU
> is in a virtual
> > +                        addressing mode, then
> LinearAddress is a virtual
> > +                        address.
> > +
> > +  @return LinearAddress.
> > +**/
> > +typedef
> > +VOID *
> > +(EFIAPI
> *UNIT_TEST_HOST_BASE_LIB_ASM_FLUSH_CACHE_LINE)(
> > +  IN      VOID                      *LinearAddress
> > +  );
> > +
> > +/**
> > +  Prototype of service that enables ot disables 32-
> bit paging modes.
> > +
> > +  @param  EntryPoint  A pointer to function to call
> with the new stack after
> > +                      paging is enabled.
> > +  @param  Context1    A pointer to the context to
> pass into the EntryPoint
> > +                      function as the first parameter
> after paging is enabled.
> > +  @param  Context2    A pointer to the context to
> pass into the EntryPoint
> > +                      function as the second
> parameter after paging is enabled.
> > +  @param  NewStack    A pointer to the new stack to
> use for the EntryPoint
> > +                      function after paging is
> enabled.
> > +
> > +**/
> > +typedef
> > +VOID
> > +(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_PAGING_32)(
> > +  IN      SWITCH_STACK_ENTRY_POINT  EntryPoint,
> > +  IN      VOID                      *Context1,
> OPTIONAL
> > +  IN      VOID                      *Context2,
> OPTIONAL
> > +  IN      VOID                      *NewStack
> > +  );
> > +
> > +/**
> > +  Enables the 64-bit paging mode on the CPU.
> > +
> > +  Enables the 64-bit paging mode on the CPU. CR0,
> CR3, CR4, and the page tables
> > +  must be properly initialized prior to calling this
> service. This function
> > +  assumes the current execution mode is 32-bit
> protected mode with flat
> > +  descriptors. This function is only available on IA-
> 32. After the 64-bit
> > +  paging mode is enabled, control is transferred to
> the function specified by
> > +  EntryPoint using the new stack specified by
> NewStack and passing in the
> > +  parameters specified by Context1 and Context2.
> Context1 and Context2 are
> > +  optional and may be 0. The function EntryPoint must
> never return.
> > +
> > +  If the current execution mode is not 32-bit
> protected mode with flat
> > +  descriptors, then ASSERT().
> > +  If EntryPoint is 0, then ASSERT().
> > +  If NewStack is 0, then ASSERT().
> > +
> > +  @param  Cs          The 16-bit selector to load in
> the CS before EntryPoint
> > +                      is called. The descriptor in
> the GDT that this selector
> > +                      references must be setup for
> long mode.
> > +  @param  EntryPoint  The 64-bit virtual address of
> the function to call with
> > +                      the new stack after paging is
> enabled.
> > +  @param  Context1    The 64-bit virtual address of
> the context to pass into
> > +                      the EntryPoint function as the
> first parameter after
> > +                      paging is enabled.
> > +  @param  Context2    The 64-bit virtual address of
> the context to pass into
> > +                      the EntryPoint function as the
> second parameter after
> > +                      paging is enabled.
> > +  @param  NewStack    The 64-bit virtual address of
> the new stack to use for
> > +                      the EntryPoint function after
> paging is enabled.
> > +
> > +**/
> > +typedef
> > +VOID
> > +(EFIAPI
> *UNIT_TEST_HOST_BASE_LIB_ASM_ENABLE_PAGING_64)(
> > +  IN      UINT16                    Cs,
> > +  IN      UINT64                    EntryPoint,
> > +  IN      UINT64                    Context1,
> OPTIONAL
> > +  IN      UINT64                    Context2,
> OPTIONAL
> > +  IN      UINT64                    NewStack
> > +  );
> > +
> > +/**
> > +  Disables the 64-bit paging mode on the CPU.
> > +
> > +  Disables the 64-bit paging mode on the CPU and
> returns to 32-bit protected
> > +  mode. This function assumes the current execution
> mode is 64-paging mode.
> > +  This function is only available on x64. After the
> 64-bit paging mode is
> > +  disabled, control is transferred to the function
> specified by EntryPoint
> > +  using the new stack specified by NewStack and
> passing in the parameters
> > +  specified by Context1 and Context2. Context1 and
> Context2 are optional and
> > +  may be 0. The function EntryPoint must never
> return.
> > +
> > +  If the current execution mode is not 64-bit paged
> mode, then ASSERT().
> > +  If EntryPoint is 0, then ASSERT().
> > +  If NewStack is 0, then ASSERT().
> > +
> > +  @param  Cs          The 16-bit selector to load in
> the CS before EntryPoint
> > +                      is called. The descriptor in
> the GDT that this selector
> > +                      references must be setup for
> 32-bit protected mode.
> > +  @param  EntryPoint  The 64-bit virtual address of
> the function to call with
> > +                      the new stack after paging is
> disabled.
> > +  @param  Context1    The 64-bit virtual address of
> the context to pass into
> > +                      the EntryPoint function as the
> first parameter after
> > +                      paging is disabled.
> > +  @param  Context2    The 64-bit virtual address of
> the context to pass into
> > +                      the EntryPoint function as the
> second parameter after
> > +                      paging is disabled.
> > +  @param  NewStack    The 64-bit virtual address of
> the new stack to use for
> > +                      the EntryPoint function after
> paging is disabled.
> > +
> > +**/
> > +typedef
> > +VOID
> > +(EFIAPI
> *UNIT_TEST_HOST_BASE_LIB_ASM_DISABLE_PAGING_64)(
> > +  IN      UINT16                    Cs,
> > +  IN      UINT32                    EntryPoint,
> > +  IN      UINT32                    Context1,
> OPTIONAL
> > +  IN      UINT32                    Context2,
> OPTIONAL
> > +  IN      UINT32                    NewStack
> > +  );
> > +
> > +/**
> > +  Retrieves the properties for 16-bit thunk
> functions.
> > +
> > +  Computes the size of the buffer and stack below 1MB
> required to use the
> > +  AsmPrepareThunk16(), AsmThunk16() and
> AsmPrepareAndThunk16() functions. This
> > +  buffer size is returned in RealModeBufferSize, and
> the stack size is returned
> > +  in ExtraStackSize. If parameters are passed to the
> 16-bit real mode code,
> > +  then the actual minimum stack size is
> ExtraStackSize plus the maximum number
> > +  of bytes that need to be passed to the 16-bit real
> mode code.
> > +
> > +  If RealModeBufferSize is NULL, then ASSERT().
> > +  If ExtraStackSize is NULL, then ASSERT().
> > +
> > +  @param  RealModeBufferSize  A pointer to the size
> of the buffer below 1MB
> > +                              required to use the 16-
> bit thunk functions.
> > +  @param  ExtraStackSize      A pointer to the extra
> size of stack below 1MB
> > +                              that the 16-bit thunk
> functions require for
> > +                              temporary storage in
> the transition to and from
> > +                              16-bit real mode.
> > +
> > +**/
> > +typedef
> > +VOID
> > +(EFIAPI
> *UNIT_TEST_HOST_BASE_LIB_ASM_GET_THUNK_16_PROPERTIES)(
> > +  OUT     UINT32
> *RealModeBufferSize,
> > +  OUT     UINT32                    *ExtraStackSize
> > +  );
> > +
> > +/**
> > +  Prototype of services that operates on a
> THUNK_CONTEXT structure.
> > +
> > +  @param  ThunkContext  A pointer to the context
> structure that describes the
> > +                        16-bit real mode code to
> call.
> > +
> > +**/
> > +typedef
> > +VOID
> > +(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_THUNK_16)(
> > +  IN OUT  THUNK_CONTEXT             *ThunkContext
> > +  );
> > +
> > +/**
> > +  Patch the immediate operand of an IA32 or X64
> instruction such that the byte,
> > +  word, dword or qword operand is encoded at the end
> of the instruction's
> > +  binary representation.
> > +
> > +  This function should be used to update object code
> that was compiled with
> > +  NASM from assembly source code. Example:
> > +
> > +  NASM source code:
> > +
> > +        mov     eax, strict dword 0 ; the imm32 zero
> operand will be patched
> > +    ASM_PFX(gPatchCr3):
> > +        mov     cr3, eax
> > +
> > +  C source code:
> > +
> > +    X86_ASSEMBLY_PATCH_LABEL gPatchCr3;
> > +    PatchInstructionX86 (gPatchCr3, AsmReadCr3 (),
> 4);
> > +
> > +  @param[out] InstructionEnd  Pointer right past the
> instruction to patch. The
> > +                              immediate operand to
> patch is expected to
> > +                              comprise the trailing
> bytes of the instruction.
> > +                              If InstructionEnd is
> closer to address 0 than
> > +                              ValueSize permits, then
> ASSERT().
> > +
> > +  @param[in] PatchValue       The constant to write
> to the immediate operand.
> > +                              The caller is
> responsible for ensuring that
> > +                              PatchValue can be
> represented in the byte, word,
> > +                              dword or qword operand
> (as indicated through
> > +                              ValueSize); otherwise
> ASSERT().
> > +
> > +  @param[in] ValueSize        The size of the operand
> in bytes; must be 1, 2,
> > +                              4, or 8. ASSERT()
> otherwise.
> > +**/
> > +typedef
> > +VOID
> > +(EFIAPI
> *UNIT_TEST_HOST_BASE_LIB_ASM_PATCH_INSTRUCTION_X86)(
> > +  OUT X86_ASSEMBLY_PATCH_LABEL *InstructionEnd,
> > +  IN  UINT64                   PatchValue,
> > +  IN  UINTN                    ValueSize
> > +  );
> > +
> > +///
> > +/// Common services
> > +///
> > +typedef struct {
> > +  UNIT_TEST_HOST_BASE_LIB_VOID
> EnableInterrupts;
> > +  UNIT_TEST_HOST_BASE_LIB_VOID
> DisableInterrupts;
> > +  UNIT_TEST_HOST_BASE_LIB_VOID
> EnableDisableInterrupts;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_BOOLEAN
> GetInterruptState;
> > +} UNIT_TEST_HOST_BASE_LIB_COMMON;
> > +
> > +///
> > +/// IA32/X64 services
> > +///
> > +typedef struct {
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_CPUID
> AsmCpuid;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_CPUID_EX
> AsmCpuidEx;
> > +  UNIT_TEST_HOST_BASE_LIB_VOID
> AsmDisableCache;
> > +  UNIT_TEST_HOST_BASE_LIB_VOID
> AsmEnableCache;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_READ_MSR_64
> AsmReadMsr64;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_WRITE_MSR_64
> AsmWriteMsr64;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINTN
> AsmReadCr0;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINTN
> AsmReadCr2;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINTN
> AsmReadCr3;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINTN
> AsmReadCr4;
> > +  UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN
> AsmWriteCr0;
> > +  UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN
> AsmWriteCr2;
> > +  UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN
> AsmWriteCr3;
> > +  UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN
> AsmWriteCr4;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINTN
> AsmReadDr0;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINTN
> AsmReadDr1;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINTN
> AsmReadDr2;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINTN
> AsmReadDr3;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINTN
> AsmReadDr4;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINTN
> AsmReadDr5;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINTN
> AsmReadDr6;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINTN
> AsmReadDr7;
> > +  UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN
> AsmWriteDr0;
> > +  UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN
> AsmWriteDr1;
> > +  UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN
> AsmWriteDr2;
> > +  UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN
> AsmWriteDr3;
> > +  UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN
> AsmWriteDr4;
> > +  UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN
> AsmWriteDr5;
> > +  UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN
> AsmWriteDr6;
> > +  UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN
> AsmWriteDr7;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINT16
> AsmReadCs;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINT16
> AsmReadDs;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINT16
> AsmReadEs;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINT16
> AsmReadFs;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINT16
> AsmReadGs;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINT16
> AsmReadSs;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINT16
> AsmReadTr;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_READ_IA32_DESCRIPTOR
> AsmReadGdtr;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_WRITE_IA32_DESCRIPTOR
> AsmWriteGdtr;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_READ_IA32_DESCRIPTOR
> AsmReadIdtr;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_WRITE_IA32_DESCRIPTOR
> AsmWriteIdtr;
> > +  UNIT_TEST_HOST_BASE_LIB_READ_UINT16
> AsmReadLdtr;
> > +  UNIT_TEST_HOST_BASE_LIB_WRITE_UINT16
> AsmWriteLdtr;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_READ_PMC
> AsmReadPmc;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_MONITOR
> AsmMonitor;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_MWAIT
> AsmMwait;
> > +  UNIT_TEST_HOST_BASE_LIB_VOID
> AsmWbinvd;
> > +  UNIT_TEST_HOST_BASE_LIB_VOID
> AsmInvd;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_FLUSH_CACHE_LINE
> AsmFlushCacheLine;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_PAGING_32
> AsmEnablePaging32;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_PAGING_32
> AsmDisablePaging32;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_ENABLE_PAGING_64
> AsmEnablePaging64;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_DISABLE_PAGING_64
> AsmDisablePaging64;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_GET_THUNK_16_PROPERTIES
> AsmGetThunk16Properties;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_THUNK_16
> AsmPrepareThunk16;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_THUNK_16
> AsmThunk16;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_THUNK_16
> AsmPrepareAndThunk16;
> > +  UNIT_TEST_HOST_BASE_LIB_WRITE_UINT16
> AsmWriteTr;
> > +  UNIT_TEST_HOST_BASE_LIB_VOID
> AsmLfence;
> > +  UNIT_TEST_HOST_BASE_LIB_ASM_PATCH_INSTRUCTION_X86
> PatchInstructionX86;
> > +} UNIT_TEST_HOST_BASE_LIB_X86;
> > +
> > +///
> > +/// Data structure that contains pointers structures
> of common services and CPU
> > +/// architctuire specific services.  Support for
> additional CPU architectures
> > +/// can be added to the end of this structure.
> > +///
> > +typedef struct {
> > +  UNIT_TEST_HOST_BASE_LIB_COMMON  *Common;
> > +  UNIT_TEST_HOST_BASE_LIB_X86     *X86;
> > +} UNIT_TEST_HOST_BASE_LIB;
> > +
> > +extern UNIT_TEST_HOST_BASE_LIB  gUnitTestHostBaseLib;
> > +
> > +#endif
> > --
> > 2.21.0.windows.1


  reply	other threads:[~2020-07-09 17:06 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-09  4:05 [Patch v2 00/16] UnitTestFrameworkPkg: Enhancements and bug fixes Michael D Kinney
2020-07-09  4:05 ` [Patch v2 01/16] BaseTools/Python: Allow HOST_APPLICATION to use NULL libraries Michael D Kinney
2020-07-09 11:44   ` Bob Feng
2020-07-09 23:50   ` [edk2-devel] " Sean
2020-07-09  4:05 ` [Patch v2 02/16] MdePkg/BaseCpuLibNull: Add Null version of CpuLib for host testing Michael D Kinney
2020-07-09 23:51   ` [edk2-devel] " Sean
2020-07-09  4:05 ` [Patch v2 03/16] MdePkg/BaseCacheMaintenanceLibNull: Add Null instance " Michael D Kinney
2020-07-09  4:05 ` [Patch v2 04/16] MdePkg/BaseLib: Break out IA32/X64 GCC inline privileged functions Michael D Kinney
2020-07-09  4:05 ` [Patch v2 05/16] MdePkg/Library/BaseLib: Add BaseLib instance for host based unit tests Michael D Kinney
2020-07-09 14:13   ` Liming Gao
2020-07-09 17:05     ` Michael D Kinney [this message]
2020-07-10  7:54       ` Liming Gao
2020-07-10 16:38         ` Michael D Kinney
2020-07-09  4:05 ` [Patch v2 06/16] UnitTestFrameworkPkg: Use host libraries from MdePkg Michael D Kinney
2020-07-09  4:05 ` [Patch v2 07/16] UnitTestFrameworkPkg: Enable source level debug for host tests Michael D Kinney
2020-07-09  4:05 ` [Patch v2 08/16] UnitTestFrameworkPkg: Set host application stack size to 256KB Michael D Kinney
2020-07-09  4:05 ` [Patch v2 09/16] UnitTestFrameworkPkg: Change target mode DebugLib mapping Michael D Kinney
2020-07-09  4:05 ` [Patch v2 10/16] UnitTestFrameworkPkg/UnitTestLib: Move print log into cleanup Michael D Kinney
2020-07-09  4:05 ` [Patch v2 11/16] UnitTestFrameworkPkg/UnitTestLib: Fix target mode log messages Michael D Kinney
2020-07-09  4:05 ` [Patch v2 12/16] UnitTestFrameworkPkg/UnitTestLib: Add checks for ASSERT() Michael D Kinney
2020-07-09  4:05 ` [Patch v2 13/16] MdePkg/Include: Hook DebugLib _ASSERT() for unit tests Michael D Kinney
2020-07-09  4:05 ` [Patch v2 14/16] MdePkg/Include: Add UT_EXPECT_ASSERT_FAILURE() to UnitTestLib Michael D Kinney
2020-07-09  4:05 ` [Patch v2 15/16] MdePkg/Library/BaseStackCheckLib: Fix PCD type in INF Michael D Kinney
2020-07-09 12:45   ` Liming Gao
2020-07-09  4:05 ` [Patch v2 16/16] UnitTestFramewokPkg/SampleUnitTest: Use UT_EXPECT_ASSERT_FAILURE() Michael D Kinney

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=MN2PR11MB44617368CA63B626EF1BFF8AD2640@MN2PR11MB4461.namprd11.prod.outlook.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox