+ Status = SmmVariableFunctionHeader->ReturnStatus;\r
+ return Status;\r
+}\r
+\r
+/**\r
+\r
+ This function get and print the variable statistics data from SMM variable driver.\r
+\r
+ @retval EFI_SUCCESS Print the statistics information successfully.\r
+ @retval EFI_NOT_FOUND Not found the statistics information.\r
+\r
+**/\r
+EFI_STATUS\r
+PrintInfoFromSmm (\r
+ VOID\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ VARIABLE_INFO_ENTRY *VariableInfo;\r
+ EFI_SMM_COMMUNICATE_HEADER *CommBuffer;\r
+ UINTN RealCommSize;\r
+ UINTN CommSize;\r
+ SMM_VARIABLE_COMMUNICATE_HEADER *FunctionHeader;\r
+ EFI_SMM_VARIABLE_PROTOCOL *Smmvariable;\r
+ EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable;\r
+ UINT32 Index;\r
+ EFI_MEMORY_DESCRIPTOR *Entry;\r
+ UINTN Size;\r
+ UINTN MaxSize;\r
+\r
+ Status = gBS->LocateProtocol (&gEfiSmmVariableProtocolGuid, NULL, (VOID **) &Smmvariable);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ CommBuffer = NULL;\r
+ RealCommSize = 0;\r
+ Status = EfiGetSystemConfigurationTable (\r
+ &gEdkiiPiSmmCommunicationRegionTableGuid,\r
+ (VOID **) &PiSmmCommunicationRegionTable\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ ASSERT (PiSmmCommunicationRegionTable != NULL);\r
+ Entry = (EFI_MEMORY_DESCRIPTOR *) (PiSmmCommunicationRegionTable + 1);\r
+ Size = 0;\r
+ MaxSize = 0;\r
+ for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) {\r
+ if (Entry->Type == EfiConventionalMemory) {\r
+ Size = EFI_PAGES_TO_SIZE ((UINTN) Entry->NumberOfPages);\r
+ if (Size > (SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE + sizeof (VARIABLE_INFO_ENTRY))) {\r
+ if (Size > MaxSize) {\r
+ MaxSize = Size;\r
+ RealCommSize = MaxSize;\r
+ CommBuffer = (EFI_SMM_COMMUNICATE_HEADER *) (UINTN) Entry->PhysicalStart;\r
+ }\r
+ }\r
+ }\r
+ Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + PiSmmCommunicationRegionTable->DescriptorSize);\r
+ }\r
+ ASSERT (CommBuffer != NULL);\r
+ ZeroMem (CommBuffer, RealCommSize);\r
+\r
+ Print (L"Non-Volatile SMM Variables:\n");\r
+ do {\r
+ CommSize = RealCommSize;\r
+ Status = GetVariableStatisticsData (CommBuffer, &CommSize);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ Print (L"The generic SMM communication buffer provided by SmmCommunicationRegionTable is too small\n");\r
+ return Status;\r
+ }\r
+\r
+ if (EFI_ERROR (Status) || (CommSize <= SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)) {\r
+ break;\r
+ }\r
+\r
+ FunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) CommBuffer->Data;\r
+ VariableInfo = (VARIABLE_INFO_ENTRY *) FunctionHeader->Data;\r
+\r
+ if (!VariableInfo->Volatile) {\r
+ Print (\r
+ L"%g R%03d(%03d) W%03d D%03d:%s\n",\r
+ &VariableInfo->VendorGuid,\r
+ VariableInfo->ReadCount,\r
+ VariableInfo->CacheCount,\r
+ VariableInfo->WriteCount,\r
+ VariableInfo->DeleteCount,\r
+ (CHAR16 *)(VariableInfo + 1)\r
+ );\r
+ }\r
+ } while (TRUE);\r
+\r
+ Print (L"Volatile SMM Variables:\n");\r
+ ZeroMem (CommBuffer, RealCommSize);\r
+ do {\r
+ CommSize = RealCommSize;\r
+ Status = GetVariableStatisticsData (CommBuffer, &CommSize);\r
+ if (Status == EFI_BUFFER_TOO_SMALL) {\r
+ Print (L"The generic SMM communication buffer provided by SmmCommunicationRegionTable is too small\n");\r
+ return Status;\r
+ }\r
+\r
+ if (EFI_ERROR (Status) || (CommSize <= SMM_COMMUNICATE_HEADER_SIZE + SMM_VARIABLE_COMMUNICATE_HEADER_SIZE)) {\r
+ break;\r
+ }\r
+\r
+ FunctionHeader = (SMM_VARIABLE_COMMUNICATE_HEADER *) CommBuffer->Data;\r
+ VariableInfo = (VARIABLE_INFO_ENTRY *) FunctionHeader->Data;\r
+\r
+ if (VariableInfo->Volatile) {\r
+ Print (\r
+ L"%g R%03d(%03d) W%03d D%03d:%s\n",\r
+ &VariableInfo->VendorGuid,\r
+ VariableInfo->ReadCount,\r
+ VariableInfo->CacheCount,\r
+ VariableInfo->WriteCount,\r
+ VariableInfo->DeleteCount,\r
+ (CHAR16 *)(VariableInfo + 1)\r
+ );\r
+ }\r
+ } while (TRUE);\r
+\r
+ return Status;\r
+}\r