Eliminate EFI_IMAGE_MACHINE_TYPE_SUPPORTED.
Move Gdt initialization from InitializeMpServiceData() to CPU Arch specific function. We create SmmFuncsArch.c for hold CPU specific function, so that EFI_IMAGE_MACHINE_TYPE_SUPPORTED(EFI_IMAGE_MACHINE_X64) can be removed. For IA32 version, we always allocate new page for GDT entry, for easy maintenance. For X64 version, we fixed TssBase in GDT entry to make sure TSS data is correct. Remove TSS fixup for GDT in ASM file. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: "Yao, Jiewen" <jiewen.yao@intel.com> Reviewed-by: "Fan, Jeff" <jeff.fan@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18937 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
70
UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
Normal file
70
UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
Normal file
@@ -0,0 +1,70 @@
|
||||
/** @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;
|
||||
}
|
Reference in New Issue
Block a user