]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/PiSmmCpuDxeSmm/MpService.c
MdeModulePkg-DxeCore: rename CoreGetMemoryMapPropertiesTable
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / MpService.c
index 730c32df0a254bdde82472187a2218cc29db858b..185cb3d5935fe92ebf79a785487c392e080a0d69 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 SMM MP service implementation\r
 \r
-Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2009 - 2016, 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
@@ -412,15 +412,9 @@ BSPHandler (
   AcquireSpinLockOrFail (&mSmmMpSyncData->CpuData[CpuIndex].Busy);\r
 \r
   //\r
-  // Restore SMM Configuration in S3 boot path.\r
+  // Perform the pre tasks\r
   //\r
-  if (mRestoreSmmConfigurationInS3) {\r
-    //\r
-    // Configure SMM Code Access Check feature if available.\r
-    //\r
-    ConfigSmmCodeAccessCheck ();\r
-    mRestoreSmmConfigurationInS3 = FALSE;\r
-  }\r
+  PerformPreTasks ();\r
 \r
   //\r
   // Invoke SMM Foundation EntryPoint with the processor information context.\r
@@ -738,12 +732,14 @@ APHandler (
   Create 4G PageTable in SMRAM.\r
 \r
   @param          ExtraPages       Additional page numbers besides for 4G memory\r
+  @param          Is32BitPageTable Whether the page table is 32-bit PAE\r
   @return         PageTable Address\r
 \r
 **/\r
 UINT32\r
 Gen4GPageTable (\r
-  IN      UINTN                     ExtraPages\r
+  IN      UINTN                     ExtraPages,\r
+  IN      BOOLEAN                   Is32BitPageTable\r
   )\r
 {\r
   VOID    *PageTable;\r
@@ -776,7 +772,7 @@ Gen4GPageTable (
   //\r
   // Allocate the page table\r
   //\r
-  PageTable = AllocatePages (ExtraPages + 5 + PagesNeeded);\r
+  PageTable = AllocatePageTableMemory (ExtraPages + 5 + PagesNeeded);\r
   ASSERT (PageTable != NULL);\r
 \r
   PageTable = (VOID *)((UINTN)PageTable + EFI_PAGES_TO_SIZE (ExtraPages));\r
@@ -791,7 +787,7 @@ Gen4GPageTable (
   // Set Page Directory Pointers\r
   //\r
   for (Index = 0; Index < 4; Index++) {\r
-    Pte[Index] = (UINTN)PageTable + EFI_PAGE_SIZE * (Index + 1) + IA32_PG_P;\r
+    Pte[Index] = (UINTN)PageTable + EFI_PAGE_SIZE * (Index + 1) + (Is32BitPageTable ? IA32_PAE_PDPTE_ATTRIBUTE_BITS : PAGE_ATTRIBUTE_BITS);\r
   }\r
   Pte += EFI_PAGE_SIZE / sizeof (*Pte);\r
 \r
@@ -799,7 +795,7 @@ Gen4GPageTable (
   // Fill in Page Directory Entries\r
   //\r
   for (Index = 0; Index < EFI_PAGE_SIZE * 4 / sizeof (*Pte); Index++) {\r
-    Pte[Index] = (Index << 21) + IA32_PG_PS + IA32_PG_RW + IA32_PG_P;\r
+    Pte[Index] = (Index << 21) | IA32_PG_PS | PAGE_ATTRIBUTE_BITS;\r
   }\r
 \r
   if (FeaturePcdGet (PcdCpuSmmStackGuard)) {\r
@@ -808,7 +804,7 @@ Gen4GPageTable (
     Pdpte = (UINT64*)PageTable;\r
     for (PageIndex = Low2MBoundary; PageIndex <= High2MBoundary; PageIndex += SIZE_2MB) {\r
       Pte = (UINT64*)(UINTN)(Pdpte[BitFieldRead32 ((UINT32)PageIndex, 30, 31)] & ~(EFI_PAGE_SIZE - 1));\r
-      Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages + IA32_PG_RW + IA32_PG_P;\r
+      Pte[BitFieldRead32 ((UINT32)PageIndex, 21, 29)] = (UINT64)Pages | PAGE_ATTRIBUTE_BITS;\r
       //\r
       // Fill in Page Table Entries\r
       //\r
@@ -825,7 +821,7 @@ Gen4GPageTable (
             GuardPage = 0;\r
           }\r
         } else {\r
-          Pte[Index] = PageAddress + IA32_PG_RW + IA32_PG_P;\r
+          Pte[Index] = PageAddress | PAGE_ATTRIBUTE_BITS;\r
         }\r
         PageAddress+= EFI_PAGE_SIZE;\r
       }\r
@@ -878,7 +874,7 @@ SetCacheability (
     //\r
     // Allocate a page from SMRAM\r
     //\r
-    NewPageTableAddress = AllocatePages (1);\r
+    NewPageTableAddress = AllocatePageTableMemory (1);\r
     ASSERT (NewPageTableAddress != NULL);\r
 \r
     NewPageTable = (UINT64 *)NewPageTableAddress;\r
@@ -892,7 +888,7 @@ SetCacheability (
       NewPageTable[Index] |= (UINT64)(Index << EFI_PAGE_SHIFT);\r
     }\r
 \r
-    PageTable[PTIndex] = ((UINTN)NewPageTableAddress & gPhyMask) | IA32_PG_P;\r
+    PageTable[PTIndex] = ((UINTN)NewPageTableAddress & gPhyMask) | PAGE_ATTRIBUTE_BITS;\r
   }\r
 \r
   ASSERT (PageTable[PTIndex] & IA32_PG_P);\r
@@ -946,6 +942,65 @@ SmmStartupThisAp (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  This function sets DR6 & DR7 according to SMM save state, before running SMM C code.\r
+  They are useful when you want to enable hardware breakpoints in SMM without entry SMM mode.\r
+\r
+  NOTE: It might not be appreciated in runtime since it might\r
+        conflict with OS debugging facilities. Turn them off in RELEASE.\r
+\r
+  @param    CpuIndex              CPU Index\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+CpuSmmDebugEntry (\r
+  IN UINTN  CpuIndex\r
+  )\r
+{\r
+  SMRAM_SAVE_STATE_MAP *CpuSaveState;\r
+  \r
+  if (FeaturePcdGet (PcdCpuSmmDebug)) {\r
+    CpuSaveState = (SMRAM_SAVE_STATE_MAP *)gSmmCpuPrivate->CpuSaveState[CpuIndex];\r
+    if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) {\r
+      AsmWriteDr6 (CpuSaveState->x86._DR6);\r
+      AsmWriteDr7 (CpuSaveState->x86._DR7);\r
+    } else {\r
+      AsmWriteDr6 ((UINTN)CpuSaveState->x64._DR6);\r
+      AsmWriteDr7 ((UINTN)CpuSaveState->x64._DR7);\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+  This function restores DR6 & DR7 to SMM save state.\r
+\r
+  NOTE: It might not be appreciated in runtime since it might\r
+        conflict with OS debugging facilities. Turn them off in RELEASE.\r
+\r
+  @param    CpuIndex              CPU Index\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+CpuSmmDebugExit (\r
+  IN UINTN  CpuIndex\r
+  )\r
+{\r
+  SMRAM_SAVE_STATE_MAP *CpuSaveState;\r
+\r
+  if (FeaturePcdGet (PcdCpuSmmDebug)) {\r
+    CpuSaveState = (SMRAM_SAVE_STATE_MAP *)gSmmCpuPrivate->CpuSaveState[CpuIndex];\r
+    if (mSmmSaveStateRegisterLma == EFI_SMM_SAVE_STATE_REGISTER_LMA_32BIT) {\r
+      CpuSaveState->x86._DR7 = (UINT32)AsmReadDr7 ();\r
+      CpuSaveState->x86._DR6 = (UINT32)AsmReadDr6 ();\r
+    } else {\r
+      CpuSaveState->x64._DR7 = AsmReadDr7 ();\r
+      CpuSaveState->x64._DR6 = AsmReadDr6 ();\r
+    }\r
+  }\r
+}\r
+\r
 /**\r
   C function for SMI entry, each processor comes here upon SMI trigger.\r
 \r
@@ -964,6 +1019,7 @@ SmiRendezvous (
   BOOLEAN           BspInProgress;\r
   UINTN             Index;\r
   UINTN             Cr2;\r
+  BOOLEAN           XdDisableFlag;\r
 \r
   //\r
   // Save Cr2 because Page Fault exception in SMM may override its value\r
@@ -1023,9 +1079,14 @@ SmiRendezvous (
     }\r
 \r
     //\r
-    // Try to enable NX\r
+    // Try to enable XD\r
     //\r
+    XdDisableFlag = FALSE;\r
     if (mXdSupported) {\r
+      if ((AsmReadMsr64 (MSR_IA32_MISC_ENABLE) & B_XD_DISABLE_BIT) != 0) {\r
+        XdDisableFlag = TRUE;\r
+        AsmMsrAnd64 (MSR_IA32_MISC_ENABLE, ~B_XD_DISABLE_BIT);\r
+      }\r
       ActivateXd ();\r
     }\r
 \r
@@ -1097,7 +1158,6 @@ SmiRendezvous (
         // BSP Handler is always called with a ValidSmi == TRUE\r
         //\r
         BSPHandler (CpuIndex, mSmmMpSyncData->EffectiveSyncMode);\r
-\r
       } else {\r
         APHandler (CpuIndex, ValidSmi, mSmmMpSyncData->EffectiveSyncMode);\r
       }\r
@@ -1110,6 +1170,13 @@ SmiRendezvous (
     //\r
     while (mSmmMpSyncData->AllCpusInSync) {\r
       CpuPause ();\r
+     }\r
+\r
+    //\r
+    // Restore XD\r
+    //\r
+    if (XdDisableFlag) {\r
+      AsmMsrOr64 (MSR_IA32_MISC_ENABLE, B_XD_DISABLE_BIT);\r
     }\r
   }\r
 \r
@@ -1163,10 +1230,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 +1246,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 +1254,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