]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Misc / DebugImageInfo.c
index 295f32f43e8eee0b2c71335f43504973f26033d6..a75d4158280b9597e5d265d8ce6fecdeeb49598c 100644 (file)
@@ -2,14 +2,8 @@
   Support functions for managing debug image info table when loading and unloading\r
   images.\r
 \r
-Copyright (c) 2006 - 2008, Intel Corporation. <BR>\r
-All rights reserved. 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
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -22,9 +16,9 @@ EFI_DEBUG_IMAGE_INFO_TABLE_HEADER  mDebugInfoTableHeader = {
   NULL        // EFI_DEBUG_IMAGE_INFO            *EfiDebugImageInfoTable;\r
 };\r
 \r
-EFI_SYSTEM_TABLE_POINTER *mDebugTable = NULL;\r
+UINTN mMaxTableEntries = 0;\r
 \r
-#define FOUR_MEG_ALIGNMENT   0x400000\r
+EFI_SYSTEM_TABLE_POINTER  *mDebugTable = NULL;\r
 \r
 #define EFI_DEBUG_TABLE_ENTRY_SIZE       (sizeof (VOID *))\r
 \r
@@ -38,17 +32,98 @@ CoreInitializeDebugImageInfoTable (
   VOID\r
   )\r
 {\r
-  EFI_STATUS                          Status;\r
+  EFI_STATUS            Status;\r
+  UINTN                 Pages;\r
+  EFI_PHYSICAL_ADDRESS  Memory;\r
+  UINTN                 AlignedMemory;\r
+  UINTN                 AlignmentMask;\r
+  UINTN                 UnalignedPages;\r
+  UINTN                 RealPages;\r
 \r
   //\r
   // Allocate 4M aligned page for the structure and fill in the data.\r
   // Ideally we would update the CRC now as well, but the service may not yet be available.\r
   // See comments in the CoreUpdateDebugTableCrc32() function below for details.\r
   //\r
-  mDebugTable = AllocateAlignedPages (EFI_SIZE_TO_PAGES (sizeof (EFI_SYSTEM_TABLE_POINTER)), FOUR_MEG_ALIGNMENT); \r
-  mDebugTable->Signature = EFI_SYSTEM_TABLE_SIGNATURE;\r
+  Pages          = EFI_SIZE_TO_PAGES (sizeof (EFI_SYSTEM_TABLE_POINTER));\r
+  AlignmentMask  = SIZE_4MB - 1;\r
+  RealPages      = Pages + EFI_SIZE_TO_PAGES (SIZE_4MB);\r
+\r
+  //\r
+  // Attempt to allocate memory below PcdMaxEfiSystemTablePointerAddress\r
+  // If PcdMaxEfiSystemTablePointerAddress is 0, then allocate memory below\r
+  // MAX_ADDRESS\r
+  //\r
+  Memory = PcdGet64 (PcdMaxEfiSystemTablePointerAddress);\r
+  if (Memory == 0) {\r
+    Memory = MAX_ADDRESS;\r
+  }\r
+  Status = CoreAllocatePages (\r
+             AllocateMaxAddress,\r
+             EfiBootServicesData,\r
+             RealPages,\r
+             &Memory\r
+             );\r
+  if (EFI_ERROR (Status)) {\r
+    if (PcdGet64 (PcdMaxEfiSystemTablePointerAddress) != 0) {\r
+      DEBUG ((EFI_D_INFO, "Allocate memory for EFI_SYSTEM_TABLE_POINTER below PcdMaxEfiSystemTablePointerAddress failed. \\r
+                          Retry to allocate memroy as close to the top of memory as feasible.\n"));\r
+    }\r
+    //\r
+    // If the initial memory allocation fails, then reattempt allocation\r
+    // as close to the top of memory as feasible.\r
+    //\r
+    Status = CoreAllocatePages (\r
+               AllocateAnyPages,\r
+               EfiBootServicesData,\r
+               RealPages,\r
+               &Memory\r
+               );\r
+    ASSERT_EFI_ERROR (Status);\r
+    if (EFI_ERROR (Status)) {\r
+      return;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Free overallocated pages\r
+  //\r
+  AlignedMemory  = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;\r
+  UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory);\r
+  if (UnalignedPages > 0) {\r
+    //\r
+    // Free first unaligned page(s).\r
+    //\r
+    Status = CoreFreePages (Memory, UnalignedPages);\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+  Memory         = AlignedMemory + EFI_PAGES_TO_SIZE (Pages);\r
+  UnalignedPages = RealPages - Pages - UnalignedPages;\r
+  if (UnalignedPages > 0) {\r
+    //\r
+    // Free last unaligned page(s).\r
+    //\r
+    Status = CoreFreePages (Memory, UnalignedPages);\r
+    ASSERT_EFI_ERROR (Status);\r
+  }\r
+\r
+  //\r
+  // Set mDebugTable to the 4MB aligned allocated pages\r
+  //\r
+  mDebugTable = (EFI_SYSTEM_TABLE_POINTER  *)(AlignedMemory);\r
+  ASSERT (mDebugTable != NULL);\r
+\r
+  //\r
+  // Initialize EFI_SYSTEM_TABLE_POINTER structure\r
+  //\r
+  mDebugTable->Signature          = EFI_SYSTEM_TABLE_SIGNATURE;\r
   mDebugTable->EfiSystemTableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) gDxeCoreST;\r
-  mDebugTable->Crc32 = 0;\r
+  mDebugTable->Crc32              = 0;\r
+\r
+  //\r
+  // Install the EFI_SYSTEM_TABLE_POINTER structure in the EFI System\r
+  // Configuration Table\r
+  //\r
   Status = CoreInstallConfigurationTable (&gEfiDebugImageInfoTableGuid, &mDebugInfoTableHeader);\r
   ASSERT_EFI_ERROR (Status);\r
 }\r
@@ -93,7 +168,6 @@ CoreNewDebugImageInfoEntry (
   EFI_DEBUG_IMAGE_INFO      *Table;\r
   EFI_DEBUG_IMAGE_INFO      *NewTable;\r
   UINTN                     Index;\r
-  UINTN                     MaxTableIndex;\r
   UINTN                     TableSize;\r
 \r
   //\r
@@ -102,21 +176,24 @@ CoreNewDebugImageInfoEntry (
   mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;\r
 \r
   Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;\r
-  MaxTableIndex = mDebugInfoTableHeader.TableSize;\r
 \r
-  for (Index = 0; Index < MaxTableIndex; Index++) {\r
-    if (Table[Index].NormalImage == NULL) {\r
-      //\r
-      // We have found a free entry so exit the loop\r
-      //\r
-      break;\r
+  if (mDebugInfoTableHeader.TableSize < mMaxTableEntries) {\r
+    //\r
+    // We still have empty entires in the Table, find the first empty entry.\r
+    //\r
+    Index = 0;\r
+    while (Table[Index].NormalImage != NULL) {\r
+      Index++;\r
     }\r
-  }\r
-  if (Index == MaxTableIndex) {\r
+    //\r
+    // There must be an empty entry in the in the table.\r
+    //\r
+    ASSERT (Index < mMaxTableEntries);\r
+  } else {\r
     //\r
     //  Table is full, so re-allocate another page for a larger table...\r
     //\r
-    TableSize = MaxTableIndex * EFI_DEBUG_TABLE_ENTRY_SIZE;\r
+    TableSize = mMaxTableEntries * EFI_DEBUG_TABLE_ENTRY_SIZE;\r
     NewTable = AllocateZeroPool (TableSize + EFI_PAGE_SIZE);\r
     if (NewTable == NULL) {\r
       mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;\r
@@ -135,8 +212,14 @@ CoreNewDebugImageInfoEntry (
     //\r
     Table = NewTable;\r
     mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable;\r
-    mDebugInfoTableHeader.TableSize += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;\r
+    //\r
+    // Enlarge the max table entries and set the first empty entry index to\r
+    // be the original max table entries.\r
+    //\r
+    Index             = mMaxTableEntries;\r
+    mMaxTableEntries += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;\r
   }\r
+\r
   //\r
   // Allocate data for new entry\r
   //\r
@@ -148,6 +231,11 @@ CoreNewDebugImageInfoEntry (
     Table[Index].NormalImage->ImageInfoType               = (UINT32) ImageInfoType;\r
     Table[Index].NormalImage->LoadedImageProtocolInstance = LoadedImage;\r
     Table[Index].NormalImage->ImageHandle                 = ImageHandle;\r
+    //\r
+    // Increase the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status.\r
+    //\r
+    mDebugInfoTableHeader.TableSize++;\r
+    mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;\r
   }\r
   mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;\r
 }\r
@@ -172,7 +260,7 @@ CoreRemoveDebugImageInfoEntry (
 \r
   Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;\r
 \r
-  for (Index = 0; Index < mDebugInfoTableHeader.TableSize; Index++) {\r
+  for (Index = 0; Index < mMaxTableEntries; Index++) {\r
     if (Table[Index].NormalImage != NULL && Table[Index].NormalImage->ImageHandle == ImageHandle) {\r
       //\r
       // Found a match. Free up the record, then NULL the pointer to indicate the slot\r
@@ -180,6 +268,11 @@ CoreRemoveDebugImageInfoEntry (
       //\r
       CoreFreePool (Table[Index].NormalImage);\r
       Table[Index].NormalImage = NULL;\r
+      //\r
+      // Decrease the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status.\r
+      //\r
+      mDebugInfoTableHeader.TableSize--;\r
+      mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;\r
       break;\r
     }\r
   }\r