## @file\r
# Base Library implementation.\r
#\r
-# Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>\r
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
# Portions copyright (c) 2011 - 2013, ARM Ltd. All rights reserved.<BR>\r
# Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>\r
\r
\r
Ia32/GccInline.c | GCC\r
+ Ia32/GccInlinePriv.c | GCC\r
Ia32/Thunk16.nasm\r
Ia32/EnableDisableInterrupts.nasm| GCC\r
Ia32/EnablePaging64.nasm\r
X86PatchInstruction.c\r
X86SpeculationBarrier.c\r
X64/GccInline.c | GCC\r
+ X64/GccInlinePriv.c | GCC\r
X64/EnableDisableInterrupts.nasm\r
X64/DisablePaging64.nasm\r
X64/RdRand.nasm\r
/** @file\r
GCC inline implementation of BaseLib processor specific functions.\r
\r
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>\r
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
\r
#include "BaseLibInternals.h"\r
\r
-\r
-\r
-/**\r
- Used to serialize load and store operations.\r
-\r
- All loads and stores that proceed calls to this function are guaranteed to be\r
- globally visible when this function returns.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-MemoryFence (\r
- VOID\r
- )\r
-{\r
- // This is a little bit of overkill and it is more about the compiler that it is\r
- // actually processor synchronization. This is like the _ReadWriteBarrier\r
- // Microsoft specific intrinsic\r
- __asm__ __volatile__ ("":::"memory");\r
-}\r
-\r
-\r
-/**\r
- Enables CPU interrupts.\r
-\r
- Enables CPU interrupts.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-EnableInterrupts (\r
- VOID\r
- )\r
-{\r
- __asm__ __volatile__ ("sti"::: "memory");\r
-}\r
-\r
-\r
-/**\r
- Disables CPU interrupts.\r
-\r
- Disables CPU interrupts.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-DisableInterrupts (\r
- VOID\r
- )\r
-{\r
- __asm__ __volatile__ ("cli"::: "memory");\r
-}\r
-\r
-\r
-\r
-\r
-/**\r
- Requests CPU to pause for a short period of time.\r
-\r
- Requests CPU to pause for a short period of time. Typically used in MP\r
- systems to prevent memory starvation while waiting for a spin lock.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-CpuPause (\r
- VOID\r
- )\r
-{\r
- __asm__ __volatile__ ("pause");\r
-}\r
-\r
-\r
-/**\r
- Generates a breakpoint on the CPU.\r
-\r
- Generates a breakpoint on the CPU. The breakpoint must be implemented such\r
- that code can resume normal execution after the breakpoint.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-CpuBreakpoint (\r
- VOID\r
- )\r
-{\r
- __asm__ __volatile__ ("int $3");\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
-AsmReadMsr64 (\r
- IN UINT32 Index\r
- )\r
-{\r
- UINT64 Data;\r
-\r
- __asm__ __volatile__ (\r
- "rdmsr"\r
- : "=A" (Data) // %0\r
- : "c" (Index) // %1\r
- );\r
-\r
- return Data;\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
- __asm__ __volatile__ (\r
- "wrmsr"\r
- :\r
- : "c" (Index),\r
- "A" (Value)\r
- );\r
-\r
- return Value;\r
-}\r
-\r
-\r
-\r
-/**\r
- Reads the current value of the EFLAGS register.\r
-\r
- Reads and returns the current value of the EFLAGS register. This function is\r
- only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a\r
- 64-bit value on X64.\r
-\r
- @return EFLAGS on IA-32 or RFLAGS on X64.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-AsmReadEflags (\r
- VOID\r
- )\r
-{\r
- UINTN Eflags;\r
-\r
- __asm__ __volatile__ (\r
- "pushfl \n\t"\r
- "popl %0 "\r
- : "=r" (Eflags)\r
- );\r
-\r
- return Eflags;\r
-}\r
-\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "movl %%cr0,%0"\r
- : "=a" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "movl %%cr2, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "movl %%cr3, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "movl %%cr4, %0"\r
- : "=a" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- __asm__ __volatile__ (\r
- "movl %0, %%cr0"\r
- :\r
- : "r" (Cr0)\r
- );\r
- return Cr0;\r
-}\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
- __asm__ __volatile__ (\r
- "movl %0, %%cr2"\r
- :\r
- : "r" (Cr2)\r
- );\r
- return Cr2;\r
-}\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
- __asm__ __volatile__ (\r
- "movl %0, %%cr3"\r
- :\r
- : "r" (Cr3)\r
- );\r
- return Cr3;\r
-}\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
- __asm__ __volatile__ (\r
- "movl %0, %%cr4"\r
- :\r
- : "r" (Cr4)\r
- );\r
- return Cr4;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "movl %%dr0, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "movl %%dr1, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "movl %%dr2, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "movl %%dr3, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "movl %%dr4, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "movl %%dr5, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "movl %%dr6, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "movl %%dr7, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- __asm__ __volatile__ (\r
- "movl %0, %%dr0"\r
- :\r
- : "r" (Dr0)\r
- );\r
- return Dr0;\r
-}\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
- __asm__ __volatile__ (\r
- "movl %0, %%dr1"\r
- :\r
- : "r" (Dr1)\r
- );\r
- return Dr1;\r
-}\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
- __asm__ __volatile__ (\r
- "movl %0, %%dr2"\r
- :\r
- : "r" (Dr2)\r
- );\r
- return Dr2;\r
-}\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
- __asm__ __volatile__ (\r
- "movl %0, %%dr3"\r
- :\r
- : "r" (Dr3)\r
- );\r
- return Dr3;\r
-}\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
- __asm__ __volatile__ (\r
- "movl %0, %%dr4"\r
- :\r
- : "r" (Dr4)\r
- );\r
- return Dr4;\r
-}\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
- __asm__ __volatile__ (\r
- "movl %0, %%dr5"\r
- :\r
- : "r" (Dr5)\r
- );\r
- return Dr5;\r
-}\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
- __asm__ __volatile__ (\r
- "movl %0, %%dr6"\r
- :\r
- : "r" (Dr6)\r
- );\r
- return Dr6;\r
-}\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
- __asm__ __volatile__ (\r
- "movl %0, %%dr7"\r
- :\r
- : "r" (Dr7)\r
- );\r
- return Dr7;\r
-}\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
- UINT16 Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%cs, %0"\r
- :"=a" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINT16 Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%ds, %0"\r
- :"=a" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINT16 Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%es, %0"\r
- :"=a" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINT16 Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%fs, %0"\r
- :"=a" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINT16 Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%gs, %0"\r
- :"=a" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINT16 Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%ds, %0"\r
- :"=a" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINT16 Data;\r
-\r
- __asm__ __volatile__ (\r
- "str %0"\r
- : "=a" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- @param Gdtr The pointer to a GDTR descriptor.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-InternalX86ReadGdtr (\r
- OUT IA32_DESCRIPTOR *Gdtr\r
- )\r
-{\r
- __asm__ __volatile__ (\r
- "sgdt %0"\r
- : "=m" (*Gdtr)\r
- );\r
-}\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
+ Used to serialize load and store operations.\r
\r
- @param Gdtr The pointer to a GDTR descriptor.\r
+ All loads and stores that proceed calls to this function are guaranteed to be\r
+ globally visible when this function returns.\r
\r
**/\r
VOID\r
EFIAPI\r
-InternalX86WriteGdtr (\r
- IN CONST IA32_DESCRIPTOR *Gdtr\r
+MemoryFence (\r
+ VOID\r
)\r
{\r
- __asm__ __volatile__ (\r
- "lgdt %0"\r
- :\r
- : "m" (*Gdtr)\r
- );\r
-\r
+ // This is a little bit of overkill and it is more about the compiler that it is\r
+ // actually processor synchronization. This is like the _ReadWriteBarrier\r
+ // Microsoft specific intrinsic\r
+ __asm__ __volatile__ ("":::"memory");\r
}\r
\r
-\r
/**\r
- Reads the current Interrupt Descriptor Table Register(GDTR) 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
+ Requests CPU to pause for a short period of time.\r
\r
- @param Idtr The pointer to a IDTR descriptor.\r
+ Requests CPU to pause for a short period of time. Typically used in MP\r
+ systems to prevent memory starvation while waiting for a spin lock.\r
\r
**/\r
VOID\r
EFIAPI\r
-InternalX86ReadIdtr (\r
- OUT IA32_DESCRIPTOR *Idtr\r
+CpuPause (\r
+ VOID\r
)\r
{\r
- __asm__ __volatile__ (\r
- "sidt %0"\r
- : "=m" (*Idtr)\r
- );\r
+ __asm__ __volatile__ ("pause");\r
}\r
\r
-\r
/**\r
- Writes the current Interrupt Descriptor Table Register(GDTR) 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
+ Generates a breakpoint on the CPU.\r
\r
- @param Idtr The pointer to a IDTR descriptor.\r
+ Generates a breakpoint on the CPU. The breakpoint must be implemented such\r
+ that code can resume normal execution after the breakpoint.\r
\r
**/\r
VOID\r
EFIAPI\r
-InternalX86WriteIdtr (\r
- IN CONST IA32_DESCRIPTOR *Idtr\r
+CpuBreakpoint (\r
+ VOID\r
)\r
{\r
- __asm__ __volatile__ (\r
- "lidt %0"\r
- :\r
- : "m" (*Idtr)\r
- );\r
+ __asm__ __volatile__ ("int $3");\r
}\r
\r
-\r
/**\r
- Reads the current Local Descriptor Table Register(LDTR) selector.\r
+ Reads the current value of the EFLAGS register.\r
\r
- Reads and returns the current 16-bit LDTR descriptor value. This function is\r
- only available on IA-32 and X64.\r
+ Reads and returns the current value of the EFLAGS register. This function is\r
+ only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a\r
+ 64-bit value on X64.\r
\r
- @return The current selector of LDT.\r
+ @return EFLAGS on IA-32 or RFLAGS on X64.\r
\r
**/\r
-UINT16\r
+UINTN\r
EFIAPI\r
-AsmReadLdtr (\r
+AsmReadEflags (\r
VOID\r
)\r
{\r
- UINT16 Data;\r
+ UINTN Eflags;\r
\r
__asm__ __volatile__ (\r
- "sldt %0"\r
- : "=g" (Data) // %0\r
+ "pushfl \n\t"\r
+ "popl %0 "\r
+ : "=r" (Eflags)\r
);\r
\r
- return Data;\r
-}\r
-\r
-\r
-/**\r
- Writes the current Local Descriptor Table Register (GDTR) 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
- __asm__ __volatile__ (\r
- "lldtw %0"\r
- :\r
- : "g" (Ldtr) // %0\r
- );\r
+ return Eflags;\r
}\r
\r
-\r
/**\r
Save the current floating point/SSE/SSE2 context to a buffer.\r
\r
\r
return Data;\r
}\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
- UINT64 Data;\r
-\r
- __asm__ __volatile__ (\r
- "rdpmc"\r
- : "=A" (Data)\r
- : "c" (Index)\r
- );\r
-\r
- return Data;\r
-}\r
-\r
-\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
- __asm__ __volatile__ ("wbinvd":::"memory");\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
-AsmInvd (\r
- VOID\r
- )\r
-{\r
- __asm__ __volatile__ ("invd":::"memory");\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
-AsmFlushCacheLine (\r
- IN VOID *LinearAddress\r
- )\r
-{\r
- UINT32 RegEdx;\r
-\r
- //\r
- // If the CPU does not support CLFLUSH instruction,\r
- // then promote flush range to flush entire cache.\r
- //\r
- AsmCpuid (0x01, NULL, NULL, NULL, &RegEdx);\r
- if ((RegEdx & BIT19) == 0) {\r
- __asm__ __volatile__ ("wbinvd":::"memory");\r
- return LinearAddress;\r
- }\r
-\r
-\r
- __asm__ __volatile__ (\r
- "clflush (%0)"\r
- : "+a" (LinearAddress)\r
- :\r
- : "memory"\r
- );\r
-\r
- return LinearAddress;\r
-}\r
-\r
-\r
--- /dev/null
+/** @file\r
+ GCC inline implementation of BaseLib processor specific functions that use\r
+ privlidged instructions.\r
+\r
+ Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>\r
+ Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+\r
+#include "BaseLibInternals.h"\r
+\r
+/**\r
+ Enables CPU interrupts.\r
+\r
+ Enables CPU interrupts.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EnableInterrupts (\r
+ VOID\r
+ )\r
+{\r
+ __asm__ __volatile__ ("sti"::: "memory");\r
+}\r
+\r
+\r
+/**\r
+ Disables CPU interrupts.\r
+\r
+ Disables CPU interrupts.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DisableInterrupts (\r
+ VOID\r
+ )\r
+{\r
+ __asm__ __volatile__ ("cli"::: "memory");\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
+ UINT64 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "rdmsr"\r
+ : "=A" (Data) // %0\r
+ : "c" (Index) // %1\r
+ );\r
+\r
+ return Data;\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
+ __asm__ __volatile__ (\r
+ "wrmsr"\r
+ :\r
+ : "c" (Index),\r
+ "A" (Value)\r
+ );\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
+AsmReadCr0 (\r
+ VOID\r
+ )\r
+{\r
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "movl %%cr0,%0"\r
+ : "=a" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "movl %%cr2, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "movl %%cr3, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "movl %%cr4, %0"\r
+ : "=a" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ __asm__ __volatile__ (\r
+ "movl %0, %%cr0"\r
+ :\r
+ : "r" (Cr0)\r
+ );\r
+ return Cr0;\r
+}\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
+ __asm__ __volatile__ (\r
+ "movl %0, %%cr2"\r
+ :\r
+ : "r" (Cr2)\r
+ );\r
+ return Cr2;\r
+}\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
+ __asm__ __volatile__ (\r
+ "movl %0, %%cr3"\r
+ :\r
+ : "r" (Cr3)\r
+ );\r
+ return Cr3;\r
+}\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
+ __asm__ __volatile__ (\r
+ "movl %0, %%cr4"\r
+ :\r
+ : "r" (Cr4)\r
+ );\r
+ return Cr4;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "movl %%dr0, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "movl %%dr1, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "movl %%dr2, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "movl %%dr3, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "movl %%dr4, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "movl %%dr5, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "movl %%dr6, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "movl %%dr7, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ __asm__ __volatile__ (\r
+ "movl %0, %%dr0"\r
+ :\r
+ : "r" (Dr0)\r
+ );\r
+ return Dr0;\r
+}\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
+ __asm__ __volatile__ (\r
+ "movl %0, %%dr1"\r
+ :\r
+ : "r" (Dr1)\r
+ );\r
+ return Dr1;\r
+}\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
+ __asm__ __volatile__ (\r
+ "movl %0, %%dr2"\r
+ :\r
+ : "r" (Dr2)\r
+ );\r
+ return Dr2;\r
+}\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
+ __asm__ __volatile__ (\r
+ "movl %0, %%dr3"\r
+ :\r
+ : "r" (Dr3)\r
+ );\r
+ return Dr3;\r
+}\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
+ __asm__ __volatile__ (\r
+ "movl %0, %%dr4"\r
+ :\r
+ : "r" (Dr4)\r
+ );\r
+ return Dr4;\r
+}\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
+ __asm__ __volatile__ (\r
+ "movl %0, %%dr5"\r
+ :\r
+ : "r" (Dr5)\r
+ );\r
+ return Dr5;\r
+}\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
+ __asm__ __volatile__ (\r
+ "movl %0, %%dr6"\r
+ :\r
+ : "r" (Dr6)\r
+ );\r
+ return Dr6;\r
+}\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
+ __asm__ __volatile__ (\r
+ "movl %0, %%dr7"\r
+ :\r
+ : "r" (Dr7)\r
+ );\r
+ return Dr7;\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%cs, %0"\r
+ :"=a" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%ds, %0"\r
+ :"=a" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%es, %0"\r
+ :"=a" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%fs, %0"\r
+ :"=a" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%gs, %0"\r
+ :"=a" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%ds, %0"\r
+ :"=a" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "str %0"\r
+ : "=a" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ @param Gdtr The pointer to a GDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InternalX86ReadGdtr (\r
+ OUT IA32_DESCRIPTOR *Gdtr\r
+ )\r
+{\r
+ __asm__ __volatile__ (\r
+ "sgdt %0"\r
+ : "=m" (*Gdtr)\r
+ );\r
+}\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
+ @param Gdtr The pointer to a GDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InternalX86WriteGdtr (\r
+ IN CONST IA32_DESCRIPTOR *Gdtr\r
+ )\r
+{\r
+ __asm__ __volatile__ (\r
+ "lgdt %0"\r
+ :\r
+ : "m" (*Gdtr)\r
+ );\r
+\r
+}\r
+\r
+\r
+/**\r
+ Reads the current Interrupt Descriptor Table Register(GDTR) 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
+ @param Idtr The pointer to a IDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InternalX86ReadIdtr (\r
+ OUT IA32_DESCRIPTOR *Idtr\r
+ )\r
+{\r
+ __asm__ __volatile__ (\r
+ "sidt %0"\r
+ : "=m" (*Idtr)\r
+ );\r
+}\r
+\r
+\r
+/**\r
+ Writes the current Interrupt Descriptor Table Register(GDTR) 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
+ @param Idtr The pointer to a IDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InternalX86WriteIdtr (\r
+ IN CONST IA32_DESCRIPTOR *Idtr\r
+ )\r
+{\r
+ __asm__ __volatile__ (\r
+ "lidt %0"\r
+ :\r
+ : "m" (*Idtr)\r
+ );\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "sldt %0"\r
+ : "=g" (Data) // %0\r
+ );\r
+\r
+ return Data;\r
+}\r
+\r
+\r
+/**\r
+ Writes the current Local Descriptor Table Register (GDTR) 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
+ __asm__ __volatile__ (\r
+ "lldtw %0"\r
+ :\r
+ : "g" (Ldtr) // %0\r
+ );\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
+ UINT64 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "rdpmc"\r
+ : "=A" (Data)\r
+ : "c" (Index)\r
+ );\r
+\r
+ return Data;\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
+ __asm__ __volatile__ ("wbinvd":::"memory");\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
+ __asm__ __volatile__ ("invd":::"memory");\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
+AsmFlushCacheLine (\r
+ IN VOID *LinearAddress\r
+ )\r
+{\r
+ UINT32 RegEdx;\r
+\r
+ //\r
+ // If the CPU does not support CLFLUSH instruction,\r
+ // then promote flush range to flush entire cache.\r
+ //\r
+ AsmCpuid (0x01, NULL, NULL, NULL, &RegEdx);\r
+ if ((RegEdx & BIT19) == 0) {\r
+ __asm__ __volatile__ ("wbinvd":::"memory");\r
+ return LinearAddress;\r
+ }\r
+\r
+\r
+ __asm__ __volatile__ (\r
+ "clflush (%0)"\r
+ : "+a" (LinearAddress)\r
+ :\r
+ : "memory"\r
+ );\r
+\r
+ return LinearAddress;\r
+}\r
/** @file\r
GCC inline implementation of BaseLib processor specific functions.\r
\r
- Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>\r
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
\r
\r
/**\r
- Enables CPU interrupts.\r
-\r
- Enables CPU interrupts.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-EnableInterrupts (\r
- VOID\r
- )\r
-{\r
- __asm__ __volatile__ ("sti"::: "memory");\r
-}\r
-\r
-\r
-/**\r
- Disables CPU interrupts.\r
-\r
- Disables CPU interrupts.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-DisableInterrupts (\r
- VOID\r
- )\r
-{\r
- __asm__ __volatile__ ("cli"::: "memory");\r
-}\r
-\r
-\r
-\r
-\r
-/**\r
- Requests CPU to pause for a short period of time.\r
-\r
- Requests CPU to pause for a short period of time. Typically used in MP\r
- systems to prevent memory starvation while waiting for a spin lock.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-CpuPause (\r
- VOID\r
- )\r
-{\r
- __asm__ __volatile__ ("pause");\r
-}\r
-\r
-\r
-/**\r
- Generates a breakpoint on the CPU.\r
-\r
- Generates a breakpoint on the CPU. The breakpoint must be implemented such\r
- that code can resume normal execution after the breakpoint.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-CpuBreakpoint (\r
- VOID\r
- )\r
-{\r
- __asm__ __volatile__ ("int $3");\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
-AsmReadMsr64 (\r
- IN UINT32 Index\r
- )\r
-{\r
- UINT32 LowData;\r
- UINT32 HighData;\r
-\r
- __asm__ __volatile__ (\r
- "rdmsr"\r
- : "=a" (LowData), // %0\r
- "=d" (HighData) // %1\r
- : "c" (Index) // %2\r
- );\r
-\r
- return (((UINT64)HighData) << 32) | LowData;\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
- UINT32 LowData;\r
- UINT32 HighData;\r
-\r
- LowData = (UINT32)(Value);\r
- HighData = (UINT32)(Value >> 32);\r
-\r
- __asm__ __volatile__ (\r
- "wrmsr"\r
- :\r
- : "c" (Index),\r
- "a" (LowData),\r
- "d" (HighData)\r
- );\r
-\r
- return Value;\r
-}\r
-\r
-\r
-\r
-/**\r
- Reads the current value of the EFLAGS register.\r
-\r
- Reads and returns the current value of the EFLAGS register. This function is\r
- only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a\r
- 64-bit value on X64.\r
-\r
- @return EFLAGS on IA-32 or RFLAGS on X64.\r
-\r
-**/\r
-UINTN\r
-EFIAPI\r
-AsmReadEflags (\r
- VOID\r
- )\r
-{\r
- UINTN Eflags;\r
-\r
- __asm__ __volatile__ (\r
- "pushfq \n\t"\r
- "pop %0 "\r
- : "=r" (Eflags) // %0\r
- );\r
-\r
- return Eflags;\r
-}\r
-\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%cr0,%0"\r
- : "=r" (Data) // %0\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%cr2, %0"\r
- : "=r" (Data) // %0\r
- );\r
-\r
- return Data;\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%cr3, %0"\r
- : "=r" (Data) // %0\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%cr4, %0"\r
- : "=r" (Data) // %0\r
- );\r
-\r
- return Data;\r
-}\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
- __asm__ __volatile__ (\r
- "mov %0, %%cr0"\r
- :\r
- : "r" (Cr0)\r
- );\r
- return Cr0;\r
-}\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
- __asm__ __volatile__ (\r
- "mov %0, %%cr2"\r
- :\r
- : "r" (Cr2)\r
- );\r
- return Cr2;\r
-}\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
- __asm__ __volatile__ (\r
- "mov %0, %%cr3"\r
- :\r
- : "r" (Cr3)\r
- );\r
- return Cr3;\r
-}\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
- __asm__ __volatile__ (\r
- "mov %0, %%cr4"\r
- :\r
- : "r" (Cr4)\r
- );\r
- return Cr4;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%dr0, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%dr1, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%dr2, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%dr3, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%dr4, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%dr5, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%dr6, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINTN Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%dr7, %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- __asm__ __volatile__ (\r
- "mov %0, %%dr0"\r
- :\r
- : "r" (Dr0)\r
- );\r
- return Dr0;\r
-}\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
- __asm__ __volatile__ (\r
- "mov %0, %%dr1"\r
- :\r
- : "r" (Dr1)\r
- );\r
- return Dr1;\r
-}\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
- __asm__ __volatile__ (\r
- "mov %0, %%dr2"\r
- :\r
- : "r" (Dr2)\r
- );\r
- return Dr2;\r
-}\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
- __asm__ __volatile__ (\r
- "mov %0, %%dr3"\r
- :\r
- : "r" (Dr3)\r
- );\r
- return Dr3;\r
-}\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
- __asm__ __volatile__ (\r
- "mov %0, %%dr4"\r
- :\r
- : "r" (Dr4)\r
- );\r
- return Dr4;\r
-}\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
- __asm__ __volatile__ (\r
- "mov %0, %%dr5"\r
- :\r
- : "r" (Dr5)\r
- );\r
- return Dr5;\r
-}\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
- __asm__ __volatile__ (\r
- "mov %0, %%dr6"\r
- :\r
- : "r" (Dr6)\r
- );\r
- return Dr6;\r
-}\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
- __asm__ __volatile__ (\r
- "mov %0, %%dr7"\r
- :\r
- : "r" (Dr7)\r
- );\r
- return Dr7;\r
-}\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
- UINT16 Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%cs, %0"\r
- :"=a" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINT16 Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%ds, %0"\r
- :"=a" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINT16 Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%es, %0"\r
- :"=a" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINT16 Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%fs, %0"\r
- :"=a" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINT16 Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%gs, %0"\r
- :"=a" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINT16 Data;\r
-\r
- __asm__ __volatile__ (\r
- "mov %%ds, %0"\r
- :"=a" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- UINT16 Data;\r
-\r
- __asm__ __volatile__ (\r
- "str %0"\r
- : "=r" (Data)\r
- );\r
-\r
- return Data;\r
-}\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
- @param Gdtr The pointer to a GDTR descriptor.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-InternalX86ReadGdtr (\r
- OUT IA32_DESCRIPTOR *Gdtr\r
- )\r
-{\r
- __asm__ __volatile__ (\r
- "sgdt %0"\r
- : "=m" (*Gdtr)\r
- );\r
-}\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
- @param Gdtr The pointer to a GDTR descriptor.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-InternalX86WriteGdtr (\r
- IN CONST IA32_DESCRIPTOR *Gdtr\r
- )\r
-{\r
- __asm__ __volatile__ (\r
- "lgdt %0"\r
- :\r
- : "m" (*Gdtr)\r
- );\r
-\r
-}\r
-\r
-\r
-/**\r
- Reads the current Interrupt Descriptor Table Register(GDTR) 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
+ Requests CPU to pause for a short period of time.\r
\r
- @param Idtr The pointer to a IDTR descriptor.\r
+ Requests CPU to pause for a short period of time. Typically used in MP\r
+ systems to prevent memory starvation while waiting for a spin lock.\r
\r
**/\r
VOID\r
EFIAPI\r
-InternalX86ReadIdtr (\r
- OUT IA32_DESCRIPTOR *Idtr\r
+CpuPause (\r
+ VOID\r
)\r
{\r
- __asm__ __volatile__ (\r
- "sidt %0"\r
- : "=m" (*Idtr)\r
- );\r
+ __asm__ __volatile__ ("pause");\r
}\r
\r
\r
/**\r
- Writes the current Interrupt Descriptor Table Register(GDTR) 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
+ Generates a breakpoint on the CPU.\r
\r
- @param Idtr The pointer to a IDTR descriptor.\r
+ Generates a breakpoint on the CPU. The breakpoint must be implemented such\r
+ that code can resume normal execution after the breakpoint.\r
\r
**/\r
VOID\r
EFIAPI\r
-InternalX86WriteIdtr (\r
- IN CONST IA32_DESCRIPTOR *Idtr\r
+CpuBreakpoint (\r
+ VOID\r
)\r
{\r
- __asm__ __volatile__ (\r
- "lidt %0"\r
- :\r
- : "m" (*Idtr)\r
- );\r
+ __asm__ __volatile__ ("int $3");\r
}\r
\r
\r
/**\r
- Reads the current Local Descriptor Table Register(LDTR) selector.\r
+ Reads the current value of the EFLAGS register.\r
\r
- Reads and returns the current 16-bit LDTR descriptor value. This function is\r
- only available on IA-32 and X64.\r
+ Reads and returns the current value of the EFLAGS register. This function is\r
+ only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a\r
+ 64-bit value on X64.\r
\r
- @return The current selector of LDT.\r
+ @return EFLAGS on IA-32 or RFLAGS on X64.\r
\r
**/\r
-UINT16\r
+UINTN\r
EFIAPI\r
-AsmReadLdtr (\r
+AsmReadEflags (\r
VOID\r
)\r
{\r
- UINT16 Data;\r
+ UINTN Eflags;\r
\r
__asm__ __volatile__ (\r
- "sldt %0"\r
- : "=g" (Data) // %0\r
+ "pushfq \n\t"\r
+ "pop %0 "\r
+ : "=r" (Eflags) // %0\r
);\r
\r
- return Data;\r
-}\r
-\r
-\r
-/**\r
- Writes the current Local Descriptor Table Register (GDTR) 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
- __asm__ __volatile__ (\r
- "lldtw %0"\r
- :\r
- : "g" (Ldtr) // %0\r
- );\r
+ return Eflags;\r
}\r
\r
-\r
/**\r
Save the current floating point/SSE/SSE2 context to a buffer.\r
\r
\r
return (((UINT64)HiData) << 32) | LowData;\r
}\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
- UINT32 LowData;\r
- UINT32 HiData;\r
-\r
- __asm__ __volatile__ (\r
- "rdpmc"\r
- : "=a" (LowData),\r
- "=d" (HiData)\r
- : "c" (Index)\r
- );\r
-\r
- return (((UINT64)HiData) << 32) | LowData;\r
-}\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
- __asm__ __volatile__ (\r
- "monitor"\r
- :\r
- : "a" (Eax),\r
- "c" (Ecx),\r
- "d" (Edx)\r
- );\r
-\r
- return Eax;\r
-}\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
- __asm__ __volatile__ (\r
- "mwait"\r
- :\r
- : "a" (Eax),\r
- "c" (Ecx)\r
- );\r
-\r
- return Eax;\r
-}\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
- __asm__ __volatile__ ("wbinvd":::"memory");\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
-AsmInvd (\r
- VOID\r
- )\r
-{\r
- __asm__ __volatile__ ("invd":::"memory");\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
-AsmFlushCacheLine (\r
- IN VOID *LinearAddress\r
- )\r
-{\r
- __asm__ __volatile__ (\r
- "clflush (%0)"\r
- :\r
- : "r" (LinearAddress)\r
- : "memory"\r
- );\r
-\r
- return LinearAddress;\r
-}\r
-\r
-\r
--- /dev/null
+/** @file\r
+ GCC inline implementation of BaseLib processor specific functions that use\r
+ privlidged instructions.\r
+\r
+ Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>\r
+ Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+\r
+#include "BaseLibInternals.h"\r
+\r
+/**\r
+ Enables CPU interrupts.\r
+\r
+ Enables CPU interrupts.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EnableInterrupts (\r
+ VOID\r
+ )\r
+{\r
+ __asm__ __volatile__ ("sti"::: "memory");\r
+}\r
+\r
+\r
+/**\r
+ Disables CPU interrupts.\r
+\r
+ Disables CPU interrupts.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DisableInterrupts (\r
+ VOID\r
+ )\r
+{\r
+ __asm__ __volatile__ ("cli"::: "memory");\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
+ UINT32 LowData;\r
+ UINT32 HighData;\r
+\r
+ __asm__ __volatile__ (\r
+ "rdmsr"\r
+ : "=a" (LowData), // %0\r
+ "=d" (HighData) // %1\r
+ : "c" (Index) // %2\r
+ );\r
+\r
+ return (((UINT64)HighData) << 32) | LowData;\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
+ UINT32 LowData;\r
+ UINT32 HighData;\r
+\r
+ LowData = (UINT32)(Value);\r
+ HighData = (UINT32)(Value >> 32);\r
+\r
+ __asm__ __volatile__ (\r
+ "wrmsr"\r
+ :\r
+ : "c" (Index),\r
+ "a" (LowData),\r
+ "d" (HighData)\r
+ );\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
+AsmReadCr0 (\r
+ VOID\r
+ )\r
+{\r
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%cr0,%0"\r
+ : "=r" (Data) // %0\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%cr2, %0"\r
+ : "=r" (Data) // %0\r
+ );\r
+\r
+ return Data;\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%cr3, %0"\r
+ : "=r" (Data) // %0\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%cr4, %0"\r
+ : "=r" (Data) // %0\r
+ );\r
+\r
+ return Data;\r
+}\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
+ __asm__ __volatile__ (\r
+ "mov %0, %%cr0"\r
+ :\r
+ : "r" (Cr0)\r
+ );\r
+ return Cr0;\r
+}\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
+ __asm__ __volatile__ (\r
+ "mov %0, %%cr2"\r
+ :\r
+ : "r" (Cr2)\r
+ );\r
+ return Cr2;\r
+}\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
+ __asm__ __volatile__ (\r
+ "mov %0, %%cr3"\r
+ :\r
+ : "r" (Cr3)\r
+ );\r
+ return Cr3;\r
+}\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
+ __asm__ __volatile__ (\r
+ "mov %0, %%cr4"\r
+ :\r
+ : "r" (Cr4)\r
+ );\r
+ return Cr4;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%dr0, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%dr1, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%dr2, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%dr3, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%dr4, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%dr5, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%dr6, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINTN Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%dr7, %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ __asm__ __volatile__ (\r
+ "mov %0, %%dr0"\r
+ :\r
+ : "r" (Dr0)\r
+ );\r
+ return Dr0;\r
+}\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
+ __asm__ __volatile__ (\r
+ "mov %0, %%dr1"\r
+ :\r
+ : "r" (Dr1)\r
+ );\r
+ return Dr1;\r
+}\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
+ __asm__ __volatile__ (\r
+ "mov %0, %%dr2"\r
+ :\r
+ : "r" (Dr2)\r
+ );\r
+ return Dr2;\r
+}\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
+ __asm__ __volatile__ (\r
+ "mov %0, %%dr3"\r
+ :\r
+ : "r" (Dr3)\r
+ );\r
+ return Dr3;\r
+}\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
+ __asm__ __volatile__ (\r
+ "mov %0, %%dr4"\r
+ :\r
+ : "r" (Dr4)\r
+ );\r
+ return Dr4;\r
+}\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
+ __asm__ __volatile__ (\r
+ "mov %0, %%dr5"\r
+ :\r
+ : "r" (Dr5)\r
+ );\r
+ return Dr5;\r
+}\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
+ __asm__ __volatile__ (\r
+ "mov %0, %%dr6"\r
+ :\r
+ : "r" (Dr6)\r
+ );\r
+ return Dr6;\r
+}\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
+ __asm__ __volatile__ (\r
+ "mov %0, %%dr7"\r
+ :\r
+ : "r" (Dr7)\r
+ );\r
+ return Dr7;\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%cs, %0"\r
+ :"=a" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%ds, %0"\r
+ :"=a" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%es, %0"\r
+ :"=a" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%fs, %0"\r
+ :"=a" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%gs, %0"\r
+ :"=a" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "mov %%ds, %0"\r
+ :"=a" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "str %0"\r
+ : "=r" (Data)\r
+ );\r
+\r
+ return Data;\r
+}\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
+ @param Gdtr The pointer to a GDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InternalX86ReadGdtr (\r
+ OUT IA32_DESCRIPTOR *Gdtr\r
+ )\r
+{\r
+ __asm__ __volatile__ (\r
+ "sgdt %0"\r
+ : "=m" (*Gdtr)\r
+ );\r
+}\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
+ @param Gdtr The pointer to a GDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InternalX86WriteGdtr (\r
+ IN CONST IA32_DESCRIPTOR *Gdtr\r
+ )\r
+{\r
+ __asm__ __volatile__ (\r
+ "lgdt %0"\r
+ :\r
+ : "m" (*Gdtr)\r
+ );\r
+\r
+}\r
+\r
+\r
+/**\r
+ Reads the current Interrupt Descriptor Table Register(GDTR) 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
+ @param Idtr The pointer to a IDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InternalX86ReadIdtr (\r
+ OUT IA32_DESCRIPTOR *Idtr\r
+ )\r
+{\r
+ __asm__ __volatile__ (\r
+ "sidt %0"\r
+ : "=m" (*Idtr)\r
+ );\r
+}\r
+\r
+\r
+/**\r
+ Writes the current Interrupt Descriptor Table Register(GDTR) 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
+ @param Idtr The pointer to a IDTR descriptor.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+InternalX86WriteIdtr (\r
+ IN CONST IA32_DESCRIPTOR *Idtr\r
+ )\r
+{\r
+ __asm__ __volatile__ (\r
+ "lidt %0"\r
+ :\r
+ : "m" (*Idtr)\r
+ );\r
+}\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
+ UINT16 Data;\r
+\r
+ __asm__ __volatile__ (\r
+ "sldt %0"\r
+ : "=g" (Data) // %0\r
+ );\r
+\r
+ return Data;\r
+}\r
+\r
+\r
+/**\r
+ Writes the current Local Descriptor Table Register (GDTR) 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
+ __asm__ __volatile__ (\r
+ "lldtw %0"\r
+ :\r
+ : "g" (Ldtr) // %0\r
+ );\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
+ UINT32 LowData;\r
+ UINT32 HiData;\r
+\r
+ __asm__ __volatile__ (\r
+ "rdpmc"\r
+ : "=a" (LowData),\r
+ "=d" (HiData)\r
+ : "c" (Index)\r
+ );\r
+\r
+ return (((UINT64)HiData) << 32) | LowData;\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
+ __asm__ __volatile__ (\r
+ "monitor"\r
+ :\r
+ : "a" (Eax),\r
+ "c" (Ecx),\r
+ "d" (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
+AsmMwait (\r
+ IN UINTN Eax,\r
+ IN UINTN Ecx\r
+ )\r
+{\r
+ __asm__ __volatile__ (\r
+ "mwait"\r
+ :\r
+ : "a" (Eax),\r
+ "c" (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
+AsmWbinvd (\r
+ VOID\r
+ )\r
+{\r
+ __asm__ __volatile__ ("wbinvd":::"memory");\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
+ __asm__ __volatile__ ("invd":::"memory");\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
+AsmFlushCacheLine (\r
+ IN VOID *LinearAddress\r
+ )\r
+{\r
+ __asm__ __volatile__ (\r
+ "clflush (%0)"\r
+ :\r
+ : "r" (LinearAddress)\r
+ : "memory"\r
+ );\r
+\r
+ return LinearAddress;\r
+}\r