]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Application/VariableInfo/VariableInfo.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Application / VariableInfo / VariableInfo.c
... / ...
CommitLineData
1/** @file\r
2 If the Variable services have PcdVariableCollectStatistics set to TRUE then\r
3 this utility will print out the statistics information. You can use console\r
4 redirection to capture the data.\r
5\r
6 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
8\r
9**/\r
10\r
11#include <Uefi.h>\r
12#include <Library/UefiLib.h>\r
13#include <Library/UefiApplicationEntryPoint.h>\r
14#include <Library/BaseMemoryLib.h>\r
15#include <Library/BaseLib.h>\r
16#include <Library/MemoryAllocationLib.h>\r
17#include <Library/DebugLib.h>\r
18#include <Library/UefiBootServicesTableLib.h>\r
19\r
20#include <Guid/VariableFormat.h>\r
21#include <Guid/SmmVariableCommon.h>\r
22#include <Guid/PiSmmCommunicationRegionTable.h>\r
23#include <Protocol/MmCommunication2.h>\r
24#include <Protocol/SmmVariable.h>\r
25\r
26EFI_MM_COMMUNICATION2_PROTOCOL *mMmCommunication2 = NULL;\r
27\r
28/**\r
29 This function get the variable statistics data from SMM variable driver.\r
30\r
31 @param[in, out] SmmCommunicateHeader In input, a pointer to a collection of data that will\r
32 be passed into an SMM environment. In output, a pointer\r
33 to a collection of data that comes from an SMM environment.\r
34 @param[in, out] SmmCommunicateSize The size of the SmmCommunicateHeader.\r
35\r
36 @retval EFI_SUCCESS Get the statistics data information.\r
37 @retval EFI_NOT_FOUND Not found.\r
38 @retval EFI_BUFFER_TO_SMALL DataSize is too small for the result.\r
39\r
40**/\r
41EFI_STATUS\r
42EFIAPI\r
43GetVariableStatisticsData (\r
44 IN OUT EFI_MM_COMMUNICATE_HEADER *SmmCommunicateHeader,\r
45 IN OUT UINTN *SmmCommunicateSize\r
46 )\r
47{\r
48 EFI_STATUS Status;\r
49 SMM_VARIABLE_COMMUNICATE_HEADER *SmmVariableFunctionHeader;\r
50\r
51 CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmVariableProtocolGuid);\r
52 SmmCommunicateHeader->MessageLength = *SmmCommunicateSize - OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);\r
53\r
54 SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *)&SmmCommunicateHeader->Data[0];\r
55 SmmVariableFunctionHeader->Function = SMM_VARIABLE_FUNCTION_GET_STATISTICS;\r
56\r
57 Status = mMmCommunication2->Communicate (\r
58 mMmCommunication2,\r
59 SmmCommunicateHeader,\r
60 SmmCommunicateHeader,\r
61 SmmCommunicateSize\r
62 );\r
63 ASSERT_EFI_ERROR (Status);\r
64\r
65 Status = SmmVariableFunctionHeader->ReturnStatus;\r
66 return Status;\r
67}\r
68\r
69/**\r
70\r
71 This function get and print the variable statistics data from SMM variable driver.\r
72\r
73 @retval EFI_SUCCESS Print the statistics information successfully.\r
74 @retval EFI_NOT_FOUND Not found the statistics information.\r
75\r
76**/\r
77EFI_STATUS\r
78PrintInfoFromSmm (\r
79 VOID\r
80 )\r
81{\r
82 EFI_STATUS Status;\r
83 VARIABLE_INFO_ENTRY *VariableInfo;\r
84 EFI_MM_COMMUNICATE_HEADER *CommBuffer;\r
85 UINTN RealCommSize;\r
86 UINTN CommSize;\r
87 SMM_VARIABLE_COMMUNICATE_HEADER *FunctionHeader;\r
88 EFI_SMM_VARIABLE_PROTOCOL *Smmvariable;\r
89 EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable;\r
90 UINT32 Index;\r
91 EFI_MEMORY_DESCRIPTOR *Entry;\r
92 UINTN Size;\r
93 UINTN MaxSize;\r
94\r
95 Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **)&Smmvariable);\r
96 if (EFI_ERROR (Status)) {\r
97 return Status;\r
98 }\r
99\r
100 Status = gBS->LocateProtocol (&gEfiMmCommunication2ProtocolGuid, NULL, (VOID **)&mMmCommunication2);\r
101 if (EFI_ERROR (Status)) {\r
102 return Status;\r
103 }\r
104\r
105 CommBuffer = NULL;\r
106 RealCommSize = 0;\r
107 Status = EfiGetSystemConfigurationTable (\r
108 &gEdkiiPiSmmCommunicationRegionTableGuid,\r
109 (VOID **)&PiSmmCommunicationRegionTable\r
110 );\r
111 if (EFI_ERROR (Status)) {\r
112 return Status;\r
113 }\r
114\r
115 ASSERT (PiSmmCommunicationRegionTable != NULL);\r
116 Entry = (EFI_MEMORY_DESCRIPTOR *)(PiSmmCommunicationRegionTable + 1);\r
117 Size = 0;\r
118 MaxSize = 0;\r
119 for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {\r
120 if (Entry->Type == EfiConventionalMemory) {\r
121 Size = EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages);\r
122 if (Size > (SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + sizeof (VARIABLE_INFO_ENTRY))) {\r
123 if (Size > MaxSize) {\r
124 MaxSize = Size;\r
125 RealCommSize = MaxSize;\r
126 CommBuffer = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)Entry->PhysicalStart;\r
127 }\r
128 }\r
129 }\r
130\r
131 Entry = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Entry + PiSmmCommunicationRegionTable->DescriptorSize);\r
132 }\r
133\r
134 ASSERT (CommBuffer != NULL);\r
135 ZeroMem (CommBuffer, RealCommSize);\r
136\r
137 Print (L"SMM Driver Non-Volatile Variables:\n");\r
138 do {\r
139 CommSize = RealCommSize;\r
140 Status = GetVariableStatisticsData (CommBuffer, &CommSize);\r
141 if (Status == EFI_BUFFER_TOO_SMALL) {\r
142 Print (L"The generic SMM communication buffer provided by SmmCommunicationRegionTable is too small\n");\r
143 return Status;\r
144 }\r
145\r
146 if (EFI_ERROR (Status) || (CommSize <= SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)) {\r
147 break;\r
148 }\r
149\r
150 FunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *)CommBuffer->Data;\r
151 VariableInfo = (VARIABLE_INFO_ENTRY *)FunctionHeader->Data;\r
152\r
153 if (!VariableInfo->Volatile) {\r
154 Print (\r
155 L"%g R%03d(%03d) W%03d D%03d:%s\n",\r
156 &VariableInfo->VendorGuid,\r
157 VariableInfo->ReadCount,\r
158 VariableInfo->CacheCount,\r
159 VariableInfo->WriteCount,\r
160 VariableInfo->DeleteCount,\r
161 (CHAR16 *)(VariableInfo + 1)\r
162 );\r
163 }\r
164 } while (TRUE);\r
165\r
166 Print (L"SMM Driver Volatile Variables:\n");\r
167 ZeroMem (CommBuffer, RealCommSize);\r
168 do {\r
169 CommSize = RealCommSize;\r
170 Status = GetVariableStatisticsData (CommBuffer, &CommSize);\r
171 if (Status == EFI_BUFFER_TOO_SMALL) {\r
172 Print (L"The generic SMM communication buffer provided by SmmCommunicationRegionTable is too small\n");\r
173 return Status;\r
174 }\r
175\r
176 if (EFI_ERROR (Status) || (CommSize <= SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)) {\r
177 break;\r
178 }\r
179\r
180 FunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *)CommBuffer->Data;\r
181 VariableInfo = (VARIABLE_INFO_ENTRY *)FunctionHeader->Data;\r
182\r
183 if (VariableInfo->Volatile) {\r
184 Print (\r
185 L"%g R%03d(%03d) W%03d D%03d:%s\n",\r
186 &VariableInfo->VendorGuid,\r
187 VariableInfo->ReadCount,\r
188 VariableInfo->CacheCount,\r
189 VariableInfo->WriteCount,\r
190 VariableInfo->DeleteCount,\r
191 (CHAR16 *)(VariableInfo + 1)\r
192 );\r
193 }\r
194 } while (TRUE);\r
195\r
196 return Status;\r
197}\r
198\r
199/**\r
200 The user Entry Point for Application. The user code starts with this function\r
201 as the real entry point for the image goes into a library that calls this\r
202 function.\r
203\r
204 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
205 @param[in] SystemTable A pointer to the EFI System Table.\r
206\r
207 @retval EFI_SUCCESS The entry point is executed successfully.\r
208 @retval other Some error occurs when executing this entry point.\r
209\r
210**/\r
211EFI_STATUS\r
212EFIAPI\r
213UefiMain (\r
214 IN EFI_HANDLE ImageHandle,\r
215 IN EFI_SYSTEM_TABLE *SystemTable\r
216 )\r
217{\r
218 EFI_STATUS RuntimeDxeStatus;\r
219 EFI_STATUS SmmStatus;\r
220 VARIABLE_INFO_ENTRY *VariableInfo;\r
221 VARIABLE_INFO_ENTRY *Entry;\r
222\r
223 RuntimeDxeStatus = EfiGetSystemConfigurationTable (&gEfiVariableGuid, (VOID **)&Entry);\r
224 if (EFI_ERROR (RuntimeDxeStatus) || (Entry == NULL)) {\r
225 RuntimeDxeStatus = EfiGetSystemConfigurationTable (&gEfiAuthenticatedVariableGuid, (VOID **)&Entry);\r
226 }\r
227\r
228 if (!EFI_ERROR (RuntimeDxeStatus) && (Entry != NULL)) {\r
229 Print (L"Runtime DXE Driver Non-Volatile EFI Variables:\n");\r
230 VariableInfo = Entry;\r
231 do {\r
232 if (!VariableInfo->Volatile) {\r
233 Print (\r
234 L"%g R%03d(%03d) W%03d D%03d:%s\n",\r
235 &VariableInfo->VendorGuid,\r
236 VariableInfo->ReadCount,\r
237 VariableInfo->CacheCount,\r
238 VariableInfo->WriteCount,\r
239 VariableInfo->DeleteCount,\r
240 VariableInfo->Name\r
241 );\r
242 }\r
243\r
244 VariableInfo = VariableInfo->Next;\r
245 } while (VariableInfo != NULL);\r
246\r
247 Print (L"Runtime DXE Driver Volatile EFI Variables:\n");\r
248 VariableInfo = Entry;\r
249 do {\r
250 if (VariableInfo->Volatile) {\r
251 Print (\r
252 L"%g R%03d(%03d) W%03d D%03d:%s\n",\r
253 &VariableInfo->VendorGuid,\r
254 VariableInfo->ReadCount,\r
255 VariableInfo->CacheCount,\r
256 VariableInfo->WriteCount,\r
257 VariableInfo->DeleteCount,\r
258 VariableInfo->Name\r
259 );\r
260 }\r
261\r
262 VariableInfo = VariableInfo->Next;\r
263 } while (VariableInfo != NULL);\r
264 }\r
265\r
266 SmmStatus = PrintInfoFromSmm ();\r
267\r
268 if (EFI_ERROR (RuntimeDxeStatus) && EFI_ERROR (SmmStatus)) {\r
269 Print (L"Warning: Variable Dxe/Smm driver doesn't enable the feature of statistical information!\n");\r
270 Print (L"If you want to see this info, please:\n");\r
271 Print (L" 1. Set PcdVariableCollectStatistics as TRUE\n");\r
272 Print (L" 2. Rebuild Variable Dxe/Smm driver\n");\r
273 Print (L" 3. Run \"VariableInfo\" cmd again\n");\r
274\r
275 return EFI_NOT_FOUND;\r
276 }\r
277\r
278 return EFI_SUCCESS;\r
279}\r