mirror of https://github.com/acidanthera/audk.git
UefiCpuPkg/MpInitLib: Get ApLoopMode and MointorFilter size
Firstly, get ApLoopMode from PcdCpuApLoopMode. If MonitorMwait feature is not supported, update ApLoopMode to ApHltLoop. If MonitorMwait feature is supported, get MointorFilter size by CPUID.[EAX=05H]:EBX.BIT0-15. v5: 1. Add comment block for enum AP_LOOP_MODE. Cc: Michael Kinney <michael.d.kinney@intel.com> Cc: Feng Tian <feng.tian@intel.com> Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jeff Fan <jeff.fan@intel.com> Reviewed-by: Michael Kinney <michael.d.kinney@intel.com> Tested-by: Laszlo Ersek <lersek@redhat.com> Tested-by: Michael Kinney <michael.d.kinney@intel.com>
This commit is contained in:
parent
f7f85d8360
commit
9ebcf0f400
|
@ -15,6 +15,65 @@
|
|||
#include "MpLib.h"
|
||||
|
||||
|
||||
/**
|
||||
Detect whether Mwait-monitor feature is supported.
|
||||
|
||||
@retval TRUE Mwait-monitor feature is supported.
|
||||
@retval FALSE Mwait-monitor feature is not supported.
|
||||
**/
|
||||
BOOLEAN
|
||||
IsMwaitSupport (
|
||||
VOID
|
||||
)
|
||||
{
|
||||
CPUID_VERSION_INFO_ECX VersionInfoEcx;
|
||||
|
||||
AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, &VersionInfoEcx.Uint32, NULL);
|
||||
return (VersionInfoEcx.Bits.MONITOR == 1) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
Get AP loop mode.
|
||||
|
||||
@param[out] MonitorFilterSize Returns the largest monitor-line size in bytes.
|
||||
|
||||
@return The AP loop mode.
|
||||
**/
|
||||
UINT8
|
||||
GetApLoopMode (
|
||||
OUT UINT32 *MonitorFilterSize
|
||||
)
|
||||
{
|
||||
UINT8 ApLoopMode;
|
||||
CPUID_MONITOR_MWAIT_EBX MonitorMwaitEbx;
|
||||
|
||||
ASSERT (MonitorFilterSize != NULL);
|
||||
|
||||
ApLoopMode = PcdGet8 (PcdCpuApLoopMode);
|
||||
ASSERT (ApLoopMode >= ApInHltLoop && ApLoopMode <= ApInRunLoop);
|
||||
if (ApLoopMode == ApInMwaitLoop) {
|
||||
if (!IsMwaitSupport ()) {
|
||||
//
|
||||
// If processor does not support MONITOR/MWAIT feature,
|
||||
// force AP in Hlt-loop mode
|
||||
//
|
||||
ApLoopMode = ApInHltLoop;
|
||||
}
|
||||
}
|
||||
|
||||
if (ApLoopMode != ApInMwaitLoop) {
|
||||
*MonitorFilterSize = sizeof (UINT32);
|
||||
} else {
|
||||
//
|
||||
// CPUID.[EAX=05H]:EBX.BIT0-15: Largest monitor-line size in bytes
|
||||
// CPUID.[EAX=05H].EDX: C-states supported using MWAIT
|
||||
//
|
||||
AsmCpuid (CPUID_MONITOR_MWAIT, NULL, &MonitorMwaitEbx.Uint32, NULL, NULL);
|
||||
*MonitorFilterSize = MonitorMwaitEbx.Bits.LargestMonitorLineSize;
|
||||
}
|
||||
|
||||
return ApLoopMode;
|
||||
}
|
||||
/**
|
||||
MP Initialize Library initialization.
|
||||
|
||||
|
@ -35,10 +94,14 @@ MpInitLibInitialize (
|
|||
)
|
||||
{
|
||||
MP_ASSEMBLY_ADDRESS_MAP AddressMap;
|
||||
UINT32 MonitorFilterSize;
|
||||
UINT8 ApLoopMode;
|
||||
UINTN ApResetVectorSize;
|
||||
|
||||
AsmGetAddressMap (&AddressMap);
|
||||
ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);
|
||||
ApLoopMode = GetApLoopMode (&MonitorFilterSize);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,16 @@
|
|||
#include <Library/MtrrLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
|
||||
//
|
||||
// AP loop state when APs are in idle state
|
||||
// It's value is the same with PcdCpuApLoopMode
|
||||
//
|
||||
typedef enum {
|
||||
ApInHltLoop = 1,
|
||||
ApInMwaitLoop = 2,
|
||||
ApInRunLoop = 3
|
||||
} AP_LOOP_MODE;
|
||||
|
||||
//
|
||||
// AP reset code information including code address and size,
|
||||
// this structure will be shared be C code and assembly code.
|
||||
|
|
Loading…
Reference in New Issue