1fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen/** @file 2fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen SMM CPU misc functions for x64 arch specific. 3fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen 4fe5f19494353421d3382f32f31a627e09724bbb2Yao, JiewenCopyright (c) 2015, Intel Corporation. All rights reserved.<BR> 5fe5f19494353421d3382f32f31a627e09724bbb2Yao, JiewenThis program and the accompanying materials 6fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewenare licensed and made available under the terms and conditions of the BSD License 7fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewenwhich accompanies this distribution. The full text of the license may be found at 8fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewenhttp://opensource.org/licenses/bsd-license.php 9fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen 10fe5f19494353421d3382f32f31a627e09724bbb2Yao, JiewenTHE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11fe5f19494353421d3382f32f31a627e09724bbb2Yao, JiewenWITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen 13fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen**/ 14fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen 15fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen#include "PiSmmCpuDxeSmm.h" 16fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen 17fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen/** 18fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen Initialize Gdt for all processors. 19fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen 20fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen @param[in] Cr3 CR3 value. 21fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen @param[out] GdtStepSize The step size for GDT table. 22fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen 23fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen @return GdtBase for processor 0. 24fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen GdtBase for processor X is: GdtBase + (GdtStepSize * X) 25fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen**/ 26fe5f19494353421d3382f32f31a627e09724bbb2Yao, JiewenVOID * 27fe5f19494353421d3382f32f31a627e09724bbb2Yao, JiewenInitGdt ( 28fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen IN UINTN Cr3, 29fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen OUT UINTN *GdtStepSize 30fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen ) 31fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen{ 32fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen UINTN Index; 33fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen IA32_SEGMENT_DESCRIPTOR *GdtDescriptor; 34fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen UINTN TssBase; 35fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen UINTN GdtTssTableSize; 36fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen UINT8 *GdtTssTables; 37fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen UINTN GdtTableStepSize; 38fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen 39fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen // 40fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen // For X64 SMM, we allocate separate GDT/TSS for each CPUs to avoid TSS load contention 41fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen // on each SMI entry. 42fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen // 43fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen GdtTssTableSize = (gcSmiGdtr.Limit + 1 + TSS_SIZE + 7) & ~7; // 8 bytes aligned 44fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus)); 45fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen ASSERT (GdtTssTables != NULL); 46fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen GdtTableStepSize = GdtTssTableSize; 47fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen 48fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) { 49fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen CopyMem (GdtTssTables + GdtTableStepSize * Index, (VOID*)(UINTN)gcSmiGdtr.Base, gcSmiGdtr.Limit + 1 + TSS_SIZE); 50fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen 51fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen // 52fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen // Fixup TSS descriptors 53fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen // 54fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen TssBase = (UINTN)(GdtTssTables + GdtTableStepSize * Index + gcSmiGdtr.Limit + 1); 55fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen GdtDescriptor = (IA32_SEGMENT_DESCRIPTOR *)(TssBase) - 2; 56fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen GdtDescriptor->Bits.BaseLow = (UINT16)(UINTN)TssBase; 57fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen GdtDescriptor->Bits.BaseMid = (UINT8)((UINTN)TssBase >> 16); 58fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen GdtDescriptor->Bits.BaseHigh = (UINT8)((UINTN)TssBase >> 24); 59fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen 60fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen if (FeaturePcdGet (PcdCpuSmmStackGuard)) { 61fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen // 62fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen // Setup top of known good stack as IST1 for each processor. 63fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen // 64fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen *(UINTN *)(TssBase + TSS_X64_IST1_OFFSET) = (mSmmStackArrayBase + EFI_PAGE_SIZE + Index * mSmmStackSize); 65fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen } 66fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen } 67fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen 68fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen *GdtStepSize = GdtTableStepSize; 69fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen return GdtTssTables; 70fe5f19494353421d3382f32f31a627e09724bbb2Yao, Jiewen} 71