summaryrefslogtreecommitdiff
path: root/UefiCpuPkg/PiSmmCpuDxeSmm
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-12-22 17:11:19 +0800
committerGuo Mang <mang.guo@intel.com>2016-12-26 19:14:50 +0800
commit2cc68ed95f4e6a5b6256a6cc1e9f6a585a7d2ba7 (patch)
treee6f0cc497ee0f06782388ab114fd2f3d37bddcc5 /UefiCpuPkg/PiSmmCpuDxeSmm
parenta6747ab91782ba4309b5f12301c8b43b1b4702dd (diff)
downloadedk2-platforms-2cc68ed95f4e6a5b6256a6cc1e9f6a585a7d2ba7.tar.xz
UefiCpuPkg: Move to new location
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'UefiCpuPkg/PiSmmCpuDxeSmm')
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c512
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c486
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.h181
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.S165
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.asm168
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c130
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/Semaphore.c48
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S169
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm177
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.S911
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.asm738
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c96
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.S84
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.asm94
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c80
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h97
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c1410
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c1517
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h797
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf161
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.uni21
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmmExtra.uni18
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c1434
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h138
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h172
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c700
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c116
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.S204
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.asm206
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c691
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/Semaphore.c67
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S196
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm196
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.S610
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.asm413
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c70
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.S141
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.asm132
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c316
-rw-r--r--UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h105
40 files changed, 0 insertions, 13967 deletions
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
deleted file mode 100644
index 5e63f8aab2..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
+++ /dev/null
@@ -1,512 +0,0 @@
-/** @file
-Code for Processor S3 restoration
-
-Copyright (c) 2006 - 2016, 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"
-
-typedef struct {
- UINTN Lock;
- VOID *StackStart;
- UINTN StackSize;
- VOID *ApFunction;
- IA32_DESCRIPTOR GdtrProfile;
- IA32_DESCRIPTOR IdtrProfile;
- UINT32 BufferStart;
- UINT32 Cr3;
-} MP_CPU_EXCHANGE_INFO;
-
-typedef struct {
- UINT8 *RendezvousFunnelAddress;
- UINTN PModeEntryOffset;
- UINTN FlatJumpOffset;
- UINTN Size;
- UINTN LModeEntryOffset;
- UINTN LongJumpOffset;
-} MP_ASSEMBLY_ADDRESS_MAP;
-
-/**
- Get starting address and size of the rendezvous entry for APs.
- Information for fixing a jump instruction in the code is also returned.
-
- @param AddressMap Output buffer for address map information.
-**/
-VOID *
-EFIAPI
-AsmGetAddressMap (
- MP_ASSEMBLY_ADDRESS_MAP *AddressMap
- );
-
-#define LEGACY_REGION_SIZE (2 * 0x1000)
-#define LEGACY_REGION_BASE (0xA0000 - LEGACY_REGION_SIZE)
-
-ACPI_CPU_DATA mAcpiCpuData;
-UINT32 mNumberToFinish;
-MP_CPU_EXCHANGE_INFO *mExchangeInfo;
-BOOLEAN mRestoreSmmConfigurationInS3 = FALSE;
-VOID *mGdtForAp = NULL;
-VOID *mIdtForAp = NULL;
-VOID *mMachineCheckHandlerForAp = NULL;
-MP_MSR_LOCK *mMsrSpinLocks = NULL;
-UINTN mMsrSpinLockCount;
-UINTN mMsrCount = 0;
-
-/**
- Get MSR spin lock by MSR index.
-
- @param MsrIndex MSR index value.
-
- @return Pointer to MSR spin lock.
-
-**/
-SPIN_LOCK *
-GetMsrSpinLockByIndex (
- IN UINT32 MsrIndex
- )
-{
- UINTN Index;
- for (Index = 0; Index < mMsrCount; Index++) {
- if (MsrIndex == mMsrSpinLocks[Index].MsrIndex) {
- return mMsrSpinLocks[Index].SpinLock;
- }
- }
- return NULL;
-}
-
-/**
- Initialize MSR spin lock by MSR index.
-
- @param MsrIndex MSR index value.
-
-**/
-VOID
-InitMsrSpinLockByIndex (
- IN UINT32 MsrIndex
- )
-{
- UINTN MsrSpinLockCount;
- UINTN NewMsrSpinLockCount;
- UINTN Index;
- UINTN AddedSize;
-
- if (mMsrSpinLocks == NULL) {
- MsrSpinLockCount = mSmmCpuSemaphores.SemaphoreMsr.AvailableCounter;
- mMsrSpinLocks = (MP_MSR_LOCK *) AllocatePool (sizeof (MP_MSR_LOCK) * MsrSpinLockCount);
- ASSERT (mMsrSpinLocks != NULL);
- for (Index = 0; Index < MsrSpinLockCount; Index++) {
- mMsrSpinLocks[Index].SpinLock =
- (SPIN_LOCK *)((UINTN)mSmmCpuSemaphores.SemaphoreMsr.Msr + Index * mSemaphoreSize);
- mMsrSpinLocks[Index].MsrIndex = (UINT32)-1;
- }
- mMsrSpinLockCount = MsrSpinLockCount;
- mSmmCpuSemaphores.SemaphoreMsr.AvailableCounter = 0;
- }
- if (GetMsrSpinLockByIndex (MsrIndex) == NULL) {
- //
- // Initialize spin lock for MSR programming
- //
- mMsrSpinLocks[mMsrCount].MsrIndex = MsrIndex;
- InitializeSpinLock (mMsrSpinLocks[mMsrCount].SpinLock);
- mMsrCount ++;
- if (mMsrCount == mMsrSpinLockCount) {
- //
- // If MSR spin lock buffer is full, enlarge it
- //
- AddedSize = SIZE_4KB;
- mSmmCpuSemaphores.SemaphoreMsr.Msr =
- AllocatePages (EFI_SIZE_TO_PAGES(AddedSize));
- ASSERT (mSmmCpuSemaphores.SemaphoreMsr.Msr != NULL);
- NewMsrSpinLockCount = mMsrSpinLockCount + AddedSize / mSemaphoreSize;
- mMsrSpinLocks = ReallocatePool (
- sizeof (MP_MSR_LOCK) * mMsrSpinLockCount,
- sizeof (MP_MSR_LOCK) * NewMsrSpinLockCount,
- mMsrSpinLocks
- );
- ASSERT (mMsrSpinLocks != NULL);
- mMsrSpinLockCount = NewMsrSpinLockCount;
- for (Index = mMsrCount; Index < mMsrSpinLockCount; Index++) {
- mMsrSpinLocks[Index].SpinLock =
- (SPIN_LOCK *)((UINTN)mSmmCpuSemaphores.SemaphoreMsr.Msr +
- (Index - mMsrCount) * mSemaphoreSize);
- mMsrSpinLocks[Index].MsrIndex = (UINT32)-1;
- }
- }
- }
-}
-
-/**
- Sync up the MTRR values for all processors.
-
- @param MtrrTable Table holding fixed/variable MTRR values to be loaded.
-**/
-VOID
-EFIAPI
-LoadMtrrData (
- EFI_PHYSICAL_ADDRESS MtrrTable
- )
-/*++
-
-Routine Description:
-
- Sync up the MTRR values for all processors.
-
-Arguments:
-
-Returns:
- None
-
---*/
-{
- MTRR_SETTINGS *MtrrSettings;
-
- MtrrSettings = (MTRR_SETTINGS *) (UINTN) MtrrTable;
- MtrrSetAllMtrrs (MtrrSettings);
-}
-
-/**
- Programs registers for the calling processor.
-
- This function programs registers for the calling processor.
-
- @param RegisterTable Pointer to register table of the running processor.
-
-**/
-VOID
-SetProcessorRegister (
- IN CPU_REGISTER_TABLE *RegisterTable
- )
-{
- CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry;
- UINTN Index;
- UINTN Value;
- SPIN_LOCK *MsrSpinLock;
-
- //
- // Traverse Register Table of this logical processor
- //
- RegisterTableEntry = (CPU_REGISTER_TABLE_ENTRY *) (UINTN) RegisterTable->RegisterTableEntry;
- for (Index = 0; Index < RegisterTable->TableLength; Index++, RegisterTableEntry++) {
- //
- // Check the type of specified register
- //
- switch (RegisterTableEntry->RegisterType) {
- //
- // The specified register is Control Register
- //
- case ControlRegister:
- switch (RegisterTableEntry->Index) {
- case 0:
- Value = AsmReadCr0 ();
- Value = (UINTN) BitFieldWrite64 (
- Value,
- RegisterTableEntry->ValidBitStart,
- RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
- (UINTN) RegisterTableEntry->Value
- );
- AsmWriteCr0 (Value);
- break;
- case 2:
- Value = AsmReadCr2 ();
- Value = (UINTN) BitFieldWrite64 (
- Value,
- RegisterTableEntry->ValidBitStart,
- RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
- (UINTN) RegisterTableEntry->Value
- );
- AsmWriteCr2 (Value);
- break;
- case 3:
- Value = AsmReadCr3 ();
- Value = (UINTN) BitFieldWrite64 (
- Value,
- RegisterTableEntry->ValidBitStart,
- RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
- (UINTN) RegisterTableEntry->Value
- );
- AsmWriteCr3 (Value);
- break;
- case 4:
- Value = AsmReadCr4 ();
- Value = (UINTN) BitFieldWrite64 (
- Value,
- RegisterTableEntry->ValidBitStart,
- RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
- (UINTN) RegisterTableEntry->Value
- );
- AsmWriteCr4 (Value);
- break;
- default:
- break;
- }
- break;
- //
- // The specified register is Model Specific Register
- //
- case Msr:
- //
- // If this function is called to restore register setting after INIT signal,
- // there is no need to restore MSRs in register table.
- //
- if (RegisterTableEntry->ValidBitLength >= 64) {
- //
- // If length is not less than 64 bits, then directly write without reading
- //
- AsmWriteMsr64 (
- RegisterTableEntry->Index,
- RegisterTableEntry->Value
- );
- } else {
- //
- // Get lock to avoid Package/Core scope MSRs programming issue in parallel execution mode
- // to make sure MSR read/write operation is atomic.
- //
- MsrSpinLock = GetMsrSpinLockByIndex (RegisterTableEntry->Index);
- AcquireSpinLock (MsrSpinLock);
- //
- // Set the bit section according to bit start and length
- //
- AsmMsrBitFieldWrite64 (
- RegisterTableEntry->Index,
- RegisterTableEntry->ValidBitStart,
- RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
- RegisterTableEntry->Value
- );
- ReleaseSpinLock (MsrSpinLock);
- }
- break;
- //
- // Enable or disable cache
- //
- case CacheControl:
- //
- // If value of the entry is 0, then disable cache. Otherwise, enable cache.
- //
- if (RegisterTableEntry->Value == 0) {
- AsmDisableCache ();
- } else {
- AsmEnableCache ();
- }
- break;
-
- default:
- break;
- }
- }
-}
-
-/**
- AP initialization before SMBASE relocation in the S3 boot path.
-**/
-VOID
-EarlyMPRendezvousProcedure (
- VOID
- )
-{
- CPU_REGISTER_TABLE *RegisterTableList;
- UINT32 InitApicId;
- UINTN Index;
-
- LoadMtrrData (mAcpiCpuData.MtrrTable);
-
- //
- // Find processor number for this CPU.
- //
- RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.PreSmmInitRegisterTable;
- InitApicId = GetInitialApicId ();
- for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {
- if (RegisterTableList[Index].InitialApicId == InitApicId) {
- SetProcessorRegister (&RegisterTableList[Index]);
- break;
- }
- }
-
- //
- // Count down the number with lock mechanism.
- //
- InterlockedDecrement (&mNumberToFinish);
-}
-
-/**
- AP initialization after SMBASE relocation in the S3 boot path.
-**/
-VOID
-MPRendezvousProcedure (
- VOID
- )
-{
- CPU_REGISTER_TABLE *RegisterTableList;
- UINT32 InitApicId;
- UINTN Index;
-
- ProgramVirtualWireMode ();
- DisableLvtInterrupts ();
-
- RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.RegisterTable;
- InitApicId = GetInitialApicId ();
- for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {
- if (RegisterTableList[Index].InitialApicId == InitApicId) {
- SetProcessorRegister (&RegisterTableList[Index]);
- break;
- }
- }
-
- //
- // Count down the number with lock mechanism.
- //
- InterlockedDecrement (&mNumberToFinish);
-}
-
-/**
- Prepares startup vector for APs.
-
- This function prepares startup vector for APs.
-
- @param WorkingBuffer The address of the work buffer.
-**/
-VOID
-PrepareApStartupVector (
- EFI_PHYSICAL_ADDRESS WorkingBuffer
- )
-{
- EFI_PHYSICAL_ADDRESS StartupVector;
- MP_ASSEMBLY_ADDRESS_MAP AddressMap;
-
- //
- // Get the address map of startup code for AP,
- // including code size, and offset of long jump instructions to redirect.
- //
- ZeroMem (&AddressMap, sizeof (AddressMap));
- AsmGetAddressMap (&AddressMap);
-
- StartupVector = WorkingBuffer;
-
- //
- // Copy AP startup code to startup vector, and then redirect the long jump
- // instructions for mode switching.
- //
- CopyMem ((VOID *) (UINTN) StartupVector, AddressMap.RendezvousFunnelAddress, AddressMap.Size);
- *(UINT32 *) (UINTN) (StartupVector + AddressMap.FlatJumpOffset + 3) = (UINT32) (StartupVector + AddressMap.PModeEntryOffset);
- if (AddressMap.LongJumpOffset != 0) {
- *(UINT32 *) (UINTN) (StartupVector + AddressMap.LongJumpOffset + 2) = (UINT32) (StartupVector + AddressMap.LModeEntryOffset);
- }
-
- //
- // Get the start address of exchange data between BSP and AP.
- //
- mExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) (StartupVector + AddressMap.Size);
- ZeroMem ((VOID *) mExchangeInfo, sizeof (MP_CPU_EXCHANGE_INFO));
-
- CopyMem ((VOID *) (UINTN) &mExchangeInfo->GdtrProfile, (VOID *) (UINTN) mAcpiCpuData.GdtrProfile, sizeof (IA32_DESCRIPTOR));
- CopyMem ((VOID *) (UINTN) &mExchangeInfo->IdtrProfile, (VOID *) (UINTN) mAcpiCpuData.IdtrProfile, sizeof (IA32_DESCRIPTOR));
-
- //
- // Copy AP's GDT, IDT and Machine Check handler from SMRAM to ACPI NVS memory
- //
- CopyMem ((VOID *) mExchangeInfo->GdtrProfile.Base, mGdtForAp, mExchangeInfo->GdtrProfile.Limit + 1);
- CopyMem ((VOID *) mExchangeInfo->IdtrProfile.Base, mIdtForAp, mExchangeInfo->IdtrProfile.Limit + 1);
- CopyMem ((VOID *)(UINTN) mAcpiCpuData.ApMachineCheckHandlerBase, mMachineCheckHandlerForAp, mAcpiCpuData.ApMachineCheckHandlerSize);
-
- mExchangeInfo->StackStart = (VOID *) (UINTN) mAcpiCpuData.StackAddress;
- mExchangeInfo->StackSize = mAcpiCpuData.StackSize;
- mExchangeInfo->BufferStart = (UINT32) StartupVector;
- mExchangeInfo->Cr3 = (UINT32) (AsmReadCr3 ());
-}
-
-/**
- The function is invoked before SMBASE relocation in S3 path to restores CPU status.
-
- The function is invoked before SMBASE relocation in S3 path. It does first time microcode load
- and restores MTRRs for both BSP and APs.
-
-**/
-VOID
-EarlyInitializeCpu (
- VOID
- )
-{
- CPU_REGISTER_TABLE *RegisterTableList;
- UINT32 InitApicId;
- UINTN Index;
-
- LoadMtrrData (mAcpiCpuData.MtrrTable);
-
- //
- // Find processor number for this CPU.
- //
- RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.PreSmmInitRegisterTable;
- InitApicId = GetInitialApicId ();
- for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {
- if (RegisterTableList[Index].InitialApicId == InitApicId) {
- SetProcessorRegister (&RegisterTableList[Index]);
- break;
- }
- }
-
- ProgramVirtualWireMode ();
-
- PrepareApStartupVector (mAcpiCpuData.StartupVector);
-
- mNumberToFinish = mAcpiCpuData.NumberOfCpus - 1;
- mExchangeInfo->ApFunction = (VOID *) (UINTN) EarlyMPRendezvousProcedure;
-
- //
- // Send INIT IPI - SIPI to all APs
- //
- SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector);
-
- while (mNumberToFinish > 0) {
- CpuPause ();
- }
-}
-
-/**
- The function is invoked after SMBASE relocation in S3 path to restores CPU status.
-
- The function is invoked after SMBASE relocation in S3 path. It restores configuration according to
- data saved by normal boot path for both BSP and APs.
-
-**/
-VOID
-InitializeCpu (
- VOID
- )
-{
- CPU_REGISTER_TABLE *RegisterTableList;
- UINT32 InitApicId;
- UINTN Index;
-
- RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.RegisterTable;
- InitApicId = GetInitialApicId ();
- for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {
- if (RegisterTableList[Index].InitialApicId == InitApicId) {
- SetProcessorRegister (&RegisterTableList[Index]);
- break;
- }
- }
-
- mNumberToFinish = mAcpiCpuData.NumberOfCpus - 1;
- //
- // StackStart was updated when APs were waken up in EarlyInitializeCpu.
- // Re-initialize StackAddress to original beginning address.
- //
- mExchangeInfo->StackStart = (VOID *) (UINTN) mAcpiCpuData.StackAddress;
- mExchangeInfo->ApFunction = (VOID *) (UINTN) MPRendezvousProcedure;
-
- //
- // Send INIT IPI - SIPI to all APs
- //
- SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector);
-
- while (mNumberToFinish > 0) {
- CpuPause ();
- }
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c
deleted file mode 100644
index 40f2a1719d..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/** @file
-Implementation of SMM CPU Services Protocol.
-
-Copyright (c) 2011 - 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"
-
-//
-// SMM CPU Service Protocol instance
-//
-EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService = {
- SmmGetProcessorInfo,
- SmmSwitchBsp,
- SmmAddProcessor,
- SmmRemoveProcessor,
- SmmWhoAmI,
- SmmRegisterExceptionHandler
-};
-
-/**
- Get Package ID/Core ID/Thread ID of a processor.
-
- APIC ID must be an initial APIC ID.
-
- The algorithm below assumes the target system has symmetry across physical package boundaries
- with respect to the number of logical processors per package, number of cores per package.
-
- @param ApicId APIC ID of the target logical processor.
- @param Location Returns the processor location information.
-**/
-VOID
-SmmGetProcessorLocation (
- IN UINT32 ApicId,
- OUT EFI_CPU_PHYSICAL_LOCATION *Location
- )
-{
- UINTN ThreadBits;
- UINTN CoreBits;
- UINT32 RegEax;
- UINT32 RegEbx;
- UINT32 RegEcx;
- UINT32 RegEdx;
- UINT32 MaxCpuIdIndex;
- UINT32 SubIndex;
- UINTN LevelType;
- UINT32 MaxLogicProcessorsPerPackage;
- UINT32 MaxCoresPerPackage;
- BOOLEAN TopologyLeafSupported;
-
- ASSERT (Location != NULL);
-
- ThreadBits = 0;
- CoreBits = 0;
- TopologyLeafSupported = FALSE;
-
- //
- // Check if the processor is capable of supporting more than one logical processor.
- //
- AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx);
- ASSERT ((RegEdx & BIT28) != 0);
-
- //
- // Assume three-level mapping of APIC ID: Package:Core:SMT.
- //
-
- //
- // Get the max index of basic CPUID
- //
- AsmCpuid (CPUID_SIGNATURE, &MaxCpuIdIndex, NULL, NULL, NULL);
-
- //
- // If the extended topology enumeration leaf is available, it
- // is the preferred mechanism for enumerating topology.
- //
- if (MaxCpuIdIndex >= CPUID_EXTENDED_TOPOLOGY) {
- AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, 0, &RegEax, &RegEbx, &RegEcx, NULL);
- //
- // If CPUID.(EAX=0BH, ECX=0H):EBX returns zero and maximum input value for
- // basic CPUID information is greater than 0BH, then CPUID.0BH leaf is not
- // supported on that processor.
- //
- if ((RegEbx & 0xffff) != 0) {
- TopologyLeafSupported = TRUE;
-
- //
- // Sub-leaf index 0 (ECX= 0 as input) provides enumeration parameters to extract
- // the SMT sub-field of x2APIC ID.
- //
- LevelType = (RegEcx >> 8) & 0xff;
- ASSERT (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_SMT);
- if ((RegEbx & 0xffff) > 1 ) {
- ThreadBits = RegEax & 0x1f;
- } else {
- //
- // HT is not supported
- //
- ThreadBits = 0;
- }
-
- //
- // Software must not assume any "level type" encoding
- // value to be related to any sub-leaf index, except sub-leaf 0.
- //
- SubIndex = 1;
- do {
- AsmCpuidEx (CPUID_EXTENDED_TOPOLOGY, SubIndex, &RegEax, NULL, &RegEcx, NULL);
- LevelType = (RegEcx >> 8) & 0xff;
- if (LevelType == CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_CORE) {
- CoreBits = (RegEax & 0x1f) - ThreadBits;
- break;
- }
- SubIndex++;
- } while (LevelType != CPUID_EXTENDED_TOPOLOGY_LEVEL_TYPE_INVALID);
- }
- }
-
- if (!TopologyLeafSupported) {
- AsmCpuid (CPUID_VERSION_INFO, NULL, &RegEbx, NULL, NULL);
- MaxLogicProcessorsPerPackage = (RegEbx >> 16) & 0xff;
- if (MaxCpuIdIndex >= CPUID_CACHE_PARAMS) {
- AsmCpuidEx (CPUID_CACHE_PARAMS, 0, &RegEax, NULL, NULL, NULL);
- MaxCoresPerPackage = (RegEax >> 26) + 1;
- } else {
- //
- // Must be a single-core processor.
- //
- MaxCoresPerPackage = 1;
- }
-
- ThreadBits = (UINTN) (HighBitSet32 (MaxLogicProcessorsPerPackage / MaxCoresPerPackage - 1) + 1);
- CoreBits = (UINTN) (HighBitSet32 (MaxCoresPerPackage - 1) + 1);
- }
-
- Location->Thread = ApicId & ~((-1) << ThreadBits);
- Location->Core = (ApicId >> ThreadBits) & ~((-1) << CoreBits);
- Location->Package = (ApicId >> (ThreadBits+ CoreBits));
-}
-
-/**
- Gets processor information on the requested processor at the instant this call is made.
-
- @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance.
- @param[in] ProcessorNumber The handle number of processor.
- @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
- the requested processor is deposited.
-
- @retval EFI_SUCCESS Processor information was returned.
- @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
- @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid.
- @retval EFI_NOT_FOUND The processor with the handle specified by
- ProcessorNumber does not exist in the platform.
-
-**/
-EFI_STATUS
-EFIAPI
-SmmGetProcessorInfo (
- IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This,
- IN UINTN ProcessorNumber,
- OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
- )
-{
- //
- // Check parameter
- //
- if (ProcessorNumber >= mMaxNumberOfCpus || ProcessorInfoBuffer == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (gSmmCpuPrivate->ProcessorInfo[ProcessorNumber].ProcessorId == INVALID_APIC_ID) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Fill in processor information
- //
- CopyMem (ProcessorInfoBuffer, &gSmmCpuPrivate->ProcessorInfo[ProcessorNumber], sizeof (EFI_PROCESSOR_INFORMATION));
- return EFI_SUCCESS;
-}
-
-/**
- This service switches the requested AP to be the BSP since the next SMI.
-
- @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance.
- @param[in] ProcessorNumber The handle number of AP that is to become the new BSP.
-
- @retval EFI_SUCCESS BSP will be switched in next SMI.
- @retval EFI_UNSUPPORTED Switching the BSP or a processor to be hot-removed is not supported.
- @retval EFI_NOT_FOUND The processor with the handle specified by ProcessorNumber does not exist.
- @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid.
-**/
-EFI_STATUS
-EFIAPI
-SmmSwitchBsp (
- IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This,
- IN UINTN ProcessorNumber
- )
-{
- //
- // Check parameter
- //
- if (ProcessorNumber >= mMaxNumberOfCpus) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (gSmmCpuPrivate->ProcessorInfo[ProcessorNumber].ProcessorId == INVALID_APIC_ID) {
- return EFI_NOT_FOUND;
- }
-
- if (gSmmCpuPrivate->Operation[ProcessorNumber] != SmmCpuNone ||
- gSmst->CurrentlyExecutingCpu == ProcessorNumber) {
- return EFI_UNSUPPORTED;
- }
-
- //
- // Setting of the BSP for next SMI is pending until all SMI handlers are finished
- //
- gSmmCpuPrivate->Operation[ProcessorNumber] = SmmCpuSwitchBsp;
- return EFI_SUCCESS;
-}
-
-/**
- Notify that a processor was hot-added.
-
- @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance.
- @param[in] ProcessorId Local APIC ID of the hot-added processor.
- @param[out] ProcessorNumber The handle number of the hot-added processor.
-
- @retval EFI_SUCCESS The hot-addition of the specified processors was successfully notified.
- @retval EFI_UNSUPPORTED Hot addition of processor is not supported.
- @retval EFI_NOT_FOUND The processor with the handle specified by ProcessorNumber does not exist.
- @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid.
- @retval EFI_ALREADY_STARTED The processor is already online in the system.
-**/
-EFI_STATUS
-EFIAPI
-SmmAddProcessor (
- IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This,
- IN UINT64 ProcessorId,
- OUT UINTN *ProcessorNumber
- )
-{
- UINTN Index;
-
- if (!FeaturePcdGet (PcdCpuHotPlugSupport)) {
- return EFI_UNSUPPORTED;
- }
-
- //
- // Check parameter
- //
- if (ProcessorNumber == NULL || ProcessorId == INVALID_APIC_ID) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check if the processor already exists
- //
-
- for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
- if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == ProcessorId) {
- return EFI_ALREADY_STARTED;
- }
- }
-
- //
- // Check CPU hot plug data. The CPU RAS handler should have created the mapping
- // of the APIC ID to SMBASE.
- //
- for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
- if (mCpuHotPlugData.ApicId[Index] == ProcessorId &&
- gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == INVALID_APIC_ID) {
- gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId = ProcessorId;
- gSmmCpuPrivate->ProcessorInfo[Index].StatusFlag = 0;
- SmmGetProcessorLocation ((UINT32)ProcessorId, &gSmmCpuPrivate->ProcessorInfo[Index].Location);
-
- *ProcessorNumber = Index;
- gSmmCpuPrivate->Operation[Index] = SmmCpuAdd;
- return EFI_SUCCESS;
- }
- }
-
- return EFI_INVALID_PARAMETER;
-}
-
-/**
- Notify that a processor was hot-removed.
-
- @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance.
- @param[in] ProcessorNumber The handle number of the hot-added processor.
-
- @retval EFI_SUCCESS The hot-removal of the specified processors was successfully notified.
- @retval EFI_UNSUPPORTED Hot removal of processor is not supported.
- @retval EFI_UNSUPPORTED Hot removal of BSP is not supported.
- @retval EFI_UNSUPPORTED Hot removal of a processor with pending hot-plug operation is not supported.
- @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid.
-**/
-EFI_STATUS
-EFIAPI
-SmmRemoveProcessor (
- IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This,
- IN UINTN ProcessorNumber
- )
-{
- if (!FeaturePcdGet (PcdCpuHotPlugSupport)) {
- return EFI_UNSUPPORTED;
- }
-
- //
- // Check parameter
- //
- if (ProcessorNumber >= mMaxNumberOfCpus ||
- gSmmCpuPrivate->ProcessorInfo[ProcessorNumber].ProcessorId == INVALID_APIC_ID) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Can't remove BSP
- //
- if (ProcessorNumber == gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu) {
- return EFI_UNSUPPORTED;
- }
-
- if (gSmmCpuPrivate->Operation[ProcessorNumber] != SmmCpuNone) {
- return EFI_UNSUPPORTED;
- }
-
- gSmmCpuPrivate->ProcessorInfo[ProcessorNumber].ProcessorId = INVALID_APIC_ID;
- mCpuHotPlugData.ApicId[ProcessorNumber] = INVALID_APIC_ID;
-
- //
- // Removal of the processor from the CPU list is pending until all SMI handlers are finished
- //
- gSmmCpuPrivate->Operation[ProcessorNumber] = SmmCpuRemove;
- return EFI_SUCCESS;
-}
-
-/**
- This return the handle number for the calling processor.
-
- @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance.
- @param[out] ProcessorNumber The handle number of currently executing processor.
-
- @retval EFI_SUCCESS The current processor handle number was returned
- in ProcessorNumber.
- @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-SmmWhoAmI (
- IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This,
- OUT UINTN *ProcessorNumber
- )
-{
- UINTN Index;
- UINT64 ApicId;
-
- //
- // Check parameter
- //
- if (ProcessorNumber == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- ApicId = GetApicId ();
-
- for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
- if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == ApicId) {
- *ProcessorNumber = Index;
- return EFI_SUCCESS;
- }
- }
- //
- // This should not happen
- //
- ASSERT (FALSE);
- return EFI_NOT_FOUND;
-}
-
-/**
- Update the SMM CPU list per the pending operation.
-
- This function is called after return from SMI handlers.
-**/
-VOID
-SmmCpuUpdate (
- VOID
- )
-{
- UINTN Index;
-
- //
- // Handle pending BSP switch operations
- //
- for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
- if (gSmmCpuPrivate->Operation[Index] == SmmCpuSwitchBsp) {
- gSmmCpuPrivate->Operation[Index] = SmmCpuNone;
- mSmmMpSyncData->SwitchBsp = TRUE;
- mSmmMpSyncData->CandidateBsp[Index] = TRUE;
- }
- }
-
- //
- // Handle pending hot-add operations
- //
- for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
- if (gSmmCpuPrivate->Operation[Index] == SmmCpuAdd) {
- gSmmCpuPrivate->Operation[Index] = SmmCpuNone;
- mNumberOfCpus++;
- }
- }
-
- //
- // Handle pending hot-remove operations
- //
- for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
- if (gSmmCpuPrivate->Operation[Index] == SmmCpuRemove) {
- gSmmCpuPrivate->Operation[Index] = SmmCpuNone;
- mNumberOfCpus--;
- }
- }
-}
-
-/**
- Register exception handler.
-
- @param This A pointer to the SMM_CPU_SERVICE_PROTOCOL instance.
- @param ExceptionType Defines which interrupt or exception to hook. Type EFI_EXCEPTION_TYPE and
- the valid values for this parameter are defined in EFI_DEBUG_SUPPORT_PROTOCOL
- of the UEFI 2.0 specification.
- @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER
- that is called when a processor interrupt occurs.
- If this parameter is NULL, then the handler will be uninstalled.
-
- @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
- @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was previously installed.
- @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not previously installed.
- @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SmmRegisterExceptionHandler (
- IN EFI_SMM_CPU_SERVICE_PROTOCOL *This,
- IN EFI_EXCEPTION_TYPE ExceptionType,
- IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
- )
-{
- return RegisterCpuInterruptHandler (ExceptionType, InterruptHandler);
-}
-
-/**
- Initialize SMM CPU Services.
-
- It installs EFI SMM CPU Services Protocol.
-
- @param ImageHandle The firmware allocated handle for the EFI image.
-
- @retval EFI_SUCCESS EFI SMM CPU Services Protocol was installed successfully.
-**/
-EFI_STATUS
-InitializeSmmCpuServices (
- IN EFI_HANDLE Handle
- )
-{
- EFI_STATUS Status;
-
- Status = gSmst->SmmInstallProtocolInterface (
- &Handle,
- &gEfiSmmCpuServiceProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &mSmmCpuService
- );
- ASSERT_EFI_ERROR (Status);
- return Status;
-}
-
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.h b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.h
deleted file mode 100644
index 9fe3f45b02..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuService.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/** @file
-Include file for SMM CPU Services protocol implementation.
-
-Copyright (c) 2011 - 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.
-
-**/
-
-#ifndef _CPU_SERVICE_H_
-#define _CPU_SERVICE_H_
-
-typedef enum {
- SmmCpuNone,
- SmmCpuAdd,
- SmmCpuRemove,
- SmmCpuSwitchBsp
-} SMM_CPU_OPERATION;
-
-//
-// SMM CPU Service Protocol function prototypes.
-//
-
-/**
- Gets processor information on the requested processor at the instant this call is made.
-
- @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance.
- @param[in] ProcessorNumber The handle number of processor.
- @param[out] ProcessorInfoBuffer A pointer to the buffer where information for
- the requested processor is deposited.
-
- @retval EFI_SUCCESS Processor information was returned.
- @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL.
- @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid.
- @retval EFI_NOT_FOUND The processor with the handle specified by
- ProcessorNumber does not exist in the platform.
-
-**/
-EFI_STATUS
-EFIAPI
-SmmGetProcessorInfo (
- IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This,
- IN UINTN ProcessorNumber,
- OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer
- );
-
-/**
- This service switches the requested AP to be the BSP since the next SMI.
-
- @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance.
- @param[in] ProcessorNumber The handle number of AP that is to become the new BSP.
-
- @retval EFI_SUCCESS BSP will be switched in next SMI.
- @retval EFI_UNSUPPORTED Switching the BSP or a processor to be hot-removed is not supported.
- @retval EFI_NOT_FOUND The processor with the handle specified by ProcessorNumber does not exist.
- @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid.
-**/
-EFI_STATUS
-EFIAPI
-SmmSwitchBsp (
- IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This,
- IN UINTN ProcessorNumber
- );
-
-/**
- Notify that a processor was hot-added.
-
- @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance.
- @param[in] ProcessorId Local APIC ID of the hot-added processor.
- @param[out] ProcessorNumber The handle number of the hot-added processor.
-
- @retval EFI_SUCCESS The hot-addition of the specified processors was successfully notified.
- @retval EFI_UNSUPPORTED Hot addition of processor is not supported.
- @retval EFI_NOT_FOUND The processor with the handle specified by ProcessorNumber does not exist.
- @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid.
- @retval EFI_ALREADY_STARTED The processor is already online in the system.
-**/
-EFI_STATUS
-EFIAPI
-SmmAddProcessor (
- IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This,
- IN UINT64 ProcessorId,
- OUT UINTN *ProcessorNumber
- );
-
-/**
- Notify that a processor was hot-removed.
-
- @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance.
- @param[in] ProcessorNumber The handle number of the hot-added processor.
-
- @retval EFI_SUCCESS The hot-removal of the specified processors was successfully notified.
- @retval EFI_UNSUPPORTED Hot removal of processor is not supported.
- @retval EFI_UNSUPPORTED Hot removal of BSP is not supported.
- @retval EFI_UNSUPPORTED Hot removal of a processor with pending hot-plug operation is not supported.
- @retval EFI_INVALID_PARAMETER ProcessorNumber is invalid.
-**/
-EFI_STATUS
-EFIAPI
-SmmRemoveProcessor (
- IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This,
- IN UINTN ProcessorNumber
- );
-
-/**
- This return the handle number for the calling processor.
-
- @param[in] This A pointer to the EFI_SMM_CPU_SERVICE_PROTOCOL instance.
- @param[out] ProcessorNumber The handle number of currently executing processor.
-
- @retval EFI_SUCCESS The current processor handle number was returned
- in ProcessorNumber.
- @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-SmmWhoAmI (
- IN CONST EFI_SMM_CPU_SERVICE_PROTOCOL *This,
- OUT UINTN *ProcessorNumber
- );
-
-/**
- Register exception handler.
-
- @param This A pointer to the SMM_CPU_SERVICE_PROTOCOL instance.
- @param ExceptionType Defines which interrupt or exception to hook. Type EFI_EXCEPTION_TYPE and
- the valid values for this parameter are defined in EFI_DEBUG_SUPPORT_PROTOCOL
- of the UEFI 2.0 specification.
- @param InterruptHandler A pointer to a function of type EFI_CPU_INTERRUPT_HANDLER
- that is called when a processor interrupt occurs.
- If this parameter is NULL, then the handler will be uninstalled.
-
- @retval EFI_SUCCESS The handler for the processor interrupt was successfully installed or uninstalled.
- @retval EFI_ALREADY_STARTED InterruptHandler is not NULL, and a handler for InterruptType was previously installed.
- @retval EFI_INVALID_PARAMETER InterruptHandler is NULL, and a handler for InterruptType was not previously installed.
- @retval EFI_UNSUPPORTED The interrupt specified by InterruptType is not supported.
-
-**/
-EFI_STATUS
-EFIAPI
-SmmRegisterExceptionHandler (
- IN EFI_SMM_CPU_SERVICE_PROTOCOL *This,
- IN EFI_EXCEPTION_TYPE ExceptionType,
- IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
- );
-
-//
-// Internal function prototypes
-//
-
-/**
- Update the SMM CPU list per the pending operation.
-
- This function is called after return from SMI handlers.
-**/
-VOID
-SmmCpuUpdate (
- VOID
- );
-
-/**
- Initialize SMM CPU Services.
-
- It installs EFI SMM CPU Services Protocol.
-
- @param ImageHandle The firmware allocated handle for the EFI image.
-
- @retval EFI_SUCCESS EFI SMM CPU Services Protocol was installed successfully.
-**/
-EFI_STATUS
-InitializeSmmCpuServices (
- IN EFI_HANDLE Handle
- );
-
-#endif
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.S b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.S
deleted file mode 100644
index 75aa312a6e..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.S
+++ /dev/null
@@ -1,165 +0,0 @@
-#------------------------------------------------------------------------------
-#
-# Copyright (c) 2006 - 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.
-#
-# Module Name:
-#
-# MpFuncs.S
-#
-# Abstract:
-#
-# This is the assembly code for Multi-processor S3 support
-#
-#------------------------------------------------------------------------------
-
-.equ VacantFlag, 0x0
-.equ NotVacantFlag, 0xff
-
-.equ LockLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart
-.equ StackStart, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x04
-.equ StackSize, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x08
-.equ RendezvousProc, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x0C
-.equ GdtrProfile, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x10
-.equ IdtrProfile, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x16
-.equ BufferStart, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x1C
-
-#-------------------------------------------------------------------------------------
-#RendezvousFunnelProc procedure follows. All APs execute their procedure. This
-#procedure serializes all the AP processors through an Init sequence. It must be
-#noted that APs arrive here very raw...ie: real mode, no stack.
-#ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
-#IS IN MACHINE CODE.
-#-------------------------------------------------------------------------------------
-#RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
-
-ASM_GLOBAL ASM_PFX(RendezvousFunnelProc)
-ASM_PFX(RendezvousFunnelProc):
-RendezvousFunnelProcStart:
-
-# At this point CS = 0x(vv00) and ip= 0x0.
-
- .byte 0x8c,0xc8 # mov ax, cs
- .byte 0x8e,0xd8 # mov ds, ax
- .byte 0x8e,0xc0 # mov es, ax
- .byte 0x8e,0xd0 # mov ss, ax
- .byte 0x33,0xc0 # xor ax, ax
- .byte 0x8e,0xe0 # mov fs, ax
- .byte 0x8e,0xe8 # mov gs, ax
-
-flat32Start:
-
- .byte 0xBE
- .word BufferStart
- .byte 0x66,0x8B,0x14 # mov edx,dword ptr [si] ; EDX is keeping the start address of wakeup buffer
-
- .byte 0xBE
- .word GdtrProfile
- .byte 0x66 # db 66h
- .byte 0x2E,0xF,0x1,0x14 # lgdt fword ptr cs:[si]
-
- .byte 0xBE
- .word IdtrProfile
- .byte 0x66 # db 66h
- .byte 0x2E,0xF,0x1,0x1C # lidt fword ptr cs:[si]
-
- .byte 0x33,0xC0 # xor ax, ax
- .byte 0x8E,0xD8 # mov ds, ax
-
- .byte 0xF,0x20,0xC0 # mov eax, cr0 ; Get control register 0
- .byte 0x66,0x83,0xC8,0x1 # or eax, 000000001h ; Set PE bit (bit #0)
- .byte 0xF,0x22,0xC0 # mov cr0, eax
-
-FLAT32_JUMP:
-
- .byte 0x66,0x67,0xEA # far jump
- .long 0x0 # 32-bit offset
- .word 0x20 # 16-bit selector
-
-PMODE_ENTRY: # protected mode entry point
-
- movw $0x8,%ax
- .byte 0x66
- movw %ax,%ds
- .byte 0x66
- movw %ax,%es
- .byte 0x66
- movw %ax,%fs
- .byte 0x66
- movw %ax,%gs
- .byte 0x66
- movw %ax,%ss # Flat mode setup.
-
- movl %edx,%esi
-
- movl %esi,%edi
- addl $LockLocation, %edi
- movb $NotVacantFlag, %al
-TestLock:
- xchgb (%edi), %al
- cmpb $NotVacantFlag, %al
- jz TestLock
-
-ProgramStack:
-
- movl %esi,%edi
- addl $StackSize, %edi
- movl (%edi),%eax
- movl %esi,%edi
- addl $StackStart, %edi
- addl (%edi),%eax
- movl %eax,%esp
- movl %eax,(%edi)
-
-Releaselock:
-
- movb $VacantFlag, %al
- movl %esi,%edi
- addl $LockLocation, %edi
- xchgb (%edi), %al
-
- #
- # Call assembly function to initialize FPU.
- #
- lea ASM_PFX(InitializeFloatingPointUnits), %ebx
- call *%ebx
- #
- # Call C Function
- #
- movl %esi,%edi
- addl $RendezvousProc, %edi
- movl (%edi),%eax
-
- testl %eax,%eax
- jz GoToSleep
- call *%eax # Call C function
-
-GoToSleep:
- cli
- hlt
- jmp GoToSleep
-
-RendezvousFunnelProcEnd:
-#-------------------------------------------------------------------------------------
-# AsmGetAddressMap (&AddressMap);
-#-------------------------------------------------------------------------------------
-ASM_GLOBAL ASM_PFX(AsmGetAddressMap)
-ASM_PFX(AsmGetAddressMap):
-
- pushal
- movl %esp,%ebp
-
- movl 0x24(%ebp), %ebx
- movl $RendezvousFunnelProcStart, (%ebx)
- movl $(PMODE_ENTRY - RendezvousFunnelProcStart), 0x4(%ebx)
- movl $(FLAT32_JUMP - RendezvousFunnelProcStart), 0x8(%ebx)
- movl $(RendezvousFunnelProcEnd - RendezvousFunnelProcStart), 0x0c(%ebx)
-
- popal
- ret
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.asm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.asm
deleted file mode 100644
index 70e24a8270..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/MpFuncs.asm
+++ /dev/null
@@ -1,168 +0,0 @@
-;------------------------------------------------------------------------------ ;
-; Copyright (c) 2006 - 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.
-;
-; Module Name:
-;
-; MpFuncs.asm
-;
-; Abstract:
-;
-; This is the assembly code for Multi-processor S3 support
-;
-;-------------------------------------------------------------------------------
-
-.686p
-.model flat,C
-.code
-
-EXTERN InitializeFloatingPointUnits:PROC
-
-VacantFlag Equ 00h
-NotVacantFlag Equ 0ffh
-
-LockLocation equ RendezvousFunnelProcEnd - RendezvousFunnelProcStart
-StackStart equ LockLocation + 4h
-StackSize equ LockLocation + 8h
-RendezvousProc equ LockLocation + 0Ch
-GdtrProfile equ LockLocation + 10h
-IdtrProfile equ LockLocation + 16h
-BufferStart equ LockLocation + 1Ch
-
-;-------------------------------------------------------------------------------------
-;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
-;procedure serializes all the AP processors through an Init sequence. It must be
-;noted that APs arrive here very raw...ie: real mode, no stack.
-;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
-;IS IN MACHINE CODE.
-;-------------------------------------------------------------------------------------
-;RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
-
-RendezvousFunnelProc PROC near C PUBLIC
-RendezvousFunnelProcStart::
-
-; At this point CS = 0x(vv00) and ip= 0x0.
-
- db 8ch, 0c8h ; mov ax, cs
- db 8eh, 0d8h ; mov ds, ax
- db 8eh, 0c0h ; mov es, ax
- db 8eh, 0d0h ; mov ss, ax
- db 33h, 0c0h ; xor ax, ax
- db 8eh, 0e0h ; mov fs, ax
- db 8eh, 0e8h ; mov gs, ax
-
-flat32Start::
-
- db 0BEh
- dw BufferStart ; mov si, BufferStart
- db 66h, 8Bh, 14h ; mov edx,dword ptr [si] ; EDX is keeping the start address of wakeup buffer
-
- db 0BEh
- dw GdtrProfile ; mov si, GdtrProfile
- db 66h ; db 66h
- db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
-
- db 0BEh
- dw IdtrProfile ; mov si, IdtrProfile
- db 66h ; db 66h
- db 2Eh, 0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
-
- db 33h, 0C0h ; xor ax, ax
- db 8Eh, 0D8h ; mov ds, ax
-
- db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Get control register 0
- db 66h, 83h, 0C8h, 01h ; or eax, 000000001h ; Set PE bit (bit #0)
- db 0Fh, 22h, 0C0h ; mov cr0, eax
-
-FLAT32_JUMP::
-
- db 66h, 67h, 0EAh ; far jump
- dd 0h ; 32-bit offset
- dw 20h ; 16-bit selector
-
-PMODE_ENTRY:: ; protected mode entry point
-
- mov ax, 8h
- mov ds, ax
- mov es, ax
- mov fs, ax
- mov gs, ax
- mov ss, ax ; Flat mode setup.
-
- mov esi, edx
-
- mov edi, esi
- add edi, LockLocation
- mov al, NotVacantFlag
-TestLock::
- xchg byte ptr [edi], al
- cmp al, NotVacantFlag
- jz TestLock
-
-ProgramStack::
-
- mov edi, esi
- add edi, StackSize
- mov eax, dword ptr [edi]
- mov edi, esi
- add edi, StackStart
- add eax, dword ptr [edi]
- mov esp, eax
- mov dword ptr [edi], eax
-
-Releaselock::
-
- mov al, VacantFlag
- mov edi, esi
- add edi, LockLocation
- xchg byte ptr [edi], al
-
- ;
- ; Call assembly function to initialize FPU.
- ;
- mov ebx, InitializeFloatingPointUnits
- call ebx
- ;
- ; Call C Function
- ;
- mov edi, esi
- add edi, RendezvousProc
- mov eax, dword ptr [edi]
-
- test eax, eax
- jz GoToSleep
- call eax ; Call C function
-
-GoToSleep::
- cli
- hlt
- jmp $-2
-
-RendezvousFunnelProc ENDP
-RendezvousFunnelProcEnd::
-;-------------------------------------------------------------------------------------
-; AsmGetAddressMap (&AddressMap);
-;-------------------------------------------------------------------------------------
-AsmGetAddressMap PROC near C PUBLIC
-
- pushad
- mov ebp,esp
-
- mov ebx, dword ptr [ebp+24h]
- mov dword ptr [ebx], RendezvousFunnelProcStart
- mov dword ptr [ebx+4h], PMODE_ENTRY - RendezvousFunnelProcStart
- mov dword ptr [ebx+8h], FLAT32_JUMP - RendezvousFunnelProcStart
- mov dword ptr [ebx+0ch], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
-
- popad
- ret
-
-AsmGetAddressMap ENDP
-
-END
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
deleted file mode 100644
index a871bef4e2..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/PageTbl.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/** @file
-Page table manipulation functions for IA-32 processors
-
-Copyright (c) 2009 - 2016, 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"
-
-/**
- Create PageTable for SMM use.
-
- @return PageTable Address
-
-**/
-UINT32
-SmmInitPageTable (
- VOID
- )
-{
- UINTN PageFaultHandlerHookAddress;
- IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
-
- //
- // Initialize spin lock
- //
- InitializeSpinLock (mPFLock);
-
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
- //
- // Set own Page Fault entry instead of the default one, because SMM Profile
- // feature depends on IRET instruction to do Single Step
- //
- PageFaultHandlerHookAddress = (UINTN)PageFaultIdtHandlerSmmProfile;
- IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) gcSmiIdtr.Base;
- IdtEntry += EXCEPT_IA32_PAGE_FAULT;
- IdtEntry->Bits.OffsetLow = (UINT16)PageFaultHandlerHookAddress;
- IdtEntry->Bits.Reserved_0 = 0;
- IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
- IdtEntry->Bits.OffsetHigh = (UINT16)(PageFaultHandlerHookAddress >> 16);
- } else {
- //
- // Register SMM Page Fault Handler
- //
- SmmRegisterExceptionHandler (&mSmmCpuService, EXCEPT_IA32_PAGE_FAULT, SmiPFHandler);
- }
-
- //
- // Additional SMM IDT initialization for SMM stack guard
- //
- if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
- InitializeIDTSmmStackGuard ();
- }
- return Gen4GPageTable (0, TRUE);
-}
-
-/**
- Page Fault handler for SMM use.
-
-**/
-VOID
-SmiDefaultPFHandler (
- VOID
- )
-{
- CpuDeadLoop ();
-}
-
-/**
- ThePage Fault handler wrapper for SMM use.
-
- @param InterruptType Defines the type of interrupt or exception that
- occurred on the processor.This parameter is processor architecture specific.
- @param SystemContext A pointer to the processor context when
- the interrupt occurred on the processor.
-**/
-VOID
-EFIAPI
-SmiPFHandler (
- IN EFI_EXCEPTION_TYPE InterruptType,
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- UINTN PFAddress;
-
- ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT);
-
- AcquireSpinLock (mPFLock);
-
- PFAddress = AsmReadCr2 ();
-
- if ((FeaturePcdGet (PcdCpuSmmStackGuard)) &&
- (PFAddress >= mCpuHotPlugData.SmrrBase) &&
- (PFAddress < (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize))) {
- DEBUG ((EFI_D_ERROR, "SMM stack overflow!\n"));
- CpuDeadLoop ();
- }
-
- //
- // If a page fault occurs in SMM range
- //
- if ((PFAddress < mCpuHotPlugData.SmrrBase) ||
- (PFAddress >= mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) {
- if ((SystemContext.SystemContextIa32->ExceptionData & IA32_PF_EC_ID) != 0) {
- DEBUG ((EFI_D_ERROR, "Code executed on IP(0x%x) out of SMM range after SMM is locked!\n", PFAddress));
- DEBUG_CODE (
- DumpModuleInfoByIp (*(UINTN *)(UINTN)SystemContext.SystemContextIa32->Esp);
- );
- CpuDeadLoop ();
- }
- }
-
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
- SmmProfilePFHandler (
- SystemContext.SystemContextIa32->Eip,
- SystemContext.SystemContextIa32->ExceptionData
- );
- } else {
- SmiDefaultPFHandler ();
- }
-
- ReleaseSpinLock (mPFLock);
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/Semaphore.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/Semaphore.c
deleted file mode 100644
index 02a866b430..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/Semaphore.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/** @file
-Semaphore mechanism to indicate to the BSP that an AP has exited SMM
-after SMBASE relocation.
-
-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"
-
-UINTN mSmmRelocationOriginalAddress;
-volatile BOOLEAN *mRebasedFlag;
-
-/**
- Hook return address of SMM Save State so that semaphore code
- can be executed immediately after AP exits SMM to indicate to
- the BSP that an AP has exited SMM after SMBASE relocation.
-
- @param[in] CpuIndex The processor index.
- @param[in] RebasedFlag A pointer to a flag that is set to TRUE
- immediately after AP exits SMM.
-
-**/
-VOID
-SemaphoreHook (
- IN UINTN CpuIndex,
- IN volatile BOOLEAN *RebasedFlag
- )
-{
- SMRAM_SAVE_STATE_MAP *CpuState;
-
- mRebasedFlag = RebasedFlag;
-
- CpuState = (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
- mSmmRelocationOriginalAddress = (UINTN)HookReturnFromSmm (
- CpuIndex,
- CpuState,
- (UINT64)(UINTN)&SmmRelocationSemaphoreComplete,
- (UINT64)(UINTN)&SmmRelocationSemaphoreComplete
- );
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S
deleted file mode 100644
index ec5b9a0b04..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S
+++ /dev/null
@@ -1,169 +0,0 @@
-#------------------------------------------------------------------------------
-#
-# 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.
-#
-# Module Name:
-#
-# SmiEntry.S
-#
-# Abstract:
-#
-# Code template of the SMI handler for a particular processor
-#
-#------------------------------------------------------------------------------
-
-ASM_GLOBAL ASM_PFX(gcSmiHandlerTemplate)
-ASM_GLOBAL ASM_PFX(gcSmiHandlerSize)
-ASM_GLOBAL ASM_PFX(gSmiCr3)
-ASM_GLOBAL ASM_PFX(gSmiStack)
-ASM_GLOBAL ASM_PFX(gSmbase)
-ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
-ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr)
-
-.equ DSC_OFFSET, 0xfb00
-.equ DSC_GDTPTR, 0x30
-.equ DSC_GDTSIZ, 0x38
-.equ DSC_CS, 14
-.equ DSC_DS, 16
-.equ DSC_SS, 18
-.equ DSC_OTHERSEG, 20
-
-.equ PROTECT_MODE_CS, 0x08
-.equ PROTECT_MODE_DS, 0x20
-.equ TSS_SEGMENT, 0x40
-
- .text
-
-ASM_PFX(gcSmiHandlerTemplate):
-
-_SmiEntryPoint:
- .byte 0xbb # mov bx, imm16
- .word _GdtDesc - _SmiEntryPoint + 0x8000
- .byte 0x2e,0xa1 # mov ax, cs:[offset16]
- .word DSC_OFFSET + DSC_GDTSIZ
- decl %eax
- movl %eax, %cs:(%edi) # mov cs:[bx], ax
- .byte 0x66,0x2e,0xa1 # mov eax, cs:[offset16]
- .word DSC_OFFSET + DSC_GDTPTR
- movw %ax, %cs:2(%edi)
- movw %ax, %bp # ebp = GDT base
- .byte 0x66
- lgdt %cs:(%edi)
-# Patch ProtectedMode Segment
- .byte 0xb8 # mov ax, imm16
- .word PROTECT_MODE_CS # set AX for segment directly
- movl %eax, %cs:-2(%edi) # mov cs:[bx - 2], ax
-# Patch ProtectedMode entry
- .byte 0x66, 0xbf # mov edi, SMBASE
-ASM_PFX(gSmbase): .space 4
- .byte 0x67
- lea ((Start32bit - _SmiEntryPoint) + 0x8000)(%edi), %ax
- movw %ax, %cs:-6(%edi)
- movl %cr0, %ebx
- .byte 0x66
- andl $0x9ffafff3, %ebx
- .byte 0x66
- orl $0x23, %ebx
- movl %ebx, %cr0
- .byte 0x66,0xea
- .space 4
- .space 2
-_GdtDesc: .space 4
- .space 2
-
-Start32bit:
- movw $PROTECT_MODE_DS, %ax
- movl %eax,%ds
- movl %eax,%es
- movl %eax,%fs
- movl %eax,%gs
- movl %eax,%ss
- .byte 0xbc # mov esp, imm32
-ASM_PFX(gSmiStack): .space 4
- movl $ASM_PFX(gSmiHandlerIdtr), %eax
- lidt (%eax)
- jmp ProtFlatMode
-
-ProtFlatMode:
- .byte 0xb8 # mov eax, imm32
-ASM_PFX(gSmiCr3): .space 4
- movl %eax, %cr3
-#
-# Need to test for CR4 specific bit support
-#
- movl $1, %eax
- cpuid # use CPUID to determine if specific CR4 bits are supported
- xorl %eax, %eax # Clear EAX
- testl $BIT2, %edx # Check for DE capabilities
- jz L8
- orl $BIT3, %eax
-L8:
- testl $BIT6, %edx # Check for PAE capabilities
- jz L9
- orl $BIT5, %eax
-L9:
- testl $BIT7, %edx # Check for MCE capabilities
- jz L10
- orl $BIT6, %eax
-L10:
- testl $BIT24, %edx # Check for FXSR capabilities
- jz L11
- orl $BIT9, %eax
-L11:
- testl $BIT25, %edx # Check for SSE capabilities
- jz L12
- orl $BIT10, %eax
-L12: # as cr4.PGE is not set here, refresh cr3
- movl %eax, %cr4 # in PreModifyMtrrs() to flush TLB.
- movl %cr0, %ebx
- orl $0x080010000, %ebx # enable paging + WP
- movl %ebx, %cr0
- leal DSC_OFFSET(%edi),%ebx
- movw DSC_DS(%ebx),%ax
- movl %eax, %ds
- movw DSC_OTHERSEG(%ebx),%ax
- movl %eax, %es
- movl %eax, %fs
- movl %eax, %gs
- movw DSC_SS(%ebx),%ax
- movl %eax, %ss
-
- cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
- jz L5
-
-# Load TSS
- movb $0x89, (TSS_SEGMENT + 5)(%ebp) # clear busy flag
- movl $TSS_SEGMENT, %eax
- ltrw %ax
-L5:
-
-# jmp _SmiHandler # instruction is not needed
-
-_SmiHandler:
- movl (%esp), %ebx
-
- pushl %ebx
- movl $ASM_PFX(CpuSmmDebugEntry), %eax
- call *%eax
- popl %ecx
-
- pushl %ebx
- movl $ASM_PFX(SmiRendezvous), %eax
- call *%eax
- popl %ecx
-
- pushl %ebx
- movl $ASM_PFX(CpuSmmDebugExit), %eax
- call *%eax
- popl %ecx
-
- rsm
-
-ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm
deleted file mode 100644
index ac1a9b48dd..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm
+++ /dev/null
@@ -1,177 +0,0 @@
-;------------------------------------------------------------------------------ ;
-; 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.
-;
-; Module Name:
-;
-; SmiEntry.asm
-;
-; Abstract:
-;
-; Code template of the SMI handler for a particular processor
-;
-;-------------------------------------------------------------------------------
-
- .686p
- .model flat,C
- .xmm
-
-DSC_OFFSET EQU 0fb00h
-DSC_GDTPTR EQU 30h
-DSC_GDTSIZ EQU 38h
-DSC_CS EQU 14
-DSC_DS EQU 16
-DSC_SS EQU 18
-DSC_OTHERSEG EQU 20
-
-PROTECT_MODE_CS EQU 08h
-PROTECT_MODE_DS EQU 20h
-TSS_SEGMENT EQU 40h
-
-SmiRendezvous PROTO C
-CpuSmmDebugEntry PROTO C
-CpuSmmDebugExit PROTO C
-
-EXTERNDEF gcSmiHandlerTemplate:BYTE
-EXTERNDEF gcSmiHandlerSize:WORD
-EXTERNDEF gSmiCr3:DWORD
-EXTERNDEF gSmiStack:DWORD
-EXTERNDEF gSmbase:DWORD
-EXTERNDEF FeaturePcdGet (PcdCpuSmmStackGuard):BYTE
-EXTERNDEF gSmiHandlerIdtr:FWORD
-
- .code
-
-gcSmiHandlerTemplate LABEL BYTE
-
-_SmiEntryPoint:
- DB 0bbh ; mov bx, imm16
- DW offset _GdtDesc - _SmiEntryPoint + 8000h
- DB 2eh, 0a1h ; mov ax, cs:[offset16]
- DW DSC_OFFSET + DSC_GDTSIZ
- dec eax
- mov cs:[edi], eax ; mov cs:[bx], ax
- DB 66h, 2eh, 0a1h ; mov eax, cs:[offset16]
- DW DSC_OFFSET + DSC_GDTPTR
- mov cs:[edi + 2], ax ; mov cs:[bx + 2], eax
- mov bp, ax ; ebp = GDT base
- DB 66h
- lgdt fword ptr cs:[edi] ; lgdt fword ptr cs:[bx]
-; Patch ProtectedMode Segment
- DB 0b8h ; mov ax, imm16
- DW PROTECT_MODE_CS ; set AX for segment directly
- mov cs:[edi - 2], eax ; mov cs:[bx - 2], ax
-; Patch ProtectedMode entry
- DB 66h, 0bfh ; mov edi, SMBASE
-gSmbase DD ?
- DB 67h
- lea ax, [edi + (@32bit - _SmiEntryPoint) + 8000h]
- mov cs:[edi - 6], ax ; mov cs:[bx - 6], eax
- mov ebx, cr0
- DB 66h
- and ebx, 9ffafff3h
- DB 66h
- or ebx, 23h
- mov cr0, ebx
- DB 66h, 0eah
- DD ?
- DW ?
-_GdtDesc FWORD ?
-
-@32bit:
- mov ax, PROTECT_MODE_DS
- mov ds, ax
- mov es, ax
- mov fs, ax
- mov gs, ax
- mov ss, ax
- DB 0bch ; mov esp, imm32
-gSmiStack DD ?
- mov eax, offset gSmiHandlerIdtr
- lidt fword ptr [eax]
- jmp ProtFlatMode
-
-ProtFlatMode:
- DB 0b8h ; mov eax, imm32
-gSmiCr3 DD ?
- mov cr3, eax
-;
-; Need to test for CR4 specific bit support
-;
- mov eax, 1
- cpuid ; use CPUID to determine if specific CR4 bits are supported
- xor eax, eax ; Clear EAX
- test edx, BIT2 ; Check for DE capabilities
- jz @f
- or eax, BIT3
-@@:
- test edx, BIT6 ; Check for PAE capabilities
- jz @f
- or eax, BIT5
-@@:
- test edx, BIT7 ; Check for MCE capabilities
- jz @f
- or eax, BIT6
-@@:
- test edx, BIT24 ; Check for FXSR capabilities
- jz @f
- or eax, BIT9
-@@:
- test edx, BIT25 ; Check for SSE capabilities
- jz @f
- or eax, BIT10
-@@: ; as cr4.PGE is not set here, refresh cr3
- mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
- mov ebx, cr0
- or ebx, 080010000h ; enable paging + WP
- mov cr0, ebx
- lea ebx, [edi + DSC_OFFSET]
- mov ax, [ebx + DSC_DS]
- mov ds, eax
- mov ax, [ebx + DSC_OTHERSEG]
- mov es, eax
- mov fs, eax
- mov gs, eax
- mov ax, [ebx + DSC_SS]
- mov ss, eax
-
- cmp FeaturePcdGet (PcdCpuSmmStackGuard), 0
- jz @F
-
-; Load TSS
- mov byte ptr [ebp + TSS_SEGMENT + 5], 89h ; clear busy flag
- mov eax, TSS_SEGMENT
- ltr ax
-@@:
-; jmp _SmiHandler ; instruction is not needed
-
-_SmiHandler PROC
- mov ebx, [esp] ; CPU Index
-
- push ebx
- mov eax, CpuSmmDebugEntry
- call eax
- pop ecx
-
- push ebx
- mov eax, SmiRendezvous
- call eax
- pop ecx
-
- push ebx
- mov eax, CpuSmmDebugExit
- call eax
- pop ecx
-
- rsm
-_SmiHandler ENDP
-
-gcSmiHandlerSize DW $ - _SmiEntryPoint
-
- END
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.S b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.S
deleted file mode 100644
index 4130bf5be5..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.S
+++ /dev/null
@@ -1,911 +0,0 @@
-#------------------------------------------------------------------------------
-#
-# 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.
-#
-# Module Name:
-#
-# SmiException.S
-#
-# Abstract:
-#
-# Exception handlers used in SM mode
-#
-#------------------------------------------------------------------------------
-
-ASM_GLOBAL ASM_PFX(SmiPFHandler)
-ASM_GLOBAL ASM_PFX(PageFaultStubFunction)
-ASM_GLOBAL ASM_PFX(gSmiMtrrs)
-ASM_GLOBAL ASM_PFX(gcSmiIdtr)
-ASM_GLOBAL ASM_PFX(gcSmiGdtr)
-ASM_GLOBAL ASM_PFX(gcPsd)
-ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmProfileEnable))
-
- .data
-
-NullSeg: .quad 0 # reserved by architecture
-CodeSeg32:
- .word -1 # LimitLow
- .word 0 # BaseLow
- .byte 0 # BaseMid
- .byte 0x9b
- .byte 0xcf # LimitHigh
- .byte 0 # BaseHigh
-ProtModeCodeSeg32:
- .word -1 # LimitLow
- .word 0 # BaseLow
- .byte 0 # BaseMid
- .byte 0x9b
- .byte 0xcf # LimitHigh
- .byte 0 # BaseHigh
-ProtModeSsSeg32:
- .word -1 # LimitLow
- .word 0 # BaseLow
- .byte 0 # BaseMid
- .byte 0x93
- .byte 0xcf # LimitHigh
- .byte 0 # BaseHigh
-DataSeg32:
- .word -1 # LimitLow
- .word 0 # BaseLow
- .byte 0 # BaseMid
- .byte 0x93
- .byte 0xcf # LimitHigh
- .byte 0 # BaseHigh
-CodeSeg16:
- .word -1
- .word 0
- .byte 0
- .byte 0x9b
- .byte 0x8f
- .byte 0
-DataSeg16:
- .word -1
- .word 0
- .byte 0
- .byte 0x93
- .byte 0x8f
- .byte 0
-CodeSeg64:
- .word -1 # LimitLow
- .word 0 # BaseLow
- .byte 0 # BaseMid
- .byte 0x9b
- .byte 0xaf # LimitHigh
- .byte 0 # BaseHigh
-.equ GDT_SIZE, .- NullSeg
-
-TssSeg:
- .word TSS_DESC_SIZE -1 # LimitLow
- .word 0 # BaseLow
- .byte 0 # BaseMid
- .byte 0x89
- .byte 0x00 # LimitHigh
- .byte 0 # BaseHigh
-ExceptionTssSeg:
- .word TSS_DESC_SIZE - 1 # LimitLow
- .word 0 # BaseLow
- .byte 0 # BaseMid
- .byte 0x89
- .byte 0x00 # LimitHigh
- .byte 0 # BaseHigh
-
-.equ CODE_SEL, CodeSeg32 - NullSeg
-.equ DATA_SEL, DataSeg32 - NullSeg
-.equ TSS_SEL, TssSeg - NullSeg
-.equ EXCEPTION_TSS_SEL, ExceptionTssSeg - NullSeg
-
-# IA32 TSS fields
-.equ TSS_ESP0, 4
-.equ TSS_SS0, 8
-.equ TSS_ESP1, 12
-.equ TSS_SS1, 16
-.equ TSS_ESP2, 20
-.equ TSS_SS2, 24
-.equ TSS_CR3, 28
-.equ TSS_EIP, 32
-.equ TSS_EFLAGS, 36
-.equ TSS_EAX, 40
-.equ TSS_ECX, 44
-.equ TSS_EDX, 48
-.equ TSS_EBX, 52
-.equ TSS_ESP, 56
-.equ TSS_EBP, 60
-.equ TSS_ESI, 64
-.equ TSS_EDI, 68
-.equ TSS_ES, 72
-.equ TSS_CS, 76
-.equ TSS_SS, 80
-.equ TSS_DS, 84
-.equ TSS_FS, 88
-.equ TSS_GS, 92
-.equ TSS_LDT, 96
-
-# Create 2 TSS segments just after GDT
-TssDescriptor:
- .word 0 # PreviousTaskLink
- .word 0 # Reserved
- .long 0 # ESP0
- .word 0 # SS0
- .word 0 # Reserved
- .long 0 # ESP1
- .word 0 # SS1
- .word 0 # Reserved
- .long 0 # ESP2
- .word 0 # SS2
- .word 0 # Reserved
- .long 0 # CR3
- .long 0 # EIP
- .long 0 # EFLAGS
- .long 0 # EAX
- .long 0 # ECX
- .long 0 # EDX
- .long 0 # EBX
- .long 0 # ESP
- .long 0 # EBP
- .long 0 # ESI
- .long 0 # EDI
- .word 0 # ES
- .word 0 # Reserved
- .word 0 # CS
- .word 0 # Reserved
- .word 0 # SS
- .word 0 # Reserved
- .word 0 # DS
- .word 0 # Reserved
- .word 0 # FS
- .word 0 # Reserved
- .word 0 # GS
- .word 0 # Reserved
- .word 0 # LDT Selector
- .word 0 # Reserved
- .word 0 # T
- .word 0 # I/O Map Base
-.equ TSS_DESC_SIZE, . - TssDescriptor
-
-ExceptionTssDescriptor:
- .word 0 # PreviousTaskLink
- .word 0 # Reserved
- .long 0 # ESP0
- .word 0 # SS0
- .word 0 # Reserved
- .long 0 # ESP1
- .word 0 # SS1
- .word 0 # Reserved
- .long 0 # ESP2
- .word 0 # SS2
- .word 0 # Reserved
- .long 0 # CR3
- .long PFHandlerEntry # EIP
- .long 00000002 # EFLAGS
- .long 0 # EAX
- .long 0 # ECX
- .long 0 # EDX
- .long 0 # EBX
- .long 0 # ESP
- .long 0 # EBP
- .long 0 # ESI
- .long 0 # EDI
- .word DATA_SEL # ES
- .word 0 # Reserved
- .word CODE_SEL # CS
- .word 0 # Reserved
- .word DATA_SEL # SS
- .word 0 # Reserved
- .word DATA_SEL # DS
- .word 0 # Reserved
- .word DATA_SEL # FS
- .word 0 # Reserved
- .word DATA_SEL # GS
- .word 0 # Reserved
- .word 0 # LDT Selector
- .word 0 # Reserved
- .word 0 # T
- .word 0 # I/O Map Base
-
-ASM_PFX(gcPsd):
- .ascii "PSDSIG "
- .word PSD_SIZE
- .word 2
- .word 1 << 2
- .word CODE_SEL
- .word DATA_SEL
- .word DATA_SEL
- .word DATA_SEL
- .word 0
- .long 0
- .long 0
- .long 0
- .long 0
- .quad 0
- .long NullSeg
- .long 0
- .long GDT_SIZE
- .long 0
- .space 24, 0
- .long ASM_PFX(gSmiMtrrs)
- .long 0
-.equ PSD_SIZE, . - ASM_PFX(gcPsd)
-
-ASM_PFX(gcSmiGdtr): .word GDT_SIZE - 1
- .long NullSeg
-
-ASM_PFX(gcSmiIdtr): .word IDT_SIZE - 1
- .long _SmiIDT
-
-_SmiIDT:
-# The following segment repeats 32 times:
-# No. 1
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 2
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 3
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 4
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 5
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 6
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 7
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 8
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 9
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 10
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 11
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 12
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 13
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 14
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 15
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 16
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 17
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 18
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 19
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 20
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 21
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 22
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 23
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 24
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 25
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 26
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 27
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 28
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 29
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 30
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 31
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-# No. 32
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
-
-.equ IDT_SIZE, . - _SmiIDT
-
-TaskGateDescriptor:
- .word 0 # Reserved
- .word EXCEPTION_TSS_SEL # TSS Segment selector
- .byte 0 # Reserved
- .byte 0x85 # Task Gate, present, DPL = 0
- .word 0 # Reserved
-
- .text
-
-#------------------------------------------------------------------------------
-# PageFaultIdtHandlerSmmProfile is the entry point for all exceptions
-#
-# Stack:
-#+---------------------+
-#+ EFlags +
-#+---------------------+
-#+ CS +
-#+---------------------+
-#+ EIP +
-#+---------------------+
-#+ Error Code +
-#+---------------------+
-#+ Vector Number +
-#+---------------------+
-#+ EBP +
-#+---------------------+ <-- EBP
-#
-# RSP set to odd multiple of 8 means ErrCode PRESENT
-#------------------------------------------------------------------------------
-ASM_GLOBAL ASM_PFX(PageFaultIdtHandlerSmmProfile)
-ASM_PFX(PageFaultIdtHandlerSmmProfile):
- pushl $0x0e # Page Fault
- pushl %ebp
- movl %esp, %ebp
-
-
- #
- # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
- # is 16-byte aligned
- #
- andl $0xfffffff0, %esp
- subl $12, %esp
-
-## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
- pushl %eax
- pushl %ecx
- pushl %edx
- pushl %ebx
- leal (6*4)(%ebp), %ecx
- pushl %ecx # ESP
- pushl (%ebp) # EBP
- pushl %esi
- pushl %edi
-
-## UINT32 Gs, Fs, Es, Ds, Cs, Ss;
- movl %ss, %eax
- pushl %eax
- movzwl (4*4)(%ebp), %eax
- pushl %eax
- movl %ds, %eax
- pushl %eax
- movl %es, %eax
- pushl %eax
- movl %fs, %eax
- pushl %eax
- movl %gs, %eax
- pushl %eax
-
-## UINT32 Eip;
- movl (3*4)(%ebp), %eax
- pushl %eax
-
-## UINT32 Gdtr[2], Idtr[2];
- subl $8, %esp
- sidt (%esp)
- movl 2(%esp), %eax
- xchgl (%esp), %eax
- andl $0xffff, %eax
- movl %eax, 4(%esp)
-
- subl $8, %esp
- sgdt (%esp)
- movl 2(%esp), %eax
- xchgl (%esp), %eax
- andl $0xffff, %eax
- movl %eax, 4(%esp)
-
-## UINT32 Ldtr, Tr;
- xorl %eax, %eax
- strw %ax
- pushl %eax
- sldtw %ax
- pushl %eax
-
-## UINT32 EFlags;
- movl (5*4)(%ebp), %eax
- pushl %eax
-
-## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- movl %cr4, %eax
- orl $0x208, %eax
- movl %eax, %cr4
- pushl %eax
- movl %cr3, %eax
- pushl %eax
- movl %cr2, %eax
- pushl %eax
- xorl %eax, %eax
- pushl %eax
- movl %cr0, %eax
- pushl %eax
-
-## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- movl %dr7, %eax
- pushl %eax
- movl %dr6, %eax
- pushl %eax
- movl %dr3, %eax
- pushl %eax
- movl %dr2, %eax
- pushl %eax
- movl %dr1, %eax
- pushl %eax
- movl %dr0, %eax
- pushl %eax
-
-## FX_SAVE_STATE_IA32 FxSaveState;
- subl $512, %esp
- movl %esp, %edi
- .byte 0x0f, 0xae, 0x07 #fxsave [edi]
-
-# UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
- cld
-
-## UINT32 ExceptionData;
- pushl (2*4)(%ebp)
-
-## call into exception handler
-
-## Prepare parameter and call
- movl %esp, %edx
- pushl %edx
- movl (1*4)(%ebp), %edx
- pushl %edx
-
- #
- # Call External Exception Handler
- #
- movl $ASM_PFX(SmiPFHandler), %eax
- call *%eax
- addl $8, %esp
- jmp L4
-
-L4:
-## UINT32 ExceptionData;
- addl $4, %esp
-
-## FX_SAVE_STATE_IA32 FxSaveState;
- movl %esp, %esi
- .byte 0xf, 0xae, 0xe # fxrstor [esi]
- addl $512, %esp
-
-## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
-## Skip restoration of DRx registers to support debuggers
-## that set breakpoints in interrupt/exception context
- addl $4*6, %esp
-
-## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- popl %eax
- movl %eax, %cr0
- addl $4, %esp # not for Cr1
- popl %eax
- movl %eax, %cr2
- popl %eax
- movl %eax, %cr3
- popl %eax
- movl %eax, %cr4
-
-## UINT32 EFlags;
- popl (5*4)(%ebp)
-
-## UINT32 Ldtr, Tr;
-## UINT32 Gdtr[2], Idtr[2];
-## Best not let anyone mess with these particular registers...
- addl $24, %esp
-
-## UINT32 Eip;
- popl (3*4)(%ebp)
-
-## UINT32 Gs, Fs, Es, Ds, Cs, Ss;
-## NOTE - modified segment registers could hang the debugger... We
-## could attempt to insulate ourselves against this possibility,
-## but that poses risks as well.
-##
- popl %gs
- popl %fs
- popl %es
- popl %ds
- popl (4*4)(%ebp)
- popl %ss
-
-## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
- popl %edi
- popl %esi
- addl $4, %esp # not for ebp
- addl $4, %esp # not for esp
- popl %ebx
- popl %edx
- popl %ecx
- popl %eax
-
- movl %ebp, %esp
- popl %ebp
-
-# Enable TF bit after page fault handler runs
- btsl $8, 16(%esp) # EFLAGS
-
- addl $8, %esp # skip INT# & ErrCode
-Return:
- iret
-#
-# Page Fault Exception Handler entry when SMM Stack Guard is enabled
-# Executiot starts here after a task switch
-#
-PFHandlerEntry:
-#
-# Get this processor's TSS
-#
- subl $8, %esp
- sgdt 2(%esp)
- movl 4(%esp), %eax # GDT base
- addl $8, %esp
- movl (TSS_SEL+2)(%eax), %ecx
- shll $8, %ecx
- movb (TSS_SEL+7)(%eax), %cl
- rorl $8, %ecx # ecx = TSS base
-
- movl %esp, %ebp
-
- #
- # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
- # is 16-byte aligned
- #
- andl $0xfffffff0, %esp
- subl $12, %esp
-
-## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
- pushl TSS_EAX(%ecx)
- pushl TSS_ECX(%ecx)
- pushl TSS_EDX(%ecx)
- pushl TSS_EBX(%ecx)
- pushl TSS_ESP(%ecx)
- pushl TSS_EBP(%ecx)
- pushl TSS_ESI(%ecx)
- pushl TSS_EDI(%ecx)
-
-## UINT32 Gs, Fs, Es, Ds, Cs, Ss;
- movzwl TSS_SS(%ecx), %eax
- pushl %eax
- movzwl TSS_CS(%ecx), %eax
- pushl %eax
- movzwl TSS_DS(%ecx), %eax
- pushl %eax
- movzwl TSS_ES(%ecx), %eax
- pushl %eax
- movzwl TSS_FS(%ecx), %eax
- pushl %eax
- movzwl TSS_GS(%ecx), %eax
- pushl %eax
-
-## UINT32 Eip;
- pushl TSS_EIP(%ecx)
-
-## UINT32 Gdtr[2], Idtr[2];
- subl $8, %esp
- sidt (%esp)
- movl 2(%esp), %eax
- xchgl (%esp), %eax
- andl $0xFFFF, %eax
- movl %eax, 4(%esp)
-
- subl $8, %esp
- sgdt (%esp)
- movl 2(%esp), %eax
- xchgl (%esp), %eax
- andl $0xFFFF, %eax
- movl %eax, 4(%esp)
-
-## UINT32 Ldtr, Tr;
- movl $TSS_SEL, %eax
- pushl %eax
- movzwl TSS_LDT(%ecx), %eax
- pushl %eax
-
-## UINT32 EFlags;
- pushl TSS_EFLAGS(%ecx)
-
-## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- movl %cr4, %eax
- orl $0x208, %eax
- movl %eax, %cr4
- pushl %eax
- movl %cr3, %eax
- pushl %eax
- movl %cr2, %eax
- pushl %eax
- xorl %eax, %eax
- pushl %eax
- movl %cr0, %eax
- pushl %eax
-
-## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- movl %dr7, %eax
- pushl %eax
- movl %dr6, %eax
- pushl %eax
- movl %dr3, %eax
- pushl %eax
- movl %dr2, %eax
- pushl %eax
- movl %dr1, %eax
- pushl %eax
- movl %dr0, %eax
- pushl %eax
-
-## FX_SAVE_STATE_IA32 FxSaveState;
-## Clear TS bit in CR0 to avoid Device Not Available Exception (#NM)
-## when executing fxsave/fxrstor instruction
- clts
- subl $512, %esp
- movl %esp, %edi
- .byte 0x0f, 0xae, 0x07 #fxsave [edi]
-
-# UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
- cld
-
-## UINT32 ExceptionData;
- pushl (%ebp)
-
-## call into exception handler
- movl %ecx, %ebx
- movl $ASM_PFX(SmiPFHandler), %eax
-
-## Prepare parameter and call
- movl %esp, %edx
- pushl %edx
- movl $14, %edx
- pushl %edx
-
- #
- # Call External Exception Handler
- #
- call *%eax
- addl $8, %esp
-
- movl %ebx, %ecx
-## UINT32 ExceptionData;
- addl $4, %esp
-
-## FX_SAVE_STATE_IA32 FxSaveState;
- movl %esp, %esi
- .byte 0xf, 0xae, 0xe # fxrstor [esi]
- addl $512, %esp
-
-## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
-## Skip restoration of DRx registers to support debuggers
-## that set breakpoints in interrupt/exception context
- addl $4*6, %esp
-
-## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- popl %eax
- movl %eax, %cr0
- addl $4, %esp # not for Cr1
- popl %eax
- movl %eax, %cr2
- popl %eax
- movl %eax, TSS_CR3(%ecx)
- popl %eax
- movl %eax, %cr4
-
-## UINT32 EFlags;
- popl TSS_EFLAGS(%ecx)
-
-## UINT32 Ldtr, Tr;
-## UINT32 Gdtr[2], Idtr[2];
-## Best not let anyone mess with these particular registers...
- addl $24, %esp
-
-## UINT32 Eip;
- popl TSS_EIP(%ecx)
-
-## UINT32 Gs, Fs, Es, Ds, Cs, Ss;
-## NOTE - modified segment registers could hang the debugger... We
-## could attempt to insulate ourselves against this possibility,
-## but that poses risks as well.
-##
- popl %eax
- movw %ax, TSS_GS(%ecx)
- popl %eax
- movw %ax, TSS_FS(%ecx)
- popl %eax
- movw %ax, TSS_ES(%ecx)
- popl %eax
- movw %ax, TSS_DS(%ecx)
- popl %eax
- movw %ax, TSS_CS(%ecx)
- popl %eax
- movw %ax, TSS_SS(%ecx)
-
-## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
- popl TSS_EDI(%ecx)
- popl TSS_ESI(%ecx)
- addl $4, %esp # not for ebp
- addl $4, %esp # not for esp
- popl TSS_EBX(%ecx)
- popl TSS_EDX(%ecx)
- popl TSS_ECX(%ecx)
- popl TSS_EAX(%ecx)
-
- movl %ebp, %esp
-
-# Set single step DB# if SMM profile is enabled and page fault exception happens
- cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmProfileEnable))
- jz Done2
-# Create return context for iret in stub function
- movl TSS_ESP(%ecx), %eax # Get old stack pointer
- movl TSS_EIP(%ecx), %ebx
- movl %ebx, -0xc(%eax) # create EIP in old stack
- movzwl TSS_CS(%ecx), %ebx
- movl %ebx, -0x8(%eax) # create CS in old stack
- movl TSS_EFLAGS(%ecx), %ebx
- btsl $8,%ebx
- movl %ebx, -0x4(%eax) # create eflags in old stack
- movl TSS_ESP(%ecx), %eax # Get old stack pointer
- subl $12, %eax # minus 12 byte
- movl %eax, TSS_ESP(%ecx) # Set new stack pointer
-
-# Replace the EIP of interrupted task with stub function
- movl $ASM_PFX(PageFaultStubFunction), %eax
- movl %eax, TSS_EIP(%ecx)
-# Jump to the iret so next page fault handler as a task will start again after iret.
-
-Done2:
-
- addl $4, %esp # skip ErrCode
-
- jmp Return
-
-ASM_PFX(PageFaultStubFunction):
-#
-# we need clean TS bit in CR0 to execute
-# x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 instructions.
-#
- clts
- iret
-
-ASM_GLOBAL ASM_PFX(InitializeIDTSmmStackGuard)
-ASM_PFX(InitializeIDTSmmStackGuard):
- pushl %ebx
-#
-# If SMM Stack Guard feature is enabled, the Page Fault Exception entry in IDT
-# is a Task Gate Descriptor so that when a Page Fault Exception occurs,
-# the processors can use a known good stack in case stack ran out.
-#
- leal _SmiIDT + 14 * 8, %ebx
- leal TaskGateDescriptor, %edx
- movl (%edx), %eax
- movl %eax, (%ebx)
- movl 4(%edx), %eax
- movl %eax, 4(%ebx)
-
- popl %ebx
- ret
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.asm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.asm
deleted file mode 100644
index b4eb492da0..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiException.asm
+++ /dev/null
@@ -1,738 +0,0 @@
-;------------------------------------------------------------------------------ ;
-; 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.
-;
-; Module Name:
-;
-; SmiException.asm
-;
-; Abstract:
-;
-; Exception handlers used in SM mode
-;
-;-------------------------------------------------------------------------------
-
- .686p
- .model flat,C
-
-EXTERNDEF SmiPFHandler:PROC
-EXTERNDEF PageFaultStubFunction:PROC
-EXTERNDEF gSmiMtrrs:QWORD
-EXTERNDEF gcSmiIdtr:FWORD
-EXTERNDEF gcSmiGdtr:FWORD
-EXTERNDEF gcPsd:BYTE
-EXTERNDEF FeaturePcdGet (PcdCpuSmmProfileEnable):BYTE
-
-
- .data
-
-NullSeg DQ 0 ; reserved by architecture
-CodeSeg32 LABEL QWORD
- DW -1 ; LimitLow
- DW 0 ; BaseLow
- DB 0 ; BaseMid
- DB 9bh
- DB 0cfh ; LimitHigh
- DB 0 ; BaseHigh
-ProtModeCodeSeg32 LABEL QWORD
- DW -1 ; LimitLow
- DW 0 ; BaseLow
- DB 0 ; BaseMid
- DB 9bh
- DB 0cfh ; LimitHigh
- DB 0 ; BaseHigh
-ProtModeSsSeg32 LABEL QWORD
- DW -1 ; LimitLow
- DW 0 ; BaseLow
- DB 0 ; BaseMid
- DB 93h
- DB 0cfh ; LimitHigh
- DB 0 ; BaseHigh
-DataSeg32 LABEL QWORD
- DW -1 ; LimitLow
- DW 0 ; BaseLow
- DB 0 ; BaseMid
- DB 93h
- DB 0cfh ; LimitHigh
- DB 0 ; BaseHigh
-CodeSeg16 LABEL QWORD
- DW -1
- DW 0
- DB 0
- DB 9bh
- DB 8fh
- DB 0
-DataSeg16 LABEL QWORD
- DW -1
- DW 0
- DB 0
- DB 93h
- DB 8fh
- DB 0
-CodeSeg64 LABEL QWORD
- DW -1 ; LimitLow
- DW 0 ; BaseLow
- DB 0 ; BaseMid
- DB 9bh
- DB 0afh ; LimitHigh
- DB 0 ; BaseHigh
-GDT_SIZE = $ - offset NullSeg
-
-TssSeg LABEL QWORD
- DW TSS_DESC_SIZE - 1 ; LimitLow
- DW 0 ; BaseLow
- DB 0 ; BaseMid
- DB 89h
- DB 00h ; LimitHigh
- DB 0 ; BaseHigh
-ExceptionTssSeg LABEL QWORD
- DW TSS_DESC_SIZE - 1 ; LimitLow
- DW 0 ; BaseLow
- DB 0 ; BaseMid
- DB 89h
- DB 00h ; LimitHigh
- DB 0 ; BaseHigh
-
-CODE_SEL = offset CodeSeg32 - offset NullSeg
-DATA_SEL = offset DataSeg32 - offset NullSeg
-TSS_SEL = offset TssSeg - offset NullSeg
-EXCEPTION_TSS_SEL = offset ExceptionTssSeg - offset NullSeg
-
-IA32_TSS STRUC
- DW ?
- DW ?
- ESP0 DD ?
- SS0 DW ?
- DW ?
- ESP1 DD ?
- SS1 DW ?
- DW ?
- ESP2 DD ?
- SS2 DW ?
- DW ?
- _CR3 DD ?
- EIP DD ?
- EFLAGS DD ?
- _EAX DD ?
- _ECX DD ?
- _EDX DD ?
- _EBX DD ?
- _ESP DD ?
- _EBP DD ?
- _ESI DD ?
- _EDI DD ?
- _ES DW ?
- DW ?
- _CS DW ?
- DW ?
- _SS DW ?
- DW ?
- _DS DW ?
- DW ?
- _FS DW ?
- DW ?
- _GS DW ?
- DW ?
- LDT DW ?
- DW ?
- DW ?
- DW ?
-IA32_TSS ENDS
-
-; Create 2 TSS segments just after GDT
-TssDescriptor LABEL BYTE
- DW 0 ; PreviousTaskLink
- DW 0 ; Reserved
- DD 0 ; ESP0
- DW 0 ; SS0
- DW 0 ; Reserved
- DD 0 ; ESP1
- DW 0 ; SS1
- DW 0 ; Reserved
- DD 0 ; ESP2
- DW 0 ; SS2
- DW 0 ; Reserved
- DD 0 ; CR3
- DD 0 ; EIP
- DD 0 ; EFLAGS
- DD 0 ; EAX
- DD 0 ; ECX
- DD 0 ; EDX
- DD 0 ; EBX
- DD 0 ; ESP
- DD 0 ; EBP
- DD 0 ; ESI
- DD 0 ; EDI
- DW 0 ; ES
- DW 0 ; Reserved
- DW 0 ; CS
- DW 0 ; Reserved
- DW 0 ; SS
- DW 0 ; Reserved
- DW 0 ; DS
- DW 0 ; Reserved
- DW 0 ; FS
- DW 0 ; Reserved
- DW 0 ; GS
- DW 0 ; Reserved
- DW 0 ; LDT Selector
- DW 0 ; Reserved
- DW 0 ; T
- DW 0 ; I/O Map Base
-TSS_DESC_SIZE = $ - offset TssDescriptor
-
-ExceptionTssDescriptor LABEL BYTE
- DW 0 ; PreviousTaskLink
- DW 0 ; Reserved
- DD 0 ; ESP0
- DW 0 ; SS0
- DW 0 ; Reserved
- DD 0 ; ESP1
- DW 0 ; SS1
- DW 0 ; Reserved
- DD 0 ; ESP2
- DW 0 ; SS2
- DW 0 ; Reserved
- DD 0 ; CR3
- DD offset PFHandlerEntry ; EIP
- DD 00000002 ; EFLAGS
- DD 0 ; EAX
- DD 0 ; ECX
- DD 0 ; EDX
- DD 0 ; EBX
- DD 0 ; ESP
- DD 0 ; EBP
- DD 0 ; ESI
- DD 0 ; EDI
- DW DATA_SEL ; ES
- DW 0 ; Reserved
- DW CODE_SEL ; CS
- DW 0 ; Reserved
- DW DATA_SEL ; SS
- DW 0 ; Reserved
- DW DATA_SEL ; DS
- DW 0 ; Reserved
- DW DATA_SEL ; FS
- DW 0 ; Reserved
- DW DATA_SEL ; GS
- DW 0 ; Reserved
- DW 0 ; LDT Selector
- DW 0 ; Reserved
- DW 0 ; T
- DW 0 ; I/O Map Base
-
-gcPsd LABEL BYTE
- DB 'PSDSIG '
- DW PSD_SIZE
- DW 2
- DW 1 SHL 2
- DW CODE_SEL
- DW DATA_SEL
- DW DATA_SEL
- DW DATA_SEL
- DW 0
- DQ 0
- DQ 0
- DQ 0
- DQ offset NullSeg
- DD GDT_SIZE
- DD 0
- DB 24 dup (0)
- DQ offset gSmiMtrrs
-PSD_SIZE = $ - offset gcPsd
-
-gcSmiGdtr LABEL FWORD
- DW GDT_SIZE - 1
- DD offset NullSeg
-
-gcSmiIdtr LABEL FWORD
- DW IDT_SIZE - 1
- DD offset _SmiIDT
-
-_SmiIDT LABEL QWORD
-REPEAT 32
- DW 0 ; Offset 0:15
- DW CODE_SEL ; Segment selector
- DB 0 ; Unused
- DB 8eh ; Interrupt Gate, Present
- DW 0 ; Offset 16:31
- ENDM
-IDT_SIZE = $ - offset _SmiIDT
-
-TaskGateDescriptor LABEL DWORD
- DW 0 ; Reserved
- DW EXCEPTION_TSS_SEL ; TSS Segment selector
- DB 0 ; Reserved
- DB 85h ; Task Gate, present, DPL = 0
- DW 0 ; Reserved
-
-
- .code
-;------------------------------------------------------------------------------
-; PageFaultIdtHandlerSmmProfile is the entry point page fault only
-;
-;
-; Stack:
-; +---------------------+
-; + EFlags +
-; +---------------------+
-; + CS +
-; +---------------------+
-; + EIP +
-; +---------------------+
-; + Error Code +
-; +---------------------+
-; + Vector Number +
-; +---------------------+
-; + EBP +
-; +---------------------+ <-- EBP
-;
-;
-;------------------------------------------------------------------------------
-PageFaultIdtHandlerSmmProfile PROC
- push 0eh ; Page Fault
-
- push ebp
- mov ebp, esp
-
-
- ;
- ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
- ; is 16-byte aligned
- ;
- and esp, 0fffffff0h
- sub esp, 12
-
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
- push eax
- push ecx
- push edx
- push ebx
- lea ecx, [ebp + 6 * 4]
- push ecx ; ESP
- push dword ptr [ebp] ; EBP
- push esi
- push edi
-
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
- mov eax, ss
- push eax
- movzx eax, word ptr [ebp + 4 * 4]
- push eax
- mov eax, ds
- push eax
- mov eax, es
- push eax
- mov eax, fs
- push eax
- mov eax, gs
- push eax
-
-;; UINT32 Eip;
- mov eax, [ebp + 3 * 4]
- push eax
-
-;; UINT32 Gdtr[2], Idtr[2];
- sub esp, 8
- sidt [esp]
- mov eax, [esp + 2]
- xchg eax, [esp]
- and eax, 0FFFFh
- mov [esp+4], eax
-
- sub esp, 8
- sgdt [esp]
- mov eax, [esp + 2]
- xchg eax, [esp]
- and eax, 0FFFFh
- mov [esp+4], eax
-
-;; UINT32 Ldtr, Tr;
- xor eax, eax
- str ax
- push eax
- sldt ax
- push eax
-
-;; UINT32 EFlags;
- mov eax, [ebp + 5 * 4]
- push eax
-
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- mov eax, cr4
- or eax, 208h
- mov cr4, eax
- push eax
- mov eax, cr3
- push eax
- mov eax, cr2
- push eax
- xor eax, eax
- push eax
- mov eax, cr0
- push eax
-
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- mov eax, dr7
- push eax
- mov eax, dr6
- push eax
- mov eax, dr3
- push eax
- mov eax, dr2
- push eax
- mov eax, dr1
- push eax
- mov eax, dr0
- push eax
-
-;; FX_SAVE_STATE_IA32 FxSaveState;
- sub esp, 512
- mov edi, esp
- db 0fh, 0aeh, 07h ;fxsave [edi]
-
-; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
- cld
-
-;; UINT32 ExceptionData;
- push dword ptr [ebp + 2 * 4]
-
-;; call into exception handler
-
-;; Prepare parameter and call
- mov edx, esp
- push edx
- mov edx, dword ptr [ebp + 1 * 4]
- push edx
-
- ;
- ; Call External Exception Handler
- ;
- mov eax, SmiPFHandler
- call eax
- add esp, 8
-
-;; UINT32 ExceptionData;
- add esp, 4
-
-;; FX_SAVE_STATE_IA32 FxSaveState;
- mov esi, esp
- db 0fh, 0aeh, 0eh ; fxrstor [esi]
- add esp, 512
-
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
-;; Skip restoration of DRx registers to support debuggers
-;; that set breakpoint in interrupt/exception context
- add esp, 4 * 6
-
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- pop eax
- mov cr0, eax
- add esp, 4 ; not for Cr1
- pop eax
- mov cr2, eax
- pop eax
- mov cr3, eax
- pop eax
- mov cr4, eax
-
-;; UINT32 EFlags;
- pop dword ptr [ebp + 5 * 4]
-
-;; UINT32 Ldtr, Tr;
-;; UINT32 Gdtr[2], Idtr[2];
-;; Best not let anyone mess with these particular registers...
- add esp, 24
-
-;; UINT32 Eip;
- pop dword ptr [ebp + 3 * 4]
-
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
-;; NOTE - modified segment registers could hang the debugger... We
-;; could attempt to insulate ourselves against this possibility,
-;; but that poses risks as well.
-;;
- pop gs
- pop fs
- pop es
- pop ds
- pop dword ptr [ebp + 4 * 4]
- pop ss
-
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
- pop edi
- pop esi
- add esp, 4 ; not for ebp
- add esp, 4 ; not for esp
- pop ebx
- pop edx
- pop ecx
- pop eax
-
- mov esp, ebp
- pop ebp
-
-; Enable TF bit after page fault handler runs
- bts dword ptr [esp + 16], 8 ; EFLAGS
-
- add esp, 8 ; skip INT# & ErrCode
-Return:
- iretd
-;
-; Page Fault Exception Handler entry when SMM Stack Guard is enabled
-; Executiot starts here after a task switch
-;
-PFHandlerEntry::
-;
-; Get this processor's TSS
-;
- sub esp, 8
- sgdt [esp + 2]
- mov eax, [esp + 4] ; GDT base
- add esp, 8
- mov ecx, [eax + TSS_SEL + 2]
- shl ecx, 8
- mov cl, [eax + TSS_SEL + 7]
- ror ecx, 8 ; ecx = TSS base
-
- mov ebp, esp
-
- ;
- ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
- ; is 16-byte aligned
- ;
- and esp, 0fffffff0h
- sub esp, 12
-
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
- push (IA32_TSS ptr [ecx])._EAX
- push (IA32_TSS ptr [ecx])._ECX
- push (IA32_TSS ptr [ecx])._EDX
- push (IA32_TSS ptr [ecx])._EBX
- push (IA32_TSS ptr [ecx])._ESP
- push (IA32_TSS ptr [ecx])._EBP
- push (IA32_TSS ptr [ecx])._ESI
- push (IA32_TSS ptr [ecx])._EDI
-
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
- movzx eax, (IA32_TSS ptr [ecx])._SS
- push eax
- movzx eax, (IA32_TSS ptr [ecx])._CS
- push eax
- movzx eax, (IA32_TSS ptr [ecx])._DS
- push eax
- movzx eax, (IA32_TSS ptr [ecx])._ES
- push eax
- movzx eax, (IA32_TSS ptr [ecx])._FS
- push eax
- movzx eax, (IA32_TSS ptr [ecx])._GS
- push eax
-
-;; UINT32 Eip;
- push (IA32_TSS ptr [ecx]).EIP
-
-;; UINT32 Gdtr[2], Idtr[2];
- sub esp, 8
- sidt [esp]
- mov eax, [esp + 2]
- xchg eax, [esp]
- and eax, 0FFFFh
- mov [esp+4], eax
-
- sub esp, 8
- sgdt [esp]
- mov eax, [esp + 2]
- xchg eax, [esp]
- and eax, 0FFFFh
- mov [esp+4], eax
-
-;; UINT32 Ldtr, Tr;
- mov eax, TSS_SEL
- push eax
- movzx eax, (IA32_TSS ptr [ecx]).LDT
- push eax
-
-;; UINT32 EFlags;
- push (IA32_TSS ptr [ecx]).EFLAGS
-
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- mov eax, cr4
- or eax, 208h
- mov cr4, eax
- push eax
- mov eax, cr3
- push eax
- mov eax, cr2
- push eax
- xor eax, eax
- push eax
- mov eax, cr0
- push eax
-
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- mov eax, dr7
- push eax
- mov eax, dr6
- push eax
- mov eax, dr3
- push eax
- mov eax, dr2
- push eax
- mov eax, dr1
- push eax
- mov eax, dr0
- push eax
-
-;; FX_SAVE_STATE_IA32 FxSaveState;
-;; Clear TS bit in CR0 to avoid Device Not Available Exception (#NM)
-;; when executing fxsave/fxrstor instruction
- clts
- sub esp, 512
- mov edi, esp
- db 0fh, 0aeh, 07h ;fxsave [edi]
-
-; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
- cld
-
-;; UINT32 ExceptionData;
- push dword ptr [ebp]
-
-;; call into exception handler
- mov ebx, ecx
- mov eax, SmiPFHandler
-
-;; Prepare parameter and call
- mov edx, esp
- push edx
- mov edx, 14
- push edx
-
- ;
- ; Call External Exception Handler
- ;
- call eax
- add esp, 8
-
- mov ecx, ebx
-;; UINT32 ExceptionData;
- add esp, 4
-
-;; FX_SAVE_STATE_IA32 FxSaveState;
- mov esi, esp
- db 0fh, 0aeh, 0eh ; fxrstor [esi]
- add esp, 512
-
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
-;; Skip restoration of DRx registers to support debuggers
-;; that set breakpoints in interrupt/exception context
- add esp, 4 * 6
-
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- pop eax
- mov cr0, eax
- add esp, 4 ; not for Cr1
- pop eax
- mov cr2, eax
- pop eax
- mov (IA32_TSS ptr [ecx])._CR3, eax
- pop eax
- mov cr4, eax
-
-;; UINT32 EFlags;
- pop (IA32_TSS ptr [ecx]).EFLAGS
-
-;; UINT32 Ldtr, Tr;
-;; UINT32 Gdtr[2], Idtr[2];
-;; Best not let anyone mess with these particular registers...
- add esp, 24
-
-;; UINT32 Eip;
- pop (IA32_TSS ptr [ecx]).EIP
-
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
-;; NOTE - modified segment registers could hang the debugger... We
-;; could attempt to insulate ourselves against this possibility,
-;; but that poses risks as well.
-;;
- pop eax
- mov (IA32_TSS ptr [ecx])._GS, ax
- pop eax
- mov (IA32_TSS ptr [ecx])._FS, ax
- pop eax
- mov (IA32_TSS ptr [ecx])._ES, ax
- pop eax
- mov (IA32_TSS ptr [ecx])._DS, ax
- pop eax
- mov (IA32_TSS ptr [ecx])._CS, ax
- pop eax
- mov (IA32_TSS ptr [ecx])._SS, ax
-
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
- pop (IA32_TSS ptr [ecx])._EDI
- pop (IA32_TSS ptr [ecx])._ESI
- add esp, 4 ; not for ebp
- add esp, 4 ; not for esp
- pop (IA32_TSS ptr [ecx])._EBX
- pop (IA32_TSS ptr [ecx])._EDX
- pop (IA32_TSS ptr [ecx])._ECX
- pop (IA32_TSS ptr [ecx])._EAX
-
- mov esp, ebp
-
-; Set single step DB# if SMM profile is enabled and page fault exception happens
- cmp FeaturePcdGet (PcdCpuSmmProfileEnable), 0
- jz @Done2
-
-; Create return context for iretd in stub function
- mov eax, (IA32_TSS ptr [ecx])._ESP ; Get old stack pointer
- mov ebx, (IA32_TSS ptr [ecx]).EIP
- mov [eax - 0ch], ebx ; create EIP in old stack
- movzx ebx, (IA32_TSS ptr [ecx])._CS
- mov [eax - 08h], ebx ; create CS in old stack
- mov ebx, (IA32_TSS ptr [ecx]).EFLAGS
- bts ebx, 8
- mov [eax - 04h], ebx ; create eflags in old stack
- mov eax, (IA32_TSS ptr [ecx])._ESP ; Get old stack pointer
- sub eax, 0ch ; minus 12 byte
- mov (IA32_TSS ptr [ecx])._ESP, eax ; Set new stack pointer
-; Replace the EIP of interrupted task with stub function
- mov eax, PageFaultStubFunction
- mov (IA32_TSS ptr [ecx]).EIP, eax
-; Jump to the iretd so next page fault handler as a task will start again after iretd.
-@Done2:
- add esp, 4 ; skip ErrCode
-
- jmp Return
-PageFaultIdtHandlerSmmProfile ENDP
-
-PageFaultStubFunction PROC
-;
-; we need clean TS bit in CR0 to execute
-; x87 FPU/MMX/SSE/SSE2/SSE3/SSSE3/SSE4 instructions.
-;
- clts
- iretd
-PageFaultStubFunction ENDP
-
-InitializeIDTSmmStackGuard PROC USES ebx
-;
-; If SMM Stack Guard feature is enabled, the Page Fault Exception entry in IDT
-; is a Task Gate Descriptor so that when a Page Fault Exception occurs,
-; the processors can use a known good stack in case stack is ran out.
-;
- lea ebx, _SmiIDT + 14 * 8
- lea edx, TaskGateDescriptor
- mov eax, [edx]
- mov [ebx], eax
- mov eax, [edx + 4]
- mov [ebx + 4], eax
- ret
-InitializeIDTSmmStackGuard ENDP
-
- END
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c
deleted file mode 100644
index 545b534f27..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/** @file
- SMM CPU misc functions for Ia32 arch specific.
-
-Copyright (c) 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"
-
-/**
- Initialize Gdt for all processors.
-
- @param[in] Cr3 CR3 value.
- @param[out] GdtStepSize The step size for GDT table.
-
- @return GdtBase for processor 0.
- GdtBase for processor X is: GdtBase + (GdtStepSize * X)
-**/
-VOID *
-InitGdt (
- IN UINTN Cr3,
- OUT UINTN *GdtStepSize
- )
-{
- UINTN Index;
- IA32_SEGMENT_DESCRIPTOR *GdtDescriptor;
- UINTN TssBase;
- UINTN GdtTssTableSize;
- UINT8 *GdtTssTables;
- UINTN GdtTableStepSize;
-
- if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
- //
- // For IA32 SMM, if SMM Stack Guard feature is enabled, we use 2 TSS.
- // in this case, we allocate separate GDT/TSS for each CPUs to avoid TSS load contention
- // on each SMI entry.
- //
-
- //
- // Enlarge GDT to contain 2 TSS descriptors
- //
- gcSmiGdtr.Limit += (UINT16)(2 * sizeof (IA32_SEGMENT_DESCRIPTOR));
-
- GdtTssTableSize = (gcSmiGdtr.Limit + 1 + TSS_SIZE * 2 + 7) & ~7; // 8 bytes aligned
- GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));
- ASSERT (GdtTssTables != NULL);
- GdtTableStepSize = GdtTssTableSize;
-
- for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {
- CopyMem (GdtTssTables + GdtTableStepSize * Index, (VOID*)(UINTN)gcSmiGdtr.Base, gcSmiGdtr.Limit + 1 + TSS_SIZE * 2);
- //
- // Fixup TSS descriptors
- //
- TssBase = (UINTN)(GdtTssTables + GdtTableStepSize * Index + gcSmiGdtr.Limit + 1);
- GdtDescriptor = (IA32_SEGMENT_DESCRIPTOR *)(TssBase) - 2;
- GdtDescriptor->Bits.BaseLow = (UINT16)TssBase;
- GdtDescriptor->Bits.BaseMid = (UINT8)(TssBase >> 16);
- GdtDescriptor->Bits.BaseHigh = (UINT8)(TssBase >> 24);
-
- TssBase += TSS_SIZE;
- GdtDescriptor++;
- GdtDescriptor->Bits.BaseLow = (UINT16)TssBase;
- GdtDescriptor->Bits.BaseMid = (UINT8)(TssBase >> 16);
- GdtDescriptor->Bits.BaseHigh = (UINT8)(TssBase >> 24);
- //
- // Fixup TSS segments
- //
- // ESP as known good stack
- //
- *(UINTN *)(TssBase + TSS_IA32_ESP_OFFSET) = mSmmStackArrayBase + EFI_PAGE_SIZE + Index * mSmmStackSize;
- *(UINT32 *)(TssBase + TSS_IA32_CR3_OFFSET) = Cr3;
- }
- } else {
- //
- // Just use original table, AllocatePage and copy them here to make sure GDTs are covered in page memory.
- //
- GdtTssTableSize = gcSmiGdtr.Limit + 1;
- GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));
- ASSERT (GdtTssTables != NULL);
- GdtTableStepSize = GdtTssTableSize;
-
- for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {
- CopyMem (GdtTssTables + GdtTableStepSize * Index, (VOID*)(UINTN)gcSmiGdtr.Base, gcSmiGdtr.Limit + 1);
- }
- }
-
- *GdtStepSize = GdtTableStepSize;
- return GdtTssTables;
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.S b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.S
deleted file mode 100644
index e8db33a45a..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.S
+++ /dev/null
@@ -1,84 +0,0 @@
-#------------------------------------------------------------------------------
-#
-# 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.
-#
-# Module Name:
-#
-# SmmInit.S
-#
-# Abstract:
-#
-# Functions for relocating SMBASE's for all processors
-#
-#------------------------------------------------------------------------------
-
-ASM_GLOBAL ASM_PFX(gSmmCr0)
-ASM_GLOBAL ASM_PFX(gSmmCr3)
-ASM_GLOBAL ASM_PFX(gSmmCr4)
-ASM_GLOBAL ASM_PFX(gcSmmInitTemplate)
-ASM_GLOBAL ASM_PFX(gcSmmInitSize)
-ASM_GLOBAL ASM_PFX(gSmmJmpAddr)
-ASM_GLOBAL ASM_PFX(SmmRelocationSemaphoreComplete)
-ASM_GLOBAL ASM_PFX(gSmmInitStack)
-ASM_GLOBAL ASM_PFX(gcSmiInitGdtr)
-
-.equ PROTECT_MODE_CS, 0x08
-.equ PROTECT_MODE_DS, 0x20
-
- .text
-
-ASM_PFX(gcSmiInitGdtr):
- .word 0
- .quad 0
-
-SmmStartup:
- .byte 0x66,0xb8
-ASM_PFX(gSmmCr3): .space 4
- movl %eax, %cr3
- .byte 0x67,0x66
- lgdt %cs:(ASM_PFX(gcSmiInitGdtr) - SmmStartup)(%ebp)
- .byte 0x66,0xb8
-ASM_PFX(gSmmCr4): .space 4
- movl %eax, %cr4
- .byte 0x66,0xb8
-ASM_PFX(gSmmCr0): .space 4
- .byte 0xbf, PROTECT_MODE_DS, 0 # mov di, PROTECT_MODE_DS
- movl %eax, %cr0
- .byte 0x66,0xea # jmp far [ptr48]
-ASM_PFX(gSmmJmpAddr): .long Start32bit
- .word PROTECT_MODE_CS
-Start32bit:
- movl %edi,%ds
- movl %edi,%es
- movl %edi,%fs
- movl %edi,%gs
- movl %edi,%ss
- .byte 0xbc # mov esp, imm32
-ASM_PFX(gSmmInitStack): .space 4
- call ASM_PFX(SmmInitHandler)
- rsm
-
-ASM_PFX(gcSmmInitTemplate):
-
-_SmmInitTemplate:
- .byte 0x66
- movl $SmmStartup, %ebp
- .byte 0x66, 0x81, 0xed, 0, 0, 3, 0 # sub ebp, 0x30000
- jmp *%bp # jmp ebp actually
-
-ASM_PFX(gcSmmInitSize): .word . - ASM_PFX(gcSmmInitTemplate)
-
-
-ASM_PFX(SmmRelocationSemaphoreComplete):
- pushl %eax
- movl ASM_PFX(mRebasedFlag), %eax
- movb $1, (%eax)
- popl %eax
- jmp *ASM_PFX(mSmmRelocationOriginalAddress)
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.asm b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.asm
deleted file mode 100644
index 9ba2aebe69..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmInit.asm
+++ /dev/null
@@ -1,94 +0,0 @@
-;------------------------------------------------------------------------------ ;
-; 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.
-;
-; Module Name:
-;
-; SmmInit.Asm
-;
-; Abstract:
-;
-; Functions for relocating SMBASE's for all processors
-;
-;-------------------------------------------------------------------------------
-
- .686p
- .xmm
- .model flat,C
-
-SmmInitHandler PROTO C
-
-EXTERNDEF C gSmmCr0:DWORD
-EXTERNDEF C gSmmCr3:DWORD
-EXTERNDEF C gSmmCr4:DWORD
-EXTERNDEF C gcSmmInitTemplate:BYTE
-EXTERNDEF C gcSmmInitSize:WORD
-EXTERNDEF C gSmmJmpAddr:QWORD
-EXTERNDEF C mRebasedFlag:PTR BYTE
-EXTERNDEF C mSmmRelocationOriginalAddress:DWORD
-EXTERNDEF C gSmmInitStack:DWORD
-EXTERNDEF C gcSmiInitGdtr:FWORD
-
-PROTECT_MODE_CS EQU 08h
-PROTECT_MODE_DS EQU 20h
-
- .code
-
-gcSmiInitGdtr LABEL FWORD
- DW 0
- DQ 0
-
-SmmStartup PROC
- DB 66h, 0b8h
-gSmmCr3 DD ?
- mov cr3, eax
- DB 67h, 66h
- lgdt fword ptr cs:[ebp + (offset gcSmiInitGdtr - SmmStartup)]
- DB 66h, 0b8h
-gSmmCr4 DD ?
- mov cr4, eax
- DB 66h, 0b8h
-gSmmCr0 DD ?
- DB 0bfh, PROTECT_MODE_DS, 0 ; mov di, PROTECT_MODE_DS
- mov cr0, eax
- DB 66h, 0eah ; jmp far [ptr48]
-gSmmJmpAddr LABEL QWORD
- DD @32bit
- DW PROTECT_MODE_CS
-@32bit:
- mov ds, edi
- mov es, edi
- mov fs, edi
- mov gs, edi
- mov ss, edi
- DB 0bch ; mov esp, imm32
-gSmmInitStack DD ?
- call SmmInitHandler
- rsm
-SmmStartup ENDP
-
-gcSmmInitTemplate LABEL BYTE
-
-_SmmInitTemplate PROC
- DB 66h
- mov ebp, SmmStartup
- DB 66h, 81h, 0edh, 00h, 00h, 03h, 00 ; sub ebp, 30000h
- jmp bp ; jmp ebp actually
-_SmmInitTemplate ENDP
-
-gcSmmInitSize DW $ - gcSmmInitTemplate
-
-SmmRelocationSemaphoreComplete PROC
- push eax
- mov eax, mRebasedFlag
- mov byte ptr [eax], 1
- pop eax
- jmp [mSmmRelocationOriginalAddress]
-SmmRelocationSemaphoreComplete ENDP
- END
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c
deleted file mode 100644
index 767cb6908b..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/** @file
-IA-32 processor specific functions to enable SMM profile.
-
-Copyright (c) 2012 - 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"
-#include "SmmProfileInternal.h"
-
-/**
- Create SMM page table for S3 path.
-
-**/
-VOID
-InitSmmS3Cr3 (
- VOID
- )
-{
- mSmmS3ResumeState->SmmS3Cr3 = Gen4GPageTable (0, TRUE);
-
- return ;
-}
-
-/**
- Allocate pages for creating 4KB-page based on 2MB-page when page fault happens.
- 32-bit firmware does not need it.
-
-**/
-VOID
-InitPagesForPFHandler (
- VOID
- )
-{
-}
-
-/**
- Update page table to map the memory correctly in order to make the instruction
- which caused page fault execute successfully. And it also save the original page
- table to be restored in single-step exception. 32-bit firmware does not need it.
-
- @param PageTable PageTable Address.
- @param PFAddress The memory address which caused page fault exception.
- @param CpuIndex The index of the processor.
- @param ErrorCode The Error code of exception.
- @param IsValidPFAddress The flag indicates if SMM profile data need be added.
-
-**/
-VOID
-RestorePageTableAbove4G (
- UINT64 *PageTable,
- UINT64 PFAddress,
- UINTN CpuIndex,
- UINTN ErrorCode,
- BOOLEAN *IsValidPFAddress
- )
-{
-}
-
-/**
- Clear TF in FLAGS.
-
- @param SystemContext A pointer to the processor context when
- the interrupt occurred on the processor.
-
-**/
-VOID
-ClearTrapFlag (
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- SystemContext.SystemContextIa32->Eflags &= (UINTN) ~BIT8;
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h
deleted file mode 100644
index 3e15bffc60..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmProfileArch.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/** @file
-IA-32 processor specific header file to enable SMM profile.
-
-Copyright (c) 2012 - 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.
-
-**/
-
-#ifndef _SMM_PROFILE_ARCH_H_
-#define _SMM_PROFILE_ARCH_H_
-
-#pragma pack (1)
-
-typedef struct _MSR_DS_AREA_STRUCT {
- UINT32 BTSBufferBase;
- UINT32 BTSIndex;
- UINT32 BTSAbsoluteMaximum;
- UINT32 BTSInterruptThreshold;
- UINT32 PEBSBufferBase;
- UINT32 PEBSIndex;
- UINT32 PEBSAbsoluteMaximum;
- UINT32 PEBSInterruptThreshold;
- UINT32 PEBSCounterReset[4];
- UINT32 Reserved;
-} MSR_DS_AREA_STRUCT;
-
-typedef struct _BRANCH_TRACE_RECORD {
- UINT32 LastBranchFrom;
- UINT32 LastBranchTo;
- UINT32 Rsvd0 : 4;
- UINT32 BranchPredicted : 1;
- UINT32 Rsvd1 : 27;
-} BRANCH_TRACE_RECORD;
-
-typedef struct _PEBS_RECORD {
- UINT32 Eflags;
- UINT32 LinearIP;
- UINT32 Eax;
- UINT32 Ebx;
- UINT32 Ecx;
- UINT32 Edx;
- UINT32 Esi;
- UINT32 Edi;
- UINT32 Ebp;
- UINT32 Esp;
-} PEBS_RECORD;
-
-#pragma pack ()
-
-#define PHYSICAL_ADDRESS_MASK ((1ull << 32) - SIZE_4KB)
-
-/**
- Update page table to map the memory correctly in order to make the instruction
- which caused page fault execute successfully. And it also save the original page
- table to be restored in single-step exception. 32-bit firmware does not need it.
-
- @param PageTable PageTable Address.
- @param PFAddress The memory address which caused page fault exception.
- @param CpuIndex The index of the processor.
- @param ErrorCode The Error code of exception.
- @param IsValidPFAddress The flag indicates if SMM profile data need be added.
-
-**/
-VOID
-RestorePageTableAbove4G (
- UINT64 *PageTable,
- UINT64 PFAddress,
- UINTN CpuIndex,
- UINTN ErrorCode,
- BOOLEAN *IsValidPFAddress
- );
-
-/**
- Create SMM page table for S3 path.
-
-**/
-VOID
-InitSmmS3Cr3 (
- VOID
- );
-
-/**
- Allocate pages for creating 4KB-page based on 2MB-page when page fault happens.
-
-**/
-VOID
-InitPagesForPFHandler (
- VOID
- );
-
-#endif // _SMM_PROFILE_ARCH_H_
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c b/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
deleted file mode 100644
index f14b471bcf..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
+++ /dev/null
@@ -1,1410 +0,0 @@
-/** @file
-SMM MP service implementation
-
-Copyright (c) 2009 - 2016, 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"
-
-//
-// Slots for all MTRR( FIXED MTRR + VARIABLE MTRR + MTRR_LIB_IA32_MTRR_DEF_TYPE)
-//
-UINT64 gSmiMtrrs[MTRR_NUMBER_OF_FIXED_MTRR + 2 * MTRR_NUMBER_OF_VARIABLE_MTRR + 1];
-UINT64 gPhyMask;
-SMM_DISPATCHER_MP_SYNC_DATA *mSmmMpSyncData = NULL;
-UINTN mSmmMpSyncDataSize;
-SMM_CPU_SEMAPHORES mSmmCpuSemaphores;
-UINTN mSemaphoreSize;
-SPIN_LOCK *mPFLock = NULL;
-
-/**
- Performs an atomic compare exchange operation to get semaphore.
- The compare exchange operation must be performed using
- MP safe mechanisms.
-
- @param Sem IN: 32-bit unsigned integer
- OUT: original integer - 1
- @return Original integer - 1
-
-**/
-UINT32
-WaitForSemaphore (
- IN OUT volatile UINT32 *Sem
- )
-{
- UINT32 Value;
-
- do {
- Value = *Sem;
- } while (Value == 0 ||
- InterlockedCompareExchange32 (
- (UINT32*)Sem,
- Value,
- Value - 1
- ) != Value);
- return Value - 1;
-}
-
-
-/**
- Performs an atomic compare exchange operation to release semaphore.
- The compare exchange operation must be performed using
- MP safe mechanisms.
-
- @param Sem IN: 32-bit unsigned integer
- OUT: original integer + 1
- @return Original integer + 1
-
-**/
-UINT32
-ReleaseSemaphore (
- IN OUT volatile UINT32 *Sem
- )
-{
- UINT32 Value;
-
- do {
- Value = *Sem;
- } while (Value + 1 != 0 &&
- InterlockedCompareExchange32 (
- (UINT32*)Sem,
- Value,
- Value + 1
- ) != Value);
- return Value + 1;
-}
-
-/**
- Performs an atomic compare exchange operation to lock semaphore.
- The compare exchange operation must be performed using
- MP safe mechanisms.
-
- @param Sem IN: 32-bit unsigned integer
- OUT: -1
- @return Original integer
-
-**/
-UINT32
-LockdownSemaphore (
- IN OUT volatile UINT32 *Sem
- )
-{
- UINT32 Value;
-
- do {
- Value = *Sem;
- } while (InterlockedCompareExchange32 (
- (UINT32*)Sem,
- Value, (UINT32)-1
- ) != Value);
- return Value;
-}
-
-/**
- Wait all APs to performs an atomic compare exchange operation to release semaphore.
-
- @param NumberOfAPs AP number
-
-**/
-VOID
-WaitForAllAPs (
- IN UINTN NumberOfAPs
- )
-{
- UINTN BspIndex;
-
- BspIndex = mSmmMpSyncData->BspIndex;
- while (NumberOfAPs-- > 0) {
- WaitForSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);
- }
-}
-
-/**
- Performs an atomic compare exchange operation to release semaphore
- for each AP.
-
-**/
-VOID
-ReleaseAllAPs (
- VOID
- )
-{
- UINTN Index;
- UINTN BspIndex;
-
- BspIndex = mSmmMpSyncData->BspIndex;
- for (Index = mMaxNumberOfCpus; Index-- > 0;) {
- if (Index != BspIndex && *(mSmmMpSyncData->CpuData[Index].Present)) {
- ReleaseSemaphore (mSmmMpSyncData->CpuData[Index].Run);
- }
- }
-}
-
-/**
- Checks if all CPUs (with certain exceptions) have checked in for this SMI run
-
- @param Exceptions CPU Arrival exception flags.
-
- @retval TRUE if all CPUs the have checked in.
- @retval FALSE if at least one Normal AP hasn't checked in.
-
-**/
-BOOLEAN
-AllCpusInSmmWithExceptions (
- SMM_CPU_ARRIVAL_EXCEPTIONS Exceptions
- )
-{
- UINTN Index;
- SMM_CPU_DATA_BLOCK *CpuData;
- EFI_PROCESSOR_INFORMATION *ProcessorInfo;
-
- ASSERT (*mSmmMpSyncData->Counter <= mNumberOfCpus);
-
- if (*mSmmMpSyncData->Counter == mNumberOfCpus) {
- return TRUE;
- }
-
- CpuData = mSmmMpSyncData->CpuData;
- ProcessorInfo = gSmmCpuPrivate->ProcessorInfo;
- for (Index = mMaxNumberOfCpus; Index-- > 0;) {
- if (!(*(CpuData[Index].Present)) && ProcessorInfo[Index].ProcessorId != INVALID_APIC_ID) {
- if (((Exceptions & ARRIVAL_EXCEPTION_DELAYED) != 0) && SmmCpuFeaturesGetSmmRegister (Index, SmmRegSmmDelayed) != 0) {
- continue;
- }
- if (((Exceptions & ARRIVAL_EXCEPTION_BLOCKED) != 0) && SmmCpuFeaturesGetSmmRegister (Index, SmmRegSmmBlocked) != 0) {
- continue;
- }
- if (((Exceptions & ARRIVAL_EXCEPTION_SMI_DISABLED) != 0) && SmmCpuFeaturesGetSmmRegister (Index, SmmRegSmmEnable) != 0) {
- continue;
- }
- return FALSE;
- }
- }
-
-
- return TRUE;
-}
-
-
-/**
- Given timeout constraint, wait for all APs to arrive, and insure when this function returns, no AP will execute normal mode code before
- entering SMM, except SMI disabled APs.
-
-**/
-VOID
-SmmWaitForApArrival (
- VOID
- )
-{
- UINT64 Timer;
- UINTN Index;
-
- ASSERT (*mSmmMpSyncData->Counter <= mNumberOfCpus);
-
- //
- // Platform implementor should choose a timeout value appropriately:
- // - The timeout value should balance the SMM time constrains and the likelihood that delayed CPUs are excluded in the SMM run. Note
- // the SMI Handlers must ALWAYS take into account the cases that not all APs are available in an SMI run.
- // - The timeout value must, in the case of 2nd timeout, be at least long enough to give time for all APs to receive the SMI IPI
- // and either enter SMM or buffer the SMI, to insure there is no CPU running normal mode code when SMI handling starts. This will
- // be TRUE even if a blocked CPU is brought out of the blocked state by a normal mode CPU (before the normal mode CPU received the
- // SMI IPI), because with a buffered SMI, and CPU will enter SMM immediately after it is brought out of the blocked state.
- // - The timeout value must be longer than longest possible IO operation in the system
- //
-
- //
- // Sync with APs 1st timeout
- //
- for (Timer = StartSyncTimer ();
- !IsSyncTimerTimeout (Timer) &&
- !AllCpusInSmmWithExceptions (ARRIVAL_EXCEPTION_BLOCKED | ARRIVAL_EXCEPTION_SMI_DISABLED );
- ) {
- CpuPause ();
- }
-
- //
- // Not all APs have arrived, so we need 2nd round of timeout. IPIs should be sent to ALL none present APs,
- // because:
- // a) Delayed AP may have just come out of the delayed state. Blocked AP may have just been brought out of blocked state by some AP running
- // normal mode code. These APs need to be guaranteed to have an SMI pending to insure that once they are out of delayed / blocked state, they
- // enter SMI immediately without executing instructions in normal mode. Note traditional flow requires there are no APs doing normal mode
- // work while SMI handling is on-going.
- // b) As a consequence of SMI IPI sending, (spurious) SMI may occur after this SMM run.
- // c) ** NOTE **: Use SMI disabling feature VERY CAREFULLY (if at all) for traditional flow, because a processor in SMI-disabled state
- // will execute normal mode code, which breaks the traditional SMI handlers' assumption that no APs are doing normal
- // mode work while SMI handling is on-going.
- // d) We don't add code to check SMI disabling status to skip sending IPI to SMI disabled APs, because:
- // - In traditional flow, SMI disabling is discouraged.
- // - In relaxed flow, CheckApArrival() will check SMI disabling status before calling this function.
- // In both cases, adding SMI-disabling checking code increases overhead.
- //
- if (*mSmmMpSyncData->Counter < mNumberOfCpus) {
- //
- // Send SMI IPIs to bring outside processors in
- //
- for (Index = mMaxNumberOfCpus; Index-- > 0;) {
- if (!(*(mSmmMpSyncData->CpuData[Index].Present)) && gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId != INVALID_APIC_ID) {
- SendSmiIpi ((UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId);
- }
- }
-
- //
- // Sync with APs 2nd timeout.
- //
- for (Timer = StartSyncTimer ();
- !IsSyncTimerTimeout (Timer) &&
- !AllCpusInSmmWithExceptions (ARRIVAL_EXCEPTION_BLOCKED | ARRIVAL_EXCEPTION_SMI_DISABLED );
- ) {
- CpuPause ();
- }
- }
-
- return;
-}
-
-
-/**
- Replace OS MTRR's with SMI MTRR's.
-
- @param CpuIndex Processor Index
-
-**/
-VOID
-ReplaceOSMtrrs (
- IN UINTN CpuIndex
- )
-{
- PROCESSOR_SMM_DESCRIPTOR *Psd;
- UINT64 *SmiMtrrs;
- MTRR_SETTINGS *BiosMtrr;
-
- Psd = (PROCESSOR_SMM_DESCRIPTOR*)(mCpuHotPlugData.SmBase[CpuIndex] + SMM_PSD_OFFSET);
- SmiMtrrs = (UINT64*)(UINTN)Psd->MtrrBaseMaskPtr;
-
- SmmCpuFeaturesDisableSmrr ();
-
- //
- // Replace all MTRRs registers
- //
- BiosMtrr = (MTRR_SETTINGS*)SmiMtrrs;
- MtrrSetAllMtrrs(BiosMtrr);
-}
-
-/**
- SMI handler for BSP.
-
- @param CpuIndex BSP processor Index
- @param SyncMode SMM MP sync mode
-
-**/
-VOID
-BSPHandler (
- IN UINTN CpuIndex,
- IN SMM_CPU_SYNC_MODE SyncMode
- )
-{
- UINTN Index;
- MTRR_SETTINGS Mtrrs;
- UINTN ApCount;
- BOOLEAN ClearTopLevelSmiResult;
- UINTN PresentCount;
-
- ASSERT (CpuIndex == mSmmMpSyncData->BspIndex);
- ApCount = 0;
-
- //
- // Flag BSP's presence
- //
- *mSmmMpSyncData->InsideSmm = TRUE;
-
- //
- // Initialize Debug Agent to start source level debug in BSP handler
- //
- InitializeDebugAgent (DEBUG_AGENT_INIT_ENTER_SMI, NULL, NULL);
-
- //
- // Mark this processor's presence
- //
- *(mSmmMpSyncData->CpuData[CpuIndex].Present) = TRUE;
-
- //
- // Clear platform top level SMI status bit before calling SMI handlers. If
- // we cleared it after SMI handlers are run, we would miss the SMI that
- // occurs after SMI handlers are done and before SMI status bit is cleared.
- //
- ClearTopLevelSmiResult = ClearTopLevelSmiStatus();
- ASSERT (ClearTopLevelSmiResult == TRUE);
-
- //
- // Set running processor index
- //
- gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu = CpuIndex;
-
- //
- // If Traditional Sync Mode or need to configure MTRRs: gather all available APs.
- //
- if (SyncMode == SmmCpuSyncModeTradition || SmmCpuFeaturesNeedConfigureMtrrs()) {
-
- //
- // Wait for APs to arrive
- //
- SmmWaitForApArrival();
-
- //
- // Lock the counter down and retrieve the number of APs
- //
- *mSmmMpSyncData->AllCpusInSync = TRUE;
- ApCount = LockdownSemaphore (mSmmMpSyncData->Counter) - 1;
-
- //
- // Wait for all APs to get ready for programming MTRRs
- //
- WaitForAllAPs (ApCount);
-
- if (SmmCpuFeaturesNeedConfigureMtrrs()) {
- //
- // Signal all APs it's time for backup MTRRs
- //
- ReleaseAllAPs ();
-
- //
- // WaitForSemaphore() may wait for ever if an AP happens to enter SMM at
- // exactly this point. Please make sure PcdCpuSmmMaxSyncLoops has been set
- // to a large enough value to avoid this situation.
- // Note: For HT capable CPUs, threads within a core share the same set of MTRRs.
- // We do the backup first and then set MTRR to avoid race condition for threads
- // in the same core.
- //
- MtrrGetAllMtrrs(&Mtrrs);
-
- //
- // Wait for all APs to complete their MTRR saving
- //
- WaitForAllAPs (ApCount);
-
- //
- // Let all processors program SMM MTRRs together
- //
- ReleaseAllAPs ();
-
- //
- // WaitForSemaphore() may wait for ever if an AP happens to enter SMM at
- // exactly this point. Please make sure PcdCpuSmmMaxSyncLoops has been set
- // to a large enough value to avoid this situation.
- //
- ReplaceOSMtrrs (CpuIndex);
-
- //
- // Wait for all APs to complete their MTRR programming
- //
- WaitForAllAPs (ApCount);
- }
- }
-
- //
- // The BUSY lock is initialized to Acquired state
- //
- AcquireSpinLockOrFail (mSmmMpSyncData->CpuData[CpuIndex].Busy);
-
- //
- // Perform the pre tasks
- //
- PerformPreTasks ();
-
- //
- // Invoke SMM Foundation EntryPoint with the processor information context.
- //
- gSmmCpuPrivate->SmmCoreEntry (&gSmmCpuPrivate->SmmCoreEntryContext);
-
- //
- // Make sure all APs have completed their pending none-block tasks
- //
- for (Index = mMaxNumberOfCpus; Index-- > 0;) {
- if (Index != CpuIndex && *(mSmmMpSyncData->CpuData[Index].Present)) {
- AcquireSpinLock (mSmmMpSyncData->CpuData[Index].Busy);
- ReleaseSpinLock (mSmmMpSyncData->CpuData[Index].Busy);
- }
- }
-
- //
- // Perform the remaining tasks
- //
- PerformRemainingTasks ();
-
- //
- // If Relaxed-AP Sync Mode: gather all available APs after BSP SMM handlers are done, and
- // make those APs to exit SMI synchronously. APs which arrive later will be excluded and
- // will run through freely.
- //
- if (SyncMode != SmmCpuSyncModeTradition && !SmmCpuFeaturesNeedConfigureMtrrs()) {
-
- //
- // Lock the counter down and retrieve the number of APs
- //
- *mSmmMpSyncData->AllCpusInSync = TRUE;
- ApCount = LockdownSemaphore (mSmmMpSyncData->Counter) - 1;
- //
- // Make sure all APs have their Present flag set
- //
- while (TRUE) {
- PresentCount = 0;
- for (Index = mMaxNumberOfCpus; Index-- > 0;) {
- if (*(mSmmMpSyncData->CpuData[Index].Present)) {
- PresentCount ++;
- }
- }
- if (PresentCount > ApCount) {
- break;
- }
- }
- }
-
- //
- // Notify all APs to exit
- //
- *mSmmMpSyncData->InsideSmm = FALSE;
- ReleaseAllAPs ();
-
- //
- // Wait for all APs to complete their pending tasks
- //
- WaitForAllAPs (ApCount);
-
- if (SmmCpuFeaturesNeedConfigureMtrrs()) {
- //
- // Signal APs to restore MTRRs
- //
- ReleaseAllAPs ();
-
- //
- // Restore OS MTRRs
- //
- SmmCpuFeaturesReenableSmrr ();
- MtrrSetAllMtrrs(&Mtrrs);
-
- //
- // Wait for all APs to complete MTRR programming
- //
- WaitForAllAPs (ApCount);
- }
-
- //
- // Stop source level debug in BSP handler, the code below will not be
- // debugged.
- //
- InitializeDebugAgent (DEBUG_AGENT_INIT_EXIT_SMI, NULL, NULL);
-
- //
- // Signal APs to Reset states/semaphore for this processor
- //
- ReleaseAllAPs ();
-
- //
- // Perform pending operations for hot-plug
- //
- SmmCpuUpdate ();
-
- //
- // Clear the Present flag of BSP
- //
- *(mSmmMpSyncData->CpuData[CpuIndex].Present) = FALSE;
-
- //
- // Gather APs to exit SMM synchronously. Note the Present flag is cleared by now but
- // WaitForAllAps does not depend on the Present flag.
- //
- WaitForAllAPs (ApCount);
-
- //
- // Reset BspIndex to -1, meaning BSP has not been elected.
- //
- if (FeaturePcdGet (PcdCpuSmmEnableBspElection)) {
- mSmmMpSyncData->BspIndex = (UINT32)-1;
- }
-
- //
- // Allow APs to check in from this point on
- //
- *mSmmMpSyncData->Counter = 0;
- *mSmmMpSyncData->AllCpusInSync = FALSE;
-}
-
-/**
- SMI handler for AP.
-
- @param CpuIndex AP processor Index.
- @param ValidSmi Indicates that current SMI is a valid SMI or not.
- @param SyncMode SMM MP sync mode.
-
-**/
-VOID
-APHandler (
- IN UINTN CpuIndex,
- IN BOOLEAN ValidSmi,
- IN SMM_CPU_SYNC_MODE SyncMode
- )
-{
- UINT64 Timer;
- UINTN BspIndex;
- MTRR_SETTINGS Mtrrs;
-
- //
- // Timeout BSP
- //
- for (Timer = StartSyncTimer ();
- !IsSyncTimerTimeout (Timer) &&
- !(*mSmmMpSyncData->InsideSmm);
- ) {
- CpuPause ();
- }
-
- if (!(*mSmmMpSyncData->InsideSmm)) {
- //
- // BSP timeout in the first round
- //
- if (mSmmMpSyncData->BspIndex != -1) {
- //
- // BSP Index is known
- //
- BspIndex = mSmmMpSyncData->BspIndex;
- ASSERT (CpuIndex != BspIndex);
-
- //
- // Send SMI IPI to bring BSP in
- //
- SendSmiIpi ((UINT32)gSmmCpuPrivate->ProcessorInfo[BspIndex].ProcessorId);
-
- //
- // Now clock BSP for the 2nd time
- //
- for (Timer = StartSyncTimer ();
- !IsSyncTimerTimeout (Timer) &&
- !(*mSmmMpSyncData->InsideSmm);
- ) {
- CpuPause ();
- }
-
- if (!(*mSmmMpSyncData->InsideSmm)) {
- //
- // Give up since BSP is unable to enter SMM
- // and signal the completion of this AP
- WaitForSemaphore (mSmmMpSyncData->Counter);
- return;
- }
- } else {
- //
- // Don't know BSP index. Give up without sending IPI to BSP.
- //
- WaitForSemaphore (mSmmMpSyncData->Counter);
- return;
- }
- }
-
- //
- // BSP is available
- //
- BspIndex = mSmmMpSyncData->BspIndex;
- ASSERT (CpuIndex != BspIndex);
-
- //
- // Mark this processor's presence
- //
- *(mSmmMpSyncData->CpuData[CpuIndex].Present) = TRUE;
-
- if (SyncMode == SmmCpuSyncModeTradition || SmmCpuFeaturesNeedConfigureMtrrs()) {
- //
- // Notify BSP of arrival at this point
- //
- ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);
- }
-
- if (SmmCpuFeaturesNeedConfigureMtrrs()) {
- //
- // Wait for the signal from BSP to backup MTRRs
- //
- WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run);
-
- //
- // Backup OS MTRRs
- //
- MtrrGetAllMtrrs(&Mtrrs);
-
- //
- // Signal BSP the completion of this AP
- //
- ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);
-
- //
- // Wait for BSP's signal to program MTRRs
- //
- WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run);
-
- //
- // Replace OS MTRRs with SMI MTRRs
- //
- ReplaceOSMtrrs (CpuIndex);
-
- //
- // Signal BSP the completion of this AP
- //
- ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);
- }
-
- while (TRUE) {
- //
- // Wait for something to happen
- //
- WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run);
-
- //
- // Check if BSP wants to exit SMM
- //
- if (!(*mSmmMpSyncData->InsideSmm)) {
- break;
- }
-
- //
- // BUSY should be acquired by SmmStartupThisAp()
- //
- ASSERT (
- !AcquireSpinLockOrFail (mSmmMpSyncData->CpuData[CpuIndex].Busy)
- );
-
- //
- // Invoke the scheduled procedure
- //
- (*mSmmMpSyncData->CpuData[CpuIndex].Procedure) (
- (VOID*)mSmmMpSyncData->CpuData[CpuIndex].Parameter
- );
-
- //
- // Release BUSY
- //
- ReleaseSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);
- }
-
- if (SmmCpuFeaturesNeedConfigureMtrrs()) {
- //
- // Notify BSP the readiness of this AP to program MTRRs
- //
- ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);
-
- //
- // Wait for the signal from BSP to program MTRRs
- //
- WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run);
-
- //
- // Restore OS MTRRs
- //
- SmmCpuFeaturesReenableSmrr ();
- MtrrSetAllMtrrs(&Mtrrs);
- }
-
- //
- // Notify BSP the readiness of this AP to Reset states/semaphore for this processor
- //
- ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);
-
- //
- // Wait for the signal from BSP to Reset states/semaphore for this processor
- //
- WaitForSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run);
-
- //
- // Reset states/semaphore for this processor
- //
- *(mSmmMpSyncData->CpuData[CpuIndex].Present) = FALSE;
-
- //
- // Notify BSP the readiness of this AP to exit SMM
- //
- ReleaseSemaphore (mSmmMpSyncData->CpuData[BspIndex].Run);
-
-}
-
-/**
- Create 4G PageTable in SMRAM.
-
- @param ExtraPages Additional page numbers besides for 4G memory
- @param Is32BitPageTable Whether the page table is 32-bit PAE
- @return PageTable Address
-
-**/
-UINT32
-Gen4GPageTable (
- IN UINTN ExtraPages,
- IN BOOLEAN Is32BitPageTable
- )
-{
- VOID *PageTable;
- UINTN Index;
- UINT64 *Pte;
- UINTN PagesNeeded;
- UINTN Low2MBoundary;
- UINTN High2MBoundary;
- UINTN Pages;
- UINTN GuardPage;
- UINT64 *Pdpte;
- UINTN PageIndex;
- UINTN PageAddress;
-
- Low2MBoundary = 0;
- High2MBoundary = 0;
- PagesNeeded = 0;
- if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
- //
- // Add one more page for known good stack, then find the lower 2MB aligned address.
- //
- Low2MBoundary = (mSmmStackArrayBase + EFI_PAGE_SIZE) & ~(SIZE_2MB-1);
- //
- // Add two more pages for known good stack and stack guard page,
- // then find the lower 2MB aligned address.
- //
- High2MBoundary = (mSmmStackArrayEnd - mSmmStackSize + EFI_PAGE_SIZE * 2) & ~(SIZE_2MB-1);
- PagesNeeded = ((High2MBoundary - Low2MBoundary) / SIZE_2MB) + 1;
- }
- //
- // Allocate the page table
- //
- PageTable = AllocatePageTableMemory (ExtraPages + 5 + PagesNeeded);
- ASSERT (PageTable != NULL);
-
- PageTable = (VOID *)((UINTN)PageTable + EFI_PAGES_TO_SIZE (ExtraPages));
- Pte = (UINT64*)PageTable;
-
- //
- // Zero out all page table entries first
- //
- ZeroMem (Pte, EFI_PAGES_TO_SIZE (1));
-
- //
- // Set Page Directory Pointers
- //
- for (Index = 0; Index < 4; Index++) {
- Pte[Index] = (UINTN)PageTable + EFI_PAGE_SIZE * (Index + 1) + (Is32BitPageTable ? IA32_PAE_PDPTE_ATTRIBUTE_BITS : PAGE_ATTRIBUTE_BITS);
- }
- Pte += EFI_PAGE_SIZE / sizeof (*Pte);
-
- //
- // Fill in Page Directory Entries
- //
- for (Index = 0; Index < EFI_PAGE_SIZE * 4 / sizeof (*Pte); Index++) {
- Pte[Index] = (Index << 21) | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;
- }
-
- if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
- Pages = (UINTN)PageTable + EFI_PAGES_TO_SIZE (5);
- GuardPage = mSmmStackArrayBase + EFI_PAGE_SIZE;
- Pdpte = (UINT64*)PageTable;
- for (PageIndex = Low2MBoundary; PageIndex <= High2MBoundary; PageIndex += SIZE_2MB) {
- Pte = (UINT64*)(UINTN)(Pdpte[BitFieldRead32 ((UINT32)PageIndex, 30, 31)] & ~(EFI_PAGE_SIZE - 1));
- Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages | PAGE_ATTRIBUTE_BITS;
- //
- // Fill in Page Table Entries
- //
- Pte = (UINT64*)Pages;
- PageAddress = PageIndex;
- for (Index = 0; Index < EFI_PAGE_SIZE / sizeof (*Pte); Index++) {
- if (PageAddress == GuardPage) {
- //
- // Mark the guard page as non-present
- //
- Pte[Index] = PageAddress;
- GuardPage += mSmmStackSize;
- if (GuardPage > mSmmStackArrayEnd) {
- GuardPage = 0;
- }
- } else {
- Pte[Index] = PageAddress | PAGE_ATTRIBUTE_BITS;
- }
- PageAddress+= EFI_PAGE_SIZE;
- }
- Pages += EFI_PAGE_SIZE;
- }
- }
-
- return (UINT32)(UINTN)PageTable;
-}
-
-/**
- Set memory cache ability.
-
- @param PageTable PageTable Address
- @param Address Memory Address to change cache ability
- @param Cacheability Cache ability to set
-
-**/
-VOID
-SetCacheability (
- IN UINT64 *PageTable,
- IN UINTN Address,
- IN UINT8 Cacheability
- )
-{
- UINTN PTIndex;
- VOID *NewPageTableAddress;
- UINT64 *NewPageTable;
- UINTN Index;
-
- ASSERT ((Address & EFI_PAGE_MASK) == 0);
-
- if (sizeof (UINTN) == sizeof (UINT64)) {
- PTIndex = (UINTN)RShiftU64 (Address, 39) & 0x1ff;
- ASSERT (PageTable[PTIndex] & IA32_PG_P);
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);
- }
-
- PTIndex = (UINTN)RShiftU64 (Address, 30) & 0x1ff;
- ASSERT (PageTable[PTIndex] & IA32_PG_P);
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);
-
- //
- // A perfect implementation should check the original cacheability with the
- // one being set, and break a 2M page entry into pieces only when they
- // disagreed.
- //
- PTIndex = (UINTN)RShiftU64 (Address, 21) & 0x1ff;
- if ((PageTable[PTIndex] & IA32_PG_PS) != 0) {
- //
- // Allocate a page from SMRAM
- //
- NewPageTableAddress = AllocatePageTableMemory (1);
- ASSERT (NewPageTableAddress != NULL);
-
- NewPageTable = (UINT64 *)NewPageTableAddress;
-
- for (Index = 0; Index < 0x200; Index++) {
- NewPageTable[Index] = PageTable[PTIndex];
- if ((NewPageTable[Index] & IA32_PG_PAT_2M) != 0) {
- NewPageTable[Index] &= ~((UINT64)IA32_PG_PAT_2M);
- NewPageTable[Index] |= (UINT64)IA32_PG_PAT_4K;
- }
- NewPageTable[Index] |= (UINT64)(Index << EFI_PAGE_SHIFT);
- }
-
- PageTable[PTIndex] = ((UINTN)NewPageTableAddress & gPhyMask) | PAGE_ATTRIBUTE_BITS;
- }
-
- ASSERT (PageTable[PTIndex] & IA32_PG_P);
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);
-
- PTIndex = (UINTN)RShiftU64 (Address, 12) & 0x1ff;
- ASSERT (PageTable[PTIndex] & IA32_PG_P);
- PageTable[PTIndex] &= ~((UINT64)((IA32_PG_PAT_4K | IA32_PG_CD | IA32_PG_WT)));
- PageTable[PTIndex] |= (UINT64)Cacheability;
-}
-
-
-/**
- Schedule a procedure to run on the specified CPU.
-
- @param Procedure The address of the procedure to run
- @param CpuIndex Target CPU Index
- @param ProcArguments The parameter to pass to the procedure
-
- @retval EFI_INVALID_PARAMETER CpuNumber not valid
- @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP
- @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM
- @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy
- @retval EFI_SUCCESS The procedure has been successfully scheduled
-
-**/
-EFI_STATUS
-EFIAPI
-SmmStartupThisAp (
- IN EFI_AP_PROCEDURE Procedure,
- IN UINTN CpuIndex,
- IN OUT VOID *ProcArguments OPTIONAL
- )
-{
- if (CpuIndex >= gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus ||
- CpuIndex == gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu ||
- !(*(mSmmMpSyncData->CpuData[CpuIndex].Present)) ||
- gSmmCpuPrivate->Operation[CpuIndex] == SmmCpuRemove ||
- !AcquireSpinLockOrFail (mSmmMpSyncData->CpuData[CpuIndex].Busy)) {
- return EFI_INVALID_PARAMETER;
- }
-
- mSmmMpSyncData->CpuData[CpuIndex].Procedure = Procedure;
- mSmmMpSyncData->CpuData[CpuIndex].Parameter = ProcArguments;
- ReleaseSemaphore (mSmmMpSyncData->CpuData[CpuIndex].Run);
-
- if (FeaturePcdGet (PcdCpuSmmBlockStartupThisAp)) {
- AcquireSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);
- ReleaseSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);
- }
- return EFI_SUCCESS;
-}
-
-/**
- This function sets DR6 & DR7 according to SMM save state, before running SMM C code.
- They are useful when you want to enable hardware breakpoints in SMM without entry SMM mode.
-
- NOTE: It might not be appreciated in runtime since it might
- conflict with OS debugging facilities. Turn them off in RELEASE.
-
- @param CpuIndex CPU Index
-
-**/
-VOID
-EFIAPI
-CpuSmmDebugEntry (
- IN UINTN CpuIndex
- )
-{
- SMRAM_SAVE_STATE_MAP *CpuSaveState;
-
- if (FeaturePcdGet (PcdCpuSmmDebug)) {
- CpuSaveState = (SMRAM_SAVE_STATE_MAP *)gSmmCpuPrivate->CpuSaveState[CpuIndex];
- if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) {
- AsmWriteDr6 (CpuSaveState->x86._DR6);
- AsmWriteDr7 (CpuSaveState->x86._DR7);
- } else {
- AsmWriteDr6 ((UINTN)CpuSaveState->x64._DR6);
- AsmWriteDr7 ((UINTN)CpuSaveState->x64._DR7);
- }
- }
-}
-
-/**
- This function restores DR6 & DR7 to SMM save state.
-
- NOTE: It might not be appreciated in runtime since it might
- conflict with OS debugging facilities. Turn them off in RELEASE.
-
- @param CpuIndex CPU Index
-
-**/
-VOID
-EFIAPI
-CpuSmmDebugExit (
- IN UINTN CpuIndex
- )
-{
- SMRAM_SAVE_STATE_MAP *CpuSaveState;
-
- if (FeaturePcdGet (PcdCpuSmmDebug)) {
- CpuSaveState = (SMRAM_SAVE_STATE_MAP *)gSmmCpuPrivate->CpuSaveState[CpuIndex];
- if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) {
- CpuSaveState->x86._DR7 = (UINT32)AsmReadDr7 ();
- CpuSaveState->x86._DR6 = (UINT32)AsmReadDr6 ();
- } else {
- CpuSaveState->x64._DR7 = AsmReadDr7 ();
- CpuSaveState->x64._DR6 = AsmReadDr6 ();
- }
- }
-}
-
-/**
- C function for SMI entry, each processor comes here upon SMI trigger.
-
- @param CpuIndex CPU Index
-
-**/
-VOID
-EFIAPI
-SmiRendezvous (
- IN UINTN CpuIndex
- )
-{
- EFI_STATUS Status;
- BOOLEAN ValidSmi;
- BOOLEAN IsBsp;
- BOOLEAN BspInProgress;
- UINTN Index;
- UINTN Cr2;
- BOOLEAN XdDisableFlag;
-
- //
- // Save Cr2 because Page Fault exception in SMM may override its value
- //
- Cr2 = AsmReadCr2 ();
-
- //
- // Perform CPU specific entry hooks
- //
- SmmCpuFeaturesRendezvousEntry (CpuIndex);
-
- //
- // Determine if this is a valid SMI
- //
- ValidSmi = PlatformValidSmi();
-
- //
- // Determine if BSP has been already in progress. Note this must be checked after
- // ValidSmi because BSP may clear a valid SMI source after checking in.
- //
- BspInProgress = *mSmmMpSyncData->InsideSmm;
-
- if (!BspInProgress && !ValidSmi) {
- //
- // If we reach here, it means when we sampled the ValidSmi flag, SMI status had not
- // been cleared by BSP in a new SMI run (so we have a truly invalid SMI), or SMI
- // status had been cleared by BSP and an existing SMI run has almost ended. (Note
- // we sampled ValidSmi flag BEFORE judging BSP-in-progress status.) In both cases, there
- // is nothing we need to do.
- //
- goto Exit;
- } else {
- //
- // Signal presence of this processor
- //
- if (ReleaseSemaphore (mSmmMpSyncData->Counter) == 0) {
- //
- // BSP has already ended the synchronization, so QUIT!!!
- //
-
- //
- // Wait for BSP's signal to finish SMI
- //
- while (*mSmmMpSyncData->AllCpusInSync) {
- CpuPause ();
- }
- goto Exit;
- } else {
-
- //
- // The BUSY lock is initialized to Released state.
- // This needs to be done early enough to be ready for BSP's SmmStartupThisAp() call.
- // E.g., with Relaxed AP flow, SmmStartupThisAp() may be called immediately
- // after AP's present flag is detected.
- //
- InitializeSpinLock (mSmmMpSyncData->CpuData[CpuIndex].Busy);
- }
-
- //
- // Try to enable XD
- //
- XdDisableFlag = FALSE;
- if (mXdSupported) {
- if ((AsmReadMsr64 (MSR_IA32_MISC_ENABLE) & B_XD_DISABLE_BIT) != 0) {
- XdDisableFlag = TRUE;
- AsmMsrAnd64 (MSR_IA32_MISC_ENABLE, ~B_XD_DISABLE_BIT);
- }
- ActivateXd ();
- }
-
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
- ActivateSmmProfile (CpuIndex);
- }
-
- if (BspInProgress) {
- //
- // BSP has been elected. Follow AP path, regardless of ValidSmi flag
- // as BSP may have cleared the SMI status
- //
- APHandler (CpuIndex, ValidSmi, mSmmMpSyncData->EffectiveSyncMode);
- } else {
- //
- // We have a valid SMI
- //
-
- //
- // Elect BSP
- //
- IsBsp = FALSE;
- if (FeaturePcdGet (PcdCpuSmmEnableBspElection)) {
- if (!mSmmMpSyncData->SwitchBsp || mSmmMpSyncData->CandidateBsp[CpuIndex]) {
- //
- // Call platform hook to do BSP election
- //
- Status = PlatformSmmBspElection (&IsBsp);
- if (EFI_SUCCESS == Status) {
- //
- // Platform hook determines successfully
- //
- if (IsBsp) {
- mSmmMpSyncData->BspIndex = (UINT32)CpuIndex;
- }
- } else {
- //
- // Platform hook fails to determine, use default BSP election method
- //
- InterlockedCompareExchange32 (
- (UINT32*)&mSmmMpSyncData->BspIndex,
- (UINT32)-1,
- (UINT32)CpuIndex
- );
- }
- }
- }
-
- //
- // "mSmmMpSyncData->BspIndex == CpuIndex" means this is the BSP
- //
- if (mSmmMpSyncData->BspIndex == CpuIndex) {
-
- //
- // Clear last request for SwitchBsp.
- //
- if (mSmmMpSyncData->SwitchBsp) {
- mSmmMpSyncData->SwitchBsp = FALSE;
- for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
- mSmmMpSyncData->CandidateBsp[Index] = FALSE;
- }
- }
-
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
- SmmProfileRecordSmiNum ();
- }
-
- //
- // BSP Handler is always called with a ValidSmi == TRUE
- //
- BSPHandler (CpuIndex, mSmmMpSyncData->EffectiveSyncMode);
- } else {
- APHandler (CpuIndex, ValidSmi, mSmmMpSyncData->EffectiveSyncMode);
- }
- }
-
- ASSERT (*mSmmMpSyncData->CpuData[CpuIndex].Run == 0);
-
- //
- // Wait for BSP's signal to exit SMI
- //
- while (*mSmmMpSyncData->AllCpusInSync) {
- CpuPause ();
- }
-
- //
- // Restore XD
- //
- if (XdDisableFlag) {
- AsmMsrOr64 (MSR_IA32_MISC_ENABLE, B_XD_DISABLE_BIT);
- }
- }
-
-Exit:
- SmmCpuFeaturesRendezvousExit (CpuIndex);
- //
- // Restore Cr2
- //
- AsmWriteCr2 (Cr2);
-}
-
-/**
- Allocate buffer for all semaphores and spin locks.
-
-**/
-VOID
-InitializeSmmCpuSemaphores (
- VOID
- )
-{
- UINTN ProcessorCount;
- UINTN TotalSize;
- UINTN GlobalSemaphoresSize;
- UINTN CpuSemaphoresSize;
- UINTN MsrSemahporeSize;
- UINTN SemaphoreSize;
- UINTN Pages;
- UINTN *SemaphoreBlock;
- UINTN SemaphoreAddr;
-
- SemaphoreSize = GetSpinLockProperties ();
- ProcessorCount = gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;
- GlobalSemaphoresSize = (sizeof (SMM_CPU_SEMAPHORE_GLOBAL) / sizeof (VOID *)) * SemaphoreSize;
- CpuSemaphoresSize = (sizeof (SMM_CPU_SEMAPHORE_CPU) / sizeof (VOID *)) * ProcessorCount * SemaphoreSize;
- MsrSemahporeSize = MSR_SPIN_LOCK_INIT_NUM * SemaphoreSize;
- TotalSize = GlobalSemaphoresSize + CpuSemaphoresSize + MsrSemahporeSize;
- DEBUG((EFI_D_INFO, "One Semaphore Size = 0x%x\n", SemaphoreSize));
- DEBUG((EFI_D_INFO, "Total Semaphores Size = 0x%x\n", TotalSize));
- Pages = EFI_SIZE_TO_PAGES (TotalSize);
- SemaphoreBlock = AllocatePages (Pages);
- ASSERT (SemaphoreBlock != NULL);
- ZeroMem (SemaphoreBlock, TotalSize);
-
- SemaphoreAddr = (UINTN)SemaphoreBlock;
- mSmmCpuSemaphores.SemaphoreGlobal.Counter = (UINT32 *)SemaphoreAddr;
- SemaphoreAddr += SemaphoreSize;
- mSmmCpuSemaphores.SemaphoreGlobal.InsideSmm = (BOOLEAN *)SemaphoreAddr;
- SemaphoreAddr += SemaphoreSize;
- mSmmCpuSemaphores.SemaphoreGlobal.AllCpusInSync = (BOOLEAN *)SemaphoreAddr;
- SemaphoreAddr += SemaphoreSize;
- mSmmCpuSemaphores.SemaphoreGlobal.PFLock = (SPIN_LOCK *)SemaphoreAddr;
- SemaphoreAddr += SemaphoreSize;
- mSmmCpuSemaphores.SemaphoreGlobal.CodeAccessCheckLock
- = (SPIN_LOCK *)SemaphoreAddr;
- SemaphoreAddr = (UINTN)SemaphoreBlock + GlobalSemaphoresSize;
- mSmmCpuSemaphores.SemaphoreCpu.Busy = (SPIN_LOCK *)SemaphoreAddr;
- SemaphoreAddr += ProcessorCount * SemaphoreSize;
- mSmmCpuSemaphores.SemaphoreCpu.Run = (UINT32 *)SemaphoreAddr;
- SemaphoreAddr += ProcessorCount * SemaphoreSize;
- mSmmCpuSemaphores.SemaphoreCpu.Present = (BOOLEAN *)SemaphoreAddr;
-
- SemaphoreAddr = (UINTN)SemaphoreBlock + GlobalSemaphoresSize + CpuSemaphoresSize;
- mSmmCpuSemaphores.SemaphoreMsr.Msr = (SPIN_LOCK *)SemaphoreAddr;
- mSmmCpuSemaphores.SemaphoreMsr.AvailableCounter =
- ((UINTN)SemaphoreBlock + Pages * SIZE_4KB - SemaphoreAddr) / SemaphoreSize;
- ASSERT (mSmmCpuSemaphores.SemaphoreMsr.AvailableCounter >= MSR_SPIN_LOCK_INIT_NUM);
-
- mPFLock = mSmmCpuSemaphores.SemaphoreGlobal.PFLock;
- mConfigSmmCodeAccessCheckLock = mSmmCpuSemaphores.SemaphoreGlobal.CodeAccessCheckLock;
-
- mSemaphoreSize = SemaphoreSize;
-}
-
-/**
- Initialize un-cacheable data.
-
-**/
-VOID
-EFIAPI
-InitializeMpSyncData (
- VOID
- )
-{
- UINTN CpuIndex;
-
- if (mSmmMpSyncData != NULL) {
- //
- // mSmmMpSyncDataSize includes one structure of SMM_DISPATCHER_MP_SYNC_DATA, one
- // CpuData array of SMM_CPU_DATA_BLOCK and one CandidateBsp array of BOOLEAN.
- //
- ZeroMem (mSmmMpSyncData, mSmmMpSyncDataSize);
- mSmmMpSyncData->CpuData = (SMM_CPU_DATA_BLOCK *)((UINT8 *)mSmmMpSyncData + sizeof (SMM_DISPATCHER_MP_SYNC_DATA));
- mSmmMpSyncData->CandidateBsp = (BOOLEAN *)(mSmmMpSyncData->CpuData + gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus);
- if (FeaturePcdGet (PcdCpuSmmEnableBspElection)) {
- //
- // Enable BSP election by setting BspIndex to -1
- //
- mSmmMpSyncData->BspIndex = (UINT32)-1;
- }
- mSmmMpSyncData->EffectiveSyncMode = (SMM_CPU_SYNC_MODE) PcdGet8 (PcdCpuSmmSyncMode);
-
- mSmmMpSyncData->Counter = mSmmCpuSemaphores.SemaphoreGlobal.Counter;
- mSmmMpSyncData->InsideSmm = mSmmCpuSemaphores.SemaphoreGlobal.InsideSmm;
- mSmmMpSyncData->AllCpusInSync = mSmmCpuSemaphores.SemaphoreGlobal.AllCpusInSync;
- ASSERT (mSmmMpSyncData->Counter != NULL && mSmmMpSyncData->InsideSmm != NULL &&
- mSmmMpSyncData->AllCpusInSync != NULL);
- *mSmmMpSyncData->Counter = 0;
- *mSmmMpSyncData->InsideSmm = FALSE;
- *mSmmMpSyncData->AllCpusInSync = FALSE;
-
- for (CpuIndex = 0; CpuIndex < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; CpuIndex ++) {
- mSmmMpSyncData->CpuData[CpuIndex].Busy =
- (SPIN_LOCK *)((UINTN)mSmmCpuSemaphores.SemaphoreCpu.Busy + mSemaphoreSize * CpuIndex);
- mSmmMpSyncData->CpuData[CpuIndex].Run =
- (UINT32 *)((UINTN)mSmmCpuSemaphores.SemaphoreCpu.Run + mSemaphoreSize * CpuIndex);
- mSmmMpSyncData->CpuData[CpuIndex].Present =
- (BOOLEAN *)((UINTN)mSmmCpuSemaphores.SemaphoreCpu.Present + mSemaphoreSize * CpuIndex);
- }
- }
-}
-
-/**
- Initialize global data for MP synchronization.
-
- @param Stacks Base address of SMI stack buffer for all processors.
- @param StackSize Stack size for each processor in SMM.
-
-**/
-UINT32
-InitializeMpServiceData (
- IN VOID *Stacks,
- IN UINTN StackSize
- )
-{
- UINT32 Cr3;
- UINTN Index;
- MTRR_SETTINGS *Mtrr;
- PROCESSOR_SMM_DESCRIPTOR *Psd;
- UINT8 *GdtTssTables;
- UINTN GdtTableStepSize;
-
- //
- // Allocate memory for all locks and semaphores
- //
- InitializeSmmCpuSemaphores ();
-
- //
- // Initialize mSmmMpSyncData
- //
- mSmmMpSyncDataSize = sizeof (SMM_DISPATCHER_MP_SYNC_DATA) +
- (sizeof (SMM_CPU_DATA_BLOCK) + sizeof (BOOLEAN)) * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;
- mSmmMpSyncData = (SMM_DISPATCHER_MP_SYNC_DATA*) AllocatePages (EFI_SIZE_TO_PAGES (mSmmMpSyncDataSize));
- ASSERT (mSmmMpSyncData != NULL);
- InitializeMpSyncData ();
-
- //
- // Initialize physical address mask
- // NOTE: Physical memory above virtual address limit is not supported !!!
- //
- AsmCpuid (0x80000008, (UINT32*)&Index, NULL, NULL, NULL);
- gPhyMask = LShiftU64 (1, (UINT8)Index) - 1;
- gPhyMask &= (1ull << 48) - EFI_PAGE_SIZE;
-
- //
- // Create page tables
- //
- Cr3 = SmmInitPageTable ();
-
- GdtTssTables = InitGdt (Cr3, &GdtTableStepSize);
-
- //
- // Initialize PROCESSOR_SMM_DESCRIPTOR for each CPU
- //
- for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
- Psd = (PROCESSOR_SMM_DESCRIPTOR *)(VOID *)(UINTN)(mCpuHotPlugData.SmBase[Index] + SMM_PSD_OFFSET);
- CopyMem (Psd, &gcPsd, sizeof (gcPsd));
- Psd->SmmGdtPtr = (UINT64)(UINTN)(GdtTssTables + GdtTableStepSize * Index);
- Psd->SmmGdtSize = gcSmiGdtr.Limit + 1;
-
- //
- // Install SMI handler
- //
- InstallSmiHandler (
- Index,
- (UINT32)mCpuHotPlugData.SmBase[Index],
- (VOID*)((UINTN)Stacks + (StackSize * Index)),
- StackSize,
- (UINTN)Psd->SmmGdtPtr,
- Psd->SmmGdtSize,
- gcSmiIdtr.Base,
- gcSmiIdtr.Limit + 1,
- Cr3
- );
- }
-
- //
- // Record current MTRR settings
- //
- ZeroMem(gSmiMtrrs, sizeof (gSmiMtrrs));
- Mtrr = (MTRR_SETTINGS*)gSmiMtrrs;
- MtrrGetAllMtrrs (Mtrr);
-
- return Cr3;
-}
-
-/**
-
- Register the SMM Foundation entry point.
-
- @param This Pointer to EFI_SMM_CONFIGURATION_PROTOCOL instance
- @param SmmEntryPoint SMM Foundation EntryPoint
-
- @retval EFI_SUCCESS Successfully to register SMM foundation entry point
-
-**/
-EFI_STATUS
-EFIAPI
-RegisterSmmEntry (
- IN CONST EFI_SMM_CONFIGURATION_PROTOCOL *This,
- IN EFI_SMM_ENTRY_POINT SmmEntryPoint
- )
-{
- //
- // Record SMM Foundation EntryPoint, later invoke it on SMI entry vector.
- //
- gSmmCpuPrivate->SmmCoreEntry = SmmEntryPoint;
- return EFI_SUCCESS;
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
deleted file mode 100644
index 8b3bb343ce..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.c
+++ /dev/null
@@ -1,1517 +0,0 @@
-/** @file
-Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.
-
-Copyright (c) 2009 - 2016, 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"
-
-//
-// SMM CPU Private Data structure that contains SMM Configuration Protocol
-// along its supporting fields.
-//
-SMM_CPU_PRIVATE_DATA mSmmCpuPrivateData = {
- SMM_CPU_PRIVATE_DATA_SIGNATURE, // Signature
- NULL, // SmmCpuHandle
- NULL, // Pointer to ProcessorInfo array
- NULL, // Pointer to Operation array
- NULL, // Pointer to CpuSaveStateSize array
- NULL, // Pointer to CpuSaveState array
- { {0} }, // SmmReservedSmramRegion
- {
- SmmStartupThisAp, // SmmCoreEntryContext.SmmStartupThisAp
- 0, // SmmCoreEntryContext.CurrentlyExecutingCpu
- 0, // SmmCoreEntryContext.NumberOfCpus
- NULL, // SmmCoreEntryContext.CpuSaveStateSize
- NULL // SmmCoreEntryContext.CpuSaveState
- },
- NULL, // SmmCoreEntry
- {
- mSmmCpuPrivateData.SmmReservedSmramRegion, // SmmConfiguration.SmramReservedRegions
- RegisterSmmEntry // SmmConfiguration.RegisterSmmEntry
- },
-};
-
-CPU_HOT_PLUG_DATA mCpuHotPlugData = {
- CPU_HOT_PLUG_DATA_REVISION_1, // Revision
- 0, // Array Length of SmBase and APIC ID
- NULL, // Pointer to APIC ID array
- NULL, // Pointer to SMBASE array
- 0, // Reserved
- 0, // SmrrBase
- 0 // SmrrSize
-};
-
-//
-// Global pointer used to access mSmmCpuPrivateData from outside and inside SMM
-//
-SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate = &mSmmCpuPrivateData;
-
-//
-// SMM Relocation variables
-//
-volatile BOOLEAN *mRebased;
-volatile BOOLEAN mIsBsp;
-
-///
-/// Handle for the SMM CPU Protocol
-///
-EFI_HANDLE mSmmCpuHandle = NULL;
-
-///
-/// SMM CPU Protocol instance
-///
-EFI_SMM_CPU_PROTOCOL mSmmCpu = {
- SmmReadSaveState,
- SmmWriteSaveState
-};
-
-EFI_CPU_INTERRUPT_HANDLER mExternalVectorTable[EXCEPTION_VECTOR_NUMBER];
-
-//
-// SMM stack information
-//
-UINTN mSmmStackArrayBase;
-UINTN mSmmStackArrayEnd;
-UINTN mSmmStackSize;
-
-//
-// Pointer to structure used during S3 Resume
-//
-SMM_S3_RESUME_STATE *mSmmS3ResumeState = NULL;
-
-UINTN mMaxNumberOfCpus = 1;
-UINTN mNumberOfCpus = 1;
-
-//
-// SMM ready to lock flag
-//
-BOOLEAN mSmmReadyToLock = FALSE;
-
-//
-// Global used to cache PCD for SMM Code Access Check enable
-//
-BOOLEAN mSmmCodeAccessCheckEnable = FALSE;
-
-//
-// Spin lock used to serialize setting of SMM Code Access Check feature
-//
-SPIN_LOCK *mConfigSmmCodeAccessCheckLock = NULL;
-
-/**
- Initialize IDT to setup exception handlers for SMM.
-
-**/
-VOID
-InitializeSmmIdt (
- VOID
- )
-{
- EFI_STATUS Status;
- BOOLEAN InterruptState;
- IA32_DESCRIPTOR DxeIdtr;
- //
- // Disable Interrupt and save DXE IDT table
- //
- InterruptState = SaveAndDisableInterrupts ();
- AsmReadIdtr (&DxeIdtr);
- //
- // Load SMM temporary IDT table
- //
- AsmWriteIdtr (&gcSmiIdtr);
- //
- // Setup SMM default exception handlers, SMM IDT table
- // will be updated and saved in gcSmiIdtr
- //
- Status = InitializeCpuExceptionHandlers (NULL);
- ASSERT_EFI_ERROR (Status);
- //
- // Restore DXE IDT table and CPU interrupt
- //
- AsmWriteIdtr ((IA32_DESCRIPTOR *) &DxeIdtr);
- SetInterruptState (InterruptState);
-}
-
-/**
- Search module name by input IP address and output it.
-
- @param CallerIpAddress Caller instruction pointer.
-
-**/
-VOID
-DumpModuleInfoByIp (
- IN UINTN CallerIpAddress
- )
-{
- UINTN Pe32Data;
- EFI_IMAGE_DOS_HEADER *DosHdr;
- EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
- VOID *PdbPointer;
- UINT64 DumpIpAddress;
-
- //
- // Find Image Base
- //
- Pe32Data = CallerIpAddress & ~(SIZE_4KB - 1);
- while (Pe32Data != 0) {
- DosHdr = (EFI_IMAGE_DOS_HEADER *) Pe32Data;
- if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
- //
- // DOS image header is present, so read the PE header after the DOS image header.
- //
- Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)(Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));
- //
- // Make sure PE header address does not overflow and is less than the initial address.
- //
- if (((UINTN)Hdr.Pe32 > Pe32Data) && ((UINTN)Hdr.Pe32 < CallerIpAddress)) {
- if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
- //
- // It's PE image.
- //
- break;
- }
- }
- }
-
- //
- // Not found the image base, check the previous aligned address
- //
- Pe32Data -= SIZE_4KB;
- }
-
- DumpIpAddress = CallerIpAddress;
- DEBUG ((EFI_D_ERROR, "It is invoked from the instruction before IP(0x%lx)", DumpIpAddress));
-
- if (Pe32Data != 0) {
- PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *) Pe32Data);
- if (PdbPointer != NULL) {
- DEBUG ((EFI_D_ERROR, " in module (%a)", PdbPointer));
- }
- }
-}
-
-/**
- Read information from the CPU save state.
-
- @param This EFI_SMM_CPU_PROTOCOL instance
- @param Width The number of bytes to read from the CPU save state.
- @param Register Specifies the CPU register to read form the save state.
- @param CpuIndex Specifies the zero-based index of the CPU save state.
- @param Buffer Upon return, this holds the CPU register value read from the save state.
-
- @retval EFI_SUCCESS The register was read from Save State
- @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
- @retval EFI_INVALID_PARAMTER This or Buffer is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-SmmReadSaveState (
- IN CONST EFI_SMM_CPU_PROTOCOL *This,
- IN UINTN Width,
- IN EFI_SMM_SAVE_STATE_REGISTER Register,
- IN UINTN CpuIndex,
- OUT VOID *Buffer
- )
-{
- EFI_STATUS Status;
-
- //
- // Retrieve pointer to the specified CPU's SMM Save State buffer
- //
- if ((CpuIndex >= gSmst->NumberOfCpus) || (Buffer == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Check for special EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID
- //
- if (Register == EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID) {
- //
- // The pseudo-register only supports the 64-bit size specified by Width.
- //
- if (Width != sizeof (UINT64)) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // If the processor is in SMM at the time the SMI occurred,
- // the pseudo register value for EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID is returned in Buffer.
- // Otherwise, EFI_NOT_FOUND is returned.
- //
- if (*(mSmmMpSyncData->CpuData[CpuIndex].Present)) {
- *(UINT64 *)Buffer = gSmmCpuPrivate->ProcessorInfo[CpuIndex].ProcessorId;
- return EFI_SUCCESS;
- } else {
- return EFI_NOT_FOUND;
- }
- }
-
- if (!(*(mSmmMpSyncData->CpuData[CpuIndex].Present))) {
- return EFI_INVALID_PARAMETER;
- }
-
- Status = SmmCpuFeaturesReadSaveStateRegister (CpuIndex, Register, Width, Buffer);
- if (Status == EFI_UNSUPPORTED) {
- Status = ReadSaveStateRegister (CpuIndex, Register, Width, Buffer);
- }
- return Status;
-}
-
-/**
- Write data to the CPU save state.
-
- @param This EFI_SMM_CPU_PROTOCOL instance
- @param Width The number of bytes to read from the CPU save state.
- @param Register Specifies the CPU register to write to the save state.
- @param CpuIndex Specifies the zero-based index of the CPU save state
- @param Buffer Upon entry, this holds the new CPU register value.
-
- @retval EFI_SUCCESS The register was written from Save State
- @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
- @retval EFI_INVALID_PARAMTER ProcessorIndex or Width is not correct
-
-**/
-EFI_STATUS
-EFIAPI
-SmmWriteSaveState (
- IN CONST EFI_SMM_CPU_PROTOCOL *This,
- IN UINTN Width,
- IN EFI_SMM_SAVE_STATE_REGISTER Register,
- IN UINTN CpuIndex,
- IN CONST VOID *Buffer
- )
-{
- EFI_STATUS Status;
-
- //
- // Retrieve pointer to the specified CPU's SMM Save State buffer
- //
- if ((CpuIndex >= gSmst->NumberOfCpus) || (Buffer == NULL)) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Writes to EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID are ignored
- //
- if (Register == EFI_SMM_SAVE_STATE_REGISTER_PROCESSOR_ID) {
- return EFI_SUCCESS;
- }
-
- if (!mSmmMpSyncData->CpuData[CpuIndex].Present) {
- return EFI_INVALID_PARAMETER;
- }
-
- Status = SmmCpuFeaturesWriteSaveStateRegister (CpuIndex, Register, Width, Buffer);
- if (Status == EFI_UNSUPPORTED) {
- Status = WriteSaveStateRegister (CpuIndex, Register, Width, Buffer);
- }
- return Status;
-}
-
-
-/**
- C function for SMI handler. To change all processor's SMMBase Register.
-
-**/
-VOID
-EFIAPI
-SmmInitHandler (
- VOID
- )
-{
- UINT32 ApicId;
- UINTN Index;
-
- //
- // Update SMM IDT entries' code segment and load IDT
- //
- AsmWriteIdtr (&gcSmiIdtr);
- ApicId = GetApicId ();
-
- ASSERT (mNumberOfCpus <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
-
- for (Index = 0; Index < mNumberOfCpus; Index++) {
- if (ApicId == (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId) {
- //
- // Initialize SMM specific features on the currently executing CPU
- //
- SmmCpuFeaturesInitializeProcessor (
- Index,
- mIsBsp,
- gSmmCpuPrivate->ProcessorInfo,
- &mCpuHotPlugData
- );
-
- if (mIsBsp) {
- //
- // BSP rebase is already done above.
- // Initialize private data during S3 resume
- //
- InitializeMpSyncData ();
- }
-
- //
- // Hook return after RSM to set SMM re-based flag
- //
- SemaphoreHook (Index, &mRebased[Index]);
-
- return;
- }
- }
- ASSERT (FALSE);
-}
-
-/**
- Relocate SmmBases for each processor.
-
- Execute on first boot and all S3 resumes
-
-**/
-VOID
-EFIAPI
-SmmRelocateBases (
- VOID
- )
-{
- UINT8 BakBuf[BACK_BUF_SIZE];
- SMRAM_SAVE_STATE_MAP BakBuf2;
- SMRAM_SAVE_STATE_MAP *CpuStatePtr;
- UINT8 *U8Ptr;
- UINT32 ApicId;
- UINTN Index;
- UINTN BspIndex;
-
- //
- // Make sure the reserved size is large enough for procedure SmmInitTemplate.
- //
- ASSERT (sizeof (BakBuf) >= gcSmmInitSize);
-
- //
- // Patch ASM code template with current CR0, CR3, and CR4 values
- //
- gSmmCr0 = (UINT32)AsmReadCr0 ();
- gSmmCr3 = (UINT32)AsmReadCr3 ();
- gSmmCr4 = (UINT32)AsmReadCr4 ();
-
- //
- // Patch GDTR for SMM base relocation
- //
- gcSmiInitGdtr.Base = gcSmiGdtr.Base;
- gcSmiInitGdtr.Limit = gcSmiGdtr.Limit;
-
- U8Ptr = (UINT8*)(UINTN)(SMM_DEFAULT_SMBASE + SMM_HANDLER_OFFSET);
- CpuStatePtr = (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
-
- //
- // Backup original contents at address 0x38000
- //
- CopyMem (BakBuf, U8Ptr, sizeof (BakBuf));
- CopyMem (&BakBuf2, CpuStatePtr, sizeof (BakBuf2));
-
- //
- // Load image for relocation
- //
- CopyMem (U8Ptr, gcSmmInitTemplate, gcSmmInitSize);
-
- //
- // Retrieve the local APIC ID of current processor
- //
- ApicId = GetApicId ();
-
- //
- // Relocate SM bases for all APs
- // This is APs' 1st SMI - rebase will be done here, and APs' default SMI handler will be overridden by gcSmmInitTemplate
- //
- mIsBsp = FALSE;
- BspIndex = (UINTN)-1;
- for (Index = 0; Index < mNumberOfCpus; Index++) {
- mRebased[Index] = FALSE;
- if (ApicId != (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId) {
- SendSmiIpi ((UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId);
- //
- // Wait for this AP to finish its 1st SMI
- //
- while (!mRebased[Index]);
- } else {
- //
- // BSP will be Relocated later
- //
- BspIndex = Index;
- }
- }
-
- //
- // Relocate BSP's SMM base
- //
- ASSERT (BspIndex != (UINTN)-1);
- mIsBsp = TRUE;
- SendSmiIpi (ApicId);
- //
- // Wait for the BSP to finish its 1st SMI
- //
- while (!mRebased[BspIndex]);
-
- //
- // Restore contents at address 0x38000
- //
- CopyMem (CpuStatePtr, &BakBuf2, sizeof (BakBuf2));
- CopyMem (U8Ptr, BakBuf, sizeof (BakBuf));
-}
-
-/**
- Perform SMM initialization for all processors in the S3 boot path.
-
- For a native platform, MP initialization in the S3 boot path is also performed in this function.
-**/
-VOID
-EFIAPI
-SmmRestoreCpu (
- VOID
- )
-{
- SMM_S3_RESUME_STATE *SmmS3ResumeState;
- IA32_DESCRIPTOR Ia32Idtr;
- IA32_DESCRIPTOR X64Idtr;
- IA32_IDT_GATE_DESCRIPTOR IdtEntryTable[EXCEPTION_VECTOR_NUMBER];
- EFI_STATUS Status;
-
- DEBUG ((EFI_D_INFO, "SmmRestoreCpu()\n"));
-
- //
- // See if there is enough context to resume PEI Phase
- //
- if (mSmmS3ResumeState == NULL) {
- DEBUG ((EFI_D_ERROR, "No context to return to PEI Phase\n"));
- CpuDeadLoop ();
- }
-
- SmmS3ResumeState = mSmmS3ResumeState;
- ASSERT (SmmS3ResumeState != NULL);
-
- if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_64) {
- //
- // Save the IA32 IDT Descriptor
- //
- AsmReadIdtr ((IA32_DESCRIPTOR *) &Ia32Idtr);
-
- //
- // Setup X64 IDT table
- //
- ZeroMem (IdtEntryTable, sizeof (IA32_IDT_GATE_DESCRIPTOR) * 32);
- X64Idtr.Base = (UINTN) IdtEntryTable;
- X64Idtr.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 32 - 1);
- AsmWriteIdtr ((IA32_DESCRIPTOR *) &X64Idtr);
-
- //
- // Setup the default exception handler
- //
- Status = InitializeCpuExceptionHandlers (NULL);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Initialize Debug Agent to support source level debug
- //
- InitializeDebugAgent (DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64, (VOID *)&Ia32Idtr, NULL);
- }
-
- //
- // Skip initialization if mAcpiCpuData is not valid
- //
- if (mAcpiCpuData.NumberOfCpus > 0) {
- //
- // First time microcode load and restore MTRRs
- //
- EarlyInitializeCpu ();
- }
-
- //
- // Restore SMBASE for BSP and all APs
- //
- SmmRelocateBases ();
-
- //
- // Skip initialization if mAcpiCpuData is not valid
- //
- if (mAcpiCpuData.NumberOfCpus > 0) {
- //
- // Restore MSRs for BSP and all APs
- //
- InitializeCpu ();
- }
-
- //
- // Set a flag to restore SMM configuration in S3 path.
- //
- mRestoreSmmConfigurationInS3 = TRUE;
-
- DEBUG (( EFI_D_INFO, "SMM S3 Return CS = %x\n", SmmS3ResumeState->ReturnCs));
- DEBUG (( EFI_D_INFO, "SMM S3 Return Entry Point = %x\n", SmmS3ResumeState->ReturnEntryPoint));
- DEBUG (( EFI_D_INFO, "SMM S3 Return Context1 = %x\n", SmmS3ResumeState->ReturnContext1));
- DEBUG (( EFI_D_INFO, "SMM S3 Return Context2 = %x\n", SmmS3ResumeState->ReturnContext2));
- DEBUG (( EFI_D_INFO, "SMM S3 Return Stack Pointer = %x\n", SmmS3ResumeState->ReturnStackPointer));
-
- //
- // If SMM is in 32-bit mode, then use SwitchStack() to resume PEI Phase
- //
- if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) {
- DEBUG ((EFI_D_INFO, "Call SwitchStack() to return to S3 Resume in PEI Phase\n"));
-
- SwitchStack (
- (SWITCH_STACK_ENTRY_POINT)(UINTN)SmmS3ResumeState->ReturnEntryPoint,
- (VOID *)(UINTN)SmmS3ResumeState->ReturnContext1,
- (VOID *)(UINTN)SmmS3ResumeState->ReturnContext2,
- (VOID *)(UINTN)SmmS3ResumeState->ReturnStackPointer
- );
- }
-
- //
- // If SMM is in 64-bit mode, then use AsmDisablePaging64() to resume PEI Phase
- //
- if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_64) {
- DEBUG ((EFI_D_INFO, "Call AsmDisablePaging64() to return to S3 Resume in PEI Phase\n"));
- //
- // Disable interrupt of Debug timer, since new IDT table is for IA32 and will not work in long mode.
- //
- SaveAndSetDebugTimerInterrupt (FALSE);
- //
- // Restore IA32 IDT table
- //
- AsmWriteIdtr ((IA32_DESCRIPTOR *) &Ia32Idtr);
- AsmDisablePaging64 (
- SmmS3ResumeState->ReturnCs,
- (UINT32)SmmS3ResumeState->ReturnEntryPoint,
- (UINT32)SmmS3ResumeState->ReturnContext1,
- (UINT32)SmmS3ResumeState->ReturnContext2,
- (UINT32)SmmS3ResumeState->ReturnStackPointer
- );
- }
-
- //
- // Can not resume PEI Phase
- //
- DEBUG ((EFI_D_ERROR, "No context to return to PEI Phase\n"));
- CpuDeadLoop ();
-}
-
-/**
- Copy register table from ACPI NVS memory into SMRAM.
-
- @param[in] DestinationRegisterTableList Points to destination register table.
- @param[in] SourceRegisterTableList Points to source register table.
- @param[in] NumberOfCpus Number of CPUs.
-
-**/
-VOID
-CopyRegisterTable (
- IN CPU_REGISTER_TABLE *DestinationRegisterTableList,
- IN CPU_REGISTER_TABLE *SourceRegisterTableList,
- IN UINT32 NumberOfCpus
- )
-{
- UINTN Index;
- UINTN Index1;
- CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry;
-
- CopyMem (DestinationRegisterTableList, SourceRegisterTableList, NumberOfCpus * sizeof (CPU_REGISTER_TABLE));
- for (Index = 0; Index < NumberOfCpus; Index++) {
- DestinationRegisterTableList[Index].RegisterTableEntry = AllocatePool (DestinationRegisterTableList[Index].AllocatedSize);
- ASSERT (DestinationRegisterTableList[Index].RegisterTableEntry != NULL);
- CopyMem (DestinationRegisterTableList[Index].RegisterTableEntry, SourceRegisterTableList[Index].RegisterTableEntry, DestinationRegisterTableList[Index].AllocatedSize);
- //
- // Go though all MSRs in register table to initialize MSR spin lock
- //
- RegisterTableEntry = DestinationRegisterTableList[Index].RegisterTableEntry;
- for (Index1 = 0; Index1 < DestinationRegisterTableList[Index].TableLength; Index1++, RegisterTableEntry++) {
- if ((RegisterTableEntry->RegisterType == Msr) && (RegisterTableEntry->ValidBitLength < 64)) {
- //
- // Initialize MSR spin lock only for those MSRs need bit field writing
- //
- InitMsrSpinLockByIndex (RegisterTableEntry->Index);
- }
- }
- }
-}
-
-/**
- SMM Ready To Lock event notification handler.
-
- The CPU S3 data is copied to SMRAM for security and mSmmReadyToLock is set to
- perform additional lock actions that must be performed from SMM on the next SMI.
-
- @param[in] Protocol Points to the protocol's unique identifier.
- @param[in] Interface Points to the interface instance.
- @param[in] Handle The handle on which the interface was installed.
-
- @retval EFI_SUCCESS Notification handler runs successfully.
- **/
-EFI_STATUS
-EFIAPI
-SmmReadyToLockEventNotify (
- IN CONST EFI_GUID *Protocol,
- IN VOID *Interface,
- IN EFI_HANDLE Handle
- )
-{
- ACPI_CPU_DATA *AcpiCpuData;
- IA32_DESCRIPTOR *Gdtr;
- IA32_DESCRIPTOR *Idtr;
-
- //
- // Prevent use of mAcpiCpuData by initialize NumberOfCpus to 0
- //
- mAcpiCpuData.NumberOfCpus = 0;
-
- //
- // If PcdCpuS3DataAddress was never set, then do not copy CPU S3 Data into SMRAM
- //
- AcpiCpuData = (ACPI_CPU_DATA *)(UINTN)PcdGet64 (PcdCpuS3DataAddress);
- if (AcpiCpuData == 0) {
- goto Done;
- }
-
- //
- // For a native platform, copy the CPU S3 data into SMRAM for use on CPU S3 Resume.
- //
- CopyMem (&mAcpiCpuData, AcpiCpuData, sizeof (mAcpiCpuData));
-
- mAcpiCpuData.MtrrTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (sizeof (MTRR_SETTINGS));
- ASSERT (mAcpiCpuData.MtrrTable != 0);
-
- CopyMem ((VOID *)(UINTN)mAcpiCpuData.MtrrTable, (VOID *)(UINTN)AcpiCpuData->MtrrTable, sizeof (MTRR_SETTINGS));
-
- mAcpiCpuData.GdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (sizeof (IA32_DESCRIPTOR));
- ASSERT (mAcpiCpuData.GdtrProfile != 0);
-
- CopyMem ((VOID *)(UINTN)mAcpiCpuData.GdtrProfile, (VOID *)(UINTN)AcpiCpuData->GdtrProfile, sizeof (IA32_DESCRIPTOR));
-
- mAcpiCpuData.IdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (sizeof (IA32_DESCRIPTOR));
- ASSERT (mAcpiCpuData.IdtrProfile != 0);
-
- CopyMem ((VOID *)(UINTN)mAcpiCpuData.IdtrProfile, (VOID *)(UINTN)AcpiCpuData->IdtrProfile, sizeof (IA32_DESCRIPTOR));
-
- mAcpiCpuData.PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE));
- ASSERT (mAcpiCpuData.PreSmmInitRegisterTable != 0);
-
- CopyRegisterTable (
- (CPU_REGISTER_TABLE *)(UINTN)mAcpiCpuData.PreSmmInitRegisterTable,
- (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->PreSmmInitRegisterTable,
- mAcpiCpuData.NumberOfCpus
- );
-
- mAcpiCpuData.RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE));
- ASSERT (mAcpiCpuData.RegisterTable != 0);
-
- CopyRegisterTable (
- (CPU_REGISTER_TABLE *)(UINTN)mAcpiCpuData.RegisterTable,
- (CPU_REGISTER_TABLE *)(UINTN)AcpiCpuData->RegisterTable,
- mAcpiCpuData.NumberOfCpus
- );
-
- //
- // Copy AP's GDT, IDT and Machine Check handler into SMRAM.
- //
- Gdtr = (IA32_DESCRIPTOR *)(UINTN)mAcpiCpuData.GdtrProfile;
- Idtr = (IA32_DESCRIPTOR *)(UINTN)mAcpiCpuData.IdtrProfile;
-
- mGdtForAp = AllocatePool ((Gdtr->Limit + 1) + (Idtr->Limit + 1) + mAcpiCpuData.ApMachineCheckHandlerSize);
- ASSERT (mGdtForAp != NULL);
- mIdtForAp = (VOID *) ((UINTN)mGdtForAp + (Gdtr->Limit + 1));
- mMachineCheckHandlerForAp = (VOID *) ((UINTN)mIdtForAp + (Idtr->Limit + 1));
-
- CopyMem (mGdtForAp, (VOID *)Gdtr->Base, Gdtr->Limit + 1);
- CopyMem (mIdtForAp, (VOID *)Idtr->Base, Idtr->Limit + 1);
- CopyMem (mMachineCheckHandlerForAp, (VOID *)(UINTN)mAcpiCpuData.ApMachineCheckHandlerBase, mAcpiCpuData.ApMachineCheckHandlerSize);
-
-Done:
- //
- // Set SMM ready to lock flag and return
- //
- mSmmReadyToLock = TRUE;
- return EFI_SUCCESS;
-}
-
-/**
- The module Entry Point of the CPU SMM driver.
-
- @param ImageHandle The firmware allocated handle for the EFI image.
- @param SystemTable A pointer to the EFI System Table.
-
- @retval EFI_SUCCESS The entry point is executed successfully.
- @retval Other Some error occurs when executing this entry point.
-
-**/
-EFI_STATUS
-EFIAPI
-PiCpuSmmEntry (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
-{
- EFI_STATUS Status;
- EFI_MP_SERVICES_PROTOCOL *MpServices;
- UINTN NumberOfEnabledProcessors;
- UINTN Index;
- VOID *Buffer;
- UINTN BufferPages;
- UINTN TileCodeSize;
- UINTN TileDataSize;
- UINTN TileSize;
- VOID *GuidHob;
- EFI_SMRAM_DESCRIPTOR *SmramDescriptor;
- SMM_S3_RESUME_STATE *SmmS3ResumeState;
- UINT8 *Stacks;
- VOID *Registration;
- UINT32 RegEax;
- UINT32 RegEdx;
- UINTN FamilyId;
- UINTN ModelId;
- UINT32 Cr3;
-
- //
- // Initialize Debug Agent to support source level debug in SMM code
- //
- InitializeDebugAgent (DEBUG_AGENT_INIT_SMM, NULL, NULL);
-
- //
- // Report the start of CPU SMM initialization.
- //
- REPORT_STATUS_CODE (
- EFI_PROGRESS_CODE,
- EFI_COMPUTING_UNIT_HOST_PROCESSOR | EFI_CU_HP_PC_SMM_INIT
- );
-
- //
- // Fix segment address of the long-mode-switch jump
- //
- if (sizeof (UINTN) == sizeof (UINT64)) {
- gSmmJmpAddr.Segment = LONG_MODE_CODE_SEGMENT;
- }
-
- //
- // Find out SMRR Base and SMRR Size
- //
- FindSmramInfo (&mCpuHotPlugData.SmrrBase, &mCpuHotPlugData.SmrrSize);
-
- //
- // Get MP Services Protocol
- //
- Status = SystemTable->BootServices->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpServices);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Use MP Services Protocol to retrieve the number of processors and number of enabled processors
- //
- Status = MpServices->GetNumberOfProcessors (MpServices, &mNumberOfCpus, &NumberOfEnabledProcessors);
- ASSERT_EFI_ERROR (Status);
- ASSERT (mNumberOfCpus <= PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
-
- //
- // If support CPU hot plug, PcdCpuSmmEnableBspElection should be set to TRUE.
- // A constant BSP index makes no sense because it may be hot removed.
- //
- DEBUG_CODE (
- if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
-
- ASSERT (FeaturePcdGet (PcdCpuSmmEnableBspElection));
- }
- );
-
- //
- // Save the PcdCpuSmmCodeAccessCheckEnable value into a global variable.
- //
- mSmmCodeAccessCheckEnable = PcdGetBool (PcdCpuSmmCodeAccessCheckEnable);
- DEBUG ((EFI_D_INFO, "PcdCpuSmmCodeAccessCheckEnable = %d\n", mSmmCodeAccessCheckEnable));
-
- //
- // If support CPU hot plug, we need to allocate resources for possibly hot-added processors
- //
- if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
- mMaxNumberOfCpus = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
- } else {
- mMaxNumberOfCpus = mNumberOfCpus;
- }
- gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus = mMaxNumberOfCpus;
-
- //
- // The CPU save state and code for the SMI entry point are tiled within an SMRAM
- // allocated buffer. The minimum size of this buffer for a uniprocessor system
- // is 32 KB, because the entry point is SMBASE + 32KB, and CPU save state area
- // just below SMBASE + 64KB. If more than one CPU is present in the platform,
- // then the SMI entry point and the CPU save state areas can be tiles to minimize
- // the total amount SMRAM required for all the CPUs. The tile size can be computed
- // by adding the // CPU save state size, any extra CPU specific context, and
- // the size of code that must be placed at the SMI entry point to transfer
- // control to a C function in the native SMM execution mode. This size is
- // rounded up to the nearest power of 2 to give the tile size for a each CPU.
- // The total amount of memory required is the maximum number of CPUs that
- // platform supports times the tile size. The picture below shows the tiling,
- // where m is the number of tiles that fit in 32KB.
- //
- // +-----------------------------+ <-- 2^n offset from Base of allocated buffer
- // | CPU m+1 Save State |
- // +-----------------------------+
- // | CPU m+1 Extra Data |
- // +-----------------------------+
- // | Padding |
- // +-----------------------------+
- // | CPU 2m SMI Entry |
- // +#############################+ <-- Base of allocated buffer + 64 KB
- // | CPU m-1 Save State |
- // +-----------------------------+
- // | CPU m-1 Extra Data |
- // +-----------------------------+
- // | Padding |
- // +-----------------------------+
- // | CPU 2m-1 SMI Entry |
- // +=============================+ <-- 2^n offset from Base of allocated buffer
- // | . . . . . . . . . . . . |
- // +=============================+ <-- 2^n offset from Base of allocated buffer
- // | CPU 2 Save State |
- // +-----------------------------+
- // | CPU 2 Extra Data |
- // +-----------------------------+
- // | Padding |
- // +-----------------------------+
- // | CPU m+1 SMI Entry |
- // +=============================+ <-- Base of allocated buffer + 32 KB
- // | CPU 1 Save State |
- // +-----------------------------+
- // | CPU 1 Extra Data |
- // +-----------------------------+
- // | Padding |
- // +-----------------------------+
- // | CPU m SMI Entry |
- // +#############################+ <-- Base of allocated buffer + 32 KB == CPU 0 SMBASE + 64 KB
- // | CPU 0 Save State |
- // +-----------------------------+
- // | CPU 0 Extra Data |
- // +-----------------------------+
- // | Padding |
- // +-----------------------------+
- // | CPU m-1 SMI Entry |
- // +=============================+ <-- 2^n offset from Base of allocated buffer
- // | . . . . . . . . . . . . |
- // +=============================+ <-- 2^n offset from Base of allocated buffer
- // | Padding |
- // +-----------------------------+
- // | CPU 1 SMI Entry |
- // +=============================+ <-- 2^n offset from Base of allocated buffer
- // | Padding |
- // +-----------------------------+
- // | CPU 0 SMI Entry |
- // +#############################+ <-- Base of allocated buffer == CPU 0 SMBASE + 32 KB
- //
-
- //
- // Retrieve CPU Family
- //
- AsmCpuid (CPUID_VERSION_INFO, &RegEax, NULL, NULL, NULL);
- FamilyId = (RegEax >> 8) & 0xf;
- ModelId = (RegEax >> 4) & 0xf;
- if (FamilyId == 0x06 || FamilyId == 0x0f) {
- ModelId = ModelId | ((RegEax >> 12) & 0xf0);
- }
-
- RegEdx = 0;
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
- if (RegEax >= CPUID_EXTENDED_CPU_SIG) {
- AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);
- }
- //
- // Determine the mode of the CPU at the time an SMI occurs
- // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
- // Volume 3C, Section 34.4.1.1
- //
- mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT;
- if ((RegEdx & BIT29) != 0) {
- mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT;
- }
- if (FamilyId == 0x06) {
- if (ModelId == 0x17 || ModelId == 0x0f || ModelId == 0x1c) {
- mSmmSaveStateRegisterLma = EFI_SMM_SAVE_STATE_REGISTER_LMA_64BIT;
- }
- }
-
- //
- // Compute tile size of buffer required to hold the CPU SMRAM Save State Map, extra CPU
- // specific context in a PROCESSOR_SMM_DESCRIPTOR, and the SMI entry point. This size
- // is rounded up to nearest power of 2.
- //
- TileCodeSize = GetSmiHandlerSize ();
- TileCodeSize = ALIGN_VALUE(TileCodeSize, SIZE_4KB);
- TileDataSize = sizeof (SMRAM_SAVE_STATE_MAP) + sizeof (PROCESSOR_SMM_DESCRIPTOR);
- TileDataSize = ALIGN_VALUE(TileDataSize, SIZE_4KB);
- TileSize = TileDataSize + TileCodeSize - 1;
- TileSize = 2 * GetPowerOfTwo32 ((UINT32)TileSize);
- DEBUG ((EFI_D_INFO, "SMRAM TileSize = 0x%08x (0x%08x, 0x%08x)\n", TileSize, TileCodeSize, TileDataSize));
-
- //
- // If the TileSize is larger than space available for the SMI Handler of CPU[i],
- // the PROCESSOR_SMM_DESCRIPTOR of CPU[i+1] and the SMRAM Save State Map of CPU[i+1],
- // the ASSERT(). If this ASSERT() is triggered, then the SMI Handler size must be
- // reduced.
- //
- ASSERT (TileSize <= (SMRAM_SAVE_STATE_MAP_OFFSET + sizeof (SMRAM_SAVE_STATE_MAP) - SMM_HANDLER_OFFSET));
-
- //
- // Allocate buffer for all of the tiles.
- //
- // Intel(R) 64 and IA-32 Architectures Software Developer's Manual
- // Volume 3C, Section 34.11 SMBASE Relocation
- // For Pentium and Intel486 processors, the SMBASE values must be
- // aligned on a 32-KByte boundary or the processor will enter shutdown
- // state during the execution of a RSM instruction.
- //
- // Intel486 processors: FamilyId is 4
- // Pentium processors : FamilyId is 5
- //
- BufferPages = EFI_SIZE_TO_PAGES (SIZE_32KB + TileSize * (mMaxNumberOfCpus - 1));
- if ((FamilyId == 4) || (FamilyId == 5)) {
- Buffer = AllocateAlignedPages (BufferPages, SIZE_32KB);
- } else {
- Buffer = AllocateAlignedPages (BufferPages, SIZE_4KB);
- }
- ASSERT (Buffer != NULL);
- DEBUG ((EFI_D_INFO, "SMRAM SaveState Buffer (0x%08x, 0x%08x)\n", Buffer, EFI_PAGES_TO_SIZE(BufferPages)));
-
- //
- // Allocate buffer for pointers to array in SMM_CPU_PRIVATE_DATA.
- //
- gSmmCpuPrivate->ProcessorInfo = (EFI_PROCESSOR_INFORMATION *)AllocatePool (sizeof (EFI_PROCESSOR_INFORMATION) * mMaxNumberOfCpus);
- ASSERT (gSmmCpuPrivate->ProcessorInfo != NULL);
-
- gSmmCpuPrivate->Operation = (SMM_CPU_OPERATION *)AllocatePool (sizeof (SMM_CPU_OPERATION) * mMaxNumberOfCpus);
- ASSERT (gSmmCpuPrivate->Operation != NULL);
-
- gSmmCpuPrivate->CpuSaveStateSize = (UINTN *)AllocatePool (sizeof (UINTN) * mMaxNumberOfCpus);
- ASSERT (gSmmCpuPrivate->CpuSaveStateSize != NULL);
-
- gSmmCpuPrivate->CpuSaveState = (VOID **)AllocatePool (sizeof (VOID *) * mMaxNumberOfCpus);
- ASSERT (gSmmCpuPrivate->CpuSaveState != NULL);
-
- mSmmCpuPrivateData.SmmCoreEntryContext.CpuSaveStateSize = gSmmCpuPrivate->CpuSaveStateSize;
- mSmmCpuPrivateData.SmmCoreEntryContext.CpuSaveState = gSmmCpuPrivate->CpuSaveState;
-
- //
- // Allocate buffer for pointers to array in CPU_HOT_PLUG_DATA.
- //
- mCpuHotPlugData.ApicId = (UINT64 *)AllocatePool (sizeof (UINT64) * mMaxNumberOfCpus);
- ASSERT (mCpuHotPlugData.ApicId != NULL);
- mCpuHotPlugData.SmBase = (UINTN *)AllocatePool (sizeof (UINTN) * mMaxNumberOfCpus);
- ASSERT (mCpuHotPlugData.SmBase != NULL);
- mCpuHotPlugData.ArrayLength = (UINT32)mMaxNumberOfCpus;
-
- //
- // Retrieve APIC ID of each enabled processor from the MP Services protocol.
- // Also compute the SMBASE address, CPU Save State address, and CPU Save state
- // size for each CPU in the platform
- //
- for (Index = 0; Index < mMaxNumberOfCpus; Index++) {
- mCpuHotPlugData.SmBase[Index] = (UINTN)Buffer + Index * TileSize - SMM_HANDLER_OFFSET;
- gSmmCpuPrivate->CpuSaveStateSize[Index] = sizeof(SMRAM_SAVE_STATE_MAP);
- gSmmCpuPrivate->CpuSaveState[Index] = (VOID *)(mCpuHotPlugData.SmBase[Index] + SMRAM_SAVE_STATE_MAP_OFFSET);
- gSmmCpuPrivate->Operation[Index] = SmmCpuNone;
-
- if (Index < mNumberOfCpus) {
- Status = MpServices->GetProcessorInfo (MpServices, Index, &gSmmCpuPrivate->ProcessorInfo[Index]);
- ASSERT_EFI_ERROR (Status);
- mCpuHotPlugData.ApicId[Index] = gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId;
-
- DEBUG ((EFI_D_INFO, "CPU[%03x] APIC ID=%04x SMBASE=%08x SaveState=%08x Size=%08x\n",
- Index,
- (UINT32)gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId,
- mCpuHotPlugData.SmBase[Index],
- gSmmCpuPrivate->CpuSaveState[Index],
- gSmmCpuPrivate->CpuSaveStateSize[Index]
- ));
- } else {
- gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId = INVALID_APIC_ID;
- mCpuHotPlugData.ApicId[Index] = INVALID_APIC_ID;
- }
- }
-
- //
- // Allocate SMI stacks for all processors.
- //
- if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
- //
- // 2 more pages is allocated for each processor.
- // one is guard page and the other is known good stack.
- //
- // +-------------------------------------------+-----+-------------------------------------------+
- // | Known Good Stack | Guard Page | SMM Stack | ... | Known Good Stack | Guard Page | SMM Stack |
- // +-------------------------------------------+-----+-------------------------------------------+
- // | | | |
- // |<-------------- Processor 0 -------------->| |<-------------- Processor n -------------->|
- //
- mSmmStackSize = EFI_PAGES_TO_SIZE (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmStackSize)) + 2);
- Stacks = (UINT8 *) AllocatePages (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * (EFI_SIZE_TO_PAGES (PcdGet32 (PcdCpuSmmStackSize)) + 2));
- ASSERT (Stacks != NULL);
- mSmmStackArrayBase = (UINTN)Stacks;
- mSmmStackArrayEnd = mSmmStackArrayBase + gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * mSmmStackSize - 1;
- } else {
- mSmmStackSize = PcdGet32 (PcdCpuSmmStackSize);
- Stacks = (UINT8 *) AllocatePages (EFI_SIZE_TO_PAGES (gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus * mSmmStackSize));
- ASSERT (Stacks != NULL);
- }
-
- //
- // Set SMI stack for SMM base relocation
- //
- gSmmInitStack = (UINTN) (Stacks + mSmmStackSize - sizeof (UINTN));
-
- //
- // Initialize IDT
- //
- InitializeSmmIdt ();
-
- //
- // Relocate SMM Base addresses to the ones allocated from SMRAM
- //
- mRebased = (BOOLEAN *)AllocateZeroPool (sizeof (BOOLEAN) * mMaxNumberOfCpus);
- ASSERT (mRebased != NULL);
- SmmRelocateBases ();
-
- //
- // Call hook for BSP to perform extra actions in normal mode after all
- // SMM base addresses have been relocated on all CPUs
- //
- SmmCpuFeaturesSmmRelocationComplete ();
-
- //
- // SMM Time initialization
- //
- InitializeSmmTimer ();
-
- //
- // Initialize MP globals
- //
- Cr3 = InitializeMpServiceData (Stacks, mSmmStackSize);
-
- //
- // Fill in SMM Reserved Regions
- //
- gSmmCpuPrivate->SmmReservedSmramRegion[0].SmramReservedStart = 0;
- gSmmCpuPrivate->SmmReservedSmramRegion[0].SmramReservedSize = 0;
-
- //
- // Install the SMM Configuration Protocol onto a new handle on the handle database.
- // The entire SMM Configuration Protocol is allocated from SMRAM, so only a pointer
- // to an SMRAM address will be present in the handle database
- //
- Status = SystemTable->BootServices->InstallMultipleProtocolInterfaces (
- &gSmmCpuPrivate->SmmCpuHandle,
- &gEfiSmmConfigurationProtocolGuid, &gSmmCpuPrivate->SmmConfiguration,
- NULL
- );
- ASSERT_EFI_ERROR (Status);
-
- //
- // Install the SMM CPU Protocol into SMM protocol database
- //
- Status = gSmst->SmmInstallProtocolInterface (
- &mSmmCpuHandle,
- &gEfiSmmCpuProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &mSmmCpu
- );
- ASSERT_EFI_ERROR (Status);
-
- //
- // Expose address of CPU Hot Plug Data structure if CPU hot plug is supported.
- //
- if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
- Status = PcdSet64S (PcdCpuHotPlugDataAddress, (UINT64)(UINTN)&mCpuHotPlugData);
- ASSERT_EFI_ERROR (Status);
- }
-
- //
- // Initialize SMM CPU Services Support
- //
- Status = InitializeSmmCpuServices (mSmmCpuHandle);
- ASSERT_EFI_ERROR (Status);
-
- //
- // register SMM Ready To Lock Protocol notification
- //
- Status = gSmst->SmmRegisterProtocolNotify (
- &gEfiSmmReadyToLockProtocolGuid,
- SmmReadyToLockEventNotify,
- &Registration
- );
- ASSERT_EFI_ERROR (Status);
-
- GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid);
- if (GuidHob != NULL) {
- SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *) GET_GUID_HOB_DATA (GuidHob);
-
- DEBUG ((EFI_D_INFO, "SMM S3 SMRAM Structure = %x\n", SmramDescriptor));
- DEBUG ((EFI_D_INFO, "SMM S3 Structure = %x\n", SmramDescriptor->CpuStart));
-
- SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart;
- ZeroMem (SmmS3ResumeState, sizeof (SMM_S3_RESUME_STATE));
-
- mSmmS3ResumeState = SmmS3ResumeState;
- SmmS3ResumeState->Smst = (EFI_PHYSICAL_ADDRESS)(UINTN)gSmst;
-
- SmmS3ResumeState->SmmS3ResumeEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)SmmRestoreCpu;
-
- SmmS3ResumeState->SmmS3StackSize = SIZE_32KB;
- SmmS3ResumeState->SmmS3StackBase = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)SmmS3ResumeState->SmmS3StackSize));
- if (SmmS3ResumeState->SmmS3StackBase == 0) {
- SmmS3ResumeState->SmmS3StackSize = 0;
- }
-
- SmmS3ResumeState->SmmS3Cr0 = gSmmCr0;
- SmmS3ResumeState->SmmS3Cr3 = Cr3;
- SmmS3ResumeState->SmmS3Cr4 = gSmmCr4;
-
- if (sizeof (UINTN) == sizeof (UINT64)) {
- SmmS3ResumeState->Signature = SMM_S3_RESUME_SMM_64;
- }
- if (sizeof (UINTN) == sizeof (UINT32)) {
- SmmS3ResumeState->Signature = SMM_S3_RESUME_SMM_32;
- }
- }
-
- //
- // Check XD and BTS features
- //
- CheckProcessorFeature ();
-
- //
- // Initialize SMM Profile feature
- //
- InitSmmProfile (Cr3);
-
- //
- // Patch SmmS3ResumeState->SmmS3Cr3
- //
- InitSmmS3Cr3 ();
-
- DEBUG ((EFI_D_INFO, "SMM CPU Module exit from SMRAM with EFI_SUCCESS\n"));
-
- return EFI_SUCCESS;
-}
-
-/**
-
- Find out SMRAM information including SMRR base and SMRR size.
-
- @param SmrrBase SMRR base
- @param SmrrSize SMRR size
-
-**/
-VOID
-FindSmramInfo (
- OUT UINT32 *SmrrBase,
- OUT UINT32 *SmrrSize
- )
-{
- EFI_STATUS Status;
- UINTN Size;
- EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
- EFI_SMRAM_DESCRIPTOR *CurrentSmramRange;
- EFI_SMRAM_DESCRIPTOR *SmramRanges;
- UINTN SmramRangeCount;
- UINTN Index;
- UINT64 MaxSize;
- BOOLEAN Found;
-
- //
- // Get SMM Access Protocol
- //
- Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Get SMRAM information
- //
- Size = 0;
- Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);
- ASSERT (Status == EFI_BUFFER_TOO_SMALL);
-
- SmramRanges = (EFI_SMRAM_DESCRIPTOR *)AllocatePool (Size);
- ASSERT (SmramRanges != NULL);
-
- Status = SmmAccess->GetCapabilities (SmmAccess, &Size, SmramRanges);
- ASSERT_EFI_ERROR (Status);
-
- SmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
-
- //
- // Find the largest SMRAM range between 1MB and 4GB that is at least 256K - 4K in size
- //
- CurrentSmramRange = NULL;
- for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < SmramRangeCount; Index++) {
- //
- // Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization
- //
- if ((SmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
- continue;
- }
-
- if (SmramRanges[Index].CpuStart >= BASE_1MB) {
- if ((SmramRanges[Index].CpuStart + SmramRanges[Index].PhysicalSize) <= BASE_4GB) {
- if (SmramRanges[Index].PhysicalSize >= MaxSize) {
- MaxSize = SmramRanges[Index].PhysicalSize;
- CurrentSmramRange = &SmramRanges[Index];
- }
- }
- }
- }
-
- ASSERT (CurrentSmramRange != NULL);
-
- *SmrrBase = (UINT32)CurrentSmramRange->CpuStart;
- *SmrrSize = (UINT32)CurrentSmramRange->PhysicalSize;
-
- do {
- Found = FALSE;
- for (Index = 0; Index < SmramRangeCount; Index++) {
- if (SmramRanges[Index].CpuStart < *SmrrBase && *SmrrBase == (SmramRanges[Index].CpuStart + SmramRanges[Index].PhysicalSize)) {
- *SmrrBase = (UINT32)SmramRanges[Index].CpuStart;
- *SmrrSize = (UINT32)(*SmrrSize + SmramRanges[Index].PhysicalSize);
- Found = TRUE;
- } else if ((*SmrrBase + *SmrrSize) == SmramRanges[Index].CpuStart && SmramRanges[Index].PhysicalSize > 0) {
- *SmrrSize = (UINT32)(*SmrrSize + SmramRanges[Index].PhysicalSize);
- Found = TRUE;
- }
- }
- } while (Found);
-
- DEBUG ((EFI_D_INFO, "SMRR Base: 0x%x, SMRR Size: 0x%x\n", *SmrrBase, *SmrrSize));
-}
-
-/**
-Configure SMM Code Access Check feature on an AP.
-SMM Feature Control MSR will be locked after configuration.
-
-@param[in,out] Buffer Pointer to private data buffer.
-**/
-VOID
-EFIAPI
-ConfigSmmCodeAccessCheckOnCurrentProcessor (
- IN OUT VOID *Buffer
- )
-{
- UINTN CpuIndex;
- UINT64 SmmFeatureControlMsr;
- UINT64 NewSmmFeatureControlMsr;
-
- //
- // Retrieve the CPU Index from the context passed in
- //
- CpuIndex = *(UINTN *)Buffer;
-
- //
- // Get the current SMM Feature Control MSR value
- //
- SmmFeatureControlMsr = SmmCpuFeaturesGetSmmRegister (CpuIndex, SmmRegFeatureControl);
-
- //
- // Compute the new SMM Feature Control MSR value
- //
- NewSmmFeatureControlMsr = SmmFeatureControlMsr;
- if (mSmmCodeAccessCheckEnable) {
- NewSmmFeatureControlMsr |= SMM_CODE_CHK_EN_BIT;
- if (FeaturePcdGet (PcdCpuSmmFeatureControlMsrLock)) {
- NewSmmFeatureControlMsr |= SMM_FEATURE_CONTROL_LOCK_BIT;
- }
- }
-
- //
- // Only set the SMM Feature Control MSR value if the new value is different than the current value
- //
- if (NewSmmFeatureControlMsr != SmmFeatureControlMsr) {
- SmmCpuFeaturesSetSmmRegister (CpuIndex, SmmRegFeatureControl, NewSmmFeatureControlMsr);
- }
-
- //
- // Release the spin lock user to serialize the updates to the SMM Feature Control MSR
- //
- ReleaseSpinLock (mConfigSmmCodeAccessCheckLock);
-}
-
-/**
-Configure SMM Code Access Check feature for all processors.
-SMM Feature Control MSR will be locked after configuration.
-**/
-VOID
-ConfigSmmCodeAccessCheck (
- VOID
- )
-{
- UINTN Index;
- EFI_STATUS Status;
-
- //
- // Check to see if the Feature Control MSR is supported on this CPU
- //
- Index = gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu;
- if (!SmmCpuFeaturesIsSmmRegisterSupported (Index, SmmRegFeatureControl)) {
- mSmmCodeAccessCheckEnable = FALSE;
- return;
- }
-
- //
- // Check to see if the CPU supports the SMM Code Access Check feature
- // Do not access this MSR unless the CPU supports the SmmRegFeatureControl
- //
- if ((AsmReadMsr64 (EFI_MSR_SMM_MCA_CAP) & SMM_CODE_ACCESS_CHK_BIT) == 0) {
- mSmmCodeAccessCheckEnable = FALSE;
- return;
- }
-
- //
- // Initialize the lock used to serialize the MSR programming in BSP and all APs
- //
- InitializeSpinLock (mConfigSmmCodeAccessCheckLock);
-
- //
- // Acquire Config SMM Code Access Check spin lock. The BSP will release the
- // spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor().
- //
- AcquireSpinLock (mConfigSmmCodeAccessCheckLock);
-
- //
- // Enable SMM Code Access Check feature on the BSP.
- //
- ConfigSmmCodeAccessCheckOnCurrentProcessor (&Index);
-
- //
- // Enable SMM Code Access Check feature for the APs.
- //
- for (Index = 0; Index < gSmst->NumberOfCpus; Index++) {
- if (Index != gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu) {
-
- //
- // Acquire Config SMM Code Access Check spin lock. The AP will release the
- // spin lock when it is done executing ConfigSmmCodeAccessCheckOnCurrentProcessor().
- //
- AcquireSpinLock (mConfigSmmCodeAccessCheckLock);
-
- //
- // Call SmmStartupThisAp() to enable SMM Code Access Check on an AP.
- //
- Status = gSmst->SmmStartupThisAp (ConfigSmmCodeAccessCheckOnCurrentProcessor, Index, &Index);
- ASSERT_EFI_ERROR (Status);
-
- //
- // Wait for the AP to release the Config SMM Code Access Check spin lock.
- //
- while (!AcquireSpinLockOrFail (mConfigSmmCodeAccessCheckLock)) {
- CpuPause ();
- }
-
- //
- // Release the Config SMM Code Access Check spin lock.
- //
- ReleaseSpinLock (mConfigSmmCodeAccessCheckLock);
- }
- }
-}
-
-/**
- This API provides a way to allocate memory for page table.
-
- This API can be called more once to allocate memory for page tables.
-
- Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
- allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
- is returned. If there is not enough memory remaining to satisfy the request, then NULL is
- returned.
-
- @param Pages The number of 4 KB pages to allocate.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-AllocatePageTableMemory (
- IN UINTN Pages
- )
-{
- VOID *Buffer;
-
- Buffer = SmmCpuFeaturesAllocatePageTableMemory (Pages);
- if (Buffer != NULL) {
- return Buffer;
- }
- return AllocatePages (Pages);
-}
-
-/**
- Perform the remaining tasks.
-
-**/
-VOID
-PerformRemainingTasks (
- VOID
- )
-{
- if (mSmmReadyToLock) {
- //
- // Start SMM Profile feature
- //
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
- SmmProfileStart ();
- }
- //
- // Create a mix of 2MB and 4KB page table. Update some memory ranges absent and execute-disable.
- //
- InitPaging ();
- //
- // Configure SMM Code Access Check feature if available.
- //
- ConfigSmmCodeAccessCheck ();
-
- SmmCpuFeaturesCompleteSmmReadyToLock ();
-
- //
- // Clean SMM ready to lock flag
- //
- mSmmReadyToLock = FALSE;
- }
-}
-
-/**
- Perform the pre tasks.
-
-**/
-VOID
-PerformPreTasks (
- VOID
- )
-{
- //
- // Restore SMM Configuration in S3 boot path.
- //
- if (mRestoreSmmConfigurationInS3) {
- //
- // Need make sure gSmst is correct because below function may use them.
- //
- gSmst->SmmStartupThisAp = gSmmCpuPrivate->SmmCoreEntryContext.SmmStartupThisAp;
- gSmst->CurrentlyExecutingCpu = gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu;
- gSmst->NumberOfCpus = gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;
- gSmst->CpuSaveStateSize = gSmmCpuPrivate->SmmCoreEntryContext.CpuSaveStateSize;
- gSmst->CpuSaveState = gSmmCpuPrivate->SmmCoreEntryContext.CpuSaveState;
-
- //
- // Configure SMM Code Access Check feature if available.
- //
- ConfigSmmCodeAccessCheck ();
-
- SmmCpuFeaturesCompleteSmmReadyToLock ();
-
- mRestoreSmmConfigurationInS3 = FALSE;
- }
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
deleted file mode 100644
index dfdafa61fa..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
+++ /dev/null
@@ -1,797 +0,0 @@
-/** @file
-Agent Module to load other modules to deploy SMM Entry Vector for X86 CPU.
-
-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.
-
-**/
-
-#ifndef _CPU_PISMMCPUDXESMM_H_
-#define _CPU_PISMMCPUDXESMM_H_
-
-#include <PiSmm.h>
-
-#include <Protocol/MpService.h>
-#include <Protocol/SmmConfiguration.h>
-#include <Protocol/SmmCpu.h>
-#include <Protocol/SmmAccess2.h>
-#include <Protocol/SmmReadyToLock.h>
-#include <Protocol/SmmCpuService.h>
-
-#include <Guid/AcpiS3Context.h>
-
-#include <Library/BaseLib.h>
-#include <Library/IoLib.h>
-#include <Library/TimerLib.h>
-#include <Library/SynchronizationLib.h>
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/PcdLib.h>
-#include <Library/CacheMaintenanceLib.h>
-#include <Library/MtrrLib.h>
-#include <Library/SmmCpuPlatformHookLib.h>
-#include <Library/SmmServicesTableLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/DebugAgentLib.h>
-#include <Library/HobLib.h>
-#include <Library/LocalApicLib.h>
-#include <Library/UefiCpuLib.h>
-#include <Library/CpuExceptionHandlerLib.h>
-#include <Library/ReportStatusCodeLib.h>
-#include <Library/SmmCpuFeaturesLib.h>
-#include <Library/PeCoffGetEntryPointLib.h>
-
-#include <AcpiCpuData.h>
-#include <CpuHotPlugData.h>
-
-#include <Register/Cpuid.h>
-
-#include "CpuService.h"
-#include "SmmProfile.h"
-
-//
-// MSRs required for configuration of SMM Code Access Check
-//
-#define EFI_MSR_SMM_MCA_CAP 0x17D
-#define SMM_CODE_ACCESS_CHK_BIT BIT58
-
-#define SMM_FEATURE_CONTROL_LOCK_BIT BIT0
-#define SMM_CODE_CHK_EN_BIT BIT2
-
-///
-/// Page Table Entry
-///
-#define IA32_PG_P BIT0
-#define IA32_PG_RW BIT1
-#define IA32_PG_U BIT2
-#define IA32_PG_WT BIT3
-#define IA32_PG_CD BIT4
-#define IA32_PG_A BIT5
-#define IA32_PG_D BIT6
-#define IA32_PG_PS BIT7
-#define IA32_PG_PAT_2M BIT12
-#define IA32_PG_PAT_4K IA32_PG_PS
-#define IA32_PG_PMNT BIT62
-#define IA32_PG_NX BIT63
-
-#define PAGE_ATTRIBUTE_BITS (IA32_PG_RW | IA32_PG_P)
-//
-// Bits 1, 2, 5, 6 are reserved in the IA32 PAE PDPTE
-// X64 PAE PDPTE does not have such restriction
-//
-#define IA32_PAE_PDPTE_ATTRIBUTE_BITS (IA32_PG_P)
-
-//
-// Size of Task-State Segment defined in IA32 Manual
-//
-#define TSS_SIZE 104
-#define TSS_X64_IST1_OFFSET 36
-#define TSS_IA32_CR3_OFFSET 28
-#define TSS_IA32_ESP_OFFSET 56
-
-//
-// Code select value
-//
-#define PROTECT_MODE_CODE_SEGMENT 0x08
-#define LONG_MODE_CODE_SEGMENT 0x38
-
-//
-// The size 0x20 must be bigger than
-// the size of template code of SmmInit. Currently,
-// the size of SmmInit requires the 0x16 Bytes buffer
-// at least.
-//
-#define BACK_BUF_SIZE 0x20
-
-#define EXCEPTION_VECTOR_NUMBER 0x20
-
-#define INVALID_APIC_ID 0xFFFFFFFFFFFFFFFFULL
-
-typedef UINT32 SMM_CPU_ARRIVAL_EXCEPTIONS;
-#define ARRIVAL_EXCEPTION_BLOCKED 0x1
-#define ARRIVAL_EXCEPTION_DELAYED 0x2
-#define ARRIVAL_EXCEPTION_SMI_DISABLED 0x4
-
-//
-// Private structure for the SMM CPU module that is stored in DXE Runtime memory
-// Contains the SMM Configuration Protocols that is produced.
-// Contains a mix of DXE and SMM contents. All the fields must be used properly.
-//
-#define SMM_CPU_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('s', 'c', 'p', 'u')
-
-typedef struct {
- UINTN Signature;
-
- EFI_HANDLE SmmCpuHandle;
-
- EFI_PROCESSOR_INFORMATION *ProcessorInfo;
- SMM_CPU_OPERATION *Operation;
- UINTN *CpuSaveStateSize;
- VOID **CpuSaveState;
-
- EFI_SMM_RESERVED_SMRAM_REGION SmmReservedSmramRegion[1];
- EFI_SMM_ENTRY_CONTEXT SmmCoreEntryContext;
- EFI_SMM_ENTRY_POINT SmmCoreEntry;
-
- EFI_SMM_CONFIGURATION_PROTOCOL SmmConfiguration;
-} SMM_CPU_PRIVATE_DATA;
-
-extern SMM_CPU_PRIVATE_DATA *gSmmCpuPrivate;
-extern CPU_HOT_PLUG_DATA mCpuHotPlugData;
-extern UINTN mMaxNumberOfCpus;
-extern UINTN mNumberOfCpus;
-extern BOOLEAN mRestoreSmmConfigurationInS3;
-extern EFI_SMM_CPU_PROTOCOL mSmmCpu;
-
-///
-/// The mode of the CPU at the time an SMI occurs
-///
-extern UINT8 mSmmSaveStateRegisterLma;
-
-
-//
-// SMM CPU Protocol function prototypes.
-//
-
-/**
- Read information from the CPU save state.
-
- @param This EFI_SMM_CPU_PROTOCOL instance
- @param Width The number of bytes to read from the CPU save state.
- @param Register Specifies the CPU register to read form the save state.
- @param CpuIndex Specifies the zero-based index of the CPU save state
- @param Buffer Upon return, this holds the CPU register value read from the save state.
-
- @retval EFI_SUCCESS The register was read from Save State
- @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
- @retval EFI_INVALID_PARAMTER This or Buffer is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-SmmReadSaveState (
- IN CONST EFI_SMM_CPU_PROTOCOL *This,
- IN UINTN Width,
- IN EFI_SMM_SAVE_STATE_REGISTER Register,
- IN UINTN CpuIndex,
- OUT VOID *Buffer
- );
-
-/**
- Write data to the CPU save state.
-
- @param This EFI_SMM_CPU_PROTOCOL instance
- @param Width The number of bytes to read from the CPU save state.
- @param Register Specifies the CPU register to write to the save state.
- @param CpuIndex Specifies the zero-based index of the CPU save state
- @param Buffer Upon entry, this holds the new CPU register value.
-
- @retval EFI_SUCCESS The register was written from Save State
- @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor
- @retval EFI_INVALID_PARAMTER ProcessorIndex or Width is not correct
-
-**/
-EFI_STATUS
-EFIAPI
-SmmWriteSaveState (
- IN CONST EFI_SMM_CPU_PROTOCOL *This,
- IN UINTN Width,
- IN EFI_SMM_SAVE_STATE_REGISTER Register,
- IN UINTN CpuIndex,
- IN CONST VOID *Buffer
- );
-
-/**
-Read a CPU Save State register on the target processor.
-
-This function abstracts the differences that whether the CPU Save State register is in the
-IA32 CPU Save State Map or X64 CPU Save State Map.
-
-This function supports reading a CPU Save State register in SMBase relocation handler.
-
-@param[in] CpuIndex Specifies the zero-based index of the CPU save state.
-@param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table.
-@param[in] Width The number of bytes to read from the CPU save state.
-@param[out] Buffer Upon return, this holds the CPU register value read from the save state.
-
-@retval EFI_SUCCESS The register was read from Save State.
-@retval EFI_NOT_FOUND The register is not defined for the Save State of Processor.
-@retval EFI_INVALID_PARAMTER This or Buffer is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-ReadSaveStateRegister (
- IN UINTN CpuIndex,
- IN EFI_SMM_SAVE_STATE_REGISTER Register,
- IN UINTN Width,
- OUT VOID *Buffer
- );
-
-/**
-Write value to a CPU Save State register on the target processor.
-
-This function abstracts the differences that whether the CPU Save State register is in the
-IA32 CPU Save State Map or X64 CPU Save State Map.
-
-This function supports writing a CPU Save State register in SMBase relocation handler.
-
-@param[in] CpuIndex Specifies the zero-based index of the CPU save state.
-@param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table.
-@param[in] Width The number of bytes to read from the CPU save state.
-@param[in] Buffer Upon entry, this holds the new CPU register value.
-
-@retval EFI_SUCCESS The register was written to Save State.
-@retval EFI_NOT_FOUND The register is not defined for the Save State of Processor.
-@retval EFI_INVALID_PARAMTER ProcessorIndex or Width is not correct.
-
-**/
-EFI_STATUS
-EFIAPI
-WriteSaveStateRegister (
- IN UINTN CpuIndex,
- IN EFI_SMM_SAVE_STATE_REGISTER Register,
- IN UINTN Width,
- IN CONST VOID *Buffer
- );
-
-//
-//
-//
-typedef struct {
- UINT32 Offset;
- UINT16 Segment;
- UINT16 Reserved;
-} IA32_FAR_ADDRESS;
-
-extern IA32_FAR_ADDRESS gSmmJmpAddr;
-
-extern CONST UINT8 gcSmmInitTemplate[];
-extern CONST UINT16 gcSmmInitSize;
-extern UINT32 gSmmCr0;
-extern UINT32 gSmmCr3;
-extern UINT32 gSmmCr4;
-extern UINTN gSmmInitStack;
-
-/**
- Semaphore operation for all processor relocate SMMBase.
-**/
-VOID
-EFIAPI
-SmmRelocationSemaphoreComplete (
- VOID
- );
-
-///
-/// The type of SMM CPU Information
-///
-typedef struct {
- SPIN_LOCK *Busy;
- volatile EFI_AP_PROCEDURE Procedure;
- volatile VOID *Parameter;
- volatile UINT32 *Run;
- volatile BOOLEAN *Present;
-} SMM_CPU_DATA_BLOCK;
-
-typedef enum {
- SmmCpuSyncModeTradition,
- SmmCpuSyncModeRelaxedAp,
- SmmCpuSyncModeMax
-} SMM_CPU_SYNC_MODE;
-
-typedef struct {
- //
- // Pointer to an array. The array should be located immediately after this structure
- // so that UC cache-ability can be set together.
- //
- SMM_CPU_DATA_BLOCK *CpuData;
- volatile UINT32 *Counter;
- volatile UINT32 BspIndex;
- volatile BOOLEAN *InsideSmm;
- volatile BOOLEAN *AllCpusInSync;
- volatile SMM_CPU_SYNC_MODE EffectiveSyncMode;
- volatile BOOLEAN SwitchBsp;
- volatile BOOLEAN *CandidateBsp;
-} SMM_DISPATCHER_MP_SYNC_DATA;
-
-#define MSR_SPIN_LOCK_INIT_NUM 15
-
-typedef struct {
- SPIN_LOCK *SpinLock;
- UINT32 MsrIndex;
-} MP_MSR_LOCK;
-
-#define SMM_PSD_OFFSET 0xfb00
-
-typedef struct {
- UINT64 Signature; // Offset 0x00
- UINT16 Reserved1; // Offset 0x08
- UINT16 Reserved2; // Offset 0x0A
- UINT16 Reserved3; // Offset 0x0C
- UINT16 SmmCs; // Offset 0x0E
- UINT16 SmmDs; // Offset 0x10
- UINT16 SmmSs; // Offset 0x12
- UINT16 SmmOtherSegment; // Offset 0x14
- UINT16 Reserved4; // Offset 0x16
- UINT64 Reserved5; // Offset 0x18
- UINT64 Reserved6; // Offset 0x20
- UINT64 Reserved7; // Offset 0x28
- UINT64 SmmGdtPtr; // Offset 0x30
- UINT32 SmmGdtSize; // Offset 0x38
- UINT32 Reserved8; // Offset 0x3C
- UINT64 Reserved9; // Offset 0x40
- UINT64 Reserved10; // Offset 0x48
- UINT16 Reserved11; // Offset 0x50
- UINT16 Reserved12; // Offset 0x52
- UINT32 Reserved13; // Offset 0x54
- UINT64 MtrrBaseMaskPtr; // Offset 0x58
-} PROCESSOR_SMM_DESCRIPTOR;
-
-
-///
-/// All global semaphores' pointer
-///
-typedef struct {
- volatile UINT32 *Counter;
- volatile BOOLEAN *InsideSmm;
- volatile BOOLEAN *AllCpusInSync;
- SPIN_LOCK *PFLock;
- SPIN_LOCK *CodeAccessCheckLock;
-} SMM_CPU_SEMAPHORE_GLOBAL;
-
-///
-/// All semaphores for each processor
-///
-typedef struct {
- SPIN_LOCK *Busy;
- volatile UINT32 *Run;
- volatile BOOLEAN *Present;
-} SMM_CPU_SEMAPHORE_CPU;
-
-///
-/// All MSRs semaphores' pointer and counter
-///
-typedef struct {
- SPIN_LOCK *Msr;
- UINTN AvailableCounter;
-} SMM_CPU_SEMAPHORE_MSR;
-
-///
-/// All semaphores' information
-///
-typedef struct {
- SMM_CPU_SEMAPHORE_GLOBAL SemaphoreGlobal;
- SMM_CPU_SEMAPHORE_CPU SemaphoreCpu;
- SMM_CPU_SEMAPHORE_MSR SemaphoreMsr;
-} SMM_CPU_SEMAPHORES;
-
-extern IA32_DESCRIPTOR gcSmiGdtr;
-extern IA32_DESCRIPTOR gcSmiIdtr;
-extern VOID *gcSmiIdtrPtr;
-extern CONST PROCESSOR_SMM_DESCRIPTOR gcPsd;
-extern UINT64 gPhyMask;
-extern ACPI_CPU_DATA mAcpiCpuData;
-extern SMM_DISPATCHER_MP_SYNC_DATA *mSmmMpSyncData;
-extern VOID *mGdtForAp;
-extern VOID *mIdtForAp;
-extern VOID *mMachineCheckHandlerForAp;
-extern UINTN mSmmStackArrayBase;
-extern UINTN mSmmStackArrayEnd;
-extern UINTN mSmmStackSize;
-extern EFI_SMM_CPU_SERVICE_PROTOCOL mSmmCpuService;
-extern IA32_DESCRIPTOR gcSmiInitGdtr;
-extern SMM_CPU_SEMAPHORES mSmmCpuSemaphores;
-extern UINTN mSemaphoreSize;
-extern SPIN_LOCK *mPFLock;
-extern SPIN_LOCK *mConfigSmmCodeAccessCheckLock;
-
-/**
- Create 4G PageTable in SMRAM.
-
- @param ExtraPages Additional page numbers besides for 4G memory
- @param Is32BitPageTable Whether the page table is 32-bit PAE
- @return PageTable Address
-
-**/
-UINT32
-Gen4GPageTable (
- IN UINTN ExtraPages,
- IN BOOLEAN Is32BitPageTable
- );
-
-
-/**
- Initialize global data for MP synchronization.
-
- @param Stacks Base address of SMI stack buffer for all processors.
- @param StackSize Stack size for each processor in SMM.
-
-**/
-UINT32
-InitializeMpServiceData (
- IN VOID *Stacks,
- IN UINTN StackSize
- );
-
-/**
- Initialize Timer for SMM AP Sync.
-
-**/
-VOID
-InitializeSmmTimer (
- VOID
- );
-
-/**
- Start Timer for SMM AP Sync.
-
-**/
-UINT64
-EFIAPI
-StartSyncTimer (
- VOID
- );
-
-/**
- Check if the SMM AP Sync timer is timeout.
-
- @param Timer The start timer from the begin.
-
-**/
-BOOLEAN
-EFIAPI
-IsSyncTimerTimeout (
- IN UINT64 Timer
- );
-
-/**
- Initialize IDT for SMM Stack Guard.
-
-**/
-VOID
-EFIAPI
-InitializeIDTSmmStackGuard (
- VOID
- );
-
-/**
- Initialize Gdt for all processors.
-
- @param[in] Cr3 CR3 value.
- @param[out] GdtStepSize The step size for GDT table.
-
- @return GdtBase for processor 0.
- GdtBase for processor X is: GdtBase + (GdtStepSize * X)
-**/
-VOID *
-InitGdt (
- IN UINTN Cr3,
- OUT UINTN *GdtStepSize
- );
-
-/**
-
- Register the SMM Foundation entry point.
-
- @param This Pointer to EFI_SMM_CONFIGURATION_PROTOCOL instance
- @param SmmEntryPoint SMM Foundation EntryPoint
-
- @retval EFI_SUCCESS Successfully to register SMM foundation entry point
-
-**/
-EFI_STATUS
-EFIAPI
-RegisterSmmEntry (
- IN CONST EFI_SMM_CONFIGURATION_PROTOCOL *This,
- IN EFI_SMM_ENTRY_POINT SmmEntryPoint
- );
-
-/**
- Create PageTable for SMM use.
-
- @return PageTable Address
-
-**/
-UINT32
-SmmInitPageTable (
- VOID
- );
-
-/**
- Schedule a procedure to run on the specified CPU.
-
- @param Procedure The address of the procedure to run
- @param CpuIndex Target CPU number
- @param ProcArguments The parameter to pass to the procedure
-
- @retval EFI_INVALID_PARAMETER CpuNumber not valid
- @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP
- @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM
- @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy
- @retval EFI_SUCCESS - The procedure has been successfully scheduled
-
-**/
-EFI_STATUS
-EFIAPI
-SmmStartupThisAp (
- IN EFI_AP_PROCEDURE Procedure,
- IN UINTN CpuIndex,
- IN OUT VOID *ProcArguments OPTIONAL
- );
-
-/**
- Schedule a procedure to run on the specified CPU in a blocking fashion.
-
- @param Procedure The address of the procedure to run
- @param CpuIndex Target CPU Index
- @param ProcArguments The parameter to pass to the procedure
-
- @retval EFI_INVALID_PARAMETER CpuNumber not valid
- @retval EFI_INVALID_PARAMETER CpuNumber specifying BSP
- @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber did not enter SMM
- @retval EFI_INVALID_PARAMETER The AP specified by CpuNumber is busy
- @retval EFI_SUCCESS The procedure has been successfully scheduled
-
-**/
-EFI_STATUS
-EFIAPI
-SmmBlockingStartupThisAp (
- IN EFI_AP_PROCEDURE Procedure,
- IN UINTN CpuIndex,
- IN OUT VOID *ProcArguments OPTIONAL
- );
-
-/**
- Initialize MP synchronization data.
-
-**/
-VOID
-EFIAPI
-InitializeMpSyncData (
- VOID
- );
-
-/**
-
- Find out SMRAM information including SMRR base and SMRR size.
-
- @param SmrrBase SMRR base
- @param SmrrSize SMRR size
-
-**/
-VOID
-FindSmramInfo (
- OUT UINT32 *SmrrBase,
- OUT UINT32 *SmrrSize
- );
-
-/**
- The function is invoked before SMBASE relocation in S3 path to restores CPU status.
-
- The function is invoked before SMBASE relocation in S3 path. It does first time microcode load
- and restores MTRRs for both BSP and APs.
-
-**/
-VOID
-EarlyInitializeCpu (
- VOID
- );
-
-/**
- The function is invoked after SMBASE relocation in S3 path to restores CPU status.
-
- The function is invoked after SMBASE relocation in S3 path. It restores configuration according to
- data saved by normal boot path for both BSP and APs.
-
-**/
-VOID
-InitializeCpu (
- VOID
- );
-
-/**
- Page Fault handler for SMM use.
-
- @param InterruptType Defines the type of interrupt or exception that
- occurred on the processor.This parameter is processor architecture specific.
- @param SystemContext A pointer to the processor context when
- the interrupt occurred on the processor.
-**/
-VOID
-EFIAPI
-SmiPFHandler (
- IN EFI_EXCEPTION_TYPE InterruptType,
- IN EFI_SYSTEM_CONTEXT SystemContext
- );
-
-/**
- Perform the remaining tasks.
-
-**/
-VOID
-PerformRemainingTasks (
- VOID
- );
-
-/**
- Perform the pre tasks.
-
-**/
-VOID
-PerformPreTasks (
- VOID
- );
-
-/**
- Initialize MSR spin lock by MSR index.
-
- @param MsrIndex MSR index value.
-
-**/
-VOID
-InitMsrSpinLockByIndex (
- IN UINT32 MsrIndex
- );
-
-/**
- Hook return address of SMM Save State so that semaphore code
- can be executed immediately after AP exits SMM to indicate to
- the BSP that an AP has exited SMM after SMBASE relocation.
-
- @param[in] CpuIndex The processor index.
- @param[in] RebasedFlag A pointer to a flag that is set to TRUE
- immediately after AP exits SMM.
-
-**/
-VOID
-SemaphoreHook (
- IN UINTN CpuIndex,
- IN volatile BOOLEAN *RebasedFlag
- );
-
-/**
-Configure SMM Code Access Check feature for all processors.
-SMM Feature Control MSR will be locked after configuration.
-**/
-VOID
-ConfigSmmCodeAccessCheck (
- VOID
- );
-
-/**
- Hook the code executed immediately after an RSM instruction on the currently
- executing CPU. The mode of code executed immediately after RSM must be
- detected, and the appropriate hook must be selected. Always clear the auto
- HALT restart flag if it is set.
-
- @param[in] CpuIndex The processor index for the currently
- executing CPU.
- @param[in] CpuState Pointer to SMRAM Save State Map for the
- currently executing CPU.
- @param[in] NewInstructionPointer32 Instruction pointer to use if resuming to
- 32-bit mode from 64-bit SMM.
- @param[in] NewInstructionPointer Instruction pointer to use if resuming to
- same mode as SMM.
-
- @retval The value of the original instruction pointer before it was hooked.
-
-**/
-UINT64
-EFIAPI
-HookReturnFromSmm (
- IN UINTN CpuIndex,
- SMRAM_SAVE_STATE_MAP *CpuState,
- UINT64 NewInstructionPointer32,
- UINT64 NewInstructionPointer
- );
-
-/**
- Get the size of the SMI Handler in bytes.
-
- @retval The size, in bytes, of the SMI Handler.
-
-**/
-UINTN
-EFIAPI
-GetSmiHandlerSize (
- VOID
- );
-
-/**
- Install the SMI handler for the CPU specified by CpuIndex. This function
- is called by the CPU that was elected as monarch during System Management
- Mode initialization.
-
- @param[in] CpuIndex The index of the CPU to install the custom SMI handler.
- The value must be between 0 and the NumberOfCpus field
- in the System Management System Table (SMST).
- @param[in] SmBase The SMBASE address for the CPU specified by CpuIndex.
- @param[in] SmiStack The stack to use when an SMI is processed by the
- the CPU specified by CpuIndex.
- @param[in] StackSize The size, in bytes, if the stack used when an SMI is
- processed by the CPU specified by CpuIndex.
- @param[in] GdtBase The base address of the GDT to use when an SMI is
- processed by the CPU specified by CpuIndex.
- @param[in] GdtSize The size, in bytes, of the GDT used when an SMI is
- processed by the CPU specified by CpuIndex.
- @param[in] IdtBase The base address of the IDT to use when an SMI is
- processed by the CPU specified by CpuIndex.
- @param[in] IdtSize The size, in bytes, of the IDT used when an SMI is
- processed by the CPU specified by CpuIndex.
- @param[in] Cr3 The base address of the page tables to use when an SMI
- is processed by the CPU specified by CpuIndex.
-**/
-VOID
-EFIAPI
-InstallSmiHandler (
- IN UINTN CpuIndex,
- IN UINT32 SmBase,
- IN VOID *SmiStack,
- IN UINTN StackSize,
- IN UINTN GdtBase,
- IN UINTN GdtSize,
- IN UINTN IdtBase,
- IN UINTN IdtSize,
- IN UINT32 Cr3
- );
-
-/**
- Search module name by input IP address and output it.
-
- @param CallerIpAddress Caller instruction pointer.
-
-**/
-VOID
-DumpModuleInfoByIp (
- IN UINTN CallerIpAddress
- );
-
-/**
- This API provides a way to allocate memory for page table.
-
- This API can be called more once to allocate memory for page tables.
-
- Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
- allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
- is returned. If there is not enough memory remaining to satisfy the request, then NULL is
- returned.
-
- @param Pages The number of 4 KB pages to allocate.
-
- @return A pointer to the allocated buffer or NULL if allocation fails.
-
-**/
-VOID *
-AllocatePageTableMemory (
- IN UINTN Pages
- );
-
-#endif
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
deleted file mode 100644
index 122318f02e..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
+++ /dev/null
@@ -1,161 +0,0 @@
-## @file
-# CPU SMM driver.
-#
-# This SMM driver performs SMM initialization, deploy SMM Entry Vector,
-# provides CPU specific services in SMM.
-#
-# 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.
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = PiSmmCpuDxeSmm
- MODULE_UNI_FILE = PiSmmCpuDxeSmm.uni
- FILE_GUID = A3FF0EF5-0C28-42f5-B544-8C7DE1E80014
- MODULE_TYPE = DXE_SMM_DRIVER
- VERSION_STRING = 1.0
- PI_SPECIFICATION_VERSION = 0x0001000A
- ENTRY_POINT = PiCpuSmmEntry
-
-#
-# The following information is for reference only and not required by the build tools.
-#
-# VALID_ARCHITECTURES = IA32 X64
-#
-
-[Sources]
- PiSmmCpuDxeSmm.c
- PiSmmCpuDxeSmm.h
- MpService.c
- SyncTimer.c
- CpuS3.c
- CpuService.c
- CpuService.h
- SmmProfile.c
- SmmProfile.h
- SmmProfileInternal.h
- SmramSaveState.c
-
-[Sources.Ia32]
- Ia32/Semaphore.c
- Ia32/PageTbl.c
- Ia32/SmmFuncsArch.c
- Ia32/SmmProfileArch.c
- Ia32/SmmProfileArch.h
- Ia32/SmmInit.asm | MSFT
- Ia32/SmiEntry.asm | MSFT
- Ia32/SmiException.asm | MSFT
- Ia32/MpFuncs.asm | MSFT
-
- Ia32/SmmInit.asm | INTEL
- Ia32/SmiEntry.asm | INTEL
- Ia32/SmiException.asm | INTEL
- Ia32/MpFuncs.asm | INTEL
-
- Ia32/SmmInit.S | GCC
- Ia32/SmiEntry.S | GCC
- Ia32/SmiException.S | GCC
- Ia32/MpFuncs.S | GCC
-
-[Sources.X64]
- X64/Semaphore.c
- X64/PageTbl.c
- X64/SmmFuncsArch.c
- X64/SmmProfileArch.c
- X64/SmmProfileArch.h
- X64/SmmInit.asm | MSFT
- X64/SmiEntry.asm | MSFT
- X64/SmiException.asm | MSFT
- X64/MpFuncs.asm | MSFT
-
- X64/SmmInit.asm | INTEL
- X64/SmiEntry.asm | INTEL
- X64/SmiException.asm | INTEL
- X64/MpFuncs.asm | INTEL
-
- X64/SmmInit.S | GCC
- X64/SmiEntry.S | GCC
- X64/SmiException.S | GCC
- X64/MpFuncs.S | GCC
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
- UefiCpuPkg/UefiCpuPkg.dec
-
-[LibraryClasses]
- UefiDriverEntryPoint
- UefiRuntimeServicesTableLib
- CacheMaintenanceLib
- PcdLib
- DebugLib
- BaseLib
- SynchronizationLib
- BaseMemoryLib
- MtrrLib
- IoLib
- TimerLib
- SmmServicesTableLib
- MemoryAllocationLib
- DebugAgentLib
- HobLib
- PciLib
- LocalApicLib
- UefiCpuLib
- SmmCpuPlatformHookLib
- CpuExceptionHandlerLib
- UefiLib
- DxeServicesTableLib
- CpuLib
- ReportStatusCodeLib
- SmmCpuFeaturesLib
- PeCoffGetEntryPointLib
-
-[Protocols]
- gEfiSmmAccess2ProtocolGuid ## CONSUMES
- gEfiMpServiceProtocolGuid ## CONSUMES
- gEfiSmmConfigurationProtocolGuid ## PRODUCES
- gEfiSmmCpuProtocolGuid ## PRODUCES
- gEfiSmmReadyToLockProtocolGuid ## NOTIFY
- gEfiSmmCpuServiceProtocolGuid ## PRODUCES
-
-[Guids]
- gEfiAcpiVariableGuid ## SOMETIMES_CONSUMES ## HOB # it is used for S3 boot.
- gEfiGlobalVariableGuid ## SOMETIMES_PRODUCES ## Variable:L"SmmProfileData"
- gEfiAcpi20TableGuid ## SOMETIMES_CONSUMES ## SystemTable
- gEfiAcpi10TableGuid ## SOMETIMES_CONSUMES ## SystemTable
-
-[FeaturePcd]
- gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmDebug ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmBlockStartupThisAp ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmEnableBspElection ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugSupport ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackGuard ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileEnable ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileRingBuffer ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmFeatureControlMsrLock ## CONSUMES
-
-[Pcd]
- gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber ## SOMETIMES_CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmProfileSize ## SOMETIMES_CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmStackSize ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmApSyncTimeout ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuS3DataAddress ## SOMETIMES_CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuHotPlugDataAddress ## SOMETIMES_PRODUCES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmCodeAccessCheckEnable ## CONSUMES
- gUefiCpuPkgTokenSpaceGuid.PcdCpuSmmSyncMode ## CONSUMES
-
-[Depex]
- gEfiMpServiceProtocolGuid
-
-[UserExtensions.TianoCore."ExtraFiles"]
- PiSmmCpuDxeSmmExtra.uni
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.uni b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.uni
deleted file mode 100644
index 98eae1d697..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.uni
+++ /dev/null
@@ -1,21 +0,0 @@
-// /** @file
-// CPU SMM driver.
-//
-// This SMM driver performs SMM initialization, deploy SMM Entry Vector,
-// provides CPU specific services in SMM.
-//
-// 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.
-//
-// **/
-
-#string STR_MODULE_ABSTRACT #language en-US "CPU SMM driver"
-
-#string STR_MODULE_DESCRIPTION #language en-US "This SMM driver performs SMM initialization, deploys SMM Entry Vector, and provides CPU-specific services in SMM."
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmmExtra.uni b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmmExtra.uni
deleted file mode 100644
index d0a8d54006..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmmExtra.uni
+++ /dev/null
@@ -1,18 +0,0 @@
-// /** @file
-// PiSmmCpuDxeSmm Localized Strings and Content
-//
-// Copyright (c) 2013 - 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.
-//
-// **/
-
-#string STR_PROPERTIES_MODULE_NAME
-#language en-US
-"Processor SMM Initialization DXE Driver"
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
deleted file mode 100644
index 71fff0e5b0..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c
+++ /dev/null
@@ -1,1434 +0,0 @@
-/** @file
-Enable SMM profile.
-
-Copyright (c) 2012 - 2016, 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"
-#include "SmmProfileInternal.h"
-
-UINT32 mSmmProfileCr3;
-
-SMM_PROFILE_HEADER *mSmmProfileBase;
-MSR_DS_AREA_STRUCT *mMsrDsAreaBase;
-//
-// The buffer to store SMM profile data.
-//
-UINTN mSmmProfileSize;
-
-//
-// The buffer to enable branch trace store.
-//
-UINTN mMsrDsAreaSize = SMM_PROFILE_DTS_SIZE;
-
-//
-// The flag indicates if execute-disable is supported by processor.
-//
-BOOLEAN mXdSupported = FALSE;
-
-//
-// The flag indicates if execute-disable is enabled on processor.
-//
-BOOLEAN mXdEnabled = FALSE;
-
-//
-// The flag indicates if BTS is supported by processor.
-//
-BOOLEAN mBtsSupported = FALSE;
-
-//
-// The flag indicates if SMM profile starts to record data.
-//
-BOOLEAN mSmmProfileStart = FALSE;
-
-//
-// Record the page fault exception count for one instruction execution.
-//
-UINTN *mPFEntryCount;
-
-UINT64 (*mLastPFEntryValue)[MAX_PF_ENTRY_COUNT];
-UINT64 *(*mLastPFEntryPointer)[MAX_PF_ENTRY_COUNT];
-
-MSR_DS_AREA_STRUCT **mMsrDsArea;
-BRANCH_TRACE_RECORD **mMsrBTSRecord;
-UINTN mBTSRecordNumber;
-PEBS_RECORD **mMsrPEBSRecord;
-
-//
-// These memory ranges are always present, they does not generate the access type of page fault exception,
-// but they possibly generate instruction fetch type of page fault exception.
-//
-MEMORY_PROTECTION_RANGE *mProtectionMemRange = NULL;
-UINTN mProtectionMemRangeCount = 0;
-
-//
-// Some predefined memory ranges.
-//
-MEMORY_PROTECTION_RANGE mProtectionMemRangeTemplate[] = {
- //
- // SMRAM range (to be fixed in runtime).
- // It is always present and instruction fetches are allowed.
- //
- {{0x00000000, 0x00000000},TRUE,FALSE},
-
- //
- // SMM profile data range( to be fixed in runtime).
- // It is always present and instruction fetches are not allowed.
- //
- {{0x00000000, 0x00000000},TRUE,TRUE},
-
- //
- // Future extended range could be added here.
- //
-
- //
- // PCI MMIO ranges (to be added in runtime).
- // They are always present and instruction fetches are not allowed.
- //
-};
-
-//
-// These memory ranges are mapped by 4KB-page instead of 2MB-page.
-//
-MEMORY_RANGE *mSplitMemRange = NULL;
-UINTN mSplitMemRangeCount = 0;
-
-//
-// SMI command port.
-//
-UINT32 mSmiCommandPort;
-
-/**
- Disable branch trace store.
-
-**/
-VOID
-DisableBTS (
- VOID
- )
-{
- AsmMsrAnd64 (MSR_DEBUG_CTL, ~((UINT64)(MSR_DEBUG_CTL_BTS | MSR_DEBUG_CTL_TR)));
-}
-
-/**
- Enable branch trace store.
-
-**/
-VOID
-EnableBTS (
- VOID
- )
-{
- AsmMsrOr64 (MSR_DEBUG_CTL, (MSR_DEBUG_CTL_BTS | MSR_DEBUG_CTL_TR));
-}
-
-/**
- Get CPU Index from APIC ID.
-
-**/
-UINTN
-GetCpuIndex (
- VOID
- )
-{
- UINTN Index;
- UINT32 ApicId;
-
- ApicId = GetApicId ();
-
- for (Index = 0; Index < PcdGet32 (PcdCpuMaxLogicalProcessorNumber); Index++) {
- if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == ApicId) {
- return Index;
- }
- }
- ASSERT (FALSE);
- return 0;
-}
-
-/**
- Get the source of IP after execute-disable exception is triggered.
-
- @param CpuIndex The index of CPU.
- @param DestinationIP The destination address.
-
-**/
-UINT64
-GetSourceFromDestinationOnBts (
- UINTN CpuIndex,
- UINT64 DestinationIP
- )
-{
- BRANCH_TRACE_RECORD *CurrentBTSRecord;
- UINTN Index;
- BOOLEAN FirstMatch;
-
- FirstMatch = FALSE;
-
- CurrentBTSRecord = (BRANCH_TRACE_RECORD *)mMsrDsArea[CpuIndex]->BTSIndex;
- for (Index = 0; Index < mBTSRecordNumber; Index++) {
- if ((UINTN)CurrentBTSRecord < (UINTN)mMsrBTSRecord[CpuIndex]) {
- //
- // Underflow
- //
- CurrentBTSRecord = (BRANCH_TRACE_RECORD *)((UINTN)mMsrDsArea[CpuIndex]->BTSAbsoluteMaximum - 1);
- CurrentBTSRecord --;
- }
- if (CurrentBTSRecord->LastBranchTo == DestinationIP) {
- //
- // Good! find 1st one, then find 2nd one.
- //
- if (!FirstMatch) {
- //
- // The first one is DEBUG exception
- //
- FirstMatch = TRUE;
- } else {
- //
- // Good find proper one.
- //
- return CurrentBTSRecord->LastBranchFrom;
- }
- }
- CurrentBTSRecord--;
- }
-
- return 0;
-}
-
-/**
- SMM profile specific INT 1 (single-step) exception handler.
-
- @param InterruptType Defines the type of interrupt or exception that
- occurred on the processor.This parameter is processor architecture specific.
- @param SystemContext A pointer to the processor context when
- the interrupt occurred on the processor.
-**/
-VOID
-EFIAPI
-DebugExceptionHandler (
- IN EFI_EXCEPTION_TYPE InterruptType,
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- UINTN CpuIndex;
- UINTN PFEntry;
-
- if (!mSmmProfileStart) {
- return;
- }
- CpuIndex = GetCpuIndex ();
-
- //
- // Clear last PF entries
- //
- for (PFEntry = 0; PFEntry < mPFEntryCount[CpuIndex]; PFEntry++) {
- *mLastPFEntryPointer[CpuIndex][PFEntry] = mLastPFEntryValue[CpuIndex][PFEntry];
- }
-
- //
- // Reset page fault exception count for next page fault.
- //
- mPFEntryCount[CpuIndex] = 0;
-
- //
- // Flush TLB
- //
- CpuFlushTlb ();
-
- //
- // Clear TF in EFLAGS
- //
- ClearTrapFlag (SystemContext);
-}
-
-/**
- Check if the memory address will be mapped by 4KB-page.
-
- @param Address The address of Memory.
- @param Nx The flag indicates if the memory is execute-disable.
-
-**/
-BOOLEAN
-IsAddressValid (
- IN EFI_PHYSICAL_ADDRESS Address,
- IN BOOLEAN *Nx
- )
-{
- UINTN Index;
-
- *Nx = FALSE;
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
- //
- // Check configuration
- //
- for (Index = 0; Index < mProtectionMemRangeCount; Index++) {
- if ((Address >= mProtectionMemRange[Index].Range.Base) && (Address < mProtectionMemRange[Index].Range.Top)) {
- *Nx = mProtectionMemRange[Index].Nx;
- return mProtectionMemRange[Index].Present;
- }
- }
- *Nx = TRUE;
- return FALSE;
-
- } else {
- if ((Address < mCpuHotPlugData.SmrrBase) ||
- (Address >= mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) {
- *Nx = TRUE;
- }
- return TRUE;
- }
-}
-
-/**
- Check if the memory address will be mapped by 4KB-page.
-
- @param Address The address of Memory.
-
-**/
-BOOLEAN
-IsAddressSplit (
- IN EFI_PHYSICAL_ADDRESS Address
- )
-{
- UINTN Index;
-
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
- //
- // Check configuration
- //
- for (Index = 0; Index < mSplitMemRangeCount; Index++) {
- if ((Address >= mSplitMemRange[Index].Base) && (Address < mSplitMemRange[Index].Top)) {
- return TRUE;
- }
- }
- } else {
- if (Address < mCpuHotPlugData.SmrrBase) {
- if ((mCpuHotPlugData.SmrrBase - Address) < BASE_2MB) {
- return TRUE;
- }
- } else if (Address > (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize - BASE_2MB)) {
- if ((Address - (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize - BASE_2MB)) < BASE_2MB) {
- return TRUE;
- }
- }
- }
- //
- // Return default
- //
- return FALSE;
-}
-
-/**
- Initialize the protected memory ranges and the 4KB-page mapped memory ranges.
-
-**/
-VOID
-InitProtectedMemRange (
- VOID
- )
-{
- UINTN Index;
- UINTN NumberOfDescriptors;
- UINTN NumberOfMmioDescriptors;
- UINTN NumberOfProtectRange;
- UINTN NumberOfSpliteRange;
- EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
- UINTN TotalSize;
- EFI_PHYSICAL_ADDRESS ProtectBaseAddress;
- EFI_PHYSICAL_ADDRESS ProtectEndAddress;
- EFI_PHYSICAL_ADDRESS Top2MBAlignedAddress;
- EFI_PHYSICAL_ADDRESS Base2MBAlignedAddress;
- UINT64 High4KBPageSize;
- UINT64 Low4KBPageSize;
-
- NumberOfDescriptors = 0;
- NumberOfMmioDescriptors = 0;
- NumberOfSpliteRange = 0;
- MemorySpaceMap = NULL;
-
- //
- // Get MMIO ranges from GCD and add them into protected memory ranges.
- //
- gDS->GetMemorySpaceMap (
- &NumberOfDescriptors,
- &MemorySpaceMap
- );
- for (Index = 0; Index < NumberOfDescriptors; Index++) {
- if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {
- NumberOfMmioDescriptors++;
- }
- }
-
- if (NumberOfMmioDescriptors != 0) {
- TotalSize = NumberOfMmioDescriptors * sizeof (MEMORY_PROTECTION_RANGE) + sizeof (mProtectionMemRangeTemplate);
- mProtectionMemRange = (MEMORY_PROTECTION_RANGE *) AllocateZeroPool (TotalSize);
- ASSERT (mProtectionMemRange != NULL);
- mProtectionMemRangeCount = TotalSize / sizeof (MEMORY_PROTECTION_RANGE);
-
- //
- // Copy existing ranges.
- //
- CopyMem (mProtectionMemRange, mProtectionMemRangeTemplate, sizeof (mProtectionMemRangeTemplate));
-
- //
- // Create split ranges which come from protected ranges.
- //
- TotalSize = (TotalSize / sizeof (MEMORY_PROTECTION_RANGE)) * sizeof (MEMORY_RANGE);
- mSplitMemRange = (MEMORY_RANGE *) AllocateZeroPool (TotalSize);
- ASSERT (mSplitMemRange != NULL);
-
- //
- // Create MMIO ranges which are set to present and execution-disable.
- //
- NumberOfProtectRange = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE);
- for (Index = 0; Index < NumberOfDescriptors; Index++) {
- if (MemorySpaceMap[Index].GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) {
- continue;
- }
- mProtectionMemRange[NumberOfProtectRange].Range.Base = MemorySpaceMap[Index].BaseAddress;
- mProtectionMemRange[NumberOfProtectRange].Range.Top = MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length;
- mProtectionMemRange[NumberOfProtectRange].Present = TRUE;
- mProtectionMemRange[NumberOfProtectRange].Nx = TRUE;
- NumberOfProtectRange++;
- }
- }
-
- //
- // According to protected ranges, create the ranges which will be mapped by 2KB page.
- //
- NumberOfSpliteRange = 0;
- NumberOfProtectRange = mProtectionMemRangeCount;
- for (Index = 0; Index < NumberOfProtectRange; Index++) {
- //
- // If MMIO base address is not 2MB alignment, make 2MB alignment for create 4KB page in page table.
- //
- ProtectBaseAddress = mProtectionMemRange[Index].Range.Base;
- ProtectEndAddress = mProtectionMemRange[Index].Range.Top;
- if (((ProtectBaseAddress & (SIZE_2MB - 1)) != 0) || ((ProtectEndAddress & (SIZE_2MB - 1)) != 0)) {
- //
- // Check if it is possible to create 4KB-page for not 2MB-aligned range and to create 2MB-page for 2MB-aligned range.
- // A mix of 4KB and 2MB page could save SMRAM space.
- //
- Top2MBAlignedAddress = ProtectEndAddress & ~(SIZE_2MB - 1);
- Base2MBAlignedAddress = (ProtectBaseAddress + SIZE_2MB - 1) & ~(SIZE_2MB - 1);
- if ((Top2MBAlignedAddress > Base2MBAlignedAddress) &&
- ((Top2MBAlignedAddress - Base2MBAlignedAddress) >= SIZE_2MB)) {
- //
- // There is an range which could be mapped by 2MB-page.
- //
- High4KBPageSize = ((ProtectEndAddress + SIZE_2MB - 1) & ~(SIZE_2MB - 1)) - (ProtectEndAddress & ~(SIZE_2MB - 1));
- Low4KBPageSize = ((ProtectBaseAddress + SIZE_2MB - 1) & ~(SIZE_2MB - 1)) - (ProtectBaseAddress & ~(SIZE_2MB - 1));
- if (High4KBPageSize != 0) {
- //
- // Add not 2MB-aligned range to be mapped by 4KB-page.
- //
- mSplitMemRange[NumberOfSpliteRange].Base = ProtectEndAddress & ~(SIZE_2MB - 1);
- mSplitMemRange[NumberOfSpliteRange].Top = (ProtectEndAddress + SIZE_2MB - 1) & ~(SIZE_2MB - 1);
- NumberOfSpliteRange++;
- }
- if (Low4KBPageSize != 0) {
- //
- // Add not 2MB-aligned range to be mapped by 4KB-page.
- //
- mSplitMemRange[NumberOfSpliteRange].Base = ProtectBaseAddress & ~(SIZE_2MB - 1);
- mSplitMemRange[NumberOfSpliteRange].Top = (ProtectBaseAddress + SIZE_2MB - 1) & ~(SIZE_2MB - 1);
- NumberOfSpliteRange++;
- }
- } else {
- //
- // The range could only be mapped by 4KB-page.
- //
- mSplitMemRange[NumberOfSpliteRange].Base = ProtectBaseAddress & ~(SIZE_2MB - 1);
- mSplitMemRange[NumberOfSpliteRange].Top = (ProtectEndAddress + SIZE_2MB - 1) & ~(SIZE_2MB - 1);
- NumberOfSpliteRange++;
- }
- }
- }
-
- mSplitMemRangeCount = NumberOfSpliteRange;
-
- DEBUG ((EFI_D_INFO, "SMM Profile Memory Ranges:\n"));
- for (Index = 0; Index < mProtectionMemRangeCount; Index++) {
- DEBUG ((EFI_D_INFO, "mProtectionMemRange[%d].Base = %lx\n", Index, mProtectionMemRange[Index].Range.Base));
- DEBUG ((EFI_D_INFO, "mProtectionMemRange[%d].Top = %lx\n", Index, mProtectionMemRange[Index].Range.Top));
- }
- for (Index = 0; Index < mSplitMemRangeCount; Index++) {
- DEBUG ((EFI_D_INFO, "mSplitMemRange[%d].Base = %lx\n", Index, mSplitMemRange[Index].Base));
- DEBUG ((EFI_D_INFO, "mSplitMemRange[%d].Top = %lx\n", Index, mSplitMemRange[Index].Top));
- }
-}
-
-/**
- Update page table according to protected memory ranges and the 4KB-page mapped memory ranges.
-
-**/
-VOID
-InitPaging (
- VOID
- )
-{
- UINT64 *Pml4;
- UINT64 *Pde;
- UINT64 *Pte;
- UINT64 *Pt;
- UINTN Address;
- UINTN Level1;
- UINTN Level2;
- UINTN Level3;
- UINTN Level4;
- UINTN NumberOfPdpEntries;
- UINTN NumberOfPml4Entries;
- UINTN SizeOfMemorySpace;
- BOOLEAN Nx;
-
- if (sizeof (UINTN) == sizeof (UINT64)) {
- Pml4 = (UINT64*)(UINTN)mSmmProfileCr3;
- SizeOfMemorySpace = HighBitSet64 (gPhyMask) + 1;
- //
- // Calculate the table entries of PML4E and PDPTE.
- //
- if (SizeOfMemorySpace <= 39 ) {
- NumberOfPml4Entries = 1;
- NumberOfPdpEntries = (UINT32)LShiftU64 (1, (SizeOfMemorySpace - 30));
- } else {
- NumberOfPml4Entries = (UINT32)LShiftU64 (1, (SizeOfMemorySpace - 39));
- NumberOfPdpEntries = 512;
- }
- } else {
- NumberOfPml4Entries = 1;
- NumberOfPdpEntries = 4;
- }
-
- //
- // Go through page table and change 2MB-page into 4KB-page.
- //
- for (Level1 = 0; Level1 < NumberOfPml4Entries; Level1++) {
- if (sizeof (UINTN) == sizeof (UINT64)) {
- if ((Pml4[Level1] & IA32_PG_P) == 0) {
- //
- // If Pml4 entry does not exist, skip it
- //
- continue;
- }
- Pde = (UINT64 *)(UINTN)(Pml4[Level1] & PHYSICAL_ADDRESS_MASK);
- } else {
- Pde = (UINT64*)(UINTN)mSmmProfileCr3;
- }
- for (Level2 = 0; Level2 < NumberOfPdpEntries; Level2++, Pde++) {
- if ((*Pde & IA32_PG_P) == 0) {
- //
- // If PDE entry does not exist, skip it
- //
- continue;
- }
- Pte = (UINT64 *)(UINTN)(*Pde & PHYSICAL_ADDRESS_MASK);
- if (Pte == 0) {
- continue;
- }
- for (Level3 = 0; Level3 < SIZE_4KB / sizeof (*Pte); Level3++, Pte++) {
- if ((*Pte & IA32_PG_P) == 0) {
- //
- // If PTE entry does not exist, skip it
- //
- continue;
- }
- Address = (((Level2 << 9) + Level3) << 21);
-
- //
- // If it is 2M page, check IsAddressSplit()
- //
- if (((*Pte & IA32_PG_PS) != 0) && IsAddressSplit (Address)) {
- //
- // Based on current page table, create 4KB page table for split area.
- //
- ASSERT (Address == (*Pte & PHYSICAL_ADDRESS_MASK));
-
- Pt = AllocatePageTableMemory (1);
- ASSERT (Pt != NULL);
-
- // Split it
- for (Level4 = 0; Level4 < SIZE_4KB / sizeof(*Pt); Level4++) {
- Pt[Level4] = Address + ((Level4 << 12) | PAGE_ATTRIBUTE_BITS);
- } // end for PT
- *Pte = (UINTN)Pt | PAGE_ATTRIBUTE_BITS;
- } // end if IsAddressSplit
- } // end for PTE
- } // end for PDE
- }
-
- //
- // Go through page table and set several page table entries to absent or execute-disable.
- //
- DEBUG ((EFI_D_INFO, "Patch page table start ...\n"));
- for (Level1 = 0; Level1 < NumberOfPml4Entries; Level1++) {
- if (sizeof (UINTN) == sizeof (UINT64)) {
- if ((Pml4[Level1] & IA32_PG_P) == 0) {
- //
- // If Pml4 entry does not exist, skip it
- //
- continue;
- }
- Pde = (UINT64 *)(UINTN)(Pml4[Level1] & PHYSICAL_ADDRESS_MASK);
- } else {
- Pde = (UINT64*)(UINTN)mSmmProfileCr3;
- }
- for (Level2 = 0; Level2 < NumberOfPdpEntries; Level2++, Pde++) {
- if ((*Pde & IA32_PG_P) == 0) {
- //
- // If PDE entry does not exist, skip it
- //
- continue;
- }
- Pte = (UINT64 *)(UINTN)(*Pde & PHYSICAL_ADDRESS_MASK);
- if (Pte == 0) {
- continue;
- }
- for (Level3 = 0; Level3 < SIZE_4KB / sizeof (*Pte); Level3++, Pte++) {
- if ((*Pte & IA32_PG_P) == 0) {
- //
- // If PTE entry does not exist, skip it
- //
- continue;
- }
- Address = (((Level2 << 9) + Level3) << 21);
-
- if ((*Pte & IA32_PG_PS) != 0) {
- // 2MB page
-
- if (!IsAddressValid (Address, &Nx)) {
- //
- // Patch to remove Present flag and RW flag
- //
- *Pte = *Pte & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);
- }
- if (Nx && mXdSupported) {
- *Pte = *Pte | IA32_PG_NX;
- }
- } else {
- // 4KB page
- Pt = (UINT64 *)(UINTN)(*Pte & PHYSICAL_ADDRESS_MASK);
- if (Pt == 0) {
- continue;
- }
- for (Level4 = 0; Level4 < SIZE_4KB / sizeof(*Pt); Level4++, Pt++) {
- if (!IsAddressValid (Address, &Nx)) {
- *Pt = *Pt & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);
- }
- if (Nx && mXdSupported) {
- *Pt = *Pt | IA32_PG_NX;
- }
- Address += SIZE_4KB;
- } // end for PT
- } // end if PS
- } // end for PTE
- } // end for PDE
- }
-
- //
- // Flush TLB
- //
- CpuFlushTlb ();
- DEBUG ((EFI_D_INFO, "Patch page table done!\n"));
- //
- // Set execute-disable flag
- //
- mXdEnabled = TRUE;
-
- return ;
-}
-
-/**
- To find FADT in ACPI tables.
-
- @param AcpiTableGuid The GUID used to find ACPI table in UEFI ConfigurationTable.
-
- @return FADT table pointer.
-**/
-EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *
-FindAcpiFadtTableByAcpiGuid (
- IN EFI_GUID *AcpiTableGuid
- )
-{
- EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp;
- EFI_ACPI_DESCRIPTION_HEADER *Rsdt;
- EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;
- UINTN Index;
- UINT32 Data32;
- Rsdp = NULL;
- Rsdt = NULL;
- Fadt = NULL;
- //
- // found ACPI table RSD_PTR from system table
- //
- for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
- if (CompareGuid (&(gST->ConfigurationTable[Index].VendorGuid), AcpiTableGuid)) {
- //
- // A match was found.
- //
- Rsdp = gST->ConfigurationTable[Index].VendorTable;
- break;
- }
- }
-
- if (Rsdp == NULL) {
- return NULL;
- }
-
- Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->RsdtAddress;
- if (Rsdt == NULL || Rsdt->Signature != EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_TABLE_SIGNATURE) {
- return NULL;
- }
-
- for (Index = sizeof (EFI_ACPI_DESCRIPTION_HEADER); Index < Rsdt->Length; Index = Index + sizeof (UINT32)) {
-
- Data32 = *(UINT32 *) ((UINT8 *) Rsdt + Index);
- Fadt = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *) (UINT32 *) (UINTN) Data32;
- if (Fadt->Header.Signature == EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
- break;
- }
- }
-
- if (Fadt == NULL || Fadt->Header.Signature != EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE) {
- return NULL;
- }
-
- return Fadt;
-}
-
-/**
- To find FADT in ACPI tables.
-
- @return FADT table pointer.
-**/
-EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *
-FindAcpiFadtTable (
- VOID
- )
-{
- EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;
-
- Fadt = FindAcpiFadtTableByAcpiGuid (&gEfiAcpi20TableGuid);
- if (Fadt != NULL) {
- return Fadt;
- }
-
- return FindAcpiFadtTableByAcpiGuid (&gEfiAcpi10TableGuid);
-}
-
-/**
- To get system port address of the SMI Command Port in FADT table.
-
-**/
-VOID
-GetSmiCommandPort (
- VOID
- )
-{
- EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt;
-
- Fadt = FindAcpiFadtTable ();
- ASSERT (Fadt != NULL);
-
- mSmiCommandPort = Fadt->SmiCmd;
- DEBUG ((EFI_D_INFO, "mSmiCommandPort = %x\n", mSmiCommandPort));
-}
-
-/**
- Updates page table to make some memory ranges (like system memory) absent
- and make some memory ranges (like MMIO) present and execute disable. It also
- update 2MB-page to 4KB-page for some memory ranges.
-
-**/
-VOID
-SmmProfileStart (
- VOID
- )
-{
- //
- // The flag indicates SMM profile starts to work.
- //
- mSmmProfileStart = TRUE;
-}
-
-/**
- Initialize SMM profile in SmmReadyToLock protocol callback function.
-
- @param Protocol Points to the protocol's unique identifier.
- @param Interface Points to the interface instance.
- @param Handle The handle on which the interface was installed.
-
- @retval EFI_SUCCESS SmmReadyToLock protocol callback runs successfully.
-**/
-EFI_STATUS
-EFIAPI
-InitSmmProfileCallBack (
- IN CONST EFI_GUID *Protocol,
- IN VOID *Interface,
- IN EFI_HANDLE Handle
- )
-{
- //
- // Save to variable so that SMM profile data can be found.
- //
- gRT->SetVariable (
- SMM_PROFILE_NAME,
- &gEfiCallerIdGuid,
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
- sizeof(mSmmProfileBase),
- &mSmmProfileBase
- );
-
- //
- // Get Software SMI from FADT
- //
- GetSmiCommandPort ();
-
- //
- // Initialize protected memory range for patching page table later.
- //
- InitProtectedMemRange ();
-
- return EFI_SUCCESS;
-}
-
-/**
- Initialize SMM profile data structures.
-
-**/
-VOID
-InitSmmProfileInternal (
- VOID
- )
-{
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS Base;
- VOID *Registration;
- UINTN Index;
- UINTN MsrDsAreaSizePerCpu;
- UINTN TotalSize;
-
- mPFEntryCount = (UINTN *)AllocateZeroPool (sizeof (UINTN) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
- ASSERT (mPFEntryCount != NULL);
- mLastPFEntryValue = (UINT64 (*)[MAX_PF_ENTRY_COUNT])AllocateZeroPool (
- sizeof (mLastPFEntryValue[0]) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
- ASSERT (mLastPFEntryValue != NULL);
- mLastPFEntryPointer = (UINT64 *(*)[MAX_PF_ENTRY_COUNT])AllocateZeroPool (
- sizeof (mLastPFEntryPointer[0]) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
- ASSERT (mLastPFEntryPointer != NULL);
-
- //
- // Allocate memory for SmmProfile below 4GB.
- // The base address
- //
- mSmmProfileSize = PcdGet32 (PcdCpuSmmProfileSize);
- ASSERT ((mSmmProfileSize & 0xFFF) == 0);
-
- if (mBtsSupported) {
- TotalSize = mSmmProfileSize + mMsrDsAreaSize;
- } else {
- TotalSize = mSmmProfileSize;
- }
-
- Base = 0xFFFFFFFF;
- Status = gBS->AllocatePages (
- AllocateMaxAddress,
- EfiReservedMemoryType,
- EFI_SIZE_TO_PAGES (TotalSize),
- &Base
- );
- ASSERT_EFI_ERROR (Status);
- ZeroMem ((VOID *)(UINTN)Base, TotalSize);
- mSmmProfileBase = (SMM_PROFILE_HEADER *)(UINTN)Base;
-
- //
- // Initialize SMM profile data header.
- //
- mSmmProfileBase->HeaderSize = sizeof (SMM_PROFILE_HEADER);
- mSmmProfileBase->MaxDataEntries = (UINT64)((mSmmProfileSize - sizeof(SMM_PROFILE_HEADER)) / sizeof (SMM_PROFILE_ENTRY));
- mSmmProfileBase->MaxDataSize = MultU64x64 (mSmmProfileBase->MaxDataEntries, sizeof(SMM_PROFILE_ENTRY));
- mSmmProfileBase->CurDataEntries = 0;
- mSmmProfileBase->CurDataSize = 0;
- mSmmProfileBase->TsegStart = mCpuHotPlugData.SmrrBase;
- mSmmProfileBase->TsegSize = mCpuHotPlugData.SmrrSize;
- mSmmProfileBase->NumSmis = 0;
- mSmmProfileBase->NumCpus = gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;
-
- if (mBtsSupported) {
- mMsrDsArea = (MSR_DS_AREA_STRUCT **)AllocateZeroPool (sizeof (MSR_DS_AREA_STRUCT *) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
- ASSERT (mMsrDsArea != NULL);
- mMsrBTSRecord = (BRANCH_TRACE_RECORD **)AllocateZeroPool (sizeof (BRANCH_TRACE_RECORD *) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
- ASSERT (mMsrBTSRecord != NULL);
- mMsrPEBSRecord = (PEBS_RECORD **)AllocateZeroPool (sizeof (PEBS_RECORD *) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber));
- ASSERT (mMsrPEBSRecord != NULL);
-
- mMsrDsAreaBase = (MSR_DS_AREA_STRUCT *)((UINTN)Base + mSmmProfileSize);
- MsrDsAreaSizePerCpu = mMsrDsAreaSize / PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
- mBTSRecordNumber = (MsrDsAreaSizePerCpu - sizeof(PEBS_RECORD) * PEBS_RECORD_NUMBER - sizeof(MSR_DS_AREA_STRUCT)) / sizeof(BRANCH_TRACE_RECORD);
- for (Index = 0; Index < PcdGet32 (PcdCpuMaxLogicalProcessorNumber); Index++) {
- mMsrDsArea[Index] = (MSR_DS_AREA_STRUCT *)((UINTN)mMsrDsAreaBase + MsrDsAreaSizePerCpu * Index);
- mMsrBTSRecord[Index] = (BRANCH_TRACE_RECORD *)((UINTN)mMsrDsArea[Index] + sizeof(MSR_DS_AREA_STRUCT));
- mMsrPEBSRecord[Index] = (PEBS_RECORD *)((UINTN)mMsrDsArea[Index] + MsrDsAreaSizePerCpu - sizeof(PEBS_RECORD) * PEBS_RECORD_NUMBER);
-
- mMsrDsArea[Index]->BTSBufferBase = (UINTN)mMsrBTSRecord[Index];
- mMsrDsArea[Index]->BTSIndex = mMsrDsArea[Index]->BTSBufferBase;
- mMsrDsArea[Index]->BTSAbsoluteMaximum = mMsrDsArea[Index]->BTSBufferBase + mBTSRecordNumber * sizeof(BRANCH_TRACE_RECORD) + 1;
- mMsrDsArea[Index]->BTSInterruptThreshold = mMsrDsArea[Index]->BTSAbsoluteMaximum + 1;
-
- mMsrDsArea[Index]->PEBSBufferBase = (UINTN)mMsrPEBSRecord[Index];
- mMsrDsArea[Index]->PEBSIndex = mMsrDsArea[Index]->PEBSBufferBase;
- mMsrDsArea[Index]->PEBSAbsoluteMaximum = mMsrDsArea[Index]->PEBSBufferBase + PEBS_RECORD_NUMBER * sizeof(PEBS_RECORD) + 1;
- mMsrDsArea[Index]->PEBSInterruptThreshold = mMsrDsArea[Index]->PEBSAbsoluteMaximum + 1;
- }
- }
-
- mProtectionMemRange = mProtectionMemRangeTemplate;
- mProtectionMemRangeCount = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE);
-
- //
- // Update TSeg entry.
- //
- mProtectionMemRange[0].Range.Base = mCpuHotPlugData.SmrrBase;
- mProtectionMemRange[0].Range.Top = mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize;
-
- //
- // Update SMM profile entry.
- //
- mProtectionMemRange[1].Range.Base = (EFI_PHYSICAL_ADDRESS)(UINTN)mSmmProfileBase;
- mProtectionMemRange[1].Range.Top = (EFI_PHYSICAL_ADDRESS)(UINTN)mSmmProfileBase + TotalSize;
-
- //
- // Allocate memory reserved for creating 4KB pages.
- //
- InitPagesForPFHandler ();
-
- //
- // Start SMM profile when SmmReadyToLock protocol is installed.
- //
- Status = gSmst->SmmRegisterProtocolNotify (
- &gEfiSmmReadyToLockProtocolGuid,
- InitSmmProfileCallBack,
- &Registration
- );
- ASSERT_EFI_ERROR (Status);
-
- return ;
-}
-
-/**
- Check if XD feature is supported by a processor.
-
- @param[in,out] Buffer The pointer to private data buffer.
-
-**/
-VOID
-EFIAPI
-CheckFeatureSupported (
- IN OUT VOID *Buffer
- )
-{
- UINT32 RegEax;
- UINT32 RegEdx;
-
- if (mXdSupported) {
- AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL);
- if (RegEax <= CPUID_EXTENDED_FUNCTION) {
- //
- // Extended CPUID functions are not supported on this processor.
- //
- mXdSupported = FALSE;
- }
-
- AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx);
- if ((RegEdx & CPUID1_EDX_XD_SUPPORT) == 0) {
- //
- // Execute Disable Bit feature is not supported on this processor.
- //
- mXdSupported = FALSE;
- }
- }
-
- if (mBtsSupported) {
- AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &RegEdx);
- if ((RegEdx & CPUID1_EDX_BTS_AVAILABLE) != 0) {
- //
- // Per IA32 manuals:
- // When CPUID.1:EDX[21] is set, the following BTS facilities are available:
- // 1. The BTS_UNAVAILABLE flag in the IA32_MISC_ENABLE MSR indicates the
- // availability of the BTS facilities, including the ability to set the BTS and
- // BTINT bits in the MSR_DEBUGCTLA MSR.
- // 2. The IA32_DS_AREA MSR can be programmed to point to the DS save area.
- //
- if ((AsmMsrBitFieldRead64 (MSR_IA32_MISC_ENABLE, 11, 11) == 0) &&
- (AsmMsrBitFieldRead64 (MSR_IA32_MISC_ENABLE, 12, 12) == 0)) {
- //
- // BTS facilities is supported.
- //
- mBtsSupported = FALSE;
- }
- }
- }
-}
-
-/**
- Check if XD and BTS features are supported by all processors.
-
-**/
-VOID
-CheckProcessorFeature (
- VOID
- )
-{
- EFI_STATUS Status;
- EFI_MP_SERVICES_PROTOCOL *MpServices;
-
- Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpServices);
- ASSERT_EFI_ERROR (Status);
-
- //
- // First detect if XD and BTS are supported
- //
- mXdSupported = TRUE;
- mBtsSupported = TRUE;
-
- //
- // Check if XD and BTS are supported on all processors.
- //
- CheckFeatureSupported (NULL);
-
- //
- //Check on other processors if BSP supports this
- //
- if (mXdSupported || mBtsSupported) {
- MpServices->StartupAllAPs (
- MpServices,
- CheckFeatureSupported,
- TRUE,
- NULL,
- 0,
- NULL,
- NULL
- );
- }
-}
-
-/**
- Enable XD feature.
-
-**/
-VOID
-ActivateXd (
- VOID
- )
-{
- UINT64 MsrRegisters;
-
- MsrRegisters = AsmReadMsr64 (MSR_EFER);
- if ((MsrRegisters & MSR_EFER_XD) != 0) {
- return ;
- }
- MsrRegisters |= MSR_EFER_XD;
- AsmWriteMsr64 (MSR_EFER, MsrRegisters);
-}
-
-/**
- Enable single step.
-
-**/
-VOID
-ActivateSingleStepDB (
- VOID
- )
-{
- UINTN Dr6;
-
- Dr6 = AsmReadDr6 ();
- if ((Dr6 & DR6_SINGLE_STEP) != 0) {
- return;
- }
- Dr6 |= DR6_SINGLE_STEP;
- AsmWriteDr6 (Dr6);
-}
-
-/**
- Enable last branch.
-
-**/
-VOID
-ActivateLBR (
- VOID
- )
-{
- UINT64 DebugCtl;
-
- DebugCtl = AsmReadMsr64 (MSR_DEBUG_CTL);
- if ((DebugCtl & MSR_DEBUG_CTL_LBR) != 0) {
- return ;
- }
- AsmWriteMsr64 (MSR_LER_FROM_LIP, 0);
- AsmWriteMsr64 (MSR_LER_TO_LIP, 0);
- DebugCtl |= MSR_DEBUG_CTL_LBR;
- AsmWriteMsr64 (MSR_DEBUG_CTL, DebugCtl);
-}
-
-/**
- Enable branch trace store.
-
- @param CpuIndex The index of the processor.
-
-**/
-VOID
-ActivateBTS (
- IN UINTN CpuIndex
- )
-{
- UINT64 DebugCtl;
-
- DebugCtl = AsmReadMsr64 (MSR_DEBUG_CTL);
- if ((DebugCtl & MSR_DEBUG_CTL_BTS) != 0) {
- return ;
- }
-
- AsmWriteMsr64 (MSR_DS_AREA, (UINT64)(UINTN)mMsrDsArea[CpuIndex]);
- DebugCtl |= (UINT64)(MSR_DEBUG_CTL_BTS | MSR_DEBUG_CTL_TR);
- DebugCtl &= ~((UINT64)MSR_DEBUG_CTL_BTINT);
- AsmWriteMsr64 (MSR_DEBUG_CTL, DebugCtl);
-}
-
-/**
- Increase SMI number in each SMI entry.
-
-**/
-VOID
-SmmProfileRecordSmiNum (
- VOID
- )
-{
- if (mSmmProfileStart) {
- mSmmProfileBase->NumSmis++;
- }
-}
-
-/**
- Initialize processor environment for SMM profile.
-
- @param CpuIndex The index of the processor.
-
-**/
-VOID
-ActivateSmmProfile (
- IN UINTN CpuIndex
- )
-{
- //
- // Enable Single Step DB#
- //
- ActivateSingleStepDB ();
-
- if (mBtsSupported) {
- //
- // We can not get useful information from LER, so we have to use BTS.
- //
- ActivateLBR ();
-
- //
- // Enable BTS
- //
- ActivateBTS (CpuIndex);
- }
-}
-
-/**
- Initialize SMM profile in SMM CPU entry point.
-
- @param[in] Cr3 The base address of the page tables to use in SMM.
-
-**/
-VOID
-InitSmmProfile (
- UINT32 Cr3
- )
-{
- //
- // Save Cr3
- //
- mSmmProfileCr3 = Cr3;
-
- //
- // Skip SMM profile initialization if feature is disabled
- //
- if (!FeaturePcdGet (PcdCpuSmmProfileEnable)) {
- return;
- }
-
- //
- // Initialize SmmProfile here
- //
- InitSmmProfileInternal ();
-
- //
- // Initialize profile IDT.
- //
- InitIdtr ();
-}
-
-/**
- Update page table to map the memory correctly in order to make the instruction
- which caused page fault execute successfully. And it also save the original page
- table to be restored in single-step exception.
-
- @param PageTable PageTable Address.
- @param PFAddress The memory address which caused page fault exception.
- @param CpuIndex The index of the processor.
- @param ErrorCode The Error code of exception.
-
-**/
-VOID
-RestorePageTableBelow4G (
- UINT64 *PageTable,
- UINT64 PFAddress,
- UINTN CpuIndex,
- UINTN ErrorCode
- )
-{
- UINTN PTIndex;
- UINTN PFIndex;
-
- //
- // PML4
- //
- if (sizeof(UINT64) == sizeof(UINTN)) {
- PTIndex = (UINTN)BitFieldRead64 (PFAddress, 39, 47);
- ASSERT (PageTable[PTIndex] != 0);
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
- }
-
- //
- // PDPTE
- //
- PTIndex = (UINTN)BitFieldRead64 (PFAddress, 30, 38);
- ASSERT (PageTable[PTIndex] != 0);
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
-
- //
- // PD
- //
- PTIndex = (UINTN)BitFieldRead64 (PFAddress, 21, 29);
- if ((PageTable[PTIndex] & IA32_PG_PS) != 0) {
- //
- // Large page
- //
-
- //
- // Record old entries with non-present status
- // Old entries include the memory which instruction is at and the memory which instruction access.
- //
- //
- ASSERT (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT);
- if (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT) {
- PFIndex = mPFEntryCount[CpuIndex];
- mLastPFEntryValue[CpuIndex][PFIndex] = PageTable[PTIndex];
- mLastPFEntryPointer[CpuIndex][PFIndex] = &PageTable[PTIndex];
- mPFEntryCount[CpuIndex]++;
- }
-
- //
- // Set new entry
- //
- PageTable[PTIndex] = (PFAddress & ~((1ull << 21) - 1));
- PageTable[PTIndex] |= (UINT64)IA32_PG_PS;
- PageTable[PTIndex] |= (UINT64)PAGE_ATTRIBUTE_BITS;
- if ((ErrorCode & IA32_PF_EC_ID) != 0) {
- PageTable[PTIndex] &= ~IA32_PG_NX;
- }
- } else {
- //
- // Small page
- //
- ASSERT (PageTable[PTIndex] != 0);
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
-
- //
- // 4K PTE
- //
- PTIndex = (UINTN)BitFieldRead64 (PFAddress, 12, 20);
-
- //
- // Record old entries with non-present status
- // Old entries include the memory which instruction is at and the memory which instruction access.
- //
- //
- ASSERT (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT);
- if (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT) {
- PFIndex = mPFEntryCount[CpuIndex];
- mLastPFEntryValue[CpuIndex][PFIndex] = PageTable[PTIndex];
- mLastPFEntryPointer[CpuIndex][PFIndex] = &PageTable[PTIndex];
- mPFEntryCount[CpuIndex]++;
- }
-
- //
- // Set new entry
- //
- PageTable[PTIndex] = (PFAddress & ~((1ull << 12) - 1));
- PageTable[PTIndex] |= (UINT64)PAGE_ATTRIBUTE_BITS;
- if ((ErrorCode & IA32_PF_EC_ID) != 0) {
- PageTable[PTIndex] &= ~IA32_PG_NX;
- }
- }
-}
-
-/**
- The Page fault handler to save SMM profile data.
-
- @param Rip The RIP when exception happens.
- @param ErrorCode The Error code of exception.
-
-**/
-VOID
-SmmProfilePFHandler (
- UINTN Rip,
- UINTN ErrorCode
- )
-{
- UINT64 *PageTable;
- UINT64 PFAddress;
- UINTN CpuIndex;
- UINTN Index;
- UINT64 InstructionAddress;
- UINTN MaxEntryNumber;
- UINTN CurrentEntryNumber;
- BOOLEAN IsValidPFAddress;
- SMM_PROFILE_ENTRY *SmmProfileEntry;
- UINT64 SmiCommand;
- EFI_STATUS Status;
- UINT8 SoftSmiValue;
- EFI_SMM_SAVE_STATE_IO_INFO IoInfo;
-
- if (!mSmmProfileStart) {
- //
- // If SMM profile does not start, call original page fault handler.
- //
- SmiDefaultPFHandler ();
- return;
- }
-
- if (mBtsSupported) {
- DisableBTS ();
- }
-
- IsValidPFAddress = FALSE;
- PageTable = (UINT64 *)AsmReadCr3 ();
- PFAddress = AsmReadCr2 ();
- CpuIndex = GetCpuIndex ();
-
- if (PFAddress <= 0xFFFFFFFF) {
- RestorePageTableBelow4G (PageTable, PFAddress, CpuIndex, ErrorCode);
- } else {
- RestorePageTableAbove4G (PageTable, PFAddress, CpuIndex, ErrorCode, &IsValidPFAddress);
- }
-
- if (!IsValidPFAddress) {
- InstructionAddress = Rip;
- if ((ErrorCode & IA32_PF_EC_ID) != 0 && (mBtsSupported)) {
- //
- // If it is instruction fetch failure, get the correct IP from BTS.
- //
- InstructionAddress = GetSourceFromDestinationOnBts (CpuIndex, Rip);
- if (InstructionAddress == 0) {
- //
- // It indicates the instruction which caused page fault is not a jump instruction,
- // set instruction address same as the page fault address.
- //
- InstructionAddress = PFAddress;
- }
- }
-
- //
- // Indicate it is not software SMI
- //
- SmiCommand = 0xFFFFFFFFFFFFFFFFULL;
- for (Index = 0; Index < gSmst->NumberOfCpus; Index++) {
- Status = SmmReadSaveState(&mSmmCpu, sizeof(IoInfo), EFI_SMM_SAVE_STATE_REGISTER_IO, Index, &IoInfo);
- if (EFI_ERROR (Status)) {
- continue;
- }
- if (IoInfo.IoPort == mSmiCommandPort) {
- //
- // A software SMI triggered by SMI command port has been found, get SmiCommand from SMI command port.
- //
- SoftSmiValue = IoRead8 (mSmiCommandPort);
- SmiCommand = (UINT64)SoftSmiValue;
- break;
- }
- }
-
- SmmProfileEntry = (SMM_PROFILE_ENTRY *)(UINTN)(mSmmProfileBase + 1);
- //
- // Check if there is already a same entry in profile data.
- //
- for (Index = 0; Index < (UINTN) mSmmProfileBase->CurDataEntries; Index++) {
- if ((SmmProfileEntry[Index].ErrorCode == (UINT64)ErrorCode) &&
- (SmmProfileEntry[Index].Address == PFAddress) &&
- (SmmProfileEntry[Index].CpuNum == (UINT64)CpuIndex) &&
- (SmmProfileEntry[Index].Instruction == InstructionAddress) &&
- (SmmProfileEntry[Index].SmiCmd == SmiCommand)) {
- //
- // Same record exist, need not save again.
- //
- break;
- }
- }
- if (Index == mSmmProfileBase->CurDataEntries) {
- CurrentEntryNumber = (UINTN) mSmmProfileBase->CurDataEntries;
- MaxEntryNumber = (UINTN) mSmmProfileBase->MaxDataEntries;
- if (FeaturePcdGet (PcdCpuSmmProfileRingBuffer)) {
- CurrentEntryNumber = CurrentEntryNumber % MaxEntryNumber;
- }
- if (CurrentEntryNumber < MaxEntryNumber) {
- //
- // Log the new entry
- //
- SmmProfileEntry[CurrentEntryNumber].SmiNum = mSmmProfileBase->NumSmis;
- SmmProfileEntry[CurrentEntryNumber].ErrorCode = (UINT64)ErrorCode;
- SmmProfileEntry[CurrentEntryNumber].ApicId = (UINT64)GetApicId ();
- SmmProfileEntry[CurrentEntryNumber].CpuNum = (UINT64)CpuIndex;
- SmmProfileEntry[CurrentEntryNumber].Address = PFAddress;
- SmmProfileEntry[CurrentEntryNumber].Instruction = InstructionAddress;
- SmmProfileEntry[CurrentEntryNumber].SmiCmd = SmiCommand;
- //
- // Update current entry index and data size in the header.
- //
- mSmmProfileBase->CurDataEntries++;
- mSmmProfileBase->CurDataSize = MultU64x64 (mSmmProfileBase->CurDataEntries, sizeof (SMM_PROFILE_ENTRY));
- }
- }
- }
- //
- // Flush TLB
- //
- CpuFlushTlb ();
-
- if (mBtsSupported) {
- EnableBTS ();
- }
-}
-
-/**
- Replace INT1 exception handler to restore page table to absent/execute-disable state
- in order to trigger page fault again to save SMM profile data..
-
-**/
-VOID
-InitIdtr (
- VOID
- )
-{
- SmmRegisterExceptionHandler (&mSmmCpuService, EXCEPT_IA32_DEBUG, DebugExceptionHandler);
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h
deleted file mode 100644
index 5488c148e8..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/** @file
-SMM profile header file.
-
-Copyright (c) 2012 - 2016, 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.
-
-**/
-
-#ifndef _SMM_PROFILE_H_
-#define _SMM_PROFILE_H_
-
-#include "SmmProfileInternal.h"
-
-///
-/// MSR Register Index
-///
-#define MSR_IA32_MISC_ENABLE 0x1A0
-#define B_XD_DISABLE_BIT BIT34
-
-//
-// External functions
-//
-
-/**
- Initialize processor environment for SMM profile.
-
- @param CpuIndex The index of the processor.
-
-**/
-VOID
-ActivateSmmProfile (
- IN UINTN CpuIndex
- );
-
-/**
- Initialize SMM profile in SMM CPU entry point.
-
- @param[in] Cr3 The base address of the page tables to use in SMM.
-
-**/
-VOID
-InitSmmProfile (
- UINT32 Cr3
- );
-
-/**
- Increase SMI number in each SMI entry.
-
-**/
-VOID
-SmmProfileRecordSmiNum (
- VOID
- );
-
-/**
- The Page fault handler to save SMM profile data.
-
- @param Rip The RIP when exception happens.
- @param ErrorCode The Error code of exception.
-
-**/
-VOID
-SmmProfilePFHandler (
- UINTN Rip,
- UINTN ErrorCode
- );
-
-/**
- Updates page table to make some memory ranges (like system memory) absent
- and make some memory ranges (like MMIO) present and execute disable. It also
- update 2MB-page to 4KB-page for some memory ranges.
-
-**/
-VOID
-SmmProfileStart (
- VOID
- );
-
-/**
- Page fault IDT handler for SMM Profile.
-
-**/
-VOID
-EFIAPI
-PageFaultIdtHandlerSmmProfile (
- VOID
- );
-
-
-/**
- Check if XD feature is supported by a processor.
-
- @param[in,out] Buffer The pointer to private data buffer.
-
-**/
-VOID
-EFIAPI
-CheckFeatureSupported (
- IN OUT VOID *Buffer
- );
-
-/**
- Enable XD feature.
-
-**/
-VOID
-ActivateXd (
- VOID
- );
-
-/**
- Update page table according to protected memory ranges and the 4KB-page mapped memory ranges.
-
-**/
-VOID
-InitPaging (
- VOID
- );
-
-/**
- Check if XD and BTS features are supported by all processors.
-
-**/
-VOID
-CheckProcessorFeature (
- VOID
- );
-
-extern BOOLEAN mXdSupported;
-extern BOOLEAN mXdEnabled;
-
-#endif // _SMM_PROFILE_H_
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h
deleted file mode 100644
index de6eb0aceb..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfileInternal.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/** @file
-SMM profile internal header file.
-
-Copyright (c) 2012 - 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.
-
-**/
-
-#ifndef _SMM_PROFILE_INTERNAL_H_
-#define _SMM_PROFILE_INTERNAL_H_
-
-#include <Guid/GlobalVariable.h>
-#include <Guid/Acpi.h>
-#include <Protocol/SmmReadyToLock.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
-#include <Library/DxeServicesTableLib.h>
-#include <Library/CpuLib.h>
-#include <IndustryStandard/Acpi.h>
-
-#include "SmmProfileArch.h"
-
-//
-// Configure the SMM_PROFILE DTS region size
-//
-#define SMM_PROFILE_DTS_SIZE (4 * 1024 * 1024) // 4M
-
-#define MAX_PF_PAGE_COUNT 0x2
-
-#define PEBS_RECORD_NUMBER 0x2
-
-#define MAX_PF_ENTRY_COUNT 10
-
-//
-// This MACRO just enable unit test for the profile
-// Please disable it.
-//
-
-#define IA32_PF_EC_P (1u << 0)
-#define IA32_PF_EC_WR (1u << 1)
-#define IA32_PF_EC_US (1u << 2)
-#define IA32_PF_EC_RSVD (1u << 3)
-#define IA32_PF_EC_ID (1u << 4)
-
-#define SMM_PROFILE_NAME L"SmmProfileData"
-
-//
-// CPU generic definition
-//
-#define CPUID1_EDX_XD_SUPPORT 0x100000
-#define MSR_EFER 0xc0000080
-#define MSR_EFER_XD 0x800
-
-#define CPUID1_EDX_BTS_AVAILABLE 0x200000
-
-#define DR6_SINGLE_STEP 0x4000
-#define RFLAG_TF 0x100
-
-#define MSR_DEBUG_CTL 0x1D9
-#define MSR_DEBUG_CTL_LBR 0x1
-#define MSR_DEBUG_CTL_TR 0x40
-#define MSR_DEBUG_CTL_BTS 0x80
-#define MSR_DEBUG_CTL_BTINT 0x100
-#define MSR_LASTBRANCH_TOS 0x1C9
-#define MSR_LER_FROM_LIP 0x1DD
-#define MSR_LER_TO_LIP 0x1DE
-#define MSR_DS_AREA 0x600
-
-typedef struct {
- EFI_PHYSICAL_ADDRESS Base;
- EFI_PHYSICAL_ADDRESS Top;
-} MEMORY_RANGE;
-
-typedef struct {
- MEMORY_RANGE Range;
- BOOLEAN Present;
- BOOLEAN Nx;
-} MEMORY_PROTECTION_RANGE;
-
-typedef struct {
- UINT64 HeaderSize;
- UINT64 MaxDataEntries;
- UINT64 MaxDataSize;
- UINT64 CurDataEntries;
- UINT64 CurDataSize;
- UINT64 TsegStart;
- UINT64 TsegSize;
- UINT64 NumSmis;
- UINT64 NumCpus;
-} SMM_PROFILE_HEADER;
-
-typedef struct {
- UINT64 SmiNum;
- UINT64 CpuNum;
- UINT64 ApicId;
- UINT64 ErrorCode;
- UINT64 Instruction;
- UINT64 Address;
- UINT64 SmiCmd;
-} SMM_PROFILE_ENTRY;
-
-extern SMM_S3_RESUME_STATE *mSmmS3ResumeState;
-extern UINTN gSmiExceptionHandlers[];
-extern BOOLEAN mXdSupported;
-extern UINTN *mPFEntryCount;
-extern UINT64 (*mLastPFEntryValue)[MAX_PF_ENTRY_COUNT];
-extern UINT64 *(*mLastPFEntryPointer)[MAX_PF_ENTRY_COUNT];
-
-//
-// Internal functions
-//
-
-/**
- Update IDT table to replace page fault handler and INT 1 handler.
-
-**/
-VOID
-InitIdtr (
- VOID
- );
-
-/**
- Check if the memory address will be mapped by 4KB-page.
-
- @param Address The address of Memory.
-
-**/
-BOOLEAN
-IsAddressSplit (
- IN EFI_PHYSICAL_ADDRESS Address
- );
-
-/**
- Check if the memory address will be mapped by 4KB-page.
-
- @param Address The address of Memory.
- @param Nx The flag indicates if the memory is execute-disable.
-
-**/
-BOOLEAN
-IsAddressValid (
- IN EFI_PHYSICAL_ADDRESS Address,
- IN BOOLEAN *Nx
- );
-
-/**
- Page Fault handler for SMM use.
-
-**/
-VOID
-SmiDefaultPFHandler (
- VOID
- );
-
-/**
- Clear TF in FLAGS.
-
- @param SystemContext A pointer to the processor context when
- the interrupt occurred on the processor.
-
-**/
-VOID
-ClearTrapFlag (
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- );
-
-#endif // _SMM_PROFILE_H_
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c
deleted file mode 100644
index 539c0294cd..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmramSaveState.c
+++ /dev/null
@@ -1,700 +0,0 @@
-/** @file
-Provides services to access SMRAM Save State Map
-
-Copyright (c) 2010 - 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 <PiSmm.h>
-
-#include <Library/SmmCpuFeaturesLib.h>
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/SmmServicesTableLib.h>
-#include <Library/DebugLib.h>
-#include <Register/Cpuid.h>
-#include <Register/SmramSaveStateMap.h>
-
-//
-// EFER register LMA bit
-//
-#define LMA BIT10
-
-///
-/// Macro used to simplify the lookup table entries of type CPU_SMM_SAVE_STATE_LOOKUP_ENTRY
-///
-#define SMM_CPU_OFFSET(Field) OFFSET_OF (SMRAM_SAVE_STATE_MAP, Field)
-
-///
-/// Macro used to simplify the lookup table entries of type CPU_SMM_SAVE_STATE_REGISTER_RANGE
-///
-#define SMM_REGISTER_RANGE(Start, End) { Start, End, End - Start + 1 }
-
-///
-/// Structure used to describe a range of registers
-///
-typedef struct {
- EFI_SMM_SAVE_STATE_REGISTER Start;
- EFI_SMM_SAVE_STATE_REGISTER End;
- UINTN Length;
-} CPU_SMM_SAVE_STATE_REGISTER_RANGE;
-
-///
-/// Structure used to build a lookup table to retrieve the widths and offsets
-/// associated with each supported EFI_SMM_SAVE_STATE_REGISTER value
-///
-
-#define SMM_SAVE_STATE_REGISTER_SMMREVID_INDEX 1
-#define SMM_SAVE_STATE_REGISTER_IOMISC_INDEX 2
-#define SMM_SAVE_STATE_REGISTER_IOMEMADDR_INDEX 3
-#define SMM_SAVE_STATE_REGISTER_MAX_INDEX 4
-
-typedef struct {
- UINT8 Width32;
- UINT8 Width64;
- UINT16 Offset32;
- UINT16 Offset64Lo;
- UINT16 Offset64Hi;
- BOOLEAN Writeable;
-} CPU_SMM_SAVE_STATE_LOOKUP_ENTRY;
-
-///
-/// Structure used to build a lookup table for the IOMisc width information
-///
-typedef struct {
- UINT8 Width;
- EFI_SMM_SAVE_STATE_IO_WIDTH IoWidth;
-} CPU_SMM_SAVE_STATE_IO_WIDTH;
-
-///
-/// Variables from SMI Handler
-///
-extern UINT32 gSmbase;
-extern volatile UINT32 gSmiStack;
-extern UINT32 gSmiCr3;
-extern volatile UINT8 gcSmiHandlerTemplate[];
-extern CONST UINT16 gcSmiHandlerSize;
-
-//
-// Variables used by SMI Handler
-//
-IA32_DESCRIPTOR gSmiHandlerIdtr;
-
-///
-/// Table used by GetRegisterIndex() to convert an EFI_SMM_SAVE_STATE_REGISTER
-/// value to an index into a table of type CPU_SMM_SAVE_STATE_LOOKUP_ENTRY
-///
-CONST CPU_SMM_SAVE_STATE_REGISTER_RANGE mSmmCpuRegisterRanges[] = {
- SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_GDTBASE, EFI_SMM_SAVE_STATE_REGISTER_LDTINFO),
- SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_ES, EFI_SMM_SAVE_STATE_REGISTER_RIP),
- SMM_REGISTER_RANGE (EFI_SMM_SAVE_STATE_REGISTER_RFLAGS, EFI_SMM_SAVE_STATE_REGISTER_CR4),
- { (EFI_SMM_SAVE_STATE_REGISTER)0, (EFI_SMM_SAVE_STATE_REGISTER)0, 0 }
-};
-
-///
-/// Lookup table used to retrieve the widths and offsets associated with each
-/// supported EFI_SMM_SAVE_STATE_REGISTER value
-///
-CONST CPU_SMM_SAVE_STATE_LOOKUP_ENTRY mSmmCpuWidthOffset[] = {
- {0, 0, 0, 0, 0, FALSE}, // Reserved
-
- //
- // Internally defined CPU Save State Registers. Not defined in PI SMM CPU Protocol.
- //
- {4, 4, SMM_CPU_OFFSET (x86.SMMRevId) , SMM_CPU_OFFSET (x64.SMMRevId) , 0 , FALSE}, // SMM_SAVE_STATE_REGISTER_SMMREVID_INDEX = 1
- {4, 4, SMM_CPU_OFFSET (x86.IOMisc) , SMM_CPU_OFFSET (x64.IOMisc) , 0 , FALSE}, // SMM_SAVE_STATE_REGISTER_IOMISC_INDEX = 2
- {4, 8, SMM_CPU_OFFSET (x86.IOMemAddr) , SMM_CPU_OFFSET (x64.IOMemAddr) , SMM_CPU_OFFSET (x64.IOMemAddr) + 4, FALSE}, // SMM_SAVE_STATE_REGISTER_IOMEMADDR_INDEX = 3
-
- //
- // CPU Save State registers defined in PI SMM CPU Protocol.
- //
- {0, 8, 0 , SMM_CPU_OFFSET (x64.GdtBaseLoDword) , SMM_CPU_OFFSET (x64.GdtBaseHiDword), FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_GDTBASE = 4
- {0, 8, 0 , SMM_CPU_OFFSET (x64.IdtBaseLoDword) , SMM_CPU_OFFSET (x64.IdtBaseHiDword), FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_IDTBASE = 5
- {0, 8, 0 , SMM_CPU_OFFSET (x64.LdtBaseLoDword) , SMM_CPU_OFFSET (x64.LdtBaseHiDword), FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_LDTBASE = 6
- {0, 0, 0 , 0 , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_GDTLIMIT = 7
- {0, 0, 0 , 0 , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_IDTLIMIT = 8
- {0, 0, 0 , 0 , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_LDTLIMIT = 9
- {0, 0, 0 , 0 , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_LDTINFO = 10
-
- {4, 4, SMM_CPU_OFFSET (x86._ES) , SMM_CPU_OFFSET (x64._ES) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_ES = 20
- {4, 4, SMM_CPU_OFFSET (x86._CS) , SMM_CPU_OFFSET (x64._CS) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_CS = 21
- {4, 4, SMM_CPU_OFFSET (x86._SS) , SMM_CPU_OFFSET (x64._SS) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_SS = 22
- {4, 4, SMM_CPU_OFFSET (x86._DS) , SMM_CPU_OFFSET (x64._DS) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_DS = 23
- {4, 4, SMM_CPU_OFFSET (x86._FS) , SMM_CPU_OFFSET (x64._FS) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_FS = 24
- {4, 4, SMM_CPU_OFFSET (x86._GS) , SMM_CPU_OFFSET (x64._GS) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_GS = 25
- {0, 4, 0 , SMM_CPU_OFFSET (x64._LDTR) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_LDTR_SEL = 26
- {4, 4, SMM_CPU_OFFSET (x86._TR) , SMM_CPU_OFFSET (x64._TR) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_TR_SEL = 27
- {4, 8, SMM_CPU_OFFSET (x86._DR7) , SMM_CPU_OFFSET (x64._DR7) , SMM_CPU_OFFSET (x64._DR7) + 4, FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_DR7 = 28
- {4, 8, SMM_CPU_OFFSET (x86._DR6) , SMM_CPU_OFFSET (x64._DR6) , SMM_CPU_OFFSET (x64._DR6) + 4, FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_DR6 = 29
- {0, 8, 0 , SMM_CPU_OFFSET (x64._R8) , SMM_CPU_OFFSET (x64._R8) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R8 = 30
- {0, 8, 0 , SMM_CPU_OFFSET (x64._R9) , SMM_CPU_OFFSET (x64._R9) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R9 = 31
- {0, 8, 0 , SMM_CPU_OFFSET (x64._R10) , SMM_CPU_OFFSET (x64._R10) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R10 = 32
- {0, 8, 0 , SMM_CPU_OFFSET (x64._R11) , SMM_CPU_OFFSET (x64._R11) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R11 = 33
- {0, 8, 0 , SMM_CPU_OFFSET (x64._R12) , SMM_CPU_OFFSET (x64._R12) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R12 = 34
- {0, 8, 0 , SMM_CPU_OFFSET (x64._R13) , SMM_CPU_OFFSET (x64._R13) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R13 = 35
- {0, 8, 0 , SMM_CPU_OFFSET (x64._R14) , SMM_CPU_OFFSET (x64._R14) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R14 = 36
- {0, 8, 0 , SMM_CPU_OFFSET (x64._R15) , SMM_CPU_OFFSET (x64._R15) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_R15 = 37
- {4, 8, SMM_CPU_OFFSET (x86._EAX) , SMM_CPU_OFFSET (x64._RAX) , SMM_CPU_OFFSET (x64._RAX) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RAX = 38
- {4, 8, SMM_CPU_OFFSET (x86._EBX) , SMM_CPU_OFFSET (x64._RBX) , SMM_CPU_OFFSET (x64._RBX) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RBX = 39
- {4, 8, SMM_CPU_OFFSET (x86._ECX) , SMM_CPU_OFFSET (x64._RCX) , SMM_CPU_OFFSET (x64._RCX) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RCX = 40
- {4, 8, SMM_CPU_OFFSET (x86._EDX) , SMM_CPU_OFFSET (x64._RDX) , SMM_CPU_OFFSET (x64._RDX) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RDX = 41
- {4, 8, SMM_CPU_OFFSET (x86._ESP) , SMM_CPU_OFFSET (x64._RSP) , SMM_CPU_OFFSET (x64._RSP) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RSP = 42
- {4, 8, SMM_CPU_OFFSET (x86._EBP) , SMM_CPU_OFFSET (x64._RBP) , SMM_CPU_OFFSET (x64._RBP) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RBP = 43
- {4, 8, SMM_CPU_OFFSET (x86._ESI) , SMM_CPU_OFFSET (x64._RSI) , SMM_CPU_OFFSET (x64._RSI) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RSI = 44
- {4, 8, SMM_CPU_OFFSET (x86._EDI) , SMM_CPU_OFFSET (x64._RDI) , SMM_CPU_OFFSET (x64._RDI) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RDI = 45
- {4, 8, SMM_CPU_OFFSET (x86._EIP) , SMM_CPU_OFFSET (x64._RIP) , SMM_CPU_OFFSET (x64._RIP) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RIP = 46
-
- {4, 8, SMM_CPU_OFFSET (x86._EFLAGS) , SMM_CPU_OFFSET (x64._RFLAGS) , SMM_CPU_OFFSET (x64._RFLAGS) + 4, TRUE }, // EFI_SMM_SAVE_STATE_REGISTER_RFLAGS = 51
- {4, 8, SMM_CPU_OFFSET (x86._CR0) , SMM_CPU_OFFSET (x64._CR0) , SMM_CPU_OFFSET (x64._CR0) + 4, FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_CR0 = 52
- {4, 8, SMM_CPU_OFFSET (x86._CR3) , SMM_CPU_OFFSET (x64._CR3) , SMM_CPU_OFFSET (x64._CR3) + 4, FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_CR3 = 53
- {0, 4, 0 , SMM_CPU_OFFSET (x64._CR4) , 0 , FALSE}, // EFI_SMM_SAVE_STATE_REGISTER_CR4 = 54
-};
-
-///
-/// Lookup table for the IOMisc width information
-///
-CONST CPU_SMM_SAVE_STATE_IO_WIDTH mSmmCpuIoWidth[] = {
- { 0, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 }, // Undefined = 0
- { 1, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 }, // SMM_IO_LENGTH_BYTE = 1
- { 2, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT16 }, // SMM_IO_LENGTH_WORD = 2
- { 0, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 }, // Undefined = 3
- { 4, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT32 }, // SMM_IO_LENGTH_DWORD = 4
- { 0, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 }, // Undefined = 5
- { 0, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 }, // Undefined = 6
- { 0, EFI_SMM_SAVE_STATE_IO_WIDTH_UINT8 } // Undefined = 7
-};
-
-///
-/// Lookup table for the IOMisc type information
-///
-CONST EFI_SMM_SAVE_STATE_IO_TYPE mSmmCpuIoType[] = {
- EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT, // SMM_IO_TYPE_OUT_DX = 0
- EFI_SMM_SAVE_STATE_IO_TYPE_INPUT, // SMM_IO_TYPE_IN_DX = 1
- EFI_SMM_SAVE_STATE_IO_TYPE_STRING, // SMM_IO_TYPE_OUTS = 2
- EFI_SMM_SAVE_STATE_IO_TYPE_STRING, // SMM_IO_TYPE_INS = 3
- (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 4
- (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 5
- EFI_SMM_SAVE_STATE_IO_TYPE_REP_PREFIX, // SMM_IO_TYPE_REP_OUTS = 6
- EFI_SMM_SAVE_STATE_IO_TYPE_REP_PREFIX, // SMM_IO_TYPE_REP_INS = 7
- EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT, // SMM_IO_TYPE_OUT_IMMEDIATE = 8
- EFI_SMM_SAVE_STATE_IO_TYPE_INPUT, // SMM_IO_TYPE_OUT_IMMEDIATE = 9
- (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 10
- (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 11
- (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 12
- (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 13
- (EFI_SMM_SAVE_STATE_IO_TYPE)0, // Undefined = 14
- (EFI_SMM_SAVE_STATE_IO_TYPE)0 // Undefined = 15
-};
-
-///
-/// The mode of the CPU at the time an SMI occurs
-///
-UINT8 mSmmSaveStateRegisterLma;
-
-/**
- Read information from the CPU save state.
-
- @param Register Specifies the CPU register to read form the save state.
-
- @retval 0 Register is not valid
- @retval >0 Index into mSmmCpuWidthOffset[] associated with Register
-
-**/
-UINTN
-GetRegisterIndex (
- IN EFI_SMM_SAVE_STATE_REGISTER Register
- )
-{
- UINTN Index;
- UINTN Offset;
-
- for (Index = 0, Offset = SMM_SAVE_STATE_REGISTER_MAX_INDEX; mSmmCpuRegisterRanges[Index].Length != 0; Index++) {
- if (Register >= mSmmCpuRegisterRanges[Index].Start && Register <= mSmmCpuRegisterRanges[Index].End) {
- return Register - mSmmCpuRegisterRanges[Index].Start + Offset;
- }
- Offset += mSmmCpuRegisterRanges[Index].Length;
- }
- return 0;
-}
-
-/**
- Read a CPU Save State register on the target processor.
-
- This function abstracts the differences that whether the CPU Save State register is in the
- IA32 CPU Save State Map or X64 CPU Save State Map.
-
- This function supports reading a CPU Save State register in SMBase relocation handler.
-
- @param[in] CpuIndex Specifies the zero-based index of the CPU save state.
- @param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table.
- @param[in] Width The number of bytes to read from the CPU save state.
- @param[out] Buffer Upon return, this holds the CPU register value read from the save state.
-
- @retval EFI_SUCCESS The register was read from Save State.
- @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor.
- @retval EFI_INVALID_PARAMTER This or Buffer is NULL.
-
-**/
-EFI_STATUS
-ReadSaveStateRegisterByIndex (
- IN UINTN CpuIndex,
- IN UINTN RegisterIndex,
- IN UINTN Width,
- OUT VOID *Buffer
- )
-{
- SMRAM_SAVE_STATE_MAP *CpuSaveState;
-
- if (RegisterIndex == 0) {
- return EFI_NOT_FOUND;
- }
-
- CpuSaveState = gSmst->CpuSaveState[CpuIndex];
-
- if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) {
- //
- // If 32-bit mode width is zero, then the specified register can not be accessed
- //
- if (mSmmCpuWidthOffset[RegisterIndex].Width32 == 0) {
- return EFI_NOT_FOUND;
- }
-
- //
- // If Width is bigger than the 32-bit mode width, then the specified register can not be accessed
- //
- if (Width > mSmmCpuWidthOffset[RegisterIndex].Width32) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Write return buffer
- //
- ASSERT(CpuSaveState != NULL);
- CopyMem(Buffer, (UINT8 *)CpuSaveState + mSmmCpuWidthOffset[RegisterIndex].Offset32, Width);
- } else {
- //
- // If 64-bit mode width is zero, then the specified register can not be accessed
- //
- if (mSmmCpuWidthOffset[RegisterIndex].Width64 == 0) {
- return EFI_NOT_FOUND;
- }
-
- //
- // If Width is bigger than the 64-bit mode width, then the specified register can not be accessed
- //
- if (Width > mSmmCpuWidthOffset[RegisterIndex].Width64) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Write lower 32-bits of return buffer
- //
- CopyMem(Buffer, (UINT8 *)CpuSaveState + mSmmCpuWidthOffset[RegisterIndex].Offset64Lo, MIN(4, Width));
- if (Width >= 4) {
- //
- // Write upper 32-bits of return buffer
- //
- CopyMem((UINT8 *)Buffer + 4, (UINT8 *)CpuSaveState + mSmmCpuWidthOffset[RegisterIndex].Offset64Hi, Width - 4);
- }
- }
- return EFI_SUCCESS;
-}
-
-/**
- Read a CPU Save State register on the target processor.
-
- This function abstracts the differences that whether the CPU Save State register is in the
- IA32 CPU Save State Map or X64 CPU Save State Map.
-
- This function supports reading a CPU Save State register in SMBase relocation handler.
-
- @param[in] CpuIndex Specifies the zero-based index of the CPU save state.
- @param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table.
- @param[in] Width The number of bytes to read from the CPU save state.
- @param[out] Buffer Upon return, this holds the CPU register value read from the save state.
-
- @retval EFI_SUCCESS The register was read from Save State.
- @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor.
- @retval EFI_INVALID_PARAMTER This or Buffer is NULL.
-
-**/
-EFI_STATUS
-EFIAPI
-ReadSaveStateRegister (
- IN UINTN CpuIndex,
- IN EFI_SMM_SAVE_STATE_REGISTER Register,
- IN UINTN Width,
- OUT VOID *Buffer
- )
-{
- UINT32 SmmRevId;
- SMRAM_SAVE_STATE_IOMISC IoMisc;
- EFI_SMM_SAVE_STATE_IO_INFO *IoInfo;
- VOID *IoMemAddr;
-
- //
- // Check for special EFI_SMM_SAVE_STATE_REGISTER_LMA
- //
- if (Register == EFI_SMM_SAVE_STATE_REGISTER_LMA) {
- //
- // Only byte access is supported for this register
- //
- if (Width != 1) {
- return EFI_INVALID_PARAMETER;
- }
-
- *(UINT8 *)Buffer = mSmmSaveStateRegisterLma;
-
- return EFI_SUCCESS;
- }
-
- //
- // Check for special EFI_SMM_SAVE_STATE_REGISTER_IO
- //
- if (Register == EFI_SMM_SAVE_STATE_REGISTER_IO) {
- //
- // Get SMM Revision ID
- //
- ReadSaveStateRegisterByIndex (CpuIndex, SMM_SAVE_STATE_REGISTER_SMMREVID_INDEX, sizeof(SmmRevId), &SmmRevId);
-
- //
- // See if the CPU supports the IOMisc register in the save state
- //
- if (SmmRevId < SMRAM_SAVE_STATE_MIN_REV_ID_IOMISC) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Get the IOMisc register value
- //
- ReadSaveStateRegisterByIndex (CpuIndex, SMM_SAVE_STATE_REGISTER_IOMISC_INDEX, sizeof(IoMisc.Uint32), &IoMisc.Uint32);
-
- //
- // Check for the SMI_FLAG in IOMisc
- //
- if (IoMisc.Bits.SmiFlag == 0) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Compute index for the I/O Length and I/O Type lookup tables
- //
- if (mSmmCpuIoWidth[IoMisc.Bits.Length].Width == 0 || mSmmCpuIoType[IoMisc.Bits.Type] == 0) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Zero the IoInfo structure that will be returned in Buffer
- //
- IoInfo = (EFI_SMM_SAVE_STATE_IO_INFO *)Buffer;
- ZeroMem (IoInfo, sizeof(EFI_SMM_SAVE_STATE_IO_INFO));
-
- //
- // Use lookup tables to help fill in all the fields of the IoInfo structure
- //
- IoInfo->IoPort = (UINT16)IoMisc.Bits.Port;
- IoInfo->IoWidth = mSmmCpuIoWidth[IoMisc.Bits.Length].IoWidth;
- IoInfo->IoType = mSmmCpuIoType[IoMisc.Bits.Type];
- if (IoInfo->IoType == EFI_SMM_SAVE_STATE_IO_TYPE_INPUT || IoInfo->IoType == EFI_SMM_SAVE_STATE_IO_TYPE_OUTPUT) {
- ReadSaveStateRegister (CpuIndex, EFI_SMM_SAVE_STATE_REGISTER_RAX, mSmmCpuIoWidth[IoMisc.Bits.Length].Width, &IoInfo->IoData);
- }
- else {
- ReadSaveStateRegisterByIndex(CpuIndex, SMM_SAVE_STATE_REGISTER_IOMEMADDR_INDEX, sizeof(IoMemAddr), &IoMemAddr);
- CopyMem(&IoInfo->IoData, IoMemAddr, mSmmCpuIoWidth[IoMisc.Bits.Length].Width);
- }
- return EFI_SUCCESS;
- }
-
- //
- // Convert Register to a register lookup table index
- //
- return ReadSaveStateRegisterByIndex (CpuIndex, GetRegisterIndex (Register), Width, Buffer);
-}
-
-/**
- Write value to a CPU Save State register on the target processor.
-
- This function abstracts the differences that whether the CPU Save State register is in the
- IA32 CPU Save State Map or X64 CPU Save State Map.
-
- This function supports writing a CPU Save State register in SMBase relocation handler.
-
- @param[in] CpuIndex Specifies the zero-based index of the CPU save state.
- @param[in] RegisterIndex Index into mSmmCpuWidthOffset[] look up table.
- @param[in] Width The number of bytes to read from the CPU save state.
- @param[in] Buffer Upon entry, this holds the new CPU register value.
-
- @retval EFI_SUCCESS The register was written to Save State.
- @retval EFI_NOT_FOUND The register is not defined for the Save State of Processor.
- @retval EFI_INVALID_PARAMTER ProcessorIndex or Width is not correct.
-
-**/
-EFI_STATUS
-EFIAPI
-WriteSaveStateRegister (
- IN UINTN CpuIndex,
- IN EFI_SMM_SAVE_STATE_REGISTER Register,
- IN UINTN Width,
- IN CONST VOID *Buffer
- )
-{
- UINTN RegisterIndex;
- SMRAM_SAVE_STATE_MAP *CpuSaveState;
-
- //
- // Writes to EFI_SMM_SAVE_STATE_REGISTER_LMA are ignored
- //
- if (Register == EFI_SMM_SAVE_STATE_REGISTER_LMA) {
- return EFI_SUCCESS;
- }
-
- //
- // Writes to EFI_SMM_SAVE_STATE_REGISTER_IO are not supported
- //
- if (Register == EFI_SMM_SAVE_STATE_REGISTER_IO) {
- return EFI_NOT_FOUND;
- }
-
- //
- // Convert Register to a register lookup table index
- //
- RegisterIndex = GetRegisterIndex (Register);
- if (RegisterIndex == 0) {
- return EFI_NOT_FOUND;
- }
-
- CpuSaveState = gSmst->CpuSaveState[CpuIndex];
-
- //
- // Do not write non-writable SaveState, because it will cause exception.
- //
- if (!mSmmCpuWidthOffset[RegisterIndex].Writeable) {
- return EFI_UNSUPPORTED;
- }
-
- //
- // Check CPU mode
- //
- if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) {
- //
- // If 32-bit mode width is zero, then the specified register can not be accessed
- //
- if (mSmmCpuWidthOffset[RegisterIndex].Width32 == 0) {
- return EFI_NOT_FOUND;
- }
-
- //
- // If Width is bigger than the 32-bit mode width, then the specified register can not be accessed
- //
- if (Width > mSmmCpuWidthOffset[RegisterIndex].Width32) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // Write SMM State register
- //
- ASSERT (CpuSaveState != NULL);
- CopyMem((UINT8 *)CpuSaveState + mSmmCpuWidthOffset[RegisterIndex].Offset32, Buffer, Width);
- } else {
- //
- // If 64-bit mode width is zero, then the specified register can not be accessed
- //
- if (mSmmCpuWidthOffset[RegisterIndex].Width64 == 0) {
- return EFI_NOT_FOUND;
- }
-
- //
- // If Width is bigger than the 64-bit mode width, then the specified register can not be accessed
- //
- if (Width > mSmmCpuWidthOffset[RegisterIndex].Width64) {
- return EFI_INVALID_PARAMETER;
- }
-
- //
- // Write lower 32-bits of SMM State register
- //
- CopyMem((UINT8 *)CpuSaveState + mSmmCpuWidthOffset[RegisterIndex].Offset64Lo, Buffer, MIN (4, Width));
- if (Width >= 4) {
- //
- // Write upper 32-bits of SMM State register
- //
- CopyMem((UINT8 *)CpuSaveState + mSmmCpuWidthOffset[RegisterIndex].Offset64Hi, (UINT8 *)Buffer + 4, Width - 4);
- }
- }
- return EFI_SUCCESS;
-}
-
-/**
- Hook the code executed immediately after an RSM instruction on the currently
- executing CPU. The mode of code executed immediately after RSM must be
- detected, and the appropriate hook must be selected. Always clear the auto
- HALT restart flag if it is set.
-
- @param[in] CpuIndex The processor index for the currently
- executing CPU.
- @param[in] CpuState Pointer to SMRAM Save State Map for the
- currently executing CPU.
- @param[in] NewInstructionPointer32 Instruction pointer to use if resuming to
- 32-bit mode from 64-bit SMM.
- @param[in] NewInstructionPointer Instruction pointer to use if resuming to
- same mode as SMM.
-
- @retval The value of the original instruction pointer before it was hooked.
-
-**/
-UINT64
-EFIAPI
-HookReturnFromSmm (
- IN UINTN CpuIndex,
- SMRAM_SAVE_STATE_MAP *CpuState,
- UINT64 NewInstructionPointer32,
- UINT64 NewInstructionPointer
- )
-{
- UINT64 OriginalInstructionPointer;
-
- OriginalInstructionPointer = SmmCpuFeaturesHookReturnFromSmm (
- CpuIndex,
- CpuState,
- NewInstructionPointer32,
- NewInstructionPointer
- );
- if (OriginalInstructionPointer != 0) {
- return OriginalInstructionPointer;
- }
-
- if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) {
- OriginalInstructionPointer = (UINT64)CpuState->x86._EIP;
- CpuState->x86._EIP = (UINT32)NewInstructionPointer;
- //
- // Clear the auto HALT restart flag so the RSM instruction returns
- // program control to the instruction following the HLT instruction.
- //
- if ((CpuState->x86.AutoHALTRestart & BIT0) != 0) {
- CpuState->x86.AutoHALTRestart &= ~BIT0;
- }
- } else {
- OriginalInstructionPointer = CpuState->x64._RIP;
- if ((CpuState->x64.IA32_EFER & LMA) == 0) {
- CpuState->x64._RIP = (UINT32)NewInstructionPointer32;
- } else {
- CpuState->x64._RIP = (UINT32)NewInstructionPointer;
- }
- //
- // Clear the auto HALT restart flag so the RSM instruction returns
- // program control to the instruction following the HLT instruction.
- //
- if ((CpuState->x64.AutoHALTRestart & BIT0) != 0) {
- CpuState->x64.AutoHALTRestart &= ~BIT0;
- }
- }
- return OriginalInstructionPointer;
-}
-
-/**
- Get the size of the SMI Handler in bytes.
-
- @retval The size, in bytes, of the SMI Handler.
-
-**/
-UINTN
-EFIAPI
-GetSmiHandlerSize (
- VOID
- )
-{
- UINTN Size;
-
- Size = SmmCpuFeaturesGetSmiHandlerSize ();
- if (Size != 0) {
- return Size;
- }
- return gcSmiHandlerSize;
-}
-
-/**
- Install the SMI handler for the CPU specified by CpuIndex. This function
- is called by the CPU that was elected as monarch during System Management
- Mode initialization.
-
- @param[in] CpuIndex The index of the CPU to install the custom SMI handler.
- The value must be between 0 and the NumberOfCpus field
- in the System Management System Table (SMST).
- @param[in] SmBase The SMBASE address for the CPU specified by CpuIndex.
- @param[in] SmiStack The stack to use when an SMI is processed by the
- the CPU specified by CpuIndex.
- @param[in] StackSize The size, in bytes, if the stack used when an SMI is
- processed by the CPU specified by CpuIndex.
- @param[in] GdtBase The base address of the GDT to use when an SMI is
- processed by the CPU specified by CpuIndex.
- @param[in] GdtSize The size, in bytes, of the GDT used when an SMI is
- processed by the CPU specified by CpuIndex.
- @param[in] IdtBase The base address of the IDT to use when an SMI is
- processed by the CPU specified by CpuIndex.
- @param[in] IdtSize The size, in bytes, of the IDT used when an SMI is
- processed by the CPU specified by CpuIndex.
- @param[in] Cr3 The base address of the page tables to use when an SMI
- is processed by the CPU specified by CpuIndex.
-**/
-VOID
-EFIAPI
-InstallSmiHandler (
- IN UINTN CpuIndex,
- IN UINT32 SmBase,
- IN VOID *SmiStack,
- IN UINTN StackSize,
- IN UINTN GdtBase,
- IN UINTN GdtSize,
- IN UINTN IdtBase,
- IN UINTN IdtSize,
- IN UINT32 Cr3
- )
-{
- if (SmmCpuFeaturesGetSmiHandlerSize () != 0) {
- //
- // Install SMI handler provided by library
- //
- SmmCpuFeaturesInstallSmiHandler (
- CpuIndex,
- SmBase,
- SmiStack,
- StackSize,
- GdtBase,
- GdtSize,
- IdtBase,
- IdtSize,
- Cr3
- );
- return;
- }
-
- //
- // Initialize values in template before copy
- //
- gSmiStack = (UINT32)((UINTN)SmiStack + StackSize - sizeof (UINTN));
- gSmiCr3 = Cr3;
- gSmbase = SmBase;
- gSmiHandlerIdtr.Base = IdtBase;
- gSmiHandlerIdtr.Limit = (UINT16)(IdtSize - 1);
-
- //
- // Set the value at the top of the CPU stack to the CPU Index
- //
- *(UINTN*)(UINTN)gSmiStack = CpuIndex;
-
- //
- // Copy template to CPU specific SMI handler location
- //
- CopyMem (
- (VOID*)(UINTN)(SmBase + SMM_HANDLER_OFFSET),
- (VOID*)gcSmiHandlerTemplate,
- gcSmiHandlerSize
- );
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c
deleted file mode 100644
index 5a632eaa24..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/SyncTimer.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/** @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);
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.S b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.S
deleted file mode 100644
index d7cbc8cdc5..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.S
+++ /dev/null
@@ -1,204 +0,0 @@
-#------------------------------------------------------------------------------
-#
-# Copyright (c) 2006 - 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.
-#
-# Module Name:
-#
-# MpFuncs.S
-#
-# Abstract:
-#
-# This is the assembly code for Multi-processor S3 support
-#
-#------------------------------------------------------------------------------
-
-.equ VacantFlag, 0x0
-.equ NotVacantFlag, 0xff
-
-.equ LockLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart
-.equ StackStartAddressLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x08
-.equ StackSizeLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x10
-.equ CProcedureLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x18
-.equ GdtrLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x20
-.equ IdtrLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x2A
-.equ BufferStartLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x34
-.equ Cr3OffsetLocation, RendezvousFunnelProcEnd - RendezvousFunnelProcStart + 0x38
-
-#-------------------------------------------------------------------------------------
-#RendezvousFunnelProc procedure follows. All APs execute their procedure. This
-#procedure serializes all the AP processors through an Init sequence. It must be
-#noted that APs arrive here very raw...ie: real mode, no stack.
-#ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
-#IS IN MACHINE CODE.
-#-------------------------------------------------------------------------------------
-#RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
-
-.code:
-
-ASM_GLOBAL ASM_PFX(RendezvousFunnelProc)
-ASM_PFX(RendezvousFunnelProc):
-RendezvousFunnelProcStart:
-
-# At this point CS = 0x(vv00) and ip= 0x0.
-
- .byte 0x8c,0xc8 # mov ax, cs
- .byte 0x8e,0xd8 # mov ds, ax
- .byte 0x8e,0xc0 # mov es, ax
- .byte 0x8e,0xd0 # mov ss, ax
- .byte 0x33,0xc0 # xor ax, ax
- .byte 0x8e,0xe0 # mov fs, ax
- .byte 0x8e,0xe8 # mov gs, ax
-
-flat32Start:
-
- .byte 0xBE
- .word BufferStartLocation
- .byte 0x66,0x8B,0x14 # mov edx,dword ptr [si] ; EDX is keeping the start address of wakeup buffer
-
- .byte 0xBE
- .word Cr3OffsetLocation
- .byte 0x66,0x8B,0xC # mov ecx,dword ptr [si] ; ECX is keeping the value of CR3
-
- .byte 0xBE
- .word GdtrLocation
- .byte 0x66 # db 66h
- .byte 0x2E,0xF,0x1,0x14 # lgdt fword ptr cs:[si]
-
- .byte 0xBE
- .word IdtrLocation
- .byte 0x66 # db 66h
- .byte 0x2E,0xF,0x1,0x1C # lidt fword ptr cs:[si]
-
- .byte 0x33,0xC0 # xor ax, ax
- .byte 0x8E,0xD8 # mov ds, ax
-
- .byte 0xF,0x20,0xC0 # mov eax, cr0 ; Get control register 0
- .byte 0x66,0x83,0xC8,0x1 # or eax, 000000001h ; Set PE bit (bit #0)
- .byte 0xF,0x22,0xC0 # mov cr0, eax
-
-FLAT32_JUMP:
-
- .byte 0x66,0x67,0xEA # far jump
- .long 0x0 # 32-bit offset
- .word 0x20 # 16-bit selector
-
-PMODE_ENTRY: # protected mode entry point
-
- .byte 0x66,0xB8,0x18,0x0 # mov ax, 18h
- .byte 0x66,0x8E,0xD8 # mov ds, ax
- .byte 0x66,0x8E,0xC0 # mov es, ax
- .byte 0x66,0x8E,0xE0 # mov fs, ax
- .byte 0x66,0x8E,0xE8 # mov gs, ax
- .byte 0x66,0x8E,0xD0 # mov ss, ax ; Flat mode setup.
-
- .byte 0xF,0x20,0xE0 # mov eax, cr4
- .byte 0xF,0xBA,0xE8,0x5 # bts eax, 5
- .byte 0xF,0x22,0xE0 # mov cr4, eax
-
- .byte 0xF,0x22,0xD9 # mov cr3, ecx
-
- .byte 0x8B,0xF2 # mov esi, edx ; Save wakeup buffer address
-
- .byte 0xB9
- .long 0xC0000080 # mov ecx, 0c0000080h ; EFER MSR number.
- .byte 0xF,0x32 # rdmsr ; Read EFER.
- .byte 0xF,0xBA,0xE8,0x8 # bts eax, 8 ; Set LME=1.
- .byte 0xF,0x30 # wrmsr ; Write EFER.
-
- .byte 0xF,0x20,0xC0 # mov eax, cr0 ; Read CR0.
- .byte 0xF,0xBA,0xE8,0x1F # bts eax, 31 ; Set PG=1.
- .byte 0xF,0x22,0xC0 # mov cr0, eax ; Write CR0.
-
-LONG_JUMP:
-
- .byte 0x67,0xEA # far jump
- .long 0x0 # 32-bit offset
- .word 0x38 # 16-bit selector
-
-LongModeStart:
-
- movw $0x30,%ax
- .byte 0x66
- movw %ax,%ds
- .byte 0x66
- movw %ax,%es
- .byte 0x66
- movw %ax,%ss
-
- movl %esi,%edi
- addl $LockLocation, %edi
- movb $NotVacantFlag, %al
-TestLock:
- xchgb (%edi), %al
- cmpb $NotVacantFlag, %al
- jz TestLock
-
-ProgramStack:
-
- movl %esi,%edi
- addl $StackSizeLocation, %edi
- movq (%edi), %rax
- movl %esi,%edi
- addl $StackStartAddressLocation, %edi
- addq (%edi), %rax
- movq %rax, %rsp
- movq %rax, (%edi)
-
-Releaselock:
-
- movb $VacantFlag, %al
- movl %esi,%edi
- addl $LockLocation, %edi
- xchgb (%edi), %al
-
- #
- # Call assembly function to initialize FPU.
- #
- movabsq $ASM_PFX(InitializeFloatingPointUnits), %rax
- subq $0x20, %rsp
- call *%rax
- addq $0x20, %rsp
- #
- # Call C Function
- #
- movl %esi,%edi
- addl $CProcedureLocation, %edi
- movq (%edi), %rax
-
- testq %rax, %rax
- jz GoToSleep
-
- subq $0x20, %rsp
- call *%rax
- addq $0x20, %rsp
-
-GoToSleep:
- cli
- hlt
- jmp .-2
-
-RendezvousFunnelProcEnd:
-
-
-#-------------------------------------------------------------------------------------
-# AsmGetAddressMap (&AddressMap);
-#-------------------------------------------------------------------------------------
-# comments here for definition of address map
-ASM_GLOBAL ASM_PFX(AsmGetAddressMap)
-ASM_PFX(AsmGetAddressMap):
- movabsq $RendezvousFunnelProcStart, %rax
- movq %rax, (%rcx)
- movq $(PMODE_ENTRY - RendezvousFunnelProcStart), 0x08(%rcx)
- movq $(FLAT32_JUMP - RendezvousFunnelProcStart), 0x10(%rcx)
- movq $(RendezvousFunnelProcEnd - RendezvousFunnelProcStart), 0x18(%rcx)
- movq $(LongModeStart - RendezvousFunnelProcStart), 0x20(%rcx)
- movq $(LONG_JUMP - RendezvousFunnelProcStart), 0x28(%rcx)
- ret
-
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.asm b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.asm
deleted file mode 100644
index 2c5a7c9bc2..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/MpFuncs.asm
+++ /dev/null
@@ -1,206 +0,0 @@
-;------------------------------------------------------------------------------ ;
-; Copyright (c) 2006 - 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.
-;
-; Module Name:
-;
-; MpFuncs.asm
-;
-; Abstract:
-;
-; This is the assembly code for Multi-processor S3 support
-;
-;-------------------------------------------------------------------------------
-
-EXTERN InitializeFloatingPointUnits:PROC
-
-VacantFlag Equ 00h
-NotVacantFlag Equ 0ffh
-
-LockLocation equ RendezvousFunnelProcEnd - RendezvousFunnelProcStart
-StackStartAddressLocation equ LockLocation + 08h
-StackSizeLocation equ LockLocation + 10h
-CProcedureLocation equ LockLocation + 18h
-GdtrLocation equ LockLocation + 20h
-IdtrLocation equ LockLocation + 2Ah
-BufferStartLocation equ LockLocation + 34h
-Cr3OffsetLocation equ LockLocation + 38h
-
-;-------------------------------------------------------------------------------------
-;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
-;procedure serializes all the AP processors through an Init sequence. It must be
-;noted that APs arrive here very raw...ie: real mode, no stack.
-;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
-;IS IN MACHINE CODE.
-;-------------------------------------------------------------------------------------
-;RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
-
-;text SEGMENT
-.code
-
-RendezvousFunnelProc PROC
-RendezvousFunnelProcStart::
-
-; At this point CS = 0x(vv00) and ip= 0x0.
-
- db 8ch, 0c8h ; mov ax, cs
- db 8eh, 0d8h ; mov ds, ax
- db 8eh, 0c0h ; mov es, ax
- db 8eh, 0d0h ; mov ss, ax
- db 33h, 0c0h ; xor ax, ax
- db 8eh, 0e0h ; mov fs, ax
- db 8eh, 0e8h ; mov gs, ax
-
-flat32Start::
-
- db 0BEh
- dw BufferStartLocation ; mov si, BufferStartLocation
- db 66h, 8Bh, 14h ; mov edx,dword ptr [si] ; EDX is keeping the start address of wakeup buffer
-
- db 0BEh
- dw Cr3OffsetLocation ; mov si, Cr3Location
- db 66h, 8Bh, 0Ch ; mov ecx,dword ptr [si] ; ECX is keeping the value of CR3
-
- db 0BEh
- dw GdtrLocation ; mov si, GdtrProfile
- db 66h ; db 66h
- db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
-
- db 0BEh
- dw IdtrLocation ; mov si, IdtrProfile
- db 66h ; db 66h
- db 2Eh, 0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
-
- db 33h, 0C0h ; xor ax, ax
- db 8Eh, 0D8h ; mov ds, ax
-
- db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Get control register 0
- db 66h, 83h, 0C8h, 01h ; or eax, 000000001h ; Set PE bit (bit #0)
- db 0Fh, 22h, 0C0h ; mov cr0, eax
-
-FLAT32_JUMP::
-
- db 66h, 67h, 0EAh ; far jump
- dd 0h ; 32-bit offset
- dw 20h ; 16-bit selector
-
-PMODE_ENTRY:: ; protected mode entry point
-
- db 66h, 0B8h, 18h, 00h ; mov ax, 18h
- db 66h, 8Eh, 0D8h ; mov ds, ax
- db 66h, 8Eh, 0C0h ; mov es, ax
- db 66h, 8Eh, 0E0h ; mov fs, ax
- db 66h, 8Eh, 0E8h ; mov gs, ax
- db 66h, 8Eh, 0D0h ; mov ss, ax ; Flat mode setup.
-
- db 0Fh, 20h, 0E0h ; mov eax, cr4
- db 0Fh, 0BAh, 0E8h, 05h ; bts eax, 5
- db 0Fh, 22h, 0E0h ; mov cr4, eax
-
- db 0Fh, 22h, 0D9h ; mov cr3, ecx
-
- db 8Bh, 0F2h ; mov esi, edx ; Save wakeup buffer address
-
- db 0B9h
- dd 0C0000080h ; mov ecx, 0c0000080h ; EFER MSR number.
- db 0Fh, 32h ; rdmsr ; Read EFER.
- db 0Fh, 0BAh, 0E8h, 08h ; bts eax, 8 ; Set LME=1.
- db 0Fh, 30h ; wrmsr ; Write EFER.
-
- db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Read CR0.
- db 0Fh, 0BAh, 0E8h, 1Fh ; bts eax, 31 ; Set PG=1.
- db 0Fh, 22h, 0C0h ; mov cr0, eax ; Write CR0.
-
-LONG_JUMP::
-
- db 67h, 0EAh ; far jump
- dd 0h ; 32-bit offset
- dw 38h ; 16-bit selector
-
-LongModeStart::
-
- mov ax, 30h
- mov ds, ax
- mov es, ax
- mov ss, ax
-
- mov edi, esi
- add edi, LockLocation
- mov al, NotVacantFlag
-TestLock::
- xchg byte ptr [edi], al
- cmp al, NotVacantFlag
- jz TestLock
-
-ProgramStack::
-
- mov edi, esi
- add edi, StackSizeLocation
- mov rax, qword ptr [edi]
- mov edi, esi
- add edi, StackStartAddressLocation
- add rax, qword ptr [edi]
- mov rsp, rax
- mov qword ptr [edi], rax
-
-Releaselock::
-
- mov al, VacantFlag
- mov edi, esi
- add edi, LockLocation
- xchg byte ptr [edi], al
-
- ;
- ; Call assembly function to initialize FPU.
- ;
- mov rax, InitializeFloatingPointUnits
- sub rsp, 20h
- call rax
- add rsp, 20h
-
- ;
- ; Call C Function
- ;
- mov edi, esi
- add edi, CProcedureLocation
- mov rax, qword ptr [edi]
-
- test rax, rax
- jz GoToSleep
-
- sub rsp, 20h
- call rax
- add rsp, 20h
-
-GoToSleep::
- cli
- hlt
- jmp $-2
-
-RendezvousFunnelProcEnd::
-RendezvousFunnelProc ENDP
-
-
-;-------------------------------------------------------------------------------------
-; AsmGetAddressMap (&AddressMap);
-;-------------------------------------------------------------------------------------
-; comments here for definition of address map
-AsmGetAddressMap PROC
- mov rax, offset RendezvousFunnelProcStart
- mov qword ptr [rcx], rax
- mov qword ptr [rcx+8h], PMODE_ENTRY - RendezvousFunnelProcStart
- mov qword ptr [rcx+10h], FLAT32_JUMP - RendezvousFunnelProcStart
- mov qword ptr [rcx+18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
- mov qword ptr [rcx+20h], LongModeStart - RendezvousFunnelProcStart
- mov qword ptr [rcx+28h], LONG_JUMP - RendezvousFunnelProcStart
- ret
-
-AsmGetAddressMap ENDP
-
-END
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
deleted file mode 100644
index 9cee784156..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/PageTbl.c
+++ /dev/null
@@ -1,691 +0,0 @@
-/** @file
-Page Fault (#PF) handler for X64 processors
-
-Copyright (c) 2009 - 2016, 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"
-
-#define PAGE_TABLE_PAGES 8
-#define ACC_MAX_BIT BIT3
-LIST_ENTRY mPagePool = INITIALIZE_LIST_HEAD_VARIABLE (mPagePool);
-BOOLEAN m1GPageTableSupport = FALSE;
-
-/**
- Check if 1-GByte pages is supported by processor or not.
-
- @retval TRUE 1-GByte pages is supported.
- @retval FALSE 1-GByte pages is not supported.
-
-**/
-BOOLEAN
-Is1GPageSupport (
- VOID
- )
-{
- UINT32 RegEax;
- UINT32 RegEdx;
-
- AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
- if (RegEax >= 0x80000001) {
- AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
- if ((RegEdx & BIT26) != 0) {
- return TRUE;
- }
- }
- return FALSE;
-}
-
-/**
- Set sub-entries number in entry.
-
- @param[in, out] Entry Pointer to entry
- @param[in] SubEntryNum Sub-entries number based on 0:
- 0 means there is 1 sub-entry under this entry
- 0x1ff means there is 512 sub-entries under this entry
-
-**/
-VOID
-SetSubEntriesNum (
- IN OUT UINT64 *Entry,
- IN UINT64 SubEntryNum
- )
-{
- //
- // Sub-entries number is saved in BIT52 to BIT60 (reserved field) in Entry
- //
- *Entry = BitFieldWrite64 (*Entry, 52, 60, SubEntryNum);
-}
-
-/**
- Return sub-entries number in entry.
-
- @param[in] Entry Pointer to entry
-
- @return Sub-entries number based on 0:
- 0 means there is 1 sub-entry under this entry
- 0x1ff means there is 512 sub-entries under this entry
-**/
-UINT64
-GetSubEntriesNum (
- IN UINT64 *Entry
- )
-{
- //
- // Sub-entries number is saved in BIT52 to BIT60 (reserved field) in Entry
- //
- return BitFieldRead64 (*Entry, 52, 60);
-}
-
-/**
- Create PageTable for SMM use.
-
- @return The address of PML4 (to set CR3).
-
-**/
-UINT32
-SmmInitPageTable (
- VOID
- )
-{
- EFI_PHYSICAL_ADDRESS Pages;
- UINT64 *PTEntry;
- LIST_ENTRY *FreePage;
- UINTN Index;
- UINTN PageFaultHandlerHookAddress;
- IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
-
- //
- // Initialize spin lock
- //
- InitializeSpinLock (mPFLock);
-
- m1GPageTableSupport = Is1GPageSupport ();
- //
- // Generate PAE page table for the first 4GB memory space
- //
- Pages = Gen4GPageTable (PAGE_TABLE_PAGES + 1, FALSE);
-
- //
- // Set IA32_PG_PMNT bit to mask this entry
- //
- PTEntry = (UINT64*)(UINTN)Pages;
- for (Index = 0; Index < 4; Index++) {
- PTEntry[Index] |= IA32_PG_PMNT;
- }
-
- //
- // Fill Page-Table-Level4 (PML4) entry
- //
- PTEntry = (UINT64*)(UINTN)(Pages - EFI_PAGES_TO_SIZE (PAGE_TABLE_PAGES + 1));
- *PTEntry = Pages + PAGE_ATTRIBUTE_BITS;
- ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry));
- //
- // Set sub-entries number
- //
- SetSubEntriesNum (PTEntry, 3);
-
- //
- // Add remaining pages to page pool
- //
- FreePage = (LIST_ENTRY*)(PTEntry + EFI_PAGE_SIZE / sizeof (*PTEntry));
- while ((UINTN)FreePage < Pages) {
- InsertTailList (&mPagePool, FreePage);
- FreePage += EFI_PAGE_SIZE / sizeof (*FreePage);
- }
-
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
- //
- // Set own Page Fault entry instead of the default one, because SMM Profile
- // feature depends on IRET instruction to do Single Step
- //
- PageFaultHandlerHookAddress = (UINTN)PageFaultIdtHandlerSmmProfile;
- IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) gcSmiIdtr.Base;
- IdtEntry += EXCEPT_IA32_PAGE_FAULT;
- IdtEntry->Bits.OffsetLow = (UINT16)PageFaultHandlerHookAddress;
- IdtEntry->Bits.Reserved_0 = 0;
- IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
- IdtEntry->Bits.OffsetHigh = (UINT16)(PageFaultHandlerHookAddress >> 16);
- IdtEntry->Bits.OffsetUpper = (UINT32)(PageFaultHandlerHookAddress >> 32);
- IdtEntry->Bits.Reserved_1 = 0;
- } else {
- //
- // Register Smm Page Fault Handler
- //
- SmmRegisterExceptionHandler (&mSmmCpuService, EXCEPT_IA32_PAGE_FAULT, SmiPFHandler);
- }
-
- //
- // Additional SMM IDT initialization for SMM stack guard
- //
- if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
- InitializeIDTSmmStackGuard ();
- }
-
- //
- // Return the address of PML4 (to set CR3)
- //
- return (UINT32)(UINTN)PTEntry;
-}
-
-/**
- Set access record in entry.
-
- @param[in, out] Entry Pointer to entry
- @param[in] Acc Access record value
-
-**/
-VOID
-SetAccNum (
- IN OUT UINT64 *Entry,
- IN UINT64 Acc
- )
-{
- //
- // Access record is saved in BIT9 to BIT11 (reserved field) in Entry
- //
- *Entry = BitFieldWrite64 (*Entry, 9, 11, Acc);
-}
-
-/**
- Return access record in entry.
-
- @param[in] Entry Pointer to entry
-
- @return Access record value.
-
-**/
-UINT64
-GetAccNum (
- IN UINT64 *Entry
- )
-{
- //
- // Access record is saved in BIT9 to BIT11 (reserved field) in Entry
- //
- return BitFieldRead64 (*Entry, 9, 11);
-}
-
-/**
- Return and update the access record in entry.
-
- @param[in, out] Entry Pointer to entry
-
- @return Access record value.
-
-**/
-UINT64
-GetAndUpdateAccNum (
- IN OUT UINT64 *Entry
- )
-{
- UINT64 Acc;
-
- Acc = GetAccNum (Entry);
- if ((*Entry & IA32_PG_A) != 0) {
- //
- // If this entry has been accessed, clear access flag in Entry and update access record
- // to the initial value 7, adding ACC_MAX_BIT is to make it larger than others
- //
- *Entry &= ~(UINT64)(UINTN)IA32_PG_A;
- SetAccNum (Entry, 0x7);
- return (0x7 + ACC_MAX_BIT);
- } else {
- if (Acc != 0) {
- //
- // If the access record is not the smallest value 0, minus 1 and update the access record field
- //
- SetAccNum (Entry, Acc - 1);
- }
- }
- return Acc;
-}
-
-/**
- Reclaim free pages for PageFault handler.
-
- Search the whole entries tree to find the leaf entry that has the smallest
- access record value. Insert the page pointed by this leaf entry into the
- page pool. And check its upper entries if need to be inserted into the page
- pool or not.
-
-**/
-VOID
-ReclaimPages (
- VOID
- )
-{
- UINT64 *Pml4;
- UINT64 *Pdpt;
- UINT64 *Pdt;
- UINTN Pml4Index;
- UINTN PdptIndex;
- UINTN PdtIndex;
- UINTN MinPml4;
- UINTN MinPdpt;
- UINTN MinPdt;
- UINT64 MinAcc;
- UINT64 Acc;
- UINT64 SubEntriesNum;
- BOOLEAN PML4EIgnore;
- BOOLEAN PDPTEIgnore;
- UINT64 *ReleasePageAddress;
-
- Pml4 = NULL;
- Pdpt = NULL;
- Pdt = NULL;
- MinAcc = (UINT64)-1;
- MinPml4 = (UINTN)-1;
- MinPdpt = (UINTN)-1;
- MinPdt = (UINTN)-1;
- Acc = 0;
- ReleasePageAddress = 0;
-
- //
- // First, find the leaf entry has the smallest access record value
- //
- Pml4 = (UINT64*)(UINTN)(AsmReadCr3 () & gPhyMask);
- for (Pml4Index = 0; Pml4Index < EFI_PAGE_SIZE / sizeof (*Pml4); Pml4Index++) {
- if ((Pml4[Pml4Index] & IA32_PG_P) == 0 || (Pml4[Pml4Index] & IA32_PG_PMNT) != 0) {
- //
- // If the PML4 entry is not present or is masked, skip it
- //
- continue;
- }
- Pdpt = (UINT64*)(UINTN)(Pml4[Pml4Index] & gPhyMask);
- PML4EIgnore = FALSE;
- for (PdptIndex = 0; PdptIndex < EFI_PAGE_SIZE / sizeof (*Pdpt); PdptIndex++) {
- if ((Pdpt[PdptIndex] & IA32_PG_P) == 0 || (Pdpt[PdptIndex] & IA32_PG_PMNT) != 0) {
- //
- // If the PDPT entry is not present or is masked, skip it
- //
- if ((Pdpt[PdptIndex] & IA32_PG_PMNT) != 0) {
- //
- // If the PDPT entry is masked, we will ignore checking the PML4 entry
- //
- PML4EIgnore = TRUE;
- }
- continue;
- }
- if ((Pdpt[PdptIndex] & IA32_PG_PS) == 0) {
- //
- // It's not 1-GByte pages entry, it should be a PDPT entry,
- // we will not check PML4 entry more
- //
- PML4EIgnore = TRUE;
- Pdt = (UINT64*)(UINTN)(Pdpt[PdptIndex] & gPhyMask);
- PDPTEIgnore = FALSE;
- for (PdtIndex = 0; PdtIndex < EFI_PAGE_SIZE / sizeof(*Pdt); PdtIndex++) {
- if ((Pdt[PdtIndex] & IA32_PG_P) == 0 || (Pdt[PdtIndex] & IA32_PG_PMNT) != 0) {
- //
- // If the PD entry is not present or is masked, skip it
- //
- if ((Pdt[PdtIndex] & IA32_PG_PMNT) != 0) {
- //
- // If the PD entry is masked, we will not PDPT entry more
- //
- PDPTEIgnore = TRUE;
- }
- continue;
- }
- if ((Pdt[PdtIndex] & IA32_PG_PS) == 0) {
- //
- // It's not 2 MByte page table entry, it should be PD entry
- // we will find the entry has the smallest access record value
- //
- PDPTEIgnore = TRUE;
- Acc = GetAndUpdateAccNum (Pdt + PdtIndex);
- if (Acc < MinAcc) {
- //
- // If the PD entry has the smallest access record value,
- // save the Page address to be released
- //
- MinAcc = Acc;
- MinPml4 = Pml4Index;
- MinPdpt = PdptIndex;
- MinPdt = PdtIndex;
- ReleasePageAddress = Pdt + PdtIndex;
- }
- }
- }
- if (!PDPTEIgnore) {
- //
- // If this PDPT entry has no PDT entries pointer to 4 KByte pages,
- // it should only has the entries point to 2 MByte Pages
- //
- Acc = GetAndUpdateAccNum (Pdpt + PdptIndex);
- if (Acc < MinAcc) {
- //
- // If the PDPT entry has the smallest access record value,
- // save the Page address to be released
- //
- MinAcc = Acc;
- MinPml4 = Pml4Index;
- MinPdpt = PdptIndex;
- MinPdt = (UINTN)-1;
- ReleasePageAddress = Pdpt + PdptIndex;
- }
- }
- }
- }
- if (!PML4EIgnore) {
- //
- // If PML4 entry has no the PDPT entry pointer to 2 MByte pages,
- // it should only has the entries point to 1 GByte Pages
- //
- Acc = GetAndUpdateAccNum (Pml4 + Pml4Index);
- if (Acc < MinAcc) {
- //
- // If the PML4 entry has the smallest access record value,
- // save the Page address to be released
- //
- MinAcc = Acc;
- MinPml4 = Pml4Index;
- MinPdpt = (UINTN)-1;
- MinPdt = (UINTN)-1;
- ReleasePageAddress = Pml4 + Pml4Index;
- }
- }
- }
- //
- // Make sure one PML4/PDPT/PD entry is selected
- //
- ASSERT (MinAcc != (UINT64)-1);
-
- //
- // Secondly, insert the page pointed by this entry into page pool and clear this entry
- //
- InsertTailList (&mPagePool, (LIST_ENTRY*)(UINTN)(*ReleasePageAddress & gPhyMask));
- *ReleasePageAddress = 0;
-
- //
- // Lastly, check this entry's upper entries if need to be inserted into page pool
- // or not
- //
- while (TRUE) {
- if (MinPdt != (UINTN)-1) {
- //
- // If 4 KByte Page Table is released, check the PDPT entry
- //
- Pdpt = (UINT64*)(UINTN)(Pml4[MinPml4] & gPhyMask);
- SubEntriesNum = GetSubEntriesNum(Pdpt + MinPdpt);
- if (SubEntriesNum == 0) {
- //
- // Release the empty Page Directory table if there was no more 4 KByte Page Table entry
- // clear the Page directory entry
- //
- InsertTailList (&mPagePool, (LIST_ENTRY*)(UINTN)(Pdpt[MinPdpt] & gPhyMask));
- Pdpt[MinPdpt] = 0;
- //
- // Go on checking the PML4 table
- //
- MinPdt = (UINTN)-1;
- continue;
- }
- //
- // Update the sub-entries filed in PDPT entry and exit
- //
- SetSubEntriesNum (Pdpt + MinPdpt, SubEntriesNum - 1);
- break;
- }
- if (MinPdpt != (UINTN)-1) {
- //
- // One 2MB Page Table is released or Page Directory table is released, check the PML4 entry
- //
- SubEntriesNum = GetSubEntriesNum (Pml4 + MinPml4);
- if (SubEntriesNum == 0) {
- //
- // Release the empty PML4 table if there was no more 1G KByte Page Table entry
- // clear the Page directory entry
- //
- InsertTailList (&mPagePool, (LIST_ENTRY*)(UINTN)(Pml4[MinPml4] & gPhyMask));
- Pml4[MinPml4] = 0;
- MinPdpt = (UINTN)-1;
- continue;
- }
- //
- // Update the sub-entries filed in PML4 entry and exit
- //
- SetSubEntriesNum (Pml4 + MinPml4, SubEntriesNum - 1);
- break;
- }
- //
- // PLM4 table has been released before, exit it
- //
- break;
- }
-}
-
-/**
- Allocate free Page for PageFault handler use.
-
- @return Page address.
-
-**/
-UINT64
-AllocPage (
- VOID
- )
-{
- UINT64 RetVal;
-
- if (IsListEmpty (&mPagePool)) {
- //
- // If page pool is empty, reclaim the used pages and insert one into page pool
- //
- ReclaimPages ();
- }
-
- //
- // Get one free page and remove it from page pool
- //
- RetVal = (UINT64)(UINTN)mPagePool.ForwardLink;
- RemoveEntryList (mPagePool.ForwardLink);
- //
- // Clean this page and return
- //
- ZeroMem ((VOID*)(UINTN)RetVal, EFI_PAGE_SIZE);
- return RetVal;
-}
-
-/**
- Page Fault handler for SMM use.
-
-**/
-VOID
-SmiDefaultPFHandler (
- VOID
- )
-{
- UINT64 *PageTable;
- UINT64 *Pml4;
- UINT64 PFAddress;
- UINTN StartBit;
- UINTN EndBit;
- UINT64 PTIndex;
- UINTN Index;
- SMM_PAGE_SIZE_TYPE PageSize;
- UINTN NumOfPages;
- UINTN PageAttribute;
- EFI_STATUS Status;
- UINT64 *UpperEntry;
-
- //
- // Set default SMM page attribute
- //
- PageSize = SmmPageSize2M;
- NumOfPages = 1;
- PageAttribute = 0;
-
- EndBit = 0;
- Pml4 = (UINT64*)(AsmReadCr3 () & gPhyMask);
- PFAddress = AsmReadCr2 ();
-
- Status = GetPlatformPageTableAttribute (PFAddress, &PageSize, &NumOfPages, &PageAttribute);
- //
- // If platform not support page table attribute, set default SMM page attribute
- //
- if (Status != EFI_SUCCESS) {
- PageSize = SmmPageSize2M;
- NumOfPages = 1;
- PageAttribute = 0;
- }
- if (PageSize >= MaxSmmPageSizeType) {
- PageSize = SmmPageSize2M;
- }
- if (NumOfPages > 512) {
- NumOfPages = 512;
- }
-
- switch (PageSize) {
- case SmmPageSize4K:
- //
- // BIT12 to BIT20 is Page Table index
- //
- EndBit = 12;
- break;
- case SmmPageSize2M:
- //
- // BIT21 to BIT29 is Page Directory index
- //
- EndBit = 21;
- PageAttribute |= (UINTN)IA32_PG_PS;
- break;
- case SmmPageSize1G:
- if (!m1GPageTableSupport) {
- DEBUG ((EFI_D_ERROR, "1-GByte pages is not supported!"));
- ASSERT (FALSE);
- }
- //
- // BIT30 to BIT38 is Page Directory Pointer Table index
- //
- EndBit = 30;
- PageAttribute |= (UINTN)IA32_PG_PS;
- break;
- default:
- ASSERT (FALSE);
- }
-
- //
- // If execute-disable is enabled, set NX bit
- //
- if (mXdEnabled) {
- PageAttribute |= IA32_PG_NX;
- }
-
- for (Index = 0; Index < NumOfPages; Index++) {
- PageTable = Pml4;
- UpperEntry = NULL;
- for (StartBit = 39; StartBit > EndBit; StartBit -= 9) {
- PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8);
- if ((PageTable[PTIndex] & IA32_PG_P) == 0) {
- //
- // If the entry is not present, allocate one page from page pool for it
- //
- PageTable[PTIndex] = AllocPage () | PAGE_ATTRIBUTE_BITS;
- } else {
- //
- // Save the upper entry address
- //
- UpperEntry = PageTable + PTIndex;
- }
- //
- // BIT9 to BIT11 of entry is used to save access record,
- // initialize value is 7
- //
- PageTable[PTIndex] |= (UINT64)IA32_PG_A;
- SetAccNum (PageTable + PTIndex, 7);
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & gPhyMask);
- }
-
- PTIndex = BitFieldRead64 (PFAddress, StartBit, StartBit + 8);
- if ((PageTable[PTIndex] & IA32_PG_P) != 0) {
- //
- // Check if the entry has already existed, this issue may occur when the different
- // size page entries created under the same entry
- //
- DEBUG ((EFI_D_ERROR, "PageTable = %lx, PTIndex = %x, PageTable[PTIndex] = %lx\n", PageTable, PTIndex, PageTable[PTIndex]));
- DEBUG ((EFI_D_ERROR, "New page table overlapped with old page table!\n"));
- ASSERT (FALSE);
- }
- //
- // Fill the new entry
- //
- PageTable[PTIndex] = (PFAddress & gPhyMask & ~((1ull << EndBit) - 1)) |
- PageAttribute | IA32_PG_A | PAGE_ATTRIBUTE_BITS;
- if (UpperEntry != NULL) {
- SetSubEntriesNum (UpperEntry, GetSubEntriesNum (UpperEntry) + 1);
- }
- //
- // Get the next page address if we need to create more page tables
- //
- PFAddress += (1ull << EndBit);
- }
-}
-
-/**
- ThePage Fault handler wrapper for SMM use.
-
- @param InterruptType Defines the type of interrupt or exception that
- occurred on the processor.This parameter is processor architecture specific.
- @param SystemContext A pointer to the processor context when
- the interrupt occurred on the processor.
-**/
-VOID
-EFIAPI
-SmiPFHandler (
- IN EFI_EXCEPTION_TYPE InterruptType,
- IN EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- UINTN PFAddress;
-
- ASSERT (InterruptType == EXCEPT_IA32_PAGE_FAULT);
-
- AcquireSpinLock (mPFLock);
-
- PFAddress = AsmReadCr2 ();
-
- //
- // If a page fault occurs in SMRAM range, it should be in a SMM stack guard page.
- //
- if ((FeaturePcdGet (PcdCpuSmmStackGuard)) &&
- (PFAddress >= mCpuHotPlugData.SmrrBase) &&
- (PFAddress < (mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize))) {
- DEBUG ((EFI_D_ERROR, "SMM stack overflow!\n"));
- CpuDeadLoop ();
- }
-
- //
- // If a page fault occurs in SMM range
- //
- if ((PFAddress < mCpuHotPlugData.SmrrBase) ||
- (PFAddress >= mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) {
- if ((SystemContext.SystemContextX64->ExceptionData & IA32_PF_EC_ID) != 0) {
- DEBUG ((EFI_D_ERROR, "Code executed on IP(0x%lx) out of SMM range after SMM is locked!\n", PFAddress));
- DEBUG_CODE (
- DumpModuleInfoByIp (*(UINTN *)(UINTN)SystemContext.SystemContextX64->Rsp);
- );
- CpuDeadLoop ();
- }
- }
-
- if (FeaturePcdGet (PcdCpuSmmProfileEnable)) {
- SmmProfilePFHandler (
- SystemContext.SystemContextX64->Rip,
- SystemContext.SystemContextX64->ExceptionData
- );
- } else {
- SmiDefaultPFHandler ();
- }
-
- ReleaseSpinLock (mPFLock);
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/Semaphore.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/Semaphore.c
deleted file mode 100644
index 6dbcb086aa..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/Semaphore.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/** @file
-Semaphore mechanism to indicate to the BSP that an AP has exited SMM
-after SMBASE relocation.
-
-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"
-
-extern UINT32 mSmmRelocationOriginalAddressPtr32;
-extern UINT32 mRebasedFlagAddr32;
-
-UINTN mSmmRelocationOriginalAddress;
-volatile BOOLEAN *mRebasedFlag;
-
-/**
-AP Semaphore operation in 32-bit mode while BSP runs in 64-bit mode.
-**/
-VOID
-SmmRelocationSemaphoreComplete32 (
- VOID
- );
-
-/**
- Hook return address of SMM Save State so that semaphore code
- can be executed immediately after AP exits SMM to indicate to
- the BSP that an AP has exited SMM after SMBASE relocation.
-
- @param[in] CpuIndex The processor index.
- @param[in] RebasedFlag A pointer to a flag that is set to TRUE
- immediately after AP exits SMM.
-
-**/
-VOID
-SemaphoreHook (
- IN UINTN CpuIndex,
- IN volatile BOOLEAN *RebasedFlag
- )
-{
- SMRAM_SAVE_STATE_MAP *CpuState;
- UINTN TempValue;
-
- mRebasedFlag = RebasedFlag;
- mRebasedFlagAddr32 = (UINT32)(UINTN)mRebasedFlag;
-
- CpuState = (SMRAM_SAVE_STATE_MAP *)(UINTN)(SMM_DEFAULT_SMBASE + SMRAM_SAVE_STATE_MAP_OFFSET);
- mSmmRelocationOriginalAddress = HookReturnFromSmm (
- CpuIndex,
- CpuState,
- (UINT64)(UINTN)&SmmRelocationSemaphoreComplete32,
- (UINT64)(UINTN)&SmmRelocationSemaphoreComplete
- );
-
- //
- // Use temp value to fix ICC complier warning
- //
- TempValue = (UINTN)&mSmmRelocationOriginalAddress;
- mSmmRelocationOriginalAddressPtr32 = (UINT32)TempValue;
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S
deleted file mode 100644
index 7e9ac58cb2..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S
+++ /dev/null
@@ -1,196 +0,0 @@
-#------------------------------------------------------------------------------
-#
-# 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.
-#
-# Module Name:
-#
-# SmiEntry.S
-#
-# Abstract:
-#
-# Code template of the SMI handler for a particular processor
-#
-#------------------------------------------------------------------------------
-
-ASM_GLOBAL ASM_PFX(gcSmiHandlerTemplate)
-ASM_GLOBAL ASM_PFX(gcSmiHandlerSize)
-ASM_GLOBAL ASM_PFX(gSmiCr3)
-ASM_GLOBAL ASM_PFX(gSmiStack)
-ASM_GLOBAL ASM_PFX(gSmbase)
-ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr)
-
-#
-# Constants relating to PROCESSOR_SMM_DESCRIPTOR
-#
-.equ DSC_OFFSET, 0xfb00
-.equ DSC_GDTPTR, 0x30
-.equ DSC_GDTSIZ, 0x38
-.equ DSC_CS, 14
-.equ DSC_DS, 16
-.equ DSC_SS, 18
-.equ DSC_OTHERSEG, 20
-#
-# Constants relating to CPU State Save Area
-#
-.equ SSM_DR6, 0xffd0
-.equ SSM_DR7, 0xffc8
-
-.equ PROTECT_MODE_CS, 0x08
-.equ PROTECT_MODE_DS, 0x20
-.equ LONG_MODE_CS, 0x38
-.equ TSS_SEGMENT, 0x40
-.equ GDT_SIZE, 0x50
-
- .text
-
-ASM_PFX(gcSmiHandlerTemplate):
-
-_SmiEntryPoint:
- #
- # The encoding of BX in 16-bit addressing mode is the same as of RDI in 64-
- # bit addressing mode. And that coincidence has been used in the following
- # "64-bit like" 16-bit code. Be aware that once RDI is referenced as a
- # base address register, it is actually BX that is referenced.
- #
- .byte 0xbb # mov bx, imm16
- .word _GdtDesc - _SmiEntryPoint + 0x8000
- #
- # fix GDT descriptor
- #
- .byte 0x2e,0xa1 # mov ax, cs:[offset16]
- .word DSC_OFFSET + DSC_GDTSIZ
- .byte 0x48 # dec ax
- .byte 0x2e
- movl %eax, (%rdi) # mov cs:[bx], ax
- .byte 0x66,0x2e,0xa1 # mov eax, cs:[offset16]
- .word DSC_OFFSET + DSC_GDTPTR
- .byte 0x2e
- movw %ax, 2(%rdi)
- .byte 0x66,0x2e
- lgdt (%rdi)
- #
- # Patch ProtectedMode Segment
- #
- .byte 0xb8
- .word PROTECT_MODE_CS
- .byte 0x2e
- movl %eax, -2(%rdi)
- #
- # Patch ProtectedMode entry
- #
- .byte 0x66, 0xbf # mov edi, SMBASE
-ASM_PFX(gSmbase): .space 4
- lea ((ProtectedMode - _SmiEntryPoint) + 0x8000)(%edi), %ax
- .byte 0x2e
- movw %ax, -6(%rdi)
- #
- # Switch into ProtectedMode
- #
- movq %cr0, %rbx
- .byte 0x66
- andl $0x9ffafff3, %ebx
- .byte 0x66
- orl $0x00000023, %ebx
-
- movq %rbx, %cr0
- .byte 0x66, 0xea
- .space 6
-
-_GdtDesc: .space 6
-
-ProtectedMode:
- movw $PROTECT_MODE_DS, %ax
- movl %eax, %ds
- movl %eax, %es
- movl %eax, %fs
- movl %eax, %gs
- movl %eax, %ss
- .byte 0xbc # mov esp, imm32
-ASM_PFX(gSmiStack): .space 4
- jmp ProtFlatMode
-
-ProtFlatMode:
- .byte 0xb8
-ASM_PFX(gSmiCr3): .space 4
- movq %rax, %cr3
- movl $0x668,%eax # as cr4.PGE is not set here, refresh cr3
- movq %rax, %cr4 # in PreModifyMtrrs() to flush TLB.
-# Load TSS
- subl $8, %esp # reserve room in stack
- sgdt (%rsp)
- movl 2(%rsp), %eax # eax = GDT base
- addl $8, %esp
- movb $0x89, %dl
- movb %dl, (TSS_SEGMENT + 5)(%rax) # clear busy flag
- movl $TSS_SEGMENT, %eax
- ltr %ax
-
- #
- # Switch to LongMode
- #
- pushq $LONG_MODE_CS # push cs hardcore here
- call Base # push return address for retf later
-Base:
- addl $(LongMode - Base), (%rsp) # offset for far retf, seg is the 1st arg
- movl $0xc0000080, %ecx
- rdmsr
- orb $1,%ah
- wrmsr
- movq %cr0, %rbx
- orl $0x080010000, %ebx # enable paging + WP
- movq %rbx, %cr0
- retf
-LongMode: # long mode (64-bit code) starts here
- movabsq $ASM_PFX(gSmiHandlerIdtr), %rax
- lidt (%rax)
- lea (DSC_OFFSET)(%rdi), %ebx
- movw DSC_DS(%rbx), %ax
- movl %eax,%ds
- movw DSC_OTHERSEG(%rbx), %ax
- movl %eax,%es
- movl %eax,%fs
- movl %eax,%gs
- movw DSC_SS(%rbx), %ax
- movl %eax,%ss
-# jmp _SmiHandler ; instruction is not needed
-
-_SmiHandler:
- movq (%rsp), %rbx
- # Save FP registers
-
- subq $0x208, %rsp
- .byte 0x48 # FXSAVE64
- fxsave (%rsp)
-
- addq $-0x20, %rsp
-
- movq %rbx, %rcx
- movabsq $ASM_PFX(CpuSmmDebugEntry), %rax
- call *%rax
-
- movq %rbx, %rcx
- movabsq $ASM_PFX(SmiRendezvous), %rax
- call *%rax
-
- movq %rbx, %rcx
- movabsq $ASM_PFX(CpuSmmDebugExit), %rax
- call *%rax
-
- addq $0x20, %rsp
-
- #
- # Restore FP registers
- #
- .byte 0x48 # FXRSTOR64
- fxrstor (%rsp)
-
- rsm
-
-ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm
deleted file mode 100644
index 094cf2c3da..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm
+++ /dev/null
@@ -1,196 +0,0 @@
-;------------------------------------------------------------------------------ ;
-; 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.
-;
-; Module Name:
-;
-; SmiEntry.asm
-;
-; Abstract:
-;
-; Code template of the SMI handler for a particular processor
-;
-;-------------------------------------------------------------------------------
-
-;
-; Variables referenced by C code
-;
-EXTERNDEF SmiRendezvous:PROC
-EXTERNDEF CpuSmmDebugEntry:PROC
-EXTERNDEF CpuSmmDebugExit:PROC
-EXTERNDEF gcSmiHandlerTemplate:BYTE
-EXTERNDEF gcSmiHandlerSize:WORD
-EXTERNDEF gSmiCr3:DWORD
-EXTERNDEF gSmiStack:DWORD
-EXTERNDEF gSmbase:DWORD
-EXTERNDEF gSmiHandlerIdtr:FWORD
-
-
-;
-; Constants relating to PROCESSOR_SMM_DESCRIPTOR
-;
-DSC_OFFSET EQU 0fb00h
-DSC_GDTPTR EQU 30h
-DSC_GDTSIZ EQU 38h
-DSC_CS EQU 14
-DSC_DS EQU 16
-DSC_SS EQU 18
-DSC_OTHERSEG EQU 20
-;
-; Constants relating to CPU State Save Area
-;
-SSM_DR6 EQU 0ffd0h
-SSM_DR7 EQU 0ffc8h
-
-PROTECT_MODE_CS EQU 08h
-PROTECT_MODE_DS EQU 20h
-LONG_MODE_CS EQU 38h
-TSS_SEGMENT EQU 40h
-GDT_SIZE EQU 50h
-
- .code
-
-gcSmiHandlerTemplate LABEL BYTE
-
-_SmiEntryPoint:
- ;
- ; The encoding of BX in 16-bit addressing mode is the same as of RDI in 64-
- ; bit addressing mode. And that coincidence has been used in the following
- ; "64-bit like" 16-bit code. Be aware that once RDI is referenced as a
- ; base address register, it is actually BX that is referenced.
- ;
- DB 0bbh ; mov bx, imm16
- DW offset _GdtDesc - _SmiEntryPoint + 8000h ; bx = GdtDesc offset
-; fix GDT descriptor
- DB 2eh, 0a1h ; mov ax, cs:[offset16]
- DW DSC_OFFSET + DSC_GDTSIZ
- DB 48h ; dec ax
- DB 2eh
- mov [rdi], eax ; mov cs:[bx], ax
- DB 66h, 2eh, 0a1h ; mov eax, cs:[offset16]
- DW DSC_OFFSET + DSC_GDTPTR
- DB 2eh
- mov [rdi + 2], ax ; mov cs:[bx + 2], eax
- DB 66h, 2eh
- lgdt fword ptr [rdi] ; lgdt fword ptr cs:[bx]
-; Patch ProtectedMode Segment
- DB 0b8h ; mov ax, imm16
- DW PROTECT_MODE_CS ; set AX for segment directly
- DB 2eh
- mov [rdi - 2], eax ; mov cs:[bx - 2], ax
-; Patch ProtectedMode entry
- DB 66h, 0bfh ; mov edi, SMBASE
-gSmbase DD ?
- lea ax, [edi + (@ProtectedMode - _SmiEntryPoint) + 8000h]
- DB 2eh
- mov [rdi - 6], ax ; mov cs:[bx - 6], eax
-; Switch into @ProtectedMode
- mov rbx, cr0
- DB 66h
- and ebx, 9ffafff3h
- DB 66h
- or ebx, 00000023h
-
- mov cr0, rbx
- DB 66h, 0eah
- DD ?
- DW ?
-
-_GdtDesc FWORD ?
-@ProtectedMode:
- mov ax, PROTECT_MODE_DS
- mov ds, ax
- mov es, ax
- mov fs, ax
- mov gs, ax
- mov ss, ax
- DB 0bch ; mov esp, imm32
-gSmiStack DD ?
- jmp ProtFlatMode
-
-ProtFlatMode:
- DB 0b8h ; mov eax, offset gSmiCr3
-gSmiCr3 DD ?
- mov cr3, rax
- mov eax, 668h ; as cr4.PGE is not set here, refresh cr3
- mov cr4, rax ; in PreModifyMtrrs() to flush TLB.
-; Load TSS
- sub esp, 8 ; reserve room in stack
- sgdt fword ptr [rsp]
- mov eax, [rsp + 2] ; eax = GDT base
- add esp, 8
- mov dl, 89h
- mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag
- mov eax, TSS_SEGMENT
- ltr ax
-
-; Switch into @LongMode
- push LONG_MODE_CS ; push cs hardcore here
- call Base ; push return address for retf later
-Base:
- add dword ptr [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg
- mov ecx, 0c0000080h
- rdmsr
- or ah, 1
- wrmsr
- mov rbx, cr0
- or ebx, 080010000h ; enable paging + WP
- mov cr0, rbx
- retf
-@LongMode: ; long mode (64-bit code) starts here
- mov rax, offset gSmiHandlerIdtr
- lidt fword ptr [rax]
- lea ebx, [rdi + DSC_OFFSET]
- mov ax, [rbx + DSC_DS]
- mov ds, eax
- mov ax, [rbx + DSC_OTHERSEG]
- mov es, eax
- mov fs, eax
- mov gs, eax
- mov ax, [rbx + DSC_SS]
- mov ss, eax
-; jmp _SmiHandler ; instruction is not needed
-
-_SmiHandler:
- mov rbx, [rsp] ; rbx <- CpuIndex
-
- ;
- ; Save FP registers
- ;
- sub rsp, 208h
- DB 48h ; FXSAVE64
- fxsave [rsp]
-
- add rsp, -20h
-
- mov rcx, rbx
- mov rax, CpuSmmDebugEntry
- call rax
-
- mov rcx, rbx
- mov rax, SmiRendezvous ; rax <- absolute addr of SmiRedezvous
- call rax
-
- mov rcx, rbx
- mov rax, CpuSmmDebugExit
- call rax
-
- add rsp, 20h
-
- ;
- ; Restore FP registers
- ;
- DB 48h ; FXRSTOR64
- fxrstor [rsp]
-
- rsm
-
-gcSmiHandlerSize DW $ - _SmiEntryPoint
-
- END
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.S b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.S
deleted file mode 100644
index 2ae6f2c32f..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.S
+++ /dev/null
@@ -1,610 +0,0 @@
-#------------------------------------------------------------------------------
-#
-# 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.
-#
-# Module Name:
-#
-# SmiException.S
-#
-# Abstract:
-#
-# Exception handlers used in SM mode
-#
-#------------------------------------------------------------------------------
-
-ASM_GLOBAL ASM_PFX(SmiPFHandler)
-ASM_GLOBAL ASM_PFX(gSmiMtrrs)
-ASM_GLOBAL ASM_PFX(gcSmiIdtr)
-ASM_GLOBAL ASM_PFX(gcSmiGdtr)
-ASM_GLOBAL ASM_PFX(gcPsd)
-
- .data
-
-NullSeg: .quad 0 # reserved by architecture
-CodeSeg32:
- .word -1 # LimitLow
- .word 0 # BaseLow
- .byte 0 # BaseMid
- .byte 0x9b
- .byte 0xcf # LimitHigh
- .byte 0 # BaseHigh
-ProtModeCodeSeg32:
- .word -1 # LimitLow
- .word 0 # BaseLow
- .byte 0 # BaseMid
- .byte 0x9b
- .byte 0xcf # LimitHigh
- .byte 0 # BaseHigh
-ProtModeSsSeg32:
- .word -1 # LimitLow
- .word 0 # BaseLow
- .byte 0 # BaseMid
- .byte 0x93
- .byte 0xcf # LimitHigh
- .byte 0 # BaseHigh
-DataSeg32:
- .word -1 # LimitLow
- .word 0 # BaseLow
- .byte 0 # BaseMid
- .byte 0x93
- .byte 0xcf # LimitHigh
- .byte 0 # BaseHigh
-CodeSeg16:
- .word -1
- .word 0
- .byte 0
- .byte 0x9b
- .byte 0x8f
- .byte 0
-DataSeg16:
- .word -1
- .word 0
- .byte 0
- .byte 0x93
- .byte 0x8f
- .byte 0
-CodeSeg64:
- .word -1 # LimitLow
- .word 0 # BaseLow
- .byte 0 # BaseMid
- .byte 0x9b
- .byte 0xaf # LimitHigh
- .byte 0 # BaseHigh
-# TSS Segment for X64 specially
-TssSeg:
- .word TSS_DESC_SIZE - 1 # LimitLow
- .word 0 # BaseLow
- .byte 0 # BaseMid
- .byte 0x89
- .byte 0x00 # LimitHigh
- .byte 0 # BaseHigh
- .long 0 # BaseUpper
- .long 0 # Reserved
-.equ GDT_SIZE, .- NullSeg
-
-TssDescriptor:
- .space 104, 0
-.equ TSS_DESC_SIZE, .- TssDescriptor
-
-#
-# This structure serves as a template for all processors.
-#
-ASM_PFX(gcPsd):
- .ascii "PSDSIG "
- .word PSD_SIZE
- .word 2
- .word 1 << 2
- .word CODE_SEL
- .word DATA_SEL
- .word DATA_SEL
- .word DATA_SEL
- .word 0
- .quad 0
- .quad 0
- .quad 0 # fixed in InitializeMpServiceData()
- .quad NullSeg
- .long GDT_SIZE
- .long 0
- .space 24, 0
- .quad ASM_PFX(gSmiMtrrs)
-.equ PSD_SIZE, . - ASM_PFX(gcPsd)
-
-#
-# CODE & DATA segments for SMM runtime
-#
-.equ CODE_SEL, CodeSeg64 - NullSeg
-.equ DATA_SEL, DataSeg32 - NullSeg
-.equ CODE32_SEL, CodeSeg32 - NullSeg
-
-ASM_PFX(gcSmiGdtr):
- .word GDT_SIZE - 1
- .quad NullSeg
-
-ASM_PFX(gcSmiIdtr):
- .word IDT_SIZE - 1
- .quad _SmiIDT
-
-
-#
-# Here is the IDT. There are 32 (not 255) entries in it since only processor
-# generated exceptions will be handled.
-#
-_SmiIDT:
-# The following segment repeats 32 times:
-# No. 1
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 2
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 3
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 4
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 5
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 6
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 7
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 8
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 9
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 10
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 11
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 12
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 13
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 14
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 15
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 16
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 17
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 18
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 19
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 20
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 21
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 22
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 23
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 24
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 25
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 26
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 27
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 28
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 29
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 30
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 31
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-# No. 32
- .word 0 # Offset 0:15
- .word CODE_SEL
- .byte 0 # Unused
- .byte 0x8e # Interrupt Gate, Present
- .word 0 # Offset 16:31
- .quad 0 # Offset 32:63
-
-_SmiIDTEnd:
-
-.equ IDT_SIZE, (_SmiIDTEnd - _SmiIDT)
-
- .text
-
-#------------------------------------------------------------------------------
-# _SmiExceptionEntryPoints is the collection of exception entry points followed
-# by a common exception handler.
-#
-# Stack frame would be as follows as specified in IA32 manuals:
-# +---------------------+ <-- 16-byte aligned ensured by processor
-# + Old SS +
-# +---------------------+
-# + Old RSP +
-# +---------------------+
-# + RFlags +
-# +---------------------+
-# + CS +
-# +---------------------+
-# + RIP +
-# +---------------------+
-# + Error Code +
-# +---------------------+
-# + Vector Number +
-# +---------------------+
-# + RBP +
-# +---------------------+ <-- RBP, 16-byte aligned
-#
-# RSP set to odd multiple of 8 at @CommonEntryPoint means ErrCode PRESENT
-#------------------------------------------------------------------------------
-ASM_GLOBAL ASM_PFX(PageFaultIdtHandlerSmmProfile)
-ASM_PFX(PageFaultIdtHandlerSmmProfile):
- pushq $0x0e # Page Fault
- .byte 0x40, 0xf6, 0xc4, 0x08 #test spl, 8
- jnz L1
- pushq (%rsp)
- movq $0, 8(%rsp)
-L1:
- pushq %rbp
- movq %rsp, %rbp
-
- #
- # Since here the stack pointer is 16-byte aligned, so
- # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
- # is 16-byte aligned
- #
-
-## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
-## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
- pushq %r15
- pushq %r14
- pushq %r13
- pushq %r12
- pushq %r11
- pushq %r10
- pushq %r9
- pushq %r8
- pushq %rax
- pushq %rcx
- pushq %rdx
- pushq %rbx
- pushq 48(%rbp) # RSP
- pushq (%rbp) # RBP
- pushq %rsi
- pushq %rdi
-
-## UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
- movzwq 56(%rbp), %rax
- pushq %rax # for ss
- movzwq 32(%rbp), %rax
- pushq %rax # for cs
- movq %ds, %rax
- pushq %rax
- movq %es, %rax
- pushq %rax
- movq %fs, %rax
- pushq %rax
- movq %gs, %rax
- pushq %rax
-
-## UINT64 Rip;
- pushq 24(%rbp)
-
-## UINT64 Gdtr[2], Idtr[2];
- subq $16, %rsp
- sidt (%rsp)
- subq $16, %rsp
- sgdt (%rsp)
-
-## UINT64 Ldtr, Tr;
- xorq %rax, %rax
- strw %ax
- pushq %rax
- sldtw %ax
- pushq %rax
-
-## UINT64 RFlags;
- pushq 40(%rbp)
-
-## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
- movq %cr8, %rax
- pushq %rax
- movq %cr4, %rax
- orq $0x208, %rax
- movq %rax, %cr4
- pushq %rax
- movq %cr3, %rax
- pushq %rax
- movq %cr2, %rax
- pushq %rax
- xorq %rax, %rax
- pushq %rax
- movq %cr0, %rax
- pushq %rax
-
-## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- movq %dr7, %rax
- pushq %rax
- movq %dr6, %rax
- pushq %rax
- movq %dr3, %rax
- pushq %rax
- movq %dr2, %rax
- pushq %rax
- movq %dr1, %rax
- pushq %rax
- movq %dr0, %rax
- pushq %rax
-
-## FX_SAVE_STATE_X64 FxSaveState;
-
- subq $512, %rsp
- movq %rsp, %rdi
- .byte 0xf, 0xae, 0x7 # fxsave [rdi]
-
-# UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear
- cld
-
-## UINT32 ExceptionData;
- pushq 16(%rbp)
-
-## call into exception handler
- movq 8(%rbp), %rcx
- movabsq $ASM_PFX(SmiPFHandler), %rax
-
-## Prepare parameter and call
- movq %rsp, %rdx
- #
- # Per X64 calling convention, allocate maximum parameter stack space
- # and make sure RSP is 16-byte aligned
- #
- subq $4 * 8 + 8, %rsp
- call *%rax
- addq $4 * 8 + 8, %rsp
- jmp L5
-
-L5:
-## UINT64 ExceptionData;
- addq $8, %rsp
-
-## FX_SAVE_STATE_X64 FxSaveState;
-
- movq %rsp, %rsi
- .byte 0xf, 0xae, 0xe # fxrstor [rsi]
- addq $512, %rsp
-
-## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
-## Skip restoration of DRx registers to support debuggers
-## that set breakpoints in interrupt/exception context
- addq $8 * 6, %rsp
-
-## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
- popq %rax
- movq %rax, %cr0
- addq $8, %rsp # not for Cr1
- popq %rax
- movq %rax, %cr2
- popq %rax
- movq %rax, %cr3
- popq %rax
- movq %rax, %cr4
- popq %rax
- movq %rax, %cr8
-
-## UINT64 RFlags;
- popq 40(%rbp)
-
-## UINT64 Ldtr, Tr;
-## UINT64 Gdtr[2], Idtr[2];
-## Best not let anyone mess with these particular registers...
- addq $48, %rsp
-
-## UINT64 Rip;
- popq 24(%rbp)
-
-## UINT64 Gs, Fs, Es, Ds, Cs, Ss;
- popq %rax
- # mov gs, rax ; not for gs
- popq %rax
- # mov fs, rax ; not for fs
- # (X64 will not use fs and gs, so we do not restore it)
- popq %rax
- movq %rax, %es
- popq %rax
- movq %rax, %ds
- popq 32(%rbp) # for cs
- popq 56(%rbp) # for ss
-
-## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
-## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
- popq %rdi
- popq %rsi
- addq $8, %rsp # not for rbp
- popq 48(%rbp) # for rsp
- popq %rbx
- popq %rdx
- popq %rcx
- popq %rax
- popq %r8
- popq %r9
- popq %r10
- popq %r11
- popq %r12
- popq %r13
- popq %r14
- popq %r15
-
- movq %rbp, %rsp
-
-# Enable TF bit after page fault handler runs
- btsl $8, 40(%rsp) #RFLAGS
-
- popq %rbp
- addq $16, %rsp # skip INT# & ErrCode
- iretq
-
-ASM_GLOBAL ASM_PFX(InitializeIDTSmmStackGuard)
-ASM_PFX(InitializeIDTSmmStackGuard):
-# If SMM Stack Guard feature is enabled, set the IST field of
-# the interrupt gate for Page Fault Exception to be 1
-#
- movabsq $_SmiIDT + 14 * 16, %rax
- movb $1, 4(%rax)
- ret
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.asm b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.asm
deleted file mode 100644
index ab716450b7..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiException.asm
+++ /dev/null
@@ -1,413 +0,0 @@
-;------------------------------------------------------------------------------ ;
-; 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.
-;
-; Module Name:
-;
-; SmiException.asm
-;
-; Abstract:
-;
-; Exception handlers used in SM mode
-;
-;-------------------------------------------------------------------------------
-
-EXTERNDEF SmiPFHandler:PROC
-EXTERNDEF gSmiMtrrs:QWORD
-EXTERNDEF gcSmiIdtr:FWORD
-EXTERNDEF gcSmiGdtr:FWORD
-EXTERNDEF gcPsd:BYTE
-
- .const
-
-NullSeg DQ 0 ; reserved by architecture
-CodeSeg32 LABEL QWORD
- DW -1 ; LimitLow
- DW 0 ; BaseLow
- DB 0 ; BaseMid
- DB 9bh
- DB 0cfh ; LimitHigh
- DB 0 ; BaseHigh
-ProtModeCodeSeg32 LABEL QWORD
- DW -1 ; LimitLow
- DW 0 ; BaseLow
- DB 0 ; BaseMid
- DB 9bh
- DB 0cfh ; LimitHigh
- DB 0 ; BaseHigh
-ProtModeSsSeg32 LABEL QWORD
- DW -1 ; LimitLow
- DW 0 ; BaseLow
- DB 0 ; BaseMid
- DB 93h
- DB 0cfh ; LimitHigh
- DB 0 ; BaseHigh
-DataSeg32 LABEL QWORD
- DW -1 ; LimitLow
- DW 0 ; BaseLow
- DB 0 ; BaseMid
- DB 93h
- DB 0cfh ; LimitHigh
- DB 0 ; BaseHigh
-CodeSeg16 LABEL QWORD
- DW -1
- DW 0
- DB 0
- DB 9bh
- DB 8fh
- DB 0
-DataSeg16 LABEL QWORD
- DW -1
- DW 0
- DB 0
- DB 93h
- DB 8fh
- DB 0
-CodeSeg64 LABEL QWORD
- DW -1 ; LimitLow
- DW 0 ; BaseLow
- DB 0 ; BaseMid
- DB 9bh
- DB 0afh ; LimitHigh
- DB 0 ; BaseHigh
-; TSS Segment for X64 specially
-TssSeg LABEL QWORD
- DW TSS_DESC_SIZE - 1 ; LimitLow
- DW 0 ; BaseLow
- DB 0 ; BaseMid
- DB 89h
- DB 00h ; LimitHigh
- DB 0 ; BaseHigh
- DD 0 ; BaseUpper
- DD 0 ; Reserved
-GDT_SIZE = $ - offset NullSeg
-
-; Create TSS Descriptor just after GDT
-TssDescriptor LABEL BYTE
- DD 0 ; Reserved
- DQ 0 ; RSP0
- DQ 0 ; RSP1
- DQ 0 ; RSP2
- DD 0 ; Reserved
- DD 0 ; Reserved
- DQ 0 ; IST1
- DQ 0 ; IST2
- DQ 0 ; IST3
- DQ 0 ; IST4
- DQ 0 ; IST5
- DQ 0 ; IST6
- DQ 0 ; IST7
- DD 0 ; Reserved
- DD 0 ; Reserved
- DW 0 ; Reserved
- DW 0 ; I/O Map Base Address
-TSS_DESC_SIZE = $ - offset TssDescriptor
-
-;
-; This structure serves as a template for all processors.
-;
-gcPsd LABEL BYTE
- DB 'PSDSIG '
- DW PSD_SIZE
- DW 2
- DW 1 SHL 2
- DW CODE_SEL
- DW DATA_SEL
- DW DATA_SEL
- DW DATA_SEL
- DW 0
- DQ 0
- DQ 0
- DQ 0 ; fixed in InitializeMpServiceData()
- DQ offset NullSeg
- DD GDT_SIZE
- DD 0
- DB 24 dup (0)
- DQ offset gSmiMtrrs
-PSD_SIZE = $ - offset gcPsd
-
-;
-; CODE & DATA segments for SMM runtime
-;
-CODE_SEL = offset CodeSeg64 - offset NullSeg
-DATA_SEL = offset DataSeg32 - offset NullSeg
-CODE32_SEL = offset CodeSeg32 - offset NullSeg
-
-gcSmiGdtr LABEL FWORD
- DW GDT_SIZE - 1
- DQ offset NullSeg
-
-gcSmiIdtr LABEL FWORD
- DW IDT_SIZE - 1
- DQ offset _SmiIDT
-
- .data
-
-;
-; Here is the IDT. There are 32 (not 255) entries in it since only processor
-; generated exceptions will be handled.
-;
-_SmiIDT:
-REPEAT 32
- DW 0 ; Offset 0:15
- DW CODE_SEL ; Segment selector
- DB 0 ; Unused
- DB 8eh ; Interrupt Gate, Present
- DW 0 ; Offset 16:31
- DQ 0 ; Offset 32:63
- ENDM
-_SmiIDTEnd:
-
-IDT_SIZE = (offset _SmiIDTEnd - offset _SmiIDT)
-
- .code
-
-;------------------------------------------------------------------------------
-; _SmiExceptionEntryPoints is the collection of exception entry points followed
-; by a common exception handler.
-;
-; Stack frame would be as follows as specified in IA32 manuals:
-;
-; +---------------------+ <-- 16-byte aligned ensured by processor
-; + Old SS +
-; +---------------------+
-; + Old RSP +
-; +---------------------+
-; + RFlags +
-; +---------------------+
-; + CS +
-; +---------------------+
-; + RIP +
-; +---------------------+
-; + Error Code +
-; +---------------------+
-; + Vector Number +
-; +---------------------+
-; + RBP +
-; +---------------------+ <-- RBP, 16-byte aligned
-;
-; RSP set to odd multiple of 8 at @CommonEntryPoint means ErrCode PRESENT
-;------------------------------------------------------------------------------
-PageFaultIdtHandlerSmmProfile PROC
- push 0eh ; Page Fault
- test spl, 8 ; odd multiple of 8 => ErrCode present
- jnz @F
- push [rsp] ; duplicate INT# if no ErrCode
- mov qword ptr [rsp + 8], 0
-@@:
- push rbp
- mov rbp, rsp
-
- ;
- ; Since here the stack pointer is 16-byte aligned, so
- ; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
- ; is 16-byte aligned
- ;
-
-;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
-;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
- push r15
- push r14
- push r13
- push r12
- push r11
- push r10
- push r9
- push r8
- push rax
- push rcx
- push rdx
- push rbx
- push qword ptr [rbp + 48] ; RSP
- push qword ptr [rbp] ; RBP
- push rsi
- push rdi
-
-;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
- movzx rax, word ptr [rbp + 56]
- push rax ; for ss
- movzx rax, word ptr [rbp + 32]
- push rax ; for cs
- mov rax, ds
- push rax
- mov rax, es
- push rax
- mov rax, fs
- push rax
- mov rax, gs
- push rax
-
-;; UINT64 Rip;
- push qword ptr [rbp + 24]
-
-;; UINT64 Gdtr[2], Idtr[2];
- sub rsp, 16
- sidt fword ptr [rsp]
- sub rsp, 16
- sgdt fword ptr [rsp]
-
-;; UINT64 Ldtr, Tr;
- xor rax, rax
- str ax
- push rax
- sldt ax
- push rax
-
-;; UINT64 RFlags;
- push qword ptr [rbp + 40]
-
-;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
- mov rax, cr8
- push rax
- mov rax, cr4
- or rax, 208h
- mov cr4, rax
- push rax
- mov rax, cr3
- push rax
- mov rax, cr2
- push rax
- xor rax, rax
- push rax
- mov rax, cr0
- push rax
-
-;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- mov rax, dr7
- push rax
- mov rax, dr6
- push rax
- mov rax, dr3
- push rax
- mov rax, dr2
- push rax
- mov rax, dr1
- push rax
- mov rax, dr0
- push rax
-
-;; FX_SAVE_STATE_X64 FxSaveState;
-
- sub rsp, 512
- mov rdi, rsp
- db 0fh, 0aeh, 00000111y ;fxsave [rdi]
-
-; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear
- cld
-
-;; UINT32 ExceptionData;
- push qword ptr [rbp + 16]
-
-;; call into exception handler
- mov rcx, [rbp + 8]
- mov rax, SmiPFHandler
-
-;; Prepare parameter and call
- mov rdx, rsp
- ;
- ; Per X64 calling convention, allocate maximum parameter stack space
- ; and make sure RSP is 16-byte aligned
- ;
- sub rsp, 4 * 8 + 8
- call rax
- add rsp, 4 * 8 + 8
- jmp @F
-
-@@:
-;; UINT64 ExceptionData;
- add rsp, 8
-
-;; FX_SAVE_STATE_X64 FxSaveState;
-
- mov rsi, rsp
- db 0fh, 0aeh, 00001110y ; fxrstor [rsi]
- add rsp, 512
-
-;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
-;; Skip restoration of DRx registers to support debuggers
-;; that set breakpoints in interrupt/exception context
- add rsp, 8 * 6
-
-;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
- pop rax
- mov cr0, rax
- add rsp, 8 ; not for Cr1
- pop rax
- mov cr2, rax
- pop rax
- mov cr3, rax
- pop rax
- mov cr4, rax
- pop rax
- mov cr8, rax
-
-;; UINT64 RFlags;
- pop qword ptr [rbp + 40]
-
-;; UINT64 Ldtr, Tr;
-;; UINT64 Gdtr[2], Idtr[2];
-;; Best not let anyone mess with these particular registers...
- add rsp, 48
-
-;; UINT64 Rip;
- pop qword ptr [rbp + 24]
-
-;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;
- pop rax
- ; mov gs, rax ; not for gs
- pop rax
- ; mov fs, rax ; not for fs
- ; (X64 will not use fs and gs, so we do not restore it)
- pop rax
- mov es, rax
- pop rax
- mov ds, rax
- pop qword ptr [rbp + 32] ; for cs
- pop qword ptr [rbp + 56] ; for ss
-
-;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
-;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
- pop rdi
- pop rsi
- add rsp, 8 ; not for rbp
- pop qword ptr [rbp + 48] ; for rsp
- pop rbx
- pop rdx
- pop rcx
- pop rax
- pop r8
- pop r9
- pop r10
- pop r11
- pop r12
- pop r13
- pop r14
- pop r15
-
- mov rsp, rbp
-
-; Enable TF bit after page fault handler runs
- bts dword ptr [rsp + 40], 8 ;RFLAGS
-
- pop rbp
- add rsp, 16 ; skip INT# & ErrCode
- iretq
-PageFaultIdtHandlerSmmProfile ENDP
-
-InitializeIDTSmmStackGuard PROC
-;
-; If SMM Stack Guard feature is enabled, set the IST field of
-; the interrupt gate for Page Fault Exception to be 1
-;
- lea rax, _SmiIDT + 14 * 16
- mov byte ptr [rax + 4], 1
- ret
-InitializeIDTSmmStackGuard ENDP
-
- END
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
deleted file mode 100644
index b53aa45c21..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/** @file
- SMM CPU misc functions for x64 arch specific.
-
-Copyright (c) 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"
-
-/**
- Initialize Gdt for all processors.
-
- @param[in] Cr3 CR3 value.
- @param[out] GdtStepSize The step size for GDT table.
-
- @return GdtBase for processor 0.
- GdtBase for processor X is: GdtBase + (GdtStepSize * X)
-**/
-VOID *
-InitGdt (
- IN UINTN Cr3,
- OUT UINTN *GdtStepSize
- )
-{
- UINTN Index;
- IA32_SEGMENT_DESCRIPTOR *GdtDescriptor;
- UINTN TssBase;
- UINTN GdtTssTableSize;
- UINT8 *GdtTssTables;
- UINTN GdtTableStepSize;
-
- //
- // For X64 SMM, we allocate separate GDT/TSS for each CPUs to avoid TSS load contention
- // on each SMI entry.
- //
- GdtTssTableSize = (gcSmiGdtr.Limit + 1 + TSS_SIZE + 7) & ~7; // 8 bytes aligned
- GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));
- ASSERT (GdtTssTables != NULL);
- GdtTableStepSize = GdtTssTableSize;
-
- for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {
- CopyMem (GdtTssTables + GdtTableStepSize * Index, (VOID*)(UINTN)gcSmiGdtr.Base, gcSmiGdtr.Limit + 1 + TSS_SIZE);
-
- //
- // Fixup TSS descriptors
- //
- TssBase = (UINTN)(GdtTssTables + GdtTableStepSize * Index + gcSmiGdtr.Limit + 1);
- GdtDescriptor = (IA32_SEGMENT_DESCRIPTOR *)(TssBase) - 2;
- GdtDescriptor->Bits.BaseLow = (UINT16)(UINTN)TssBase;
- GdtDescriptor->Bits.BaseMid = (UINT8)((UINTN)TssBase >> 16);
- GdtDescriptor->Bits.BaseHigh = (UINT8)((UINTN)TssBase >> 24);
-
- if (FeaturePcdGet (PcdCpuSmmStackGuard)) {
- //
- // Setup top of known good stack as IST1 for each processor.
- //
- *(UINTN *)(TssBase + TSS_X64_IST1_OFFSET) = (mSmmStackArrayBase + EFI_PAGE_SIZE + Index * mSmmStackSize);
- }
- }
-
- *GdtStepSize = GdtTableStepSize;
- return GdtTssTables;
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.S b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.S
deleted file mode 100644
index 5e352f57c3..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.S
+++ /dev/null
@@ -1,141 +0,0 @@
-#------------------------------------------------------------------------------
-#
-# 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.
-#
-# Module Name:
-#
-# SmmInit.S
-#
-# Abstract:
-#
-# Functions for relocating SMBASE's for all processors
-#
-#------------------------------------------------------------------------------
-
-ASM_GLOBAL ASM_PFX(gSmmCr0)
-ASM_GLOBAL ASM_PFX(gSmmCr3)
-ASM_GLOBAL ASM_PFX(gSmmCr4)
-ASM_GLOBAL ASM_PFX(gSmmJmpAddr)
-ASM_GLOBAL ASM_PFX(gcSmmInitTemplate)
-ASM_GLOBAL ASM_PFX(gcSmmInitSize)
-ASM_GLOBAL ASM_PFX(mRebasedFlagAddr32)
-ASM_GLOBAL ASM_PFX(SmmRelocationSemaphoreComplete)
-ASM_GLOBAL ASM_PFX(SmmRelocationSemaphoreComplete32)
-ASM_GLOBAL ASM_PFX(mSmmRelocationOriginalAddressPtr32)
-ASM_GLOBAL ASM_PFX(gSmmInitStack)
-ASM_GLOBAL ASM_PFX(gcSmiInitGdtr)
-
-
- .text
-
-ASM_PFX(gcSmiInitGdtr):
- .word 0
- .quad 0
-
-SmmStartup:
- .byte 0x66,0xb8 # mov eax, imm32
-ASM_PFX(gSmmCr3): .space 4
- movq %rax, %cr3
- .byte 0x66,0x2e
- lgdt (ASM_PFX(gcSmiInitGdtr) - SmmStartup)(%ebp)
- .byte 0x66,0xb8 # mov eax, imm32
-ASM_PFX(gSmmCr4): .space 4
- orb $2, %ah # enable XMM registers access
- movq %rax, %cr4
- .byte 0x66
- movl $0xc0000080,%ecx # IA32_EFER MSR
- rdmsr
- orb $1,%ah # set LME bit
- wrmsr
- .byte 0x66,0xb8 # mov eax, imm32
-ASM_PFX(gSmmCr0): .space 4
- movq %rax, %cr0
- .byte 0x66,0xea # far jmp to long mode
-ASM_PFX(gSmmJmpAddr): .quad LongMode
-LongMode: # long-mode starts here
- .byte 0x48,0xbc # mov rsp, imm64
-ASM_PFX(gSmmInitStack): .space 8
- andw $0xfff0, %sp # make sure RSP is 16-byte aligned
- #
- # Accoring to X64 calling convention, XMM0~5 are volatile, we need to save
- # them before calling C-function.
- #
- subq $0x60, %rsp
- movdqa %xmm0, 0x0(%rsp)
- movdqa %xmm1, 0x10(%rsp)
- movdqa %xmm2, 0x20(%rsp)
- movdqa %xmm3, 0x30(%rsp)
- movdqa %xmm4, 0x40(%rsp)
- movdqa %xmm5, 0x50(%rsp)
-
-
- addq $-0x20, %rsp
- call ASM_PFX(SmmInitHandler)
- addq $0x20, %rsp
- #
- # Restore XMM0~5 after calling C-function.
- #
- movdqa 0x0(%rsp), %xmm0
- movdqa 0x10(%rsp), %xmm1
- movdqa 0x20(%rsp), %xmm2
- movdqa 0x30(%rsp), %xmm3
- movdqa 0x40(%rsp), %xmm4
- movdqa 0x50(%rsp), %xmm5
-
- rsm
-
-ASM_PFX(gcSmmInitTemplate):
-
-_SmmInitTemplate:
- .byte 0x66,0x2e,0x8b,0x2e # mov ebp, cs:[@F]
- .word L1 - _SmmInitTemplate + 0x8000
- .byte 0x66, 0x81, 0xed, 0, 0, 3, 0 # sub ebp, 0x30000
- jmp *%bp # jmp ebp actually
-L1:
- .quad SmmStartup
-
-ASM_PFX(gcSmmInitSize): .word . - ASM_PFX(gcSmmInitTemplate)
-
-ASM_PFX(SmmRelocationSemaphoreComplete):
- # Create a simple stack frame to store RAX and the original RSM location
- pushq %rax # Used to store return address
- pushq %rax
-
- # Load the original RSM location onto stack
- movabsq $ASM_PFX(mSmmRelocationOriginalAddress), %rax
- movq (%rax), %rax
- movq %rax, 0x08(%rsp)
-
- # Update rebase flag
- movabsq $ASM_PFX(mRebasedFlag), %rax
- movq (%rax), %rax
- movb $1, (%rax)
-
- #restore RAX and return to original RSM location
- popq %rax
- retq
-
-#
-# Semaphore code running in 32-bit mode
-#
-ASM_PFX(SmmRelocationSemaphoreComplete32):
- #
- # movb $1, ()
- #
- .byte 0xc6, 0x05
-ASM_PFX(mRebasedFlagAddr32):
- .long 0
- .byte 1
- #
- # jmpd ()
- #
- .byte 0xff, 0x25
-ASM_PFX(mSmmRelocationOriginalAddressPtr32):
- .long 0
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.asm b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.asm
deleted file mode 100644
index 9182f0293a..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmInit.asm
+++ /dev/null
@@ -1,132 +0,0 @@
-;------------------------------------------------------------------------------ ;
-; 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.
-;
-; Module Name:
-;
-; SmmInit.Asm
-;
-; Abstract:
-;
-; Functions for relocating SMBASE's for all processors
-;
-;-------------------------------------------------------------------------------
-
-EXTERNDEF SmmInitHandler:PROC
-EXTERNDEF gSmmCr0:DWORD
-EXTERNDEF gSmmCr3:DWORD
-EXTERNDEF gSmmCr4:DWORD
-EXTERNDEF gSmmJmpAddr:QWORD
-EXTERNDEF gcSmmInitTemplate:BYTE
-EXTERNDEF gcSmmInitSize:WORD
-EXTERNDEF mRebasedFlag:PTR BYTE
-EXTERNDEF mSmmRelocationOriginalAddress:QWORD
-EXTERNDEF mRebasedFlagAddr32:DWORD
-EXTERNDEF mSmmRelocationOriginalAddressPtr32:DWORD
-EXTERNDEF gSmmInitStack:QWORD
-EXTERNDEF gcSmiInitGdtr:FWORD
-
- .code
-
-gcSmiInitGdtr LABEL FWORD
- DW 0
- DQ 0
-
-SmmStartup PROC
- DB 66h, 0b8h ; mov eax, imm32
-gSmmCr3 DD ?
- mov cr3, rax
- DB 66h, 2eh
- lgdt fword ptr [ebp + (offset gcSmiInitGdtr - SmmStartup)]
- DB 66h, 0b8h ; mov eax, imm32
-gSmmCr4 DD ?
- or ah, 2 ; enable XMM registers access
- mov cr4, rax
- DB 66h
- mov ecx, 0c0000080h ; IA32_EFER MSR
- rdmsr
- or ah, 1 ; set LME bit
- wrmsr
- DB 66h, 0b8h ; mov eax, imm32
-gSmmCr0 DD ?
- mov cr0, rax ; enable protected mode & paging
- DB 66h, 0eah ; far jmp to long mode
-gSmmJmpAddr DQ @LongMode
-@LongMode: ; long-mode starts here
- DB 48h, 0bch ; mov rsp, imm64
-gSmmInitStack DQ ?
- and sp, 0fff0h ; make sure RSP is 16-byte aligned
- ;
- ; Accoring to X64 calling convention, XMM0~5 are volatile, we need to save
- ; them before calling C-function.
- ;
- sub rsp, 60h
- movdqa [rsp], xmm0
- movdqa [rsp + 10h], xmm1
- movdqa [rsp + 20h], xmm2
- movdqa [rsp + 30h], xmm3
- movdqa [rsp + 40h], xmm4
- movdqa [rsp + 50h], xmm5
-
- add rsp, -20h
- call SmmInitHandler
- add rsp, 20h
-
- ;
- ; Restore XMM0~5 after calling C-function.
- ;
- movdqa xmm0, [rsp]
- movdqa xmm1, [rsp + 10h]
- movdqa xmm2, [rsp + 20h]
- movdqa xmm3, [rsp + 30h]
- movdqa xmm4, [rsp + 40h]
- movdqa xmm5, [rsp + 50h]
-
- rsm
-SmmStartup ENDP
-
-gcSmmInitTemplate LABEL BYTE
-
-_SmmInitTemplate PROC
- DB 66h, 2eh, 8bh, 2eh ; mov ebp, cs:[@F]
- DW @L1 - _SmmInitTemplate + 8000h
- DB 66h, 81h, 0edh, 00h, 00h, 03h, 00 ; sub ebp, 30000h
- jmp bp ; jmp ebp actually
-@L1:
- DQ SmmStartup
-_SmmInitTemplate ENDP
-
-gcSmmInitSize DW $ - gcSmmInitTemplate
-
-SmmRelocationSemaphoreComplete PROC
- push rax
- mov rax, mRebasedFlag
- mov byte ptr [rax], 1
- pop rax
- jmp [mSmmRelocationOriginalAddress]
-SmmRelocationSemaphoreComplete ENDP
-
-;
-; Semaphore code running in 32-bit mode
-;
-SmmRelocationSemaphoreComplete32 PROC
- ;
- ; mov byte ptr [], 1
- ;
- db 0c6h, 05h
-mRebasedFlagAddr32 dd 0
- db 1
- ;
- ; jmp dword ptr []
- ;
- db 0ffh, 25h
-mSmmRelocationOriginalAddressPtr32 dd 0
-SmmRelocationSemaphoreComplete32 ENDP
-
- END
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c
deleted file mode 100644
index 065fb2c24c..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.c
+++ /dev/null
@@ -1,316 +0,0 @@
-/** @file
-X64 processor specific functions to enable SMM profile.
-
-Copyright (c) 2012 - 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"
-#include "SmmProfileInternal.h"
-
-//
-// Current page index.
-//
-UINTN mPFPageIndex;
-
-//
-// Pool for dynamically creating page table in page fault handler.
-//
-UINT64 mPFPageBuffer;
-
-//
-// Store the uplink information for each page being used.
-//
-UINT64 *mPFPageUplink[MAX_PF_PAGE_COUNT];
-
-/**
- Create SMM page table for S3 path.
-
-**/
-VOID
-InitSmmS3Cr3 (
- VOID
- )
-{
- EFI_PHYSICAL_ADDRESS Pages;
- UINT64 *PTEntry;
-
- //
- // Generate PAE page table for the first 4GB memory space
- //
- Pages = Gen4GPageTable (1, FALSE);
-
- //
- // Fill Page-Table-Level4 (PML4) entry
- //
- PTEntry = (UINT64*)(UINTN)(Pages - EFI_PAGES_TO_SIZE (1));
- *PTEntry = Pages | PAGE_ATTRIBUTE_BITS;
- ZeroMem (PTEntry + 1, EFI_PAGE_SIZE - sizeof (*PTEntry));
-
- //
- // Return the address of PML4 (to set CR3)
- //
- mSmmS3ResumeState->SmmS3Cr3 = (UINT32)(UINTN)PTEntry;
-
- return ;
-}
-
-/**
- Allocate pages for creating 4KB-page based on 2MB-page when page fault happens.
-
-**/
-VOID
-InitPagesForPFHandler (
- VOID
- )
-{
- VOID *Address;
-
- //
- // Pre-Allocate memory for page fault handler
- //
- Address = NULL;
- Address = AllocatePages (MAX_PF_PAGE_COUNT);
- ASSERT (Address != NULL);
-
- mPFPageBuffer = (UINT64)(UINTN) Address;
- mPFPageIndex = 0;
- ZeroMem ((VOID *) (UINTN) mPFPageBuffer, EFI_PAGE_SIZE * MAX_PF_PAGE_COUNT);
- ZeroMem (mPFPageUplink, sizeof (mPFPageUplink));
-
- return;
-}
-
-/**
- Allocate one page for creating 4KB-page based on 2MB-page.
-
- @param Uplink The address of Page-Directory entry.
-
-**/
-VOID
-AcquirePage (
- UINT64 *Uplink
- )
-{
- UINT64 Address;
-
- //
- // Get the buffer
- //
- Address = mPFPageBuffer + EFI_PAGES_TO_SIZE (mPFPageIndex);
- ZeroMem ((VOID *) (UINTN) Address, EFI_PAGE_SIZE);
-
- //
- // Cut the previous uplink if it exists and wasn't overwritten
- //
- if ((mPFPageUplink[mPFPageIndex] != NULL) && ((*mPFPageUplink[mPFPageIndex] & PHYSICAL_ADDRESS_MASK) == Address)) {
- *mPFPageUplink[mPFPageIndex] = 0;
- }
-
- //
- // Link & Record the current uplink
- //
- *Uplink = Address | PAGE_ATTRIBUTE_BITS;
- mPFPageUplink[mPFPageIndex] = Uplink;
-
- mPFPageIndex = (mPFPageIndex + 1) % MAX_PF_PAGE_COUNT;
-}
-
-/**
- Update page table to map the memory correctly in order to make the instruction
- which caused page fault execute successfully. And it also save the original page
- table to be restored in single-step exception.
-
- @param PageTable PageTable Address.
- @param PFAddress The memory address which caused page fault exception.
- @param CpuIndex The index of the processor.
- @param ErrorCode The Error code of exception.
- @param IsValidPFAddress The flag indicates if SMM profile data need be added.
-
-**/
-VOID
-RestorePageTableAbove4G (
- UINT64 *PageTable,
- UINT64 PFAddress,
- UINTN CpuIndex,
- UINTN ErrorCode,
- BOOLEAN *IsValidPFAddress
- )
-{
- UINTN PTIndex;
- UINT64 Address;
- BOOLEAN Nx;
- BOOLEAN Existed;
- UINTN Index;
- UINTN PFIndex;
-
- ASSERT ((PageTable != NULL) && (IsValidPFAddress != NULL));
-
- //
- // If page fault address is 4GB above.
- //
-
- //
- // Check if page fault address has existed in page table.
- // If it exists in page table but page fault is generated,
- // there are 2 possible reasons: 1. present flag is set to 0; 2. instruction fetch in protected memory range.
- //
- Existed = FALSE;
- PageTable = (UINT64*)(AsmReadCr3 () & PHYSICAL_ADDRESS_MASK);
- PTIndex = BitFieldRead64 (PFAddress, 39, 47);
- if ((PageTable[PTIndex] & IA32_PG_P) != 0) {
- // PML4E
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
- PTIndex = BitFieldRead64 (PFAddress, 30, 38);
- if ((PageTable[PTIndex] & IA32_PG_P) != 0) {
- // PDPTE
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
- PTIndex = BitFieldRead64 (PFAddress, 21, 29);
- // PD
- if ((PageTable[PTIndex] & IA32_PG_PS) != 0) {
- //
- // 2MB page
- //
- Address = (UINT64)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
- if ((Address & PHYSICAL_ADDRESS_MASK & ~((1ull << 21) - 1)) == ((PFAddress & PHYSICAL_ADDRESS_MASK & ~((1ull << 21) - 1)))) {
- Existed = TRUE;
- }
- } else {
- //
- // 4KB page
- //
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
- if (PageTable != 0) {
- //
- // When there is a valid entry to map to 4KB page, need not create a new entry to map 2MB.
- //
- PTIndex = BitFieldRead64 (PFAddress, 12, 20);
- Address = (UINT64)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
- if ((Address & PHYSICAL_ADDRESS_MASK & ~((1ull << 12) - 1)) == (PFAddress & PHYSICAL_ADDRESS_MASK & ~((1ull << 12) - 1))) {
- Existed = TRUE;
- }
- }
- }
- }
- }
-
- //
- // If page entry does not existed in page table at all, create a new entry.
- //
- if (!Existed) {
-
- if (IsAddressValid (PFAddress, &Nx)) {
- //
- // If page fault address above 4GB is in protected range but it causes a page fault exception,
- // Will create a page entry for this page fault address, make page table entry as present/rw and execution-disable.
- // this access is not saved into SMM profile data.
- //
- *IsValidPFAddress = TRUE;
- }
-
- //
- // Create one entry in page table for page fault address.
- //
- SmiDefaultPFHandler ();
- //
- // Find the page table entry created just now.
- //
- PageTable = (UINT64*)(AsmReadCr3 () & PHYSICAL_ADDRESS_MASK);
- PFAddress = AsmReadCr2 ();
- // PML4E
- PTIndex = BitFieldRead64 (PFAddress, 39, 47);
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
- // PDPTE
- PTIndex = BitFieldRead64 (PFAddress, 30, 38);
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
- // PD
- PTIndex = BitFieldRead64 (PFAddress, 21, 29);
- Address = PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK;
- //
- // Check if 2MB-page entry need be changed to 4KB-page entry.
- //
- if (IsAddressSplit (Address)) {
- AcquirePage (&PageTable[PTIndex]);
-
- // PTE
- PageTable = (UINT64*)(UINTN)(PageTable[PTIndex] & PHYSICAL_ADDRESS_MASK);
- for (Index = 0; Index < 512; Index++) {
- PageTable[Index] = Address | PAGE_ATTRIBUTE_BITS;
- if (!IsAddressValid (Address, &Nx)) {
- PageTable[Index] = PageTable[Index] & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);
- }
- if (Nx && mXdSupported) {
- PageTable[Index] = PageTable[Index] | IA32_PG_NX;
- }
- if (Address == (PFAddress & PHYSICAL_ADDRESS_MASK & ~((1ull << 12) - 1))) {
- PTIndex = Index;
- }
- Address += SIZE_4KB;
- } // end for PT
- } else {
- //
- // Update 2MB page entry.
- //
- if (!IsAddressValid (Address, &Nx)) {
- //
- // Patch to remove present flag and rw flag.
- //
- PageTable[PTIndex] = PageTable[PTIndex] & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS);
- }
- //
- // Set XD bit to 1
- //
- if (Nx && mXdSupported) {
- PageTable[PTIndex] = PageTable[PTIndex] | IA32_PG_NX;
- }
- }
- }
-
- //
- // Record old entries with non-present status
- // Old entries include the memory which instruction is at and the memory which instruction access.
- //
- //
- ASSERT (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT);
- if (mPFEntryCount[CpuIndex] < MAX_PF_ENTRY_COUNT) {
- PFIndex = mPFEntryCount[CpuIndex];
- mLastPFEntryValue[CpuIndex][PFIndex] = PageTable[PTIndex];
- mLastPFEntryPointer[CpuIndex][PFIndex] = &PageTable[PTIndex];
- mPFEntryCount[CpuIndex]++;
- }
-
- //
- // Add present flag or clear XD flag to make page fault handler succeed.
- //
- PageTable[PTIndex] |= (UINT64)(PAGE_ATTRIBUTE_BITS);
- if ((ErrorCode & IA32_PF_EC_ID) != 0) {
- //
- // If page fault is caused by instruction fetch, clear XD bit in the entry.
- //
- PageTable[PTIndex] &= ~IA32_PG_NX;
- }
-
- return;
-}
-
-/**
- Clear TF in FLAGS.
-
- @param SystemContext A pointer to the processor context when
- the interrupt occurred on the processor.
-
-**/
-VOID
-ClearTrapFlag (
- IN OUT EFI_SYSTEM_CONTEXT SystemContext
- )
-{
- SystemContext.SystemContextX64->Rflags &= (UINTN) ~BIT8;
-}
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h
deleted file mode 100644
index 32f33139bf..0000000000
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmProfileArch.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/** @file
-X64 processor specific header file to enable SMM profile.
-
-Copyright (c) 2012 - 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.
-
-**/
-
-#ifndef _SMM_PROFILE_ARCH_H_
-#define _SMM_PROFILE_ARCH_H_
-
-#pragma pack (1)
-
-typedef struct _MSR_DS_AREA_STRUCT {
- UINT64 BTSBufferBase;
- UINT64 BTSIndex;
- UINT64 BTSAbsoluteMaximum;
- UINT64 BTSInterruptThreshold;
- UINT64 PEBSBufferBase;
- UINT64 PEBSIndex;
- UINT64 PEBSAbsoluteMaximum;
- UINT64 PEBSInterruptThreshold;
- UINT64 PEBSCounterReset[2];
- UINT64 Reserved;
-} MSR_DS_AREA_STRUCT;
-
-typedef struct _BRANCH_TRACE_RECORD {
- UINT64 LastBranchFrom;
- UINT64 LastBranchTo;
- UINT64 Rsvd0 : 4;
- UINT64 BranchPredicted : 1;
- UINT64 Rsvd1 : 59;
-} BRANCH_TRACE_RECORD;
-
-typedef struct _PEBS_RECORD {
- UINT64 Rflags;
- UINT64 LinearIP;
- UINT64 Rax;
- UINT64 Rbx;
- UINT64 Rcx;
- UINT64 Rdx;
- UINT64 Rsi;
- UINT64 Rdi;
- UINT64 Rbp;
- UINT64 Rsp;
- UINT64 R8;
- UINT64 R9;
- UINT64 R10;
- UINT64 R11;
- UINT64 R12;
- UINT64 R13;
- UINT64 R14;
- UINT64 R15;
-} PEBS_RECORD;
-
-#pragma pack ()
-
-#define PHYSICAL_ADDRESS_MASK ((1ull << 52) - SIZE_4KB)
-
-/**
- Update page table to map the memory correctly in order to make the instruction
- which caused page fault execute successfully. And it also save the original page
- table to be restored in single-step exception.
-
- @param PageTable PageTable Address.
- @param PFAddress The memory address which caused page fault exception.
- @param CpuIndex The index of the processor.
- @param ErrorCode The Error code of exception.
- @param IsValidPFAddress The flag indicates if SMM profile data need be added.
-
-**/
-VOID
-RestorePageTableAbove4G (
- UINT64 *PageTable,
- UINT64 PFAddress,
- UINTN CpuIndex,
- UINTN ErrorCode,
- BOOLEAN *IsValidPFAddress
- );
-
-/**
- Create SMM page table for S3 path.
-
-**/
-VOID
-InitSmmS3Cr3 (
- VOID
- );
-
-/**
- Allocate pages for creating 4KB-page based on 2MB-page when page fault happens.
-
-**/
-VOID
-InitPagesForPFHandler (
- VOID
- );
-
-#endif // _SMM_PROFILE_ARCH_H_