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