]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Application/VariableInfo/VariableInfo.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Application / VariableInfo / VariableInfo.c
CommitLineData
33a5a666 1/** @file\r
627e117a
SZ
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
1747ab6c 6 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>\r
9d510e61 7 SPDX-License-Identifier: BSD-2-Clause-Patent\r
33a5a666
A
8\r
9**/\r
10\r
11#include <Uefi.h>\r
33a5a666
A
12#include <Library/UefiLib.h>\r
13#include <Library/UefiApplicationEntryPoint.h>\r
627e117a
SZ
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
3709c4cd 20#include <Guid/VariableFormat.h>\r
627e117a 21#include <Guid/SmmVariableCommon.h>\r
faf3de9b 22#include <Guid/PiSmmCommunicationRegionTable.h>\r
789ea79e 23#include <Protocol/MmCommunication2.h>\r
627e117a
SZ
24#include <Protocol/SmmVariable.h>\r
25\r
789ea79e 26EFI_MM_COMMUNICATION2_PROTOCOL *mMmCommunication2 = NULL;\r
627e117a
SZ
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
1436aea4
MK
44 IN OUT EFI_MM_COMMUNICATE_HEADER *SmmCommunicateHeader,\r
45 IN OUT UINTN *SmmCommunicateSize\r
627e117a
SZ
46 )\r
47{\r
1436aea4
MK
48 EFI_STATUS Status;\r
49 SMM_VARIABLE_COMMUNICATE_HEADER *SmmVariableFunctionHeader;\r
627e117a
SZ
50\r
51 CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmVariableProtocolGuid);\r
789ea79e 52 SmmCommunicateHeader->MessageLength = *SmmCommunicateSize - OFFSET_OF (EFI_MM_COMMUNICATE_HEADER, Data);\r
627e117a 53\r
1436aea4 54 SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *)&SmmCommunicateHeader->Data[0];\r
627e117a 55 SmmVariableFunctionHeader->Function = SMM_VARIABLE_FUNCTION_GET_STATISTICS;\r
33a5a666 56\r
1436aea4
MK
57 Status = mMmCommunication2->Communicate (\r
58 mMmCommunication2,\r
59 SmmCommunicateHeader,\r
60 SmmCommunicateHeader,\r
61 SmmCommunicateSize\r
62 );\r
627e117a
SZ
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
1436aea4
MK
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
627e117a
SZ
96 if (EFI_ERROR (Status)) {\r
97 return Status;\r
98 }\r
99\r
1436aea4 100 Status = gBS->LocateProtocol (&gEfiMmCommunication2ProtocolGuid, NULL, (VOID **)&mMmCommunication2);\r
627e117a
SZ
101 if (EFI_ERROR (Status)) {\r
102 return Status;\r
103 }\r
104\r
1436aea4 105 CommBuffer = NULL;\r
05b39efb 106 RealCommSize = 0;\r
1436aea4
MK
107 Status = EfiGetSystemConfigurationTable (\r
108 &gEdkiiPiSmmCommunicationRegionTableGuid,\r
109 (VOID **)&PiSmmCommunicationRegionTable\r
110 );\r
faf3de9b
SZ
111 if (EFI_ERROR (Status)) {\r
112 return Status;\r
113 }\r
1436aea4 114\r
faf3de9b 115 ASSERT (PiSmmCommunicationRegionTable != NULL);\r
1436aea4
MK
116 Entry = (EFI_MEMORY_DESCRIPTOR *)(PiSmmCommunicationRegionTable + 1);\r
117 Size = 0;\r
faf3de9b
SZ
118 MaxSize = 0;\r
119 for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {\r
120 if (Entry->Type == EfiConventionalMemory) {\r
1436aea4 121 Size = EFI_PAGES_TO_SIZE ((UINTN)Entry->NumberOfPages);\r
faf3de9b
SZ
122 if (Size > (SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + sizeof (VARIABLE_INFO_ENTRY))) {\r
123 if (Size > MaxSize) {\r
1436aea4 124 MaxSize = Size;\r
faf3de9b 125 RealCommSize = MaxSize;\r
1436aea4 126 CommBuffer = (EFI_MM_COMMUNICATE_HEADER *)(UINTN)Entry->PhysicalStart;\r
faf3de9b
SZ
127 }\r
128 }\r
129 }\r
1436aea4
MK
130\r
131 Entry = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)Entry + PiSmmCommunicationRegionTable->DescriptorSize);\r
faf3de9b 132 }\r
1436aea4 133\r
627e117a 134 ASSERT (CommBuffer != NULL);\r
faf3de9b 135 ZeroMem (CommBuffer, RealCommSize);\r
627e117a 136\r
1747ab6c 137 Print (L"SMM Driver Non-Volatile Variables:\n");\r
627e117a 138 do {\r
faf3de9b 139 CommSize = RealCommSize;\r
1436aea4 140 Status = GetVariableStatisticsData (CommBuffer, &CommSize);\r
627e117a 141 if (Status == EFI_BUFFER_TOO_SMALL) {\r
faf3de9b
SZ
142 Print (L"The generic SMM communication buffer provided by SmmCommunicationRegionTable is too small\n");\r
143 return Status;\r
627e117a
SZ
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
1436aea4
MK
150 FunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *)CommBuffer->Data;\r
151 VariableInfo = (VARIABLE_INFO_ENTRY *)FunctionHeader->Data;\r
627e117a
SZ
152\r
153 if (!VariableInfo->Volatile) {\r
154 Print (\r
1436aea4
MK
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
627e117a
SZ
163 }\r
164 } while (TRUE);\r
165\r
1747ab6c 166 Print (L"SMM Driver Volatile Variables:\n");\r
faf3de9b 167 ZeroMem (CommBuffer, RealCommSize);\r
627e117a 168 do {\r
faf3de9b 169 CommSize = RealCommSize;\r
1436aea4 170 Status = GetVariableStatisticsData (CommBuffer, &CommSize);\r
627e117a 171 if (Status == EFI_BUFFER_TOO_SMALL) {\r
faf3de9b
SZ
172 Print (L"The generic SMM communication buffer provided by SmmCommunicationRegionTable is too small\n");\r
173 return Status;\r
627e117a
SZ
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
1436aea4
MK
180 FunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *)CommBuffer->Data;\r
181 VariableInfo = (VARIABLE_INFO_ENTRY *)FunctionHeader->Data;\r
627e117a
SZ
182\r
183 if (VariableInfo->Volatile) {\r
184 Print (\r
1436aea4
MK
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
627e117a
SZ
193 }\r
194 } while (TRUE);\r
195\r
627e117a
SZ
196 return Status;\r
197}\r
33a5a666
A
198\r
199/**\r
200 The user Entry Point for Application. The user code starts with this function\r
627e117a 201 as the real entry point for the image goes into a library that calls this\r
33a5a666
A
202 function.\r
203\r
627e117a 204 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
33a5a666 205 @param[in] SystemTable A pointer to the EFI System Table.\r
627e117a 206\r
33a5a666
A
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
1436aea4
MK
218 EFI_STATUS RuntimeDxeStatus;\r
219 EFI_STATUS SmmStatus;\r
220 VARIABLE_INFO_ENTRY *VariableInfo;\r
221 VARIABLE_INFO_ENTRY *Entry;\r
33a5a666 222\r
1436aea4 223 RuntimeDxeStatus = EfiGetSystemConfigurationTable (&gEfiVariableGuid, (VOID **)&Entry);\r
1747ab6c 224 if (EFI_ERROR (RuntimeDxeStatus) || (Entry == NULL)) {\r
1436aea4 225 RuntimeDxeStatus = EfiGetSystemConfigurationTable (&gEfiAuthenticatedVariableGuid, (VOID **)&Entry);\r
627e117a
SZ
226 }\r
227\r
1747ab6c
MK
228 if (!EFI_ERROR (RuntimeDxeStatus) && (Entry != NULL)) {\r
229 Print (L"Runtime DXE Driver Non-Volatile EFI Variables:\n");\r
33a5a666
A
230 VariableInfo = Entry;\r
231 do {\r
232 if (!VariableInfo->Volatile) {\r
233 Print (\r
627e117a
SZ
234 L"%g R%03d(%03d) W%03d D%03d:%s\n",\r
235 &VariableInfo->VendorGuid,\r
33a5a666
A
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
1747ab6c 247 Print (L"Runtime DXE Driver Volatile EFI Variables:\n");\r
33a5a666
A
248 VariableInfo = Entry;\r
249 do {\r
250 if (VariableInfo->Volatile) {\r
251 Print (\r
627e117a
SZ
252 L"%g R%03d(%03d) W%03d D%03d:%s\n",\r
253 &VariableInfo->VendorGuid,\r
33a5a666
A
254 VariableInfo->ReadCount,\r
255 VariableInfo->CacheCount,\r
256 VariableInfo->WriteCount,\r
257 VariableInfo->DeleteCount,\r
258 VariableInfo->Name\r
259 );\r
260 }\r
1436aea4 261\r
33a5a666
A
262 VariableInfo = VariableInfo->Next;\r
263 } while (VariableInfo != NULL);\r
1747ab6c
MK
264 }\r
265\r
266 SmmStatus = PrintInfoFromSmm ();\r
33a5a666 267\r
1747ab6c 268 if (EFI_ERROR (RuntimeDxeStatus) && EFI_ERROR (SmmStatus)) {\r
faf3de9b 269 Print (L"Warning: Variable Dxe/Smm driver doesn't enable the feature of statistical information!\n");\r
5e895e6a 270 Print (L"If you want to see this info, please:\n");\r
271 Print (L" 1. Set PcdVariableCollectStatistics as TRUE\n");\r
faf3de9b 272 Print (L" 2. Rebuild Variable Dxe/Smm driver\n");\r
5e895e6a 273 Print (L" 3. Run \"VariableInfo\" cmd again\n");\r
1747ab6c
MK
274\r
275 return EFI_NOT_FOUND;\r
33a5a666
A
276 }\r
277\r
1747ab6c 278 return EFI_SUCCESS;\r
33a5a666 279}\r