From 7f05fa00f73038b425002566d3afe6c3ade2ccdb Mon Sep 17 00:00:00 2001 From: Guo Mang Date: Thu, 22 Dec 2016 15:55:38 +0800 Subject: MdeModulePkg: Move to new location Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang --- .../Application/VariableInfo/VariableInfo.c | 277 +++++++++++++++++++++ 1 file changed, 277 insertions(+) create mode 100644 Core/MdeModulePkg/Application/VariableInfo/VariableInfo.c (limited to 'Core/MdeModulePkg/Application/VariableInfo/VariableInfo.c') diff --git a/Core/MdeModulePkg/Application/VariableInfo/VariableInfo.c b/Core/MdeModulePkg/Application/VariableInfo/VariableInfo.c new file mode 100644 index 0000000000..a88b7f1ec4 --- /dev/null +++ b/Core/MdeModulePkg/Application/VariableInfo/VariableInfo.c @@ -0,0 +1,277 @@ +/** @file + If the Variable services have PcdVariableCollectStatistics set to TRUE then + this utility will print out the statistics information. You can use console + redirection to capture the data. + + Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL; + +/** + This function get the variable statistics data from SMM variable driver. + + @param[in, out] SmmCommunicateHeader In input, a pointer to a collection of data that will + be passed into an SMM environment. In output, a pointer + to a collection of data that comes from an SMM environment. + @param[in, out] SmmCommunicateSize The size of the SmmCommunicateHeader. + + @retval EFI_SUCCESS Get the statistics data information. + @retval EFI_NOT_FOUND Not found. + @retval EFI_BUFFER_TO_SMALL DataSize is too small for the result. + +**/ +EFI_STATUS +EFIAPI +GetVariableStatisticsData ( + IN OUT EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader, + IN OUT UINTN *SmmCommunicateSize + ) +{ + EFI_STATUS Status; + SMM_VARIABLE_COMMUNICATE_HEADER *SmmVariableFunctionHeader; + + CopyGuid (&SmmCommunicateHeader->HeaderGuid, &gEfiSmmVariableProtocolGuid); + SmmCommunicateHeader->MessageLength = *SmmCommunicateSize - OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data); + + SmmVariableFunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) &SmmCommunicateHeader->Data[0]; + SmmVariableFunctionHeader->Function = SMM_VARIABLE_FUNCTION_GET_STATISTICS; + + Status = mSmmCommunication->Communicate (mSmmCommunication, SmmCommunicateHeader, SmmCommunicateSize); + ASSERT_EFI_ERROR (Status); + + Status = SmmVariableFunctionHeader->ReturnStatus; + return Status; +} + +/** + + This function get and print the variable statistics data from SMM variable driver. + + @retval EFI_SUCCESS Print the statistics information successfully. + @retval EFI_NOT_FOUND Not found the statistics information. + +**/ +EFI_STATUS +PrintInfoFromSmm ( + VOID + ) +{ + EFI_STATUS Status; + VARIABLE_INFO_ENTRY *VariableInfo; + EFI_SMM_COMMUNICATE_HEADER *CommBuffer; + UINTN RealCommSize; + UINTN CommSize; + SMM_VARIABLE_COMMUNICATE_HEADER *FunctionHeader; + EFI_SMM_VARIABLE_PROTOCOL *Smmvariable; + EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable; + UINT32 Index; + EFI_MEMORY_DESCRIPTOR *Entry; + UINTN Size; + UINTN MaxSize; + + Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **) &Smmvariable); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication); + if (EFI_ERROR (Status)) { + return Status; + } + + CommBuffer = NULL; + RealCommSize = 0; + Status = EfiGetSystemConfigurationTable ( + &gEdkiiPiSmmCommunicationRegionTableGuid, + (VOID **) &PiSmmCommunicationRegionTable + ); + if (EFI_ERROR (Status)) { + return Status; + } + ASSERT (PiSmmCommunicationRegionTable != NULL); + Entry = (EFI_MEMORY_DESCRIPTOR *) (PiSmmCommunicationRegionTable + 1); + Size = 0; + MaxSize = 0; + for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) { + if (Entry->Type == EfiConventionalMemory) { + Size = EFI_PAGES_TO_SIZE ((UINTN) Entry->NumberOfPages); + if (Size > (SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + sizeof (VARIABLE_INFO_ENTRY))) { + if (Size > MaxSize) { + MaxSize = Size; + RealCommSize = MaxSize; + CommBuffer = (EFI_SMM_COMMUNICATE_HEADER *) (UINTN) Entry->PhysicalStart; + } + } + } + Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + PiSmmCommunicationRegionTable->DescriptorSize); + } + ASSERT (CommBuffer != NULL); + ZeroMem (CommBuffer, RealCommSize); + + Print (L"Non-Volatile SMM Variables:\n"); + do { + CommSize = RealCommSize; + Status = GetVariableStatisticsData (CommBuffer, &CommSize); + if (Status == EFI_BUFFER_TOO_SMALL) { + Print (L"The generic SMM communication buffer provided by SmmCommunicationRegionTable is too small\n"); + return Status; + } + + if (EFI_ERROR (Status) || (CommSize <= SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)) { + break; + } + + FunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) CommBuffer->Data; + VariableInfo = (VARIABLE_INFO_ENTRY *) FunctionHeader->Data; + + if (!VariableInfo->Volatile) { + Print ( + L"%g R%03d(%03d) W%03d D%03d:%s\n", + &VariableInfo->VendorGuid, + VariableInfo->ReadCount, + VariableInfo->CacheCount, + VariableInfo->WriteCount, + VariableInfo->DeleteCount, + (CHAR16 *)(VariableInfo + 1) + ); + } + } while (TRUE); + + Print (L"Volatile SMM Variables:\n"); + ZeroMem (CommBuffer, RealCommSize); + do { + CommSize = RealCommSize; + Status = GetVariableStatisticsData (CommBuffer, &CommSize); + if (Status == EFI_BUFFER_TOO_SMALL) { + Print (L"The generic SMM communication buffer provided by SmmCommunicationRegionTable is too small\n"); + return Status; + } + + if (EFI_ERROR (Status) || (CommSize <= SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)) { + break; + } + + FunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) CommBuffer->Data; + VariableInfo = (VARIABLE_INFO_ENTRY *) FunctionHeader->Data; + + if (VariableInfo->Volatile) { + Print ( + L"%g R%03d(%03d) W%03d D%03d:%s\n", + &VariableInfo->VendorGuid, + VariableInfo->ReadCount, + VariableInfo->CacheCount, + VariableInfo->WriteCount, + VariableInfo->DeleteCount, + (CHAR16 *)(VariableInfo + 1) + ); + } + } while (TRUE); + + return Status; +} + +/** + The user Entry Point for Application. The user code starts with this function + as the real entry point for the image goes into a library that calls this + function. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +UefiMain ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + VARIABLE_INFO_ENTRY *VariableInfo; + VARIABLE_INFO_ENTRY *Entry; + + Status = EfiGetSystemConfigurationTable (&gEfiVariableGuid, (VOID **)&Entry); + if (EFI_ERROR (Status) || (Entry == NULL)) { + Status = EfiGetSystemConfigurationTable (&gEfiAuthenticatedVariableGuid, (VOID **)&Entry); + } + + if (EFI_ERROR (Status) || (Entry == NULL)) { + Status = PrintInfoFromSmm (); + if (!EFI_ERROR (Status)) { + return Status; + } + } + + if (!EFI_ERROR (Status) && (Entry != NULL)) { + Print (L"Non-Volatile EFI Variables:\n"); + VariableInfo = Entry; + do { + if (!VariableInfo->Volatile) { + Print ( + L"%g R%03d(%03d) W%03d D%03d:%s\n", + &VariableInfo->VendorGuid, + VariableInfo->ReadCount, + VariableInfo->CacheCount, + VariableInfo->WriteCount, + VariableInfo->DeleteCount, + VariableInfo->Name + ); + } + + VariableInfo = VariableInfo->Next; + } while (VariableInfo != NULL); + + Print (L"Volatile EFI Variables:\n"); + VariableInfo = Entry; + do { + if (VariableInfo->Volatile) { + Print ( + L"%g R%03d(%03d) W%03d D%03d:%s\n", + &VariableInfo->VendorGuid, + VariableInfo->ReadCount, + VariableInfo->CacheCount, + VariableInfo->WriteCount, + VariableInfo->DeleteCount, + VariableInfo->Name + ); + } + VariableInfo = VariableInfo->Next; + } while (VariableInfo != NULL); + + } else { + Print (L"Warning: Variable Dxe/Smm driver doesn't enable the feature of statistical information!\n"); + Print (L"If you want to see this info, please:\n"); + Print (L" 1. Set PcdVariableCollectStatistics as TRUE\n"); + Print (L" 2. Rebuild Variable Dxe/Smm driver\n"); + Print (L" 3. Run \"VariableInfo\" cmd again\n"); + } + + return Status; +} -- cgit v1.2.3