TianoCore EDK2 master
Loading...
Searching...
No Matches
DebugImageInfo.c
Go to the documentation of this file.
1
10#include "DxeMain.h"
11
12EFI_DEBUG_IMAGE_INFO_TABLE_HEADER mDebugInfoTableHeader = {
13 0, // volatile UINT32 UpdateStatus;
14 0, // UINT32 TableSize;
15 NULL // EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable;
16};
17
18UINTN mMaxTableEntries = 0;
19
20EFI_SYSTEM_TABLE_POINTER *mDebugTable = NULL;
21
22#define EFI_DEBUG_TABLE_ENTRY_SIZE (sizeof (VOID *))
23
29VOID
31 VOID
32 )
33{
34 EFI_STATUS Status;
35 UINTN Pages;
37 UINTN AlignedMemory;
38 UINTN AlignmentMask;
39 UINTN UnalignedPages;
40 UINTN RealPages;
41
42 //
43 // Allocate 4M aligned page for the structure and fill in the data.
44 // Ideally we would update the CRC now as well, but the service may not yet be available.
45 // See comments in the CoreUpdateDebugTableCrc32() function below for details.
46 //
48 AlignmentMask = SIZE_4MB - 1;
49 RealPages = Pages + EFI_SIZE_TO_PAGES (SIZE_4MB);
50
51 //
52 // Attempt to allocate memory below PcdMaxEfiSystemTablePointerAddress
53 // If PcdMaxEfiSystemTablePointerAddress is 0, then allocate memory below
54 // MAX_ADDRESS
55 //
56 Memory = PcdGet64 (PcdMaxEfiSystemTablePointerAddress);
57 if (Memory == 0) {
58 Memory = MAX_ADDRESS;
59 }
60
61 Status = CoreAllocatePages (
64 RealPages,
65 &Memory
66 );
67 if (EFI_ERROR (Status)) {
68 if (PcdGet64 (PcdMaxEfiSystemTablePointerAddress) != 0) {
69 DEBUG ((DEBUG_INFO, "Allocate memory for EFI_SYSTEM_TABLE_POINTER below PcdMaxEfiSystemTablePointerAddress failed. \
70 Retry to allocate memroy as close to the top of memory as feasible.\n"));
71 }
72
73 //
74 // If the initial memory allocation fails, then reattempt allocation
75 // as close to the top of memory as feasible.
76 //
77 Status = CoreAllocatePages (
80 RealPages,
81 &Memory
82 );
83 ASSERT_EFI_ERROR (Status);
84 if (EFI_ERROR (Status)) {
85 return;
86 }
87 }
88
89 //
90 // Free overallocated pages
91 //
92 AlignedMemory = ((UINTN)Memory + AlignmentMask) & ~AlignmentMask;
93 UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN)Memory);
94 if (UnalignedPages > 0) {
95 //
96 // Free first unaligned page(s).
97 //
98 Status = CoreFreePages (Memory, UnalignedPages);
99 ASSERT_EFI_ERROR (Status);
100 }
101
102 Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages);
103 UnalignedPages = RealPages - Pages - UnalignedPages;
104 if (UnalignedPages > 0) {
105 //
106 // Free last unaligned page(s).
107 //
108 Status = CoreFreePages (Memory, UnalignedPages);
109 ASSERT_EFI_ERROR (Status);
110 }
111
112 //
113 // Set mDebugTable to the 4MB aligned allocated pages
114 //
115 mDebugTable = (EFI_SYSTEM_TABLE_POINTER *)(AlignedMemory);
116 ASSERT (mDebugTable != NULL);
117
118 //
119 // Initialize EFI_SYSTEM_TABLE_POINTER structure
120 //
121 mDebugTable->Signature = EFI_SYSTEM_TABLE_SIGNATURE;
122 mDebugTable->EfiSystemTableBase = (EFI_PHYSICAL_ADDRESS)(UINTN)gDxeCoreST;
123 mDebugTable->Crc32 = 0;
124
125 //
126 // Install the EFI_SYSTEM_TABLE_POINTER structure in the EFI System
127 // Configuration Table
128 //
129 Status = CoreInstallConfigurationTable (&gEfiDebugImageInfoTableGuid, &mDebugInfoTableHeader);
130 ASSERT_EFI_ERROR (Status);
131}
132
141VOID
143 VOID
144 )
145{
146 ASSERT (mDebugTable != NULL);
147 mDebugTable->Crc32 = 0;
148 gBS->CalculateCrc32 ((VOID *)mDebugTable, sizeof (EFI_SYSTEM_TABLE_POINTER), &mDebugTable->Crc32);
149}
150
161VOID
163 IN UINT32 ImageInfoType,
164 IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
165 IN EFI_HANDLE ImageHandle
166 )
167{
169 EFI_DEBUG_IMAGE_INFO *NewTable;
170 UINTN Index;
171 UINTN TableSize;
172
173 //
174 // Set the flag indicating that we're in the process of updating the table.
175 //
176 mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
177
178 Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;
179
180 if (mDebugInfoTableHeader.TableSize < mMaxTableEntries) {
181 //
182 // We still have empty entires in the Table, find the first empty entry.
183 //
184 Index = 0;
185 while (Table[Index].NormalImage != NULL) {
186 Index++;
187 }
188
189 //
190 // There must be an empty entry in the in the table.
191 //
192 ASSERT (Index < mMaxTableEntries);
193 } else {
194 //
195 // Table is full, so re-allocate another page for a larger table...
196 //
197 TableSize = mMaxTableEntries * EFI_DEBUG_TABLE_ENTRY_SIZE;
198 NewTable = AllocateZeroPool (TableSize + EFI_PAGE_SIZE);
199 if (NewTable == NULL) {
200 mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
201 return;
202 }
203
204 //
205 // Copy the old table into the new one
206 //
207 CopyMem (NewTable, Table, TableSize);
208 //
209 // Free the old table
210 //
211 CoreFreePool (Table);
212 //
213 // Update the table header
214 //
215 Table = NewTable;
216 mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable;
217 //
218 // Enlarge the max table entries and set the first empty entry index to
219 // be the original max table entries.
220 //
221 Index = mMaxTableEntries;
222 mMaxTableEntries += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;
223 }
224
225 //
226 // Allocate data for new entry
227 //
228 Table[Index].NormalImage = AllocateZeroPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL));
229 if (Table[Index].NormalImage != NULL) {
230 //
231 // Update the entry
232 //
233 Table[Index].NormalImage->ImageInfoType = (UINT32)ImageInfoType;
234 Table[Index].NormalImage->LoadedImageProtocolInstance = LoadedImage;
235 Table[Index].NormalImage->ImageHandle = ImageHandle;
236 //
237 // Increase the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status.
238 //
239 mDebugInfoTableHeader.TableSize++;
240 mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;
241 }
242
243 mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
244}
245
252VOID
254 EFI_HANDLE ImageHandle
255 )
256{
258 UINTN Index;
259
260 mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
261
262 Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;
263
264 for (Index = 0; Index < mMaxTableEntries; Index++) {
265 if ((Table[Index].NormalImage != NULL) && (Table[Index].NormalImage->ImageHandle == ImageHandle)) {
266 //
267 // Found a match. Free up the record, then NULL the pointer to indicate the slot
268 // is free.
269 //
270 CoreFreePool (Table[Index].NormalImage);
271 Table[Index].NormalImage = NULL;
272 //
273 // Decrease the number of EFI_DEBUG_IMAGE_INFO elements and set the mDebugInfoTable in modified status.
274 //
275 mDebugInfoTableHeader.TableSize--;
276 mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED;
277 break;
278 }
279 }
280
281 mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
282}
UINT64 UINTN
#define MAX_ADDRESS
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID CoreNewDebugImageInfoEntry(IN UINT32 ImageInfoType, IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage, IN EFI_HANDLE ImageHandle)
VOID CoreInitializeDebugImageInfoTable(VOID)
VOID CoreUpdateDebugTableCrc32(VOID)
VOID CoreRemoveDebugImageInfoEntry(EFI_HANDLE ImageHandle)
EFI_STATUS EFIAPI CoreAllocatePages(IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN NumberOfPages, IN OUT EFI_PHYSICAL_ADDRESS *Memory)
EFI_STATUS EFIAPI CoreInstallConfigurationTable(IN EFI_GUID *Guid, IN VOID *Table)
EFI_STATUS EFIAPI CoreFreePages(IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN NumberOfPages)
Definition: Page.c:1737
EFI_STATUS EFIAPI CoreFreePool(IN VOID *Buffer)
Definition: Pool.c:591
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
#define NULL
Definition: Base.h:319
#define IN
Definition: Base.h:279
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
EFI_BOOT_SERVICES * gBS
@ EfiBootServicesData
@ AllocateMaxAddress
Definition: UefiSpec.h:38
@ AllocateAnyPages
Definition: UefiSpec.h:33
EFI_LOADED_IMAGE_PROTOCOL * LoadedImageProtocolInstance
EFI_DEBUG_IMAGE_INFO * EfiDebugImageInfoTable
UINT32 Crc32
A 32-bit CRC value that is used to verify the EFI_SYSTEM_TABLE_POINTER structure is valid.
UINT64 Signature
A constant UINT64 that has the value EFI_SYSTEM_TABLE_SIGNATURE.
EFI_PHYSICAL_ADDRESS EfiSystemTableBase
The physical address of the EFI system table.