From: Liming Gao Date: Fri, 22 Apr 2016 07:32:30 +0000 (+0800) Subject: MdeModulePkg-FPDT(4): Use fixed buffer for SMM_PERF_COMMUNICATE in PerfLib. X-Git-Tag: edk2-stable201903~7210 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=de2459d66d87eb526e3a21f1e6682fac8e1926c5 MdeModulePkg-FPDT(4): Use fixed buffer for SMM_PERF_COMMUNICATE in PerfLib. This patch enhance performance data SMM communication by using fixed SMM communication buffer. Update PerformanceLib to use fixed SMM communication buffer to get performance data by SMM_PERF_COMMUNICATE API. This is designed to meet Microsoft WSMT table definition on FIXED_COMM_BUFFERS requirement. Cc: Liming Gao Cc: Feng Tian Cc: Laszlo Ersek Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Liming Gao Reviewed-by: Feng Tian --- diff --git a/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.c b/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.c index 218cf8b4a7..d8d0684273 100644 --- a/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.c +++ b/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.c @@ -32,10 +32,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include +#include +#include + #define SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + sizeof (SMM_PERF_COMMUNICATE)) EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL; -UINT8 mSmmPerformanceBuffer[SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE]; +UINT8 *mSmmPerformanceBuffer; GAUGE_DATA_ENTRY *mGaugeData = NULL; UINTN mGaugeNumberOfEntries = 0; GAUGE_DATA_ENTRY_EX *mGaugeDataEx = NULL; @@ -383,11 +386,18 @@ GetAllSmmGaugeData ( IN UINTN LogEntryKey ) { - EFI_STATUS Status; - EFI_SMM_COMMUNICATE_HEADER *SmmCommBufferHeader; - SMM_PERF_COMMUNICATE *SmmPerfCommData; - UINTN CommSize; - UINTN DataSize; + EFI_STATUS Status; + EFI_SMM_COMMUNICATE_HEADER *SmmCommBufferHeader; + SMM_PERF_COMMUNICATE *SmmPerfCommData; + UINTN CommSize; + UINTN DataSize; + EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable; + UINT32 Index; + EFI_MEMORY_DESCRIPTOR *Entry; + UINT8 *Buffer; + UINTN Size; + UINTN NumberOfEntries; + UINTN EntriesGot; if (mNoSmmPerfHandler) { // @@ -417,6 +427,28 @@ GetAllSmmGaugeData ( return NULL; } + Status = EfiGetSystemConfigurationTable ( + &gEdkiiPiSmmCommunicationRegionTableGuid, + (VOID **) &PiSmmCommunicationRegionTable + ); + if (EFI_ERROR (Status)) { + return NULL; + } + ASSERT (PiSmmCommunicationRegionTable != NULL); + Entry = (EFI_MEMORY_DESCRIPTOR *) (PiSmmCommunicationRegionTable + 1); + Size = 0; + for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) { + if (Entry->Type == EfiConventionalMemory) { + Size = EFI_PAGES_TO_SIZE ((UINTN) Entry->NumberOfPages); + if (Size >= (SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE + sizeof (GAUGE_DATA_ENTRY))) { + break; + } + } + Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + PiSmmCommunicationRegionTable->DescriptorSize); + } + ASSERT (Index < PiSmmCommunicationRegionTable->NumberOfEntries); + mSmmPerformanceBuffer = (UINT8 *) (UINTN) Entry->PhysicalStart; + // // Initialize communicate buffer // @@ -441,24 +473,37 @@ GetAllSmmGaugeData ( } mGaugeNumberOfEntries = SmmPerfCommData->NumberOfEntries; - + + Buffer = mSmmPerformanceBuffer + SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE; + NumberOfEntries = (Size - SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE) / sizeof (GAUGE_DATA_ENTRY); DataSize = mGaugeNumberOfEntries * sizeof(GAUGE_DATA_ENTRY); mGaugeData = AllocateZeroPool(DataSize); ASSERT (mGaugeData != NULL); - + // // Get all SMM gauge data // SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_DATA; - SmmPerfCommData->LogEntryKey = 0; - SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntries; - SmmPerfCommData->GaugeData = mGaugeData; - Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize); - if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) { - FreePool (mGaugeData); - mGaugeData = NULL; - mGaugeNumberOfEntries = 0; - } + SmmPerfCommData->GaugeData = (GAUGE_DATA_ENTRY *) Buffer; + EntriesGot = 0; + do { + SmmPerfCommData->LogEntryKey = EntriesGot; + if ((mGaugeNumberOfEntries - EntriesGot) >= NumberOfEntries) { + SmmPerfCommData->NumberOfEntries = NumberOfEntries; + } else { + SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntries - EntriesGot; + } + Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize); + if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) { + FreePool (mGaugeData); + mGaugeData = NULL; + mGaugeNumberOfEntries = 0; + return NULL; + } else { + CopyMem (&mGaugeData[EntriesGot], Buffer, SmmPerfCommData->NumberOfEntries * sizeof (GAUGE_DATA_ENTRY)); + } + EntriesGot += SmmPerfCommData->NumberOfEntries; + } while (EntriesGot < mGaugeNumberOfEntries); return mGaugeData; } @@ -481,11 +526,18 @@ GetAllSmmGaugeDataEx ( IN UINTN LogEntryKey ) { - EFI_STATUS Status; - EFI_SMM_COMMUNICATE_HEADER *SmmCommBufferHeader; - SMM_PERF_COMMUNICATE_EX *SmmPerfCommData; - UINTN CommSize; - UINTN DataSize; + EFI_STATUS Status; + EFI_SMM_COMMUNICATE_HEADER *SmmCommBufferHeader; + SMM_PERF_COMMUNICATE_EX *SmmPerfCommData; + UINTN CommSize; + UINTN DataSize; + EDKII_PI_SMM_COMMUNICATION_REGION_TABLE *PiSmmCommunicationRegionTable; + UINT32 Index; + EFI_MEMORY_DESCRIPTOR *Entry; + UINT8 *Buffer; + UINTN Size; + UINTN NumberOfEntries; + UINTN EntriesGot; if (mNoSmmPerfExHandler) { // @@ -515,6 +567,27 @@ GetAllSmmGaugeDataEx ( return NULL; } + Status = EfiGetSystemConfigurationTable ( + &gEdkiiPiSmmCommunicationRegionTableGuid, + (VOID **) &PiSmmCommunicationRegionTable + ); + if (EFI_ERROR (Status)) { + return NULL; + } + ASSERT (PiSmmCommunicationRegionTable != NULL); + Entry = (EFI_MEMORY_DESCRIPTOR *) (PiSmmCommunicationRegionTable + 1); + Size = 0; + for (Index = 0; Index < PiSmmCommunicationRegionTable->NumberOfEntries; Index++) { + if (Entry->Type == EfiConventionalMemory) { + Size = EFI_PAGES_TO_SIZE ((UINTN) Entry->NumberOfPages); + if (Size >= (SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE + sizeof (GAUGE_DATA_ENTRY_EX))) { + break; + } + } + Entry = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) Entry + PiSmmCommunicationRegionTable->DescriptorSize); + } + ASSERT (Index < PiSmmCommunicationRegionTable->NumberOfEntries); + mSmmPerformanceBuffer = (UINT8 *) (UINTN) Entry->PhysicalStart; // // Initialize communicate buffer // @@ -539,25 +612,38 @@ GetAllSmmGaugeDataEx ( } mGaugeNumberOfEntriesEx = SmmPerfCommData->NumberOfEntries; - + + Buffer = mSmmPerformanceBuffer + SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE; + NumberOfEntries = (Size - SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE) / sizeof (GAUGE_DATA_ENTRY_EX); DataSize = mGaugeNumberOfEntriesEx * sizeof(GAUGE_DATA_ENTRY_EX); mGaugeDataEx = AllocateZeroPool(DataSize); ASSERT (mGaugeDataEx != NULL); - + // // Get all SMM gauge data // SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_DATA; - SmmPerfCommData->LogEntryKey = 0; - SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntriesEx; - SmmPerfCommData->GaugeDataEx = mGaugeDataEx; - Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize); - if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) { - FreePool (mGaugeDataEx); - mGaugeDataEx = NULL; - mGaugeNumberOfEntriesEx = 0; - } - + SmmPerfCommData->GaugeDataEx = (GAUGE_DATA_ENTRY_EX *) Buffer; + EntriesGot = 0; + do { + SmmPerfCommData->LogEntryKey = EntriesGot; + if ((mGaugeNumberOfEntriesEx - EntriesGot) >= NumberOfEntries) { + SmmPerfCommData->NumberOfEntries = NumberOfEntries; + } else { + SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntriesEx - EntriesGot; + } + Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize); + if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) { + FreePool (mGaugeDataEx); + mGaugeDataEx = NULL; + mGaugeNumberOfEntriesEx = 0; + return NULL; + } else { + CopyMem (&mGaugeDataEx[EntriesGot], Buffer, SmmPerfCommData->NumberOfEntries * sizeof (GAUGE_DATA_ENTRY_EX)); + } + EntriesGot += SmmPerfCommData->NumberOfEntries; + } while (EntriesGot < mGaugeNumberOfEntriesEx); + return mGaugeDataEx; } diff --git a/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.inf b/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.inf index a661328dce..2dbaa7c297 100644 --- a/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.inf +++ b/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.inf @@ -5,7 +5,7 @@ # StartPerformanceMeasurement(), EndPerformanceMeasurement(), StartPerformanceMeasurementEx() # and EndPerformanceMeasurementEx() are not implemented. # -# Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.
+# Copyright (c) 2011 - 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 @@ -54,6 +54,7 @@ gPerformanceExProtocolGuid ## SOMETIMES_CONSUMES ## UNDEFINED # Locate protocol gSmmPerformanceProtocolGuid ## SOMETIMES_PRODUCES ## UNDEFINED # Used to do smm communication gSmmPerformanceExProtocolGuid ## SOMETIMES_PRODUCES ## UNDEFINED # Used to do smm communication + gEdkiiPiSmmCommunicationRegionTableGuid ## CONSUMES ## SystemTable [Protocols] gEfiSmmCommunicationProtocolGuid ## CONSUMES