summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Universal/Acpi
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Universal/Acpi')
-rw-r--r--MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.S8
-rw-r--r--MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c240
-rw-r--r--MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf7
-rw-r--r--MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.c37
-rw-r--r--MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf4
-rw-r--r--MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c50
6 files changed, 242 insertions, 104 deletions
diff --git a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.S b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.S
index dcce6fb6ae..e59fd048b0 100644
--- a/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.S
+++ b/MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/X64/S3Asm.S
@@ -2,7 +2,7 @@
# This is the assembly code for transferring to control to OS S3 waking vector
# for X64 platform
#
-# Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2013, 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
@@ -18,14 +18,14 @@ ASM_GLOBAL ASM_PFX(AsmTransferControl)
ASM_PFX(AsmTransferControl):
# rcx S3WakingVector :DWORD
# rdx AcpiLowMemoryBase :DWORD
- lea _AsmTransferControl_al_0000, %eax
+ lea _AsmTransferControl_al_0000(%rip), %eax
movq $0x2800000000, %r8
orq %r8, %rax
pushq %rax
shrd $20, %ecx, %ebx
andl $0x0f, %ecx
movw %cx, %bx
- movl %ebx, jmp_addr
+ movl %ebx, jmp_addr(%rip)
lret
_AsmTransferControl_al_0000:
.byte 0x0b8, 0x30, 0 # mov ax, 30h as selector
@@ -124,7 +124,7 @@ ASM_PFX(PageFaultHandlerHook):
popq %rcx
popq %rax # restore all volatile registers
jnz L1
- jmpq *ASM_PFX(mOriginalHandler)
+ jmpq *ASM_PFX(mOriginalHandler)(%rip)
L1:
addq $0x08, %rsp # skip error code for PF
iretq
diff --git a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c
index ce17e4f928..f834778acd 100644
--- a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c
+++ b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.c
@@ -5,7 +5,7 @@
for Firmware Basic Boot Performance Record and other boot performance records,
and install FPDT to ACPI table.
- Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2011 - 2013, 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
@@ -21,6 +21,8 @@
#include <Protocol/ReportStatusCodeHandler.h>
#include <Protocol/AcpiTable.h>
#include <Protocol/SmmCommunication.h>
+#include <Protocol/LockBox.h>
+#include <Protocol/Variable.h>
#include <Guid/Acpi.h>
#include <Guid/FirmwarePerformance.h>
@@ -36,7 +38,8 @@
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/HobLib.h>
-#include <Library/PcdLib.h>
+#include <Library/LockBoxLib.h>
+#include <Library/UefiLib.h>
//
// ACPI table information used to initialize tables.
@@ -51,6 +54,7 @@
EFI_RSC_HANDLER_PROTOCOL *mRscHandlerProtocol = NULL;
+BOOLEAN mLockBoxReady = FALSE;
EFI_EVENT mReadyToBootEvent;
EFI_EVENT mLegacyBootEvent;
EFI_EVENT mExitBootServicesEvent;
@@ -206,6 +210,7 @@ FpdtAllocateReservedMemoryBelow4G (
EFI_STATUS Status;
VOID *Buffer;
+ Buffer = NULL;
Pages = EFI_SIZE_TO_PAGES (Size);
Address = 0xffffffff;
@@ -217,13 +222,107 @@ FpdtAllocateReservedMemoryBelow4G (
);
ASSERT_EFI_ERROR (Status);
- Buffer = (VOID *) (UINTN) Address;
- ZeroMem (Buffer, Size);
+ if (!EFI_ERROR (Status)) {
+ Buffer = (VOID *) (UINTN) Address;
+ ZeroMem (Buffer, Size);
+ }
return Buffer;
}
/**
+ Callback function upon VariableArchProtocol and LockBoxProtocol
+ to allocate S3 performance table memory and save the pointer to LockBox.
+
+ @param[in] Event Event whose notification function is being invoked.
+ @param[in] Context Pointer to the notification function's context.
+**/
+VOID
+EFIAPI
+FpdtAllocateS3PerformanceTableMemory (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ VOID *Interface;
+ FIRMWARE_PERFORMANCE_VARIABLE PerformanceVariable;
+ UINTN Size;
+ EFI_PHYSICAL_ADDRESS S3PerformanceTablePointer;
+
+ if (mLockBoxReady && (mAcpiS3PerformanceTable != NULL)) {
+ //
+ // The memory for S3 performance table should have been ready,
+ // and the pointer should have been saved to LockBox, just return.
+ //
+ return;
+ }
+
+ if (!mLockBoxReady) {
+ Status = gBS->LocateProtocol (&gEfiLockBoxProtocolGuid, NULL, &Interface);
+ if (!EFI_ERROR (Status)) {
+ //
+ // LockBox services has been ready.
+ //
+ mLockBoxReady = TRUE;
+ }
+ }
+
+ if (mAcpiS3PerformanceTable == NULL) {
+ Status = gBS->LocateProtocol (&gEfiVariableArchProtocolGuid, NULL, &Interface);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Try to allocate the same runtime buffer as last time boot.
+ //
+ ZeroMem (&PerformanceVariable, sizeof (PerformanceVariable));
+ Size = sizeof (PerformanceVariable);
+ Status = gRT->GetVariable (
+ EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
+ &gEfiFirmwarePerformanceGuid,
+ NULL,
+ &Size,
+ &PerformanceVariable
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->AllocatePages (
+ AllocateAddress,
+ EfiReservedMemoryType,
+ EFI_SIZE_TO_PAGES (sizeof (S3_PERFORMANCE_TABLE)),
+ &PerformanceVariable.S3PerformanceTablePointer
+ );
+ if (!EFI_ERROR (Status)) {
+ mAcpiS3PerformanceTable = (S3_PERFORMANCE_TABLE *) (UINTN) PerformanceVariable.S3PerformanceTablePointer;
+ }
+ }
+ if (mAcpiS3PerformanceTable == NULL) {
+ //
+ // Fail to allocate at specified address, continue to allocate at any address.
+ //
+ mAcpiS3PerformanceTable = (S3_PERFORMANCE_TABLE *) FpdtAllocateReservedMemoryBelow4G (sizeof (S3_PERFORMANCE_TABLE));
+ }
+ DEBUG ((EFI_D_INFO, "FPDT: ACPI S3 Performance Table address = 0x%x\n", mAcpiS3PerformanceTable));
+ if (mAcpiS3PerformanceTable != NULL) {
+ CopyMem (mAcpiS3PerformanceTable, &mS3PerformanceTableTemplate, sizeof (mS3PerformanceTableTemplate));
+ }
+ }
+ }
+
+ if (mLockBoxReady && (mAcpiS3PerformanceTable != NULL)) {
+ //
+ // If LockBox services has been ready and memory for FPDT S3 performance table has been allocated,
+ // save the pointer to LockBox for use in S3 resume.
+ //
+ S3PerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiS3PerformanceTable;
+ Status = SaveLockBox (
+ &gFirmwarePerformanceS3PointerGuid,
+ &S3PerformanceTablePointer,
+ sizeof (EFI_PHYSICAL_ADDRESS)
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+}
+
+/**
Install ACPI Firmware Performance Data Table (FPDT).
@return Status code.
@@ -236,15 +335,13 @@ InstallFirmwarePerformanceDataTable (
{
EFI_STATUS Status;
EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol;
- EFI_PHYSICAL_ADDRESS Address;
UINTN Size;
- UINT8 SmmBootRecordCommBuffer[SMM_BOOT_RECORD_COMM_SIZE];
+ UINT8 *SmmBootRecordCommBuffer;
EFI_SMM_COMMUNICATE_HEADER *SmmCommBufferHeader;
SMM_BOOT_RECORD_COMMUNICATE *SmmCommData;
UINTN CommSize;
- UINTN PerformanceRuntimeDataSize;
- UINT8 *PerformanceRuntimeData;
- UINT8 *PerformanceRuntimeDataHead;
+ UINTN BootPerformanceDataSize;
+ UINT8 *BootPerformanceData;
EFI_SMM_COMMUNICATION_PROTOCOL *Communication;
FIRMWARE_PERFORMANCE_VARIABLE PerformanceVariable;
@@ -259,12 +356,15 @@ InstallFirmwarePerformanceDataTable (
//
// Collect boot records from SMM drivers.
//
- SmmCommData = NULL;
+ SmmBootRecordCommBuffer = NULL;
+ SmmCommData = NULL;
Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &Communication);
if (!EFI_ERROR (Status)) {
//
// Initialize communicate buffer
//
+ SmmBootRecordCommBuffer = AllocateZeroPool (SMM_BOOT_RECORD_COMM_SIZE);
+ ASSERT (SmmBootRecordCommBuffer != NULL);
SmmCommBufferHeader = (EFI_SMM_COMMUNICATE_HEADER*)SmmBootRecordCommBuffer;
SmmCommData = (SMM_BOOT_RECORD_COMMUNICATE*)SmmCommBufferHeader->Data;
ZeroMem((UINT8*)SmmCommData, sizeof(SMM_BOOT_RECORD_COMMUNICATE));
@@ -296,15 +396,12 @@ InstallFirmwarePerformanceDataTable (
}
//
- // Prepare memory for runtime Performance Record.
- // Runtime performance records includes two tables S3 performance table and Boot performance table.
- // S3 Performance table includes S3Resume and S3Suspend records.
+ // Prepare memory for Boot Performance table.
// Boot Performance table includes BasicBoot record, and one or more appended Boot Records.
//
- PerformanceRuntimeData = NULL;
- PerformanceRuntimeDataSize = sizeof (S3_PERFORMANCE_TABLE) + sizeof (BOOT_PERFORMANCE_TABLE) + mBootRecordSize + PcdGet32 (PcdExtFpdtBootRecordPadSize);
+ BootPerformanceDataSize = sizeof (BOOT_PERFORMANCE_TABLE) + mBootRecordSize + PcdGet32 (PcdExtFpdtBootRecordPadSize);
if (SmmCommData != NULL) {
- PerformanceRuntimeDataSize += SmmCommData->BootRecordSize;
+ BootPerformanceDataSize += SmmCommData->BootRecordSize;
}
//
@@ -320,87 +417,66 @@ InstallFirmwarePerformanceDataTable (
&PerformanceVariable
);
if (!EFI_ERROR (Status)) {
- Address = PerformanceVariable.S3PerformanceTablePointer;
Status = gBS->AllocatePages (
AllocateAddress,
EfiReservedMemoryType,
- EFI_SIZE_TO_PAGES (PerformanceRuntimeDataSize),
- &Address
+ EFI_SIZE_TO_PAGES (BootPerformanceDataSize),
+ &PerformanceVariable.BootPerformanceTablePointer
);
if (!EFI_ERROR (Status)) {
- PerformanceRuntimeData = (UINT8 *) (UINTN) Address;
+ mAcpiBootPerformanceTable = (BOOT_PERFORMANCE_TABLE *) (UINTN) PerformanceVariable.BootPerformanceTablePointer;
}
}
- if (PerformanceRuntimeData == NULL) {
+ if (mAcpiBootPerformanceTable == NULL) {
//
// Fail to allocate at specified address, continue to allocate at any address.
//
- PerformanceRuntimeData = FpdtAllocateReservedMemoryBelow4G (PerformanceRuntimeDataSize);
+ mAcpiBootPerformanceTable = (BOOT_PERFORMANCE_TABLE *) FpdtAllocateReservedMemoryBelow4G (BootPerformanceDataSize);
}
- DEBUG ((EFI_D_INFO, "FPDT: Performance Runtime Data address = 0x%x\n", PerformanceRuntimeData));
+ DEBUG ((EFI_D_INFO, "FPDT: ACPI Boot Performance Table address = 0x%x\n", mAcpiBootPerformanceTable));
- if (PerformanceRuntimeData == NULL) {
+ if (mAcpiBootPerformanceTable == NULL) {
if (SmmCommData != NULL && SmmCommData->BootRecordData != NULL) {
FreePool (SmmCommData->BootRecordData);
}
+ if (SmmBootRecordCommBuffer != NULL) {
+ FreePool (SmmBootRecordCommBuffer);
+ }
+ if (mAcpiS3PerformanceTable != NULL) {
+ FreePages (mAcpiS3PerformanceTable, EFI_SIZE_TO_PAGES (sizeof (S3_PERFORMANCE_TABLE)));
+ }
return EFI_OUT_OF_RESOURCES;
}
-
- PerformanceRuntimeDataHead = PerformanceRuntimeData;
-
- if (FeaturePcdGet (PcdFirmwarePerformanceDataTableS3Support)) {
- //
- // Prepare S3 Performance Table.
- //
- mAcpiS3PerformanceTable = (S3_PERFORMANCE_TABLE *) PerformanceRuntimeData;
- CopyMem (mAcpiS3PerformanceTable, &mS3PerformanceTableTemplate, sizeof (mS3PerformanceTableTemplate));
- PerformanceRuntimeData = PerformanceRuntimeData + mAcpiS3PerformanceTable->Header.Length;
- DEBUG ((EFI_D_INFO, "FPDT: ACPI S3 Performance Table address = 0x%x\n", mAcpiS3PerformanceTable));
- //
- // Save S3 Performance Table address to Variable for use in Firmware Performance PEIM.
- //
- PerformanceVariable.S3PerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiS3PerformanceTable;
- //
- // Update S3 Performance Table Pointer in template.
- //
- mFirmwarePerformanceTableTemplate.S3PointerRecord.S3PerformanceTablePointer = (UINT64) PerformanceVariable.S3PerformanceTablePointer;
- } else {
- //
- // Exclude S3 Performance Table Pointer from FPDT table template.
- //
- mFirmwarePerformanceTableTemplate.Header.Length -= sizeof (EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD);
- }
//
// Prepare Boot Performance Table.
//
- mAcpiBootPerformanceTable = (BOOT_PERFORMANCE_TABLE *) PerformanceRuntimeData;
+ BootPerformanceData = (UINT8 *) mAcpiBootPerformanceTable;
//
// Fill Basic Boot record to Boot Performance Table.
//
- CopyMem (PerformanceRuntimeData, &mBootPerformanceTableTemplate, sizeof (mBootPerformanceTableTemplate));
- PerformanceRuntimeData = PerformanceRuntimeData + mAcpiBootPerformanceTable->Header.Length;
+ CopyMem (mAcpiBootPerformanceTable, &mBootPerformanceTableTemplate, sizeof (mBootPerformanceTableTemplate));
+ BootPerformanceData = BootPerformanceData + mAcpiBootPerformanceTable->Header.Length;
//
// Fill Boot records from boot drivers.
//
- CopyMem (PerformanceRuntimeData, mBootRecordBuffer, mBootRecordSize);
+ CopyMem (BootPerformanceData, mBootRecordBuffer, mBootRecordSize);
mAcpiBootPerformanceTable->Header.Length += mBootRecordSize;
- PerformanceRuntimeData = PerformanceRuntimeData + mBootRecordSize;
+ BootPerformanceData = BootPerformanceData + mBootRecordSize;
if (SmmCommData != NULL && SmmCommData->BootRecordData != NULL) {
//
// Fill Boot records from SMM drivers.
//
- CopyMem (PerformanceRuntimeData, SmmCommData->BootRecordData, SmmCommData->BootRecordSize);
+ CopyMem (BootPerformanceData, SmmCommData->BootRecordData, SmmCommData->BootRecordSize);
FreePool (SmmCommData->BootRecordData);
mAcpiBootPerformanceTable->Header.Length = (UINT32) (mAcpiBootPerformanceTable->Header.Length + SmmCommData->BootRecordSize);
- PerformanceRuntimeData = PerformanceRuntimeData + SmmCommData->BootRecordSize;
+ BootPerformanceData = BootPerformanceData + SmmCommData->BootRecordSize;
}
- //
- // Reserve space for boot records after ReadyToBoot.
- //
- PerformanceRuntimeData = PerformanceRuntimeData + PcdGet32 (PcdExtFpdtBootRecordPadSize);
- DEBUG ((EFI_D_INFO, "FPDT: ACPI Boot Performance Table address = 0x%x\n", mAcpiBootPerformanceTable));
+ if (SmmBootRecordCommBuffer != NULL) {
+ FreePool (SmmBootRecordCommBuffer);
+ }
+
//
// Save Boot Performance Table address to Variable for use in S4 resume.
//
@@ -411,12 +487,20 @@ InstallFirmwarePerformanceDataTable (
mFirmwarePerformanceTableTemplate.BootPointerRecord.BootPerformanceTablePointer = (UINT64) (UINTN) mAcpiBootPerformanceTable;
//
+ // Save S3 Performance Table address to Variable for use in S4 resume.
+ //
+ PerformanceVariable.S3PerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiS3PerformanceTable;
+ //
+ // Update S3 Performance Table Pointer in template.
+ //
+ mFirmwarePerformanceTableTemplate.S3PointerRecord.S3PerformanceTablePointer = (UINT64) (UINTN) mAcpiS3PerformanceTable;
+ //
// Save Runtime Performance Table pointers to Variable.
//
Status = gRT->SetVariable (
EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
&gEfiFirmwarePerformanceGuid,
- EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof (PerformanceVariable),
&PerformanceVariable
);
@@ -433,7 +517,10 @@ InstallFirmwarePerformanceDataTable (
&mFirmwarePerformanceTableTemplateKey
);
if (EFI_ERROR (Status)) {
- FreePool (PerformanceRuntimeDataHead);
+ FreePages (mAcpiBootPerformanceTable, EFI_SIZE_TO_PAGES (BootPerformanceDataSize));
+ if (mAcpiS3PerformanceTable != NULL) {
+ FreePages (mAcpiS3PerformanceTable, EFI_SIZE_TO_PAGES (sizeof (S3_PERFORMANCE_TABLE)));
+ }
mAcpiBootPerformanceTable = NULL;
mAcpiS3PerformanceTable = NULL;
return Status;
@@ -700,6 +787,7 @@ FirmwarePerformanceDxeEntryPoint (
EFI_STATUS Status;
EFI_HOB_GUID_TYPE *GuidHob;
FIRMWARE_SEC_PERFORMANCE *Performance;
+ VOID *Registration;
//
// Get Report Status Code Handler Protocol.
@@ -766,5 +854,31 @@ FirmwarePerformanceDxeEntryPoint (
DEBUG ((EFI_D_ERROR, "FPDT: WARNING: SEC Performance Data Hob not found, ResetEnd will be set to 0!\n"));
}
+ if (FeaturePcdGet (PcdFirmwarePerformanceDataTableS3Support)) {
+ //
+ // Register callback function upon VariableArchProtocol and LockBoxProtocol
+ // to allocate S3 performance table memory and save the pointer to LockBox.
+ //
+ EfiCreateProtocolNotifyEvent (
+ &gEfiVariableArchProtocolGuid,
+ TPL_CALLBACK,
+ FpdtAllocateS3PerformanceTableMemory,
+ NULL,
+ &Registration
+ );
+ EfiCreateProtocolNotifyEvent (
+ &gEfiLockBoxProtocolGuid,
+ TPL_CALLBACK,
+ FpdtAllocateS3PerformanceTableMemory,
+ NULL,
+ &Registration
+ );
+ } else {
+ //
+ // Exclude S3 Performance Table Pointer from FPDT table template.
+ //
+ mFirmwarePerformanceTableTemplate.Header.Length -= sizeof (EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD);
+ }
+
return EFI_SUCCESS;
}
diff --git a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf
index 89424acaae..5a9628f924 100644
--- a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf
+++ b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableDxe/FirmwarePerformanceDxe.inf
@@ -5,7 +5,7 @@
# for Firmware Basic Boot Performance Record and other boot performance records,
# and install FPDT to ACPI table.
#
-# Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2011 - 2013, 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
@@ -48,11 +48,15 @@
MemoryAllocationLib
PcdLib
HobLib
+ LockBoxLib
+ UefiLib
[Protocols]
gEfiAcpiTableProtocolGuid ## SOMETIMES_CONSUMES
gEfiRscHandlerProtocolGuid ## CONSUMES
gEfiSmmCommunicationProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiVariableArchProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiLockBoxProtocolGuid ## SOMETIMES_CONSUMES
[Guids]
gEfiEventExitBootServicesGuid ## CONSUMES
@@ -65,6 +69,7 @@
gEfiFirmwarePerformanceGuid ## SOMETIMES_CONSUMES ## Hob
gEfiFirmwarePerformanceGuid ## SOMETIMES_CONSUMES ## SmiHandler
gEfiFirmwarePerformanceGuid ## SOMETIMES_CONSUMES ## StatusCode Data
+ gFirmwarePerformanceS3PointerGuid ## SOMETIMES_PRODUCES # SaveLockBox
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeOsLoaderLoad
diff --git a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.c b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.c
index af9b4e3c65..70592cbc3c 100644
--- a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.c
+++ b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.c
@@ -7,7 +7,7 @@
This module register report status code listener to collect performance data
for S3 Resume Performance Record on S3 resume boot path.
- Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2011 - 2013, 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
@@ -20,7 +20,6 @@
#include <PiPei.h>
-#include <Ppi/ReadOnlyVariable2.h>
#include <Ppi/ReportStatusCodeHandler.h>
#include <Ppi/SecPerformance.h>
@@ -68,9 +67,8 @@ FpdtStatusCodeListenerPei (
{
EFI_STATUS Status;
UINT64 CurrentTime;
- EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
UINTN VarSize;
- FIRMWARE_PERFORMANCE_VARIABLE PerformanceVariable;
+ EFI_PHYSICAL_ADDRESS S3PerformanceTablePointer;
S3_PERFORMANCE_TABLE *AcpiS3PerformanceTable;
EFI_ACPI_5_0_FPDT_S3_RESUME_RECORD *AcpiS3ResumeRecord;
UINT64 S3ResumeTotal;
@@ -90,33 +88,20 @@ FpdtStatusCodeListenerPei (
//
CurrentTime = GetTimeInNanoSecond (GetPerformanceCounter ());
- Status = PeiServicesLocatePpi (
- &gEfiPeiReadOnlyVariable2PpiGuid,
- 0,
- NULL,
- (VOID **) &VariableServices
- );
- ASSERT_EFI_ERROR (Status);
-
//
// Update S3 Resume Performance Record.
//
- VarSize = sizeof (FIRMWARE_PERFORMANCE_VARIABLE);
- Status = VariableServices->GetVariable (
- VariableServices,
- EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
- &gEfiFirmwarePerformanceGuid,
- NULL,
- &VarSize,
- &PerformanceVariable
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ S3PerformanceTablePointer = 0;
+ VarSize = sizeof (EFI_PHYSICAL_ADDRESS);
+ Status = RestoreLockBox (&gFirmwarePerformanceS3PointerGuid, &S3PerformanceTablePointer, &VarSize);
+ ASSERT_EFI_ERROR (Status);
- AcpiS3PerformanceTable = (S3_PERFORMANCE_TABLE *) (UINTN) PerformanceVariable.S3PerformanceTablePointer;
+ AcpiS3PerformanceTable = (S3_PERFORMANCE_TABLE *) (UINTN) S3PerformanceTablePointer;
ASSERT (AcpiS3PerformanceTable != NULL);
- ASSERT (AcpiS3PerformanceTable->Header.Signature == EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE);
+ if (AcpiS3PerformanceTable->Header.Signature != EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE) {
+ DEBUG ((EFI_D_ERROR, "FPDT S3 performance data in ACPI memory get corrupted\n"));
+ return EFI_ABORTED;
+ }
AcpiS3ResumeRecord = &AcpiS3PerformanceTable->S3Resume;
AcpiS3ResumeRecord->FullResume = CurrentTime;
//
diff --git a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf
index 0694899bcb..aced5c521e 100644
--- a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf
+++ b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTablePei/FirmwarePerformancePei.inf
@@ -7,7 +7,7 @@
# This module register report status code listener to collect performance data
# for S3 Resume Performance Record on S3 resume boot path.
#
-# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2011 - 2013, 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
@@ -52,11 +52,11 @@
[Ppis]
gEfiPeiRscHandlerPpiGuid ## CONSUMES
- gEfiPeiReadOnlyVariable2PpiGuid ## SOMETIMES_CONSUMES
gPeiSecPerformancePpiGuid ## CONSUMES
[Guids]
gEfiFirmwarePerformanceGuid ## CONSUMES
+ gFirmwarePerformanceS3PointerGuid ## CONSUMES
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwarePerformanceDataTableS3Support
diff --git a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c
index 54a2275d4e..9c5fd4db85 100644
--- a/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c
+++ b/MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c
@@ -11,7 +11,7 @@
FpdtSmiHandler() will receive untrusted input and do basic validation.
- Copyright (c) 2011 - 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2011 - 2013, 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
@@ -205,6 +205,33 @@ InternalIsAddressInSmram (
}
/**
+ This function check if the address refered by Buffer and Length is valid.
+
+ @param Buffer the buffer address to be checked.
+ @param Length the buffer length to be checked.
+
+ @retval TRUE this address is valid.
+ @retval FALSE this address is NOT valid.
+**/
+BOOLEAN
+InternalIsAddressValid (
+ IN UINTN Buffer,
+ IN UINTN Length
+ )
+{
+ if (Buffer > (MAX_ADDRESS - Length)) {
+ //
+ // Overflow happen
+ //
+ return FALSE;
+ }
+ if (InternalIsAddressInSmram ((EFI_PHYSICAL_ADDRESS)Buffer, (UINT64)Length)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
Communication service SMI Handler entry.
This SMI handler provides services for report SMM boot records.
@@ -239,6 +266,9 @@ FpdtSmiHandler (
{
EFI_STATUS Status;
SMM_BOOT_RECORD_COMMUNICATE *SmmCommData;
+ UINTN BootRecordSize;
+ VOID *BootRecordData;
+ UINTN TempCommBufferSize;
//
// If input is invalid, stop processing this SMI
@@ -247,12 +277,14 @@ FpdtSmiHandler (
return EFI_SUCCESS;
}
- if(*CommBufferSize < sizeof (SMM_BOOT_RECORD_COMMUNICATE)) {
+ TempCommBufferSize = *CommBufferSize;
+
+ if(TempCommBufferSize < sizeof (SMM_BOOT_RECORD_COMMUNICATE)) {
return EFI_SUCCESS;
}
- if (InternalIsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBuffer, *CommBufferSize)) {
- DEBUG ((EFI_D_ERROR, "SMM communication data buffer is in SMRAM!\n"));
+ if (!InternalIsAddressValid ((UINTN)CommBuffer, TempCommBufferSize)) {
+ DEBUG ((EFI_D_ERROR, "FpdtSmiHandler: SMM communication data buffer in SMRAM or overflow!\n"));
return EFI_SUCCESS;
}
@@ -266,7 +298,9 @@ FpdtSmiHandler (
break;
case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA :
- if (SmmCommData->BootRecordData == NULL || SmmCommData->BootRecordSize < mBootRecordSize) {
+ BootRecordData = SmmCommData->BootRecordData;
+ BootRecordSize = SmmCommData->BootRecordSize;
+ if (BootRecordData == NULL || BootRecordSize < mBootRecordSize) {
Status = EFI_INVALID_PARAMETER;
break;
}
@@ -275,14 +309,14 @@ FpdtSmiHandler (
// Sanity check
//
SmmCommData->BootRecordSize = mBootRecordSize;
- if (InternalIsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)SmmCommData->BootRecordData, mBootRecordSize)) {
- DEBUG ((EFI_D_ERROR, "SMM Data buffer is in SMRAM!\n"));
+ if (!InternalIsAddressValid ((UINTN)BootRecordData, mBootRecordSize)) {
+ DEBUG ((EFI_D_ERROR, "FpdtSmiHandler: SMM Data buffer in SMRAM or overflow!\n"));
Status = EFI_ACCESS_DENIED;
break;
}
CopyMem (
- (UINT8*)SmmCommData->BootRecordData,
+ (UINT8*)BootRecordData,
mBootRecordBuffer,
mBootRecordSize
);