]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/DxeIplPeim/Ia32/DxeLoadFunc.c
MdeModulePkg/DxeLoadFunc: Add use case for new Perf macro
[mirror_edk2.git] / MdeModulePkg / Core / DxeIplPeim / Ia32 / DxeLoadFunc.c
index 6ec51ff09a3fccb8522142a2d3ae285a917defd4..8a939b6c24870f03f6e9ce0f7de633afc03e279b 100644 (file)
@@ -1,7 +1,9 @@
 /** @file\r
   Ia32-specific functionality for DxeLoad.\r
 \r
-Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
+\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
@@ -71,7 +73,7 @@ Create4GPageTablesIa32Pae (
   IN EFI_PHYSICAL_ADDRESS   StackBase,\r
   IN UINTN                  StackSize\r
   )\r
-{  \r
+{\r
   UINT8                                         PhysicalAddressBits;\r
   EFI_PHYSICAL_ADDRESS                          PhysicalAddress;\r
   UINTN                                         IndexOfPdpEntries;\r
@@ -82,6 +84,12 @@ Create4GPageTablesIa32Pae (
   PAGE_TABLE_ENTRY                              *PageDirectoryEntry;\r
   UINTN                                         TotalPagesNum;\r
   UINTN                                         PageAddress;\r
+  UINT64                                        AddressEncMask;\r
+\r
+  //\r
+  // Make sure AddressEncMask is contained to smallest supported address field\r
+  //\r
+  AddressEncMask = PcdGet64 (PcdPteMemoryEncryptionAddressOrMask) & PAGING_1G_ADDRESS_MASK_64;\r
 \r
   PhysicalAddressBits = 32;\r
 \r
@@ -91,7 +99,7 @@ Create4GPageTablesIa32Pae (
   NumberOfPdpEntriesNeeded = (UINT32) LShiftU64 (1, (PhysicalAddressBits - 30));\r
 \r
   TotalPagesNum = NumberOfPdpEntriesNeeded + 1;\r
-  PageAddress = (UINTN) AllocatePages (TotalPagesNum);\r
+  PageAddress = (UINTN) AllocatePageTableMemory (TotalPagesNum);\r
   ASSERT (PageAddress != 0);\r
 \r
   PageMap = (VOID *) PageAddress;\r
@@ -104,18 +112,20 @@ Create4GPageTablesIa32Pae (
     //\r
     // Each Directory Pointer entries points to a page of Page Directory entires.\r
     // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.\r
-    //       \r
+    //\r
     PageDirectoryEntry = (VOID *) PageAddress;\r
     PageAddress += SIZE_4KB;\r
 \r
     //\r
     // Fill in a Page Directory Pointer Entries\r
     //\r
-    PageDirectoryPointerEntry->Uint64 = (UINT64) (UINTN) PageDirectoryEntry;\r
+    PageDirectoryPointerEntry->Uint64 = (UINT64) (UINTN) PageDirectoryEntry | AddressEncMask;\r
     PageDirectoryPointerEntry->Bits.Present = 1;\r
 \r
     for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PhysicalAddress += SIZE_2MB) {\r
-      if ((PhysicalAddress < StackBase + StackSize) && ((PhysicalAddress + SIZE_2MB) > StackBase)) {\r
+      if ((IsNullDetectionEnabled () && PhysicalAddress == 0)\r
+          || ((PhysicalAddress < StackBase + StackSize)\r
+              && ((PhysicalAddress + SIZE_2MB) > StackBase))) {\r
         //\r
         // Need to split this 2M page that covers stack range.\r
         //\r
@@ -124,7 +134,7 @@ Create4GPageTablesIa32Pae (
         //\r
         // Fill in the Page Directory entries\r
         //\r
-        PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress;\r
+        PageDirectoryEntry->Uint64 = (UINT64) PhysicalAddress | AddressEncMask;\r
         PageDirectoryEntry->Bits.ReadWrite = 1;\r
         PageDirectoryEntry->Bits.Present = 1;\r
         PageDirectoryEntry->Bits.MustBe1 = 1;\r
@@ -139,6 +149,12 @@ Create4GPageTablesIa32Pae (
       );\r
   }\r
 \r
+  //\r
+  // Protect the page table by marking the memory used for page table to be\r
+  // read-only.\r
+  //\r
+  EnablePageTableProtection ((UINTN)PageMap, FALSE);\r
+\r
   return (UINTN) PageMap;\r
 }\r
 \r
@@ -201,6 +217,41 @@ IsExecuteDisableBitAvailable (
   return Available;\r
 }\r
 \r
+/**\r
+  The function will check if page table should be setup or not.\r
+\r
+  @retval TRUE      Page table should be created.\r
+  @retval FALSE     Page table should not be created.\r
+\r
+**/\r
+BOOLEAN\r
+ToBuildPageTable (\r
+  VOID\r
+  )\r
+{\r
+  if (!IsIa32PaeSupport ()) {\r
+    return FALSE;\r
+  }\r
+\r
+  if (IsNullDetectionEnabled ()) {\r
+    return TRUE;\r
+  }\r
+\r
+  if (PcdGet8 (PcdHeapGuardPropertyMask) != 0) {\r
+    return TRUE;\r
+  }\r
+\r
+  if (PcdGetBool (PcdCpuStackGuard)) {\r
+    return TRUE;\r
+  }\r
+\r
+  if (PcdGetBool (PcdSetNxForStack) && IsExecuteDisableBitAvailable ()) {\r
+    return TRUE;\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
 /**\r
    Transfers control to DxeCore.\r
 \r
@@ -232,6 +283,10 @@ HandOffToDxeCore (
   EFI_PEI_VECTOR_HANDOFF_INFO_PPI *VectorHandoffInfoPpi;\r
   BOOLEAN                   BuildPageTablesIa32Pae;\r
 \r
+  if (IsNullDetectionEnabled ()) {\r
+    ClearFirst4KPage (HobList.Raw);\r
+  }\r
+\r
   Status = PeiServicesAllocatePages (EfiBootServicesData, EFI_SIZE_TO_PAGES (STACK_SIZE), &BaseOfStack);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
@@ -265,7 +320,9 @@ HandOffToDxeCore (
     //\r
     // End of PEI phase signal\r
     //\r
+    PERF_EVENT_SIGNAL_BEGIN (gEndOfPeiSignalPpi.Guid);\r
     Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);\r
+    PERF_EVENT_SIGNAL_END (gEndOfPeiSignalPpi.Guid);\r
     ASSERT_EFI_ERROR (Status);\r
 \r
     AsmWriteCr3 (PageTables);\r
@@ -280,7 +337,7 @@ HandOffToDxeCore (
     Status = PeiServicesAllocatePages (\r
                EfiBootServicesData,\r
                EFI_SIZE_TO_PAGES(sizeof (X64_IDT_TABLE) + SizeOfTemplate * IDT_ENTRY_COUNT),\r
-               (EFI_PHYSICAL_ADDRESS *) &IdtTableForX64\r
+               &VectorAddress\r
                );\r
     ASSERT_EFI_ERROR (Status);\r
 \r
@@ -288,6 +345,7 @@ HandOffToDxeCore (
     // Store EFI_PEI_SERVICES** in the 4 bytes immediately preceding IDT to avoid that\r
     // it may not be gotten correctly after IDT register is re-written.\r
     //\r
+    IdtTableForX64 = (X64_IDT_TABLE *) (UINTN) VectorAddress;\r
     IdtTableForX64->PeiService = GetPeiServicesTablePointer ();\r
 \r
     VectorAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) (IdtTableForX64 + 1);\r
@@ -370,16 +428,20 @@ HandOffToDxeCore (
     TopOfStack = (EFI_PHYSICAL_ADDRESS) (UINTN) ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);\r
 \r
     PageTables = 0;\r
-    BuildPageTablesIa32Pae = (BOOLEAN) (PcdGetBool (PcdSetNxForStack) && IsIa32PaeSupport () && IsExecuteDisableBitAvailable ());\r
+    BuildPageTablesIa32Pae = ToBuildPageTable ();\r
     if (BuildPageTablesIa32Pae) {\r
       PageTables = Create4GPageTablesIa32Pae (BaseOfStack, STACK_SIZE);\r
-      EnableExecuteDisableBit ();\r
+      if (IsExecuteDisableBitAvailable ()) {\r
+        EnableExecuteDisableBit();\r
+      }\r
     }\r
 \r
     //\r
     // End of PEI phase signal\r
     //\r
+    PERF_EVENT_SIGNAL_BEGIN (gEndOfPeiSignalPpi.Guid);\r
     Status = PeiServicesInstallPpi (&gEndOfPeiSignalPpi);\r
+    PERF_EVENT_SIGNAL_END (gEndOfPeiSignalPpi.Guid);\r
     ASSERT_EFI_ERROR (Status);\r
 \r
     if (BuildPageTablesIa32Pae) {\r