This module will execute the boot script saved during last boot and after that,\r
control is passed to OS waking up handler.\r
\r
- Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
\r
#include <Guid/AcpiS3Context.h>\r
#include <Guid/BootScriptExecutorVariable.h>\r
-#include <Guid/Performance.h>\r
+#include <Guid/ExtendedFirmwarePerformance.h>\r
+#include <Guid/EndOfS3Resume.h>\r
+#include <Guid/S3SmmInitDone.h>\r
#include <Ppi/ReadOnlyVariable2.h>\r
#include <Ppi/S3Resume2.h>\r
#include <Ppi/SmmAccess.h>\r
#include <Ppi/EndOfPeiPhase.h>\r
#include <Ppi/SmmCommunication.h>\r
\r
-#include <Protocol/SmmEndOfS3Resume.h>\r
-\r
#include <Library/DebugLib.h>\r
#include <Library/BaseLib.h>\r
#include <Library/TimerLib.h>\r
\r
//\r
// Define two type of smm communicate headers.\r
-// One for 32 bits PEI + 64 bits DXE, the other for 32 bits PEI + 32 bits DXE case.\r
+// One for 32 bits PEI + 64 bits DXE, the other for 32 bits PEI + 32 bits DXE case.\r
//\r
typedef struct {\r
EFI_GUID HeaderGuid;\r
0\r
};\r
\r
+EFI_PEI_PPI_DESCRIPTOR mPpiListS3SmmInitDoneTable = {\r
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),\r
+ &gEdkiiS3SmmInitDoneGuid,\r
+ 0\r
+};\r
+\r
//\r
// Global Descriptor Table (GDT)\r
//\r
(UINTN) mGdtEntries\r
};\r
\r
-/**\r
- Performance measure function to get S3 detailed performance data.\r
-\r
- This function will getS3 detailed performance data and saved in pre-reserved ACPI memory.\r
-**/\r
-VOID\r
-WriteToOsS3PerformanceData (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS mAcpiLowMemoryBase;\r
- PERF_HEADER *PerfHeader;\r
- PERF_DATA *PerfData;\r
- UINT64 Ticker;\r
- UINTN Index;\r
- EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;\r
- UINTN VarSize;\r
- UINTN LogEntryKey;\r
- CONST VOID *Handle;\r
- CONST CHAR8 *Token;\r
- CONST CHAR8 *Module;\r
- UINT64 StartTicker;\r
- UINT64 EndTicker;\r
- UINT64 StartValue;\r
- UINT64 EndValue;\r
- BOOLEAN CountUp;\r
- UINT64 Freq;\r
-\r
- //\r
- // Retrieve time stamp count as early as possible\r
- //\r
- Ticker = GetPerformanceCounter ();\r
-\r
- Freq = GetPerformanceCounterProperties (&StartValue, &EndValue);\r
-\r
- Freq = DivU64x32 (Freq, 1000);\r
-\r
- Status = PeiServicesLocatePpi (\r
- &gEfiPeiReadOnlyVariable2PpiGuid,\r
- 0,\r
- NULL,\r
- (VOID **) &VariableServices\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return;\r
- }\r
-\r
- VarSize = sizeof (EFI_PHYSICAL_ADDRESS);\r
- Status = VariableServices->GetVariable (\r
- VariableServices,\r
- L"PerfDataMemAddr",\r
- &gPerformanceProtocolGuid,\r
- NULL,\r
- &VarSize,\r
- &mAcpiLowMemoryBase\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "Fail to retrieve variable to log S3 performance data \n"));\r
- return;\r
- }\r
-\r
- PerfHeader = (PERF_HEADER *) (UINTN) mAcpiLowMemoryBase;\r
-\r
- if (PerfHeader->Signiture != PERFORMANCE_SIGNATURE) {\r
- DEBUG ((EFI_D_ERROR, "Performance data in ACPI memory get corrupted! \n"));\r
- return;\r
- }\r
-\r
- //\r
- // Record total S3 resume time.\r
- //\r
- if (EndValue >= StartValue) {\r
- PerfHeader->S3Resume = Ticker - StartValue;\r
- CountUp = TRUE;\r
- } else {\r
- PerfHeader->S3Resume = StartValue - Ticker;\r
- CountUp = FALSE;\r
- }\r
-\r
- //\r
- // Get S3 detailed performance data\r
- //\r
- Index = 0;\r
- LogEntryKey = 0;\r
- while ((LogEntryKey = GetPerformanceMeasurement (\r
- LogEntryKey,\r
- &Handle,\r
- &Token,\r
- &Module,\r
- &StartTicker,\r
- &EndTicker)) != 0) {\r
- if (EndTicker != 0) {\r
- PerfData = &PerfHeader->S3Entry[Index];\r
-\r
- //\r
- // Use File Handle to specify the different performance log for PEIM.\r
- // File Handle is the base address of PEIM FFS file.\r
- //\r
- if ((AsciiStrnCmp (Token, "PEIM", PEI_PERFORMANCE_STRING_SIZE) == 0) && (Handle != NULL)) {\r
- AsciiSPrint (PerfData->Token, PERF_TOKEN_LENGTH, "0x%11p", Handle);\r
- } else {\r
- AsciiStrnCpyS (PerfData->Token, PERF_TOKEN_SIZE, Token, PERF_TOKEN_LENGTH);\r
- }\r
- if (StartTicker == 1) {\r
- StartTicker = StartValue;\r
- }\r
- if (EndTicker == 1) {\r
- EndTicker = StartValue;\r
- }\r
- Ticker = CountUp? (EndTicker - StartTicker) : (StartTicker - EndTicker);\r
- PerfData->Duration = (UINT32) DivU64x32 (Ticker, (UINT32) Freq);\r
-\r
- //\r
- // Only Record > 1ms performance data so that more big performance can be recorded.\r
- //\r
- if ((Ticker > Freq) && (++Index >= PERF_PEI_ENTRY_MAX_NUM)) {\r
- //\r
- // Reach the maximum number of PEI performance log entries.\r
- //\r
- break;\r
- }\r
- }\r
- }\r
- PerfHeader->S3EntryNum = (UINT32) Index;\r
-}\r
\r
/**\r
The function will check if current waking vector is long mode.\r
}\r
\r
/**\r
- Send EndOfS3Resume event to SmmCore through communication buffer way.\r
+ Signal to SMM through communication buffer way.\r
+\r
+ @param[in] HandlerType SMI handler type to be signaled.\r
\r
- @retval EFI_SUCCESS Return send the event success.\r
**/\r
-EFI_STATUS\r
-SignalEndOfS3Resume (\r
- VOID\r
+VOID\r
+SignalToSmmByCommunication (\r
+ IN EFI_GUID *HandlerType\r
)\r
{\r
EFI_STATUS Status;\r
SMM_COMMUNICATE_HEADER_64 Header64;\r
VOID *CommBuffer;\r
\r
- DEBUG ((DEBUG_INFO, "SignalEndOfS3Resume - Enter\n"));\r
+ DEBUG ((DEBUG_INFO, "Signal %g to SMM - Enter\n", HandlerType));\r
\r
//\r
// This buffer consumed in DXE phase, so base on DXE mode to prepare communicate buffer.\r
// Detect whether DXE is 64 bits mode.\r
// if (sizeof(UINTN) == sizeof(UINT64), PEI already 64 bits, assume DXE also 64 bits.\r
- // or (FeaturePcdGet (PcdDxeIplSwitchToLongMode)), Dxe will switch to 64 bits.\r
+ // or (FeaturePcdGet (PcdDxeIplSwitchToLongMode)), DXE will switch to 64 bits.\r
//\r
if ((sizeof(UINTN) == sizeof(UINT64)) || (FeaturePcdGet (PcdDxeIplSwitchToLongMode))) {\r
CommBuffer = &Header64;\r
Header32.MessageLength = 0;\r
CommSize = OFFSET_OF (SMM_COMMUNICATE_HEADER_32, Data);\r
}\r
- CopyGuid (CommBuffer, &gEdkiiSmmEndOfS3ResumeProtocolGuid);\r
+ CopyGuid (CommBuffer, HandlerType);\r
\r
Status = PeiServicesLocatePpi (\r
&gEfiPeiSmmCommunicationPpiGuid,\r
);\r
if (EFI_ERROR (Status)) {\r
DEBUG ((DEBUG_ERROR, "Locate Smm Communicate Ppi failed (%r)!\n", Status));\r
- return Status;\r
+ return;\r
}\r
\r
Status = SmmCommunicationPpi->Communicate (\r
DEBUG ((DEBUG_ERROR, "SmmCommunicationPpi->Communicate return failure (%r)!\n", Status));\r
}\r
\r
- DEBUG ((DEBUG_INFO, "SignalEndOfS3Resume - Exit (%r)\n", Status));\r
- return Status;\r
+ DEBUG ((DEBUG_INFO, "Signal %g to SMM - Exit (%r)\n", HandlerType, Status));\r
+ return;\r
}\r
\r
/**\r
//\r
// Install BootScriptDonePpi\r
//\r
+ PERF_START_EX (NULL, "BootScriptDonePpi", NULL, 0, PERF_INMODULE_START_ID);\r
+\r
Status = PeiServicesInstallPpi (&mPpiListPostScriptTable);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ PERF_END_EX (NULL, "BootScriptDonePpi", NULL, 0, PERF_INMODULE_END_ID);\r
+\r
//\r
// Get ACPI Table Address\r
//\r
//\r
// Install EndOfPeiPpi\r
//\r
+ PERF_START_EX (NULL, "EndOfPeiPpi", NULL, 0, PERF_INMODULE_START_ID);\r
+\r
Status = PeiServicesInstallPpi (&mPpiListEndOfPeiTable);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ PERF_END_EX (NULL, "EndOfPeiPpi", NULL, 0, PERF_INMODULE_END_ID);\r
+\r
+ PERF_START_EX (NULL, "EndOfS3Resume", NULL, 0, PERF_INMODULE_START_ID);\r
+\r
+ DEBUG ((DEBUG_INFO, "Signal EndOfS3Resume\n"));\r
//\r
- // Signal EndOfS3Resume event.\r
+ // Signal EndOfS3Resume to SMM.\r
//\r
- SignalEndOfS3Resume ();\r
+ SignalToSmmByCommunication (&gEdkiiEndOfS3ResumeGuid);\r
+\r
+ PERF_END_EX (NULL, "EndOfS3Resume", NULL, 0, PERF_INMODULE_END_ID);\r
\r
//\r
// report status code on S3 resume\r
//\r
REPORT_STATUS_CODE (EFI_PROGRESS_CODE, EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE);\r
\r
- PERF_CODE (\r
- WriteToOsS3PerformanceData ();\r
- );\r
-\r
AsmTransferControl = (ASM_TRANSFER_CONTROL)(UINTN)PeiS3ResumeState->AsmTransferControl;\r
if (Facs->XFirmwareWakingVector != 0) {\r
//\r
Status = SmmAccess->Lock ((EFI_PEI_SERVICES **)GetPeiServicesTablePointer (), SmmAccess, Index);\r
}\r
}\r
+\r
+ DEBUG ((DEBUG_INFO, "Signal S3SmmInitDone\n"));\r
+ //\r
+ // Install S3SmmInitDone PPI.\r
+ //\r
+ Status = PeiServicesInstallPpi (&mPpiListS3SmmInitDoneTable);\r
+ ASSERT_EFI_ERROR (Status);\r
+ //\r
+ // Signal S3SmmInitDone to SMM.\r
+ //\r
+ SignalToSmmByCommunication (&gEdkiiS3SmmInitDoneGuid);\r
}\r
\r
if (FeaturePcdGet (PcdDxeIplSwitchToLongMode)) {\r