Eliminate EFI_IMAGE_MACHINE_TYPE_SUPPORTED.
authorYao, Jiewen <jiewen.yao@intel.com>
Wed, 25 Nov 2015 04:23:01 +0000 (04:23 +0000)
committerjyao1 <jyao1@Edk2>
Wed, 25 Nov 2015 04:23:01 +0000 (04:23 +0000)
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

UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c [new file with mode: 0644]
UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h
UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.inf
UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S
UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm
UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c [new file with mode: 0644]

diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c
new file mode 100644 (file)
index 0000000..545b534
--- /dev/null
@@ -0,0 +1,96 @@
+/** @file\r
+  SMM CPU misc functions for Ia32 arch specific.\r
+  \r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "PiSmmCpuDxeSmm.h"\r
+\r
+/**\r
+  Initialize Gdt for all processors.\r
+  \r
+  @param[in]   Cr3          CR3 value.\r
+  @param[out]  GdtStepSize  The step size for GDT table.\r
+\r
+  @return GdtBase for processor 0.\r
+          GdtBase for processor X is: GdtBase + (GdtStepSize * X)\r
+**/\r
+VOID *\r
+InitGdt (\r
+  IN  UINTN  Cr3,\r
+  OUT UINTN  *GdtStepSize\r
+  )\r
+{\r
+  UINTN                     Index;\r
+  IA32_SEGMENT_DESCRIPTOR   *GdtDescriptor;\r
+  UINTN                     TssBase;\r
+  UINTN                     GdtTssTableSize;\r
+  UINT8                     *GdtTssTables;\r
+  UINTN                     GdtTableStepSize;\r
+\r
+  if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
+    //\r
+    // For IA32 SMM, if SMM Stack Guard feature is enabled, we use 2 TSS.\r
+    // in this case, we allocate separate GDT/TSS for each CPUs to avoid TSS load contention\r
+    // on each SMI entry.\r
+    //\r
+\r
+    //\r
+    // Enlarge GDT to contain 2 TSS descriptors\r
+    //\r
+    gcSmiGdtr.Limit += (UINT16)(2 * sizeof (IA32_SEGMENT_DESCRIPTOR));\r
+\r
+    GdtTssTableSize = (gcSmiGdtr.Limit + 1 + TSS_SIZE * 2 + 7) & ~7; // 8 bytes aligned\r
+    GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));\r
+    ASSERT (GdtTssTables != NULL);\r
+    GdtTableStepSize = GdtTssTableSize;\r
+\r
+    for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {\r
+      CopyMem (GdtTssTables + GdtTableStepSize * Index, (VOID*)(UINTN)gcSmiGdtr.Base, gcSmiGdtr.Limit + 1 + TSS_SIZE * 2);\r
+      //\r
+      // Fixup TSS descriptors\r
+      //\r
+      TssBase = (UINTN)(GdtTssTables + GdtTableStepSize * Index + gcSmiGdtr.Limit + 1);\r
+      GdtDescriptor = (IA32_SEGMENT_DESCRIPTOR *)(TssBase) - 2;\r
+      GdtDescriptor->Bits.BaseLow = (UINT16)TssBase;\r
+      GdtDescriptor->Bits.BaseMid = (UINT8)(TssBase >> 16);\r
+      GdtDescriptor->Bits.BaseHigh = (UINT8)(TssBase >> 24);\r
+\r
+      TssBase += TSS_SIZE;\r
+      GdtDescriptor++;\r
+      GdtDescriptor->Bits.BaseLow = (UINT16)TssBase;\r
+      GdtDescriptor->Bits.BaseMid = (UINT8)(TssBase >> 16);\r
+      GdtDescriptor->Bits.BaseHigh = (UINT8)(TssBase >> 24);\r
+      //\r
+      // Fixup TSS segments\r
+      //\r
+      // ESP as known good stack\r
+      //\r
+      *(UINTN *)(TssBase + TSS_IA32_ESP_OFFSET) =  mSmmStackArrayBase + EFI_PAGE_SIZE + Index * mSmmStackSize;\r
+      *(UINT32 *)(TssBase + TSS_IA32_CR3_OFFSET) = Cr3;\r
+    }\r
+  } else {\r
+    //\r
+    // Just use original table, AllocatePage and copy them here to make sure GDTs are covered in page memory.\r
+    //\r
+    GdtTssTableSize = gcSmiGdtr.Limit + 1;\r
+    GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));\r
+    ASSERT (GdtTssTables != NULL);\r
+    GdtTableStepSize = GdtTssTableSize;\r
+\r
+    for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {\r
+      CopyMem (GdtTssTables + GdtTableStepSize * Index, (VOID*)(UINTN)gcSmiGdtr.Base, gcSmiGdtr.Limit + 1);\r
+    }\r
+  }\r
+\r
+  *GdtStepSize = GdtTableStepSize;\r
+  return GdtTssTables;\r
+}\r
index 730c32df0a254bdde82472187a2218cc29db858b..80378a3faf4262601a69826337b4297865934834 100644 (file)
@@ -1163,10 +1163,7 @@ InitializeMpServiceData (
   UINTN                     Index;\r
   MTRR_SETTINGS             *Mtrr;\r
   PROCESSOR_SMM_DESCRIPTOR  *Psd;\r
-  UINTN                     GdtTssTableSize;\r
   UINT8                     *GdtTssTables;\r
-  IA32_SEGMENT_DESCRIPTOR   *GdtDescriptor;\r
-  UINTN                     TssBase;\r
   UINTN                     GdtTableStepSize;\r
 \r
   //\r
@@ -1182,71 +1179,7 @@ InitializeMpServiceData (
   //\r
   Cr3 = SmmInitPageTable ();\r
 \r
-  GdtTssTables    = NULL;\r
-  GdtTssTableSize = 0;\r
-  GdtTableStepSize = 0;\r
-  //\r
-  // For X64 SMM, we allocate separate GDT/TSS for each CPUs to avoid TSS load contention\r
-  // on each SMI entry.\r
-  //\r
-  if (EFI_IMAGE_MACHINE_TYPE_SUPPORTED(EFI_IMAGE_MACHINE_X64)) {\r
-    GdtTssTableSize = (gcSmiGdtr.Limit + 1 + TSS_SIZE + 7) & ~7; // 8 bytes aligned\r
-    GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));\r
-    ASSERT (GdtTssTables != NULL);\r
-    GdtTableStepSize = GdtTssTableSize;\r
-\r
-    for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {\r
-      CopyMem (GdtTssTables + GdtTableStepSize * Index, (VOID*)(UINTN)gcSmiGdtr.Base, gcSmiGdtr.Limit + 1 + TSS_SIZE);\r
-      if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
-        //\r
-        // Setup top of known good stack as IST1 for each processor.\r
-        //\r
-        *(UINTN *)(GdtTssTables + GdtTableStepSize * Index + gcSmiGdtr.Limit + 1 + TSS_X64_IST1_OFFSET) = (mSmmStackArrayBase + EFI_PAGE_SIZE + Index * mSmmStackSize);\r
-      }\r
-    }\r
-  } else if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
-\r
-    //\r
-    // For IA32 SMM, if SMM Stack Guard feature is enabled, we use 2 TSS.\r
-    // in this case, we allocate separate GDT/TSS for each CPUs to avoid TSS load contention\r
-    // on each SMI entry.\r
-    //\r
-\r
-    //\r
-    // Enlarge GDT to contain 2 TSS descriptors\r
-    //\r
-    gcSmiGdtr.Limit += (UINT16)(2 * sizeof (IA32_SEGMENT_DESCRIPTOR));\r
-\r
-    GdtTssTableSize = (gcSmiGdtr.Limit + 1 + TSS_SIZE * 2 + 7) & ~7; // 8 bytes aligned\r
-    GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));\r
-    ASSERT (GdtTssTables != NULL);\r
-    GdtTableStepSize = GdtTssTableSize;\r
-\r
-    for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {\r
-      CopyMem (GdtTssTables + GdtTableStepSize * Index, (VOID*)(UINTN)gcSmiGdtr.Base, gcSmiGdtr.Limit + 1 + TSS_SIZE * 2);\r
-      //\r
-      // Fixup TSS descriptors\r
-      //\r
-      TssBase = (UINTN)(GdtTssTables + GdtTableStepSize * Index + gcSmiGdtr.Limit + 1);\r
-      GdtDescriptor = (IA32_SEGMENT_DESCRIPTOR *)(TssBase) - 2;\r
-      GdtDescriptor->Bits.BaseLow = (UINT16)TssBase;\r
-      GdtDescriptor->Bits.BaseMid = (UINT8)(TssBase >> 16);\r
-      GdtDescriptor->Bits.BaseHigh = (UINT8)(TssBase >> 24);\r
-\r
-      TssBase += TSS_SIZE;\r
-      GdtDescriptor++;\r
-      GdtDescriptor->Bits.BaseLow = (UINT16)TssBase;\r
-      GdtDescriptor->Bits.BaseMid = (UINT8)(TssBase >> 16);\r
-      GdtDescriptor->Bits.BaseHigh = (UINT8)(TssBase >> 24);\r
-      //\r
-      // Fixup TSS segments\r
-      //\r
-      // ESP as known good stack\r
-      //\r
-      *(UINTN *)(TssBase + TSS_IA32_ESP_OFFSET) =  mSmmStackArrayBase + EFI_PAGE_SIZE + Index * mSmmStackSize;\r
-      *(UINT32 *)(TssBase + TSS_IA32_CR3_OFFSET) = Cr3;\r
-    }\r
-  }\r
+  GdtTssTables = InitGdt (Cr3, &GdtTableStepSize);\r
 \r
   //\r
   // Initialize PROCESSOR_SMM_DESCRIPTOR for each CPU\r
@@ -1254,18 +1187,8 @@ InitializeMpServiceData (
   for (Index = 0; Index < mMaxNumberOfCpus; Index++) {\r
     Psd = (PROCESSOR_SMM_DESCRIPTOR *)(VOID *)(UINTN)(mCpuHotPlugData.SmBase[Index] + SMM_PSD_OFFSET);\r
     CopyMem (Psd, &gcPsd, sizeof (gcPsd));\r
-    if (EFI_IMAGE_MACHINE_TYPE_SUPPORTED (EFI_IMAGE_MACHINE_X64)) {\r
-      //\r
-      // For X64 SMM, set GDT to the copy allocated above.\r
-      //\r
-      Psd->SmmGdtPtr = (UINT64)(UINTN)(GdtTssTables + GdtTableStepSize * Index);\r
-    } else if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
-      //\r
-      // For IA32 SMM, if SMM Stack Guard feature is enabled, set GDT to the copy allocated above.\r
-      //\r
-      Psd->SmmGdtPtr = (UINT64)(UINTN)(GdtTssTables + GdtTableStepSize * Index);\r
-      Psd->SmmGdtSize = gcSmiGdtr.Limit + 1;\r
-    }\r
+    Psd->SmmGdtPtr = (UINT64)(UINTN)(GdtTssTables + GdtTableStepSize * Index);\r
+    Psd->SmmGdtSize = gcSmiGdtr.Limit + 1;\r
 \r
     //\r
     // Install SMI handler\r
index cfbf2ca6dae38ea89d4645bb25e473026367cb92..106e67465c0a4c7112fecc8a962c7a538fafaaa8 100644 (file)
@@ -427,6 +427,21 @@ InitializeIDTSmmStackGuard (
   VOID\r
   );\r
 \r
+/**\r
+  Initialize Gdt for all processors.\r
+  \r
+  @param[in]   Cr3          CR3 value.\r
+  @param[out]  GdtStepSize  The step size for GDT table.\r
+\r
+  @return GdtBase for processor 0.\r
+          GdtBase for processor X is: GdtBase + (GdtStepSize * X)\r
+**/\r
+VOID *\r
+InitGdt (\r
+  IN  UINTN  Cr3,\r
+  OUT UINTN  *GdtStepSize\r
+  );\r
+\r
 /**\r
 \r
   Register the SMM Foundation entry point.\r
index a293a88e9914930ddbe6e2e8cdf3e35469aacd4f..122318f02e686ca0c49b070a59f546678308b50d 100644 (file)
@@ -48,6 +48,7 @@
 [Sources.Ia32]\r
   Ia32/Semaphore.c\r
   Ia32/PageTbl.c\r
+  Ia32/SmmFuncsArch.c\r
   Ia32/SmmProfileArch.c\r
   Ia32/SmmProfileArch.h\r
   Ia32/SmmInit.asm      | MSFT\r
@@ -68,6 +69,7 @@
 [Sources.X64]\r
   X64/Semaphore.c\r
   X64/PageTbl.c\r
+  X64/SmmFuncsArch.c\r
   X64/SmmProfileArch.c\r
   X64/SmmProfileArch.h\r
   X64/SmmInit.asm      | MSFT\r
index 831559357f159035bb9f793604ae53aba5b2beec..95e6dfa814f79058e7e149503f7ec4b27fac30fb 100644 (file)
@@ -128,14 +128,6 @@ ASM_PFX(gSmiCr3):    .space  4
     sgdt    (%rsp)\r
     movl    2(%rsp), %eax               # eax = GDT base\r
     addl    $8, %esp\r
-    movl    %eax, %edx\r
-    addl    $GDT_SIZE, %edx\r
-    movb    %dl, (TSS_SEGMENT + 2)(%rax)\r
-    movb    %dh, (TSS_SEGMENT + 3)(%rax)\r
-    .byte   0xc1, 0xea, 0x10             # shr     edx, 16\r
-    movb    %dl, (TSS_SEGMENT + 4)(%rax)\r
-    movb    %dh, (TSS_SEGMENT + 7)(%rax)\r
-    movl    %eax, %edx\r
     movb    $0x89, %dl\r
     movb    %dl, (TSS_SEGMENT + 5)(%rax) # clear busy flag\r
     movl    $TSS_SEGMENT, %eax\r
index c556bf5f5b284813e2bfb1e327fff4bd8560a164..4d53db5b00da6c6ca961c69c73dd7e2e1a70617d 100644 (file)
@@ -124,14 +124,6 @@ gSmiCr3     DD      ?
     sgdt    fword ptr [rsp]\r
     mov     eax, [rsp + 2]              ; eax = GDT base\r
     add     esp, 8\r
-    mov     edx, eax\r
-    add     edx, GDT_SIZE\r
-    mov     [rax + TSS_SEGMENT + 2], dl\r
-    mov     [rax + TSS_SEGMENT + 3], dh\r
-    DB      0c1h, 0eah, 10h             ; shr     edx, 16\r
-    mov     [rax + TSS_SEGMENT + 4], dl\r
-    mov     [rax + TSS_SEGMENT + 7], dh\r
-    mov     edx, eax\r
     mov     dl, 89h\r
     mov     [rax + TSS_SEGMENT + 5], dl ; clear busy flag\r
     mov     eax, TSS_SEGMENT\r
diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c
new file mode 100644 (file)
index 0000000..b53aa45
--- /dev/null
@@ -0,0 +1,70 @@
+/** @file\r
+  SMM CPU misc functions for x64 arch specific.\r
+  \r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "PiSmmCpuDxeSmm.h"\r
+\r
+/**\r
+  Initialize Gdt for all processors.\r
+  \r
+  @param[in]   Cr3          CR3 value.\r
+  @param[out]  GdtStepSize  The step size for GDT table.\r
+\r
+  @return GdtBase for processor 0.\r
+          GdtBase for processor X is: GdtBase + (GdtStepSize * X)\r
+**/\r
+VOID *\r
+InitGdt (\r
+  IN  UINTN  Cr3,\r
+  OUT UINTN  *GdtStepSize\r
+  )\r
+{\r
+  UINTN                     Index;\r
+  IA32_SEGMENT_DESCRIPTOR   *GdtDescriptor;\r
+  UINTN                     TssBase;\r
+  UINTN                     GdtTssTableSize;\r
+  UINT8                     *GdtTssTables;\r
+  UINTN                     GdtTableStepSize;\r
+\r
+  //\r
+  // For X64 SMM, we allocate separate GDT/TSS for each CPUs to avoid TSS load contention\r
+  // on each SMI entry.\r
+  //\r
+  GdtTssTableSize = (gcSmiGdtr.Limit + 1 + TSS_SIZE + 7) & ~7; // 8 bytes aligned\r
+  GdtTssTables = (UINT8*)AllocatePages (EFI_SIZE_TO_PAGES (GdtTssTableSize * gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus));\r
+  ASSERT (GdtTssTables != NULL);\r
+  GdtTableStepSize = GdtTssTableSize;\r
+\r
+  for (Index = 0; Index < gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; Index++) {\r
+    CopyMem (GdtTssTables + GdtTableStepSize * Index, (VOID*)(UINTN)gcSmiGdtr.Base, gcSmiGdtr.Limit + 1 + TSS_SIZE);\r
+\r
+    //\r
+    // Fixup TSS descriptors\r
+    //\r
+    TssBase = (UINTN)(GdtTssTables + GdtTableStepSize * Index + gcSmiGdtr.Limit + 1);\r
+    GdtDescriptor = (IA32_SEGMENT_DESCRIPTOR *)(TssBase) - 2;\r
+    GdtDescriptor->Bits.BaseLow = (UINT16)(UINTN)TssBase;\r
+    GdtDescriptor->Bits.BaseMid = (UINT8)((UINTN)TssBase >> 16);\r
+    GdtDescriptor->Bits.BaseHigh = (UINT8)((UINTN)TssBase >> 24);\r
+\r
+    if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
+      //\r
+      // Setup top of known good stack as IST1 for each processor.\r
+      //\r
+      *(UINTN *)(TssBase + TSS_X64_IST1_OFFSET) = (mSmmStackArrayBase + EFI_PAGE_SIZE + Index * mSmmStackSize);\r
+    }\r
+  }\r
+\r
+  *GdtStepSize = GdtTableStepSize;\r
+  return GdtTssTables;\r
+}\r