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 <liming.gao@intel.com>
Cc: Feng Tian <feng.tian@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
This commit is contained in:
Liming Gao 2016-04-22 15:32:30 +08:00 committed by Jiewen Yao
parent d158ba675b
commit de2459d66d
2 changed files with 122 additions and 35 deletions

View File

@ -32,10 +32,13 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Protocol/SmmCommunication.h> #include <Protocol/SmmCommunication.h>
#include <Guid/PiSmmCommunicationRegionTable.h>
#include <Library/UefiLib.h>
#define SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + sizeof (SMM_PERF_COMMUNICATE)) #define SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + sizeof (SMM_PERF_COMMUNICATE))
EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL; EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL;
UINT8 mSmmPerformanceBuffer[SMM_PERFORMANCE_COMMUNICATION_BUFFER_SIZE]; UINT8 *mSmmPerformanceBuffer;
GAUGE_DATA_ENTRY *mGaugeData = NULL; GAUGE_DATA_ENTRY *mGaugeData = NULL;
UINTN mGaugeNumberOfEntries = 0; UINTN mGaugeNumberOfEntries = 0;
GAUGE_DATA_ENTRY_EX *mGaugeDataEx = NULL; GAUGE_DATA_ENTRY_EX *mGaugeDataEx = NULL;
@ -388,6 +391,13 @@ GetAllSmmGaugeData (
SMM_PERF_COMMUNICATE *SmmPerfCommData; SMM_PERF_COMMUNICATE *SmmPerfCommData;
UINTN CommSize; UINTN CommSize;
UINTN DataSize; 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) { if (mNoSmmPerfHandler) {
// //
@ -417,6 +427,28 @@ GetAllSmmGaugeData (
return NULL; 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 // Initialize communicate buffer
// //
@ -442,6 +474,8 @@ GetAllSmmGaugeData (
mGaugeNumberOfEntries = SmmPerfCommData->NumberOfEntries; 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); DataSize = mGaugeNumberOfEntries * sizeof(GAUGE_DATA_ENTRY);
mGaugeData = AllocateZeroPool(DataSize); mGaugeData = AllocateZeroPool(DataSize);
ASSERT (mGaugeData != NULL); ASSERT (mGaugeData != NULL);
@ -450,15 +484,26 @@ GetAllSmmGaugeData (
// Get all SMM gauge data // Get all SMM gauge data
// //
SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_DATA; SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_DATA;
SmmPerfCommData->LogEntryKey = 0; SmmPerfCommData->GaugeData = (GAUGE_DATA_ENTRY *) Buffer;
SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntries; EntriesGot = 0;
SmmPerfCommData->GaugeData = mGaugeData; do {
SmmPerfCommData->LogEntryKey = EntriesGot;
if ((mGaugeNumberOfEntries - EntriesGot) >= NumberOfEntries) {
SmmPerfCommData->NumberOfEntries = NumberOfEntries;
} else {
SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntries - EntriesGot;
}
Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize); Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);
if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) { if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {
FreePool (mGaugeData); FreePool (mGaugeData);
mGaugeData = NULL; mGaugeData = NULL;
mGaugeNumberOfEntries = 0; mGaugeNumberOfEntries = 0;
return NULL;
} else {
CopyMem (&mGaugeData[EntriesGot], Buffer, SmmPerfCommData->NumberOfEntries * sizeof (GAUGE_DATA_ENTRY));
} }
EntriesGot += SmmPerfCommData->NumberOfEntries;
} while (EntriesGot < mGaugeNumberOfEntries);
return mGaugeData; return mGaugeData;
} }
@ -486,6 +531,13 @@ GetAllSmmGaugeDataEx (
SMM_PERF_COMMUNICATE_EX *SmmPerfCommData; SMM_PERF_COMMUNICATE_EX *SmmPerfCommData;
UINTN CommSize; UINTN CommSize;
UINTN DataSize; 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) { if (mNoSmmPerfExHandler) {
// //
@ -515,6 +567,27 @@ GetAllSmmGaugeDataEx (
return NULL; 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 // Initialize communicate buffer
// //
@ -540,6 +613,8 @@ GetAllSmmGaugeDataEx (
mGaugeNumberOfEntriesEx = SmmPerfCommData->NumberOfEntries; 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); DataSize = mGaugeNumberOfEntriesEx * sizeof(GAUGE_DATA_ENTRY_EX);
mGaugeDataEx = AllocateZeroPool(DataSize); mGaugeDataEx = AllocateZeroPool(DataSize);
ASSERT (mGaugeDataEx != NULL); ASSERT (mGaugeDataEx != NULL);
@ -548,15 +623,26 @@ GetAllSmmGaugeDataEx (
// Get all SMM gauge data // Get all SMM gauge data
// //
SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_DATA; SmmPerfCommData->Function = SMM_PERF_FUNCTION_GET_GAUGE_DATA;
SmmPerfCommData->LogEntryKey = 0; SmmPerfCommData->GaugeDataEx = (GAUGE_DATA_ENTRY_EX *) Buffer;
SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntriesEx; EntriesGot = 0;
SmmPerfCommData->GaugeDataEx = mGaugeDataEx; do {
SmmPerfCommData->LogEntryKey = EntriesGot;
if ((mGaugeNumberOfEntriesEx - EntriesGot) >= NumberOfEntries) {
SmmPerfCommData->NumberOfEntries = NumberOfEntries;
} else {
SmmPerfCommData->NumberOfEntries = mGaugeNumberOfEntriesEx - EntriesGot;
}
Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize); Status = mSmmCommunication->Communicate (mSmmCommunication, mSmmPerformanceBuffer, &CommSize);
if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) { if (EFI_ERROR (Status) || EFI_ERROR (SmmPerfCommData->ReturnStatus)) {
FreePool (mGaugeDataEx); FreePool (mGaugeDataEx);
mGaugeDataEx = NULL; mGaugeDataEx = NULL;
mGaugeNumberOfEntriesEx = 0; mGaugeNumberOfEntriesEx = 0;
return NULL;
} else {
CopyMem (&mGaugeDataEx[EntriesGot], Buffer, SmmPerfCommData->NumberOfEntries * sizeof (GAUGE_DATA_ENTRY_EX));
} }
EntriesGot += SmmPerfCommData->NumberOfEntries;
} while (EntriesGot < mGaugeNumberOfEntriesEx);
return mGaugeDataEx; return mGaugeDataEx;
} }

View File

@ -5,7 +5,7 @@
# StartPerformanceMeasurement(), EndPerformanceMeasurement(), StartPerformanceMeasurementEx() # StartPerformanceMeasurement(), EndPerformanceMeasurement(), StartPerformanceMeasurementEx()
# and EndPerformanceMeasurementEx() are not implemented. # and EndPerformanceMeasurementEx() are not implemented.
# #
# Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR> # Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials # This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License # 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 # which accompanies this distribution. The full text of the license may be found at
@ -54,6 +54,7 @@
gPerformanceExProtocolGuid ## SOMETIMES_CONSUMES ## UNDEFINED # Locate protocol gPerformanceExProtocolGuid ## SOMETIMES_CONSUMES ## UNDEFINED # Locate protocol
gSmmPerformanceProtocolGuid ## SOMETIMES_PRODUCES ## UNDEFINED # Used to do smm communication gSmmPerformanceProtocolGuid ## SOMETIMES_PRODUCES ## UNDEFINED # Used to do smm communication
gSmmPerformanceExProtocolGuid ## SOMETIMES_PRODUCES ## UNDEFINED # Used to do smm communication gSmmPerformanceExProtocolGuid ## SOMETIMES_PRODUCES ## UNDEFINED # Used to do smm communication
gEdkiiPiSmmCommunicationRegionTableGuid ## CONSUMES ## SystemTable
[Protocols] [Protocols]
gEfiSmmCommunicationProtocolGuid ## CONSUMES gEfiSmmCommunicationProtocolGuid ## CONSUMES