audk/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c

117 lines
2.6 KiB
C
Raw Normal View History

UefiCpuPkg: Add PiSmmCpuDxeSmm module no IA32/X64 files Add module that initializes a CPU for the SMM environment and installs the first level SMI handler. This module along with the SMM IPL and SMM Core provide the services required for DXE_SMM_DRIVERS to register hardware and software SMI handlers. CPU specific features are abstracted through the SmmCpuFeaturesLib Platform specific features are abstracted through the SmmCpuPlatformHookLib Several PCDs are added to enable/disable features and configure settings for the PiSmmCpuDxeSmm module Changes between [PATCH v1] and [PATCH v2]: 1) Swap PTE init order for QEMU compatibility. Current PTE initialization algorithm works on HW but breaks QEMU emulator. Update the PTE initialization order to be compatible with both. 2) Update comment block that describes 32KB SMBASE alignment requirement to match contents of Intel(R) 64 and IA-32 Architectures Software Developer's Manual 3) Remove BUGBUG comment and call to ClearSmi() that is not required. SMI should be cleared by root SMI handler. [jeff.fan@intel.com: Fix code style issues reported by ECC] Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Michael Kinney <michael.d.kinney@intel.com> Cc: Laszlo Ersek <lersek@redhat.com> Cc: Paolo Bonzini <pbonzini@redhat.com> [pbonzini@redhat.com: InitPaging: prepare PT before filling in PDE] Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Acked-by: Laszlo Ersek <lersek@redhat.com> Reviewed-by: Jeff Fan <jeff.fan@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18645 6f19259b-4bc3-4df7-8a09-765794883524
2015-10-19 21:12:53 +02:00
/** @file
SMM Timer feature support
Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include "PiSmmCpuDxeSmm.h"
UINT64 mTimeoutTicker = 0;
//
// Number of counts in a roll-over cycle of the performance counter.
//
UINT64 mCycle = 0;
//
// Flag to indicate the performance counter is count-up or count-down.
//
BOOLEAN mCountDown;
/**
Initialize Timer for SMM AP Sync.
**/
VOID
InitializeSmmTimer (
VOID
)
{
UINT64 TimerFrequency;
UINT64 Start;
UINT64 End;
TimerFrequency = GetPerformanceCounterProperties (&Start, &End);
mTimeoutTicker = DivU64x32 (
MultU64x64(TimerFrequency, PcdGet64 (PcdCpuSmmApSyncTimeout)),
1000 * 1000
);
if (End < Start) {
mCountDown = TRUE;
mCycle = Start - End;
} else {
mCountDown = FALSE;
mCycle = End - Start;
}
}
/**
Start Timer for SMM AP Sync.
**/
UINT64
EFIAPI
StartSyncTimer (
VOID
)
{
return GetPerformanceCounter ();
}
/**
Check if the SMM AP Sync timer is timeout.
@param Timer The start timer from the begin.
**/
BOOLEAN
EFIAPI
IsSyncTimerTimeout (
IN UINT64 Timer
)
{
UINT64 CurrentTimer;
UINT64 Delta;
CurrentTimer = GetPerformanceCounter ();
//
// We need to consider the case that CurrentTimer is equal to Timer
// when some timer runs too slow and CPU runs fast. We think roll over
// condition does not happen on this case.
//
if (mCountDown) {
//
// The performance counter counts down. Check for roll over condition.
//
if (CurrentTimer <= Timer) {
Delta = Timer - CurrentTimer;
} else {
//
// Handle one roll-over.
//
Delta = mCycle - (CurrentTimer - Timer) + 1;
}
} else {
//
// The performance counter counts up. Check for roll over condition.
//
if (CurrentTimer >= Timer) {
Delta = CurrentTimer - Timer;
} else {
//
// Handle one roll-over.
//
Delta = mCycle - (Timer - CurrentTimer) + 1;
}
}
return (BOOLEAN) (Delta >= mTimeoutTicker);
}