]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Core/Dxe/Misc/DebugImageInfo.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Core / Dxe / Misc / DebugImageInfo.c
CommitLineData
23c98c94 1/** @file\r
504214c4
LG
2 Support functions for managing debug image info table when loading and unloading\r
3 images.\r
4\r
d1102dba 5Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
28a00297 7\r
504214c4 8**/\r
28a00297 9\r
9c4ac31c 10#include "DxeMain.h"\r
28a00297 11\r
12\r
e94a9ff7 13EFI_DEBUG_IMAGE_INFO_TABLE_HEADER mDebugInfoTableHeader = {\r
28a00297 14 0, // volatile UINT32 UpdateStatus;\r
15 0, // UINT32 TableSize;\r
16 NULL // EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable;\r
17};\r
18\r
2f2a277d 19UINTN mMaxTableEntries = 0;\r
20\r
6eea8eae 21EFI_SYSTEM_TABLE_POINTER *mDebugTable = NULL;\r
022c6d45 22\r
ec90508b 23#define EFI_DEBUG_TABLE_ENTRY_SIZE (sizeof (VOID *))\r
28a00297 24\r
162ed594 25/**\r
28a00297 26 Creates and initializes the DebugImageInfo Table. Also creates the configuration\r
27 table and registers it into the system table.\r
28\r
162ed594 29**/\r
30VOID\r
31CoreInitializeDebugImageInfoTable (\r
32 VOID\r
33 )\r
022c6d45 34{\r
6eea8eae
LG
35 EFI_STATUS Status;\r
36 UINTN Pages;\r
37 EFI_PHYSICAL_ADDRESS Memory;\r
38 UINTN AlignedMemory;\r
39 UINTN AlignmentMask;\r
40 UINTN UnalignedPages;\r
41 UINTN RealPages;\r
022c6d45 42\r
28a00297 43 //\r
19e14fc9 44 // Allocate 4M aligned page for the structure and fill in the data.\r
28a00297 45 // Ideally we would update the CRC now as well, but the service may not yet be available.\r
46 // See comments in the CoreUpdateDebugTableCrc32() function below for details.\r
47 //\r
6eea8eae
LG
48 Pages = EFI_SIZE_TO_PAGES (sizeof (EFI_SYSTEM_TABLE_POINTER));\r
49 AlignmentMask = SIZE_4MB - 1;\r
50 RealPages = Pages + EFI_SIZE_TO_PAGES (SIZE_4MB);\r
51\r
52 //\r
53 // Attempt to allocate memory below PcdMaxEfiSystemTablePointerAddress\r
54 // If PcdMaxEfiSystemTablePointerAddress is 0, then allocate memory below\r
55 // MAX_ADDRESS\r
56 //\r
57 Memory = PcdGet64 (PcdMaxEfiSystemTablePointerAddress);\r
58 if (Memory == 0) {\r
59 Memory = MAX_ADDRESS;\r
60 }\r
61 Status = CoreAllocatePages (\r
d1102dba 62 AllocateMaxAddress,\r
6eea8eae 63 EfiBootServicesData,\r
d1102dba 64 RealPages,\r
6eea8eae
LG
65 &Memory\r
66 );\r
67 if (EFI_ERROR (Status)) {\r
68 if (PcdGet64 (PcdMaxEfiSystemTablePointerAddress) != 0) {\r
69 DEBUG ((EFI_D_INFO, "Allocate memory for EFI_SYSTEM_TABLE_POINTER below PcdMaxEfiSystemTablePointerAddress failed. \\r
70 Retry to allocate memroy as close to the top of memory as feasible.\n"));\r
71 }\r
72 //\r
73 // If the initial memory allocation fails, then reattempt allocation\r
74 // as close to the top of memory as feasible.\r
75 //\r
76 Status = CoreAllocatePages (\r
d1102dba 77 AllocateAnyPages,\r
6eea8eae 78 EfiBootServicesData,\r
d1102dba 79 RealPages,\r
6eea8eae
LG
80 &Memory\r
81 );\r
82 ASSERT_EFI_ERROR (Status);\r
83 if (EFI_ERROR (Status)) {\r
84 return;\r
85 }\r
d1102dba 86 }\r
6eea8eae
LG
87\r
88 //\r
89 // Free overallocated pages\r
90 //\r
91 AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;\r
92 UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory);\r
93 if (UnalignedPages > 0) {\r
94 //\r
95 // Free first unaligned page(s).\r
96 //\r
97 Status = CoreFreePages (Memory, UnalignedPages);\r
98 ASSERT_EFI_ERROR (Status);\r
99 }\r
16f69227 100 Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages);\r
6eea8eae
LG
101 UnalignedPages = RealPages - Pages - UnalignedPages;\r
102 if (UnalignedPages > 0) {\r
103 //\r
104 // Free last unaligned page(s).\r
105 //\r
106 Status = CoreFreePages (Memory, UnalignedPages);\r
107 ASSERT_EFI_ERROR (Status);\r
108 }\r
109\r
110 //\r
111 // Set mDebugTable to the 4MB aligned allocated pages\r
112 //\r
113 mDebugTable = (EFI_SYSTEM_TABLE_POINTER *)(AlignedMemory);\r
b364eeb0 114 ASSERT (mDebugTable != NULL);\r
6eea8eae
LG
115\r
116 //\r
117 // Initialize EFI_SYSTEM_TABLE_POINTER structure\r
d1102dba 118 //\r
6eea8eae 119 mDebugTable->Signature = EFI_SYSTEM_TABLE_SIGNATURE;\r
28a00297 120 mDebugTable->EfiSystemTableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) gDxeCoreST;\r
6eea8eae 121 mDebugTable->Crc32 = 0;\r
d1102dba 122\r
6eea8eae 123 //\r
d1102dba 124 // Install the EFI_SYSTEM_TABLE_POINTER structure in the EFI System\r
6eea8eae
LG
125 // Configuration Table\r
126 //\r
28a00297 127 Status = CoreInstallConfigurationTable (&gEfiDebugImageInfoTableGuid, &mDebugInfoTableHeader);\r
128 ASSERT_EFI_ERROR (Status);\r
129}\r
130\r
28a00297 131\r
162ed594 132/**\r
28a00297 133 Update the CRC32 in the Debug Table.\r
134 Since the CRC32 service is made available by the Runtime driver, we have to\r
135 wait for the Runtime Driver to be installed before the CRC32 can be computed.\r
136 This function is called elsewhere by the core when the runtime architectural\r
137 protocol is produced.\r
138\r
162ed594 139**/\r
140VOID\r
141CoreUpdateDebugTableCrc32 (\r
142 VOID\r
143 )\r
28a00297 144{\r
145 ASSERT(mDebugTable != NULL);\r
146 mDebugTable->Crc32 = 0;\r
0e9b156d 147 gBS->CalculateCrc32 ((VOID *)mDebugTable, sizeof (EFI_SYSTEM_TABLE_POINTER), &mDebugTable->Crc32);\r
28a00297 148}\r
149\r
162ed594 150\r
151/**\r
152 Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates\r
153 the table if it's not large enough to accomidate another entry.\r
154\r
022c6d45 155 @param ImageInfoType type of debug image information\r
156 @param LoadedImage pointer to the loaded image protocol for the image being\r
157 loaded\r
162ed594 158 @param ImageHandle image handle for the image being loaded\r
159\r
160**/\r
28a00297 161VOID\r
162CoreNewDebugImageInfoEntry (\r
163 IN UINT32 ImageInfoType,\r
164 IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,\r
165 IN EFI_HANDLE ImageHandle\r
166 )\r
022c6d45 167{\r
28a00297 168 EFI_DEBUG_IMAGE_INFO *Table;\r
169 EFI_DEBUG_IMAGE_INFO *NewTable;\r
170 UINTN Index;\r
28a00297 171 UINTN TableSize;\r
172\r
173 //\r
174 // Set the flag indicating that we're in the process of updating the table.\r
175 //\r
176 mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;\r
177\r
178 Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;\r
d1102dba 179\r
2f2a277d 180 if (mDebugInfoTableHeader.TableSize < mMaxTableEntries) {\r
181 //\r
182 // We still have empty entires in the Table, find the first empty entry.\r
183 //\r
184 Index = 0;\r
185 while (Table[Index].NormalImage != NULL) {\r
186 Index++;\r
28a00297 187 }\r
2f2a277d 188 //\r
189 // There must be an empty entry in the in the table.\r
190 //\r
191 ASSERT (Index < mMaxTableEntries);\r
192 } else {\r
28a00297 193 //\r
194 // Table is full, so re-allocate another page for a larger table...\r
195 //\r
2f2a277d 196 TableSize = mMaxTableEntries * EFI_DEBUG_TABLE_ENTRY_SIZE;\r
9c4ac31c 197 NewTable = AllocateZeroPool (TableSize + EFI_PAGE_SIZE);\r
28a00297 198 if (NewTable == NULL) {\r
199 mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;\r
200 return;\r
201 }\r
202 //\r
203 // Copy the old table into the new one\r
204 //\r
205 CopyMem (NewTable, Table, TableSize);\r
206 //\r
207 // Free the old table\r
208 //\r
209 CoreFreePool (Table);\r
210 //\r
211 // Update the table header\r
212 //\r
213 Table = NewTable;\r
214 mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable;\r
2f2a277d 215 //\r
216 // Enlarge the max table entries and set the first empty entry index to\r
217 // be the original max table entries.\r
218 //\r
219 Index = mMaxTableEntries;\r
220 mMaxTableEntries += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;\r
28a00297 221 }\r
2f2a277d 222\r
28a00297 223 //\r
224 // Allocate data for new entry\r
225 //\r
9c4ac31c 226 Table[Index].NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL));\r
28a00297 227 if (Table[Index].NormalImage != NULL) {\r
228 //\r
229 // Update the entry\r
230 //\r
231 Table[Index].NormalImage->ImageInfoType = (UINT32) ImageInfoType;\r
232 Table[Index].NormalImage->LoadedImageProtocolInstance = LoadedImage;\r
233 Table[Index].NormalImage->ImageHandle = ImageHandle;\r
2f2a277d 234 //\r
235 // Increase the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status.\r
236 //\r
237 mDebugInfoTableHeader.TableSize++;\r
238 mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;\r
28a00297 239 }\r
240 mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;\r
241}\r
242\r
243\r
28a00297 244\r
162ed594 245/**\r
28a00297 246 Removes and frees an entry from the DebugImageInfo Table.\r
247\r
162ed594 248 @param ImageHandle image handle for the image being unloaded\r
28a00297 249\r
162ed594 250**/\r
251VOID\r
252CoreRemoveDebugImageInfoEntry (\r
253 EFI_HANDLE ImageHandle\r
254 )\r
022c6d45 255{\r
28a00297 256 EFI_DEBUG_IMAGE_INFO *Table;\r
257 UINTN Index;\r
258\r
259 mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;\r
260\r
261 Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;\r
262\r
2f2a277d 263 for (Index = 0; Index < mMaxTableEntries; Index++) {\r
28a00297 264 if (Table[Index].NormalImage != NULL && Table[Index].NormalImage->ImageHandle == ImageHandle) {\r
265 //\r
266 // Found a match. Free up the record, then NULL the pointer to indicate the slot\r
267 // is free.\r
268 //\r
269 CoreFreePool (Table[Index].NormalImage);\r
270 Table[Index].NormalImage = NULL;\r
2f2a277d 271 //\r
272 // Decrease the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status.\r
273 //\r
274 mDebugInfoTableHeader.TableSize--;\r
275 mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;\r
28a00297 276 break;\r
277 }\r
278 }\r
279 mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;\r
280}\r
281\r
162ed594 282\r