]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdeModulePkg/Application/VariableInfo/VariableInfo.c
IntelSiliconPkg: Replace BSD License with BSD+Patent License
[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 - 2016, Intel Corporation. All rights reserved.<BR>\r
7 This program and the accompanying materials\r
8 are licensed and made available under the terms and conditions of the BSD License\r
9 which accompanies this distribution. The full text of the license may be found at\r
10 http://opensource.org/licenses/bsd-license.php\r
11\r
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
14\r
15**/\r
16\r
17#include <Uefi.h>\r
18#include <Library/UefiLib.h>\r
19#include <Library/UefiApplicationEntryPoint.h>\r
20#include <Library/BaseMemoryLib.h>\r
21#include <Library/BaseLib.h>\r
22#include <Library/MemoryAllocationLib.h>\r
23#include <Library/DebugLib.h>\r
24#include <Library/UefiBootServicesTableLib.h>\r
25\r
26#include <Guid/VariableFormat.h>\r
27#include <Guid/SmmVariableCommon.h>\r
28#include <Guid/PiSmmCommunicationRegionTable.h>\r
29#include <Protocol/SmmCommunication.h>\r
30#include <Protocol/SmmVariable.h>\r
31\r
32EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL;\r
33\r
34/**\r
35 This function get the variable statistics data from SMM variable driver.\r
36\r
37 @param[in, out] SmmCommunicateHeader In input, a pointer to a collection of data that will\r
38 be passed into an SMM environment. In output, a pointer\r
39 to a collection of data that comes from an SMM environment.\r
40 @param[in, out] SmmCommunicateSize The size of the SmmCommunicateHeader.\r
41\r
42 @retval EFI_SUCCESS Get the statistics data information.\r
43 @retval EFI_NOT_FOUND Not found.\r
44 @retval EFI_BUFFER_TO_SMALL DataSize is too small for the result.\r
45\r
46**/\r
47EFI_STATUS\r
48EFIAPI\r
49GetVariableStatisticsData (\r
50 IN OUT EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader,\r
51 IN OUT UINTN *SmmCommunicateSize\r
52 )\r
53{\r
54 EFI_STATUS Status;\r
55 SMM_VARIABLE_COMMUNICATE_HEADER *SmmVariableFunctionHeader;\r
56\r
57 CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmVariableProtocolGuid);\r
58 SmmCommunicateHeader->MessageLength = *SmmCommunicateSize - OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);\r
59\r
60 SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) &SmmCommunicateHeader->Data[0];\r
61 SmmVariableFunctionHeader->Function = SMM_VARIABLE_FUNCTION_GET_STATISTICS;\r
62\r
63 Status = mSmmCommunication->Communicate (mSmmCommunication, SmmCommunicateHeader, SmmCommunicateSize);\r
64 ASSERT_EFI_ERROR (Status);\r
65\r
66 Status = SmmVariableFunctionHeader->ReturnStatus;\r
67 return Status;\r
68}\r
69\r
70/**\r
71\r
72 This function get and print the variable statistics data from SMM variable driver.\r
73\r
74 @retval EFI_SUCCESS Print the statistics information successfully.\r
75 @retval EFI_NOT_FOUND Not found the statistics information.\r
76\r
77**/\r
78EFI_STATUS\r
79PrintInfoFromSmm (\r
80 VOID\r
81 )\r
82{\r
83 EFI_STATUS Status;\r
84 VARIABLE_INFO_ENTRY *VariableInfo;\r
85 EFI_SMM_COMMUNICATE_HEADER *CommBuffer;\r
86 UINTN RealCommSize;\r
87 UINTN CommSize;\r
88 SMM_VARIABLE_COMMUNICATE_HEADER *FunctionHeader;\r
89 EFI_SMM_VARIABLE_PROTOCOL *Smmvariable;\r
90 EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable;\r
91 UINT32 Index;\r
92 EFI_MEMORY_DESCRIPTOR *Entry;\r
93 UINTN Size;\r
94 UINTN MaxSize;\r
95\r
96 Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **) &Smmvariable);\r
97 if (EFI_ERROR (Status)) {\r
98 return Status;\r
99 }\r
100\r
101 Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication);\r
102 if (EFI_ERROR (Status)) {\r
103 return Status;\r
104 }\r
105\r
106 CommBuffer = NULL;\r
107 RealCommSize = 0;\r
108 Status = EfiGetSystemConfigurationTable (\r
109 &gEdkiiPiSmmCommunicationRegionTableGuid,\r
110 (VOID **) &PiSmmCommunicationRegionTable\r
111 );\r
112 if (EFI_ERROR (Status)) {\r
113 return Status;\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_SMM_COMMUNICATE_HEADER *) (UINTN) Entry->PhysicalStart;\r
127 }\r
128 }\r
129 }\r
130 Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + PiSmmCommunicationRegionTable->DescriptorSize);\r
131 }\r
132 ASSERT (CommBuffer != NULL);\r
133 ZeroMem (CommBuffer, RealCommSize);\r
134\r
135 Print (L"Non-Volatile SMM Variables:\n");\r
136 do {\r
137 CommSize = RealCommSize;\r
138 Status = GetVariableStatisticsData (CommBuffer, &CommSize);\r
139 if (Status == EFI_BUFFER_TOO_SMALL) {\r
140 Print (L"The generic SMM communication buffer provided by SmmCommunicationRegionTable is too small\n");\r
141 return Status;\r
142 }\r
143\r
144 if (EFI_ERROR (Status) || (CommSize <= SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)) {\r
145 break;\r
146 }\r
147\r
148 FunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) CommBuffer->Data;\r
149 VariableInfo = (VARIABLE_INFO_ENTRY *) FunctionHeader->Data;\r
150\r
151 if (!VariableInfo->Volatile) {\r
152 Print (\r
153 L"%g R%03d(%03d) W%03d D%03d:%s\n",\r
154 &VariableInfo->VendorGuid,\r
155 VariableInfo->ReadCount,\r
156 VariableInfo->CacheCount,\r
157 VariableInfo->WriteCount,\r
158 VariableInfo->DeleteCount,\r
159 (CHAR16 *)(VariableInfo + 1)\r
160 );\r
161 }\r
162 } while (TRUE);\r
163\r
164 Print (L"Volatile SMM Variables:\n");\r
165 ZeroMem (CommBuffer, RealCommSize);\r
166 do {\r
167 CommSize = RealCommSize;\r
168 Status = GetVariableStatisticsData (CommBuffer, &CommSize);\r
169 if (Status == EFI_BUFFER_TOO_SMALL) {\r
170 Print (L"The generic SMM communication buffer provided by SmmCommunicationRegionTable is too small\n");\r
171 return Status;\r
172 }\r
173\r
174 if (EFI_ERROR (Status) || (CommSize <= SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)) {\r
175 break;\r
176 }\r
177\r
178 FunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) CommBuffer->Data;\r
179 VariableInfo = (VARIABLE_INFO_ENTRY *) FunctionHeader->Data;\r
180\r
181 if (VariableInfo->Volatile) {\r
182 Print (\r
183 L"%g R%03d(%03d) W%03d D%03d:%s\n",\r
184 &VariableInfo->VendorGuid,\r
185 VariableInfo->ReadCount,\r
186 VariableInfo->CacheCount,\r
187 VariableInfo->WriteCount,\r
188 VariableInfo->DeleteCount,\r
189 (CHAR16 *)(VariableInfo + 1)\r
190 );\r
191 }\r
192 } while (TRUE);\r
193\r
194 return Status;\r
195}\r
196\r
197/**\r
198 The user Entry Point for Application. The user code starts with this function\r
199 as the real entry point for the image goes into a library that calls this\r
200 function.\r
201\r
202 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
203 @param[in] SystemTable A pointer to the EFI System Table.\r
204\r
205 @retval EFI_SUCCESS The entry point is executed successfully.\r
206 @retval other Some error occurs when executing this entry point.\r
207\r
208**/\r
209EFI_STATUS\r
210EFIAPI\r
211UefiMain (\r
212 IN EFI_HANDLE ImageHandle,\r
213 IN EFI_SYSTEM_TABLE *SystemTable\r
214 )\r
215{\r
216 EFI_STATUS Status;\r
217 VARIABLE_INFO_ENTRY *VariableInfo;\r
218 VARIABLE_INFO_ENTRY *Entry;\r
219\r
220 Status = EfiGetSystemConfigurationTable (&gEfiVariableGuid, (VOID **)&Entry);\r
221 if (EFI_ERROR (Status) || (Entry == NULL)) {\r
222 Status = EfiGetSystemConfigurationTable (&gEfiAuthenticatedVariableGuid, (VOID **)&Entry);\r
223 }\r
224\r
225 if (EFI_ERROR (Status) || (Entry == NULL)) {\r
226 Status = PrintInfoFromSmm ();\r
227 if (!EFI_ERROR (Status)) {\r
228 return Status;\r
229 }\r
230 }\r
231\r
232 if (!EFI_ERROR (Status) && (Entry != NULL)) {\r
233 Print (L"Non-Volatile EFI Variables:\n");\r
234 VariableInfo = Entry;\r
235 do {\r
236 if (!VariableInfo->Volatile) {\r
237 Print (\r
238 L"%g R%03d(%03d) W%03d D%03d:%s\n",\r
239 &VariableInfo->VendorGuid,\r
240 VariableInfo->ReadCount,\r
241 VariableInfo->CacheCount,\r
242 VariableInfo->WriteCount,\r
243 VariableInfo->DeleteCount,\r
244 VariableInfo->Name\r
245 );\r
246 }\r
247\r
248 VariableInfo = VariableInfo->Next;\r
249 } while (VariableInfo != NULL);\r
250\r
251 Print (L"Volatile EFI Variables:\n");\r
252 VariableInfo = Entry;\r
253 do {\r
254 if (VariableInfo->Volatile) {\r
255 Print (\r
256 L"%g R%03d(%03d) W%03d D%03d:%s\n",\r
257 &VariableInfo->VendorGuid,\r
258 VariableInfo->ReadCount,\r
259 VariableInfo->CacheCount,\r
260 VariableInfo->WriteCount,\r
261 VariableInfo->DeleteCount,\r
262 VariableInfo->Name\r
263 );\r
264 }\r
265 VariableInfo = VariableInfo->Next;\r
266 } while (VariableInfo != NULL);\r
267\r
268 } else {\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\r
276 return Status;\r
277}\r