diff options
author | Liming Gao <liming.gao@intel.com> | 2016-04-22 15:32:30 +0800 |
---|---|---|
committer | Hao Wu <hao.a.wu@intel.com> | 2016-07-06 16:19:58 +0800 |
commit | 9679c1d9d1ee26a066d37188537988c1f18bd359 (patch) | |
tree | 6c167a6fa8f7af7d55b4082a29b5cf52c396c8c2 | |
parent | 647550191f3886898e9daa47ae7075677509ec35 (diff) | |
download | edk2-platforms-9679c1d9d1ee26a066d37188537988c1f18bd359.tar.xz |
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>
(cherry picked from commit de2459d66d87eb526e3a21f1e6682fac8e1926c5)
-rw-r--r-- | MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.c | 154 | ||||
-rw-r--r-- | MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.inf | 3 |
2 files changed, 122 insertions, 35 deletions
diff --git a/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.c b/MdeModulePkg/Library/DxeSmmPerformanceLib/DxeSmmPerformanceLib.c index 3c7cfc17fe..7af6478bec 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 <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))
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.<BR>
+# Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR>
# 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
|