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:
@@ -15,6 +15,65 @@
|
|||||||
#include "MpLib.h"
|
#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.
|
MP Initialize Library initialization.
|
||||||
|
|
||||||
@@ -35,10 +94,14 @@ MpInitLibInitialize (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
MP_ASSEMBLY_ADDRESS_MAP AddressMap;
|
MP_ASSEMBLY_ADDRESS_MAP AddressMap;
|
||||||
|
UINT32 MonitorFilterSize;
|
||||||
|
UINT8 ApLoopMode;
|
||||||
UINTN ApResetVectorSize;
|
UINTN ApResetVectorSize;
|
||||||
|
|
||||||
AsmGetAddressMap (&AddressMap);
|
AsmGetAddressMap (&AddressMap);
|
||||||
ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);
|
ApResetVectorSize = AddressMap.RendezvousFunnelSize + sizeof (MP_CPU_EXCHANGE_INFO);
|
||||||
|
ApLoopMode = GetApLoopMode (&MonitorFilterSize);
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -35,6 +35,16 @@
|
|||||||
#include <Library/MtrrLib.h>
|
#include <Library/MtrrLib.h>
|
||||||
#include <Library/HobLib.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,
|
// AP reset code information including code address and size,
|
||||||
// this structure will be shared be C code and assembly code.
|
// this structure will be shared be C code and assembly code.
|
||||||
|
Reference in New Issue
Block a user