mirror of https://github.com/acidanthera/audk.git
563 lines
9.5 KiB
C
563 lines
9.5 KiB
C
/** @file
|
|
GCC inline implementation of BaseLib processor specific functions.
|
|
|
|
Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.<BR>
|
|
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
|
|
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__ (
|
|
"pushfq \n\t"
|
|
"pop %0 "
|
|
: "=r" (Eflags) // %0
|
|
);
|
|
|
|
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__ (
|
|
"movd %%mm0, %0 \n\t"
|
|
: "=r" (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__ (
|
|
"movd %%mm1, %0 \n\t"
|
|
: "=r" (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__ (
|
|
"movd %%mm2, %0 \n\t"
|
|
: "=r" (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__ (
|
|
"movd %%mm3, %0 \n\t"
|
|
: "=r" (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__ (
|
|
"movd %%mm4, %0 \n\t"
|
|
: "=r" (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__ (
|
|
"movd %%mm5, %0 \n\t"
|
|
: "=r" (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__ (
|
|
"movd %%mm6, %0 \n\t"
|
|
: "=r" (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__ (
|
|
"movd %%mm7, %0 \n\t"
|
|
: "=r" (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__ (
|
|
"movd %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__ (
|
|
"movd %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__ (
|
|
"movd %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__ (
|
|
"movd %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__ (
|
|
"movd %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__ (
|
|
"movd %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__ (
|
|
"movd %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__ (
|
|
"movd %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
|
|
)
|
|
{
|
|
UINT32 LowData;
|
|
UINT32 HiData;
|
|
|
|
__asm__ __volatile__ (
|
|
"rdtsc"
|
|
: "=a" (LowData),
|
|
"=d" (HiData)
|
|
);
|
|
|
|
return (((UINT64)HiData) << 32) | LowData;
|
|
}
|