/** @file
GCC inline implementation of BaseLib processor specific functions.
Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "BaseLibInternals.h"
/**
Used to serialize load and store operations.
All loads and stores that proceed calls to this function are guaranteed to be
globally visible when this function returns.
**/
VOID
EFIAPI
MemoryFence (
VOID
)
{
// This is a little bit of overkill and it is more about the compiler that it is
// actually processor synchronization. This is like the _ReadWriteBarrier
// Microsoft specific intrinsic
__asm__ __volatile__ ("":::"memory");
}
/**
Requests CPU to pause for a short period of time.
Requests CPU to pause for a short period of time. Typically used in MP
systems to prevent memory starvation while waiting for a spin lock.
**/
VOID
EFIAPI
CpuPause (
VOID
)
{
__asm__ __volatile__ ("pause");
}
/**
Generates a breakpoint on the CPU.
Generates a breakpoint on the CPU. The breakpoint must be implemented such
that code can resume normal execution after the breakpoint.
**/
VOID
EFIAPI
CpuBreakpoint (
VOID
)
{
__asm__ __volatile__ ("int $3");
}
/**
Reads the current value of the EFLAGS register.
Reads and returns the current value of the EFLAGS register. This function is
only available on IA-32 and X64. This returns a 32-bit value on IA-32 and a
64-bit value on X64.
@return EFLAGS on IA-32 or RFLAGS on X64.
**/
UINTN
EFIAPI
AsmReadEflags (
VOID
)
{
UINTN Eflags;
__asm__ __volatile__ (
"pushfl \n\t"
"popl %0 "
: "=r" (Eflags)
);
return Eflags;
}
/**
Save the current floating point/SSE/SSE2 context to a buffer.
Saves the current floating point/SSE/SSE2 state to the buffer specified by
Buffer. Buffer must be aligned on a 16-byte boundary. This function is only
available on IA-32 and X64.
@param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
**/
VOID
EFIAPI
InternalX86FxSave (
OUT IA32_FX_BUFFER *Buffer
)
{
__asm__ __volatile__ (
"fxsave %0"
:
: "m" (*Buffer) // %0
);
}
/**
Restores the current floating point/SSE/SSE2 context from a buffer.
Restores the current floating point/SSE/SSE2 state from the buffer specified
by Buffer. Buffer must be aligned on a 16-byte boundary. This function is
only available on IA-32 and X64.
@param Buffer The pointer to a buffer to save the floating point/SSE/SSE2 context.
**/
VOID
EFIAPI
InternalX86FxRestore (
IN CONST IA32_FX_BUFFER *Buffer
)
{
__asm__ __volatile__ (
"fxrstor %0"
:
: "m" (*Buffer) // %0
);
}
/**
Reads the current value of 64-bit MMX Register #0 (MM0).
Reads and returns the current value of MM0. This function is only available
on IA-32 and X64.
@return The current value of MM0.
**/
UINT64
EFIAPI
AsmReadMm0 (
VOID
)
{
UINT64 Data;
__asm__ __volatile__ (
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm0, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
: "=A" (Data) // %0
);
return Data;
}
/**
Reads the current value of 64-bit MMX Register #1 (MM1).
Reads and returns the current value of MM1. This function is only available
on IA-32 and X64.
@return The current value of MM1.
**/
UINT64
EFIAPI
AsmReadMm1 (
VOID
)
{
UINT64 Data;
__asm__ __volatile__ (
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm1, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
: "=A" (Data) // %0
);
return Data;
}
/**
Reads the current value of 64-bit MMX Register #2 (MM2).
Reads and returns the current value of MM2. This function is only available
on IA-32 and X64.
@return The current value of MM2.
**/
UINT64
EFIAPI
AsmReadMm2 (
VOID
)
{
UINT64 Data;
__asm__ __volatile__ (
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm2, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
: "=A" (Data) // %0
);
return Data;
}
/**
Reads the current value of 64-bit MMX Register #3 (MM3).
Reads and returns the current value of MM3. This function is only available
on IA-32 and X64.
@return The current value of MM3.
**/
UINT64
EFIAPI
AsmReadMm3 (
VOID
)
{
UINT64 Data;
__asm__ __volatile__ (
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm3, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
: "=A" (Data) // %0
);
return Data;
}
/**
Reads the current value of 64-bit MMX Register #4 (MM4).
Reads and returns the current value of MM4. This function is only available
on IA-32 and X64.
@return The current value of MM4.
**/
UINT64
EFIAPI
AsmReadMm4 (
VOID
)
{
UINT64 Data;
__asm__ __volatile__ (
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm4, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
: "=A" (Data) // %0
);
return Data;
}
/**
Reads the current value of 64-bit MMX Register #5 (MM5).
Reads and returns the current value of MM5. This function is only available
on IA-32 and X64.
@return The current value of MM5.
**/
UINT64
EFIAPI
AsmReadMm5 (
VOID
)
{
UINT64 Data;
__asm__ __volatile__ (
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm5, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
: "=A" (Data) // %0
);
return Data;
}
/**
Reads the current value of 64-bit MMX Register #6 (MM6).
Reads and returns the current value of MM6. This function is only available
on IA-32 and X64.
@return The current value of MM6.
**/
UINT64
EFIAPI
AsmReadMm6 (
VOID
)
{
UINT64 Data;
__asm__ __volatile__ (
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm6, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
: "=A" (Data) // %0
);
return Data;
}
/**
Reads the current value of 64-bit MMX Register #7 (MM7).
Reads and returns the current value of MM7. This function is only available
on IA-32 and X64.
@return The current value of MM7.
**/
UINT64
EFIAPI
AsmReadMm7 (
VOID
)
{
UINT64 Data;
__asm__ __volatile__ (
"push %%eax \n\t"
"push %%eax \n\t"
"movq %%mm7, (%%esp)\n\t"
"pop %%eax \n\t"
"pop %%edx \n\t"
: "=A" (Data) // %0
);
return Data;
}
/**
Writes the current value of 64-bit MMX Register #0 (MM0).
Writes the current value of MM0. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM0.
**/
VOID
EFIAPI
AsmWriteMm0 (
IN UINT64 Value
)
{
__asm__ __volatile__ (
"movq %0, %%mm0" // %0
:
: "m" (Value)
);
}
/**
Writes the current value of 64-bit MMX Register #1 (MM1).
Writes the current value of MM1. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM1.
**/
VOID
EFIAPI
AsmWriteMm1 (
IN UINT64 Value
)
{
__asm__ __volatile__ (
"movq %0, %%mm1" // %0
:
: "m" (Value)
);
}
/**
Writes the current value of 64-bit MMX Register #2 (MM2).
Writes the current value of MM2. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM2.
**/
VOID
EFIAPI
AsmWriteMm2 (
IN UINT64 Value
)
{
__asm__ __volatile__ (
"movq %0, %%mm2" // %0
:
: "m" (Value)
);
}
/**
Writes the current value of 64-bit MMX Register #3 (MM3).
Writes the current value of MM3. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM3.
**/
VOID
EFIAPI
AsmWriteMm3 (
IN UINT64 Value
)
{
__asm__ __volatile__ (
"movq %0, %%mm3" // %0
:
: "m" (Value)
);
}
/**
Writes the current value of 64-bit MMX Register #4 (MM4).
Writes the current value of MM4. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM4.
**/
VOID
EFIAPI
AsmWriteMm4 (
IN UINT64 Value
)
{
__asm__ __volatile__ (
"movq %0, %%mm4" // %0
:
: "m" (Value)
);
}
/**
Writes the current value of 64-bit MMX Register #5 (MM5).
Writes the current value of MM5. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM5.
**/
VOID
EFIAPI
AsmWriteMm5 (
IN UINT64 Value
)
{
__asm__ __volatile__ (
"movq %0, %%mm5" // %0
:
: "m" (Value)
);
}
/**
Writes the current value of 64-bit MMX Register #6 (MM6).
Writes the current value of MM6. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM6.
**/
VOID
EFIAPI
AsmWriteMm6 (
IN UINT64 Value
)
{
__asm__ __volatile__ (
"movq %0, %%mm6" // %0
:
: "m" (Value)
);
}
/**
Writes the current value of 64-bit MMX Register #7 (MM7).
Writes the current value of MM7. This function is only available on IA32 and
X64.
@param Value The 64-bit value to write to MM7.
**/
VOID
EFIAPI
AsmWriteMm7 (
IN UINT64 Value
)
{
__asm__ __volatile__ (
"movq %0, %%mm7" // %0
:
: "m" (Value)
);
}
/**
Reads the current value of Time Stamp Counter (TSC).
Reads and returns the current value of TSC. This function is only available
on IA-32 and X64.
@return The current value of TSC
**/
UINT64
EFIAPI
AsmReadTsc (
VOID
)
{
UINT64 Data;
__asm__ __volatile__ (
"rdtsc"
: "=A" (Data)
);
return Data;
}