blob: e2df47d5d5818b2993467164026583a26c34645a [file]
/** @file
Provide functions to read or write FS base register.
Copyright (c) 2026, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "BaseLibInternals.h"
#include <Register/Intel/Cpuid.h>
/**
Worker function that returns TRUE if the CPU supports FS/GS base instructions,
FALSE otherwise.
@retval TRUE The CPU supports FS/GS base instructions.
@retval FALSE The CPU does not support FS/GS base instructions.
**/
BOOLEAN
InternalFsGsBaseSupported (
VOID
)
{
UINT32 MaxLeaf;
CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_EBX Ebx;
AsmCpuid (CPUID_SIGNATURE, &MaxLeaf, NULL, NULL, NULL);
if (MaxLeaf < CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS) {
return FALSE;
}
AsmCpuidEx (
CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS,
CPUID_STRUCTURED_EXTENDED_FEATURE_FLAGS_SUB_LEAF_INFO,
NULL,
&Ebx.Uint32,
NULL,
NULL
);
return (BOOLEAN)(Ebx.Bits.FSGSBASE == 1);
}
/**
Worker function that returns TRUE if the CPU enables FS/GS base instructions,
FALSE otherwise.
@retval TRUE The CPU enables FS/GS base instructions.
@retval FALSE The CPU does not enable FS/GS base instructions.
**/
BOOLEAN
InternalFsGsBaseEnabled (
VOID
)
{
IA32_CR4 Cr4;
Cr4.UintN = AsmReadCr4 ();
return (BOOLEAN)(Cr4.Bits.FSGSBASE == 1);
}
/**
Reads the current value of the FS segment base address.
Reads and returns the current value of the FS segment base address using
the RDFSBASE instruction. This function is only available on X64.
Note: The function requires that CPUID.(EAX=7,ECX=0):EBX.FSGSBASE=1
and CR4.FSGSBASE=1.
@return The current value of the FS segment base address.
**/
UINT64
EFIAPI
AsmReadFsBase (
VOID
)
{
ASSERT (InternalFsGsBaseSupported ());
ASSERT (InternalFsGsBaseEnabled ());
return InternalX86ReadFsBase ();
}
/**
Writes a value to the FS segment base address.
Writes FsBase to the FS segment base address register using the WRFSBASE
instruction. This function is only available on X64.
Note: The function requires that CPUID.(EAX=7,ECX=0):EBX.FSGSBASE=1
and CR4.FSGSBASE=1.
@param FsBase The value to write to the FS segment base address.
@return FsBase
**/
UINT64
EFIAPI
AsmWriteFsBase (
IN UINT64 FsBase
)
{
ASSERT (InternalFsGsBaseSupported ());
ASSERT (InternalFsGsBaseEnabled ());
InternalX86WriteFsBase (FsBase);
return FsBase;
}