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:
Jeff Fan 2016-07-20 23:32:17 +08:00
parent f7f85d8360
commit 9ebcf0f400
2 changed files with 73 additions and 0 deletions

View File

@ -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;
}

View File

@ -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.