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