--- /dev/null
+/** @file\r
+ IA32/X64 specific Unit Test Host functions.\r
+\r
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "UnitTestHost.h"\r
+\r
+///\r
+/// Defines for mUnitTestHostBaseLibSegment indexes\r
+///\r
+#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_CS 0\r
+#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_DS 1\r
+#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_ES 2\r
+#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_FS 3\r
+#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_GS 4\r
+#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_SS 5\r
+#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_TR 6\r
+#define UNIT_TEST_HOST_BASE_LIB_SEGMENT_LDTR 7\r
+\r
+///\r
+/// Module global variables for simple system emulation of MSRs, CRx, DRx,\r
+/// GDTR, IDTR, and Segment Selectors.\r
+///\r
+STATIC UINT64 mUnitTestHostBaseLibMsr[2][0x1000];\r
+STATIC UINTN mUnitTestHostBaseLibCr[5];\r
+STATIC UINTN mUnitTestHostBaseLibDr[8];\r
+STATIC UINT16 mUnitTestHostBaseLibSegment[8];\r
+STATIC IA32_DESCRIPTOR mUnitTestHostBaseLibGdtr;\r
+STATIC IA32_DESCRIPTOR mUnitTestHostBaseLibIdtr;\r
+\r
+/**\r
+ Retrieves CPUID information.\r
+\r
+ Executes the CPUID instruction with EAX set to the value specified by Index.\r
+ This function always returns Index.\r
+ If Eax is not NULL, then the value of EAX after CPUID is returned in Eax.\r
+ If Ebx is not NULL, then the value of EBX after CPUID is returned in Ebx.\r
+ If Ecx is not NULL, then the value of ECX after CPUID is returned in Ecx.\r
+ If Edx is not NULL, then the value of EDX after CPUID is returned in Edx.\r
+ This function is only available on IA-32 and x64.\r
+\r
+ @param Index The 32-bit value to load into EAX prior to invoking the CPUID\r
+ instruction.\r
+ @param Eax The pointer to the 32-bit EAX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be NULL.\r
+ @param Ebx The pointer to the 32-bit EBX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be NULL.\r
+ @param Ecx The pointer to the 32-bit ECX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be NULL.\r
+ @param Edx The pointer to the 32-bit EDX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be NULL.\r
+\r
+ @return Index.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+UnitTestHostBaseLibAsmCpuid (\r
+ IN UINT32 Index,\r
+ OUT UINT32 *Eax, OPTIONAL\r
+ OUT UINT32 *Ebx, OPTIONAL\r
+ OUT UINT32 *Ecx, OPTIONAL\r
+ OUT UINT32 *Edx OPTIONAL\r
+ )\r
+{\r
+ if (Eax != NULL) {\r
+ *Eax = 0;\r
+ }\r
+ if (Ebx != NULL) {\r
+ *Ebx = 0;\r
+ }\r
+ if (Ecx != NULL) {\r
+ *Ecx = 0;\r
+ }\r
+ if (Edx != NULL) {\r
+ *Edx = 0;\r
+ }\r
+ return Index;\r
+}\r
+\r
+/**\r
+ Retrieves CPUID information using an extended leaf identifier.\r
+\r
+ Executes the CPUID instruction with EAX set to the value specified by Index\r
+ and ECX set to the value specified by SubIndex. This function always returns\r
+ Index. This function is only available on IA-32 and x64.\r
+\r
+ If Eax is not NULL, then the value of EAX after CPUID is returned in Eax.\r
+ If Ebx is not NULL, then the value of EBX after CPUID is returned in Ebx.\r
+ If Ecx is not NULL, then the value of ECX after CPUID is returned in Ecx.\r
+ If Edx is not NULL, then the value of EDX after CPUID is returned in Edx.\r
+\r
+ @param Index The 32-bit value to load into EAX prior to invoking the\r
+ CPUID instruction.\r
+ @param SubIndex The 32-bit value to load into ECX prior to invoking the\r
+ CPUID instruction.\r
+ @param Eax The pointer to the 32-bit EAX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be\r
+ NULL.\r
+ @param Ebx The pointer to the 32-bit EBX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be\r
+ NULL.\r
+ @param Ecx The pointer to the 32-bit ECX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be\r
+ NULL.\r
+ @param Edx The pointer to the 32-bit EDX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be\r
+ NULL.\r
+\r
+ @return Index.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+UnitTestHostBaseLibAsmCpuidEx (\r
+ IN UINT32 Index,\r
+ IN UINT32 SubIndex,\r
+ OUT UINT32 *Eax, OPTIONAL\r
+ OUT UINT32 *Ebx, OPTIONAL\r
+ OUT UINT32 *Ecx, OPTIONAL\r
+ OUT UINT32 *Edx OPTIONAL\r
+ )\r
+{\r
+ if (Eax != NULL) {\r
+ *Eax = 0;\r
+ }\r
+ if (Ebx != NULL) {\r
+ *Ebx = 0;\r
+ }\r
+ if (Ecx != NULL) {\r
+ *Ecx = 0;\r
+ }\r
+ if (Edx != NULL) {\r
+ *Edx = 0;\r
+ }\r
+ return Index;\r
+}\r
+\r
+/**\r
+ Set CD bit and clear NW bit of CR0 followed by a WBINVD.\r
+\r
+ Disables the caches by setting the CD bit of CR0 to 1, clearing the NW bit of CR0 to 0,\r
+ and executing a WBINVD instruction. This function is only available on IA-32 and x64.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmDisableCache (\r
+ VOID\r
+ )\r
+{\r
+}\r
+\r
+/**\r
+ Perform a WBINVD and clear both the CD and NW bits of CR0.\r
+\r
+ Enables the caches by executing a WBINVD instruction and then clear both the CD and NW\r
+ bits of CR0 to 0. This function is only available on IA-32 and x64.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmEnableCache (\r
+ VOID\r
+ )\r
+{\r
+}\r
+\r
+/**\r
+ Returns a 64-bit Machine Specific Register(MSR).\r
+\r
+ Reads and returns the 64-bit MSR specified by Index. No parameter checking is\r
+ performed on Index, and some Index values may cause CPU exceptions. The\r
+ caller must either guarantee that Index is valid, or the caller must set up\r
+ exception handlers to catch the exceptions. This function is only available\r
+ on IA-32 and x64.\r
+\r
+ @param Index The 32-bit MSR index to read.\r
+\r
+ @return The value of the MSR identified by Index.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadMsr64 (\r
+ IN UINT32 Index\r
+ )\r
+{\r
+ if (Index < 0x1000) {\r
+ return mUnitTestHostBaseLibMsr[0][Index];\r
+ }\r
+ if (Index >= 0xC0000000 && Index < 0xC0001000) {\r
+ return mUnitTestHostBaseLibMsr[1][Index];\r
+ }\r
+ return 0;\r
+}\r
+\r
+/**\r
+ Writes a 64-bit value to a Machine Specific Register(MSR), and returns the\r
+ value.\r
+\r
+ Writes the 64-bit value specified by Value to the MSR specified by Index. The\r
+ 64-bit value written to the MSR is returned. No parameter checking is\r
+ performed on Index or Value, and some of these may cause CPU exceptions. The\r
+ caller must either guarantee that Index and Value are valid, or the caller\r
+ must establish proper exception handlers. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @param Index The 32-bit MSR index to write.\r
+ @param Value The 64-bit value to write to the MSR.\r
+\r
+ @return Value\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteMsr64 (\r
+ IN UINT32 Index,\r
+ IN UINT64 Value\r
+ )\r
+{\r
+ if (Index < 0x1000) {\r
+ mUnitTestHostBaseLibMsr[0][Index] = Value;\r
+ }\r
+ if (Index >= 0xC0000000 && Index < 0xC0001000) {\r
+ mUnitTestHostBaseLibMsr[1][Index - 0xC00000000] = Value;\r
+ }\r
+ return Value;\r
+}\r
+\r
+/**\r
+ Reads the current value of the Control Register 0 (CR0).\r
+\r
+ Reads and returns the current value of CR0. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of the Control Register 0 (CR0).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadCr0 (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibCr[0];\r
+}\r
+\r
+/**\r
+ Reads the current value of the Control Register 2 (CR2).\r
+\r
+ Reads and returns the current value of CR2. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of the Control Register 2 (CR2).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadCr2 (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibCr[2];\r
+}\r
+\r
+/**\r
+ Reads the current value of the Control Register 3 (CR3).\r
+\r
+ Reads and returns the current value of CR3. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of the Control Register 3 (CR3).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadCr3 (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibCr[3];\r
+}\r
+\r
+/**\r
+ Reads the current value of the Control Register 4 (CR4).\r
+\r
+ Reads and returns the current value of CR4. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of the Control Register 4 (CR4).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadCr4 (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibCr[4];\r
+}\r
+\r
+/**\r
+ Writes a value to Control Register 0 (CR0).\r
+\r
+ Writes and returns a new value to CR0. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Cr0 The value to write to CR0.\r
+\r
+ @return The value written to CR0.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteCr0 (\r
+ UINTN Cr0\r
+ )\r
+{\r
+ mUnitTestHostBaseLibCr[0] = Cr0;\r
+ return Cr0;\r
+}\r
+\r
+/**\r
+ Writes a value to Control Register 2 (CR2).\r
+\r
+ Writes and returns a new value to CR2. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Cr2 The value to write to CR2.\r
+\r
+ @return The value written to CR2.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteCr2 (\r
+ UINTN Cr2\r
+ )\r
+{\r
+ mUnitTestHostBaseLibCr[2] = Cr2;\r
+ return Cr2;\r
+}\r
+\r
+/**\r
+ Writes a value to Control Register 3 (CR3).\r
+\r
+ Writes and returns a new value to CR3. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Cr3 The value to write to CR3.\r
+\r
+ @return The value written to CR3.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteCr3 (\r
+ UINTN Cr3\r
+ )\r
+{\r
+ mUnitTestHostBaseLibCr[3] = Cr3;\r
+ return Cr3;\r
+}\r
+\r
+/**\r
+ Writes a value to Control Register 4 (CR4).\r
+\r
+ Writes and returns a new value to CR4. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Cr4 The value to write to CR4.\r
+\r
+ @return The value written to CR4.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteCr4 (\r
+ UINTN Cr4\r
+ )\r
+{\r
+ mUnitTestHostBaseLibCr[4] = Cr4;\r
+ return Cr4;\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 0 (DR0).\r
+\r
+ Reads and returns the current value of DR0. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 0 (DR0).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadDr0 (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibDr[0];\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 1 (DR1).\r
+\r
+ Reads and returns the current value of DR1. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 1 (DR1).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadDr1 (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibDr[1];\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 2 (DR2).\r
+\r
+ Reads and returns the current value of DR2. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 2 (DR2).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadDr2 (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibDr[2];\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 3 (DR3).\r
+\r
+ Reads and returns the current value of DR3. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 3 (DR3).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadDr3 (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibDr[3];\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 4 (DR4).\r
+\r
+ Reads and returns the current value of DR4. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 4 (DR4).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadDr4 (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibDr[4];\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 5 (DR5).\r
+\r
+ Reads and returns the current value of DR5. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 5 (DR5).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadDr5 (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibDr[5];\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 6 (DR6).\r
+\r
+ Reads and returns the current value of DR6. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 6 (DR6).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadDr6 (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibDr[6];\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 7 (DR7).\r
+\r
+ Reads and returns the current value of DR7. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 7 (DR7).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadDr7 (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibDr[7];\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 0 (DR0).\r
+\r
+ Writes and returns a new value to DR0. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr0 The value to write to Dr0.\r
+\r
+ @return The value written to Debug Register 0 (DR0).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteDr0 (\r
+ UINTN Dr0\r
+ )\r
+{\r
+ mUnitTestHostBaseLibDr[0] = Dr0;\r
+ return Dr0;\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 1 (DR1).\r
+\r
+ Writes and returns a new value to DR1. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr1 The value to write to Dr1.\r
+\r
+ @return The value written to Debug Register 1 (DR1).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteDr1 (\r
+ UINTN Dr1\r
+ )\r
+{\r
+ mUnitTestHostBaseLibDr[1] = Dr1;\r
+ return Dr1;\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 2 (DR2).\r
+\r
+ Writes and returns a new value to DR2. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr2 The value to write to Dr2.\r
+\r
+ @return The value written to Debug Register 2 (DR2).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteDr2 (\r
+ UINTN Dr2\r
+ )\r
+{\r
+ mUnitTestHostBaseLibDr[2] = Dr2;\r
+ return Dr2;\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 3 (DR3).\r
+\r
+ Writes and returns a new value to DR3. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr3 The value to write to Dr3.\r
+\r
+ @return The value written to Debug Register 3 (DR3).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteDr3 (\r
+ UINTN Dr3\r
+ )\r
+{\r
+ mUnitTestHostBaseLibDr[3] = Dr3;\r
+ return Dr3;\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 4 (DR4).\r
+\r
+ Writes and returns a new value to DR4. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr4 The value to write to Dr4.\r
+\r
+ @return The value written to Debug Register 4 (DR4).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteDr4 (\r
+ UINTN Dr4\r
+ )\r
+{\r
+ mUnitTestHostBaseLibDr[4] = Dr4;\r
+ return Dr4;\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 5 (DR5).\r
+\r
+ Writes and returns a new value to DR5. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr5 The value to write to Dr5.\r
+\r
+ @return The value written to Debug Register 5 (DR5).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteDr5 (\r
+ UINTN Dr5\r
+ )\r
+{\r
+ mUnitTestHostBaseLibDr[5] = Dr5;\r
+ return Dr5;\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 6 (DR6).\r
+\r
+ Writes and returns a new value to DR6. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr6 The value to write to Dr6.\r
+\r
+ @return The value written to Debug Register 6 (DR6).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteDr6 (\r
+ UINTN Dr6\r
+ )\r
+{\r
+ mUnitTestHostBaseLibDr[6] = Dr6;\r
+ return Dr6;\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 7 (DR7).\r
+\r
+ Writes and returns a new value to DR7. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr7 The value to write to Dr7.\r
+\r
+ @return The value written to Debug Register 7 (DR7).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteDr7 (\r
+ UINTN Dr7\r
+ )\r
+{\r
+ mUnitTestHostBaseLibDr[7] = Dr7;\r
+ return Dr7;\r
+}\r
+\r
+/**\r
+ Reads the current value of Code Segment Register (CS).\r
+\r
+ Reads and returns the current value of CS. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @return The current value of CS.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadCs (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGMENT_CS];\r
+}\r
+\r
+/**\r
+ Reads the current value of Data Segment Register (DS).\r
+\r
+ Reads and returns the current value of DS. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @return The current value of DS.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadDs (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGMENT_DS];\r
+}\r
+\r
+/**\r
+ Reads the current value of Extra Segment Register (ES).\r
+\r
+ Reads and returns the current value of ES. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @return The current value of ES.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadEs (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGMENT_ES];\r
+}\r
+\r
+/**\r
+ Reads the current value of FS Data Segment Register (FS).\r
+\r
+ Reads and returns the current value of FS. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @return The current value of FS.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadFs (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGMENT_FS];\r
+}\r
+\r
+/**\r
+ Reads the current value of GS Data Segment Register (GS).\r
+\r
+ Reads and returns the current value of GS. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @return The current value of GS.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadGs (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGMENT_GS];\r
+}\r
+\r
+/**\r
+ Reads the current value of Stack Segment Register (SS).\r
+\r
+ Reads and returns the current value of SS. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @return The current value of SS.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadSs (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGMENT_SS];\r
+}\r
+\r
+/**\r
+ Reads the current value of Task Register (TR).\r
+\r
+ Reads and returns the current value of TR. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @return The current value of TR.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadTr (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGMENT_TR];\r
+}\r
+\r
+/**\r
+ Reads the current Global Descriptor Table Register(GDTR) descriptor.\r
+\r
+ Reads and returns the current GDTR descriptor and returns it in Gdtr. This\r
+ function is only available on IA-32 and x64.\r
+\r
+ If Gdtr is NULL, then ASSERT().\r
+\r
+ @param Gdtr The pointer to a GDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadGdtr (\r
+ OUT IA32_DESCRIPTOR *Gdtr\r
+ )\r
+{\r
+ Gdtr = &mUnitTestHostBaseLibGdtr;\r
+}\r
+\r
+/**\r
+ Writes the current Global Descriptor Table Register (GDTR) descriptor.\r
+\r
+ Writes and the current GDTR descriptor specified by Gdtr. This function is\r
+ only available on IA-32 and x64.\r
+\r
+ If Gdtr is NULL, then ASSERT().\r
+\r
+ @param Gdtr The pointer to a GDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteGdtr (\r
+ IN CONST IA32_DESCRIPTOR *Gdtr\r
+ )\r
+{\r
+ CopyMem (&mUnitTestHostBaseLibGdtr, Gdtr, sizeof (IA32_DESCRIPTOR));\r
+}\r
+\r
+/**\r
+ Reads the current Interrupt Descriptor Table Register(IDTR) descriptor.\r
+\r
+ Reads and returns the current IDTR descriptor and returns it in Idtr. This\r
+ function is only available on IA-32 and x64.\r
+\r
+ If Idtr is NULL, then ASSERT().\r
+\r
+ @param Idtr The pointer to a IDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadIdtr (\r
+ OUT IA32_DESCRIPTOR *Idtr\r
+ )\r
+{\r
+ Idtr = &mUnitTestHostBaseLibIdtr;\r
+}\r
+\r
+/**\r
+ Writes the current Interrupt Descriptor Table Register(IDTR) descriptor.\r
+\r
+ Writes the current IDTR descriptor and returns it in Idtr. This function is\r
+ only available on IA-32 and x64.\r
+\r
+ If Idtr is NULL, then ASSERT().\r
+\r
+ @param Idtr The pointer to a IDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteIdtr (\r
+ IN CONST IA32_DESCRIPTOR *Idtr\r
+ )\r
+{\r
+ CopyMem (&mUnitTestHostBaseLibIdtr, Idtr, sizeof (IA32_DESCRIPTOR));\r
+}\r
+\r
+/**\r
+ Reads the current Local Descriptor Table Register(LDTR) selector.\r
+\r
+ Reads and returns the current 16-bit LDTR descriptor value. This function is\r
+ only available on IA-32 and x64.\r
+\r
+ @return The current selector of LDT.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadLdtr (\r
+ VOID\r
+ )\r
+{\r
+ return mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGMENT_LDTR];\r
+}\r
+\r
+/**\r
+ Writes the current Local Descriptor Table Register (LDTR) selector.\r
+\r
+ Writes and the current LDTR descriptor specified by Ldtr. This function is\r
+ only available on IA-32 and x64.\r
+\r
+ @param Ldtr 16-bit LDTR selector value.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteLdtr (\r
+ IN UINT16 Ldtr\r
+ )\r
+{\r
+ mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGMENT_LDTR] = Ldtr;\r
+}\r
+\r
+/**\r
+ Reads the current value of a Performance Counter (PMC).\r
+\r
+ Reads and returns the current value of performance counter specified by\r
+ Index. This function is only available on IA-32 and x64.\r
+\r
+ @param Index The 32-bit Performance Counter index to read.\r
+\r
+ @return The value of the PMC specified by Index.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+UnitTestHostBaseLibAsmReadPmc (\r
+ IN UINT32 Index\r
+ )\r
+{\r
+ return 0;\r
+}\r
+\r
+/**\r
+ Sets up a monitor buffer that is used by AsmMwait().\r
+\r
+ Executes a MONITOR instruction with the register state specified by Eax, Ecx\r
+ and Edx. Returns Eax. This function is only available on IA-32 and x64.\r
+\r
+ @param Eax The value to load into EAX or RAX before executing the MONITOR\r
+ instruction.\r
+ @param Ecx The value to load into ECX or RCX before executing the MONITOR\r
+ instruction.\r
+ @param Edx The value to load into EDX or RDX before executing the MONITOR\r
+ instruction.\r
+\r
+ @return Eax\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmMonitor (\r
+ IN UINTN Eax,\r
+ IN UINTN Ecx,\r
+ IN UINTN Edx\r
+ )\r
+{\r
+ return Eax;\r
+}\r
+\r
+/**\r
+ Executes an MWAIT instruction.\r
+\r
+ Executes an MWAIT instruction with the register state specified by Eax and\r
+ Ecx. Returns Eax. This function is only available on IA-32 and x64.\r
+\r
+ @param Eax The value to load into EAX or RAX before executing the MONITOR\r
+ instruction.\r
+ @param Ecx The value to load into ECX or RCX before executing the MONITOR\r
+ instruction.\r
+\r
+ @return Eax\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+UnitTestHostBaseLibAsmMwait (\r
+ IN UINTN Eax,\r
+ IN UINTN Ecx\r
+ )\r
+{\r
+ return Eax;\r
+}\r
+\r
+/**\r
+ Executes a WBINVD instruction.\r
+\r
+ Executes a WBINVD instruction. This function is only available on IA-32 and\r
+ x64.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWbinvd (\r
+ VOID\r
+ )\r
+{\r
+}\r
+\r
+/**\r
+ Executes a INVD instruction.\r
+\r
+ Executes a INVD instruction. This function is only available on IA-32 and\r
+ x64.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmInvd (\r
+ VOID\r
+ )\r
+{\r
+}\r
+\r
+/**\r
+ Flushes a cache line from all the instruction and data caches within the\r
+ coherency domain of the CPU.\r
+\r
+ Flushed the cache line specified by LinearAddress, and returns LinearAddress.\r
+ This function is only available on IA-32 and x64.\r
+\r
+ @param LinearAddress The address of the cache line to flush. If the CPU is\r
+ in a physical addressing mode, then LinearAddress is a\r
+ physical address. If the CPU is in a virtual\r
+ addressing mode, then LinearAddress is a virtual\r
+ address.\r
+\r
+ @return LinearAddress.\r
+**/\r
+VOID *\r
+EFIAPI\r
+UnitTestHostBaseLibAsmFlushCacheLine (\r
+ IN VOID *LinearAddress\r
+ )\r
+{\r
+ return LinearAddress;\r
+}\r
+\r
+/**\r
+ Enables the 32-bit paging mode on the CPU.\r
+\r
+ Enables the 32-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables\r
+ must be properly initialized prior to calling this service. This function\r
+ assumes the current execution mode is 32-bit protected mode. This function is\r
+ only available on IA-32. After the 32-bit paging mode is enabled, control is\r
+ transferred to the function specified by EntryPoint using the new stack\r
+ specified by NewStack and passing in the parameters specified by Context1 and\r
+ Context2. Context1 and Context2 are optional and may be NULL. The function\r
+ EntryPoint must never return.\r
+\r
+ If the current execution mode is not 32-bit protected mode, then ASSERT().\r
+ If EntryPoint is NULL, then ASSERT().\r
+ If NewStack is NULL, then ASSERT().\r
+\r
+ There are a number of constraints that must be followed before calling this\r
+ function:\r
+ 1) Interrupts must be disabled.\r
+ 2) The caller must be in 32-bit protected mode with flat descriptors. This\r
+ means all descriptors must have a base of 0 and a limit of 4GB.\r
+ 3) CR0 and CR4 must be compatible with 32-bit protected mode with flat\r
+ descriptors.\r
+ 4) CR3 must point to valid page tables that will be used once the transition\r
+ is complete, and those page tables must guarantee that the pages for this\r
+ function and the stack are identity mapped.\r
+\r
+ @param EntryPoint A pointer to function to call with the new stack after\r
+ paging is enabled.\r
+ @param Context1 A pointer to the context to pass into the EntryPoint\r
+ function as the first parameter after paging is enabled.\r
+ @param Context2 A pointer to the context to pass into the EntryPoint\r
+ function as the second parameter after paging is enabled.\r
+ @param NewStack A pointer to the new stack to use for the EntryPoint\r
+ function after paging is enabled.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmEnablePaging32 (\r
+ IN SWITCH_STACK_ENTRY_POINT EntryPoint,\r
+ IN VOID *Context1, OPTIONAL\r
+ IN VOID *Context2, OPTIONAL\r
+ IN VOID *NewStack\r
+ )\r
+{\r
+ EntryPoint (Context1, Context2);\r
+}\r
+\r
+/**\r
+ Disables the 32-bit paging mode on the CPU.\r
+\r
+ Disables the 32-bit paging mode on the CPU and returns to 32-bit protected\r
+ mode. This function assumes the current execution mode is 32-paged protected\r
+ mode. This function is only available on IA-32. After the 32-bit paging mode\r
+ is disabled, control is transferred to the function specified by EntryPoint\r
+ using the new stack specified by NewStack and passing in the parameters\r
+ specified by Context1 and Context2. Context1 and Context2 are optional and\r
+ may be NULL. The function EntryPoint must never return.\r
+\r
+ If the current execution mode is not 32-bit paged mode, then ASSERT().\r
+ If EntryPoint is NULL, then ASSERT().\r
+ If NewStack is NULL, then ASSERT().\r
+\r
+ There are a number of constraints that must be followed before calling this\r
+ function:\r
+ 1) Interrupts must be disabled.\r
+ 2) The caller must be in 32-bit paged mode.\r
+ 3) CR0, CR3, and CR4 must be compatible with 32-bit paged mode.\r
+ 4) CR3 must point to valid page tables that guarantee that the pages for\r
+ this function and the stack are identity mapped.\r
+\r
+ @param EntryPoint A pointer to function to call with the new stack after\r
+ paging is disabled.\r
+ @param Context1 A pointer to the context to pass into the EntryPoint\r
+ function as the first parameter after paging is disabled.\r
+ @param Context2 A pointer to the context to pass into the EntryPoint\r
+ function as the second parameter after paging is\r
+ disabled.\r
+ @param NewStack A pointer to the new stack to use for the EntryPoint\r
+ function after paging is disabled.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmDisablePaging32 (\r
+ IN SWITCH_STACK_ENTRY_POINT EntryPoint,\r
+ IN VOID *Context1, OPTIONAL\r
+ IN VOID *Context2, OPTIONAL\r
+ IN VOID *NewStack\r
+ )\r
+{\r
+ EntryPoint (Context1, Context2);\r
+}\r
+\r
+/**\r
+ Enables the 64-bit paging mode on the CPU.\r
+\r
+ Enables the 64-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables\r
+ must be properly initialized prior to calling this service. This function\r
+ assumes the current execution mode is 32-bit protected mode with flat\r
+ descriptors. This function is only available on IA-32. After the 64-bit\r
+ paging mode is enabled, control is transferred to the function specified by\r
+ EntryPoint using the new stack specified by NewStack and passing in the\r
+ parameters specified by Context1 and Context2. Context1 and Context2 are\r
+ optional and may be 0. The function EntryPoint must never return.\r
+\r
+ If the current execution mode is not 32-bit protected mode with flat\r
+ descriptors, then ASSERT().\r
+ If EntryPoint is 0, then ASSERT().\r
+ If NewStack is 0, then ASSERT().\r
+\r
+ @param Cs The 16-bit selector to load in the CS before EntryPoint\r
+ is called. The descriptor in the GDT that this selector\r
+ references must be setup for long mode.\r
+ @param EntryPoint The 64-bit virtual address of the function to call with\r
+ the new stack after paging is enabled.\r
+ @param Context1 The 64-bit virtual address of the context to pass into\r
+ the EntryPoint function as the first parameter after\r
+ paging is enabled.\r
+ @param Context2 The 64-bit virtual address of the context to pass into\r
+ the EntryPoint function as the second parameter after\r
+ paging is enabled.\r
+ @param NewStack The 64-bit virtual address of the new stack to use for\r
+ the EntryPoint function after paging is enabled.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmEnablePaging64 (\r
+ IN UINT16 Cs,\r
+ IN UINT64 EntryPoint,\r
+ IN UINT64 Context1, OPTIONAL\r
+ IN UINT64 Context2, OPTIONAL\r
+ IN UINT64 NewStack\r
+ )\r
+{\r
+ SWITCH_STACK_ENTRY_POINT NewEntryPoint;\r
+\r
+ NewEntryPoint = (SWITCH_STACK_ENTRY_POINT)(UINTN)(EntryPoint);\r
+ NewEntryPoint ((VOID *)(UINTN)Context1, (VOID *)(UINTN)Context2);\r
+}\r
+\r
+/**\r
+ Disables the 64-bit paging mode on the CPU.\r
+\r
+ Disables the 64-bit paging mode on the CPU and returns to 32-bit protected\r
+ mode. This function assumes the current execution mode is 64-paging mode.\r
+ This function is only available on x64. After the 64-bit paging mode is\r
+ disabled, control is transferred to the function specified by EntryPoint\r
+ using the new stack specified by NewStack and passing in the parameters\r
+ specified by Context1 and Context2. Context1 and Context2 are optional and\r
+ may be 0. The function EntryPoint must never return.\r
+\r
+ If the current execution mode is not 64-bit paged mode, then ASSERT().\r
+ If EntryPoint is 0, then ASSERT().\r
+ If NewStack is 0, then ASSERT().\r
+\r
+ @param Cs The 16-bit selector to load in the CS before EntryPoint\r
+ is called. The descriptor in the GDT that this selector\r
+ references must be setup for 32-bit protected mode.\r
+ @param EntryPoint The 64-bit virtual address of the function to call with\r
+ the new stack after paging is disabled.\r
+ @param Context1 The 64-bit virtual address of the context to pass into\r
+ the EntryPoint function as the first parameter after\r
+ paging is disabled.\r
+ @param Context2 The 64-bit virtual address of the context to pass into\r
+ the EntryPoint function as the second parameter after\r
+ paging is disabled.\r
+ @param NewStack The 64-bit virtual address of the new stack to use for\r
+ the EntryPoint function after paging is disabled.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmDisablePaging64 (\r
+ IN UINT16 Cs,\r
+ IN UINT32 EntryPoint,\r
+ IN UINT32 Context1, OPTIONAL\r
+ IN UINT32 Context2, OPTIONAL\r
+ IN UINT32 NewStack\r
+ )\r
+{\r
+ SWITCH_STACK_ENTRY_POINT NewEntryPoint;\r
+\r
+ NewEntryPoint = (SWITCH_STACK_ENTRY_POINT)(UINTN)(EntryPoint);\r
+ NewEntryPoint ((VOID *)(UINTN)Context1, (VOID *)(UINTN)Context2);\r
+}\r
+\r
+/**\r
+ Retrieves the properties for 16-bit thunk functions.\r
+\r
+ Computes the size of the buffer and stack below 1MB required to use the\r
+ AsmPrepareThunk16(), AsmThunk16() and AsmPrepareAndThunk16() functions. This\r
+ buffer size is returned in RealModeBufferSize, and the stack size is returned\r
+ in ExtraStackSize. If parameters are passed to the 16-bit real mode code,\r
+ then the actual minimum stack size is ExtraStackSize plus the maximum number\r
+ of bytes that need to be passed to the 16-bit real mode code.\r
+\r
+ If RealModeBufferSize is NULL, then ASSERT().\r
+ If ExtraStackSize is NULL, then ASSERT().\r
+\r
+ @param RealModeBufferSize A pointer to the size of the buffer below 1MB\r
+ required to use the 16-bit thunk functions.\r
+ @param ExtraStackSize A pointer to the extra size of stack below 1MB\r
+ that the 16-bit thunk functions require for\r
+ temporary storage in the transition to and from\r
+ 16-bit real mode.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmGetThunk16Properties (\r
+ OUT UINT32 *RealModeBufferSize,\r
+ OUT UINT32 *ExtraStackSize\r
+ )\r
+{\r
+ *RealModeBufferSize = 0;\r
+ *ExtraStackSize = 0;\r
+}\r
+\r
+/**\r
+ Prepares all structures a code required to use AsmThunk16().\r
+\r
+ Prepares all structures and code required to use AsmThunk16().\r
+\r
+ This interface is limited to be used in either physical mode or virtual modes with paging enabled where the\r
+ virtual to physical mappings for ThunkContext.RealModeBuffer is mapped 1:1.\r
+\r
+ If ThunkContext is NULL, then ASSERT().\r
+\r
+ @param ThunkContext A pointer to the context structure that describes the\r
+ 16-bit real mode code to call.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmPrepareThunk16 (\r
+ IN OUT THUNK_CONTEXT *ThunkContext\r
+ )\r
+{\r
+}\r
+\r
+/**\r
+ Transfers control to a 16-bit real mode entry point and returns the results.\r
+\r
+ Transfers control to a 16-bit real mode entry point and returns the results.\r
+ AsmPrepareThunk16() must be called with ThunkContext before this function is used.\r
+ This function must be called with interrupts disabled.\r
+\r
+ The register state from the RealModeState field of ThunkContext is restored just prior\r
+ to calling the 16-bit real mode entry point. This includes the EFLAGS field of RealModeState,\r
+ which is used to set the interrupt state when a 16-bit real mode entry point is called.\r
+ Control is transferred to the 16-bit real mode entry point specified by the CS and Eip fields of RealModeState.\r
+ The stack is initialized to the SS and ESP fields of RealModeState. Any parameters passed to\r
+ the 16-bit real mode code must be populated by the caller at SS:ESP prior to calling this function.\r
+ The 16-bit real mode entry point is invoked with a 16-bit CALL FAR instruction,\r
+ so when accessing stack contents, the 16-bit real mode code must account for the 16-bit segment\r
+ and 16-bit offset of the return address that were pushed onto the stack. The 16-bit real mode entry\r
+ point must exit with a RETF instruction. The register state is captured into RealModeState immediately\r
+ after the RETF instruction is executed.\r
+\r
+ If EFLAGS specifies interrupts enabled, or any of the 16-bit real mode code enables interrupts,\r
+ or any of the 16-bit real mode code makes a SW interrupt, then the caller is responsible for making sure\r
+ the IDT at address 0 is initialized to handle any HW or SW interrupts that may occur while in 16-bit real mode.\r
+\r
+ If EFLAGS specifies interrupts enabled, or any of the 16-bit real mode code enables interrupts,\r
+ then the caller is responsible for making sure the 8259 PIC is in a state compatible with 16-bit real mode.\r
+ This includes the base vectors, the interrupt masks, and the edge/level trigger mode.\r
+\r
+ If THUNK_ATTRIBUTE_BIG_REAL_MODE is set in the ThunkAttributes field of ThunkContext, then the user code\r
+ is invoked in big real mode. Otherwise, the user code is invoked in 16-bit real mode with 64KB segment limits.\r
+\r
+ If neither THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 nor THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL are set in\r
+ ThunkAttributes, then it is assumed that the user code did not enable the A20 mask, and no attempt is made to\r
+ disable the A20 mask.\r
+\r
+ If THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 is set and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL is clear in\r
+ ThunkAttributes, then attempt to use the INT 15 service to disable the A20 mask. If this INT 15 call fails,\r
+ then attempt to disable the A20 mask by directly accessing the 8042 keyboard controller I/O ports.\r
+\r
+ If THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 is clear and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL is set in\r
+ ThunkAttributes, then attempt to disable the A20 mask by directly accessing the 8042 keyboard controller I/O ports.\r
+\r
+ If ThunkContext is NULL, then ASSERT().\r
+ If AsmPrepareThunk16() was not previously called with ThunkContext, then ASSERT().\r
+ If both THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL are set in\r
+ ThunkAttributes, then ASSERT().\r
+\r
+ This interface is limited to be used in either physical mode or virtual modes with paging enabled where the\r
+ virtual to physical mappings for ThunkContext.RealModeBuffer are mapped 1:1.\r
+\r
+ @param ThunkContext A pointer to the context structure that describes the\r
+ 16-bit real mode code to call.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmThunk16 (\r
+ IN OUT THUNK_CONTEXT *ThunkContext\r
+ )\r
+{\r
+}\r
+\r
+/**\r
+ Prepares all structures and code for a 16-bit real mode thunk, transfers\r
+ control to a 16-bit real mode entry point, and returns the results.\r
+\r
+ Prepares all structures and code for a 16-bit real mode thunk, transfers\r
+ control to a 16-bit real mode entry point, and returns the results. If the\r
+ caller only need to perform a single 16-bit real mode thunk, then this\r
+ service should be used. If the caller intends to make more than one 16-bit\r
+ real mode thunk, then it is more efficient if AsmPrepareThunk16() is called\r
+ once and AsmThunk16() can be called for each 16-bit real mode thunk.\r
+\r
+ This interface is limited to be used in either physical mode or virtual modes with paging enabled where the\r
+ virtual to physical mappings for ThunkContext.RealModeBuffer is mapped 1:1.\r
+\r
+ See AsmPrepareThunk16() and AsmThunk16() for the detailed description and ASSERT() conditions.\r
+\r
+ @param ThunkContext A pointer to the context structure that describes the\r
+ 16-bit real mode code to call.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmPrepareAndThunk16 (\r
+ IN OUT THUNK_CONTEXT *ThunkContext\r
+ )\r
+{\r
+}\r
+\r
+/**\r
+ Load given selector into TR register.\r
+\r
+ @param[in] Selector Task segment selector\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmWriteTr (\r
+ IN UINT16 Selector\r
+ )\r
+{\r
+ mUnitTestHostBaseLibSegment[UNIT_TEST_HOST_BASE_LIB_SEGMENT_TR] = Selector;\r
+}\r
+\r
+/**\r
+ Performs a serializing operation on all load-from-memory instructions that\r
+ were issued prior the AsmLfence function.\r
+\r
+ Executes a LFENCE instruction. This function is only available on IA-32 and x64.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibAsmLfence (\r
+ VOID\r
+ )\r
+{\r
+}\r
+\r
+/**\r
+ Patch the immediate operand of an IA32 or X64 instruction such that the byte,\r
+ word, dword or qword operand is encoded at the end of the instruction's\r
+ binary representation.\r
+\r
+ This function should be used to update object code that was compiled with\r
+ NASM from assembly source code. Example:\r
+\r
+ NASM source code:\r
+\r
+ mov eax, strict dword 0 ; the imm32 zero operand will be patched\r
+ ASM_PFX(gPatchCr3):\r
+ mov cr3, eax\r
+\r
+ C source code:\r
+\r
+ X86_ASSEMBLY_PATCH_LABEL gPatchCr3;\r
+ PatchInstructionX86 (gPatchCr3, AsmReadCr3 (), 4);\r
+\r
+ @param[out] InstructionEnd Pointer right past the instruction to patch. The\r
+ immediate operand to patch is expected to\r
+ comprise the trailing bytes of the instruction.\r
+ If InstructionEnd is closer to address 0 than\r
+ ValueSize permits, then ASSERT().\r
+\r
+ @param[in] PatchValue The constant to write to the immediate operand.\r
+ The caller is responsible for ensuring that\r
+ PatchValue can be represented in the byte, word,\r
+ dword or qword operand (as indicated through\r
+ ValueSize); otherwise ASSERT().\r
+\r
+ @param[in] ValueSize The size of the operand in bytes; must be 1, 2,\r
+ 4, or 8. ASSERT() otherwise.\r
+**/\r
+VOID\r
+EFIAPI\r
+UnitTestHostBaseLibPatchInstructionX86 (\r
+ OUT X86_ASSEMBLY_PATCH_LABEL *InstructionEnd,\r
+ IN UINT64 PatchValue,\r
+ IN UINTN ValueSize\r
+ )\r
+{\r
+}\r
+\r
+/**\r
+ Retrieves CPUID information.\r
+\r
+ Executes the CPUID instruction with EAX set to the value specified by Index.\r
+ This function always returns Index.\r
+ If Eax is not NULL, then the value of EAX after CPUID is returned in Eax.\r
+ If Ebx is not NULL, then the value of EBX after CPUID is returned in Ebx.\r
+ If Ecx is not NULL, then the value of ECX after CPUID is returned in Ecx.\r
+ If Edx is not NULL, then the value of EDX after CPUID is returned in Edx.\r
+ This function is only available on IA-32 and x64.\r
+\r
+ @param Index The 32-bit value to load into EAX prior to invoking the CPUID\r
+ instruction.\r
+ @param Eax The pointer to the 32-bit EAX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be NULL.\r
+ @param Ebx The pointer to the 32-bit EBX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be NULL.\r
+ @param Ecx The pointer to the 32-bit ECX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be NULL.\r
+ @param Edx The pointer to the 32-bit EDX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be NULL.\r
+\r
+ @return Index.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+AsmCpuid (\r
+ IN UINT32 Index,\r
+ OUT UINT32 *Eax, OPTIONAL\r
+ OUT UINT32 *Ebx, OPTIONAL\r
+ OUT UINT32 *Ecx, OPTIONAL\r
+ OUT UINT32 *Edx OPTIONAL\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmCpuid (Index, Eax, Ebx, Ecx, Edx);\r
+}\r
+\r
+/**\r
+ Retrieves CPUID information using an extended leaf identifier.\r
+\r
+ Executes the CPUID instruction with EAX set to the value specified by Index\r
+ and ECX set to the value specified by SubIndex. This function always returns\r
+ Index. This function is only available on IA-32 and x64.\r
+\r
+ If Eax is not NULL, then the value of EAX after CPUID is returned in Eax.\r
+ If Ebx is not NULL, then the value of EBX after CPUID is returned in Ebx.\r
+ If Ecx is not NULL, then the value of ECX after CPUID is returned in Ecx.\r
+ If Edx is not NULL, then the value of EDX after CPUID is returned in Edx.\r
+\r
+ @param Index The 32-bit value to load into EAX prior to invoking the\r
+ CPUID instruction.\r
+ @param SubIndex The 32-bit value to load into ECX prior to invoking the\r
+ CPUID instruction.\r
+ @param Eax The pointer to the 32-bit EAX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be\r
+ NULL.\r
+ @param Ebx The pointer to the 32-bit EBX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be\r
+ NULL.\r
+ @param Ecx The pointer to the 32-bit ECX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be\r
+ NULL.\r
+ @param Edx The pointer to the 32-bit EDX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be\r
+ NULL.\r
+\r
+ @return Index.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+AsmCpuidEx (\r
+ IN UINT32 Index,\r
+ IN UINT32 SubIndex,\r
+ OUT UINT32 *Eax, OPTIONAL\r
+ OUT UINT32 *Ebx, OPTIONAL\r
+ OUT UINT32 *Ecx, OPTIONAL\r
+ OUT UINT32 *Edx OPTIONAL\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmCpuidEx (Index, SubIndex, Eax, Ebx, Ecx, Edx);\r
+}\r
+\r
+/**\r
+ Set CD bit and clear NW bit of CR0 followed by a WBINVD.\r
+\r
+ Disables the caches by setting the CD bit of CR0 to 1, clearing the NW bit of CR0 to 0,\r
+ and executing a WBINVD instruction. This function is only available on IA-32 and x64.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmDisableCache (\r
+ VOID\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmDisableCache ();\r
+}\r
+\r
+/**\r
+ Perform a WBINVD and clear both the CD and NW bits of CR0.\r
+\r
+ Enables the caches by executing a WBINVD instruction and then clear both the CD and NW\r
+ bits of CR0 to 0. This function is only available on IA-32 and x64.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmEnableCache (\r
+ VOID\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmEnableCache ();\r
+}\r
+\r
+/**\r
+ Returns a 64-bit Machine Specific Register(MSR).\r
+\r
+ Reads and returns the 64-bit MSR specified by Index. No parameter checking is\r
+ performed on Index, and some Index values may cause CPU exceptions. The\r
+ caller must either guarantee that Index is valid, or the caller must set up\r
+ exception handlers to catch the exceptions. This function is only available\r
+ on IA-32 and x64.\r
+\r
+ @param Index The 32-bit MSR index to read.\r
+\r
+ @return The value of the MSR identified by Index.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+AsmReadMsr64 (\r
+ IN UINT32 Index\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadMsr64 (Index);\r
+}\r
+\r
+/**\r
+ Writes a 64-bit value to a Machine Specific Register(MSR), and returns the\r
+ value.\r
+\r
+ Writes the 64-bit value specified by Value to the MSR specified by Index. The\r
+ 64-bit value written to the MSR is returned. No parameter checking is\r
+ performed on Index or Value, and some of these may cause CPU exceptions. The\r
+ caller must either guarantee that Index and Value are valid, or the caller\r
+ must establish proper exception handlers. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @param Index The 32-bit MSR index to write.\r
+ @param Value The 64-bit value to write to the MSR.\r
+\r
+ @return Value\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+AsmWriteMsr64 (\r
+ IN UINT32 Index,\r
+ IN UINT64 Value\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmWriteMsr64 (Index, Value);\r
+}\r
+\r
+/**\r
+ Reads the current value of the Control Register 0 (CR0).\r
+\r
+ Reads and returns the current value of CR0. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of the Control Register 0 (CR0).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmReadCr0 (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadCr0 ();\r
+}\r
+\r
+/**\r
+ Reads the current value of the Control Register 2 (CR2).\r
+\r
+ Reads and returns the current value of CR2. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of the Control Register 2 (CR2).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmReadCr2 (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadCr2 ();\r
+}\r
+\r
+/**\r
+ Reads the current value of the Control Register 3 (CR3).\r
+\r
+ Reads and returns the current value of CR3. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of the Control Register 3 (CR3).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmReadCr3 (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadCr3 ();\r
+}\r
+\r
+/**\r
+ Reads the current value of the Control Register 4 (CR4).\r
+\r
+ Reads and returns the current value of CR4. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of the Control Register 4 (CR4).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmReadCr4 (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadCr4 ();\r
+}\r
+\r
+/**\r
+ Writes a value to Control Register 0 (CR0).\r
+\r
+ Writes and returns a new value to CR0. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Cr0 The value to write to CR0.\r
+\r
+ @return The value written to CR0.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmWriteCr0 (\r
+ UINTN Cr0\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmWriteCr0 (Cr0);\r
+}\r
+\r
+/**\r
+ Writes a value to Control Register 2 (CR2).\r
+\r
+ Writes and returns a new value to CR2. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Cr2 The value to write to CR2.\r
+\r
+ @return The value written to CR2.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmWriteCr2 (\r
+ UINTN Cr2\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmWriteCr2 (Cr2);\r
+}\r
+\r
+/**\r
+ Writes a value to Control Register 3 (CR3).\r
+\r
+ Writes and returns a new value to CR3. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Cr3 The value to write to CR3.\r
+\r
+ @return The value written to CR3.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmWriteCr3 (\r
+ UINTN Cr3\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmWriteCr3 (Cr3);\r
+}\r
+\r
+/**\r
+ Writes a value to Control Register 4 (CR4).\r
+\r
+ Writes and returns a new value to CR4. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Cr4 The value to write to CR4.\r
+\r
+ @return The value written to CR4.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmWriteCr4 (\r
+ UINTN Cr4\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmWriteCr4 (Cr4);\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 0 (DR0).\r
+\r
+ Reads and returns the current value of DR0. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 0 (DR0).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmReadDr0 (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadDr0 ();\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 1 (DR1).\r
+\r
+ Reads and returns the current value of DR1. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 1 (DR1).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmReadDr1 (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadDr1 ();\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 2 (DR2).\r
+\r
+ Reads and returns the current value of DR2. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 2 (DR2).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmReadDr2 (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadDr2 ();\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 3 (DR3).\r
+\r
+ Reads and returns the current value of DR3. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 3 (DR3).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmReadDr3 (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadDr3 ();\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 4 (DR4).\r
+\r
+ Reads and returns the current value of DR4. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 4 (DR4).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmReadDr4 (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadDr4 ();\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 5 (DR5).\r
+\r
+ Reads and returns the current value of DR5. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 5 (DR5).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmReadDr5 (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadDr5 ();\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 6 (DR6).\r
+\r
+ Reads and returns the current value of DR6. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 6 (DR6).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmReadDr6 (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadDr6 ();\r
+}\r
+\r
+/**\r
+ Reads the current value of Debug Register 7 (DR7).\r
+\r
+ Reads and returns the current value of DR7. This function is only available\r
+ on IA-32 and x64. This returns a 32-bit value on IA-32 and a 64-bit value on\r
+ x64.\r
+\r
+ @return The value of Debug Register 7 (DR7).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmReadDr7 (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadDr7 ();\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 0 (DR0).\r
+\r
+ Writes and returns a new value to DR0. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr0 The value to write to Dr0.\r
+\r
+ @return The value written to Debug Register 0 (DR0).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmWriteDr0 (\r
+ UINTN Dr0\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmWriteDr0 (Dr0);\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 1 (DR1).\r
+\r
+ Writes and returns a new value to DR1. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr1 The value to write to Dr1.\r
+\r
+ @return The value written to Debug Register 1 (DR1).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmWriteDr1 (\r
+ UINTN Dr1\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmWriteDr1 (Dr1);\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 2 (DR2).\r
+\r
+ Writes and returns a new value to DR2. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr2 The value to write to Dr2.\r
+\r
+ @return The value written to Debug Register 2 (DR2).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmWriteDr2 (\r
+ UINTN Dr2\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmWriteDr2 (Dr2);\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 3 (DR3).\r
+\r
+ Writes and returns a new value to DR3. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr3 The value to write to Dr3.\r
+\r
+ @return The value written to Debug Register 3 (DR3).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmWriteDr3 (\r
+ UINTN Dr3\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmWriteDr3 (Dr3);\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 4 (DR4).\r
+\r
+ Writes and returns a new value to DR4. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr4 The value to write to Dr4.\r
+\r
+ @return The value written to Debug Register 4 (DR4).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmWriteDr4 (\r
+ UINTN Dr4\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmWriteDr4 (Dr4);\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 5 (DR5).\r
+\r
+ Writes and returns a new value to DR5. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr5 The value to write to Dr5.\r
+\r
+ @return The value written to Debug Register 5 (DR5).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmWriteDr5 (\r
+ UINTN Dr5\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmWriteDr5 (Dr5);\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 6 (DR6).\r
+\r
+ Writes and returns a new value to DR6. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr6 The value to write to Dr6.\r
+\r
+ @return The value written to Debug Register 6 (DR6).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmWriteDr6 (\r
+ UINTN Dr6\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmWriteDr6 (Dr6);\r
+}\r
+\r
+/**\r
+ Writes a value to Debug Register 7 (DR7).\r
+\r
+ Writes and returns a new value to DR7. This function is only available on\r
+ IA-32 and x64. This writes a 32-bit value on IA-32 and a 64-bit value on x64.\r
+\r
+ @param Dr7 The value to write to Dr7.\r
+\r
+ @return The value written to Debug Register 7 (DR7).\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmWriteDr7 (\r
+ UINTN Dr7\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmWriteDr7 (Dr7);\r
+}\r
+\r
+/**\r
+ Reads the current value of Code Segment Register (CS).\r
+\r
+ Reads and returns the current value of CS. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @return The current value of CS.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+AsmReadCs (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadCs ();\r
+}\r
+\r
+/**\r
+ Reads the current value of Data Segment Register (DS).\r
+\r
+ Reads and returns the current value of DS. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @return The current value of DS.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+AsmReadDs (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadDs ();\r
+}\r
+\r
+/**\r
+ Reads the current value of Extra Segment Register (ES).\r
+\r
+ Reads and returns the current value of ES. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @return The current value of ES.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+AsmReadEs (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadEs ();\r
+}\r
+\r
+/**\r
+ Reads the current value of FS Data Segment Register (FS).\r
+\r
+ Reads and returns the current value of FS. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @return The current value of FS.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+AsmReadFs (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadFs ();\r
+}\r
+\r
+/**\r
+ Reads the current value of GS Data Segment Register (GS).\r
+\r
+ Reads and returns the current value of GS. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @return The current value of GS.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+AsmReadGs (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadGs ();\r
+}\r
+\r
+/**\r
+ Reads the current value of Stack Segment Register (SS).\r
+\r
+ Reads and returns the current value of SS. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @return The current value of SS.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+AsmReadSs (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadSs ();\r
+}\r
+\r
+/**\r
+ Reads the current value of Task Register (TR).\r
+\r
+ Reads and returns the current value of TR. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @return The current value of TR.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+AsmReadTr (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadTr ();\r
+}\r
+\r
+/**\r
+ Reads the current Global Descriptor Table Register(GDTR) descriptor.\r
+\r
+ Reads and returns the current GDTR descriptor and returns it in Gdtr. This\r
+ function is only available on IA-32 and x64.\r
+\r
+ If Gdtr is NULL, then ASSERT().\r
+\r
+ @param Gdtr The pointer to a GDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmReadGdtr (\r
+ OUT IA32_DESCRIPTOR *Gdtr\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmReadGdtr (Gdtr);\r
+}\r
+\r
+/**\r
+ Writes the current Global Descriptor Table Register (GDTR) descriptor.\r
+\r
+ Writes and the current GDTR descriptor specified by Gdtr. This function is\r
+ only available on IA-32 and x64.\r
+\r
+ If Gdtr is NULL, then ASSERT().\r
+\r
+ @param Gdtr The pointer to a GDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmWriteGdtr (\r
+ IN CONST IA32_DESCRIPTOR *Gdtr\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmWriteGdtr (Gdtr);\r
+}\r
+\r
+/**\r
+ Reads the current Interrupt Descriptor Table Register(IDTR) descriptor.\r
+\r
+ Reads and returns the current IDTR descriptor and returns it in Idtr. This\r
+ function is only available on IA-32 and x64.\r
+\r
+ If Idtr is NULL, then ASSERT().\r
+\r
+ @param Idtr The pointer to a IDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmReadIdtr (\r
+ OUT IA32_DESCRIPTOR *Idtr\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmReadIdtr (Idtr);\r
+}\r
+\r
+/**\r
+ Writes the current Interrupt Descriptor Table Register(IDTR) descriptor.\r
+\r
+ Writes the current IDTR descriptor and returns it in Idtr. This function is\r
+ only available on IA-32 and x64.\r
+\r
+ If Idtr is NULL, then ASSERT().\r
+\r
+ @param Idtr The pointer to a IDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmWriteIdtr (\r
+ IN CONST IA32_DESCRIPTOR *Idtr\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmWriteIdtr (Idtr);\r
+}\r
+\r
+/**\r
+ Reads the current Local Descriptor Table Register(LDTR) selector.\r
+\r
+ Reads and returns the current 16-bit LDTR descriptor value. This function is\r
+ only available on IA-32 and x64.\r
+\r
+ @return The current selector of LDT.\r
+\r
+**/\r
+UINT16\r
+EFIAPI\r
+AsmReadLdtr (\r
+ VOID\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadLdtr ();\r
+}\r
+\r
+/**\r
+ Writes the current Local Descriptor Table Register (LDTR) selector.\r
+\r
+ Writes and the current LDTR descriptor specified by Ldtr. This function is\r
+ only available on IA-32 and x64.\r
+\r
+ @param Ldtr 16-bit LDTR selector value.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmWriteLdtr (\r
+ IN UINT16 Ldtr\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmWriteLdtr (Ldtr);\r
+}\r
+\r
+/**\r
+ Reads the current value of a Performance Counter (PMC).\r
+\r
+ Reads and returns the current value of performance counter specified by\r
+ Index. This function is only available on IA-32 and x64.\r
+\r
+ @param Index The 32-bit Performance Counter index to read.\r
+\r
+ @return The value of the PMC specified by Index.\r
+\r
+**/\r
+UINT64\r
+EFIAPI\r
+AsmReadPmc (\r
+ IN UINT32 Index\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmReadPmc (Index);\r
+}\r
+\r
+/**\r
+ Sets up a monitor buffer that is used by AsmMwait().\r
+\r
+ Executes a MONITOR instruction with the register state specified by Eax, Ecx\r
+ and Edx. Returns Eax. This function is only available on IA-32 and x64.\r
+\r
+ @param Eax The value to load into EAX or RAX before executing the MONITOR\r
+ instruction.\r
+ @param Ecx The value to load into ECX or RCX before executing the MONITOR\r
+ instruction.\r
+ @param Edx The value to load into EDX or RDX before executing the MONITOR\r
+ instruction.\r
+\r
+ @return Eax\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmMonitor (\r
+ IN UINTN Eax,\r
+ IN UINTN Ecx,\r
+ IN UINTN Edx\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmMonitor (Eax, Ecx, Edx);\r
+}\r
+\r
+/**\r
+ Executes an MWAIT instruction.\r
+\r
+ Executes an MWAIT instruction with the register state specified by Eax and\r
+ Ecx. Returns Eax. This function is only available on IA-32 and x64.\r
+\r
+ @param Eax The value to load into EAX or RAX before executing the MONITOR\r
+ instruction.\r
+ @param Ecx The value to load into ECX or RCX before executing the MONITOR\r
+ instruction.\r
+\r
+ @return Eax\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+AsmMwait (\r
+ IN UINTN Eax,\r
+ IN UINTN Ecx\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmMwait (Eax, Ecx);\r
+}\r
+\r
+/**\r
+ Executes a WBINVD instruction.\r
+\r
+ Executes a WBINVD instruction. This function is only available on IA-32 and\r
+ x64.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmWbinvd (\r
+ VOID\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmWbinvd ();\r
+}\r
+\r
+/**\r
+ Executes a INVD instruction.\r
+\r
+ Executes a INVD instruction. This function is only available on IA-32 and\r
+ x64.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmInvd (\r
+ VOID\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmInvd ();\r
+}\r
+\r
+/**\r
+ Flushes a cache line from all the instruction and data caches within the\r
+ coherency domain of the CPU.\r
+\r
+ Flushed the cache line specified by LinearAddress, and returns LinearAddress.\r
+ This function is only available on IA-32 and x64.\r
+\r
+ @param LinearAddress The address of the cache line to flush. If the CPU is\r
+ in a physical addressing mode, then LinearAddress is a\r
+ physical address. If the CPU is in a virtual\r
+ addressing mode, then LinearAddress is a virtual\r
+ address.\r
+\r
+ @return LinearAddress.\r
+**/\r
+VOID *\r
+EFIAPI\r
+AsmFlushCacheLine (\r
+ IN VOID *LinearAddress\r
+ )\r
+{\r
+ return gUnitTestHostBaseLib.X86->AsmFlushCacheLine (LinearAddress);\r
+}\r
+\r
+/**\r
+ Enables the 32-bit paging mode on the CPU.\r
+\r
+ Enables the 32-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables\r
+ must be properly initialized prior to calling this service. This function\r
+ assumes the current execution mode is 32-bit protected mode. This function is\r
+ only available on IA-32. After the 32-bit paging mode is enabled, control is\r
+ transferred to the function specified by EntryPoint using the new stack\r
+ specified by NewStack and passing in the parameters specified by Context1 and\r
+ Context2. Context1 and Context2 are optional and may be NULL. The function\r
+ EntryPoint must never return.\r
+\r
+ If the current execution mode is not 32-bit protected mode, then ASSERT().\r
+ If EntryPoint is NULL, then ASSERT().\r
+ If NewStack is NULL, then ASSERT().\r
+\r
+ There are a number of constraints that must be followed before calling this\r
+ function:\r
+ 1) Interrupts must be disabled.\r
+ 2) The caller must be in 32-bit protected mode with flat descriptors. This\r
+ means all descriptors must have a base of 0 and a limit of 4GB.\r
+ 3) CR0 and CR4 must be compatible with 32-bit protected mode with flat\r
+ descriptors.\r
+ 4) CR3 must point to valid page tables that will be used once the transition\r
+ is complete, and those page tables must guarantee that the pages for this\r
+ function and the stack are identity mapped.\r
+\r
+ @param EntryPoint A pointer to function to call with the new stack after\r
+ paging is enabled.\r
+ @param Context1 A pointer to the context to pass into the EntryPoint\r
+ function as the first parameter after paging is enabled.\r
+ @param Context2 A pointer to the context to pass into the EntryPoint\r
+ function as the second parameter after paging is enabled.\r
+ @param NewStack A pointer to the new stack to use for the EntryPoint\r
+ function after paging is enabled.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmEnablePaging32 (\r
+ IN SWITCH_STACK_ENTRY_POINT EntryPoint,\r
+ IN VOID *Context1, OPTIONAL\r
+ IN VOID *Context2, OPTIONAL\r
+ IN VOID *NewStack\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmEnablePaging32 (EntryPoint, Context1, Context2, NewStack);\r
+}\r
+\r
+/**\r
+ Disables the 32-bit paging mode on the CPU.\r
+\r
+ Disables the 32-bit paging mode on the CPU and returns to 32-bit protected\r
+ mode. This function assumes the current execution mode is 32-paged protected\r
+ mode. This function is only available on IA-32. After the 32-bit paging mode\r
+ is disabled, control is transferred to the function specified by EntryPoint\r
+ using the new stack specified by NewStack and passing in the parameters\r
+ specified by Context1 and Context2. Context1 and Context2 are optional and\r
+ may be NULL. The function EntryPoint must never return.\r
+\r
+ If the current execution mode is not 32-bit paged mode, then ASSERT().\r
+ If EntryPoint is NULL, then ASSERT().\r
+ If NewStack is NULL, then ASSERT().\r
+\r
+ There are a number of constraints that must be followed before calling this\r
+ function:\r
+ 1) Interrupts must be disabled.\r
+ 2) The caller must be in 32-bit paged mode.\r
+ 3) CR0, CR3, and CR4 must be compatible with 32-bit paged mode.\r
+ 4) CR3 must point to valid page tables that guarantee that the pages for\r
+ this function and the stack are identity mapped.\r
+\r
+ @param EntryPoint A pointer to function to call with the new stack after\r
+ paging is disabled.\r
+ @param Context1 A pointer to the context to pass into the EntryPoint\r
+ function as the first parameter after paging is disabled.\r
+ @param Context2 A pointer to the context to pass into the EntryPoint\r
+ function as the second parameter after paging is\r
+ disabled.\r
+ @param NewStack A pointer to the new stack to use for the EntryPoint\r
+ function after paging is disabled.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmDisablePaging32 (\r
+ IN SWITCH_STACK_ENTRY_POINT EntryPoint,\r
+ IN VOID *Context1, OPTIONAL\r
+ IN VOID *Context2, OPTIONAL\r
+ IN VOID *NewStack\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmDisablePaging32 (EntryPoint, Context1, Context2, NewStack);\r
+}\r
+\r
+/**\r
+ Enables the 64-bit paging mode on the CPU.\r
+\r
+ Enables the 64-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables\r
+ must be properly initialized prior to calling this service. This function\r
+ assumes the current execution mode is 32-bit protected mode with flat\r
+ descriptors. This function is only available on IA-32. After the 64-bit\r
+ paging mode is enabled, control is transferred to the function specified by\r
+ EntryPoint using the new stack specified by NewStack and passing in the\r
+ parameters specified by Context1 and Context2. Context1 and Context2 are\r
+ optional and may be 0. The function EntryPoint must never return.\r
+\r
+ If the current execution mode is not 32-bit protected mode with flat\r
+ descriptors, then ASSERT().\r
+ If EntryPoint is 0, then ASSERT().\r
+ If NewStack is 0, then ASSERT().\r
+\r
+ @param Cs The 16-bit selector to load in the CS before EntryPoint\r
+ is called. The descriptor in the GDT that this selector\r
+ references must be setup for long mode.\r
+ @param EntryPoint The 64-bit virtual address of the function to call with\r
+ the new stack after paging is enabled.\r
+ @param Context1 The 64-bit virtual address of the context to pass into\r
+ the EntryPoint function as the first parameter after\r
+ paging is enabled.\r
+ @param Context2 The 64-bit virtual address of the context to pass into\r
+ the EntryPoint function as the second parameter after\r
+ paging is enabled.\r
+ @param NewStack The 64-bit virtual address of the new stack to use for\r
+ the EntryPoint function after paging is enabled.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmEnablePaging64 (\r
+ IN UINT16 Cs,\r
+ IN UINT64 EntryPoint,\r
+ IN UINT64 Context1, OPTIONAL\r
+ IN UINT64 Context2, OPTIONAL\r
+ IN UINT64 NewStack\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmEnablePaging64 (Cs, EntryPoint, Context1, Context2, NewStack);\r
+}\r
+\r
+/**\r
+ Disables the 64-bit paging mode on the CPU.\r
+\r
+ Disables the 64-bit paging mode on the CPU and returns to 32-bit protected\r
+ mode. This function assumes the current execution mode is 64-paging mode.\r
+ This function is only available on x64. After the 64-bit paging mode is\r
+ disabled, control is transferred to the function specified by EntryPoint\r
+ using the new stack specified by NewStack and passing in the parameters\r
+ specified by Context1 and Context2. Context1 and Context2 are optional and\r
+ may be 0. The function EntryPoint must never return.\r
+\r
+ If the current execution mode is not 64-bit paged mode, then ASSERT().\r
+ If EntryPoint is 0, then ASSERT().\r
+ If NewStack is 0, then ASSERT().\r
+\r
+ @param Cs The 16-bit selector to load in the CS before EntryPoint\r
+ is called. The descriptor in the GDT that this selector\r
+ references must be setup for 32-bit protected mode.\r
+ @param EntryPoint The 64-bit virtual address of the function to call with\r
+ the new stack after paging is disabled.\r
+ @param Context1 The 64-bit virtual address of the context to pass into\r
+ the EntryPoint function as the first parameter after\r
+ paging is disabled.\r
+ @param Context2 The 64-bit virtual address of the context to pass into\r
+ the EntryPoint function as the second parameter after\r
+ paging is disabled.\r
+ @param NewStack The 64-bit virtual address of the new stack to use for\r
+ the EntryPoint function after paging is disabled.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmDisablePaging64 (\r
+ IN UINT16 Cs,\r
+ IN UINT32 EntryPoint,\r
+ IN UINT32 Context1, OPTIONAL\r
+ IN UINT32 Context2, OPTIONAL\r
+ IN UINT32 NewStack\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmDisablePaging64 (Cs, EntryPoint, Context1, Context2, NewStack);\r
+}\r
+\r
+/**\r
+ Retrieves the properties for 16-bit thunk functions.\r
+\r
+ Computes the size of the buffer and stack below 1MB required to use the\r
+ AsmPrepareThunk16(), AsmThunk16() and AsmPrepareAndThunk16() functions. This\r
+ buffer size is returned in RealModeBufferSize, and the stack size is returned\r
+ in ExtraStackSize. If parameters are passed to the 16-bit real mode code,\r
+ then the actual minimum stack size is ExtraStackSize plus the maximum number\r
+ of bytes that need to be passed to the 16-bit real mode code.\r
+\r
+ If RealModeBufferSize is NULL, then ASSERT().\r
+ If ExtraStackSize is NULL, then ASSERT().\r
+\r
+ @param RealModeBufferSize A pointer to the size of the buffer below 1MB\r
+ required to use the 16-bit thunk functions.\r
+ @param ExtraStackSize A pointer to the extra size of stack below 1MB\r
+ that the 16-bit thunk functions require for\r
+ temporary storage in the transition to and from\r
+ 16-bit real mode.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmGetThunk16Properties (\r
+ OUT UINT32 *RealModeBufferSize,\r
+ OUT UINT32 *ExtraStackSize\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmGetThunk16Properties (RealModeBufferSize, ExtraStackSize);\r
+}\r
+\r
+/**\r
+ Prepares all structures a code required to use AsmThunk16().\r
+\r
+ Prepares all structures and code required to use AsmThunk16().\r
+\r
+ This interface is limited to be used in either physical mode or virtual modes with paging enabled where the\r
+ virtual to physical mappings for ThunkContext.RealModeBuffer is mapped 1:1.\r
+\r
+ If ThunkContext is NULL, then ASSERT().\r
+\r
+ @param ThunkContext A pointer to the context structure that describes the\r
+ 16-bit real mode code to call.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmPrepareThunk16 (\r
+ IN OUT THUNK_CONTEXT *ThunkContext\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmPrepareThunk16 (ThunkContext);\r
+}\r
+\r
+/**\r
+ Transfers control to a 16-bit real mode entry point and returns the results.\r
+\r
+ Transfers control to a 16-bit real mode entry point and returns the results.\r
+ AsmPrepareThunk16() must be called with ThunkContext before this function is used.\r
+ This function must be called with interrupts disabled.\r
+\r
+ The register state from the RealModeState field of ThunkContext is restored just prior\r
+ to calling the 16-bit real mode entry point. This includes the EFLAGS field of RealModeState,\r
+ which is used to set the interrupt state when a 16-bit real mode entry point is called.\r
+ Control is transferred to the 16-bit real mode entry point specified by the CS and Eip fields of RealModeState.\r
+ The stack is initialized to the SS and ESP fields of RealModeState. Any parameters passed to\r
+ the 16-bit real mode code must be populated by the caller at SS:ESP prior to calling this function.\r
+ The 16-bit real mode entry point is invoked with a 16-bit CALL FAR instruction,\r
+ so when accessing stack contents, the 16-bit real mode code must account for the 16-bit segment\r
+ and 16-bit offset of the return address that were pushed onto the stack. The 16-bit real mode entry\r
+ point must exit with a RETF instruction. The register state is captured into RealModeState immediately\r
+ after the RETF instruction is executed.\r
+\r
+ If EFLAGS specifies interrupts enabled, or any of the 16-bit real mode code enables interrupts,\r
+ or any of the 16-bit real mode code makes a SW interrupt, then the caller is responsible for making sure\r
+ the IDT at address 0 is initialized to handle any HW or SW interrupts that may occur while in 16-bit real mode.\r
+\r
+ If EFLAGS specifies interrupts enabled, or any of the 16-bit real mode code enables interrupts,\r
+ then the caller is responsible for making sure the 8259 PIC is in a state compatible with 16-bit real mode.\r
+ This includes the base vectors, the interrupt masks, and the edge/level trigger mode.\r
+\r
+ If THUNK_ATTRIBUTE_BIG_REAL_MODE is set in the ThunkAttributes field of ThunkContext, then the user code\r
+ is invoked in big real mode. Otherwise, the user code is invoked in 16-bit real mode with 64KB segment limits.\r
+\r
+ If neither THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 nor THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL are set in\r
+ ThunkAttributes, then it is assumed that the user code did not enable the A20 mask, and no attempt is made to\r
+ disable the A20 mask.\r
+\r
+ If THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 is set and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL is clear in\r
+ ThunkAttributes, then attempt to use the INT 15 service to disable the A20 mask. If this INT 15 call fails,\r
+ then attempt to disable the A20 mask by directly accessing the 8042 keyboard controller I/O ports.\r
+\r
+ If THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 is clear and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL is set in\r
+ ThunkAttributes, then attempt to disable the A20 mask by directly accessing the 8042 keyboard controller I/O ports.\r
+\r
+ If ThunkContext is NULL, then ASSERT().\r
+ If AsmPrepareThunk16() was not previously called with ThunkContext, then ASSERT().\r
+ If both THUNK_ATTRIBUTE_DISABLE_A20_MASK_INT_15 and THUNK_ATTRIBUTE_DISABLE_A20_MASK_KBD_CTRL are set in\r
+ ThunkAttributes, then ASSERT().\r
+\r
+ This interface is limited to be used in either physical mode or virtual modes with paging enabled where the\r
+ virtual to physical mappings for ThunkContext.RealModeBuffer are mapped 1:1.\r
+\r
+ @param ThunkContext A pointer to the context structure that describes the\r
+ 16-bit real mode code to call.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmThunk16 (\r
+ IN OUT THUNK_CONTEXT *ThunkContext\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmThunk16 (ThunkContext);\r
+}\r
+\r
+/**\r
+ Prepares all structures and code for a 16-bit real mode thunk, transfers\r
+ control to a 16-bit real mode entry point, and returns the results.\r
+\r
+ Prepares all structures and code for a 16-bit real mode thunk, transfers\r
+ control to a 16-bit real mode entry point, and returns the results. If the\r
+ caller only need to perform a single 16-bit real mode thunk, then this\r
+ service should be used. If the caller intends to make more than one 16-bit\r
+ real mode thunk, then it is more efficient if AsmPrepareThunk16() is called\r
+ once and AsmThunk16() can be called for each 16-bit real mode thunk.\r
+\r
+ This interface is limited to be used in either physical mode or virtual modes with paging enabled where the\r
+ virtual to physical mappings for ThunkContext.RealModeBuffer is mapped 1:1.\r
+\r
+ See AsmPrepareThunk16() and AsmThunk16() for the detailed description and ASSERT() conditions.\r
+\r
+ @param ThunkContext A pointer to the context structure that describes the\r
+ 16-bit real mode code to call.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmPrepareAndThunk16 (\r
+ IN OUT THUNK_CONTEXT *ThunkContext\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmPrepareAndThunk16 (ThunkContext);\r
+}\r
+\r
+/**\r
+ Load given selector into TR register.\r
+\r
+ @param[in] Selector Task segment selector\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmWriteTr (\r
+ IN UINT16 Selector\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmWriteTr (Selector);\r
+}\r
+\r
+/**\r
+ Performs a serializing operation on all load-from-memory instructions that\r
+ were issued prior the AsmLfence function.\r
+\r
+ Executes a LFENCE instruction. This function is only available on IA-32 and x64.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+AsmLfence (\r
+ VOID\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->AsmLfence ();\r
+}\r
+\r
+/**\r
+ Patch the immediate operand of an IA32 or X64 instruction such that the byte,\r
+ word, dword or qword operand is encoded at the end of the instruction's\r
+ binary representation.\r
+\r
+ This function should be used to update object code that was compiled with\r
+ NASM from assembly source code. Example:\r
+\r
+ NASM source code:\r
+\r
+ mov eax, strict dword 0 ; the imm32 zero operand will be patched\r
+ ASM_PFX(gPatchCr3):\r
+ mov cr3, eax\r
+\r
+ C source code:\r
+\r
+ X86_ASSEMBLY_PATCH_LABEL gPatchCr3;\r
+ PatchInstructionX86 (gPatchCr3, AsmReadCr3 (), 4);\r
+\r
+ @param[out] InstructionEnd Pointer right past the instruction to patch. The\r
+ immediate operand to patch is expected to\r
+ comprise the trailing bytes of the instruction.\r
+ If InstructionEnd is closer to address 0 than\r
+ ValueSize permits, then ASSERT().\r
+\r
+ @param[in] PatchValue The constant to write to the immediate operand.\r
+ The caller is responsible for ensuring that\r
+ PatchValue can be represented in the byte, word,\r
+ dword or qword operand (as indicated through\r
+ ValueSize); otherwise ASSERT().\r
+\r
+ @param[in] ValueSize The size of the operand in bytes; must be 1, 2,\r
+ 4, or 8. ASSERT() otherwise.\r
+**/\r
+VOID\r
+EFIAPI\r
+PatchInstructionX86 (\r
+ OUT X86_ASSEMBLY_PATCH_LABEL *InstructionEnd,\r
+ IN UINT64 PatchValue,\r
+ IN UINTN ValueSize\r
+ )\r
+{\r
+ gUnitTestHostBaseLib.X86->PatchInstructionX86 (InstructionEnd, PatchValue, ValueSize);\r
+}\r
+\r
+///\r
+/// Common services\r
+///\r
+STATIC UNIT_TEST_HOST_BASE_LIB_COMMON mUnitTestHostBaseLibCommon = {\r
+ UnitTestHostBaseLibEnableInterrupts,\r
+ UnitTestHostBaseLibDisableInterrupts,\r
+ UnitTestHostBaseLibEnableDisableInterrupts,\r
+ UnitTestHostBaseLibGetInterruptState,\r
+};\r
+\r
+///\r
+/// IA32/X64 services\r
+///\r
+STATIC UNIT_TEST_HOST_BASE_LIB_X86 mUnitTestHostBaseLibX86 = {\r
+ UnitTestHostBaseLibAsmCpuid,\r
+ UnitTestHostBaseLibAsmCpuidEx,\r
+ UnitTestHostBaseLibAsmDisableCache,\r
+ UnitTestHostBaseLibAsmEnableCache,\r
+ UnitTestHostBaseLibAsmReadMsr64,\r
+ UnitTestHostBaseLibAsmWriteMsr64,\r
+ UnitTestHostBaseLibAsmReadCr0,\r
+ UnitTestHostBaseLibAsmReadCr2,\r
+ UnitTestHostBaseLibAsmReadCr3,\r
+ UnitTestHostBaseLibAsmReadCr4,\r
+ UnitTestHostBaseLibAsmWriteCr0,\r
+ UnitTestHostBaseLibAsmWriteCr2,\r
+ UnitTestHostBaseLibAsmWriteCr3,\r
+ UnitTestHostBaseLibAsmWriteCr4,\r
+ UnitTestHostBaseLibAsmReadDr0,\r
+ UnitTestHostBaseLibAsmReadDr1,\r
+ UnitTestHostBaseLibAsmReadDr2,\r
+ UnitTestHostBaseLibAsmReadDr3,\r
+ UnitTestHostBaseLibAsmReadDr4,\r
+ UnitTestHostBaseLibAsmReadDr5,\r
+ UnitTestHostBaseLibAsmReadDr6,\r
+ UnitTestHostBaseLibAsmReadDr7,\r
+ UnitTestHostBaseLibAsmWriteDr0,\r
+ UnitTestHostBaseLibAsmWriteDr1,\r
+ UnitTestHostBaseLibAsmWriteDr2,\r
+ UnitTestHostBaseLibAsmWriteDr3,\r
+ UnitTestHostBaseLibAsmWriteDr4,\r
+ UnitTestHostBaseLibAsmWriteDr5,\r
+ UnitTestHostBaseLibAsmWriteDr6,\r
+ UnitTestHostBaseLibAsmWriteDr7,\r
+ UnitTestHostBaseLibAsmReadCs,\r
+ UnitTestHostBaseLibAsmReadDs,\r
+ UnitTestHostBaseLibAsmReadEs,\r
+ UnitTestHostBaseLibAsmReadFs,\r
+ UnitTestHostBaseLibAsmReadGs,\r
+ UnitTestHostBaseLibAsmReadSs,\r
+ UnitTestHostBaseLibAsmReadTr,\r
+ UnitTestHostBaseLibAsmReadGdtr,\r
+ UnitTestHostBaseLibAsmWriteGdtr,\r
+ UnitTestHostBaseLibAsmReadIdtr,\r
+ UnitTestHostBaseLibAsmWriteIdtr,\r
+ UnitTestHostBaseLibAsmReadLdtr,\r
+ UnitTestHostBaseLibAsmWriteLdtr,\r
+ UnitTestHostBaseLibAsmReadPmc,\r
+ UnitTestHostBaseLibAsmMonitor,\r
+ UnitTestHostBaseLibAsmMwait,\r
+ UnitTestHostBaseLibAsmWbinvd,\r
+ UnitTestHostBaseLibAsmInvd,\r
+ UnitTestHostBaseLibAsmFlushCacheLine,\r
+ UnitTestHostBaseLibAsmEnablePaging32,\r
+ UnitTestHostBaseLibAsmDisablePaging32,\r
+ UnitTestHostBaseLibAsmEnablePaging64,\r
+ UnitTestHostBaseLibAsmDisablePaging64,\r
+ UnitTestHostBaseLibAsmGetThunk16Properties,\r
+ UnitTestHostBaseLibAsmPrepareThunk16,\r
+ UnitTestHostBaseLibAsmThunk16,\r
+ UnitTestHostBaseLibAsmPrepareAndThunk16,\r
+ UnitTestHostBaseLibAsmWriteTr,\r
+ UnitTestHostBaseLibAsmLfence,\r
+ UnitTestHostBaseLibPatchInstructionX86\r
+};\r
+\r
+///\r
+/// Structure of hook functions for BaseLib functions that can not be used from\r
+/// a host application. A simple emulation of these function is provided by\r
+/// default. A specific unit test can provide its own implementation for any\r
+/// of these functions.\r
+///\r
+UNIT_TEST_HOST_BASE_LIB gUnitTestHostBaseLib = {\r
+ &mUnitTestHostBaseLibCommon,\r
+ &mUnitTestHostBaseLibX86\r
+};\r
--- /dev/null
+/** @file\r
+ Unit Test Host BaseLib hooks.\r
+\r
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef __UNIT_TEST_HOST_BASE_LIB_H__\r
+#define __UNIT_TEST_HOST_BASE_LIB_H__\r
+\r
+/**\r
+ Prototype of service with no parameters and no return value.\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_VOID)(\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Prototype of service that reads and returns a BOOLEAN value.\r
+\r
+ @return The value read.\r
+**/\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_READ_BOOLEAN)(\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Prototype of service that reads and returns a UINT16 value.\r
+\r
+ @return The value read.\r
+**/\r
+typedef\r
+UINT16\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_READ_UINT16)(\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Prototype of service that reads and returns a UINTN value.\r
+\r
+ @return The value read.\r
+**/\r
+typedef\r
+UINTN\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_READ_UINTN)(\r
+ VOID\r
+ );\r
+\r
+/**\r
+ Prototype of service that writes and returns a UINT16 value.\r
+\r
+ @param[in] Value The value to write.\r
+\r
+ @return The value written.\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_WRITE_UINT16)(\r
+ IN UINT16 Value\r
+ );\r
+\r
+/**\r
+ Prototype of service that writes and returns a UINTN value.\r
+\r
+ @param[in] Value The value to write.\r
+\r
+ @return The value written.\r
+**/\r
+typedef\r
+UINTN\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN)(\r
+ IN UINTN Value\r
+ );\r
+\r
+/**\r
+ Prototype of service that reads and returns an IA32_DESCRIPTOR.\r
+\r
+ @param[out] Ia32Descriptor Pointer to the descriptor read.\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_READ_IA32_DESCRIPTOR)(\r
+ OUT IA32_DESCRIPTOR *Ia32Descriptor\r
+ );\r
+\r
+/**\r
+ Prototype of service that writes an IA32_DESCRIPTOR.\r
+\r
+ @param[in] Ia32Descriptor Pointer to the descriptor to write.\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_WRITE_IA32_DESCRIPTOR)(\r
+ IN CONST IA32_DESCRIPTOR *Ia32Descriptor\r
+ );\r
+\r
+/**\r
+ Retrieves CPUID information.\r
+\r
+ Executes the CPUID instruction with EAX set to the value specified by Index.\r
+ This function always returns Index.\r
+ If Eax is not NULL, then the value of EAX after CPUID is returned in Eax.\r
+ If Ebx is not NULL, then the value of EBX after CPUID is returned in Ebx.\r
+ If Ecx is not NULL, then the value of ECX after CPUID is returned in Ecx.\r
+ If Edx is not NULL, then the value of EDX after CPUID is returned in Edx.\r
+ This function is only available on IA-32 and x64.\r
+\r
+ @param Index The 32-bit value to load into EAX prior to invoking the CPUID\r
+ instruction.\r
+ @param Eax The pointer to the 32-bit EAX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be NULL.\r
+ @param Ebx The pointer to the 32-bit EBX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be NULL.\r
+ @param Ecx The pointer to the 32-bit ECX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be NULL.\r
+ @param Edx The pointer to the 32-bit EDX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be NULL.\r
+\r
+ @return Index.\r
+\r
+**/\r
+typedef\r
+UINT32\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_CPUID)(\r
+ IN UINT32 Index,\r
+ OUT UINT32 *Eax, OPTIONAL\r
+ OUT UINT32 *Ebx, OPTIONAL\r
+ OUT UINT32 *Ecx, OPTIONAL\r
+ OUT UINT32 *Edx OPTIONAL\r
+ );\r
+\r
+/**\r
+ Retrieves CPUID information using an extended leaf identifier.\r
+\r
+ Executes the CPUID instruction with EAX set to the value specified by Index\r
+ and ECX set to the value specified by SubIndex. This function always returns\r
+ Index. This function is only available on IA-32 and x64.\r
+\r
+ If Eax is not NULL, then the value of EAX after CPUID is returned in Eax.\r
+ If Ebx is not NULL, then the value of EBX after CPUID is returned in Ebx.\r
+ If Ecx is not NULL, then the value of ECX after CPUID is returned in Ecx.\r
+ If Edx is not NULL, then the value of EDX after CPUID is returned in Edx.\r
+\r
+ @param Index The 32-bit value to load into EAX prior to invoking the\r
+ CPUID instruction.\r
+ @param SubIndex The 32-bit value to load into ECX prior to invoking the\r
+ CPUID instruction.\r
+ @param Eax The pointer to the 32-bit EAX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be\r
+ NULL.\r
+ @param Ebx The pointer to the 32-bit EBX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be\r
+ NULL.\r
+ @param Ecx The pointer to the 32-bit ECX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be\r
+ NULL.\r
+ @param Edx The pointer to the 32-bit EDX value returned by the CPUID\r
+ instruction. This is an optional parameter that may be\r
+ NULL.\r
+\r
+ @return Index.\r
+\r
+**/\r
+typedef\r
+UINT32\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_CPUID_EX)(\r
+ IN UINT32 Index,\r
+ IN UINT32 SubIndex,\r
+ OUT UINT32 *Eax, OPTIONAL\r
+ OUT UINT32 *Ebx, OPTIONAL\r
+ OUT UINT32 *Ecx, OPTIONAL\r
+ OUT UINT32 *Edx OPTIONAL\r
+ );\r
+\r
+/**\r
+ Returns a 64-bit Machine Specific Register(MSR).\r
+\r
+ Reads and returns the 64-bit MSR specified by Index. No parameter checking is\r
+ performed on Index, and some Index values may cause CPU exceptions. The\r
+ caller must either guarantee that Index is valid, or the caller must set up\r
+ exception handlers to catch the exceptions. This function is only available\r
+ on IA-32 and x64.\r
+\r
+ @param Index The 32-bit MSR index to read.\r
+\r
+ @return The value of the MSR identified by Index.\r
+\r
+**/\r
+typedef\r
+UINT64\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_READ_MSR_64)(\r
+ IN UINT32 Index\r
+ );\r
+\r
+/**\r
+ Writes a 64-bit value to a Machine Specific Register(MSR), and returns the\r
+ value.\r
+\r
+ Writes the 64-bit value specified by Value to the MSR specified by Index. The\r
+ 64-bit value written to the MSR is returned. No parameter checking is\r
+ performed on Index or Value, and some of these may cause CPU exceptions. The\r
+ caller must either guarantee that Index and Value are valid, or the caller\r
+ must establish proper exception handlers. This function is only available on\r
+ IA-32 and x64.\r
+\r
+ @param Index The 32-bit MSR index to write.\r
+ @param Value The 64-bit value to write to the MSR.\r
+\r
+ @return Value\r
+\r
+**/\r
+typedef\r
+UINT64\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_WRITE_MSR_64)(\r
+ IN UINT32 Index,\r
+ IN UINT64 Value\r
+ );\r
+\r
+/**\r
+ Reads the current value of a Performance Counter (PMC).\r
+\r
+ Reads and returns the current value of performance counter specified by\r
+ Index. This function is only available on IA-32 and x64.\r
+\r
+ @param Index The 32-bit Performance Counter index to read.\r
+\r
+ @return The value of the PMC specified by Index.\r
+\r
+**/\r
+typedef\r
+UINT64\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_READ_PMC)(\r
+ IN UINT32 Index\r
+ );\r
+\r
+/**\r
+ Sets up a monitor buffer that is used by AsmMwait().\r
+\r
+ Executes a MONITOR instruction with the register state specified by Eax, Ecx\r
+ and Edx. Returns Eax. This function is only available on IA-32 and x64.\r
+\r
+ @param Eax The value to load into EAX or RAX before executing the MONITOR\r
+ instruction.\r
+ @param Ecx The value to load into ECX or RCX before executing the MONITOR\r
+ instruction.\r
+ @param Edx The value to load into EDX or RDX before executing the MONITOR\r
+ instruction.\r
+\r
+ @return Eax\r
+\r
+**/\r
+typedef\r
+UINTN\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_MONITOR)(\r
+ IN UINTN Eax,\r
+ IN UINTN Ecx,\r
+ IN UINTN Edx\r
+ );\r
+\r
+/**\r
+ Executes an MWAIT instruction.\r
+\r
+ Executes an MWAIT instruction with the register state specified by Eax and\r
+ Ecx. Returns Eax. This function is only available on IA-32 and x64.\r
+\r
+ @param Eax The value to load into EAX or RAX before executing the MONITOR\r
+ instruction.\r
+ @param Ecx The value to load into ECX or RCX before executing the MONITOR\r
+ instruction.\r
+\r
+ @return Eax\r
+\r
+**/\r
+typedef\r
+UINTN\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_MWAIT)(\r
+ IN UINTN Eax,\r
+ IN UINTN Ecx\r
+ );\r
+\r
+/**\r
+ Flushes a cache line from all the instruction and data caches within the\r
+ coherency domain of the CPU.\r
+\r
+ Flushed the cache line specified by LinearAddress, and returns LinearAddress.\r
+ This function is only available on IA-32 and x64.\r
+\r
+ @param LinearAddress The address of the cache line to flush. If the CPU is\r
+ in a physical addressing mode, then LinearAddress is a\r
+ physical address. If the CPU is in a virtual\r
+ addressing mode, then LinearAddress is a virtual\r
+ address.\r
+\r
+ @return LinearAddress.\r
+**/\r
+typedef\r
+VOID *\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_FLUSH_CACHE_LINE)(\r
+ IN VOID *LinearAddress\r
+ );\r
+\r
+/**\r
+ Prototype of service that enables ot disables 32-bit paging modes.\r
+\r
+ @param EntryPoint A pointer to function to call with the new stack after\r
+ paging is enabled.\r
+ @param Context1 A pointer to the context to pass into the EntryPoint\r
+ function as the first parameter after paging is enabled.\r
+ @param Context2 A pointer to the context to pass into the EntryPoint\r
+ function as the second parameter after paging is enabled.\r
+ @param NewStack A pointer to the new stack to use for the EntryPoint\r
+ function after paging is enabled.\r
+\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_PAGING_32)(\r
+ IN SWITCH_STACK_ENTRY_POINT EntryPoint,\r
+ IN VOID *Context1, OPTIONAL\r
+ IN VOID *Context2, OPTIONAL\r
+ IN VOID *NewStack\r
+ );\r
+\r
+/**\r
+ Enables the 64-bit paging mode on the CPU.\r
+\r
+ Enables the 64-bit paging mode on the CPU. CR0, CR3, CR4, and the page tables\r
+ must be properly initialized prior to calling this service. This function\r
+ assumes the current execution mode is 32-bit protected mode with flat\r
+ descriptors. This function is only available on IA-32. After the 64-bit\r
+ paging mode is enabled, control is transferred to the function specified by\r
+ EntryPoint using the new stack specified by NewStack and passing in the\r
+ parameters specified by Context1 and Context2. Context1 and Context2 are\r
+ optional and may be 0. The function EntryPoint must never return.\r
+\r
+ If the current execution mode is not 32-bit protected mode with flat\r
+ descriptors, then ASSERT().\r
+ If EntryPoint is 0, then ASSERT().\r
+ If NewStack is 0, then ASSERT().\r
+\r
+ @param Cs The 16-bit selector to load in the CS before EntryPoint\r
+ is called. The descriptor in the GDT that this selector\r
+ references must be setup for long mode.\r
+ @param EntryPoint The 64-bit virtual address of the function to call with\r
+ the new stack after paging is enabled.\r
+ @param Context1 The 64-bit virtual address of the context to pass into\r
+ the EntryPoint function as the first parameter after\r
+ paging is enabled.\r
+ @param Context2 The 64-bit virtual address of the context to pass into\r
+ the EntryPoint function as the second parameter after\r
+ paging is enabled.\r
+ @param NewStack The 64-bit virtual address of the new stack to use for\r
+ the EntryPoint function after paging is enabled.\r
+\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_ENABLE_PAGING_64)(\r
+ IN UINT16 Cs,\r
+ IN UINT64 EntryPoint,\r
+ IN UINT64 Context1, OPTIONAL\r
+ IN UINT64 Context2, OPTIONAL\r
+ IN UINT64 NewStack\r
+ );\r
+\r
+/**\r
+ Disables the 64-bit paging mode on the CPU.\r
+\r
+ Disables the 64-bit paging mode on the CPU and returns to 32-bit protected\r
+ mode. This function assumes the current execution mode is 64-paging mode.\r
+ This function is only available on x64. After the 64-bit paging mode is\r
+ disabled, control is transferred to the function specified by EntryPoint\r
+ using the new stack specified by NewStack and passing in the parameters\r
+ specified by Context1 and Context2. Context1 and Context2 are optional and\r
+ may be 0. The function EntryPoint must never return.\r
+\r
+ If the current execution mode is not 64-bit paged mode, then ASSERT().\r
+ If EntryPoint is 0, then ASSERT().\r
+ If NewStack is 0, then ASSERT().\r
+\r
+ @param Cs The 16-bit selector to load in the CS before EntryPoint\r
+ is called. The descriptor in the GDT that this selector\r
+ references must be setup for 32-bit protected mode.\r
+ @param EntryPoint The 64-bit virtual address of the function to call with\r
+ the new stack after paging is disabled.\r
+ @param Context1 The 64-bit virtual address of the context to pass into\r
+ the EntryPoint function as the first parameter after\r
+ paging is disabled.\r
+ @param Context2 The 64-bit virtual address of the context to pass into\r
+ the EntryPoint function as the second parameter after\r
+ paging is disabled.\r
+ @param NewStack The 64-bit virtual address of the new stack to use for\r
+ the EntryPoint function after paging is disabled.\r
+\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_DISABLE_PAGING_64)(\r
+ IN UINT16 Cs,\r
+ IN UINT32 EntryPoint,\r
+ IN UINT32 Context1, OPTIONAL\r
+ IN UINT32 Context2, OPTIONAL\r
+ IN UINT32 NewStack\r
+ );\r
+\r
+/**\r
+ Retrieves the properties for 16-bit thunk functions.\r
+\r
+ Computes the size of the buffer and stack below 1MB required to use the\r
+ AsmPrepareThunk16(), AsmThunk16() and AsmPrepareAndThunk16() functions. This\r
+ buffer size is returned in RealModeBufferSize, and the stack size is returned\r
+ in ExtraStackSize. If parameters are passed to the 16-bit real mode code,\r
+ then the actual minimum stack size is ExtraStackSize plus the maximum number\r
+ of bytes that need to be passed to the 16-bit real mode code.\r
+\r
+ If RealModeBufferSize is NULL, then ASSERT().\r
+ If ExtraStackSize is NULL, then ASSERT().\r
+\r
+ @param RealModeBufferSize A pointer to the size of the buffer below 1MB\r
+ required to use the 16-bit thunk functions.\r
+ @param ExtraStackSize A pointer to the extra size of stack below 1MB\r
+ that the 16-bit thunk functions require for\r
+ temporary storage in the transition to and from\r
+ 16-bit real mode.\r
+\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_GET_THUNK_16_PROPERTIES)(\r
+ OUT UINT32 *RealModeBufferSize,\r
+ OUT UINT32 *ExtraStackSize\r
+ );\r
+\r
+/**\r
+ Prototype of services that operates on a THUNK_CONTEXT structure.\r
+\r
+ @param ThunkContext A pointer to the context structure that describes the\r
+ 16-bit real mode code to call.\r
+\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_THUNK_16)(\r
+ IN OUT THUNK_CONTEXT *ThunkContext\r
+ );\r
+\r
+/**\r
+ Patch the immediate operand of an IA32 or X64 instruction such that the byte,\r
+ word, dword or qword operand is encoded at the end of the instruction's\r
+ binary representation.\r
+\r
+ This function should be used to update object code that was compiled with\r
+ NASM from assembly source code. Example:\r
+\r
+ NASM source code:\r
+\r
+ mov eax, strict dword 0 ; the imm32 zero operand will be patched\r
+ ASM_PFX(gPatchCr3):\r
+ mov cr3, eax\r
+\r
+ C source code:\r
+\r
+ X86_ASSEMBLY_PATCH_LABEL gPatchCr3;\r
+ PatchInstructionX86 (gPatchCr3, AsmReadCr3 (), 4);\r
+\r
+ @param[out] InstructionEnd Pointer right past the instruction to patch. The\r
+ immediate operand to patch is expected to\r
+ comprise the trailing bytes of the instruction.\r
+ If InstructionEnd is closer to address 0 than\r
+ ValueSize permits, then ASSERT().\r
+\r
+ @param[in] PatchValue The constant to write to the immediate operand.\r
+ The caller is responsible for ensuring that\r
+ PatchValue can be represented in the byte, word,\r
+ dword or qword operand (as indicated through\r
+ ValueSize); otherwise ASSERT().\r
+\r
+ @param[in] ValueSize The size of the operand in bytes; must be 1, 2,\r
+ 4, or 8. ASSERT() otherwise.\r
+**/\r
+typedef\r
+VOID\r
+(EFIAPI *UNIT_TEST_HOST_BASE_LIB_ASM_PATCH_INSTRUCTION_X86)(\r
+ OUT X86_ASSEMBLY_PATCH_LABEL *InstructionEnd,\r
+ IN UINT64 PatchValue,\r
+ IN UINTN ValueSize\r
+ );\r
+\r
+///\r
+/// Common services\r
+///\r
+typedef struct {\r
+ UNIT_TEST_HOST_BASE_LIB_VOID EnableInterrupts;\r
+ UNIT_TEST_HOST_BASE_LIB_VOID DisableInterrupts;\r
+ UNIT_TEST_HOST_BASE_LIB_VOID EnableDisableInterrupts;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_BOOLEAN GetInterruptState;\r
+} UNIT_TEST_HOST_BASE_LIB_COMMON;\r
+\r
+///\r
+/// IA32/X64 services\r
+///\r
+typedef struct {\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_CPUID AsmCpuid;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_CPUID_EX AsmCpuidEx;\r
+ UNIT_TEST_HOST_BASE_LIB_VOID AsmDisableCache;\r
+ UNIT_TEST_HOST_BASE_LIB_VOID AsmEnableCache;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_READ_MSR_64 AsmReadMsr64;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_WRITE_MSR_64 AsmWriteMsr64;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINTN AsmReadCr0;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINTN AsmReadCr2;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINTN AsmReadCr3;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINTN AsmReadCr4;\r
+ UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN AsmWriteCr0;\r
+ UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN AsmWriteCr2;\r
+ UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN AsmWriteCr3;\r
+ UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN AsmWriteCr4;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINTN AsmReadDr0;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINTN AsmReadDr1;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINTN AsmReadDr2;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINTN AsmReadDr3;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINTN AsmReadDr4;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINTN AsmReadDr5;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINTN AsmReadDr6;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINTN AsmReadDr7;\r
+ UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN AsmWriteDr0;\r
+ UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN AsmWriteDr1;\r
+ UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN AsmWriteDr2;\r
+ UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN AsmWriteDr3;\r
+ UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN AsmWriteDr4;\r
+ UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN AsmWriteDr5;\r
+ UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN AsmWriteDr6;\r
+ UNIT_TEST_HOST_BASE_LIB_WRITE_UINTN AsmWriteDr7;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINT16 AsmReadCs;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINT16 AsmReadDs;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINT16 AsmReadEs;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINT16 AsmReadFs;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINT16 AsmReadGs;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINT16 AsmReadSs;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINT16 AsmReadTr;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_READ_IA32_DESCRIPTOR AsmReadGdtr;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_WRITE_IA32_DESCRIPTOR AsmWriteGdtr;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_READ_IA32_DESCRIPTOR AsmReadIdtr;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_WRITE_IA32_DESCRIPTOR AsmWriteIdtr;\r
+ UNIT_TEST_HOST_BASE_LIB_READ_UINT16 AsmReadLdtr;\r
+ UNIT_TEST_HOST_BASE_LIB_WRITE_UINT16 AsmWriteLdtr;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_READ_PMC AsmReadPmc;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_MONITOR AsmMonitor;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_MWAIT AsmMwait;\r
+ UNIT_TEST_HOST_BASE_LIB_VOID AsmWbinvd;\r
+ UNIT_TEST_HOST_BASE_LIB_VOID AsmInvd;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_FLUSH_CACHE_LINE AsmFlushCacheLine;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_PAGING_32 AsmEnablePaging32;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_PAGING_32 AsmDisablePaging32;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_ENABLE_PAGING_64 AsmEnablePaging64;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_DISABLE_PAGING_64 AsmDisablePaging64;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_GET_THUNK_16_PROPERTIES AsmGetThunk16Properties;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_THUNK_16 AsmPrepareThunk16;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_THUNK_16 AsmThunk16;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_THUNK_16 AsmPrepareAndThunk16;\r
+ UNIT_TEST_HOST_BASE_LIB_WRITE_UINT16 AsmWriteTr;\r
+ UNIT_TEST_HOST_BASE_LIB_VOID AsmLfence;\r
+ UNIT_TEST_HOST_BASE_LIB_ASM_PATCH_INSTRUCTION_X86 PatchInstructionX86;\r
+} UNIT_TEST_HOST_BASE_LIB_X86;\r
+\r
+///\r
+/// Data structure that contains pointers structures of common services and CPU\r
+/// architctuire specific services. Support for additional CPU architectures\r
+/// can be added to the end of this structure.\r
+///\r
+typedef struct {\r
+ UNIT_TEST_HOST_BASE_LIB_COMMON *Common;\r
+ UNIT_TEST_HOST_BASE_LIB_X86 *X86;\r
+} UNIT_TEST_HOST_BASE_LIB;\r
+\r
+extern UNIT_TEST_HOST_BASE_LIB gUnitTestHostBaseLib;\r
+\r
+#endif\r